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

Unified Diff: src/objects.cc

Issue 1479543002: [proxies] Implement [[Delete]]. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix typo Created 5 years, 1 month 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
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index dbabe93e752e28cb3890e1f03455adabe697b545..39048b0e4c61784d1888f40b03050f29c672d27a 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -4643,33 +4643,54 @@ Maybe<bool> JSProxy::SetPropertyViaPrototypesWithHandler(
}
-MaybeHandle<Object> JSProxy::DeletePropertyWithHandler(
- Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode) {
+Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy,
+ Handle<Name> name,
+ LanguageMode language_mode) {
+ ShouldThrow should_throw =
+ is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR;
Isolate* isolate = proxy->GetIsolate();
+ Factory* factory = isolate->factory();
+ Handle<String> trap_name = factory->deleteProperty_string();
- // TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (name->IsSymbol()) return isolate->factory()->false_value();
+ if (IsRevoked(proxy)) {
+ isolate->Throw(
+ *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
+ return Nothing<bool>();
+ }
- Handle<Object> args[] = { name };
- Handle<Object> result;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, result,
- CallTrap(proxy,
- "delete",
- Handle<Object>(),
- arraysize(args),
- args),
- Object);
-
- bool result_bool = result->BooleanValue();
- if (is_strict(language_mode) && !result_bool) {
- Handle<Object> handler(proxy->handler(), isolate);
- THROW_NEW_ERROR(
- isolate,
- NewTypeError(MessageTemplate::kProxyHandlerDeleteFailed, handler),
- Object);
+ Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
+ Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate);
+
+ Handle<Object> trap;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, trap, GetTrap(proxy, trap_name),
+ Nothing<bool>());
+ if (trap->IsUndefined()) {
+ return JSReceiver::DeletePropertyOrElement(target, name, language_mode);
}
- return isolate->factory()->ToBoolean(result_bool);
+
+ Handle<Object> trap_result;
+ Handle<Object> args[] = {target, name};
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, trap_result,
+ Execution::Call(isolate, trap, handler, arraysize(args), args),
+ Nothing<bool>());
+ if (!trap_result->BooleanValue()) {
+ RETURN_FAILURE(isolate, should_throw,
+ NewTypeError(MessageTemplate::kProxyHandlerReturned, handler,
+ factory->false_string(), trap_name));
+ }
+
+ // Enforce the invariant.
+ PropertyDescriptor target_desc;
+ bool owned =
+ JSReceiver::GetOwnPropertyDescriptor(isolate, target, name, &target_desc);
+ if (isolate->has_pending_exception()) return Nothing<bool>();
+ if (owned && !target_desc.configurable()) {
+ isolate->Throw(*factory->NewTypeError(
+ MessageTemplate::kProxyDeletePropertyViolatesInvariant, name));
+ return Nothing<bool>();
+ }
+ return Just(true);
}
@@ -5762,8 +5783,7 @@ Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object,
}
-MaybeHandle<Object> JSObject::DeletePropertyWithInterceptor(
- LookupIterator* it) {
+Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it) {
Isolate* isolate = it->isolate();
// Make sure that the top context does not change when doing callbacks or
// interceptor calls.
@@ -5771,7 +5791,7 @@ MaybeHandle<Object> JSObject::DeletePropertyWithInterceptor(
DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
Handle<InterceptorInfo> interceptor(it->GetInterceptor());
- if (interceptor->deleter()->IsUndefined()) return MaybeHandle<Object>();
+ if (interceptor->deleter()->IsUndefined()) return Nothing<bool>();
Handle<JSObject> holder = it->GetHolder<JSObject>();
@@ -5786,7 +5806,7 @@ MaybeHandle<Object> JSObject::DeletePropertyWithInterceptor(
ApiIndexedPropertyAccess("interceptor-indexed-delete", *holder, index));
result = args.Call(deleter, index);
} else if (it->name()->IsSymbol() && !interceptor->can_intercept_symbols()) {
- return MaybeHandle<Object>();
+ return Nothing<bool>();
} else {
Handle<Name> name = it->name();
v8::GenericNamedPropertyDeleterCallback deleter =
@@ -5797,14 +5817,14 @@ MaybeHandle<Object> JSObject::DeletePropertyWithInterceptor(
result = args.Call(deleter, v8::Utils::ToLocal(name));
}
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
- if (result.IsEmpty()) return MaybeHandle<Object>();
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
+ if (result.IsEmpty()) return Nothing<bool>();
DCHECK(result->IsBoolean());
Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
result_internal->VerifyApiCallResultType();
// Rebox CustomArguments::kReturnValueOffset before returning.
- return handle(*result_internal, isolate);
+ return Just(result_internal->BooleanValue());
}
@@ -5835,13 +5855,13 @@ void JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
}
-// ECMA-262, 3rd, 8.6.2.5
-MaybeHandle<Object> JSReceiver::DeleteProperty(LookupIterator* it,
- LanguageMode language_mode) {
+Maybe<bool> JSReceiver::DeleteProperty(LookupIterator* it,
+ LanguageMode language_mode) {
Isolate* isolate = it->isolate();
+
if (it->state() == LookupIterator::JSPROXY) {
- return JSProxy::DeletePropertyWithHandler(it->GetHolder<JSProxy>(),
- it->GetName(), language_mode);
+ return JSProxy::DeletePropertyOrElement(it->GetHolder<JSProxy>(),
+ it->GetName(), language_mode);
}
Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
@@ -5861,19 +5881,20 @@ MaybeHandle<Object> JSReceiver::DeleteProperty(LookupIterator* it,
case LookupIterator::ACCESS_CHECK:
if (it->HasAccess()) break;
isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
- return it->factory()->false_value();
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
+ return Just(false);
case LookupIterator::INTERCEPTOR: {
- MaybeHandle<Object> maybe_result =
- JSObject::DeletePropertyWithInterceptor(it);
- // Delete with interceptor succeeded. Return result.
- if (!maybe_result.is_null()) return maybe_result;
+ Maybe<bool> result = JSObject::DeletePropertyWithInterceptor(it);
// An exception was thrown in the interceptor. Propagate.
- if (isolate->has_pending_exception()) return maybe_result;
+ if (isolate->has_pending_exception()) return Nothing<bool>();
+ // Delete with interceptor succeeded. Return result.
+ // TODO(neis): In strict mode, we should probably throw if the
+ // interceptor returns false.
+ if (result.IsJust()) return result;
break;
}
case LookupIterator::INTEGER_INDEXED_EXOTIC:
- return it->factory()->true_value();
+ return Just(true);
case LookupIterator::DATA:
if (is_observed) {
old_value = it->GetDataValue();
@@ -5887,49 +5908,50 @@ MaybeHandle<Object> JSReceiver::DeleteProperty(LookupIterator* it,
receiver->map()->is_strong()
? MessageTemplate::kStrongDeleteProperty
: MessageTemplate::kStrictDeleteProperty;
- THROW_NEW_ERROR(
- isolate, NewTypeError(templ, it->GetName(), receiver), Object);
+ isolate->Throw(*isolate->factory()->NewTypeError(
+ templ, it->GetName(), receiver));
+ return Nothing<bool>();
}
- return it->factory()->false_value();
+ return Just(false);
}
it->Delete();
if (is_observed) {
- RETURN_ON_EXCEPTION(isolate,
- JSObject::EnqueueChangeRecord(
- receiver, "delete", it->GetName(), old_value),
- Object);
+ RETURN_ON_EXCEPTION_VALUE(
+ isolate, JSObject::EnqueueChangeRecord(receiver, "delete",
+ it->GetName(), old_value),
+ Nothing<bool>());
}
- return it->factory()->true_value();
+ return Just(true);
}
}
}
- return it->factory()->true_value();
+ return Just(true);
}
-MaybeHandle<Object> JSReceiver::DeleteElement(Handle<JSReceiver> object,
- uint32_t index,
- LanguageMode language_mode) {
+Maybe<bool> JSReceiver::DeleteElement(Handle<JSReceiver> object, uint32_t index,
+ LanguageMode language_mode) {
LookupIterator it(object->GetIsolate(), object, index,
LookupIterator::HIDDEN);
return DeleteProperty(&it, language_mode);
}
-MaybeHandle<Object> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
- Handle<Name> name,
- LanguageMode language_mode) {
+Maybe<bool> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
+ Handle<Name> name,
+ LanguageMode language_mode) {
LookupIterator it(object, name, LookupIterator::HIDDEN);
return DeleteProperty(&it, language_mode);
}
-MaybeHandle<Object> JSReceiver::DeletePropertyOrElement(
- Handle<JSReceiver> object, Handle<Name> name, LanguageMode language_mode) {
+Maybe<bool> JSReceiver::DeletePropertyOrElement(Handle<JSReceiver> object,
+ Handle<Name> name,
+ LanguageMode language_mode) {
LookupIterator it = LookupIterator::PropertyOrElement(
name->GetIsolate(), object, name, LookupIterator::HIDDEN);
return DeleteProperty(&it, language_mode);

Powered by Google App Engine
This is Rietveld 408576698