Reland of Port ProxyHasProperty to Torque

Refactor CheckHasTrapResult as well.

Spec: https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p
Bug: v8:6664
Change-Id: Iaa9c1cb46ab4f7c8139dfe1380b3ec807a4719ee
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1610215
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#61546}
This commit is contained in:
Z Duong Nguyen-Huu 2019-05-14 11:38:43 -07:00 committed by Commit Bot
parent f52e8ee4f4
commit 94b2c12119
9 changed files with 83 additions and 93 deletions

View File

@ -950,9 +950,10 @@ 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-has-property.tq",
"src/builtins/proxy-revocable.tq",
"src/builtins/proxy-revoke.tq",
"src/builtins/proxy-set-property.tq",
"src/builtins/proxy.tq",
"src/builtins/regexp-replace.tq",
"src/builtins/regexp.tq",

View File

@ -1285,7 +1285,7 @@ extern transitioning builtin SetPropertyInLiteral(implicit context: Context)(
extern transitioning builtin DeleteProperty(implicit context: Context)(
Object, Object, LanguageMode);
extern transitioning builtin HasProperty(implicit context: Context)(
JSReceiver, Object): Boolean;
Object, Object): Boolean;
extern transitioning macro HasProperty_Inline(implicit context: Context)(
JSReceiver, Object): Boolean;
@ -2570,6 +2570,7 @@ macro NewFastJSArrayWitness(array: FastJSArray): FastJSArrayWitness {
extern macro TransitionElementsKind(
JSObject, Map, constexpr ElementsKind,
constexpr ElementsKind): void labels Bailout;
extern macro PerformStackCheck(implicit context: Context)(): void;
extern macro IsCallable(HeapObject): bool;
extern macro IsConstructor(HeapObject): bool;

View File

@ -822,9 +822,6 @@ namespace internal {
/* V8 Extras: v8.resolvePromise(promise, resolution) */ \
TFJ(PromiseInternalResolve, 2, kReceiver, kPromise, kResolution) \
\
/* Proxy */ \
TFS(ProxyHasProperty, kProxy, kName) \
\
/* Reflect */ \
ASM(ReflectApply, Dummy) \
ASM(ReflectConstruct, Dummy) \

View File

@ -262,82 +262,6 @@ TF_BUILTIN(ConstructProxy, ProxiesCodeStubAssembler) {
{ ThrowTypeError(context, MessageTemplate::kProxyRevoked, "construct"); }
}
TF_BUILTIN(ProxyHasProperty, ProxiesCodeStubAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* proxy = Parameter(Descriptor::kProxy);
Node* name = Parameter(Descriptor::kName);
CSA_ASSERT(this, IsJSProxy(proxy));
PerformStackCheck(CAST(context));
// 1. Assert: IsPropertyKey(P) is true.
CSA_ASSERT(this, IsName(name));
CSA_ASSERT(this, Word32Equal(IsPrivateSymbol(name), Int32Constant(0)));
Label throw_proxy_handler_revoked(this, Label::kDeferred),
trap_undefined(this),
if_try_get_own_property_bailout(this, Label::kDeferred),
trap_not_callable(this, Label::kDeferred), return_true(this),
return_false(this), check_target_desc(this);
// 2. Let handler be O.[[ProxyHandler]].
Node* handler = LoadObjectField(proxy, JSProxy::kHandlerOffset);
// 3. If handler is null, throw a TypeError exception.
// 4. Assert: Type(handler) is Object.
GotoIfNot(IsJSReceiver(handler), &throw_proxy_handler_revoked);
// 5. Let target be O.[[ProxyTarget]].
Node* target = LoadObjectField(proxy, JSProxy::kTargetOffset);
// 6. Let trap be ? GetMethod(handler, "has").
// 7. If trap is undefined, then (see 7.a below).
Handle<Name> trap_name = factory()->has_string();
Node* trap = GetMethod(context, handler, trap_name, &trap_undefined);
GotoIf(TaggedIsSmi(trap), &trap_not_callable);
GotoIfNot(IsCallable(trap), &trap_not_callable);
// 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P
// »)).
BranchIfToBooleanIsTrue(CallJS(CodeFactory::Call(isolate()), context, trap,
handler, target, name),
&return_true, &check_target_desc);
BIND(&check_target_desc);
{
// 9. If booleanTrapResult is false, then (see 9.a. in CheckHasTrapResult).
CheckHasTrapResult(context, target, proxy, name, &return_false,
&if_try_get_own_property_bailout);
}
BIND(&if_try_get_own_property_bailout);
{
CallRuntime(Runtime::kCheckProxyHasTrap, context, name, target);
Return(FalseConstant());
}
BIND(&trap_undefined);
{
// 7.a. Return ? target.[[HasProperty]](P).
TailCallBuiltin(Builtins::kHasProperty, context, target, name);
}
BIND(&return_false);
Return(FalseConstant());
BIND(&return_true);
Return(TrueConstant());
BIND(&throw_proxy_handler_revoked);
ThrowTypeError(context, MessageTemplate::kProxyRevoked, "has");
BIND(&trap_not_callable);
ThrowTypeError(context, MessageTemplate::kPropertyNotFunction, trap,
StringConstant("has"), proxy);
}
Node* ProxiesCodeStubAssembler::CheckGetSetTrapResult(
Node* context, Node* target, Node* proxy, Node* name, Node* trap_result,
JSProxy::AccessKind access_kind) {
@ -446,10 +370,8 @@ Node* ProxiesCodeStubAssembler::CheckGetSetTrapResult(
}
}
void ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target,
Node* proxy, Node* name,
Label* check_passed,
Label* if_bailout) {
Node* ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target,
Node* proxy, Node* name) {
Node* target_map = LoadMap(target);
VARIABLE(var_value, MachineRepresentation::kTagged);
VARIABLE(var_details, MachineRepresentation::kWord32);
@ -457,14 +379,15 @@ void ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target,
Label if_found_value(this, Label::kDeferred),
throw_non_configurable(this, Label::kDeferred),
throw_non_extensible(this, Label::kDeferred);
throw_non_extensible(this, Label::kDeferred), check_passed(this),
check_in_runtime(this, Label::kDeferred);
// 9.a. Let targetDesc be ? target.[[GetOwnProperty]](P).
GotoIfNot(IsUniqueNameNoIndex(CAST(name)), if_bailout);
GotoIfNot(IsUniqueNameNoIndex(CAST(name)), &check_in_runtime);
Node* instance_type = LoadInstanceType(target);
TryGetOwnProperty(context, target, target, target_map, instance_type, name,
&if_found_value, &var_value, &var_details, &var_raw_value,
check_passed, if_bailout, kReturnAccessorPair);
&check_passed, &check_in_runtime, kReturnAccessorPair);
// 9.b. If targetDesc is not undefined, then (see 9.b.i. below).
BIND(&if_found_value);
@ -480,7 +403,7 @@ void ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target,
// 9.b.iii. If extensibleTarget is false, throw a TypeError exception.
GotoIfNot(target_extensible, &throw_non_extensible);
Goto(check_passed);
Goto(&check_passed);
}
BIND(&throw_non_configurable);
@ -488,6 +411,15 @@ void ProxiesCodeStubAssembler::CheckHasTrapResult(Node* context, Node* target,
BIND(&throw_non_extensible);
{ ThrowTypeError(context, MessageTemplate::kProxyHasNonExtensible, name); }
BIND(&check_in_runtime);
{
CallRuntime(Runtime::kCheckProxyHasTrapResult, context, name, target);
Goto(&check_passed);
}
BIND(&check_passed);
return FalseConstant();
}
} // namespace internal

View File

@ -29,6 +29,9 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler {
Node* name, Node* trap_result,
JSProxy::AccessKind access_kind);
Node* CheckHasTrapResult(Node* context, Node* target, Node* proxy,
Node* name);
protected:
enum ProxyRevokeFunctionContextSlot {
kProxySlot = Context::MIN_CONTEXT_SLOTS,
@ -38,8 +41,6 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler {
Node* AllocateJSArrayForCodeStubArguments(Node* context,
CodeStubArguments& args, Node* argc,
ParameterMode mode);
void CheckHasTrapResult(Node* context, Node* target, Node* proxy, Node* name,
Label* check_passed, Label* if_bailout);
private:
Node* CreateProxyRevokeFunctionContext(Node* proxy, Node* native_context);

View File

@ -0,0 +1,55 @@
// 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 {
// ES #sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p
// https://tc39.github.io/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p
transitioning builtin ProxyHasProperty(implicit context: Context)(
proxy: JSProxy, name: Name): Object {
assert(IsJSProxy(proxy));
PerformStackCheck();
// 1. Assert: IsPropertyKey(P) is true.
assert(IsName(name));
assert(!IsPrivateSymbol(name));
try {
// 2. Let handler be O.[[ProxyHandler]].
// 3. If handler is null, throw a TypeError exception.
// 4. Assert: Type(handler) is Object.
const handler =
Cast<JSReceiver>(proxy.handler) otherwise ThrowProxyHandlerRevoked;
// 5. Let target be O.[[ProxyTarget]].
const target = proxy.target;
// 6. Let trap be ? GetMethod(handler, "has").
// 7. If trap is undefined, then (see 7.a below).
const trap: Callable = GetMethod(handler, 'has')
otherwise goto TrapUndefined(target);
// 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, «
// target»)).
// 9. If booleanTrapResult is false, then (see 9.a. in
// CheckHasTrapResult).
// 10. Return booleanTrapResult.
const trapResult = Call(context, trap, handler, target, name);
if (BranchIfToBooleanIsTrue(trapResult)) {
return True;
}
return CheckHasTrapResult(target, proxy, name);
}
label TrapUndefined(target: Object) {
// 7.a. Return ? target.[[HasProperty]](P).
tail HasProperty(target, name);
}
label ThrowProxyHandlerRevoked deferred {
ThrowTypeError(kProxyRevoked, 'has');
}
}
}

View File

@ -24,6 +24,9 @@ namespace proxy {
implicit context:
Context)(Object, JSProxy, Name, Object, constexpr int31): Object;
extern transitioning macro ProxiesCodeStubAssembler::CheckHasTrapResult(
implicit context: Context)(Object, JSProxy, Name): Object;
const kProxyNonObject: constexpr MessageTemplate
generates 'MessageTemplate::kProxyNonObject';
const kProxyHandlerOrTargetRevoked: constexpr MessageTemplate

View File

@ -98,7 +98,7 @@ RUNTIME_FUNCTION(Runtime_CheckProxyGetSetTrapResult) {
JSProxy::AccessKind(access_kind)));
}
RUNTIME_FUNCTION(Runtime_CheckProxyHasTrap) {
RUNTIME_FUNCTION(Runtime_CheckProxyHasTrapResult) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());

View File

@ -361,7 +361,7 @@ namespace internal {
#define FOR_EACH_INTRINSIC_PROXY(F, I) \
F(CheckProxyGetSetTrapResult, 2, 1) \
F(CheckProxyHasTrap, 2, 1) \
F(CheckProxyHasTrapResult, 2, 1) \
F(GetPropertyWithReceiver, 3, 1) \
F(IsJSProxy, 1, 1) \
F(JSProxyGetHandler, 1, 1) \