Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(894)

Unified Diff: src/objects.cc

Issue 1394983005: Restructure Object::SetProperty and related functions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-array.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 49e8b52d944f7b65c362460db47f6cb6001864a6..c8c843740a646965876668165250f05fb70ccfcb 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -866,8 +866,10 @@ bool AccessorInfo::IsCompatibleReceiverMap(Isolate* isolate,
}
-MaybeHandle<Object> Object::SetPropertyWithAccessor(
- LookupIterator* it, Handle<Object> value, LanguageMode language_mode) {
+Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
+ Handle<Object> value,
+ LanguageMode language_mode,
+ ShouldThrow should_throw) {
Isolate* isolate = it->isolate();
Handle<Object> structure = it->GetAccessors();
Handle<Object> receiver = it->GetReceiver();
@@ -883,21 +885,24 @@ MaybeHandle<Object> Object::SetPropertyWithAccessor(
Handle<ExecutableAccessorInfo> info =
Handle<ExecutableAccessorInfo>::cast(structure);
if (!info->IsCompatibleReceiver(*receiver)) {
- THROW_NEW_ERROR(isolate,
- NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
- name, receiver),
- Object);
+ isolate->Throw(*isolate->factory()->NewTypeError(
+ MessageTemplate::kIncompatibleMethodReceiver, name, receiver));
+ return Nothing<bool>();
}
v8::AccessorNameSetterCallback call_fun =
v8::ToCData<v8::AccessorNameSetterCallback>(info->setter());
- if (call_fun == nullptr) return value;
+ if (call_fun == nullptr) return Just(true);
+ // TODO(verwaest): Shouldn't this case be unreachable (at least in the
+ // long run?) Should we have ExecutableAccessorPairs with missing setter
+ // that are "writable"? If they aren't writable, shouldn't we have bailed
+ // out already earlier?
LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name));
PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder);
args.Call(call_fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
- return value;
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
+ return Just(true);
}
// Regular accessor.
@@ -905,15 +910,13 @@ MaybeHandle<Object> Object::SetPropertyWithAccessor(
if (setter->IsCallable()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return SetPropertyWithDefinedSetter(
- receiver, Handle<JSReceiver>::cast(setter), value);
+ receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
}
- if (is_sloppy(language_mode)) return value;
-
- THROW_NEW_ERROR(isolate,
- NewTypeError(MessageTemplate::kNoSetterInCallback,
- it->GetName(), it->GetHolder<JSObject>()),
- Object);
+ if (is_sloppy(language_mode)) return Just(true);
+ RETURN_FAILURE(isolate, should_throw,
+ NewTypeError(MessageTemplate::kNoSetterInCallback,
+ it->GetName(), it->GetHolder<JSObject>()));
}
@@ -945,10 +948,10 @@ MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
}
-MaybeHandle<Object> Object::SetPropertyWithDefinedSetter(
- Handle<Object> receiver,
- Handle<JSReceiver> setter,
- Handle<Object> value) {
+Maybe<bool> Object::SetPropertyWithDefinedSetter(Handle<Object> receiver,
+ Handle<JSReceiver> setter,
+ Handle<Object> value,
+ ShouldThrow should_throw) {
Isolate* isolate = setter->GetIsolate();
Debug* debug = isolate->debug();
@@ -957,10 +960,10 @@ MaybeHandle<Object> Object::SetPropertyWithDefinedSetter(
if (debug->is_active()) debug->HandleStepIn(setter, false);
Handle<Object> argv[] = { value };
- RETURN_ON_EXCEPTION(isolate, Execution::Call(isolate, setter, receiver,
- arraysize(argv), argv),
- Object);
- return value;
+ RETURN_ON_EXCEPTION_VALUE(isolate, Execution::Call(isolate, setter, receiver,
+ arraysize(argv), argv),
+ Nothing<bool>());
+ return Just(true);
}
@@ -1045,17 +1048,20 @@ bool JSObject::AllCanWrite(LookupIterator* it) {
}
-MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck(
- LookupIterator* it, Handle<Object> value) {
+Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck(
+ LookupIterator* it, Handle<Object> value, ShouldThrow should_throw) {
Handle<JSObject> checked = it->GetHolder<JSObject>();
if (AllCanWrite(it)) {
// The supplied language-mode is ignored by SetPropertyWithAccessor.
- return SetPropertyWithAccessor(it, value, SLOPPY);
+ return SetPropertyWithAccessor(it, value, SLOPPY, should_throw);
}
it->isolate()->ReportFailedAccessCheck(checked);
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
- return value;
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
+ UNREACHABLE();
Jakob Kummerow 2015/10/27 15:51:52 We're hitting this in the wild (crbug.com/548194).
+ it->isolate()->Throw(
+ *it->isolate()->factory()->NewTypeError(MessageTemplate::kNoAccess));
+ return Nothing<bool>();
}
@@ -3514,8 +3520,8 @@ Handle<Map> Map::Update(Handle<Map> map) {
}
-MaybeHandle<Object> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
- Handle<Object> value) {
+Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
+ Handle<Object> value) {
Isolate* isolate = it->isolate();
// Make sure that the top context does not change when doing callbacks or
// interceptor calls.
@@ -3523,7 +3529,7 @@ MaybeHandle<Object> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
Handle<InterceptorInfo> interceptor(it->GetInterceptor());
- if (interceptor->setter()->IsUndefined()) return MaybeHandle<Object>();
+ if (interceptor->setter()->IsUndefined()) return Just(false);
Handle<JSObject> holder = it->GetHolder<JSObject>();
v8::Local<v8::Value> result;
@@ -3541,7 +3547,7 @@ MaybeHandle<Object> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
Handle<Name> name = it->name();
if (name->IsSymbol() && !interceptor->can_intercept_symbols()) {
- return MaybeHandle<Object>();
+ return Just(false);
}
v8::GenericNamedPropertySetterCallback setter =
@@ -3553,13 +3559,13 @@ MaybeHandle<Object> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
}
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
- if (result.IsEmpty()) return MaybeHandle<Object>();
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
+ if (result.IsEmpty()) return Just(false);
#ifdef DEBUG
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
result_internal->VerifyApiCallResultType();
#endif
- return value;
+ return Just(true);
}
@@ -3572,11 +3578,9 @@ MaybeHandle<Object> Object::SetProperty(Handle<Object> object,
}
-MaybeHandle<Object> Object::SetPropertyInternal(LookupIterator* it,
- Handle<Object> value,
- LanguageMode language_mode,
- StoreFromKeyed store_mode,
- bool* found) {
+Maybe<bool> Object::SetPropertyInternal(
+ LookupIterator* it, Handle<Object> value, LanguageMode language_mode,
+ ShouldThrow should_throw, StoreFromKeyed store_mode, bool* found) {
// Make sure that the top context does not change when doing callbacks or
// interceptor calls.
AssertNoContextChange ncc(it->isolate());
@@ -3593,20 +3597,21 @@ MaybeHandle<Object> Object::SetPropertyInternal(LookupIterator* it,
if (it->HasAccess()) break;
// Check whether it makes sense to reuse the lookup iterator. Here it
// might still call into setters up the prototype chain.
- return JSObject::SetPropertyWithFailedAccessCheck(it, value);
+ return JSObject::SetPropertyWithFailedAccessCheck(it, value,
+ should_throw);
case LookupIterator::JSPROXY:
if (it->HolderIsReceiverOrHiddenPrototype()) {
return JSProxy::SetPropertyWithHandler(
it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(), value,
- language_mode);
+ language_mode, should_throw);
} else {
// TODO(verwaest): Use the MaybeHandle to indicate result.
bool has_result = false;
- MaybeHandle<Object> maybe_result =
+ Maybe<bool> maybe_result =
JSProxy::SetPropertyViaPrototypesWithHandler(
it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName(),
- value, language_mode, &has_result);
+ value, language_mode, should_throw, &has_result);
if (has_result) return maybe_result;
done = true;
}
@@ -3614,24 +3619,26 @@ MaybeHandle<Object> Object::SetPropertyInternal(LookupIterator* it,
case LookupIterator::INTERCEPTOR:
if (it->HolderIsReceiverOrHiddenPrototype()) {
- MaybeHandle<Object> maybe_result =
+ Maybe<bool> maybe_result =
JSObject::SetPropertyWithInterceptor(it, value);
- if (!maybe_result.is_null()) return maybe_result;
- if (it->isolate()->has_pending_exception()) return maybe_result;
+ if (maybe_result.IsNothing()) return Nothing<bool>();
+ if (maybe_result.FromJust()) return Just(true);
} else {
Maybe<PropertyAttributes> maybe_attributes =
JSObject::GetPropertyAttributesWithInterceptor(it);
- if (!maybe_attributes.IsJust()) return MaybeHandle<Object>();
+ if (!maybe_attributes.IsJust()) return Nothing<bool>();
done = maybe_attributes.FromJust() != ABSENT;
if (done && (maybe_attributes.FromJust() & READ_ONLY) != 0) {
- return WriteToReadOnlyProperty(it, value, language_mode);
+ return WriteToReadOnlyProperty(it, value, language_mode,
+ should_throw);
}
}
break;
case LookupIterator::ACCESSOR: {
if (it->IsReadOnly()) {
- return WriteToReadOnlyProperty(it, value, language_mode);
+ return WriteToReadOnlyProperty(it, value, language_mode,
+ should_throw);
}
Handle<Object> accessors = it->GetAccessors();
if (accessors->IsAccessorInfo() &&
@@ -3640,18 +3647,19 @@ MaybeHandle<Object> Object::SetPropertyInternal(LookupIterator* it,
done = true;
break;
}
- return SetPropertyWithAccessor(it, value, language_mode);
+ return SetPropertyWithAccessor(it, value, language_mode, should_throw);
}
case LookupIterator::INTEGER_INDEXED_EXOTIC:
// TODO(verwaest): We should throw an exception.
- return value;
+ return Just(true);
case LookupIterator::DATA:
if (it->IsReadOnly()) {
- return WriteToReadOnlyProperty(it, value, language_mode);
+ return WriteToReadOnlyProperty(it, value, language_mode,
+ should_throw);
}
if (it->HolderIsReceiverOrHiddenPrototype()) {
- return SetDataProperty(it, value);
+ return SetDataProperty(it, value, should_throw);
}
done = true;
break;
@@ -3668,13 +3676,12 @@ MaybeHandle<Object> Object::SetPropertyInternal(LookupIterator* it,
// the property did not exist yet on the global object itself, we have to
// throw a reference error in strict mode.
if (it->GetReceiver()->IsJSGlobalObject() && is_strict(language_mode)) {
- THROW_NEW_ERROR(it->isolate(),
- NewReferenceError(MessageTemplate::kNotDefined, it->name()),
- Object);
+ RETURN_FAILURE(it->isolate(), should_throw,
+ NewReferenceError(MessageTemplate::kNotDefined, it->name()));
}
*found = false;
- return MaybeHandle<Object>();
+ return Nothing<bool>();
}
@@ -3682,11 +3689,22 @@ MaybeHandle<Object> Object::SetProperty(LookupIterator* it,
Handle<Object> value,
LanguageMode language_mode,
StoreFromKeyed store_mode) {
+ MAYBE_RETURN_NULL(
+ SetProperty(it, value, language_mode, THROW_ON_ERROR, store_mode));
+ return value;
+}
+
+
+Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value,
+ LanguageMode language_mode,
+ ShouldThrow should_throw,
+ StoreFromKeyed store_mode) {
bool found = false;
- MaybeHandle<Object> result =
- SetPropertyInternal(it, value, language_mode, store_mode, &found);
+ Maybe<bool> result = SetPropertyInternal(it, value, language_mode,
+ should_throw, store_mode, &found);
if (found) return result;
- return AddDataProperty(it, value, NONE, language_mode, store_mode);
+ return AddDataProperty(it, value, NONE, language_mode, should_throw,
+ store_mode);
}
@@ -3695,12 +3713,17 @@ MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it,
LanguageMode language_mode,
StoreFromKeyed store_mode) {
bool found = false;
- MaybeHandle<Object> result =
- SetPropertyInternal(it, value, language_mode, store_mode, &found);
- if (found) return result;
+ Maybe<bool> result = SetPropertyInternal(it, value, language_mode,
+ THROW_ON_ERROR, store_mode, &found);
+ if (found) {
+ MAYBE_RETURN_NULL(result);
+ return value;
+ }
if (!it->GetReceiver()->IsJSReceiver()) {
- return WriteToReadOnlyProperty(it, value, language_mode);
+ MAYBE_RETURN_NULL(
+ WriteToReadOnlyProperty(it, value, language_mode, THROW_ON_ERROR));
+ return value;
}
LookupIterator::Configuration c = LookupIterator::OWN;
@@ -3713,7 +3736,9 @@ MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it,
switch (own_lookup.state()) {
case LookupIterator::ACCESS_CHECK:
if (!own_lookup.HasAccess()) {
- return JSObject::SetPropertyWithFailedAccessCheck(&own_lookup, value);
+ MAYBE_RETURN_NULL(JSObject::SetPropertyWithFailedAccessCheck(
+ &own_lookup, value, THROW_ON_ERROR));
+ return value;
}
break;
@@ -3727,7 +3752,9 @@ MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it,
return JSObject::DefineOwnPropertyIgnoreAttributes(
&own_lookup, value, details.attributes());
}
- return WriteToReadOnlyProperty(&own_lookup, value, language_mode);
+ MAYBE_RETURN_NULL(WriteToReadOnlyProperty(
+ &own_lookup, value, language_mode, THROW_ON_ERROR));
+ return value;
}
case LookupIterator::ACCESSOR: {
@@ -3744,9 +3771,13 @@ MaybeHandle<Object> Object::SetSuperProperty(LookupIterator* it,
case LookupIterator::INTERCEPTOR:
case LookupIterator::JSPROXY: {
bool found = false;
- MaybeHandle<Object> result = SetPropertyInternal(
- &own_lookup, value, language_mode, store_mode, &found);
- if (found) return result;
+ Maybe<bool> result =
+ SetPropertyInternal(&own_lookup, value, language_mode,
+ THROW_ON_ERROR, store_mode, &found);
+ if (found) {
+ MAYBE_RETURN_NULL(result);
+ return value;
+ }
break;
}
@@ -3786,44 +3817,40 @@ MaybeHandle<Object> Object::ReadAbsentProperty(Isolate* isolate,
}
-MaybeHandle<Object> Object::CannotCreateProperty(LookupIterator* it,
- Handle<Object> value,
- LanguageMode language_mode) {
- return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
- value, language_mode);
-}
-
-
-MaybeHandle<Object> Object::CannotCreateProperty(Isolate* isolate,
- Handle<Object> receiver,
- Handle<Object> name,
- Handle<Object> value,
- LanguageMode language_mode) {
- if (is_sloppy(language_mode)) return value;
- Handle<String> typeof_string = Object::TypeOf(isolate, receiver);
- THROW_NEW_ERROR(isolate,
- NewTypeError(MessageTemplate::kStrictCannotCreateProperty,
- name, typeof_string, receiver),
- Object);
+Maybe<bool> Object::CannotCreateProperty(Isolate* isolate,
+ Handle<Object> receiver,
+ Handle<Object> name,
+ Handle<Object> value,
+ LanguageMode language_mode,
+ ShouldThrow should_throw) {
+ if (is_sloppy(language_mode)) return Just(true);
+ RETURN_FAILURE(
+ isolate, should_throw,
+ NewTypeError(MessageTemplate::kStrictCannotCreateProperty, name,
+ Object::TypeOf(isolate, receiver), receiver));
}
-MaybeHandle<Object> Object::WriteToReadOnlyProperty(
- LookupIterator* it, Handle<Object> value, LanguageMode language_mode) {
+Maybe<bool> Object::WriteToReadOnlyProperty(LookupIterator* it,
+ Handle<Object> value,
+ LanguageMode language_mode,
+ ShouldThrow should_throw) {
return WriteToReadOnlyProperty(it->isolate(), it->GetReceiver(),
- it->GetName(), value, language_mode);
+ it->GetName(), value, language_mode,
+ should_throw);
}
-MaybeHandle<Object> Object::WriteToReadOnlyProperty(
- Isolate* isolate, Handle<Object> receiver, Handle<Object> name,
- Handle<Object> value, LanguageMode language_mode) {
- if (is_sloppy(language_mode)) return value;
- Handle<String> typeof_string = Object::TypeOf(isolate, receiver);
- THROW_NEW_ERROR(isolate,
- NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
- typeof_string, receiver),
- Object);
+Maybe<bool> Object::WriteToReadOnlyProperty(Isolate* isolate,
+ Handle<Object> receiver,
+ Handle<Object> name,
+ Handle<Object> value,
+ LanguageMode language_mode,
+ ShouldThrow should_throw) {
+ if (is_sloppy(language_mode)) return Just(true);
+ RETURN_FAILURE(isolate, should_throw,
+ NewTypeError(MessageTemplate::kStrictReadOnlyProperty, name,
+ Object::TypeOf(isolate, receiver), receiver));
}
@@ -3837,8 +3864,8 @@ MaybeHandle<Object> Object::RedefineNonconfigurableProperty(
}
-MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
- Handle<Object> value) {
+Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value,
+ ShouldThrow should_throw) {
// Proxies are handled on the WithHandler path. Other non-JSObjects cannot
// have own properties.
Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
@@ -3859,8 +3886,8 @@ MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
// Convert the incoming value to a number for storing into typed arrays.
if (it->IsElement() && receiver->HasFixedTypedArrayElements()) {
if (!value->IsNumber() && !value->IsUndefined()) {
- ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), to_assign,
- Object::ToNumber(value), Object);
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ it->isolate(), to_assign, Object::ToNumber(value), Nothing<bool>());
// ToNumber above might modify the receiver, causing the cached
// holder_map to mismatch the actual holder->map() after this point.
// Reload the map to be in consistent state. Other cached state cannot
@@ -3871,7 +3898,8 @@ MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
// We have to recheck the length. However, it can only change if the
// underlying buffer was neutered, so just check that.
if (Handle<JSArrayBufferView>::cast(receiver)->WasNeutered()) {
- return value;
+ return Just(true);
+ // TODO(neis): According to the spec, this should throw a TypeError.
}
}
}
@@ -3885,10 +3913,11 @@ MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
// Send the change record if there are observers.
if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) {
- RETURN_ON_EXCEPTION(it->isolate(), JSObject::EnqueueChangeRecord(
- receiver, "update", it->GetName(),
- maybe_old.ToHandleChecked()),
- Object);
+ RETURN_ON_EXCEPTION_VALUE(
+ it->isolate(),
+ JSObject::EnqueueChangeRecord(receiver, "update", it->GetName(),
+ maybe_old.ToHandleChecked()),
+ Nothing<bool>());
}
#if VERIFY_HEAP
@@ -3896,7 +3925,7 @@ MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
receiver->JSObjectVerify();
}
#endif
- return value;
+ return Just(true);
}
@@ -3946,9 +3975,21 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
PropertyAttributes attributes,
LanguageMode language_mode,
StoreFromKeyed store_mode) {
+ MAYBE_RETURN_NULL(AddDataProperty(it, value, attributes, language_mode,
+ THROW_ON_ERROR, store_mode));
+ return value;
+}
+
+
+Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
+ PropertyAttributes attributes,
+ LanguageMode language_mode,
+ ShouldThrow should_throw,
+ StoreFromKeyed store_mode) {
DCHECK(!it->GetReceiver()->IsJSProxy());
if (!it->GetReceiver()->IsJSObject()) {
- return CannotCreateProperty(it, value, language_mode);
+ return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
+ value, language_mode, should_throw);
}
DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, it->state());
@@ -3957,24 +3998,27 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
// If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
// instead. If the prototype is Null, the proxy is detached.
- if (receiver->IsJSGlobalProxy()) return value;
+ if (receiver->IsJSGlobalProxy()) return Just(true);
Isolate* isolate = it->isolate();
if (!receiver->map()->is_extensible() &&
(it->IsElement() || !isolate->IsInternallyUsedPropertyName(it->name()))) {
- if (is_sloppy(language_mode)) return value;
- THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kObjectNotExtensible,
- it->GetName()),
- Object);
+ if (is_sloppy(language_mode)) return Just(true);
+ RETURN_FAILURE(
+ isolate, should_throw,
+ NewTypeError(MessageTemplate::kObjectNotExtensible, it->GetName()));
}
if (it->IsElement()) {
if (receiver->IsJSArray()) {
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
if (JSArray::WouldChangeReadOnlyLength(array, it->index())) {
- if (is_sloppy(language_mode)) return value;
- return JSArray::ReadOnlyLengthError(array);
+ if (is_sloppy(language_mode)) return Just(true);
+ RETURN_FAILURE(array->GetIsolate(), should_throw,
+ NewTypeError(MessageTemplate::kStrictReadOnlyProperty,
+ isolate->factory()->length_string(),
+ Object::TypeOf(isolate, array), array));
}
if (FLAG_trace_external_array_abuse &&
@@ -3987,8 +4031,8 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
}
}
- MaybeHandle<Object> result =
- JSObject::AddDataElement(receiver, it->index(), value, attributes);
+ Maybe<bool> result = JSObject::AddDataElement(receiver, it->index(), value,
+ attributes, should_throw);
JSObject::ValidateElements(receiver);
return result;
} else {
@@ -4012,10 +4056,10 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
// Send the change record if there are observers.
if (receiver->map()->is_observed() &&
!isolate->IsInternallyUsedPropertyName(it->name())) {
- RETURN_ON_EXCEPTION(isolate, JSObject::EnqueueChangeRecord(
- receiver, "add", it->name(),
- it->factory()->the_hole_value()),
- Object);
+ RETURN_ON_EXCEPTION_VALUE(isolate, JSObject::EnqueueChangeRecord(
+ receiver, "add", it->name(),
+ it->factory()->the_hole_value()),
+ Nothing<bool>());
}
#if VERIFY_HEAP
if (FLAG_verify_heap) {
@@ -4024,7 +4068,7 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
#endif
}
- return value;
+ return Just(true);
}
@@ -4376,68 +4420,63 @@ Maybe<bool> JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy,
}
-MaybeHandle<Object> JSProxy::SetPropertyWithHandler(
- Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
- Handle<Object> value, LanguageMode language_mode) {
+Maybe<bool> JSProxy::SetPropertyWithHandler(Handle<JSProxy> proxy,
+ Handle<Object> receiver,
+ Handle<Name> name,
+ Handle<Object> value,
+ LanguageMode language_mode,
+ ShouldThrow should_throw) {
Isolate* isolate = proxy->GetIsolate();
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (name->IsSymbol()) return value;
+ if (name->IsSymbol()) return Just(true);
Handle<Object> args[] = { receiver, name, value };
- RETURN_ON_EXCEPTION(
- isolate,
- CallTrap(proxy,
- "set",
- isolate->derived_set_trap(),
- arraysize(args),
- args),
- Object);
+ RETURN_ON_EXCEPTION_VALUE(isolate,
+ CallTrap(proxy, "set", isolate->derived_set_trap(),
+ arraysize(args), args),
+ Nothing<bool>());
- return value;
+ return Just(true);
+ // TODO(neis): This needs to be made spec-conformant by throwing a TypeError
+ // if the trap's result is falsish.
}
-MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
+Maybe<bool> JSProxy::SetPropertyViaPrototypesWithHandler(
Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
- Handle<Object> value, LanguageMode language_mode, bool* done) {
+ Handle<Object> value, LanguageMode language_mode, ShouldThrow should_throw,
+ bool* done) {
Isolate* isolate = proxy->GetIsolate();
Handle<Object> handler(proxy->handler(), isolate); // Trap might morph proxy.
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (name->IsSymbol()) {
- *done = false;
- return isolate->factory()->the_hole_value();
+ *done = false; // Return value will be ignored.
+ return Nothing<bool>();
}
*done = true; // except where redefined...
Handle<Object> args[] = { name };
Handle<Object> result;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, result,
- CallTrap(proxy,
- "getPropertyDescriptor",
- Handle<Object>(),
- arraysize(args),
- args),
- Object);
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, result, CallTrap(proxy, "getPropertyDescriptor",
+ Handle<Object>(), arraysize(args), args),
+ Nothing<bool>());
if (result->IsUndefined()) {
- *done = false;
- return isolate->factory()->the_hole_value();
+ *done = false; // Return value will be ignored.
+ return Nothing<bool>();
}
// Emulate [[GetProperty]] semantics for proxies.
Handle<Object> argv[] = { result };
Handle<Object> desc;
- ASSIGN_RETURN_ON_EXCEPTION(
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, desc,
- Execution::Call(isolate,
- isolate->to_complete_property_descriptor(),
- result,
- arraysize(argv),
- argv),
- Object);
+ Execution::Call(isolate, isolate->to_complete_property_descriptor(),
+ result, arraysize(argv), argv),
+ Nothing<bool>());
// [[GetProperty]] requires to check that all properties are configurable.
Handle<String> configurable_name =
@@ -4447,12 +4486,11 @@ MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
Object::GetProperty(desc, configurable_name).ToHandleChecked();
DCHECK(configurable->IsBoolean());
if (configurable->IsFalse()) {
- Handle<String> trap = isolate->factory()->InternalizeOneByteString(
- STATIC_CHAR_VECTOR("getPropertyDescriptor"));
- THROW_NEW_ERROR(isolate,
- NewTypeError(MessageTemplate::kProxyPropNotConfigurable,
- handler, name, trap),
- Object);
+ RETURN_FAILURE(
+ isolate, should_throw,
+ NewTypeError(MessageTemplate::kProxyPropNotConfigurable, handler, name,
+ isolate->factory()->NewStringFromAsciiChecked(
+ "getPropertyDescriptor")));
}
DCHECK(configurable->IsTrue());
@@ -4470,9 +4508,9 @@ MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
Object::GetProperty(desc, writable_name).ToHandleChecked();
DCHECK(writable->IsBoolean());
*done = writable->IsFalse();
- if (!*done) return isolate->factory()->the_hole_value();
+ if (!*done) return Nothing<bool>(); // Return value will be ignored.
return WriteToReadOnlyProperty(isolate, receiver, name, value,
- language_mode);
+ language_mode, should_throw);
}
// We have an AccessorDescriptor.
@@ -4482,13 +4520,13 @@ MaybeHandle<Object> JSProxy::SetPropertyViaPrototypesWithHandler(
if (!setter->IsUndefined()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return SetPropertyWithDefinedSetter(
- receiver, Handle<JSReceiver>::cast(setter), value);
+ receiver, Handle<JSReceiver>::cast(setter), value, should_throw);
}
- if (is_sloppy(language_mode)) return value;
- THROW_NEW_ERROR(
- isolate, NewTypeError(MessageTemplate::kNoSetterInCallback, name, proxy),
- Object);
+ if (is_sloppy(language_mode)) return Just(true);
+ RETURN_FAILURE(
+ isolate, should_throw,
+ NewTypeError(MessageTemplate::kNoSetterInCallback, name, proxy));
}
@@ -4768,10 +4806,9 @@ MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
// they throw. Here we should do the same.
case LookupIterator::INTERCEPTOR:
if (handling == DONT_FORCE_FIELD) {
- MaybeHandle<Object> maybe_result =
- JSObject::SetPropertyWithInterceptor(it, value);
- if (!maybe_result.is_null()) return maybe_result;
- if (it->isolate()->has_pending_exception()) return maybe_result;
+ Maybe<bool> result = JSObject::SetPropertyWithInterceptor(it, value);
+ if (result.IsNothing()) return MaybeHandle<Object>();
+ if (result.FromJust()) return value;
}
break;
@@ -4786,11 +4823,9 @@ MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
// Ensure the context isn't changed after calling into accessors.
AssertNoContextChange ncc(it->isolate());
- Handle<Object> result;
- ASSIGN_RETURN_ON_EXCEPTION(
- it->isolate(), result,
- JSObject::SetPropertyWithAccessor(it, value, STRICT), Object);
- DCHECK(result->SameValue(*value));
+ Maybe<bool> result = JSObject::SetPropertyWithAccessor(
+ it, value, STRICT, THROW_ON_ERROR);
+ if (result.IsNothing()) return MaybeHandle<Object>();
if (details.attributes() == attributes) return value;
@@ -4829,7 +4864,8 @@ MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
Handle<Object> old_value = it->factory()->the_hole_value();
// Regular property update if the attributes match.
if (details.attributes() == attributes) {
- return SetDataProperty(it, value);
+ MAYBE_RETURN_NULL(SetDataProperty(it, value, THROW_ON_ERROR));
+ return value;
}
// Special case: properties of typed arrays cannot be reconfigured to
@@ -6962,18 +6998,16 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) {
- return PreventExtensionsWithTransition<FROZEN>(object, THROW_ON_ERROR)
- .IsJust()
- ? object
- : MaybeHandle<Object>();
+ MAYBE_RETURN_NULL(
+ PreventExtensionsWithTransition<FROZEN>(object, THROW_ON_ERROR));
+ return object;
}
MaybeHandle<Object> JSObject::Seal(Handle<JSObject> object) {
- return PreventExtensionsWithTransition<SEALED>(object, THROW_ON_ERROR)
- .IsJust()
- ? object
- : MaybeHandle<Object>();
+ MAYBE_RETURN_NULL(
+ PreventExtensionsWithTransition<SEALED>(object, THROW_ON_ERROR));
+ return object;
}
@@ -14155,6 +14189,17 @@ MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> object,
uint32_t index,
Handle<Object> value,
PropertyAttributes attributes) {
+ MAYBE_RETURN_NULL(
+ AddDataElement(object, index, value, attributes, THROW_ON_ERROR));
+ return value;
+}
+
+
+// static
+Maybe<bool> JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+ ShouldThrow should_throw) {
DCHECK(object->map()->is_extensible());
Isolate* isolate = object->GetIsolate();
@@ -14215,30 +14260,33 @@ MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> object,
Handle<JSArray> array = Handle<JSArray>::cast(object);
Handle<String> name = isolate->factory()->Uint32ToString(index);
- RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object);
- RETURN_ON_EXCEPTION(
+ RETURN_ON_EXCEPTION_VALUE(isolate, BeginPerformSplice(array),
+ Nothing<bool>());
+ RETURN_ON_EXCEPTION_VALUE(
isolate, EnqueueChangeRecord(array, "add", name,
isolate->factory()->the_hole_value()),
- Object);
- RETURN_ON_EXCEPTION(isolate,
- EnqueueChangeRecord(array, "update",
- isolate->factory()->length_string(),
- old_length_handle),
- Object);
- RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object);
+ Nothing<bool>());
+ RETURN_ON_EXCEPTION_VALUE(
+ isolate, EnqueueChangeRecord(array, "update",
+ isolate->factory()->length_string(),
+ old_length_handle),
+ Nothing<bool>());
+ RETURN_ON_EXCEPTION_VALUE(isolate, EndPerformSplice(array),
+ Nothing<bool>());
Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
- RETURN_ON_EXCEPTION(isolate, EnqueueSpliceRecord(array, old_length, deleted,
- new_length - old_length),
- Object);
+ RETURN_ON_EXCEPTION_VALUE(isolate,
+ EnqueueSpliceRecord(array, old_length, deleted,
+ new_length - old_length),
+ Nothing<bool>());
} else if (object->map()->is_observed()) {
Handle<String> name = isolate->factory()->Uint32ToString(index);
- RETURN_ON_EXCEPTION(
+ RETURN_ON_EXCEPTION_VALUE(
isolate, EnqueueChangeRecord(object, "add", name,
isolate->factory()->the_hole_value()),
- Object);
+ Nothing<bool>());
}
- return value;
+ return Just(true);
}
@@ -14441,17 +14489,6 @@ bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
}
-MaybeHandle<Object> JSArray::ReadOnlyLengthError(Handle<JSArray> array) {
- Isolate* isolate = array->GetIsolate();
- Handle<Name> length = isolate->factory()->length_string();
- Handle<String> typeof_string = Object::TypeOf(isolate, array);
- THROW_NEW_ERROR(isolate,
- NewTypeError(MessageTemplate::kStrictReadOnlyProperty, length,
- typeof_string, array),
- Object);
-}
-
-
template <typename BackingStore>
static int FastHoleyElementsUsage(JSObject* object, BackingStore* store) {
int limit = object->IsJSArray()
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-array.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698