Commit 0fbf1708 authored by Z Duong Nguyen-Huu's avatar Z Duong Nguyen-Huu Committed by Commit Bot

Porting ProxyConstructor to Torque

Spec: https://tc39.github.io/ecma262/#sec-proxy-constructor
Bug: v8:6664
Change-Id: Ia8b5ed75841d813babd1db4743c3bb9d25658b51
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1553007Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#60892}
parent d97ceb27
......@@ -940,6 +940,8 @@ torque_files = [
"src/builtins/extras-utils.tq",
"src/builtins/iterator.tq",
"src/builtins/object-fromentries.tq",
"src/builtins/proxy.tq",
"src/builtins/proxy-constructor.tq",
"src/builtins/proxy-revocable.tq",
"src/builtins/proxy-revoke.tq",
"src/builtins/regexp.tq",
......
......@@ -803,6 +803,8 @@ const kProxyNonObject: constexpr MessageTemplate
generates 'MessageTemplate::kProxyNonObject';
const kProxyHandlerOrTargetRevoked: constexpr MessageTemplate
generates 'MessageTemplate::kProxyHandlerOrTargetRevoked';
const kConstructorNotFunction: constexpr MessageTemplate
generates 'MessageTemplate::kConstructorNotFunction';
const kMaxArrayIndex:
constexpr uint32 generates 'JSArray::kMaxArrayIndex';
......
......@@ -870,7 +870,6 @@ namespace internal {
TFJ(PromiseInternalResolve, 2, kReceiver, kPromise, kResolution) \
\
/* Proxy */ \
TFJ(ProxyConstructor, 2, kReceiver, kTarget, kHandler) \
TFS(ProxyGetProperty, kProxy, kName, kReceiverValue, kOnNonExistent) \
TFS(ProxyHasProperty, kProxy, kName) \
TFS(ProxySetProperty, kProxy, kName, kValue, kReceiverValue) \
......
......@@ -13,15 +13,6 @@
namespace v8 {
namespace internal {
void ProxiesCodeStubAssembler::GotoIfRevokedProxy(Node* object,
Label* if_proxy_revoked) {
Label proxy_not_revoked(this);
GotoIfNot(IsJSProxy(object), &proxy_not_revoked);
Branch(IsJSReceiver(CAST(LoadObjectField(object, JSProxy::kHandlerOffset))),
&proxy_not_revoked, if_proxy_revoked);
BIND(&proxy_not_revoked);
}
Node* ProxiesCodeStubAssembler::AllocateProxy(Node* target, Node* handler,
Node* context) {
VARIABLE(map, MachineRepresentation::kTagged);
......@@ -145,63 +136,9 @@ Node* ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(Node* proxy,
proxy_context);
}
// ES #sec-proxy-constructor
TF_BUILTIN(ProxyConstructor, ProxiesCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
// 1. If NewTarget is undefined, throw a TypeError exception.
Node* new_target = Parameter(Descriptor::kJSNewTarget);
Label throwtypeerror(this, Label::kDeferred), createproxy(this);
Branch(IsUndefined(new_target), &throwtypeerror, &createproxy);
BIND(&throwtypeerror);
{
ThrowTypeError(context, MessageTemplate::kConstructorNotFunction, "Proxy");
}
// 2. Return ? ProxyCreate(target, handler).
BIND(&createproxy);
{
// https://tc39.github.io/ecma262/#sec-proxycreate
Node* target = Parameter(Descriptor::kTarget);
Node* handler = Parameter(Descriptor::kHandler);
// 1. If Type(target) is not Object, throw a TypeError exception.
// 2. If target is a Proxy exotic object and target.[[ProxyHandler]] is
// null, throw a TypeError exception.
// 3. If Type(handler) is not Object, throw a TypeError exception.
// 4. If handler is a Proxy exotic object and handler.[[ProxyHandler]]
// is null, throw a TypeError exception.
Label throw_proxy_non_object(this, Label::kDeferred),
throw_proxy_handler_or_target_revoked(this, Label::kDeferred),
return_create_proxy(this);
GotoIf(TaggedIsSmi(target), &throw_proxy_non_object);
GotoIfNot(IsJSReceiver(target), &throw_proxy_non_object);
GotoIfRevokedProxy(target, &throw_proxy_handler_or_target_revoked);
GotoIf(TaggedIsSmi(handler), &throw_proxy_non_object);
GotoIfNot(IsJSReceiver(handler), &throw_proxy_non_object);
GotoIfRevokedProxy(handler, &throw_proxy_handler_or_target_revoked);
// 5. Let P be a newly created object.
// 6. Set P's essential internal methods (except for [[Call]] and
// [[Construct]]) to the definitions specified in 9.5.
// 7. If IsCallable(target) is true, then
// a. Set P.[[Call]] as specified in 9.5.12.
// b. If IsConstructor(target) is true, then
// 1. Set P.[[Construct]] as specified in 9.5.13.
// 8. Set P.[[ProxyTarget]] to target.
// 9. Set P.[[ProxyHandler]] to handler.
// 10. Return P.
Return(AllocateProxy(target, handler, context));
BIND(&throw_proxy_non_object);
ThrowTypeError(context, MessageTemplate::kProxyNonObject);
BIND(&throw_proxy_handler_or_target_revoked);
ThrowTypeError(context, MessageTemplate::kProxyHandlerOrTargetRevoked);
}
Node* ProxiesCodeStubAssembler::GetProxyConstructorJSNewTarget() {
return CodeAssembler::Parameter(static_cast<int>(
Builtin_ProxyConstructor_InterfaceDescriptor::kJSNewTarget));
}
TF_BUILTIN(CallProxy, ProxiesCodeStubAssembler) {
......
......@@ -7,6 +7,7 @@
#include "src/code-stub-assembler.h"
#include "src/objects/js-proxy.h"
#include "torque-generated/builtins-proxy-from-dsl-gen.h"
namespace v8 {
namespace internal {
......@@ -30,13 +31,16 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler {
Node* AllocateProxy(Node* target, Node* handler, Node* context);
Node* AllocateProxyRevokeFunction(Node* proxy, Node* context);
// Get JSNewTarget parameter for ProxyConstructor builtin (Torque).
// TODO(v8:9120): Remove this once torque support exists
Node* GetProxyConstructorJSNewTarget();
protected:
enum ProxyRevokeFunctionContextSlot {
kProxySlot = Context::MIN_CONTEXT_SLOTS,
kProxyContextLength,
};
void GotoIfRevokedProxy(Node* object, Label* if_proxy_revoked);
Node* AllocateJSArrayForCodeStubArguments(Node* context,
CodeStubArguments& args, Node* argc,
ParameterMode mode);
......
// 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 macro ProxiesCodeStubAssembler::GetProxyConstructorJSNewTarget():
Object;
// ES #sec-proxy-constructor
// https://tc39.github.io/ecma262/#sec-proxy-constructor
transitioning javascript builtin
ProxyConstructor(implicit context: Context)(
receiver: Object, target: Object, handler: Object): JSProxy {
try {
// 1. If NewTarget is undefined, throw a TypeError exception.
const newTarget: Object = GetProxyConstructorJSNewTarget();
if (newTarget == Undefined) {
ThrowTypeError(kConstructorNotFunction, 'Proxy');
}
// 2. Return ? ProxyCreate(target, handler).
// https://tc39.github.io/ecma262/#sec-proxycreate
// 1. If Type(target) is not Object, throw a TypeError exception.
// 2. If target is a Proxy exotic object and target.[[ProxyHandler]] is
// null, throw a TypeError exception.
// 3. If Type(handler) is not Object, throw a TypeError exception.
// 4. If handler is a Proxy exotic object and handler.[[ProxyHandler]]
// is null, throw a TypeError exception.
const targetJSReceiver =
Cast<JSReceiver>(target) otherwise ThrowProxyNonObject;
if (IsRevokedProxy(targetJSReceiver)) {
goto ThrowProxyHandlerOrTargetRevoked;
}
const handlerJSReceiver =
Cast<JSReceiver>(handler) otherwise ThrowProxyNonObject;
if (IsRevokedProxy(handlerJSReceiver)) {
goto ThrowProxyHandlerOrTargetRevoked;
}
// 5. Let P be a newly created object.
// 6. Set P's essential internal methods (except for [[Call]] and
// [[Construct]]) to the definitions specified in 9.5.
// 7. If IsCallable(target) is true, then
// a. Set P.[[Call]] as specified in 9.5.12.
// b. If IsConstructor(target) is true, then
// 1. Set P.[[Construct]] as specified in 9.5.13.
// 8. Set P.[[ProxyTarget]] to target.
// 9. Set P.[[ProxyHandler]] to handler.
// 10. Return P.
return AllocateProxy(targetJSReceiver, handlerJSReceiver);
}
label ThrowProxyNonObject deferred {
ThrowTypeError(kProxyNonObject);
}
label ThrowProxyHandlerOrTargetRevoked deferred {
ThrowTypeError(kProxyHandlerOrTargetRevoked);
}
}
}
......@@ -6,13 +6,6 @@
namespace proxy {
extern macro ProxiesCodeStubAssembler::AllocateProxy(
JSReceiver, JSReceiver, Context): JSProxy;
macro AllocateProxy(implicit context: Context)(
target: JSReceiver, handler: JSReceiver): JSProxy {
return AllocateProxy(target, handler, context);
}
extern macro ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(
Object, Object): JSFunction;
macro AllocateProxyRevokeFunction(implicit context: Context)(proxy: JSProxy):
......@@ -20,18 +13,6 @@ namespace proxy {
return AllocateProxyRevokeFunction(proxy, context);
}
macro IsRevokedProxy(implicit context: Context)(o: JSReceiver): bool {
try {
const proxy: JSProxy = Cast<JSProxy>(o) otherwise ReturnFalse;
const handler: JSReceiver =
Cast<JSReceiver>(proxy.handler) otherwise ReturnFalse;
return true;
}
label ReturnFalse {
return false;
}
}
// Proxy.revocable(target, handler)
// https://tc39.github.io/ecma262/#sec-proxy.revocable
transitioning javascript builtin
......
......@@ -6,15 +6,6 @@
namespace proxy {
macro ValidateProxy(context: Context, o: Object, method: String): JSProxy {
try {
return Cast<JSProxy>(o) otherwise CastError;
}
label CastError {
ThrowTypeError(kIncompatibleMethodReceiver, method);
}
}
// Proxy Revocation Functions
// https://tc39.github.io/ecma262/#sec-proxy-revocation-functions
// TODO(v8:9007) remove receiver in argument since we don't use it
......
// 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 macro ProxiesCodeStubAssembler::AllocateProxy(
JSReceiver, JSReceiver, Context): JSProxy;
macro AllocateProxy(implicit context: Context)(
target: JSReceiver, handler: JSReceiver): JSProxy {
return AllocateProxy(target, handler, context);
}
macro IsRevokedProxy(implicit context: Context)(o: JSReceiver): bool {
const proxy: JSProxy = Cast<JSProxy>(o) otherwise return false;
const handler: JSReceiver =
Cast<JSReceiver>(proxy.handler) otherwise return true;
return false;
}
}
......@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(function testNewTarget() {
assertThrows(function(){ Proxy({}, {}); }, TypeError);
assertDoesNotThrow(function(){ new Proxy({}, {}); });
})();
(function testNonObjectTargetTypes() {
assertThrows(function(){ new Proxy(undefined, {}); }, TypeError);
......
......@@ -21,3 +21,9 @@ assertEquals(undefined, revoke());
for (var trap of traps) {
assertThrows(() => Reflect[trap](proxy), TypeError);
}
// Throw TypeError if target or handler is revoked proxy
var revocable = Proxy.revocable({}, {});
revocable.revoke();
assertThrows(function(){ Proxy.revocable(revocable.proxy, {}); }, TypeError);
assertThrows(function(){ Proxy.revocable({}, revocable.proxy); }, TypeError);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment