Port Proxy.revocable to Torque
This is a part of porting Proxy-related builtins to Torque. Spec: https://tc39.github.io/ecma262/#sec-proxy.revocable Bug: v8:6664 Change-Id: I5f53eb4dff8ff9d3156b601652f3f86ede25fc1d Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1529261 Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com> Reviewed-by: Maya Lekova <mslekova@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#60613}
This commit is contained in:
parent
4415b1d112
commit
253ce6e188
1
BUILD.gn
1
BUILD.gn
@ -939,6 +939,7 @@ torque_files = [
|
||||
"src/builtins/extras-utils.tq",
|
||||
"src/builtins/iterator.tq",
|
||||
"src/builtins/object-fromentries.tq",
|
||||
"src/builtins/proxy-revocable.tq",
|
||||
"src/builtins/proxy-revoke.tq",
|
||||
"src/builtins/regexp.tq",
|
||||
"src/builtins/regexp-replace.tq",
|
||||
|
@ -166,6 +166,14 @@ macro NewJSObject(implicit context: Context)(): JSObject {
|
||||
return new JSObject{map, kEmptyFixedArray, kEmptyFixedArray};
|
||||
}
|
||||
|
||||
extern class JSFunction extends JSObject {
|
||||
shared_function_info: SharedFunctionInfo;
|
||||
context: Context;
|
||||
feedback_cell: Smi;
|
||||
weak code: Code;
|
||||
weak prototype_or_initial_map: JSReceiver | Map;
|
||||
}
|
||||
|
||||
extern class JSProxy extends JSReceiver {
|
||||
target: Object;
|
||||
handler: Object;
|
||||
@ -176,6 +184,17 @@ extern class JSProxyRevocableResult extends JSObject {
|
||||
revoke: Object;
|
||||
}
|
||||
|
||||
macro NewJSProxyRevocableResult(implicit context: Context)(
|
||||
proxy: JSProxy, revoke: JSFunction): JSProxyRevocableResult {
|
||||
return new JSProxyRevocableResult{
|
||||
GetProxyRevocableResultMap(), // HeapObject.map
|
||||
kEmptyFixedArray, // JSReceiver.properties_or_hash
|
||||
kEmptyFixedArray, // JSObject.elements
|
||||
proxy, // JSProxyRevocableResult.proxy
|
||||
revoke // JSProxyRevocableResult.revoke
|
||||
};
|
||||
}
|
||||
|
||||
extern class JSGlobalProxy extends JSObject { native_context: Object; }
|
||||
|
||||
extern class JSValue extends JSObject { value: Object; }
|
||||
@ -307,14 +326,6 @@ extern class SharedFunctionInfoWithID extends SharedFunctionInfo {
|
||||
unique_id: int32;
|
||||
}
|
||||
|
||||
extern class JSFunction extends JSObject {
|
||||
shared_function_info: SharedFunctionInfo;
|
||||
context: Context;
|
||||
feedback_cell: Smi;
|
||||
weak code: Code;
|
||||
weak prototype_or_initial_map: JSReceiver | Map;
|
||||
}
|
||||
|
||||
extern class JSBoundFunction extends JSObject {
|
||||
bound_target_function: JSReceiver;
|
||||
bound_this: Object;
|
||||
@ -363,6 +374,8 @@ const ITERATOR_RESULT_MAP_INDEX: constexpr NativeContextSlot
|
||||
generates 'Context::ITERATOR_RESULT_MAP_INDEX';
|
||||
const JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX: constexpr NativeContextSlot
|
||||
generates 'Context::JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX';
|
||||
const PROXY_REVOCABLE_RESULT_MAP_INDEX: constexpr NativeContextSlot
|
||||
generates 'Context::PROXY_REVOCABLE_RESULT_MAP_INDEX';
|
||||
extern operator '[]' macro LoadContextElement(
|
||||
NativeContext, NativeContextSlot): Object;
|
||||
extern operator '[]=' macro StoreContextElement(
|
||||
@ -706,6 +719,10 @@ const kTypedArrayTooShort: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kTypedArrayTooShort';
|
||||
const kInvalidCountValue: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kInvalidCountValue';
|
||||
const kProxyNonObject: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kProxyNonObject';
|
||||
const kProxyHandlerOrTargetRevoked: constexpr MessageTemplate
|
||||
generates 'MessageTemplate::kProxyHandlerOrTargetRevoked';
|
||||
|
||||
const kMaxArrayIndex:
|
||||
constexpr uint32 generates 'JSArray::kMaxArrayIndex';
|
||||
@ -1839,6 +1856,11 @@ macro GetFastPackedSmiElementsJSArrayMap(implicit context: Context)(): Map {
|
||||
LoadNativeContext(context)[JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX]);
|
||||
}
|
||||
|
||||
macro GetProxyRevocableResultMap(implicit context: Context)(): Map {
|
||||
return UnsafeCast<Map>(
|
||||
LoadNativeContext(context)[PROXY_REVOCABLE_RESULT_MAP_INDEX]);
|
||||
}
|
||||
|
||||
extern transitioning macro Call(Context, Callable, Object): Object;
|
||||
extern transitioning macro Call(Context, Callable, Object, Object): Object;
|
||||
extern transitioning macro Call(
|
||||
|
@ -867,7 +867,6 @@ namespace internal {
|
||||
\
|
||||
/* Proxy */ \
|
||||
TFJ(ProxyConstructor, 2, kReceiver, kTarget, kHandler) \
|
||||
TFJ(ProxyRevocable, 2, kReceiver, kTarget, kHandler) \
|
||||
TFS(ProxyGetProperty, kProxy, kName, kReceiverValue, kOnNonExistent) \
|
||||
TFS(ProxyHasProperty, kProxy, kName) \
|
||||
TFS(ProxySetProperty, kProxy, kName, kValue, kReceiverValue) \
|
||||
|
@ -204,48 +204,6 @@ TF_BUILTIN(ProxyConstructor, ProxiesCodeStubAssembler) {
|
||||
}
|
||||
}
|
||||
|
||||
TF_BUILTIN(ProxyRevocable, ProxiesCodeStubAssembler) {
|
||||
Node* const target = Parameter(Descriptor::kTarget);
|
||||
Node* const handler = Parameter(Descriptor::kHandler);
|
||||
Node* const context = Parameter(Descriptor::kContext);
|
||||
Node* const native_context = LoadNativeContext(context);
|
||||
|
||||
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);
|
||||
|
||||
Node* const proxy = AllocateProxy(target, handler, context);
|
||||
Node* const revoke = AllocateProxyRevokeFunction(proxy, context);
|
||||
|
||||
Node* const result = Allocate(JSProxyRevocableResult::kSize);
|
||||
Node* const result_map = LoadContextElement(
|
||||
native_context, Context::PROXY_REVOCABLE_RESULT_MAP_INDEX);
|
||||
StoreMapNoWriteBarrier(result, result_map);
|
||||
StoreObjectFieldRoot(result, JSProxyRevocableResult::kPropertiesOrHashOffset,
|
||||
RootIndex::kEmptyFixedArray);
|
||||
StoreObjectFieldRoot(result, JSProxyRevocableResult::kElementsOffset,
|
||||
RootIndex::kEmptyFixedArray);
|
||||
StoreObjectFieldNoWriteBarrier(result, JSProxyRevocableResult::kProxyOffset,
|
||||
proxy);
|
||||
StoreObjectFieldNoWriteBarrier(result, JSProxyRevocableResult::kRevokeOffset,
|
||||
revoke);
|
||||
Return(result);
|
||||
|
||||
BIND(&throw_proxy_non_object);
|
||||
ThrowTypeError(context, MessageTemplate::kProxyNonObject);
|
||||
|
||||
BIND(&throw_proxy_handler_or_target_revoked);
|
||||
ThrowTypeError(context, MessageTemplate::kProxyHandlerOrTargetRevoked);
|
||||
}
|
||||
|
||||
TF_BUILTIN(CallProxy, ProxiesCodeStubAssembler) {
|
||||
Node* argc = Parameter(Descriptor::kActualArgumentsCount);
|
||||
Node* argc_ptr = ChangeInt32ToIntPtr(argc);
|
||||
|
@ -27,6 +27,9 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler {
|
||||
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);
|
||||
|
||||
protected:
|
||||
enum ProxyRevokeFunctionContextSlot {
|
||||
kProxySlot = Context::MIN_CONTEXT_SLOTS,
|
||||
@ -34,11 +37,9 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler {
|
||||
};
|
||||
|
||||
void GotoIfRevokedProxy(Node* object, Label* if_proxy_revoked);
|
||||
Node* AllocateProxy(Node* target, Node* handler, Node* context);
|
||||
Node* AllocateJSArrayForCodeStubArguments(Node* context,
|
||||
CodeStubArguments& args, Node* argc,
|
||||
ParameterMode mode);
|
||||
Node* AllocateProxyRevokeFunction(Node* proxy, Node* context);
|
||||
void CheckHasTrapResult(Node* context, Node* target, Node* proxy, Node* name,
|
||||
Label* check_passed, Label* if_bailout);
|
||||
|
||||
|
76
src/builtins/proxy-revocable.tq
Normal file
76
src/builtins/proxy-revocable.tq
Normal file
@ -0,0 +1,76 @@
|
||||
// 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);
|
||||
}
|
||||
|
||||
extern macro ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(
|
||||
Object, Object): JSFunction;
|
||||
macro AllocateProxyRevokeFunction(implicit context: Context)(proxy: JSProxy):
|
||||
JSFunction {
|
||||
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
|
||||
ProxyRevocable(
|
||||
context: Context, receiver: Object, target: Object,
|
||||
handler: Object): JSProxyRevocableResult {
|
||||
try {
|
||||
const targetJSReceiver =
|
||||
Cast<JSReceiver>(target) otherwise ThrowProxyNonObject;
|
||||
if (IsRevokedProxy(targetJSReceiver)) {
|
||||
goto ThrowProxyHandlerOrTargetRevoked;
|
||||
}
|
||||
|
||||
const handlerJSReceiver =
|
||||
Cast<JSReceiver>(handler) otherwise ThrowProxyNonObject;
|
||||
if (IsRevokedProxy(handlerJSReceiver)) {
|
||||
goto ThrowProxyHandlerOrTargetRevoked;
|
||||
}
|
||||
|
||||
// 1. Let p be ? ProxyCreate(target, handler).
|
||||
const proxy: JSProxy = AllocateProxy(targetJSReceiver, handlerJSReceiver);
|
||||
|
||||
// 2. Let steps be the algorithm steps defined in Proxy Revocation
|
||||
// Functions.
|
||||
// 3. Let revoker be CreateBuiltinFunction(steps, « [[RevocableProxy]] »).
|
||||
// 4. Set revoker.[[RevocableProxy]] to p.
|
||||
const revoke: JSFunction = AllocateProxyRevokeFunction(proxy);
|
||||
|
||||
// 5. Let result be ObjectCreate(%ObjectPrototype%).
|
||||
// 6. Perform CreateDataProperty(result, "proxy", p).
|
||||
// 7. Perform CreateDataProperty(result, "revoke", revoker).
|
||||
// 8. Return result.
|
||||
return NewJSProxyRevocableResult(proxy, revoke);
|
||||
}
|
||||
label ThrowProxyNonObject deferred {
|
||||
ThrowTypeError(kProxyNonObject, 'Proxy.revocable');
|
||||
}
|
||||
label ThrowProxyHandlerOrTargetRevoked deferred {
|
||||
ThrowTypeError(kProxyHandlerOrTargetRevoked, 'Proxy.revocable');
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user