1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/builtins/builtins-utils-inl.h"
6 #include "src/builtins/builtins.h"
7 #include "src/heap/heap-inl.h" // For ToBoolean.
8 #include "src/logging/counters.h"
9 #include "src/objects/call-site-info-inl.h"
10 #include "src/objects/objects-inl.h"
11
12 namespace v8 {
13 namespace internal {
14
15 #define CHECK_CALLSITE(frame, method) \
16 CHECK_RECEIVER(JSObject, receiver, method); \
17 LookupIterator it(isolate, receiver, \
18 isolate->factory()->call_site_info_symbol(), \
19 LookupIterator::OWN_SKIP_INTERCEPTOR); \
20 if (it.state() != LookupIterator::DATA) { \
21 THROW_NEW_ERROR_RETURN_FAILURE( \
22 isolate, \
23 NewTypeError(MessageTemplate::kCallSiteMethod, \
24 isolate->factory()->NewStringFromAsciiChecked(method))); \
25 } \
26 Handle<CallSiteInfo> frame = Handle<CallSiteInfo>::cast(it.GetDataValue())
27 namespace {
28
PositiveNumberOrNull(int value,Isolate * isolate)29 Object PositiveNumberOrNull(int value, Isolate* isolate) {
30 if (value > 0) return *isolate->factory()->NewNumberFromInt(value);
31 return ReadOnlyRoots(isolate).null_value();
32 }
33
34 } // namespace
35
BUILTIN(CallSitePrototypeGetColumnNumber)36 BUILTIN(CallSitePrototypeGetColumnNumber) {
37 HandleScope scope(isolate);
38 CHECK_CALLSITE(frame, "getColumnNumber");
39 return PositiveNumberOrNull(CallSiteInfo::GetColumnNumber(frame), isolate);
40 }
41
BUILTIN(CallSitePrototypeGetEnclosingColumnNumber)42 BUILTIN(CallSitePrototypeGetEnclosingColumnNumber) {
43 HandleScope scope(isolate);
44 CHECK_CALLSITE(frame, "getEnclosingColumnNumber");
45 return PositiveNumberOrNull(CallSiteInfo::GetEnclosingColumnNumber(frame),
46 isolate);
47 }
48
BUILTIN(CallSitePrototypeGetEnclosingLineNumber)49 BUILTIN(CallSitePrototypeGetEnclosingLineNumber) {
50 HandleScope scope(isolate);
51 CHECK_CALLSITE(frame, "getEnclosingLineNumber");
52 return PositiveNumberOrNull(CallSiteInfo::GetEnclosingLineNumber(frame),
53 isolate);
54 }
55
BUILTIN(CallSitePrototypeGetEvalOrigin)56 BUILTIN(CallSitePrototypeGetEvalOrigin) {
57 HandleScope scope(isolate);
58 CHECK_CALLSITE(frame, "getEvalOrigin");
59 return *CallSiteInfo::GetEvalOrigin(frame);
60 }
61
BUILTIN(CallSitePrototypeGetFileName)62 BUILTIN(CallSitePrototypeGetFileName) {
63 HandleScope scope(isolate);
64 CHECK_CALLSITE(frame, "getFileName");
65 return frame->GetScriptName();
66 }
67
BUILTIN(CallSitePrototypeGetFunction)68 BUILTIN(CallSitePrototypeGetFunction) {
69 HandleScope scope(isolate);
70 CHECK_CALLSITE(frame, "getFunction");
71 if (frame->IsStrict() ||
72 (frame->function().IsJSFunction() &&
73 JSFunction::cast(frame->function()).shared().is_toplevel())) {
74 return ReadOnlyRoots(isolate).undefined_value();
75 }
76 isolate->CountUsage(v8::Isolate::kCallSiteAPIGetFunctionSloppyCall);
77 return frame->function();
78 }
79
BUILTIN(CallSitePrototypeGetFunctionName)80 BUILTIN(CallSitePrototypeGetFunctionName) {
81 HandleScope scope(isolate);
82 CHECK_CALLSITE(frame, "getFunctionName");
83 return *CallSiteInfo::GetFunctionName(frame);
84 }
85
BUILTIN(CallSitePrototypeGetLineNumber)86 BUILTIN(CallSitePrototypeGetLineNumber) {
87 HandleScope scope(isolate);
88 CHECK_CALLSITE(frame, "getLineNumber");
89 return PositiveNumberOrNull(CallSiteInfo::GetLineNumber(frame), isolate);
90 }
91
BUILTIN(CallSitePrototypeGetMethodName)92 BUILTIN(CallSitePrototypeGetMethodName) {
93 HandleScope scope(isolate);
94 CHECK_CALLSITE(frame, "getMethodName");
95 return *CallSiteInfo::GetMethodName(frame);
96 }
97
BUILTIN(CallSitePrototypeGetPosition)98 BUILTIN(CallSitePrototypeGetPosition) {
99 HandleScope scope(isolate);
100 CHECK_CALLSITE(frame, "getPosition");
101 return Smi::FromInt(CallSiteInfo::GetSourcePosition(frame));
102 }
103
BUILTIN(CallSitePrototypeGetPromiseIndex)104 BUILTIN(CallSitePrototypeGetPromiseIndex) {
105 HandleScope scope(isolate);
106 CHECK_CALLSITE(frame, "getPromiseIndex");
107 if (!frame->IsPromiseAll() && !frame->IsPromiseAny() &&
108 !frame->IsPromiseAllSettled()) {
109 return ReadOnlyRoots(isolate).null_value();
110 }
111 return Smi::FromInt(CallSiteInfo::GetSourcePosition(frame));
112 }
113
BUILTIN(CallSitePrototypeGetScriptNameOrSourceURL)114 BUILTIN(CallSitePrototypeGetScriptNameOrSourceURL) {
115 HandleScope scope(isolate);
116 CHECK_CALLSITE(frame, "getScriptNameOrSourceUrl");
117 return frame->GetScriptNameOrSourceURL();
118 }
119
BUILTIN(CallSitePrototypeGetThis)120 BUILTIN(CallSitePrototypeGetThis) {
121 HandleScope scope(isolate);
122 CHECK_CALLSITE(frame, "getThis");
123 if (frame->IsStrict()) return ReadOnlyRoots(isolate).undefined_value();
124 isolate->CountUsage(v8::Isolate::kCallSiteAPIGetThisSloppyCall);
125 #if V8_ENABLE_WEBASSEMBLY
126 if (frame->IsAsmJsWasm()) {
127 return frame->GetWasmInstance().native_context().global_proxy();
128 }
129 #endif // V8_ENABLE_WEBASSEMBLY
130 return frame->receiver_or_instance();
131 }
132
BUILTIN(CallSitePrototypeGetTypeName)133 BUILTIN(CallSitePrototypeGetTypeName) {
134 HandleScope scope(isolate);
135 CHECK_CALLSITE(frame, "getTypeName");
136 return *CallSiteInfo::GetTypeName(frame);
137 }
138
BUILTIN(CallSitePrototypeIsAsync)139 BUILTIN(CallSitePrototypeIsAsync) {
140 HandleScope scope(isolate);
141 CHECK_CALLSITE(frame, "isAsync");
142 return isolate->heap()->ToBoolean(frame->IsAsync());
143 }
144
BUILTIN(CallSitePrototypeIsConstructor)145 BUILTIN(CallSitePrototypeIsConstructor) {
146 HandleScope scope(isolate);
147 CHECK_CALLSITE(frame, "isConstructor");
148 return isolate->heap()->ToBoolean(frame->IsConstructor());
149 }
150
BUILTIN(CallSitePrototypeIsEval)151 BUILTIN(CallSitePrototypeIsEval) {
152 HandleScope scope(isolate);
153 CHECK_CALLSITE(frame, "isEval");
154 return isolate->heap()->ToBoolean(frame->IsEval());
155 }
156
BUILTIN(CallSitePrototypeIsNative)157 BUILTIN(CallSitePrototypeIsNative) {
158 HandleScope scope(isolate);
159 CHECK_CALLSITE(frame, "isNative");
160 return isolate->heap()->ToBoolean(frame->IsNative());
161 }
162
BUILTIN(CallSitePrototypeIsPromiseAll)163 BUILTIN(CallSitePrototypeIsPromiseAll) {
164 HandleScope scope(isolate);
165 CHECK_CALLSITE(frame, "isPromiseAll");
166 return isolate->heap()->ToBoolean(frame->IsPromiseAll());
167 }
168
BUILTIN(CallSitePrototypeIsToplevel)169 BUILTIN(CallSitePrototypeIsToplevel) {
170 HandleScope scope(isolate);
171 CHECK_CALLSITE(frame, "isToplevel");
172 return isolate->heap()->ToBoolean(frame->IsToplevel());
173 }
174
BUILTIN(CallSitePrototypeToString)175 BUILTIN(CallSitePrototypeToString) {
176 HandleScope scope(isolate);
177 CHECK_CALLSITE(frame, "toString");
178 RETURN_RESULT_OR_FAILURE(isolate, SerializeCallSiteInfo(isolate, frame));
179 }
180
181 #undef CHECK_CALLSITE
182
183 } // namespace internal
184 } // namespace v8
185