Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 07987e2e39e271da31ce4b88346de252736167f3..0ac8ef10489910ed33cbbbd38bfa3a04a8572ecc 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> SetOwnElement(Isolate* isolate, |
+ 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> SetOwnProperty(Isolate* isolate, |
+ 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 SetOwnElement(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 SetOwnElement(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_SetOwnProperty) { |
+ 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, |
+ SetOwnProperty(isolate, object, key, value)); |
+ return *result; |
+} |
+ |
+ |
RUNTIME_FUNCTION(Runtime_TransitionElementsKind) { |
HandleScope scope(isolate); |
RUNTIME_ASSERT(args.length() == 2); |