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/objects-inl.h"
10 #include "src/objects/stack-frame-info-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_frame_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<StackFrameInfo> frame = Handle<StackFrameInfo>::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(StackFrameInfo::GetColumnNumber(frame), isolate);
40 }
41 
BUILTIN(CallSitePrototypeGetEnclosingColumnNumber)42 BUILTIN(CallSitePrototypeGetEnclosingColumnNumber) {
43   HandleScope scope(isolate);
44   CHECK_CALLSITE(frame, "getEnclosingColumnNumber");
45   return PositiveNumberOrNull(StackFrameInfo::GetEnclosingColumnNumber(frame),
46                               isolate);
47 }
48 
BUILTIN(CallSitePrototypeGetEnclosingLineNumber)49 BUILTIN(CallSitePrototypeGetEnclosingLineNumber) {
50   HandleScope scope(isolate);
51   CHECK_CALLSITE(frame, "getEnclosingLineNumber");
52   return PositiveNumberOrNull(StackFrameInfo::GetEnclosingLineNumber(frame),
53                               isolate);
54 }
55 
BUILTIN(CallSitePrototypeGetEvalOrigin)56 BUILTIN(CallSitePrototypeGetEvalOrigin) {
57   HandleScope scope(isolate);
58   CHECK_CALLSITE(frame, "getEvalOrigin");
59   return *StackFrameInfo::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 *StackFrameInfo::GetFunctionName(frame);
84 }
85 
BUILTIN(CallSitePrototypeGetLineNumber)86 BUILTIN(CallSitePrototypeGetLineNumber) {
87   HandleScope scope(isolate);
88   CHECK_CALLSITE(frame, "getLineNumber");
89   return PositiveNumberOrNull(StackFrameInfo::GetLineNumber(frame), isolate);
90 }
91 
BUILTIN(CallSitePrototypeGetMethodName)92 BUILTIN(CallSitePrototypeGetMethodName) {
93   HandleScope scope(isolate);
94   CHECK_CALLSITE(frame, "getMethodName");
95   return *StackFrameInfo::GetMethodName(frame);
96 }
97 
BUILTIN(CallSitePrototypeGetPosition)98 BUILTIN(CallSitePrototypeGetPosition) {
99   HandleScope scope(isolate);
100   CHECK_CALLSITE(frame, "getPosition");
101   return Smi::FromInt(StackFrameInfo::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     return ReadOnlyRoots(isolate).null_value();
109   }
110   return Smi::FromInt(StackFrameInfo::GetSourcePosition(frame));
111 }
112 
BUILTIN(CallSitePrototypeGetScriptNameOrSourceURL)113 BUILTIN(CallSitePrototypeGetScriptNameOrSourceURL) {
114   HandleScope scope(isolate);
115   CHECK_CALLSITE(frame, "getScriptNameOrSourceUrl");
116   return frame->GetScriptNameOrSourceURL();
117 }
118 
BUILTIN(CallSitePrototypeGetThis)119 BUILTIN(CallSitePrototypeGetThis) {
120   HandleScope scope(isolate);
121   CHECK_CALLSITE(frame, "getThis");
122   if (frame->IsStrict()) return ReadOnlyRoots(isolate).undefined_value();
123   isolate->CountUsage(v8::Isolate::kCallSiteAPIGetThisSloppyCall);
124 #if V8_ENABLE_WEBASSEMBLY
125   if (frame->IsAsmJsWasm()) {
126     return frame->GetWasmInstance().native_context().global_proxy();
127   }
128 #endif  // V8_ENABLE_WEBASSEMBLY
129   return frame->receiver_or_instance();
130 }
131 
BUILTIN(CallSitePrototypeGetTypeName)132 BUILTIN(CallSitePrototypeGetTypeName) {
133   HandleScope scope(isolate);
134   CHECK_CALLSITE(frame, "getTypeName");
135   return *StackFrameInfo::GetTypeName(frame);
136 }
137 
BUILTIN(CallSitePrototypeIsAsync)138 BUILTIN(CallSitePrototypeIsAsync) {
139   HandleScope scope(isolate);
140   CHECK_CALLSITE(frame, "isAsync");
141   return isolate->heap()->ToBoolean(frame->IsAsync());
142 }
143 
BUILTIN(CallSitePrototypeIsConstructor)144 BUILTIN(CallSitePrototypeIsConstructor) {
145   HandleScope scope(isolate);
146   CHECK_CALLSITE(frame, "isConstructor");
147   return isolate->heap()->ToBoolean(frame->IsConstructor());
148 }
149 
BUILTIN(CallSitePrototypeIsEval)150 BUILTIN(CallSitePrototypeIsEval) {
151   HandleScope scope(isolate);
152   CHECK_CALLSITE(frame, "isEval");
153   return isolate->heap()->ToBoolean(frame->IsEval());
154 }
155 
BUILTIN(CallSitePrototypeIsNative)156 BUILTIN(CallSitePrototypeIsNative) {
157   HandleScope scope(isolate);
158   CHECK_CALLSITE(frame, "isNative");
159   return isolate->heap()->ToBoolean(frame->IsNative());
160 }
161 
BUILTIN(CallSitePrototypeIsPromiseAll)162 BUILTIN(CallSitePrototypeIsPromiseAll) {
163   HandleScope scope(isolate);
164   CHECK_CALLSITE(frame, "isPromiseAll");
165   return isolate->heap()->ToBoolean(frame->IsPromiseAll());
166 }
167 
BUILTIN(CallSitePrototypeIsToplevel)168 BUILTIN(CallSitePrototypeIsToplevel) {
169   HandleScope scope(isolate);
170   CHECK_CALLSITE(frame, "isToplevel");
171   return isolate->heap()->ToBoolean(frame->IsToplevel());
172 }
173 
BUILTIN(CallSitePrototypeToString)174 BUILTIN(CallSitePrototypeToString) {
175   HandleScope scope(isolate);
176   CHECK_CALLSITE(frame, "toString");
177   RETURN_RESULT_OR_FAILURE(isolate, SerializeStackFrameInfo(isolate, frame));
178 }
179 
180 #undef CHECK_CALLSITE
181 
182 }  // namespace internal
183 }  // namespace v8
184