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:
Z Duong Nguyen-Huu 2019-04-03 09:20:17 -07:00 committed by Commit Bot
parent 4415b1d112
commit 253ce6e188
6 changed files with 110 additions and 53 deletions

View File

@ -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",

View File

@ -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(

View File

@ -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) \

View File

@ -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);

View File

@ -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);

View 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');
}
}
}