// Copyright 2014 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 #include #include "src/v8.h" #include "src/arguments.h" #include "src/debug.h" #include "src/messages.h" #include "src/runtime/runtime.h" #include "src/runtime/runtime-utils.h" namespace v8 { namespace internal { RUNTIME_FUNCTION(Runtime_ThrowNonMethodError) { HandleScope scope(isolate); DCHECK(args.length() == 0); THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewReferenceError(MessageTemplate::kNonMethod)); } RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) { HandleScope scope(isolate); DCHECK(args.length() == 0); THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewReferenceError(MessageTemplate::kUnsupportedSuper)); } RUNTIME_FUNCTION(Runtime_ThrowConstructorNonCallableError) { HandleScope scope(isolate); DCHECK(args.length() == 0); THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kConstructorNonCallable)); } RUNTIME_FUNCTION(Runtime_ThrowArrayNotSubclassableError) { HandleScope scope(isolate); DCHECK(args.length() == 0); THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kArrayNotSubclassable)); } static Object* ThrowStaticPrototypeError(Isolate* isolate) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError("static_prototype", HandleVector(NULL, 0))); } RUNTIME_FUNCTION(Runtime_ThrowStaticPrototypeError) { HandleScope scope(isolate); DCHECK(args.length() == 0); return ThrowStaticPrototypeError(isolate); } RUNTIME_FUNCTION(Runtime_ThrowIfStaticPrototype) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(Name, name, 0); if (Name::Equals(name, isolate->factory()->prototype_string())) { return ThrowStaticPrototypeError(isolate); } return *name; } RUNTIME_FUNCTION(Runtime_ToMethod) { HandleScope scope(isolate); DCHECK(args.length() == 2); CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); Handle clone = JSFunction::CloneClosure(fun); Handle home_object_symbol(isolate->heap()->home_object_symbol()); JSObject::SetOwnPropertyIgnoreAttributes(clone, home_object_symbol, home_object, DONT_ENUM).Assert(); return *clone; } RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) { DCHECK(args.length() == 0); return isolate->heap()->home_object_symbol(); } RUNTIME_FUNCTION(Runtime_DefineClass) { HandleScope scope(isolate); DCHECK(args.length() == 6); CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 1); CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 2); CONVERT_ARG_HANDLE_CHECKED(Script, script, 3); CONVERT_SMI_ARG_CHECKED(start_position, 4); CONVERT_SMI_ARG_CHECKED(end_position, 5); Handle prototype_parent; Handle constructor_parent; if (super_class->IsTheHole()) { prototype_parent = isolate->initial_object_prototype(); } else { if (super_class->IsNull()) { prototype_parent = isolate->factory()->null_value(); } else if (super_class->IsSpecFunction()) { if (Handle::cast(super_class)->shared()->is_generator()) { Handle args[1] = {super_class}; THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError("extends_value_generator", HandleVector(args, 1))); } ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, prototype_parent, Runtime::GetObjectProperty(isolate, super_class, isolate->factory()->prototype_string())); if (!prototype_parent->IsNull() && !prototype_parent->IsSpecObject()) { Handle args[1] = {prototype_parent}; THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError("prototype_parent_not_an_object", HandleVector(args, 1))); } constructor_parent = super_class; } else { // TODO(arv): Should be IsConstructor. Handle args[1] = {super_class}; THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError("extends_value_not_a_function", HandleVector(args, 1))); } } Handle map = isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); Map::SetPrototype(map, prototype_parent); map->SetConstructor(*constructor); Handle prototype = isolate->factory()->NewJSObjectFromMap(map); Handle name_string = name->IsString() ? Handle::cast(name) : isolate->factory()->empty_string(); constructor->shared()->set_name(*name_string); if (!super_class->IsTheHole()) { Handle stub(isolate->builtins()->JSConstructStubForDerived()); constructor->shared()->set_construct_stub(*stub); } JSFunction::SetPrototype(constructor, prototype); PropertyAttributes attribs = static_cast(DONT_ENUM | DONT_DELETE | READ_ONLY); RETURN_FAILURE_ON_EXCEPTION( isolate, JSObject::SetOwnPropertyIgnoreAttributes( constructor, isolate->factory()->prototype_string(), prototype, attribs)); // TODO(arv): Only do this conditionally. Handle home_object_symbol(isolate->heap()->home_object_symbol()); RETURN_FAILURE_ON_EXCEPTION( isolate, JSObject::SetOwnPropertyIgnoreAttributes( constructor, home_object_symbol, prototype, DONT_ENUM)); if (!constructor_parent.is_null()) { RETURN_FAILURE_ON_EXCEPTION( isolate, JSObject::SetPrototype(constructor, constructor_parent, false)); } JSObject::AddProperty(prototype, isolate->factory()->constructor_string(), constructor, DONT_ENUM); // Install private properties that are used to construct the FunctionToString. RETURN_FAILURE_ON_EXCEPTION( isolate, Object::SetProperty(constructor, isolate->factory()->class_script_symbol(), script, STRICT)); RETURN_FAILURE_ON_EXCEPTION( isolate, Object::SetProperty( constructor, isolate->factory()->class_start_position_symbol(), handle(Smi::FromInt(start_position), isolate), STRICT)); RETURN_FAILURE_ON_EXCEPTION( isolate, Object::SetProperty( constructor, isolate->factory()->class_end_position_symbol(), handle(Smi::FromInt(end_position), isolate), STRICT)); return *constructor; } RUNTIME_FUNCTION(Runtime_DefineClassMethod) { HandleScope scope(isolate); DCHECK(args.length() == 3); CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 2); uint32_t index; if (name->AsArrayIndex(&index)) { RETURN_FAILURE_ON_EXCEPTION( isolate, JSObject::SetOwnElement(object, index, function, DONT_ENUM, STRICT)); } else { RETURN_FAILURE_ON_EXCEPTION( isolate, JSObject::SetOwnPropertyIgnoreAttributes(object, name, function, DONT_ENUM)); } return isolate->heap()->undefined_value(); } RUNTIME_FUNCTION(Runtime_ClassGetSourceCode) { HandleScope shs(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); Handle script; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, script, Object::GetProperty(fun, isolate->factory()->class_script_symbol())); if (!script->IsScript()) { return isolate->heap()->undefined_value(); } Handle start_position_symbol( isolate->heap()->class_start_position_symbol()); Handle start_position; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, start_position, Object::GetProperty(fun, start_position_symbol)); Handle end_position_symbol( isolate->heap()->class_end_position_symbol()); Handle end_position; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, end_position, Object::GetProperty(fun, end_position_symbol)); if (!start_position->IsSmi() || !end_position->IsSmi() || !Handle