Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index 5a443efc3d0fb9b0445b50cf50a22f9472da78f9..5cf64e417f373fef6d12768ad02c7fad199fd784 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -160,7 +160,8 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(JSObject* boilerplate) { |
| if (!maybe_result->ToObject(&result)) return maybe_result; |
| } |
| { MaybeObject* maybe_result = |
| - copy->SetProperty(key_string, result, NONE); |
| + // Creating object copy for literals. No strict mode needed. |
| + copy->SetProperty(key_string, result, NONE, kNonStrictMode); |
| if (!maybe_result->ToObject(&result)) return maybe_result; |
| } |
| } |
| @@ -546,7 +547,9 @@ static MaybeObject* Runtime_CreateCatchExtensionObject(Arguments args) { |
| // Assign the exception value to the catch variable and make sure |
| // that the catch variable is DontDelete. |
| { MaybeObject* maybe_value = |
| - JSObject::cast(object)->SetProperty(key, value, DONT_DELETE); |
| + // Passing non-strict per Ecma-262 5th Ed. 12.14. Catch, bullet #4. |
| + JSObject::cast(object)->SetProperty( |
| + key, value, DONT_DELETE, kNonStrictMode); |
| if (!maybe_value->ToObject(&value)) return maybe_value; |
| } |
| return object; |
| @@ -1109,7 +1112,12 @@ static MaybeObject* Runtime_DeclareGlobals(Arguments args) { |
| value, |
| attributes)); |
| } else { |
| - RETURN_IF_EMPTY_HANDLE(SetProperty(global, name, value, attributes)); |
| + // TODO(mmaly): Runtime_DeclareGlobals. Do we need strict? |
| + RETURN_IF_EMPTY_HANDLE(SetProperty(global, |
| + name, |
| + value, |
| + attributes, |
| + kNonStrictMode)); |
| } |
| } |
| @@ -1170,7 +1178,9 @@ static MaybeObject* Runtime_DeclareContextSlot(Arguments args) { |
| // Slow case: The property is not in the FixedArray part of the context. |
| Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); |
| RETURN_IF_EMPTY_HANDLE( |
| - SetProperty(context_ext, name, initial_value, mode)); |
| + // TODO(mmaly): Runtime_DeclareContextSlot. Need strict? |
| + SetProperty(context_ext, name, initial_value, |
| + mode, kNonStrictMode)); |
| } |
| } |
| @@ -1211,7 +1221,9 @@ static MaybeObject* Runtime_DeclareContextSlot(Arguments args) { |
| return ThrowRedeclarationError("const", name); |
| } |
| } |
| - RETURN_IF_EMPTY_HANDLE(SetProperty(context_ext, name, value, mode)); |
| + // TODO(mmaly): Runtime_DeclareContextSlot. Need strict? |
| + RETURN_IF_EMPTY_HANDLE(SetProperty(context_ext, name, value, mode, |
| + kNonStrictMode)); |
| } |
| return Heap::undefined_value(); |
| @@ -1284,7 +1296,9 @@ static MaybeObject* Runtime_InitializeVarGlobal(Arguments args) { |
| // Assign the value (or undefined) to the property. |
| Object* value = (assign) ? args[1] : Heap::undefined_value(); |
| - return real_holder->SetProperty(&lookup, *name, value, attributes); |
| + // TODO(mmaly): Runtime_InitializeVarGlobal. pass strict mode through? |
| + return real_holder->SetProperty(&lookup, *name, value, attributes, |
| + kNonStrictMode); |
| } |
| Object* proto = real_holder->GetPrototype(); |
| @@ -1298,7 +1312,10 @@ static MaybeObject* Runtime_InitializeVarGlobal(Arguments args) { |
| } |
| global = Top::context()->global(); |
| - if (assign) return global->SetProperty(*name, args[1], attributes); |
| + if (assign) { |
| + // TODO(mmaly): Runtime_InitializeVarGlobal. pass strict mode through? |
| + return global->SetProperty(*name, args[1], attributes, kNonStrictMode); |
| + } |
| return Heap::undefined_value(); |
| } |
| @@ -1357,7 +1374,12 @@ static MaybeObject* Runtime_InitializeConstGlobal(Arguments args) { |
| // BUG 1213575: Handle the case where we have to set a read-only |
| // property through an interceptor and only do it if it's |
| // uninitialized, e.g. the hole. Nirk... |
| - RETURN_IF_EMPTY_HANDLE(SetProperty(global, name, value, attributes)); |
| + // Passing non-strict mode because the property is writable. |
| + RETURN_IF_EMPTY_HANDLE(SetProperty(global, |
| + name, |
| + value, |
| + attributes, |
| + kNonStrictMode)); |
| return *value; |
| } |
| @@ -1371,14 +1393,17 @@ static MaybeObject* Runtime_InitializeConstGlobal(Arguments args) { |
| if (properties->get(index)->IsTheHole()) { |
| properties->set(index, *value); |
| } |
| + // TODO(mmaly): Runtime_InitializeConstGlobal. throw in strict mode? |
| } else if (type == NORMAL) { |
| if (global->GetNormalizedProperty(&lookup)->IsTheHole()) { |
| global->SetNormalizedProperty(&lookup, *value); |
| } |
| + // TODO(mmaly): Runtime_InitializeConstGlobal. throw in strict mode? |
| } else { |
| // Ignore re-initialization of constants that have already been |
| // assigned a function value. |
| ASSERT(lookup.IsReadOnly() && type == CONSTANT_FUNCTION); |
| + // TODO(mmaly): Runtime_InitializeConstGlobal. throw in strict mode? |
| } |
| // Use the set value as the result of the operation. |
| @@ -1439,7 +1464,10 @@ static MaybeObject* Runtime_InitializeConstContextSlot(Arguments args) { |
| // context. |
| if (attributes == ABSENT) { |
| Handle<JSObject> global = Handle<JSObject>(Top::context()->global()); |
| - RETURN_IF_EMPTY_HANDLE(SetProperty(global, name, value, NONE)); |
| + // TODO(mmaly): Runtime_InitializeConstContextSlot. Probably needs strict. |
| + // (introduces variable in global context) unless this is only called |
| + // from with which is disabled in strict mode. |
| + RETURN_IF_EMPTY_HANDLE(SetProperty(global, name, value, NONE, kNonStrictMode)); |
| return *value; |
| } |
| @@ -1476,8 +1504,11 @@ static MaybeObject* Runtime_InitializeConstContextSlot(Arguments args) { |
| // The property was found in a different context extension object. |
| // Set it if it is not a read-only property. |
| if ((attributes & READ_ONLY) == 0) { |
| + // TODO(mmaly): Runtime_InitializeConstContextSlot. Probably should throw |
| + // if strict mode and r/o property. Unless this is only called from |
| + // with which is disabled in strict mode. |
| RETURN_IF_EMPTY_HANDLE( |
| - SetProperty(context_ext, name, value, attributes)); |
| + SetProperty(context_ext, name, value, attributes, kNonStrictMode)); |
| } |
| } |
| @@ -1643,7 +1674,8 @@ static Handle<JSFunction> InstallBuiltin(Handle<JSObject> holder, |
| code, |
| false); |
| optimized->shared()->DontAdaptArguments(); |
| - SetProperty(holder, key, optimized, NONE); |
| + // No need for strict mode here. Called from SetupArray (array.js). |
| + SetProperty(holder, key, optimized, NONE, kNonStrictMode); |
| return optimized; |
| } |
| @@ -3739,7 +3771,8 @@ static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) { |
| MaybeObject* Runtime::SetObjectProperty(Handle<Object> object, |
| Handle<Object> key, |
| Handle<Object> value, |
| - PropertyAttributes attr) { |
| + PropertyAttributes attr, |
| + StrictModeFlag strict) { |
| HandleScope scope; |
| if (object->IsUndefined() || object->IsNull()) { |
| @@ -3769,6 +3802,7 @@ MaybeObject* Runtime::SetObjectProperty(Handle<Object> object, |
| return *value; |
| } |
| + // TODO(mmaly): SetElement strict mode. |
|
Martin Maly
2011/02/24 06:33:34
The big todo. SetElement currently does no strict
|
| Handle<Object> result = SetElement(js_object, index, value); |
| if (result.is_null()) return Failure::Exception(); |
| return *value; |
| @@ -3781,7 +3815,7 @@ MaybeObject* Runtime::SetObjectProperty(Handle<Object> object, |
| } else { |
| Handle<String> key_string = Handle<String>::cast(key); |
| key_string->TryFlatten(); |
| - result = SetProperty(js_object, key_string, value, attr); |
| + result = SetProperty(js_object, key_string, value, attr, strict); |
| } |
| if (result.is_null()) return Failure::Exception(); |
| return *value; |
| @@ -3794,9 +3828,10 @@ MaybeObject* Runtime::SetObjectProperty(Handle<Object> object, |
| Handle<String> name = Handle<String>::cast(converted); |
| if (name->AsArrayIndex(&index)) { |
| + // TODO(mmaly): Strict mode handling in SetElement. |
| return js_object->SetElement(index, *value); |
| } else { |
| - return js_object->SetProperty(*name, *value, attr); |
| + return js_object->SetProperty(*name, *value, attr, strict); |
| } |
| } |
| @@ -3888,23 +3923,27 @@ MaybeObject* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object, |
| static MaybeObject* Runtime_SetProperty(Arguments args) { |
| NoHandleAllocation ha; |
| - RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); |
| + RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); |
| Handle<Object> object = args.at<Object>(0); |
| Handle<Object> key = args.at<Object>(1); |
| Handle<Object> value = args.at<Object>(2); |
| - |
| + CONVERT_SMI_CHECKED(unchecked_attributes, args[3]); |
| + RUNTIME_ASSERT( |
| + (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| // Compute attributes. |
| - PropertyAttributes attributes = NONE; |
| - if (args.length() == 4) { |
| - CONVERT_CHECKED(Smi, value_obj, args[3]); |
| - int unchecked_value = value_obj->value(); |
| - // Only attribute bits should be set. |
| - RUNTIME_ASSERT( |
| - (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| - attributes = static_cast<PropertyAttributes>(unchecked_value); |
| + PropertyAttributes attributes = |
| + static_cast<PropertyAttributes>(unchecked_attributes); |
| + |
| + StrictModeFlag strict = kNonStrictMode; |
| + if (args.length() == 5) { |
| + CONVERT_SMI_CHECKED(strict_unchecked, args[4]); |
| + RUNTIME_ASSERT(strict_unchecked == kStrictMode || |
| + strict_unchecked == kNonStrictMode); |
| + strict = static_cast<StrictModeFlag>(strict_unchecked); |
| } |
| - return Runtime::SetObjectProperty(object, key, value, attributes); |
| + |
| + return Runtime::SetObjectProperty(object, key, value, attributes, strict); |
| } |
| @@ -7482,11 +7521,16 @@ static ObjectPair Runtime_LoadContextSlotNoReferenceError(Arguments args) { |
| static MaybeObject* Runtime_StoreContextSlot(Arguments args) { |
| HandleScope scope; |
| - ASSERT(args.length() == 3); |
| + ASSERT(args.length() == 4); |
| Handle<Object> value(args[0]); |
| CONVERT_ARG_CHECKED(Context, context, 1); |
| CONVERT_ARG_CHECKED(String, name, 2); |
| + CONVERT_SMI_CHECKED(strict_unchecked, args[3]); |
| + RUNTIME_ASSERT(strict_unchecked == kStrictMode || |
| + strict_unchecked == kNonStrictMode); |
| + StrictModeFlag strict = static_cast<StrictModeFlag>(strict_unchecked); |
| + |
| int index; |
| PropertyAttributes attributes; |
| @@ -7530,7 +7574,12 @@ static MaybeObject* Runtime_StoreContextSlot(Arguments args) { |
| // extension object itself. |
| if ((attributes & READ_ONLY) == 0 || |
| (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) { |
| - RETURN_IF_EMPTY_HANDLE(SetProperty(context_ext, name, value, NONE)); |
| + RETURN_IF_EMPTY_HANDLE(SetProperty(context_ext, name, value, NONE, strict)); |
| + } else if (strict == kStrictMode && (attributes & READ_ONLY) != 0) { |
| + // Setting read only property in strict mode. |
| + Handle<Object> error = |
| + Factory::NewTypeError("strict_cannot_assign", HandleVector(&name, 1)); |
| + return Top::Throw(*error); |
| } |
| return *value; |
| } |
| @@ -9192,7 +9241,9 @@ static bool CopyContextLocalsToScopeObject( |
| RETURN_IF_EMPTY_HANDLE_VALUE( |
| SetProperty(scope_object, |
| scope_info.context_slot_name(i), |
| - Handle<Object>(context->get(context_index)), NONE), |
| + Handle<Object>(context->get(context_index)), |
| + NONE, |
| + kNonStrictMode), |
| false); |
| } |
| } |
| @@ -9218,7 +9269,9 @@ static Handle<JSObject> MaterializeLocalScope(JavaScriptFrame* frame) { |
| RETURN_IF_EMPTY_HANDLE_VALUE( |
| SetProperty(local_scope, |
| scope_info.parameter_name(i), |
| - Handle<Object>(frame->GetParameter(i)), NONE), |
| + Handle<Object>(frame->GetParameter(i)), |
| + NONE, |
| + kNonStrictMode), |
| Handle<JSObject>()); |
| } |
| @@ -9227,7 +9280,9 @@ static Handle<JSObject> MaterializeLocalScope(JavaScriptFrame* frame) { |
| RETURN_IF_EMPTY_HANDLE_VALUE( |
| SetProperty(local_scope, |
| scope_info.stack_slot_name(i), |
| - Handle<Object>(frame->GetExpression(i)), NONE), |
| + Handle<Object>(frame->GetExpression(i)), |
| + NONE, |
| + kNonStrictMode), |
| Handle<JSObject>()); |
| } |
| @@ -9251,7 +9306,11 @@ static Handle<JSObject> MaterializeLocalScope(JavaScriptFrame* frame) { |
| ASSERT(keys->get(i)->IsString()); |
| Handle<String> key(String::cast(keys->get(i))); |
| RETURN_IF_EMPTY_HANDLE_VALUE( |
| - SetProperty(local_scope, key, GetProperty(ext, key), NONE), |
| + SetProperty(local_scope, |
| + key, |
| + GetProperty(ext, key), |
| + NONE, |
| + kNonStrictMode), |
| Handle<JSObject>()); |
| } |
| } |
| @@ -9289,7 +9348,8 @@ static Handle<JSObject> MaterializeClosure(Handle<Context> context) { |
| SetProperty(closure_scope, |
| scope_info.parameter_name(i), |
| Handle<Object>(element), |
| - NONE), |
| + NONE, |
| + kNonStrictMode), |
| Handle<JSObject>()); |
| } |
| } |
| @@ -9310,7 +9370,7 @@ static Handle<JSObject> MaterializeClosure(Handle<Context> context) { |
| ASSERT(keys->get(i)->IsString()); |
| Handle<String> key(String::cast(keys->get(i))); |
| RETURN_IF_EMPTY_HANDLE_VALUE( |
| - SetProperty(closure_scope, key, GetProperty(ext, key), NONE), |
| + SetProperty(closure_scope, key, GetProperty(ext, key), NONE, kNonStrictMode), |
| Handle<JSObject>()); |
| } |
| } |