| // 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.h" |
| #include "src/builtins/builtins-utils.h" |
| |
| #include "src/counters.h" |
| #include "src/objects-inl.h" |
| #include "src/objects/frame-array-inl.h" |
| #include "src/string-builder.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| #define CHECK_CALLSITE(recv, method) \ |
| CHECK_RECEIVER(JSObject, recv, method); \ |
| if (!JSReceiver::HasOwnProperty( \ |
| recv, isolate->factory()->call_site_frame_array_symbol()) \ |
| .FromMaybe(false)) { \ |
| THROW_NEW_ERROR_RETURN_FAILURE( \ |
| isolate, \ |
| NewTypeError(MessageTemplate::kCallSiteMethod, \ |
| isolate->factory()->NewStringFromAsciiChecked(method))); \ |
| } |
| |
| namespace { |
| |
| Object* PositiveNumberOrNull(int value, Isolate* isolate) { |
| if (value >= 0) return *isolate->factory()->NewNumberFromInt(value); |
| return isolate->heap()->null_value(); |
| } |
| |
| Handle<FrameArray> GetFrameArray(Isolate* isolate, Handle<JSObject> object) { |
| Handle<Object> frame_array_obj = JSObject::GetDataProperty( |
| object, isolate->factory()->call_site_frame_array_symbol()); |
| return Handle<FrameArray>::cast(frame_array_obj); |
| } |
| |
| int GetFrameIndex(Isolate* isolate, Handle<JSObject> object) { |
| Handle<Object> frame_index_obj = JSObject::GetDataProperty( |
| object, isolate->factory()->call_site_frame_index_symbol()); |
| return Smi::ToInt(*frame_index_obj); |
| } |
| |
| } // namespace |
| |
| BUILTIN(CallSitePrototypeGetColumnNumber) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "getColumnNumber"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return PositiveNumberOrNull(it.Frame()->GetColumnNumber(), isolate); |
| } |
| |
| BUILTIN(CallSitePrototypeGetEvalOrigin) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "getEvalOrigin"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return *it.Frame()->GetEvalOrigin(); |
| } |
| |
| BUILTIN(CallSitePrototypeGetFileName) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "getFileName"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return *it.Frame()->GetFileName(); |
| } |
| |
| BUILTIN(CallSitePrototypeGetFunction) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "getFunction"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| |
| StackFrameBase* frame = it.Frame(); |
| if (frame->IsStrict()) return isolate->heap()->undefined_value(); |
| return *frame->GetFunction(); |
| } |
| |
| BUILTIN(CallSitePrototypeGetFunctionName) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "getFunctionName"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return *it.Frame()->GetFunctionName(); |
| } |
| |
| BUILTIN(CallSitePrototypeGetLineNumber) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "getLineNumber"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return PositiveNumberOrNull(it.Frame()->GetLineNumber(), isolate); |
| } |
| |
| BUILTIN(CallSitePrototypeGetMethodName) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "getMethodName"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return *it.Frame()->GetMethodName(); |
| } |
| |
| BUILTIN(CallSitePrototypeGetPosition) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "getPosition"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return Smi::FromInt(it.Frame()->GetPosition()); |
| } |
| |
| BUILTIN(CallSitePrototypeGetScriptNameOrSourceURL) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "getScriptNameOrSourceUrl"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return *it.Frame()->GetScriptNameOrSourceUrl(); |
| } |
| |
| BUILTIN(CallSitePrototypeGetThis) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "getThis"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| |
| StackFrameBase* frame = it.Frame(); |
| if (frame->IsStrict()) return isolate->heap()->undefined_value(); |
| return *frame->GetReceiver(); |
| } |
| |
| BUILTIN(CallSitePrototypeGetTypeName) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "getTypeName"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return *it.Frame()->GetTypeName(); |
| } |
| |
| BUILTIN(CallSitePrototypeIsConstructor) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "isConstructor"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return isolate->heap()->ToBoolean(it.Frame()->IsConstructor()); |
| } |
| |
| BUILTIN(CallSitePrototypeIsEval) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "isEval"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return isolate->heap()->ToBoolean(it.Frame()->IsEval()); |
| } |
| |
| BUILTIN(CallSitePrototypeIsNative) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "isNative"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return isolate->heap()->ToBoolean(it.Frame()->IsNative()); |
| } |
| |
| BUILTIN(CallSitePrototypeIsToplevel) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "isToplevel"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| return isolate->heap()->ToBoolean(it.Frame()->IsToplevel()); |
| } |
| |
| BUILTIN(CallSitePrototypeToString) { |
| HandleScope scope(isolate); |
| CHECK_CALLSITE(recv, "toString"); |
| FrameArrayIterator it(isolate, GetFrameArray(isolate, recv), |
| GetFrameIndex(isolate, recv)); |
| RETURN_RESULT_OR_FAILURE(isolate, it.Frame()->ToString()); |
| } |
| |
| #undef CHECK_CALLSITE |
| |
| } // namespace internal |
| } // namespace v8 |