| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 39c30336ea755b86a1c9a25fccbba19d76adb284..069b3a21dfc21212dab372a04a151b6475ebba5c 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -6722,17 +6722,6 @@ bool JSObject::ReferencesObject(Object* obj) {
|
| }
|
|
|
|
|
| -#define RETURN_FAILURE(isolate, should_throw, call) \
|
| - do { \
|
| - if ((should_throw) == DONT_THROW) { \
|
| - return Just(false); \
|
| - } else { \
|
| - isolate->Throw(*isolate->factory()->call); \
|
| - return Nothing<bool>(); \
|
| - } \
|
| - } while (false)
|
| -
|
| -
|
| Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object,
|
| ShouldThrow should_throw) {
|
| if (!object->IsJSObject()) return Just(false);
|
| @@ -13878,9 +13867,19 @@ Handle<Map> Map::TransitionToPrototype(Handle<Map> map,
|
| }
|
|
|
|
|
| -MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
|
| - Handle<Object> value,
|
| - bool from_javascript) {
|
| +Maybe<bool> JSReceiver::SetPrototype(Handle<JSReceiver> object,
|
| + Handle<Object> value, bool from_javascript,
|
| + ShouldThrow should_throw) {
|
| + if (!object->IsJSObject()) return Just(false);
|
| + // TODO(neis): Deal with proxies.
|
| + return JSObject::SetPrototype(Handle<JSObject>::cast(object), value,
|
| + from_javascript, should_throw);
|
| +}
|
| +
|
| +
|
| +Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
|
| + Handle<Object> value, bool from_javascript,
|
| + ShouldThrow should_throw) {
|
| Isolate* isolate = object->GetIsolate();
|
|
|
| const bool observed = from_javascript && object->map()->is_observed();
|
| @@ -13889,19 +13888,18 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
|
| old_value = Object::GetPrototype(isolate, object);
|
| }
|
|
|
| - Handle<Object> result;
|
| - ASSIGN_RETURN_ON_EXCEPTION(
|
| - isolate, result, SetPrototypeUnobserved(object, value, from_javascript),
|
| - Object);
|
| + Maybe<bool> result =
|
| + SetPrototypeUnobserved(object, value, from_javascript, should_throw);
|
| + MAYBE_RETURN(result, Nothing<bool>());
|
|
|
| - if (observed) {
|
| + if (result.FromJust() && observed) {
|
| Handle<Object> new_value = Object::GetPrototype(isolate, object);
|
| if (!new_value->SameValue(*old_value)) {
|
| - RETURN_ON_EXCEPTION(isolate,
|
| - JSObject::EnqueueChangeRecord(
|
| - object, "setPrototype",
|
| - isolate->factory()->proto_string(), old_value),
|
| - Object);
|
| + RETURN_ON_EXCEPTION_VALUE(
|
| + isolate, JSObject::EnqueueChangeRecord(
|
| + object, "setPrototype",
|
| + isolate->factory()->proto_string(), old_value),
|
| + Nothing<bool>());
|
| }
|
| }
|
|
|
| @@ -13909,9 +13907,10 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
|
| }
|
|
|
|
|
| -MaybeHandle<Object> JSObject::SetPrototypeUnobserved(Handle<JSObject> object,
|
| - Handle<Object> value,
|
| - bool from_javascript) {
|
| +Maybe<bool> JSObject::SetPrototypeUnobserved(Handle<JSObject> object,
|
| + Handle<Object> value,
|
| + bool from_javascript,
|
| + ShouldThrow should_throw) {
|
| #ifdef DEBUG
|
| int size = object->Size();
|
| #endif
|
| @@ -13922,8 +13921,8 @@ MaybeHandle<Object> JSObject::SetPrototypeUnobserved(Handle<JSObject> object,
|
| if (object->IsAccessCheckNeeded() &&
|
| !isolate->MayAccess(handle(isolate->context()), object)) {
|
| isolate->ReportFailedAccessCheck(object);
|
| - RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
| - return isolate->factory()->undefined_value();
|
| + RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
|
| + UNREACHABLE();
|
| }
|
| } else {
|
| DCHECK(!object->IsAccessCheckNeeded());
|
| @@ -13932,14 +13931,13 @@ MaybeHandle<Object> JSObject::SetPrototypeUnobserved(Handle<JSObject> object,
|
| // Strong objects may not have their prototype set via __proto__ or
|
| // setPrototypeOf.
|
| if (from_javascript && object->map()->is_strong()) {
|
| - THROW_NEW_ERROR(isolate,
|
| - NewTypeError(MessageTemplate::kStrongSetProto, object),
|
| - Object);
|
| + RETURN_FAILURE(isolate, should_throw,
|
| + NewTypeError(MessageTemplate::kStrongSetProto, object));
|
| }
|
| Heap* heap = isolate->heap();
|
| // Silently ignore the change if value is not a JSObject or null.
|
| // SpiderMonkey behaves this way.
|
| - if (!value->IsJSReceiver() && !value->IsNull()) return value;
|
| + if (!value->IsJSReceiver() && !value->IsNull()) return Just(true);
|
|
|
| // From 8.6.2 Object Internal Methods
|
| // ...
|
| @@ -13950,9 +13948,9 @@ MaybeHandle<Object> JSObject::SetPrototypeUnobserved(Handle<JSObject> object,
|
| // or [[Extensible]] must not violate the invariants defined in the preceding
|
| // paragraph.
|
| if (!object->map()->is_extensible()) {
|
| - THROW_NEW_ERROR(isolate,
|
| - NewTypeError(MessageTemplate::kNonExtensibleProto, object),
|
| - Object);
|
| + RETURN_FAILURE(isolate, should_throw,
|
| + NewTypeError(MessageTemplate::kNonExtensibleProto, object));
|
| + // TODO(neis): Don't fail if new and old prototype happen to be the same.
|
| }
|
|
|
| // Before we can set the prototype we need to be sure
|
| @@ -13964,8 +13962,8 @@ MaybeHandle<Object> JSObject::SetPrototypeUnobserved(Handle<JSObject> object,
|
| !iter.IsAtEnd(); iter.Advance()) {
|
| if (iter.GetCurrent<JSReceiver>() == *object) {
|
| // Cycle detected.
|
| - THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kCyclicProto),
|
| - Object);
|
| + RETURN_FAILURE(isolate, should_throw,
|
| + NewTypeError(MessageTemplate::kCyclicProto));
|
| }
|
| }
|
|
|
| @@ -13981,9 +13979,9 @@ MaybeHandle<Object> JSObject::SetPrototypeUnobserved(Handle<JSObject> object,
|
| real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
|
| iter.Advance();
|
| if (!real_receiver->map()->is_extensible()) {
|
| - THROW_NEW_ERROR(
|
| - isolate, NewTypeError(MessageTemplate::kNonExtensibleProto, object),
|
| - Object);
|
| + RETURN_FAILURE(
|
| + isolate, should_throw,
|
| + NewTypeError(MessageTemplate::kNonExtensibleProto, object));
|
| }
|
| }
|
| }
|
| @@ -13992,7 +13990,7 @@ MaybeHandle<Object> JSObject::SetPrototypeUnobserved(Handle<JSObject> object,
|
| Handle<Map> map(real_receiver->map());
|
|
|
| // Nothing to do if prototype is already set.
|
| - if (map->prototype() == *value) return value;
|
| + if (map->prototype() == *value) return Just(true);
|
|
|
| isolate->UpdateArrayProtectorOnSetPrototype(real_receiver);
|
|
|
| @@ -14012,7 +14010,7 @@ MaybeHandle<Object> JSObject::SetPrototypeUnobserved(Handle<JSObject> object,
|
|
|
| heap->ClearInstanceofCache();
|
| DCHECK(size == object->Size());
|
| - return value;
|
| + return Just(true);
|
| }
|
|
|
|
|
|
|