Chromium Code Reviews| 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. |