diff options
Diffstat (limited to 'deps/v8/src/runtime/runtime-scopes.cc')
-rw-r--r-- | deps/v8/src/runtime/runtime-scopes.cc | 456 |
1 files changed, 170 insertions, 286 deletions
diff --git a/deps/v8/src/runtime/runtime-scopes.cc b/deps/v8/src/runtime/runtime-scopes.cc index 094f1a10ed..a8f3a74918 100644 --- a/deps/v8/src/runtime/runtime-scopes.cc +++ b/deps/v8/src/runtime/runtime-scopes.cc @@ -65,21 +65,27 @@ static Object* DeclareGlobals(Isolate* isolate, Handle<JSGlobalObject> global, // Check whether we can reconfigure the existing property into a // function. PropertyDetails old_details = it.property_details(); - // TODO(verwaest): ACCESSOR_CONSTANT invalidly includes - // ExecutableAccessInfo, - // which are actually data properties, not accessor properties. if (old_details.IsReadOnly() || old_details.IsDontEnum() || - old_details.type() == ACCESSOR_CONSTANT) { + (it.state() == LookupIterator::ACCESSOR && + it.GetAccessors()->IsAccessorPair())) { return ThrowRedeclarationError(isolate, name); } // If the existing property is not configurable, keep its attributes. Do attr = old_attributes; } + + // If the current state is ACCESSOR, this could mean it's an AccessorInfo + // type property. We are not allowed to call into such setters during global + // function declaration since this would break e.g., onload. Meaning + // 'function onload() {}' would invalidly register that function as the + // onload callback. To avoid this situation, we first delete the property + // before readding it as a regular data property below. + if (it.state() == LookupIterator::ACCESSOR) it.Delete(); } // Define or redefine own property. - RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( - global, name, value, attr)); + RETURN_FAILURE_ON_EXCEPTION( + isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr)); return isolate->heap()->undefined_value(); } @@ -196,8 +202,8 @@ RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) { } } - RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( - global, name, value, attr)); + RETURN_FAILURE_ON_EXCEPTION( + isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr)); return *value; } @@ -414,10 +420,8 @@ RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) { namespace { // Find the arguments of the JavaScript function invocation that called -// into C++ code. Collect these in a newly allocated array of handles (possibly -// prefixed by a number of empty handles). +// into C++ code. Collect these in a newly allocated array of handles. base::SmartArrayPointer<Handle<Object>> GetCallerArguments(Isolate* isolate, - int prefix_argc, int* total_argc) { // Find frame containing arguments passed to the caller. JavaScriptFrameIterator it(isolate); @@ -442,14 +446,14 @@ base::SmartArrayPointer<Handle<Object>> GetCallerArguments(Isolate* isolate, iter++; argument_count--; - *total_argc = prefix_argc + argument_count; + *total_argc = argument_count; base::SmartArrayPointer<Handle<Object>> param_data( NewArray<Handle<Object>>(*total_argc)); bool should_deoptimize = false; for (int i = 0; i < argument_count; i++) { should_deoptimize = should_deoptimize || iter->IsMaterializedObject(); Handle<Object> value = iter->GetValue(); - param_data[prefix_argc + i] = value; + param_data[i] = value; iter++; } @@ -463,12 +467,12 @@ base::SmartArrayPointer<Handle<Object>> GetCallerArguments(Isolate* isolate, frame = it.frame(); int args_count = frame->ComputeParametersCount(); - *total_argc = prefix_argc + args_count; + *total_argc = args_count; base::SmartArrayPointer<Handle<Object>> param_data( NewArray<Handle<Object>>(*total_argc)); for (int i = 0; i < args_count; i++) { Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate); - param_data[prefix_argc + i] = val; + param_data[i] = val; } return param_data; } @@ -564,46 +568,6 @@ Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee, } -template <typename T> -Handle<JSObject> NewStrictArguments(Isolate* isolate, Handle<JSFunction> callee, - T parameters, int argument_count) { - Handle<JSObject> result = - isolate->factory()->NewArgumentsObject(callee, argument_count); - - if (argument_count > 0) { - Handle<FixedArray> array = - isolate->factory()->NewUninitializedFixedArray(argument_count); - DisallowHeapAllocation no_gc; - WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); - for (int i = 0; i < argument_count; i++) { - array->set(i, parameters[i], mode); - } - result->set_elements(*array); - } - return result; -} - - -template <typename T> -Handle<JSObject> NewRestArguments(Isolate* isolate, Handle<JSFunction> callee, - T parameters, int argument_count, - int start_index) { - int num_elements = std::max(0, argument_count - start_index); - Handle<JSObject> result = isolate->factory()->NewJSArray( - FAST_ELEMENTS, num_elements, num_elements, Strength::WEAK, - DONT_INITIALIZE_ARRAY_ELEMENTS); - { - DisallowHeapAllocation no_gc; - FixedArray* elements = FixedArray::cast(result->elements()); - WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); - for (int i = 0; i < num_elements; i++) { - elements->set(i, parameters[i + start_index], mode); - } - } - return result; -} - - class HandleArguments BASE_EMBEDDED { public: explicit HandleArguments(Handle<Object>* array) : array_(array) {} @@ -634,39 +598,60 @@ RUNTIME_FUNCTION(Runtime_NewSloppyArguments_Generic) { // inlined, we use the slow but accurate {GetCallerArguments}. int argument_count = 0; base::SmartArrayPointer<Handle<Object>> arguments = - GetCallerArguments(isolate, 0, &argument_count); + GetCallerArguments(isolate, &argument_count); HandleArguments argument_getter(arguments.get()); return *NewSloppyArguments(isolate, callee, argument_getter, argument_count); } -RUNTIME_FUNCTION(Runtime_NewStrictArguments_Generic) { +RUNTIME_FUNCTION(Runtime_NewStrictArguments) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); // This generic runtime function can also be used when the caller has been // inlined, we use the slow but accurate {GetCallerArguments}. int argument_count = 0; base::SmartArrayPointer<Handle<Object>> arguments = - GetCallerArguments(isolate, 0, &argument_count); - HandleArguments argument_getter(arguments.get()); - return *NewStrictArguments(isolate, callee, argument_getter, argument_count); + GetCallerArguments(isolate, &argument_count); + Handle<JSObject> result = + isolate->factory()->NewArgumentsObject(callee, argument_count); + if (argument_count) { + Handle<FixedArray> array = + isolate->factory()->NewUninitializedFixedArray(argument_count); + DisallowHeapAllocation no_gc; + WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); + for (int i = 0; i < argument_count; i++) { + array->set(i, *arguments[i], mode); + } + result->set_elements(*array); + } + return *result; } -RUNTIME_FUNCTION(Runtime_NewRestArguments_Generic) { +RUNTIME_FUNCTION(Runtime_NewRestParameter) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0) - CONVERT_SMI_ARG_CHECKED(start_index, 1); + int start_index = callee->shared()->internal_formal_parameter_count(); // This generic runtime function can also be used when the caller has been // inlined, we use the slow but accurate {GetCallerArguments}. int argument_count = 0; base::SmartArrayPointer<Handle<Object>> arguments = - GetCallerArguments(isolate, 0, &argument_count); - HandleArguments argument_getter(arguments.get()); - return *NewRestArguments(isolate, callee, argument_getter, argument_count, - start_index); + GetCallerArguments(isolate, &argument_count); + int num_elements = std::max(0, argument_count - start_index); + Handle<JSObject> result = isolate->factory()->NewJSArray( + FAST_ELEMENTS, num_elements, num_elements, Strength::WEAK, + DONT_INITIALIZE_ARRAY_ELEMENTS); + { + DisallowHeapAllocation no_gc; + FixedArray* elements = FixedArray::cast(result->elements()); + WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); + for (int i = 0; i < num_elements; i++) { + elements->set(i, *arguments[i + start_index], mode); + } + } + return *result; } @@ -687,42 +672,6 @@ RUNTIME_FUNCTION(Runtime_NewSloppyArguments) { } -RUNTIME_FUNCTION(Runtime_NewStrictArguments) { - HandleScope scope(isolate); - DCHECK(args.length() == 3); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0) - Object** parameters = reinterpret_cast<Object**>(args[1]); - CONVERT_SMI_ARG_CHECKED(argument_count, 2); -#ifdef DEBUG - // This runtime function does not materialize the correct arguments when the - // caller has been inlined, better make sure we are not hitting that case. - JavaScriptFrameIterator it(isolate); - DCHECK(!it.frame()->HasInlinedFrames()); -#endif // DEBUG - ParameterArguments argument_getter(parameters); - return *NewStrictArguments(isolate, callee, argument_getter, argument_count); -} - - -RUNTIME_FUNCTION(Runtime_NewRestParam) { - HandleScope scope(isolate); - DCHECK(args.length() == 3); - CONVERT_SMI_ARG_CHECKED(num_params, 0); - Object** parameters = reinterpret_cast<Object**>(args[1]); - CONVERT_SMI_ARG_CHECKED(rest_index, 2); -#ifdef DEBUG - // This runtime function does not materialize the correct arguments when the - // caller has been inlined, better make sure we are not hitting that case. - JavaScriptFrameIterator it(isolate); - DCHECK(!it.frame()->HasInlinedFrames()); -#endif // DEBUG - Handle<JSFunction> callee; - ParameterArguments argument_getter(parameters); - return *NewRestArguments(isolate, callee, argument_getter, num_params, - rest_index); -} - - RUNTIME_FUNCTION(Runtime_NewClosure) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -957,17 +906,14 @@ RUNTIME_FUNCTION(Runtime_DeclareModules) { RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) { HandleScope scope(isolate); - DCHECK(args.length() == 2); - - CONVERT_ARG_HANDLE_CHECKED(Context, context, 0); - CONVERT_ARG_HANDLE_CHECKED(String, name, 1); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(String, name, 0); int index; PropertyAttributes attributes; - ContextLookupFlags flags = FOLLOW_CHAINS; - BindingFlags binding_flags; - Handle<Object> holder = - context->Lookup(name, flags, &index, &attributes, &binding_flags); + BindingFlags flags; + Handle<Object> holder = isolate->context()->Lookup( + name, FOLLOW_CHAINS, &index, &attributes, &flags); // If the slot was not found the result is true. if (holder.is_null()) { @@ -991,161 +937,158 @@ RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) { } -static Object* ComputeReceiverForNonGlobal(Isolate* isolate, JSObject* holder) { - DCHECK(!holder->IsJSGlobalObject()); - - // If the holder isn't a context extension object, we just return it - // as the receiver. This allows arguments objects to be used as - // receivers, but only if they are put in the context scope chain - // explicitly via a with-statement. - if (holder->map()->instance_type() != JS_CONTEXT_EXTENSION_OBJECT_TYPE) { - return holder; - } - // Fall back to using the global object as the implicit receiver if - // the property turns out to be a local variable allocated in a - // context extension object - introduced via eval. - return isolate->heap()->undefined_value(); -} - - -static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate, - bool throw_error) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); +namespace { - if (!args[0]->IsContext() || !args[1]->IsString()) { - return MakePair(isolate->ThrowIllegalOperation(), NULL); - } - Handle<Context> context = args.at<Context>(0); - Handle<String> name = args.at<String>(1); +MaybeHandle<Object> LoadLookupSlot(Handle<String> name, + Object::ShouldThrow should_throw, + Handle<Object>* receiver_return = nullptr) { + Isolate* const isolate = name->GetIsolate(); int index; PropertyAttributes attributes; - ContextLookupFlags flags = FOLLOW_CHAINS; - BindingFlags binding_flags; - Handle<Object> holder = - context->Lookup(name, flags, &index, &attributes, &binding_flags); - if (isolate->has_pending_exception()) { - return MakePair(isolate->heap()->exception(), NULL); - } + BindingFlags flags; + Handle<Object> holder = isolate->context()->Lookup( + name, FOLLOW_CHAINS, &index, &attributes, &flags); + if (isolate->has_pending_exception()) return MaybeHandle<Object>(); if (index != Context::kNotFound) { DCHECK(holder->IsContext()); // If the "property" we were looking for is a local variable, the // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3. Handle<Object> receiver = isolate->factory()->undefined_value(); - Object* value = Context::cast(*holder)->get(index); + Handle<Object> value = handle(Context::cast(*holder)->get(index), isolate); // Check for uninitialized bindings. - switch (binding_flags) { + switch (flags) { case MUTABLE_CHECK_INITIALIZED: case IMMUTABLE_CHECK_INITIALIZED_HARMONY: if (value->IsTheHole()) { - Handle<Object> error = isolate->factory()->NewReferenceError( - MessageTemplate::kNotDefined, name); - isolate->Throw(*error); - return MakePair(isolate->heap()->exception(), NULL); + THROW_NEW_ERROR(isolate, + NewReferenceError(MessageTemplate::kNotDefined, name), + Object); + } + // FALLTHROUGH + case IMMUTABLE_CHECK_INITIALIZED: + if (value->IsTheHole()) { + DCHECK(attributes & READ_ONLY); + value = isolate->factory()->undefined_value(); } // FALLTHROUGH case MUTABLE_IS_INITIALIZED: case IMMUTABLE_IS_INITIALIZED: case IMMUTABLE_IS_INITIALIZED_HARMONY: DCHECK(!value->IsTheHole()); - return MakePair(value, *receiver); - case IMMUTABLE_CHECK_INITIALIZED: - if (value->IsTheHole()) { - DCHECK((attributes & READ_ONLY) != 0); - value = isolate->heap()->undefined_value(); - } - return MakePair(value, *receiver); + if (receiver_return) *receiver_return = receiver; + return value; case MISSING_BINDING: - UNREACHABLE(); - return MakePair(NULL, NULL); + break; } + UNREACHABLE(); } // Otherwise, if the slot was found the holder is a context extension // object, subject of a with, or a global object. We read the named // property from it. if (!holder.is_null()) { - Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); - // GetProperty below can cause GC. - Handle<Object> receiver_handle( - object->IsJSGlobalObject() - ? Object::cast(isolate->heap()->undefined_value()) - : object->IsJSProxy() ? static_cast<Object*>(*object) - : ComputeReceiverForNonGlobal( - isolate, JSObject::cast(*object)), - isolate); - // No need to unhole the value here. This is taken care of by the // GetProperty function. Handle<Object> value; - ASSIGN_RETURN_ON_EXCEPTION_VALUE( - isolate, value, Object::GetProperty(object, name), - MakePair(isolate->heap()->exception(), NULL)); - return MakePair(*value, *receiver_handle); + ASSIGN_RETURN_ON_EXCEPTION( + isolate, value, Object::GetProperty(holder, name), + Object); + if (receiver_return) { + *receiver_return = + (holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()) + ? Handle<Object>::cast(isolate->factory()->undefined_value()) + : holder; + } + return value; } - if (throw_error) { + if (should_throw == Object::THROW_ON_ERROR) { // The property doesn't exist - throw exception. - Handle<Object> error = isolate->factory()->NewReferenceError( - MessageTemplate::kNotDefined, name); - isolate->Throw(*error); - return MakePair(isolate->heap()->exception(), NULL); - } else { - // The property doesn't exist - return undefined. - return MakePair(isolate->heap()->undefined_value(), - isolate->heap()->undefined_value()); + THROW_NEW_ERROR( + isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object); } + + // The property doesn't exist - return undefined. + if (receiver_return) *receiver_return = isolate->factory()->undefined_value(); + return isolate->factory()->undefined_value(); } +} // namespace -RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlot) { - return LoadLookupSlotHelper(args, isolate, true); + +RUNTIME_FUNCTION(Runtime_LoadLookupSlot) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(String, name, 0); + Handle<Object> value; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, value, LoadLookupSlot(name, Object::THROW_ON_ERROR)); + return *value; } -RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotNoReferenceError) { - return LoadLookupSlotHelper(args, isolate, false); +RUNTIME_FUNCTION(Runtime_LoadLookupSlotInsideTypeof) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(String, name, 0); + Handle<Object> value; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, value, LoadLookupSlot(name, Object::DONT_THROW)); + return *value; } -RUNTIME_FUNCTION(Runtime_StoreLookupSlot) { +RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotForCall) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(1, args.length()); + DCHECK(args[0]->IsString()); + Handle<String> name = args.at<String>(0); + Handle<Object> value; + Handle<Object> receiver; + ASSIGN_RETURN_ON_EXCEPTION_VALUE( + isolate, value, LoadLookupSlot(name, Object::THROW_ON_ERROR, &receiver), + MakePair(isolate->heap()->exception(), nullptr)); + return MakePair(*value, *receiver); +} - CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); - CONVERT_ARG_HANDLE_CHECKED(Context, context, 1); - CONVERT_ARG_HANDLE_CHECKED(String, name, 2); - CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3); + +namespace { + +MaybeHandle<Object> StoreLookupSlot(Handle<String> name, Handle<Object> value, + LanguageMode language_mode) { + Isolate* const isolate = name->GetIsolate(); + Handle<Context> context(isolate->context(), isolate); int index; PropertyAttributes attributes; - ContextLookupFlags flags = FOLLOW_CHAINS; - BindingFlags binding_flags; + BindingFlags flags; Handle<Object> holder = - context->Lookup(name, flags, &index, &attributes, &binding_flags); + context->Lookup(name, FOLLOW_CHAINS, &index, &attributes, &flags); if (holder.is_null()) { // In case of JSProxy, an exception might have been thrown. - if (isolate->has_pending_exception()) return isolate->heap()->exception(); + if (isolate->has_pending_exception()) return MaybeHandle<Object>(); } // The property was found in a context slot. if (index != Context::kNotFound) { - if ((binding_flags == MUTABLE_CHECK_INITIALIZED || - binding_flags == IMMUTABLE_CHECK_INITIALIZED_HARMONY) && + if ((flags == MUTABLE_CHECK_INITIALIZED || + flags == IMMUTABLE_CHECK_INITIALIZED_HARMONY) && Handle<Context>::cast(holder)->is_the_hole(index)) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewReferenceError(MessageTemplate::kNotDefined, name)); + THROW_NEW_ERROR(isolate, + NewReferenceError(MessageTemplate::kNotDefined, name), + Object); } if ((attributes & READ_ONLY) == 0) { Handle<Context>::cast(holder)->set(index, *value); } else if (is_strict(language_mode)) { // Setting read only property in strict mode. - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kStrictCannotAssign, name)); + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrictCannotAssign, name), + Object); } - return *value; + return value; } // Slow case: The property is not in a context slot. It is either in a @@ -1157,101 +1100,42 @@ RUNTIME_FUNCTION(Runtime_StoreLookupSlot) { object = Handle<JSReceiver>::cast(holder); } else if (is_strict(language_mode)) { // If absent in strict mode: throw. - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewReferenceError(MessageTemplate::kNotDefined, name)); + THROW_NEW_ERROR( + isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object); } else { // If absent in sloppy mode: add the property to the global object. object = Handle<JSReceiver>(context->global_object()); } - RETURN_FAILURE_ON_EXCEPTION( - isolate, Object::SetProperty(object, name, value, language_mode)); - - return *value; + ASSIGN_RETURN_ON_EXCEPTION( + isolate, value, Object::SetProperty(object, name, value, language_mode), + Object); + return value; } +} // namespace + -RUNTIME_FUNCTION(Runtime_ArgumentsLength) { +RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Sloppy) { HandleScope scope(isolate); - DCHECK(args.length() == 0); - int argument_count = 0; - GetCallerArguments(isolate, 0, &argument_count); - return Smi::FromInt(argument_count); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(String, name, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, + StoreLookupSlot(name, value, SLOPPY)); + return *value; } -RUNTIME_FUNCTION(Runtime_Arguments) { +RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { HandleScope scope(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0); - - // Determine the actual arguments passed to the function. - int argument_count_signed = 0; - base::SmartArrayPointer<Handle<Object>> arguments = - GetCallerArguments(isolate, 0, &argument_count_signed); - const uint32_t argument_count = argument_count_signed; - - // Try to convert the key to an index. If successful and within - // index return the the argument from the frame. - uint32_t index = 0; - if (raw_key->ToArrayIndex(&index) && index < argument_count) { - return *arguments[index]; - } - - if (raw_key->IsSymbol()) { - Handle<Symbol> symbol = Handle<Symbol>::cast(raw_key); - if (Name::Equals(symbol, isolate->factory()->iterator_symbol())) { - return isolate->native_context()->array_values_iterator(); - } - // Lookup in the initial Object.prototype object. - Handle<Object> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, - Object::GetProperty(isolate->initial_object_prototype(), - Handle<Symbol>::cast(raw_key))); - return *result; - } - - // Convert the key to a string. - Handle<Object> converted; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, converted, - Object::ToString(isolate, raw_key)); - Handle<String> key = Handle<String>::cast(converted); - - // Try to convert the string key into an array index. - if (key->AsArrayIndex(&index)) { - if (index < argument_count) { - return *arguments[index]; - } else { - Handle<Object> initial_prototype(isolate->initial_object_prototype()); - Handle<Object> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, - Object::GetElement(isolate, initial_prototype, index)); - return *result; - } - } - - // Handle special arguments properties. - if (String::Equals(isolate->factory()->length_string(), key)) { - return Smi::FromInt(argument_count); - } - if (String::Equals(isolate->factory()->callee_string(), key)) { - JavaScriptFrameIterator it(isolate); - JSFunction* function = it.frame()->function(); - if (is_strict(function->shared()->language_mode())) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kStrictPoisonPill)); - } - return function; - } - - // Lookup in the initial Object.prototype object. - Handle<Object> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, - Object::GetProperty(isolate->initial_object_prototype(), key)); - return *result; + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(String, name, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, + StoreLookupSlot(name, value, STRICT)); + return *value; } + } // namespace internal } // namespace v8 |