[builtins] Port Proxy constructor to CSA.
Rename builtins-proxy.cc to builtins-proxy-gen.cc. Bug: v8:6557, v8:6567 Change-Id: I0e52a0c0c6c9b307c33bb18ec36079bdfd4a89ef Reviewed-on: https://chromium-review.googlesource.com/565278 Commit-Queue: Maya Lekova <mslekova@google.com> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#46511}
This commit is contained in:
parent
aba708a146
commit
f2af839b19
2
BUILD.gn
2
BUILD.gn
@ -972,6 +972,7 @@ v8_source_set("v8_builtins_generators") {
|
||||
"src/builtins/builtins-object-gen.cc",
|
||||
"src/builtins/builtins-promise-gen.cc",
|
||||
"src/builtins/builtins-promise-gen.h",
|
||||
"src/builtins/builtins-proxy-gen.cc",
|
||||
"src/builtins/builtins-regexp-gen.cc",
|
||||
"src/builtins/builtins-regexp-gen.h",
|
||||
"src/builtins/builtins-sharedarraybuffer-gen.cc",
|
||||
@ -1206,7 +1207,6 @@ v8_source_set("v8_base") {
|
||||
"src/builtins/builtins-math.cc",
|
||||
"src/builtins/builtins-number.cc",
|
||||
"src/builtins/builtins-object.cc",
|
||||
"src/builtins/builtins-proxy.cc",
|
||||
"src/builtins/builtins-reflect.cc",
|
||||
"src/builtins/builtins-regexp.cc",
|
||||
"src/builtins/builtins-sharedarraybuffer.cc",
|
||||
|
@ -791,8 +791,9 @@ namespace internal {
|
||||
TFJ(PromiseRace, 1, kIterable) \
|
||||
\
|
||||
/* Proxy */ \
|
||||
CPP(ProxyConstructor) \
|
||||
CPP(ProxyConstructor_ConstructStub) \
|
||||
TFJ(ProxyConstructor, 0) \
|
||||
TFJ(ProxyConstructor_ConstructStub, \
|
||||
SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
||||
\
|
||||
/* Reflect */ \
|
||||
ASM(ReflectApply) \
|
||||
|
139
src/builtins/builtins-proxy-gen.cc
Normal file
139
src/builtins/builtins-proxy-gen.cc
Normal file
@ -0,0 +1,139 @@
|
||||
// Copyright 2016 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-utils-gen.h"
|
||||
#include "src/builtins/builtins-utils.h"
|
||||
#include "src/builtins/builtins.h"
|
||||
#include "src/code-stub-assembler.h"
|
||||
|
||||
#include "src/counters.h"
|
||||
#include "src/objects-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
using compiler::Node;
|
||||
using compiler::CodeAssembler;
|
||||
|
||||
// ES6 section 26.2.1.1 Proxy ( target, handler ) for the [[Call]] case.
|
||||
TF_BUILTIN(ProxyConstructor, CodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
|
||||
CallRuntime(Runtime::kThrowTypeError, context,
|
||||
SmiConstant(MessageTemplate::kConstructorNotFunction),
|
||||
CStringConstant("Proxy"));
|
||||
Unreachable();
|
||||
}
|
||||
|
||||
class ProxiesCodeStubAssembler : public CodeStubAssembler {
|
||||
public:
|
||||
explicit ProxiesCodeStubAssembler(compiler::CodeAssemblerState* state)
|
||||
: CodeStubAssembler(state) {}
|
||||
|
||||
Node* IsProxyRevoked(Node* proxy) {
|
||||
CSA_ASSERT(this, IsJSProxy(proxy));
|
||||
|
||||
Node* handler = LoadObjectField(proxy, JSProxy::kHandlerOffset);
|
||||
CSA_ASSERT(this, Word32Or(IsJSReceiver(handler), IsNull(handler)));
|
||||
|
||||
return IsNull(handler);
|
||||
}
|
||||
|
||||
void GotoIfProxyRevoked(Node* object, Label* if_proxy_revoked) {
|
||||
Label continue_checks(this);
|
||||
GotoIfNot(IsJSProxy(object), &continue_checks);
|
||||
GotoIf(IsProxyRevoked(object), if_proxy_revoked);
|
||||
Goto(&continue_checks);
|
||||
BIND(&continue_checks);
|
||||
}
|
||||
|
||||
Node* AllocateProxy(Node* target, Node* handler, Node* context) {
|
||||
VARIABLE(map, MachineRepresentation::kTagged);
|
||||
|
||||
Label callable_target(this), constructor_target(this), none_target(this),
|
||||
create_proxy(this);
|
||||
|
||||
Node* nativeContext = LoadNativeContext(context);
|
||||
|
||||
GotoIf(IsCallable(target), &callable_target);
|
||||
Goto(&none_target);
|
||||
|
||||
BIND(&callable_target);
|
||||
{
|
||||
// Every object that is a constructor is implicitly callable
|
||||
// so it's okay to nest this check here
|
||||
GotoIf(IsConstructor(target), &constructor_target);
|
||||
map.Bind(
|
||||
LoadContextElement(nativeContext, Context::PROXY_CALLABLE_MAP_INDEX));
|
||||
Goto(&create_proxy);
|
||||
}
|
||||
BIND(&constructor_target);
|
||||
{
|
||||
map.Bind(LoadContextElement(nativeContext,
|
||||
Context::PROXY_CONSTRUCTOR_MAP_INDEX));
|
||||
Goto(&create_proxy);
|
||||
}
|
||||
BIND(&none_target);
|
||||
{
|
||||
map.Bind(LoadContextElement(nativeContext, Context::PROXY_MAP_INDEX));
|
||||
Goto(&create_proxy);
|
||||
}
|
||||
|
||||
BIND(&create_proxy);
|
||||
Node* proxy = Allocate(JSProxy::kSize);
|
||||
StoreMapNoWriteBarrier(proxy, map.value());
|
||||
StoreObjectFieldRoot(proxy, JSProxy::kPropertiesOffset,
|
||||
Heap::kEmptyPropertiesDictionaryRootIndex);
|
||||
StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kTargetOffset, target);
|
||||
StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kHandlerOffset, handler);
|
||||
StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kHashOffset,
|
||||
UndefinedConstant());
|
||||
|
||||
return proxy;
|
||||
}
|
||||
};
|
||||
|
||||
// ES6 section 26.2.1.1 Proxy ( target, handler ) for the [[Construct]] case.
|
||||
TF_BUILTIN(ProxyConstructor_ConstructStub, ProxiesCodeStubAssembler) {
|
||||
int const kTargetArg = 0;
|
||||
int const kHandlerArg = 1;
|
||||
|
||||
Node* argc =
|
||||
ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount));
|
||||
CodeStubArguments args(this, argc);
|
||||
|
||||
Node* target = args.GetOptionalArgumentValue(kTargetArg);
|
||||
Node* handler = args.GetOptionalArgumentValue(kHandlerArg);
|
||||
Node* context = Parameter(BuiltinDescriptor::kContext);
|
||||
|
||||
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);
|
||||
GotoIfProxyRevoked(target, &throw_proxy_handler_or_target_revoked);
|
||||
|
||||
GotoIf(TaggedIsSmi(handler), &throw_proxy_non_object);
|
||||
GotoIfNot(IsJSReceiver(handler), &throw_proxy_non_object);
|
||||
GotoIfProxyRevoked(handler, &throw_proxy_handler_or_target_revoked);
|
||||
|
||||
args.PopAndReturn(AllocateProxy(target, handler, context));
|
||||
|
||||
BIND(&throw_proxy_non_object);
|
||||
{
|
||||
CallRuntime(Runtime::kThrowTypeError, context,
|
||||
SmiConstant(MessageTemplate::kProxyNonObject));
|
||||
Unreachable();
|
||||
}
|
||||
|
||||
BIND(&throw_proxy_handler_or_target_revoked);
|
||||
{
|
||||
CallRuntime(Runtime::kThrowTypeError, context,
|
||||
SmiConstant(MessageTemplate::kProxyHandlerOrTargetRevoked));
|
||||
Unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
@ -1,33 +0,0 @@
|
||||
// Copyright 2016 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.h"
|
||||
#include "src/builtins/builtins-utils.h"
|
||||
|
||||
#include "src/counters.h"
|
||||
#include "src/objects-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// ES6 section 26.2.1.1 Proxy ( target, handler ) for the [[Call]] case.
|
||||
BUILTIN(ProxyConstructor) {
|
||||
HandleScope scope(isolate);
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate,
|
||||
NewTypeError(MessageTemplate::kConstructorNotFunction,
|
||||
isolate->factory()->NewStringFromAsciiChecked("Proxy")));
|
||||
}
|
||||
|
||||
// ES6 section 26.2.1.1 Proxy ( target, handler ) for the [[Construct]] case.
|
||||
BUILTIN(ProxyConstructor_ConstructStub) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(isolate->proxy_function()->IsConstructor());
|
||||
Handle<Object> target = args.atOrUndefined(isolate, 1);
|
||||
Handle<Object> handler = args.atOrUndefined(isolate, 2);
|
||||
RETURN_RESULT_OR_FAILURE(isolate, JSProxy::New(isolate, target, handler));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
@ -3070,7 +3070,7 @@ Node* CodeStubAssembler::ToThisValue(Node* context, Node* value,
|
||||
? &done_loop
|
||||
: &done_throw);
|
||||
|
||||
// Load the mape of the {value}.
|
||||
// Load the map of the {value}.
|
||||
Node* value_map = LoadMap(value);
|
||||
|
||||
// Load the instance type of the {value}.
|
||||
@ -3298,6 +3298,13 @@ Node* CodeStubAssembler::IsJSObject(Node* object) {
|
||||
return IsJSObjectMap(LoadMap(object));
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsJSProxy(Node* object) {
|
||||
Node* object_map = LoadMap(object);
|
||||
Node* object_instance_type = LoadMapInstanceType(object_map);
|
||||
|
||||
return InstanceTypeEqual(object_instance_type, JS_PROXY_TYPE);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsJSGlobalProxy(Node* object) {
|
||||
return Word32Equal(LoadInstanceType(object),
|
||||
Int32Constant(JS_GLOBAL_PROXY_TYPE));
|
||||
|
@ -805,6 +805,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
Node* IsJSGlobalProxy(Node* object);
|
||||
Node* IsJSObjectMap(Node* map);
|
||||
Node* IsJSObject(Node* object);
|
||||
Node* IsJSProxy(Node* object);
|
||||
Node* IsJSReceiverInstanceType(Node* instance_type);
|
||||
Node* IsJSReceiverMap(Node* map);
|
||||
Node* IsJSReceiver(Node* object);
|
||||
|
@ -207,6 +207,7 @@
|
||||
'builtins/builtins-object-gen.cc',
|
||||
'builtins/builtins-promise-gen.cc',
|
||||
'builtins/builtins-promise-gen.h',
|
||||
'builtins/builtins-proxy-gen.cc',
|
||||
'builtins/builtins-regexp-gen.cc',
|
||||
'builtins/builtins-regexp-gen.h',
|
||||
'builtins/builtins-sharedarraybuffer-gen.cc',
|
||||
@ -645,7 +646,6 @@
|
||||
'builtins/builtins-math.cc',
|
||||
'builtins/builtins-number.cc',
|
||||
'builtins/builtins-object.cc',
|
||||
'builtins/builtins-proxy.cc',
|
||||
'builtins/builtins-reflect.cc',
|
||||
'builtins/builtins-regexp.cc',
|
||||
'builtins/builtins-sharedarraybuffer.cc',
|
||||
|
@ -47,3 +47,50 @@
|
||||
|
||||
assertThrows(function(){ new Proxy({}, revocable.proxy); }, TypeError);
|
||||
})();
|
||||
|
||||
|
||||
(function testConstructionWithoutArguments() {
|
||||
assertThrows(function(){ new Proxy(); }, TypeError);
|
||||
|
||||
assertThrows(function(){ new Proxy(42); }, TypeError);
|
||||
|
||||
assertThrows(function(){ new Proxy({}); }, TypeError);
|
||||
})();
|
||||
|
||||
|
||||
(function testConstructionFromArray() {
|
||||
var p = new Proxy([42], {});
|
||||
assertTrue(p instanceof Array);
|
||||
assertEquals(p[0], 42);
|
||||
})();
|
||||
|
||||
|
||||
(function testConstructionFromObject() {
|
||||
var p = new Proxy({
|
||||
prop: 42
|
||||
}, {});
|
||||
assertTrue(p instanceof Object);
|
||||
assertEquals(p.prop, 42);
|
||||
})();
|
||||
|
||||
|
||||
(function testConstructionFromCallable() {
|
||||
var p = new Proxy(() => { return 42; }, {});
|
||||
assertTrue(p instanceof Function);
|
||||
assertEquals(p(), 42);
|
||||
})();
|
||||
|
||||
|
||||
(function testConstructionFromConstructor() {
|
||||
class foo {};
|
||||
var p = new Proxy(foo, {});
|
||||
assertTrue(p instanceof Function);
|
||||
assertTrue(new p() instanceof foo);
|
||||
})();
|
||||
|
||||
|
||||
(function testConstructionFromProxy() {
|
||||
var q = new Proxy({}, {});
|
||||
var p = new Proxy(q, {});
|
||||
assertTrue(p instanceof Object);
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user