Chromium Code Reviews| Index: src/runtime.cc |
| diff --git a/src/runtime.cc b/src/runtime.cc |
| index 07987e2e39e271da31ce4b88346de252736167f3..4345052058caf00bec8d2d9d31940e3e9200e1fc 100644 |
| --- a/src/runtime.cc |
| +++ b/src/runtime.cc |
| @@ -200,6 +200,14 @@ static Handle<Map> ComputeObjectLiteralMap( |
| } |
| +MUST_USE_RESULT static MaybeHandle<Object> DefineOrRedefineDataProperty( |
| + Isolate* isolate, |
| + Handle<JSObject> object, |
| + Handle<Name> name, |
| + Handle<Object> value, |
| + PropertyAttributes attr); |
| + |
| + |
| MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( |
| Isolate* isolate, |
| Handle<FixedArray> literals, |
| @@ -5169,28 +5177,12 @@ RUNTIME_FUNCTION(Runtime_DefineOrRedefineAccessorProperty) { |
| } |
| -// Implements part of 8.12.9 DefineOwnProperty. |
| -// There are 3 cases that lead here: |
| -// Step 4a - define a new data property. |
| -// Steps 9b & 12 - replace an existing accessor property with a data property. |
| -// Step 12 - update an existing data property with a data or generic |
| -// descriptor. |
| -RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) { |
| - HandleScope scope(isolate); |
| - ASSERT(args.length() == 4); |
| - CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); |
| - CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
| - CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); |
| - CONVERT_SMI_ARG_CHECKED(unchecked, 3); |
| - RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| - PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
| - |
| - // Check access rights if needed. |
| - if (js_object->IsAccessCheckNeeded() && |
| - !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) { |
| - return isolate->heap()->undefined_value(); |
| - } |
| - |
| +static MaybeHandle<Object> DefineOrRedefineDataProperty( |
| + Isolate* isolate, |
| + Handle<JSObject> js_object, |
| + Handle<Name> name, |
| + Handle<Object> obj_value, |
| + PropertyAttributes attr) { |
| LookupResult lookup(isolate); |
| js_object->LookupOwnRealNamedProperty(name, &lookup); |
| @@ -5217,25 +5209,46 @@ RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) { |
| // Use IgnoreAttributes version since a readonly property may be |
| // overridden and SetProperty does not allow this. |
| - Handle<Object> result; |
| - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| - isolate, result, |
| - JSObject::SetOwnPropertyIgnoreAttributes( |
| - js_object, name, obj_value, attr, |
| - Object::OPTIMAL_REPRESENTATION, |
| - ALLOW_AS_CONSTANT, |
| - JSReceiver::PERFORM_EXTENSIBILITY_CHECK, |
| - JSReceiver::MAY_BE_STORE_FROM_KEYED, |
| - JSObject::DONT_FORCE_FIELD)); |
| - return *result; |
| + return JSObject::SetOwnPropertyIgnoreAttributes( |
| + js_object, name, obj_value, attr, |
| + Object::OPTIMAL_REPRESENTATION, |
| + ALLOW_AS_CONSTANT, |
| + JSReceiver::PERFORM_EXTENSIBILITY_CHECK, |
| + JSReceiver::MAY_BE_STORE_FROM_KEYED, |
| + JSObject::DONT_FORCE_FIELD); |
| + } |
| + |
| + return Runtime::ForceSetObjectProperty( |
| + js_object, name, obj_value, attr, |
| + JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED); |
| +} |
| + |
| + |
| +// Implements part of 8.12.9 DefineOwnProperty. |
| +// There are 3 cases that lead here: |
| +// Step 4a - define a new data property. |
| +// Steps 9b & 12 - replace an existing accessor property with a data property. |
| +// Step 12 - update an existing data property with a data or generic |
| +// descriptor. |
| +RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) { |
| + HandleScope scope(isolate); |
| + ASSERT(args.length() == 4); |
| + CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); |
| + CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); |
| + CONVERT_SMI_ARG_CHECKED(unchecked, 3); |
| + RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| + PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
| + |
| + // Check access rights if needed. |
| + if (js_object->IsAccessCheckNeeded() && |
| + !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) { |
| + return isolate->heap()->undefined_value(); |
| } |
| Handle<Object> result; |
| - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| - isolate, result, |
| - Runtime::ForceSetObjectProperty( |
| - js_object, name, obj_value, attr, |
| - JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED)); |
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| + DefineOrRedefineDataProperty(isolate, js_object, name, obj_value, attr)); |
| return *result; |
| } |
| @@ -5481,6 +5494,74 @@ RUNTIME_FUNCTION(Runtime_SetProperty) { |
| } |
| +// This function is only used on object literals. |
| +static MaybeHandle<Object> PutOwnElement(Isolate* isolate, |
|
rossberg
2014/06/13 15:19:24
Nit: SetOwnElement
wingo
2014/06/16 08:32:27
Done.
|
| + Handle<JSObject> object, |
| + uint32_t index, |
| + Handle<Object> value) { |
| + StrictMode strict_mode = SLOPPY; |
| + |
| + JSObject::ValidateElements(object); |
| + |
| + // Object literals don't have these. |
| + ASSERT(!object->HasExternalArrayElements()); |
| + ASSERT(!object->HasFixedTypedArrayElements()); |
| + |
| + // It is currently impossible for an object literal to have a getter or a |
| + // setter for an element, though this may change when we have computed |
| + // accessor property names. |
| + MaybeHandle<Object> result = JSObject::SetOwnElement( |
| + object, index, value, strict_mode); |
| + JSObject::ValidateElements(object); |
| + |
| + return result.is_null() ? result : value; |
| +} |
| + |
| + |
| +static MaybeHandle<Object> PutOwnProperty(Isolate* isolate, |
|
rossberg
2014/06/13 15:19:24
Nit: SetOwnProperty
wingo
2014/06/16 08:32:27
Done.
|
| + Handle<JSObject> object, |
| + Handle<Object> key, |
| + Handle<Object> value) { |
| + PropertyAttributes attr = NONE; |
| + |
| + // Check if the given key is an array index. |
| + uint32_t index; |
| + if (key->ToArrayIndex(&index)) { |
| + return PutOwnElement(isolate, object, index, value); |
| + } |
| + |
| + if (!key->IsName()) { |
| + // Call back into JavaScript to convert the key to a string. |
| + ASSIGN_RETURN_ON_EXCEPTION( |
| + isolate, key, Execution::ToString(isolate, key), Object); |
| + } |
| + |
| + Handle<Name> name = Handle<Name>::cast(key); |
| + if (name->AsArrayIndex(&index)) { |
| + return PutOwnElement(isolate, object, index, value); |
| + } |
| + |
| + return DefineOrRedefineDataProperty(isolate, object, name, value, attr); |
| +} |
| + |
| + |
| +// Used to initialize data properties on object literals. We know that the |
| +// attributes will be NONE. |
| +RUNTIME_FUNCTION(Runtime_PutOwnProperty) { |
| + HandleScope scope(isolate); |
| + RUNTIME_ASSERT(args.length() == 3); |
| + |
| + CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); |
| + CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); |
| + |
| + Handle<Object> result; |
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| + PutOwnProperty(isolate, object, key, value)); |
| + return *result; |
| +} |
| + |
| + |
| RUNTIME_FUNCTION(Runtime_TransitionElementsKind) { |
| HandleScope scope(isolate); |
| RUNTIME_ASSERT(args.length() == 2); |