Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 8c71f21a8f80ee951beff3a17e6dbd27233ef077..255c42090b706b686a8465497455460ff60aa6b4 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(Object* obj) { |
Michael Starzinger
2012/03/07 12:49:14
Since this is only used as part of an assertion, I
Sven Panne
2012/03/07 13:23:32
As discussed offline, it's OK to keep this funtion
|
+ 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,34 @@ 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); |
Michael Starzinger
2012/03/07 12:49:14
Is there a particular reason you handlified the na
Sven Panne
2012/03/07 13:23:32
The Object class was missing an IsObject predicate
|
+ Object* getter = args[2]; |
+ RUNTIME_ASSERT(IsValidAccessor(getter)); |
+ Object* setter = args[3]; |
+ RUNTIME_ASSERT(IsValidAccessor(setter)); |
CONVERT_SMI_ARG_CHECKED(unchecked, 4); |
- |
Michael Starzinger
2012/03/07 12:49:14
Please leave this empty line in (or at least keep
Sven Panne
2012/03/07 13:23:32
Done.
|
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; |
+ } |
+ getter = FixedArray::cast(array->elements())->get(GETTER_INDEX); |
Michael Starzinger
2012/03/07 12:49:14
I assume that this goes away once the above TODO i
Sven Panne
2012/03/07 13:23:32
Yes, this will vanish, it is just a temporary C++
|
+ } |
+ 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. |