blob: 7a1c65e4a19cc90ef8caeed5bc86776b157fc995 [file] [log] [blame]
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/builtins/builtins-utils-inl.h"
#include "src/builtins/builtins.h"
#include "src/heap/heap-inl.h" // For ToBoolean.
#include "src/logging/counters.h"
#include "src/objects/objects-inl.h"
#include "src/objects/stack-frame-info-inl.h"
namespace v8 {
namespace internal {
#define CHECK_CALLSITE(frame, method) \
CHECK_RECEIVER(JSObject, receiver, method); \
LookupIterator it(isolate, receiver, \
isolate->factory()->call_site_frame_info_symbol(), \
LookupIterator::OWN_SKIP_INTERCEPTOR); \
if (it.state() != LookupIterator::DATA) { \
THROW_NEW_ERROR_RETURN_FAILURE( \
isolate, \
NewTypeError(MessageTemplate::kCallSiteMethod, \
isolate->factory()->NewStringFromAsciiChecked(method))); \
} \
Handle<StackFrameInfo> frame = Handle<StackFrameInfo>::cast(it.GetDataValue())
namespace {
Object PositiveNumberOrNull(int value, Isolate* isolate) {
if (value > 0) return *isolate->factory()->NewNumberFromInt(value);
return ReadOnlyRoots(isolate).null_value();
}
} // namespace
BUILTIN(CallSitePrototypeGetColumnNumber) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getColumnNumber");
return PositiveNumberOrNull(StackFrameInfo::GetColumnNumber(frame), isolate);
}
BUILTIN(CallSitePrototypeGetEnclosingColumnNumber) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getEnclosingColumnNumber");
return PositiveNumberOrNull(StackFrameInfo::GetEnclosingColumnNumber(frame),
isolate);
}
BUILTIN(CallSitePrototypeGetEnclosingLineNumber) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getEnclosingLineNumber");
return PositiveNumberOrNull(StackFrameInfo::GetEnclosingLineNumber(frame),
isolate);
}
BUILTIN(CallSitePrototypeGetEvalOrigin) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getEvalOrigin");
return *StackFrameInfo::GetEvalOrigin(frame);
}
BUILTIN(CallSitePrototypeGetFileName) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getFileName");
return frame->GetScriptName();
}
BUILTIN(CallSitePrototypeGetFunction) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getFunction");
if (frame->IsStrict() ||
(frame->function().IsJSFunction() &&
JSFunction::cast(frame->function()).shared().is_toplevel())) {
return ReadOnlyRoots(isolate).undefined_value();
}
isolate->CountUsage(v8::Isolate::kCallSiteAPIGetFunctionSloppyCall);
return frame->function();
}
BUILTIN(CallSitePrototypeGetFunctionName) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getFunctionName");
return *StackFrameInfo::GetFunctionName(frame);
}
BUILTIN(CallSitePrototypeGetLineNumber) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getLineNumber");
return PositiveNumberOrNull(StackFrameInfo::GetLineNumber(frame), isolate);
}
BUILTIN(CallSitePrototypeGetMethodName) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getMethodName");
return *StackFrameInfo::GetMethodName(frame);
}
BUILTIN(CallSitePrototypeGetPosition) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getPosition");
return Smi::FromInt(StackFrameInfo::GetSourcePosition(frame));
}
BUILTIN(CallSitePrototypeGetPromiseIndex) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getPromiseIndex");
if (!frame->IsPromiseAll() && !frame->IsPromiseAny()) {
return ReadOnlyRoots(isolate).null_value();
}
return Smi::FromInt(StackFrameInfo::GetSourcePosition(frame));
}
BUILTIN(CallSitePrototypeGetScriptNameOrSourceURL) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getScriptNameOrSourceUrl");
return frame->GetScriptNameOrSourceURL();
}
BUILTIN(CallSitePrototypeGetThis) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getThis");
if (frame->IsStrict()) return ReadOnlyRoots(isolate).undefined_value();
isolate->CountUsage(v8::Isolate::kCallSiteAPIGetThisSloppyCall);
#if V8_ENABLE_WEBASSEMBLY
if (frame->IsAsmJsWasm()) {
return frame->GetWasmInstance().native_context().global_proxy();
}
#endif // V8_ENABLE_WEBASSEMBLY
return frame->receiver_or_instance();
}
BUILTIN(CallSitePrototypeGetTypeName) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getTypeName");
return *StackFrameInfo::GetTypeName(frame);
}
BUILTIN(CallSitePrototypeIsAsync) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "isAsync");
return isolate->heap()->ToBoolean(frame->IsAsync());
}
BUILTIN(CallSitePrototypeIsConstructor) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "isConstructor");
return isolate->heap()->ToBoolean(frame->IsConstructor());
}
BUILTIN(CallSitePrototypeIsEval) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "isEval");
return isolate->heap()->ToBoolean(frame->IsEval());
}
BUILTIN(CallSitePrototypeIsNative) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "isNative");
return isolate->heap()->ToBoolean(frame->IsNative());
}
BUILTIN(CallSitePrototypeIsPromiseAll) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "isPromiseAll");
return isolate->heap()->ToBoolean(frame->IsPromiseAll());
}
BUILTIN(CallSitePrototypeIsToplevel) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "isToplevel");
return isolate->heap()->ToBoolean(frame->IsToplevel());
}
BUILTIN(CallSitePrototypeToString) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "toString");
RETURN_RESULT_OR_FAILURE(isolate, SerializeStackFrameInfo(isolate, frame));
}
#undef CHECK_CALLSITE
} // namespace internal
} // namespace v8