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.h"
6#include "src/builtins/builtins-utils.h"
7
8#include "src/counters.h"
9#include "src/objects-inl.h"
10#include "src/string-builder.h"
11#include "src/wasm/wasm-module.h"
12
13namespace v8 {
14namespace internal {
15
16#define CHECK_CALLSITE(recv, method)                                          \
17  CHECK_RECEIVER(JSObject, recv, method);                                     \
18  if (!JSReceiver::HasOwnProperty(                                            \
19           recv, isolate->factory()->call_site_frame_array_symbol())          \
20           .FromMaybe(false)) {                                               \
21    THROW_NEW_ERROR_RETURN_FAILURE(                                           \
22        isolate,                                                              \
23        NewTypeError(MessageTemplate::kCallSiteMethod,                        \
24                     isolate->factory()->NewStringFromAsciiChecked(method))); \
25  }
26
27namespace {
28
29Object* PositiveNumberOrNull(int value, Isolate* isolate) {
30  if (value >= 0) return *isolate->factory()->NewNumberFromInt(value);
31  return isolate->heap()->null_value();
32}
33
34Handle<FrameArray> GetFrameArray(Isolate* isolate, Handle<JSObject> object) {
35  Handle<Object> frame_array_obj = JSObject::GetDataProperty(
36      object, isolate->factory()->call_site_frame_array_symbol());
37  return Handle<FrameArray>::cast(frame_array_obj);
38}
39
40int GetFrameIndex(Isolate* isolate, Handle<JSObject> object) {
41  Handle<Object> frame_index_obj = JSObject::GetDataProperty(
42      object, isolate->factory()->call_site_frame_index_symbol());
43  return Smi::cast(*frame_index_obj)->value();
44}
45
46}  // namespace
47
48BUILTIN(CallSitePrototypeGetColumnNumber) {
49  HandleScope scope(isolate);
50  CHECK_CALLSITE(recv, "getColumnNumber");
51  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
52                        GetFrameIndex(isolate, recv));
53  return PositiveNumberOrNull(it.Frame()->GetColumnNumber(), isolate);
54}
55
56BUILTIN(CallSitePrototypeGetEvalOrigin) {
57  HandleScope scope(isolate);
58  CHECK_CALLSITE(recv, "getEvalOrigin");
59  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
60                        GetFrameIndex(isolate, recv));
61  return *it.Frame()->GetEvalOrigin();
62}
63
64BUILTIN(CallSitePrototypeGetFileName) {
65  HandleScope scope(isolate);
66  CHECK_CALLSITE(recv, "getFileName");
67  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
68                        GetFrameIndex(isolate, recv));
69  return *it.Frame()->GetFileName();
70}
71
72BUILTIN(CallSitePrototypeGetFunction) {
73  HandleScope scope(isolate);
74  CHECK_CALLSITE(recv, "getFunction");
75  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
76                        GetFrameIndex(isolate, recv));
77
78  StackFrameBase* frame = it.Frame();
79  if (frame->IsStrict()) return isolate->heap()->undefined_value();
80  return *frame->GetFunction();
81}
82
83BUILTIN(CallSitePrototypeGetFunctionName) {
84  HandleScope scope(isolate);
85  CHECK_CALLSITE(recv, "getFunctionName");
86  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
87                        GetFrameIndex(isolate, recv));
88  return *it.Frame()->GetFunctionName();
89}
90
91BUILTIN(CallSitePrototypeGetLineNumber) {
92  HandleScope scope(isolate);
93  CHECK_CALLSITE(recv, "getLineNumber");
94  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
95                        GetFrameIndex(isolate, recv));
96  return PositiveNumberOrNull(it.Frame()->GetLineNumber(), isolate);
97}
98
99BUILTIN(CallSitePrototypeGetMethodName) {
100  HandleScope scope(isolate);
101  CHECK_CALLSITE(recv, "getMethodName");
102  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
103                        GetFrameIndex(isolate, recv));
104  return *it.Frame()->GetMethodName();
105}
106
107BUILTIN(CallSitePrototypeGetPosition) {
108  HandleScope scope(isolate);
109  CHECK_CALLSITE(recv, "getPosition");
110  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
111                        GetFrameIndex(isolate, recv));
112  return Smi::FromInt(it.Frame()->GetPosition());
113}
114
115BUILTIN(CallSitePrototypeGetScriptNameOrSourceURL) {
116  HandleScope scope(isolate);
117  CHECK_CALLSITE(recv, "getScriptNameOrSourceUrl");
118  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
119                        GetFrameIndex(isolate, recv));
120  return *it.Frame()->GetScriptNameOrSourceUrl();
121}
122
123BUILTIN(CallSitePrototypeGetThis) {
124  HandleScope scope(isolate);
125  CHECK_CALLSITE(recv, "getThis");
126  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
127                        GetFrameIndex(isolate, recv));
128
129  StackFrameBase* frame = it.Frame();
130  if (frame->IsStrict()) return isolate->heap()->undefined_value();
131  return *frame->GetReceiver();
132}
133
134BUILTIN(CallSitePrototypeGetTypeName) {
135  HandleScope scope(isolate);
136  CHECK_CALLSITE(recv, "getTypeName");
137  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
138                        GetFrameIndex(isolate, recv));
139  return *it.Frame()->GetTypeName();
140}
141
142BUILTIN(CallSitePrototypeIsConstructor) {
143  HandleScope scope(isolate);
144  CHECK_CALLSITE(recv, "isConstructor");
145  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
146                        GetFrameIndex(isolate, recv));
147  return isolate->heap()->ToBoolean(it.Frame()->IsConstructor());
148}
149
150BUILTIN(CallSitePrototypeIsEval) {
151  HandleScope scope(isolate);
152  CHECK_CALLSITE(recv, "isEval");
153  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
154                        GetFrameIndex(isolate, recv));
155  return isolate->heap()->ToBoolean(it.Frame()->IsEval());
156}
157
158BUILTIN(CallSitePrototypeIsNative) {
159  HandleScope scope(isolate);
160  CHECK_CALLSITE(recv, "isNative");
161  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
162                        GetFrameIndex(isolate, recv));
163  return isolate->heap()->ToBoolean(it.Frame()->IsNative());
164}
165
166BUILTIN(CallSitePrototypeIsToplevel) {
167  HandleScope scope(isolate);
168  CHECK_CALLSITE(recv, "isToplevel");
169  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
170                        GetFrameIndex(isolate, recv));
171  return isolate->heap()->ToBoolean(it.Frame()->IsToplevel());
172}
173
174BUILTIN(CallSitePrototypeToString) {
175  HandleScope scope(isolate);
176  CHECK_CALLSITE(recv, "toString");
177  FrameArrayIterator it(isolate, GetFrameArray(isolate, recv),
178                        GetFrameIndex(isolate, recv));
179  RETURN_RESULT_OR_FAILURE(isolate, it.Frame()->ToString());
180}
181
182#undef CHECK_CALLSITE
183
184}  // namespace internal
185}  // namespace v8
186