Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index a96152d8d1fdf5c10c9facbcac103535d29ed22f..9209b9e169cee922799358dba69f9686d65a787a 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -995,23 +995,14 @@ enum PropertyDescriptorIndices { |
DESCRIPTOR_SIZE |
}; |
-// Returns an array with the property description: |
-// if args[1] is not a property on args[0] |
-// returns undefined |
-// if args[1] is a data property on args[0] |
-// [false, value, Writeable, Enumerable, Configurable] |
-// if args[1] is an accessor on args[0] |
-// [true, GetFunction, SetFunction, Enumerable, Configurable] |
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { |
- ASSERT(args.length() == 2); |
+ |
+static MaybeObject* GetOwnProperty(Isolate* isolate, |
+ Handle<JSObject> obj, |
+ Handle<String> name) { |
Heap* heap = isolate->heap(); |
- HandleScope scope(isolate); |
Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); |
Handle<JSArray> desc = isolate->factory()->NewJSArrayWithElements(elms); |
LookupResult result(isolate); |
- CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
- CONVERT_ARG_HANDLE_CHECKED(String, name, 1); |
- |
// This could be an element. |
uint32_t index; |
if (name->AsArrayIndex(&index)) { |
@@ -1145,6 +1136,22 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { |
} |
+// Returns an array with the property description: |
+// if args[1] is not a property on args[0] |
+// returns undefined |
+// if args[1] is a data property on args[0] |
+// [false, value, Writeable, Enumerable, Configurable] |
+// if args[1] is an accessor on args[0] |
+// [true, GetFunction, SetFunction, Enumerable, Configurable] |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { |
+ ASSERT(args.length() == 2); |
+ HandleScope scope(isolate); |
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 1); |
+ return GetOwnProperty(isolate, obj, name); |
+} |
+ |
+ |
RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) { |
ASSERT(args.length() == 1); |
CONVERT_ARG_CHECKED(JSObject, obj, 0); |
@@ -4307,6 +4314,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) { |
args.at<Object>(1)); |
} |
+ |
+static bool IsValidAccessor(Handle<Object> obj) { |
+ return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull(); |
+} |
+ |
+ |
// Implements part of 8.12.9 DefineOwnProperty. |
// There are 3 cases that lead here: |
// Step 4b - define a new accessor property. |
@@ -4317,18 +4330,37 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) { |
ASSERT(args.length() == 5); |
HandleScope scope(isolate); |
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
- CONVERT_ARG_CHECKED(String, name, 1); |
- CONVERT_SMI_ARG_CHECKED(flag, 2); |
- Object* fun = args[3]; |
+ RUNTIME_ASSERT(!obj->IsNull()); |
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 1); |
+ CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); |
+ RUNTIME_ASSERT(IsValidAccessor(getter)); |
+ CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); |
+ RUNTIME_ASSERT(IsValidAccessor(setter)); |
CONVERT_SMI_ARG_CHECKED(unchecked, 4); |
- |
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
- RUNTIME_ASSERT(!obj->IsNull()); |
- RUNTIME_ASSERT(fun->IsSpecFunction() || fun->IsUndefined()); |
- AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER; |
- return obj->DefineAccessor(name, component, fun, attr); |
+ // TODO(svenpanne) Define getter/setter/attributes in a single step. |
+ if (getter->IsNull() && setter->IsNull()) { |
+ JSArray* array; |
+ { MaybeObject* maybe_array = GetOwnProperty(isolate, obj, name); |
+ if (!maybe_array->To(&array)) return maybe_array; |
+ } |
+ Object* current = FixedArray::cast(array->elements())->get(GETTER_INDEX); |
+ getter = Handle<Object>(current, isolate); |
+ } |
+ if (!getter->IsNull()) { |
+ MaybeObject* ok = |
+ obj->DefineAccessor(*name, ACCESSOR_GETTER, *getter, attr); |
+ if (ok->IsFailure()) return ok; |
+ } |
+ if (!setter->IsNull()) { |
+ MaybeObject* ok = |
+ obj->DefineAccessor(*name, ACCESSOR_SETTER, *setter, attr); |
+ if (ok->IsFailure()) return ok; |
+ } |
+ |
+ return isolate->heap()->undefined_value(); |
} |
// Implements part of 8.12.9 DefineOwnProperty. |
@@ -4342,9 +4374,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { |
HandleScope scope(isolate); |
CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); |
CONVERT_ARG_HANDLE_CHECKED(String, name, 1); |
- Handle<Object> obj_value = args.at<Object>(2); |
+ 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); |