| Index: src/runtime.cc
|
| ===================================================================
|
| --- src/runtime.cc (revision 6703)
|
| +++ src/runtime.cc (working copy)
|
| @@ -884,10 +884,17 @@
|
| return obj->PreventExtensions();
|
| }
|
|
|
| +
|
| static MaybeObject* Runtime_IsExtensible(Arguments args) {
|
| ASSERT(args.length() == 1);
|
| CONVERT_CHECKED(JSObject, obj, args[0]);
|
| - return obj->map()->is_extensible() ? Heap::true_value()
|
| + if (obj->IsJSGlobalProxy()) {
|
| + Object* proto = obj->GetPrototype();
|
| + if (proto->IsNull()) return Heap::false_value();
|
| + ASSERT(proto->IsJSGlobalObject());
|
| + obj = JSObject::cast(proto);
|
| + }
|
| + return obj->map()->is_extensible() ? Heap::true_value()
|
| : Heap::false_value();
|
| }
|
|
|
| @@ -1082,7 +1089,11 @@
|
| const char* type = (lookup.IsReadOnly()) ? "const" : "var";
|
| return ThrowRedeclarationError(type, name);
|
| }
|
| - SetProperty(global, name, value, attributes);
|
| + Handle<Object> result = SetProperty(global, name, value, attributes);
|
| + if (result.is_null()) {
|
| + ASSERT(Top::has_pending_exception());
|
| + return Failure::Exception();
|
| + }
|
| } else {
|
| // If a property with this name does not already exist on the
|
| // global object add the property locally. We take special
|
| @@ -1090,10 +1101,16 @@
|
| // of callbacks in the prototype chain (this rules out using
|
| // SetProperty). Also, we must use the handle-based version to
|
| // avoid GC issues.
|
| - SetLocalPropertyIgnoreAttributes(global, name, value, attributes);
|
| + Handle<Object> result =
|
| + SetLocalPropertyIgnoreAttributes(global, name, value, attributes);
|
| + if (result.is_null()) {
|
| + ASSERT(Top::has_pending_exception());
|
| + return Failure::Exception();
|
| + }
|
| }
|
| }
|
|
|
| + ASSERT(!Top::has_pending_exception());
|
| return Heap::undefined_value();
|
| }
|
|
|
| @@ -1143,12 +1160,15 @@
|
| } else {
|
| // The holder is an arguments object.
|
| Handle<JSObject> arguments(Handle<JSObject>::cast(holder));
|
| - SetElement(arguments, index, initial_value);
|
| + Handle<Object> result = SetElement(arguments, index, initial_value);
|
| + if (result.is_null()) return Failure::Exception();
|
| }
|
| } else {
|
| // Slow case: The property is not in the FixedArray part of the context.
|
| Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
|
| - SetProperty(context_ext, name, initial_value, mode);
|
| + Handle<Object> result =
|
| + SetProperty(context_ext, name, initial_value, mode);
|
| + if (result.is_null()) return Failure::Exception();
|
| }
|
| }
|
|
|
| @@ -1175,8 +1195,8 @@
|
| ASSERT(!context_ext->HasLocalProperty(*name));
|
| Handle<Object> value(Heap::undefined_value());
|
| if (*initial_value != NULL) value = initial_value;
|
| - SetProperty(context_ext, name, value, mode);
|
| - ASSERT(context_ext->GetLocalPropertyAttribute(*name) == mode);
|
| + Handle<Object> result = SetProperty(context_ext, name, value, mode);
|
| + if (result.is_null()) return Failure::Exception();
|
| }
|
|
|
| return Heap::undefined_value();
|
| @@ -3655,12 +3675,20 @@
|
| if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) &&
|
| is_element) {
|
| // Normalize the elements to enable attributes on the property.
|
| + if (js_object->IsJSGlobalProxy()) {
|
| + Handle<Object> proto(js_object->GetPrototype());
|
| + // If proxy is detached, ignore the assignment. Alternatively,
|
| + // we could throw an exception.
|
| + if (proto->IsNull()) return *obj_value;
|
| + js_object = Handle<JSObject>::cast(proto);
|
| + }
|
| NormalizeElements(js_object);
|
| Handle<NumberDictionary> dictionary(js_object->element_dictionary());
|
| // Make sure that we never go back to fast case.
|
| dictionary->set_requires_slow_elements();
|
| PropertyDetails details = PropertyDetails(attr, NORMAL);
|
| NumberDictionarySet(dictionary, index, obj_value, details);
|
| + return *obj_value;
|
| }
|
|
|
| LookupResult result;
|
| @@ -3675,6 +3703,11 @@
|
| if (result.IsProperty() &&
|
| (attr != result.GetAttributes() || result.type() == CALLBACKS)) {
|
| // New attributes - normalize to avoid writing to instance descriptor
|
| + if (js_object->IsJSGlobalProxy()) {
|
| + // Since the result is a property, the prototype will exist so
|
| + // we don't have to check for null.
|
| + js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
|
| + }
|
| NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
|
| // Use IgnoreAttributes version since a readonly property may be
|
| // overridden and SetProperty does not allow this.
|
| @@ -7323,12 +7356,17 @@
|
| if (holder->IsContext()) {
|
| // Ignore if read_only variable.
|
| if ((attributes & READ_ONLY) == 0) {
|
| - Handle<Context>::cast(holder)->set(index, *value);
|
| + // Context is a fixed array and set cannot fail.
|
| + Context::cast(*holder)->set(index, *value);
|
| }
|
| } else {
|
| ASSERT((attributes & READ_ONLY) == 0);
|
| - Handle<JSObject>::cast(holder)->SetElement(index, *value)->
|
| - ToObjectUnchecked();
|
| + Handle<Object> result =
|
| + SetElement(Handle<JSObject>::cast(holder), index, value);
|
| + if (result.is_null()) {
|
| + ASSERT(Top::has_pending_exception());
|
| + return Failure::Exception();
|
| + }
|
| }
|
| return *value;
|
| }
|
| @@ -7351,8 +7389,8 @@
|
| // extension object itself.
|
| if ((attributes & READ_ONLY) == 0 ||
|
| (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) {
|
| - Handle<Object> set = SetProperty(context_ext, name, value, NONE);
|
| - if (set.is_null()) {
|
| + Handle<Object> result = SetProperty(context_ext, name, value, NONE);
|
| + if (result.is_null()) {
|
| // Failure::Exception is converted to a null handle in the
|
| // handle-based methods such as SetProperty. We therefore need
|
| // to convert null handles back to exceptions.
|
|
|