| Index: src/runtime.cc
|
| ===================================================================
|
| --- src/runtime.cc (revision 3785)
|
| +++ src/runtime.cc (working copy)
|
| @@ -596,8 +596,9 @@
|
|
|
| if (result.type() == CALLBACKS) {
|
| Object* structure = result.GetCallbackObject();
|
| - if (structure->IsProxy()) {
|
| - // Property that is internally implemented as a callback.
|
| + if (structure->IsProxy() || structure->IsAccessorInfo()) {
|
| + // Property that is internally implemented as a callback or
|
| + // an API defined callback.
|
| Object* value = obj->GetPropertyWithCallback(
|
| obj, structure, name, result.holder());
|
| elms->set(0, Heap::false_value());
|
| @@ -609,7 +610,6 @@
|
| elms->set(1, FixedArray::cast(structure)->get(0));
|
| elms->set(2, FixedArray::cast(structure)->get(1));
|
| } else {
|
| - // TODO(ricow): Handle API callbacks.
|
| return Heap::undefined_value();
|
| }
|
| } else {
|
| @@ -619,7 +619,7 @@
|
| }
|
|
|
| elms->set(3, Heap::ToBoolean(!result.IsDontEnum()));
|
| - elms->set(4, Heap::ToBoolean(!result.IsReadOnly()));
|
| + elms->set(4, Heap::ToBoolean(!result.IsDontDelete()));
|
| return *desc;
|
| }
|
|
|
| @@ -2888,6 +2888,66 @@
|
| }
|
|
|
|
|
| +static Object* Runtime_DefineOrRedefineAccessorProperty(Arguments args) {
|
| + ASSERT(args.length() == 5);
|
| + HandleScope scope;
|
| + Handle<JSObject> obj = args.at<JSObject>(0);
|
| + CONVERT_CHECKED(String, name, args[1]);
|
| + CONVERT_CHECKED(Smi, flag_setter, args[2]);
|
| + CONVERT_CHECKED(JSFunction, fun, args[3]);
|
| + CONVERT_CHECKED(Smi, flag_attr, args[4]);
|
| + int unchecked = flag_attr->value();
|
| + RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
|
| +
|
| + LookupResult result;
|
| + obj->LocalLookupRealNamedProperty(name, &result);
|
| +
|
| + PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
|
| + // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION
|
| + // delete it to avoid running into trouble in DefineAccessor, which
|
| + // handles this incorrectly if the property is readonly (does nothing)
|
| + if (result.type() == FIELD || result.type() == NORMAL
|
| + || result.type() == CONSTANT_FUNCTION)
|
| + obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
|
| +
|
| + return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr);
|
| +}
|
| +
|
| +static Object* Runtime_DefineOrRedefineDataProperty(Arguments args) {
|
| + ASSERT(args.length() == 4);
|
| + HandleScope scope;
|
| + Handle<Object> obj = args.at<Object>(0);
|
| + Handle<Object> name = args.at<Object>(1);
|
| + Handle<Object> obj_value = args.at<Object>(2);
|
| + Handle<JSObject> js_object = Handle<JSObject>::cast(obj);
|
| + Handle<String> key_string = Handle<String>::cast(name);
|
| +
|
| + CONVERT_CHECKED(Smi, flag, args[3]);
|
| + int unchecked = flag->value();
|
| + RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
|
| +
|
| + LookupResult result;
|
| + js_object->LocalLookupRealNamedProperty(*key_string, &result);
|
| +
|
| + PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
|
| +
|
| + // Take special care when attributes are different and there is already
|
| + // a property. For simplicity we normalize the property which enables us
|
| + // to not worry about changing the instance_descriptor and creating a new
|
| + // map. The current version of SetObjectProperty does not handle attributes
|
| + // correctly in the case where a property is a field and is reset with
|
| + // new attributes.
|
| + if (result.IsProperty() && attr != result.GetAttributes()) {
|
| + PropertyDetails details = PropertyDetails(attr, NORMAL);
|
| + // New attributes - normalize to avoid writing to instance descriptor
|
| + js_object->NormalizeProperties(KEEP_INOBJECT_PROPERTIES, 0);
|
| + return js_object->SetNormalizedProperty(*key_string, *obj_value, details);
|
| + }
|
| +
|
| + return Runtime::SetObjectProperty(js_object, name, obj_value, attr);
|
| +}
|
| +
|
| +
|
| Object* Runtime::SetObjectProperty(Handle<Object> object,
|
| Handle<Object> key,
|
| Handle<Object> value,
|
|
|