Revert "Port Proxy SetProperty trap builtin to Torque"
This reverts commit 7275c9c8e2
.
Reason for revert: Introduces a crash
Original change's description:
> Port Proxy SetProperty trap builtin to Torque
>
> Spec: https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver
> Bug: v8:6664
> Change-Id: Ieddb645669a72d78ff9c0a45267165de3c5276f1
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1585269
> Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Reviewed-by: Maya Lekova <mslekova@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#61351}
TBR=jgruber@chromium.org,mslekova@chromium.org,duongn@microsoft.com
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: v8:6664, v8:9234
Change-Id: I4e26f5321a51498ab44efac75a963afea7b2ca16
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1605944
Reviewed-by: Dan Elphick <delphick@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61415}
This commit is contained in:
parent
ff74066b64
commit
82b7db3362
1
BUILD.gn
1
BUILD.gn
@ -948,7 +948,6 @@ torque_files = [
|
||||
"src/builtins/object-fromentries.tq",
|
||||
"src/builtins/proxy-constructor.tq",
|
||||
"src/builtins/proxy-get-property.tq",
|
||||
"src/builtins/proxy-set-property.tq",
|
||||
"src/builtins/proxy-revocable.tq",
|
||||
"src/builtins/proxy-revoke.tq",
|
||||
"src/builtins/proxy.tq",
|
||||
|
@ -1208,17 +1208,6 @@ extern macro ThrowTypeError(implicit context: Context)(
|
||||
constexpr MessageTemplate, Object, Object): never;
|
||||
extern macro ThrowTypeError(implicit context: Context)(
|
||||
constexpr MessageTemplate, Object, Object, Object): never;
|
||||
extern transitioning runtime ThrowTypeErrorIfStrict(implicit context: Context)(
|
||||
constexpr MessageTemplate, Object, Object): void;
|
||||
transitioning macro ThrowTypeErrorIfStrictRT(implicit context: Context)(
|
||||
message: constexpr MessageTemplate): void {
|
||||
ThrowTypeErrorIfStrict(message, Null, Null);
|
||||
}
|
||||
transitioning macro ThrowTypeErrorIfStrictRT(implicit context: Context)(
|
||||
message: constexpr MessageTemplate, arg1: constexpr string,
|
||||
arg2: Object): void {
|
||||
ThrowTypeErrorIfStrict(message, arg1, arg2);
|
||||
}
|
||||
extern macro ArraySpeciesCreate(Context, Object, Number): JSReceiver;
|
||||
extern macro ArrayCreate(implicit context: Context)(Number): JSArray;
|
||||
extern macro BuildAppendJSArray(
|
||||
|
@ -826,6 +826,7 @@ namespace internal {
|
||||
\
|
||||
/* Proxy */ \
|
||||
TFS(ProxyHasProperty, kProxy, kName) \
|
||||
TFS(ProxySetProperty, kProxy, kName, kValue, kReceiverValue) \
|
||||
\
|
||||
/* Reflect */ \
|
||||
ASM(ReflectApply, Dummy) \
|
||||
|
@ -338,6 +338,93 @@ TF_BUILTIN(ProxyHasProperty, ProxiesCodeStubAssembler) {
|
||||
StringConstant("has"), proxy);
|
||||
}
|
||||
|
||||
TF_BUILTIN(ProxySetProperty, ProxiesCodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* proxy = Parameter(Descriptor::kProxy);
|
||||
Node* name = Parameter(Descriptor::kName);
|
||||
Node* value = Parameter(Descriptor::kValue);
|
||||
Node* receiver = Parameter(Descriptor::kReceiverValue);
|
||||
|
||||
CSA_ASSERT(this, IsJSProxy(proxy));
|
||||
|
||||
// 1. Assert: IsPropertyKey(P) is true.
|
||||
CSA_ASSERT(this, TaggedIsNotSmi(name));
|
||||
CSA_ASSERT(this, IsName(name));
|
||||
|
||||
Label throw_proxy_handler_revoked(this, Label::kDeferred),
|
||||
trap_undefined(this), failure(this, Label::kDeferred),
|
||||
continue_checks(this), success(this),
|
||||
private_symbol(this, Label::kDeferred);
|
||||
|
||||
GotoIf(IsPrivateSymbol(name), &private_symbol);
|
||||
|
||||
// 2. Let handler be O.[[ProxyHandler]].
|
||||
Node* handler = LoadObjectField(proxy, JSProxy::kHandlerOffset);
|
||||
|
||||
// 3. If handler is null, throw a TypeError exception.
|
||||
GotoIfNot(IsJSReceiver(handler), &throw_proxy_handler_revoked);
|
||||
|
||||
// 4. Assert: Type(handler) is Object.
|
||||
CSA_ASSERT(this, IsJSReceiver(handler));
|
||||
|
||||
// 5. Let target be O.[[ProxyTarget]].
|
||||
Node* target = LoadObjectField(proxy, JSProxy::kTargetOffset);
|
||||
|
||||
// 6. Let trap be ? GetMethod(handler, "set").
|
||||
// 7. If trap is undefined, then (see 7.a below).
|
||||
Handle<Name> set_string = factory()->set_string();
|
||||
Node* trap = GetMethod(context, handler, set_string, &trap_undefined);
|
||||
|
||||
// 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler,
|
||||
// « target, P, V, Receiver »)).
|
||||
// 9. If booleanTrapResult is false, return false.
|
||||
BranchIfToBooleanIsTrue(
|
||||
CallJS(CodeFactory::Call(isolate(),
|
||||
ConvertReceiverMode::kNotNullOrUndefined),
|
||||
context, trap, handler, target, name, value, receiver),
|
||||
&continue_checks, &failure);
|
||||
|
||||
BIND(&continue_checks);
|
||||
{
|
||||
// 9. Let targetDesc be ? target.[[GetOwnProperty]](P).
|
||||
Label return_result(this);
|
||||
Return(CheckGetSetTrapResult(context, target, proxy, name, value,
|
||||
JSProxy::kSet));
|
||||
}
|
||||
|
||||
BIND(&failure);
|
||||
{
|
||||
CallRuntime(Runtime::kThrowTypeErrorIfStrict, context,
|
||||
SmiConstant(MessageTemplate::kProxyTrapReturnedFalsishFor),
|
||||
HeapConstant(set_string), name);
|
||||
Goto(&success);
|
||||
}
|
||||
|
||||
// 12. Return true.
|
||||
BIND(&success);
|
||||
Return(value);
|
||||
|
||||
BIND(&private_symbol);
|
||||
{
|
||||
Label failure(this);
|
||||
|
||||
CallRuntime(Runtime::kThrowTypeErrorIfStrict, context,
|
||||
SmiConstant(MessageTemplate::kProxyPrivate));
|
||||
Return(UndefinedConstant());
|
||||
}
|
||||
|
||||
BIND(&trap_undefined);
|
||||
{
|
||||
// 7.a. Return ? target.[[Set]](P, V, Receiver).
|
||||
CallRuntime(Runtime::kSetPropertyWithReceiver, context, target, name, value,
|
||||
receiver);
|
||||
Return(value);
|
||||
}
|
||||
|
||||
BIND(&throw_proxy_handler_revoked);
|
||||
ThrowTypeError(context, MessageTemplate::kProxyRevoked, "set");
|
||||
}
|
||||
|
||||
Node* ProxiesCodeStubAssembler::CheckGetSetTrapResult(
|
||||
Node* context, Node* target, Node* proxy, Node* name, Node* trap_result,
|
||||
JSProxy::AccessKind access_kind) {
|
||||
|
@ -18,6 +18,16 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler {
|
||||
explicit ProxiesCodeStubAssembler(compiler::CodeAssemblerState* state)
|
||||
: CodeStubAssembler(state) {}
|
||||
|
||||
// ES6 section 9.5.8 [[Get]] ( P, Receiver )
|
||||
// name should not be an index.
|
||||
Node* ProxyGetProperty(Node* context, Node* proxy, Node* name,
|
||||
Node* receiver);
|
||||
|
||||
// ES6 section 9.5.9 [[Set]] ( P, V, Receiver )
|
||||
// name should not be an index.
|
||||
Node* ProxySetProperty(Node* context, Node* proxy, Node* name, Node* value,
|
||||
Node* receiver);
|
||||
|
||||
Node* AllocateProxy(Node* target, Node* handler, Node* context);
|
||||
Node* AllocateProxyRevokeFunction(Node* proxy, Node* context);
|
||||
|
||||
|
@ -10,6 +10,10 @@ namespace proxy {
|
||||
GetPropertyWithReceiver(implicit context: Context)(Object, Name, Object, Smi):
|
||||
Object;
|
||||
|
||||
extern transitioning macro ProxiesCodeStubAssembler::CheckGetSetTrapResult(
|
||||
implicit context:
|
||||
Context)(Object, JSProxy, Name, Object, constexpr int31): Object;
|
||||
|
||||
// ES #sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver
|
||||
// https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver
|
||||
transitioning builtin
|
||||
|
@ -1,78 +0,0 @@
|
||||
// Copyright 2019 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include 'src/builtins/builtins-proxy-gen.h'
|
||||
|
||||
namespace proxy {
|
||||
|
||||
extern transitioning runtime
|
||||
SetPropertyWithReceiver(implicit context:
|
||||
Context)(Object, Name, Object, Object): void;
|
||||
|
||||
// ES #sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver
|
||||
// https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver
|
||||
transitioning builtin
|
||||
ProxySetProperty(implicit context: Context)(
|
||||
proxy: JSProxy, name: Name, value: Object,
|
||||
receiverValue: Object): Object {
|
||||
// 1. Assert: IsPropertyKey(P) is true.
|
||||
assert(TaggedIsNotSmi(name));
|
||||
assert(IsName(name));
|
||||
|
||||
if (IsPrivateSymbol(name)) {
|
||||
ThrowTypeErrorIfStrictRT(kProxyPrivate);
|
||||
return Undefined;
|
||||
}
|
||||
|
||||
// 2. Let handler be O.[[ProxyHandler]].
|
||||
const handler: Object = proxy.handler;
|
||||
|
||||
try {
|
||||
// 3. If handler is null, throw a TypeError exception.
|
||||
// 4. Assert: Type(handler) is Object.
|
||||
const handlerJSReceiver =
|
||||
Cast<JSReceiver>(handler) otherwise ThrowProxyHandlerRevoked;
|
||||
|
||||
// 5. Let target be O.[[ProxyTarget]].
|
||||
const target = proxy.target;
|
||||
|
||||
// 6. Let trap be ? GetMethod(handler, "set").
|
||||
// 7. If trap is undefined, then (see 7.a below).
|
||||
const trap: Callable = GetMethod(handlerJSReceiver, 'set')
|
||||
otherwise goto TrapUndefined(target);
|
||||
|
||||
// 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler,
|
||||
// « target, P, V, Receiver »)).
|
||||
// 9. If booleanTrapResult is false, return false.
|
||||
// 10. Let targetDesc be ? target.[[GetOwnProperty]](P).
|
||||
// 11. If targetDesc is not undefined and targetDesc.[[Configurable]] is
|
||||
// false, then
|
||||
// a. If IsDataDescriptor(targetDesc) is true and
|
||||
// targetDesc.[[Writable]] is false, then
|
||||
// i. If SameValue(V, targetDesc.[[Value]]) is false, throw a
|
||||
// TypeError exception.
|
||||
// b. If IsAccessorDescriptor(targetDesc) is true, then
|
||||
// i. If targetDesc.[[Set]] is undefined, throw a TypeError
|
||||
// exception.
|
||||
// 12. Return true.
|
||||
const trapResult = Call(
|
||||
context, trap, handlerJSReceiver, target, name, value, receiverValue);
|
||||
if (BranchIfToBooleanIsTrue(trapResult)) {
|
||||
return CheckGetSetTrapResult(
|
||||
target, proxy, name, trapResult, kProxySet);
|
||||
}
|
||||
ThrowTypeErrorIfStrictRT(kProxyTrapReturnedFalsishFor, 'set', name);
|
||||
return value;
|
||||
}
|
||||
label TrapUndefined(target: Object) {
|
||||
// 7.a. Return ? target.[[Set]](P, V, Receiver).
|
||||
SetPropertyWithReceiver(target, name, value, receiverValue);
|
||||
return value;
|
||||
}
|
||||
label ThrowProxyHandlerRevoked deferred {
|
||||
assert(handler == Null);
|
||||
ThrowTypeError(kProxyRevoked, 'set');
|
||||
}
|
||||
}
|
||||
}
|
@ -20,20 +20,12 @@ namespace proxy {
|
||||
return false;
|
||||
}
|
||||
|
||||
extern transitioning macro ProxiesCodeStubAssembler::CheckGetSetTrapResult(
|
||||
implicit context:
|
||||
Context)(Object, JSProxy, Name, Object, constexpr int31): Object;
|
||||
|
||||
const kProxyNonObject: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kProxyNonObject';
|
||||
const kProxyHandlerOrTargetRevoked: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kProxyHandlerOrTargetRevoked';
|
||||
const kProxyRevoked: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kProxyRevoked';
|
||||
const kProxyTrapReturnedFalsishFor: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kProxyTrapReturnedFalsishFor';
|
||||
const kProxyPrivate: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kProxyPrivate';
|
||||
|
||||
const kProxyGet: constexpr int31
|
||||
generates 'JSProxy::AccessKind::kGet';
|
||||
|
Loading…
Reference in New Issue
Block a user