diff options
Diffstat (limited to 'deps/v8/src/runtime/runtime-internal.cc')
-rw-r--r-- | deps/v8/src/runtime/runtime-internal.cc | 346 |
1 files changed, 220 insertions, 126 deletions
diff --git a/deps/v8/src/runtime/runtime-internal.cc b/deps/v8/src/runtime/runtime-internal.cc index d871fc7f5a..3de0f16b1e 100644 --- a/deps/v8/src/runtime/runtime-internal.cc +++ b/deps/v8/src/runtime/runtime-internal.cc @@ -4,6 +4,8 @@ #include "src/runtime/runtime-utils.h" +#include <memory> + #include "src/arguments.h" #include "src/ast/prettyprinter.h" #include "src/bootstrapper.h" @@ -12,7 +14,9 @@ #include "src/frames-inl.h" #include "src/isolate-inl.h" #include "src/messages.h" +#include "src/parsing/parse-info.h" #include "src/parsing/parser.h" +#include "src/wasm/wasm-module.h" namespace v8 { namespace internal { @@ -20,7 +24,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) { SealHandleScope shs(isolate); DCHECK(args.length() == 0); - RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); + CHECK(isolate->bootstrapper()->IsActive()); return isolate->heap()->undefined_value(); } @@ -29,7 +33,7 @@ RUNTIME_FUNCTION(Runtime_ExportFromRuntime) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(JSObject, container, 0); - RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); + CHECK(isolate->bootstrapper()->IsActive()); JSObject::NormalizeProperties(container, KEEP_INOBJECT_PROPERTIES, 10, "ExportFromRuntime"); Bootstrapper::ExportFromRuntime(isolate, container); @@ -42,7 +46,7 @@ RUNTIME_FUNCTION(Runtime_ExportExperimentalFromRuntime) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(JSObject, container, 0); - RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); + CHECK(isolate->bootstrapper()->IsActive()); JSObject::NormalizeProperties(container, KEEP_INOBJECT_PROPERTIES, 10, "ExportExperimentalFromRuntime"); Bootstrapper::ExportExperimentalFromRuntime(isolate, container); @@ -55,21 +59,21 @@ RUNTIME_FUNCTION(Runtime_InstallToContext) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); - RUNTIME_ASSERT(array->HasFastElements()); - RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); + CHECK(array->HasFastElements()); + CHECK(isolate->bootstrapper()->IsActive()); Handle<Context> native_context = isolate->native_context(); Handle<FixedArray> fixed_array(FixedArray::cast(array->elements())); int length = Smi::cast(array->length())->value(); for (int i = 0; i < length; i += 2) { - RUNTIME_ASSERT(fixed_array->get(i)->IsString()); + CHECK(fixed_array->get(i)->IsString()); Handle<String> name(String::cast(fixed_array->get(i))); - RUNTIME_ASSERT(fixed_array->get(i + 1)->IsJSObject()); + CHECK(fixed_array->get(i + 1)->IsJSObject()); Handle<JSObject> object(JSObject::cast(fixed_array->get(i + 1))); int index = Context::ImportedFieldIndexForName(name); if (index == Context::kNotFound) { index = Context::IntrinsicIndexForName(name); } - RUNTIME_ASSERT(index != Context::kNotFound); + CHECK(index != Context::kNotFound); native_context->set(index, *object); } return isolate->heap()->undefined_value(); @@ -96,6 +100,60 @@ RUNTIME_FUNCTION(Runtime_ThrowStackOverflow) { return isolate->StackOverflow(); } +RUNTIME_FUNCTION(Runtime_ThrowWasmError) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_SMI_ARG_CHECKED(message_id, 0); + CONVERT_SMI_ARG_CHECKED(byte_offset, 1); + Handle<Object> error_obj = isolate->factory()->NewError( + static_cast<MessageTemplate::Template>(message_id)); + + // For wasm traps, the byte offset (a.k.a source position) can not be + // determined from relocation info, since the explicit checks for traps + // converge in one singe block which calls this runtime function. + // We hence pass the byte offset explicitely, and patch it into the top-most + // frame (a wasm frame) on the collected stack trace. + // TODO(wasm): This implementation is temporary, see bug #5007: + // https://bugs.chromium.org/p/v8/issues/detail?id=5007 + Handle<JSObject> error = Handle<JSObject>::cast(error_obj); + Handle<Object> stack_trace_obj = JSReceiver::GetDataProperty( + error, isolate->factory()->stack_trace_symbol()); + // Patch the stack trace (array of <receiver, function, code, position>). + if (stack_trace_obj->IsJSArray()) { + Handle<FixedArray> stack_elements( + FixedArray::cast(JSArray::cast(*stack_trace_obj)->elements())); + DCHECK_EQ(1, stack_elements->length() % 4); + DCHECK(Code::cast(stack_elements->get(3))->kind() == Code::WASM_FUNCTION); + DCHECK(stack_elements->get(4)->IsSmi() && + Smi::cast(stack_elements->get(4))->value() >= 0); + stack_elements->set(4, Smi::FromInt(-1 - byte_offset)); + } + Handle<Object> detailed_stack_trace_obj = JSReceiver::GetDataProperty( + error, isolate->factory()->detailed_stack_trace_symbol()); + // Patch the detailed stack trace (array of JSObjects with various + // properties). + if (detailed_stack_trace_obj->IsJSArray()) { + Handle<FixedArray> stack_elements( + FixedArray::cast(JSArray::cast(*detailed_stack_trace_obj)->elements())); + DCHECK_GE(stack_elements->length(), 1); + Handle<JSObject> top_frame(JSObject::cast(stack_elements->get(0))); + Handle<String> wasm_offset_key = + isolate->factory()->InternalizeOneByteString( + STATIC_CHAR_VECTOR("column")); + LookupIterator it(top_frame, wasm_offset_key, top_frame, + LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); + if (it.IsFound()) { + DCHECK(JSReceiver::GetDataProperty(&it)->IsSmi()); + // Make column number 1-based here. + Maybe<bool> data_set = JSReceiver::SetDataProperty( + &it, handle(Smi::FromInt(byte_offset + 1), isolate)); + DCHECK(data_set.IsJust() && data_set.FromJust() == true); + USE(data_set); + } + } + + return isolate->Throw(*error_obj); +} RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler) { SealHandleScope shs(isolate); @@ -152,6 +210,11 @@ RUNTIME_FUNCTION(Runtime_NewSyntaxError) { return *isolate->factory()->NewSyntaxError(message_template, arg0); } +RUNTIME_FUNCTION(Runtime_ThrowCannotConvertToPrimitive) { + HandleScope scope(isolate); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kCannotConvertToPrimitive)); +} RUNTIME_FUNCTION(Runtime_ThrowIllegalInvocation) { HandleScope scope(isolate); @@ -160,6 +223,21 @@ RUNTIME_FUNCTION(Runtime_ThrowIllegalInvocation) { isolate, NewTypeError(MessageTemplate::kIllegalInvocation)); } +RUNTIME_FUNCTION(Runtime_ThrowIncompatibleMethodReceiver) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, arg1, 1); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, arg0, arg1)); +} + +RUNTIME_FUNCTION(Runtime_ThrowInvalidStringLength) { + HandleScope scope(isolate); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewRangeError(MessageTemplate::kInvalidStringLength)); +} RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject) { HandleScope scope(isolate); @@ -170,6 +248,20 @@ RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject) { NewTypeError(MessageTemplate::kIteratorResultNotAnObject, value)); } +RUNTIME_FUNCTION(Runtime_ThrowNotGeneric) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 0); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kNotGeneric, arg0)); +} + +RUNTIME_FUNCTION(Runtime_ThrowGeneratorRunning) { + HandleScope scope(isolate); + DCHECK_EQ(0, args.length()); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kGeneratorRunning)); +} RUNTIME_FUNCTION(Runtime_ThrowApplyNonFunction) { HandleScope scope(isolate); @@ -190,7 +282,7 @@ RUNTIME_FUNCTION(Runtime_PromiseRejectEvent) { if (debug_event) isolate->debug()->OnPromiseReject(promise, value); Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol(); // Do not report if we actually have a handler. - if (JSReceiver::GetDataProperty(promise, key)->IsUndefined()) { + if (JSReceiver::GetDataProperty(promise, key)->IsUndefined(isolate)) { isolate->ReportPromiseReject(promise, value, v8::kPromiseRejectWithNoHandler); } @@ -204,7 +296,7 @@ RUNTIME_FUNCTION(Runtime_PromiseRevokeReject) { CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol(); // At this point, no revocation has been issued before - RUNTIME_ASSERT(JSReceiver::GetDataProperty(promise, key)->IsUndefined()); + CHECK(JSReceiver::GetDataProperty(promise, key)->IsUndefined(isolate)); isolate->ReportPromiseReject(promise, Handle<Object>(), v8::kPromiseHandlerAddedAfterReject); return isolate->heap()->undefined_value(); @@ -236,9 +328,9 @@ RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_SMI_ARG_CHECKED(size, 0); - RUNTIME_ASSERT(IsAligned(size, kPointerSize)); - RUNTIME_ASSERT(size > 0); - RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize); + CHECK(IsAligned(size, kPointerSize)); + CHECK(size > 0); + CHECK(size <= Page::kMaxRegularHeapObjectSize); return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE); } @@ -248,108 +340,34 @@ RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) { DCHECK(args.length() == 2); CONVERT_SMI_ARG_CHECKED(size, 0); CONVERT_SMI_ARG_CHECKED(flags, 1); - RUNTIME_ASSERT(IsAligned(size, kPointerSize)); - RUNTIME_ASSERT(size > 0); - RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize); + CHECK(IsAligned(size, kPointerSize)); + CHECK(size > 0); + CHECK(size <= Page::kMaxRegularHeapObjectSize); bool double_align = AllocateDoubleAlignFlag::decode(flags); AllocationSpace space = AllocateTargetSpace::decode(flags); return *isolate->factory()->NewFillerObject(size, double_align, space); } - -// Collect the raw data for a stack trace. Returns an array of 4 -// element segments each containing a receiver, function, code and -// native code offset. -RUNTIME_FUNCTION(Runtime_CollectStackTrace) { +RUNTIME_FUNCTION(Runtime_AllocateSeqOneByteString) { HandleScope scope(isolate); - DCHECK(args.length() == 2); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, error_object, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1); - - if (!isolate->bootstrapper()->IsActive()) { - // Optionally capture a more detailed stack trace for the message. - RETURN_FAILURE_ON_EXCEPTION( - isolate, isolate->CaptureAndSetDetailedStackTrace(error_object)); - // Capture a simple stack trace for the stack property. - RETURN_FAILURE_ON_EXCEPTION( - isolate, isolate->CaptureAndSetSimpleStackTrace(error_object, caller)); - } - return isolate->heap()->undefined_value(); -} - - -RUNTIME_FUNCTION(Runtime_MessageGetStartPosition) { - SealHandleScope shs(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_CHECKED(JSMessageObject, message, 0); - return Smi::FromInt(message->start_position()); -} - - -RUNTIME_FUNCTION(Runtime_MessageGetScript) { - SealHandleScope shs(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_CHECKED(JSMessageObject, message, 0); - return message->script(); + DCHECK_EQ(1, args.length()); + CONVERT_SMI_ARG_CHECKED(length, 0); + Handle<SeqOneByteString> result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, isolate->factory()->NewRawOneByteString(length)); + return *result; } - -RUNTIME_FUNCTION(Runtime_FormatMessageString) { +RUNTIME_FUNCTION(Runtime_AllocateSeqTwoByteString) { HandleScope scope(isolate); - DCHECK(args.length() == 4); - CONVERT_INT32_ARG_CHECKED(template_index, 0); - CONVERT_ARG_HANDLE_CHECKED(String, arg0, 1); - CONVERT_ARG_HANDLE_CHECKED(String, arg1, 2); - CONVERT_ARG_HANDLE_CHECKED(String, arg2, 3); - Handle<String> result; + DCHECK_EQ(1, args.length()); + CONVERT_SMI_ARG_CHECKED(length, 0); + Handle<SeqTwoByteString> result; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, - MessageTemplate::FormatMessage(template_index, arg0, arg1, arg2)); - isolate->native_context()->IncrementErrorsThrown(); + isolate, result, isolate->factory()->NewRawTwoByteString(length)); return *result; } -#define CALLSITE_GET(NAME, RETURN) \ - RUNTIME_FUNCTION(Runtime_CallSite##NAME##RT) { \ - HandleScope scope(isolate); \ - DCHECK(args.length() == 1); \ - CONVERT_ARG_HANDLE_CHECKED(JSObject, call_site_obj, 0); \ - Handle<String> result; \ - CallSite call_site(isolate, call_site_obj); \ - RUNTIME_ASSERT(call_site.IsValid()); \ - return RETURN(call_site.NAME(), isolate); \ - } - -static inline Object* ReturnDereferencedHandle(Handle<Object> obj, - Isolate* isolate) { - return *obj; -} - - -static inline Object* ReturnPositiveNumberOrNull(int value, Isolate* isolate) { - if (value >= 0) return *isolate->factory()->NewNumberFromInt(value); - return isolate->heap()->null_value(); -} - - -static inline Object* ReturnBoolean(bool value, Isolate* isolate) { - return isolate->heap()->ToBoolean(value); -} - - -CALLSITE_GET(GetFileName, ReturnDereferencedHandle) -CALLSITE_GET(GetFunctionName, ReturnDereferencedHandle) -CALLSITE_GET(GetScriptNameOrSourceUrl, ReturnDereferencedHandle) -CALLSITE_GET(GetMethodName, ReturnDereferencedHandle) -CALLSITE_GET(GetLineNumber, ReturnPositiveNumberOrNull) -CALLSITE_GET(GetColumnNumber, ReturnPositiveNumberOrNull) -CALLSITE_GET(IsNative, ReturnBoolean) -CALLSITE_GET(IsToplevel, ReturnBoolean) -CALLSITE_GET(IsEval, ReturnBoolean) -CALLSITE_GET(IsConstructor, ReturnBoolean) - -#undef CALLSITE_GET - RUNTIME_FUNCTION(Runtime_IS_VAR) { UNREACHABLE(); // implemented as macro in the parser @@ -366,8 +384,8 @@ bool ComputeLocation(Isolate* isolate, MessageLocation* target) { JSFunction* fun = frame->function(); Object* script = fun->shared()->script(); if (script->IsScript() && - !(Script::cast(script)->source()->IsUndefined())) { - Handle<Script> casted_script(Script::cast(script)); + !(Script::cast(script)->source()->IsUndefined(isolate))) { + Handle<Script> casted_script(Script::cast(script), isolate); // Compute the location from the function and the relocation info of the // baseline code. For optimized code this will use the deoptimization // information to get canonical location information. @@ -387,16 +405,14 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object) { MessageLocation location; if (ComputeLocation(isolate, &location)) { Zone zone(isolate->allocator()); - base::SmartPointer<ParseInfo> info( + std::unique_ptr<ParseInfo> info( location.function()->shared()->is_function() ? new ParseInfo(&zone, location.function()) : new ParseInfo(&zone, location.script())); if (Parser::ParseStatic(info.get())) { CallPrinter printer(isolate, location.function()->shared()->IsBuiltin()); - const char* string = printer.Print(info->literal(), location.start_pos()); - if (strlen(string) > 0) { - return isolate->factory()->NewStringFromAsciiChecked(string); - } + Handle<String> str = printer.Print(info->literal(), location.start_pos()); + if (str->length() > 0) return str; } else { isolate->clear_pending_exception(); } @@ -416,6 +432,13 @@ RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) { isolate, NewTypeError(MessageTemplate::kCalledNonCallable, callsite)); } +RUNTIME_FUNCTION(Runtime_ThrowCalledOnNullOrUndefined) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(String, name, 0); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, name)); +} RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable) { HandleScope scope(isolate); @@ -426,7 +449,6 @@ RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable) { isolate, NewTypeError(MessageTemplate::kNotConstructor, callsite)); } - RUNTIME_FUNCTION(Runtime_ThrowDerivedConstructorReturnedNonObject) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); @@ -434,17 +456,21 @@ RUNTIME_FUNCTION(Runtime_ThrowDerivedConstructorReturnedNonObject) { isolate, NewTypeError(MessageTemplate::kDerivedConstructorReturn)); } +RUNTIME_FUNCTION(Runtime_ThrowUndefinedOrNullToObject) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(String, name, 0); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject, name)); +} // ES6 section 7.3.17 CreateListFromArrayLike (obj) RUNTIME_FUNCTION(Runtime_CreateListFromArrayLike) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); - Handle<FixedArray> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, - Object::CreateListFromArrayLike(isolate, object, ElementTypes::kAll)); - return *result; + RETURN_RESULT_OR_FAILURE(isolate, Object::CreateListFromArrayLike( + isolate, object, ElementTypes::kAll)); } @@ -456,22 +482,90 @@ RUNTIME_FUNCTION(Runtime_IncrementUseCounter) { return isolate->heap()->undefined_value(); } -RUNTIME_FUNCTION(Runtime_GetOrdinaryHasInstance) { +RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) { HandleScope scope(isolate); - DCHECK_EQ(0, args.length()); + if (args.length() == 0) { + // Without arguments, the result is returned as a string. + DCHECK_EQ(0, args.length()); + std::stringstream stats_stream; + isolate->counters()->runtime_call_stats()->Print(stats_stream); + Handle<String> result = isolate->factory()->NewStringFromAsciiChecked( + stats_stream.str().c_str()); + isolate->counters()->runtime_call_stats()->Reset(); + return *result; + } else { + DCHECK_LE(args.length(), 2); + std::FILE* f; + if (args[0]->IsString()) { + // With a string argument, the results are appended to that file. + CONVERT_ARG_HANDLE_CHECKED(String, arg0, 0); + String::FlatContent flat = arg0->GetFlatContent(); + const char* filename = + reinterpret_cast<const char*>(&(flat.ToOneByteVector()[0])); + f = std::fopen(filename, "a"); + DCHECK_NOT_NULL(f); + } else { + // With an integer argument, the results are written to stdout/stderr. + CONVERT_SMI_ARG_CHECKED(fd, 0); + DCHECK(fd == 1 || fd == 2); + f = fd == 1 ? stdout : stderr; + } + // The second argument (if any) is a message header to be printed. + if (args.length() >= 2) { + CONVERT_ARG_HANDLE_CHECKED(String, arg1, 1); + arg1->PrintOn(f); + std::fputc('\n', f); + std::fflush(f); + } + OFStream stats_stream(f); + isolate->counters()->runtime_call_stats()->Print(stats_stream); + isolate->counters()->runtime_call_stats()->Reset(); + if (args[0]->IsString()) + std::fclose(f); + else + std::fflush(f); + return isolate->heap()->undefined_value(); + } +} - return isolate->native_context()->ordinary_has_instance(); +RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0); + isolate->EnqueueMicrotask(microtask); + return isolate->heap()->undefined_value(); } -RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) { +RUNTIME_FUNCTION(Runtime_RunMicrotasks) { HandleScope scope(isolate); - DCHECK_EQ(0, args.length()); - std::stringstream stats_stream; - isolate->counters()->runtime_call_stats()->Print(stats_stream); - Handle<String> result = - isolate->factory()->NewStringFromAsciiChecked(stats_stream.str().c_str()); - isolate->counters()->runtime_call_stats()->Reset(); - return *result; + DCHECK(args.length() == 0); + isolate->RunMicrotasks(); + return isolate->heap()->undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_OrdinaryHasInstance) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, callable, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, object, 1); + RETURN_RESULT_OR_FAILURE( + isolate, Object::OrdinaryHasInstance(isolate, callable, object)); +} + +RUNTIME_FUNCTION(Runtime_IsWasmObject) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_CHECKED(Object, object, 0); + bool is_wasm_object = + object->IsJSObject() && wasm::IsWasmObject(JSObject::cast(object)); + return *isolate->factory()->ToBoolean(is_wasm_object); +} + +RUNTIME_FUNCTION(Runtime_Typeof) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); + return *Object::TypeOf(isolate, object); } } // namespace internal |