Skip to content

Commit 105f606

Browse files
devsnektargos
authored andcommitted
v8: backport 9fb02b526f1cd3b859a530a01adb08bc0d089f4f
Refs: v8/v8@9fb02b5 Original commit message: Allow function callbacks to have Proxy as receiver. [email protected] Bug: v8:5773 Change-Id: Ifd29a1116ee8c86b8d8d24485bbfd19e260ab66b Reviewed-on: chromium-review.googlesource.com/1046088 Commit-Queue: Yang Guo <[email protected]> Reviewed-by: Camillo Bruni <[email protected]> Cr-Commit-Position: refs/heads/master@{#53015} PR-URL: #20575 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]>
1 parent 1f34c04 commit 105f606

File tree

3 files changed

+50
-21
lines changed

3 files changed

+50
-21
lines changed

common.gypi

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
# Reset this number to 0 on major V8 upgrades.
2929
# Increment by one for each non-official patch applied to deps/v8.
30-
'v8_embedder_string': '-node.6',
30+
'v8_embedder_string': '-node.7',
3131

3232
# Enable disassembler for `--print-code` v8 options
3333
'v8_enable_disassembler': 1,

deps/v8/src/builtins/builtins-api.cc

+21-20
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,21 @@ namespace {
2121
// Returns the holder JSObject if the function can legally be called with this
2222
// receiver. Returns nullptr if the call is illegal.
2323
// TODO(dcarney): CallOptimization duplicates this logic, merge.
24-
JSObject* GetCompatibleReceiver(Isolate* isolate, FunctionTemplateInfo* info,
25-
JSObject* receiver) {
24+
JSReceiver* GetCompatibleReceiver(Isolate* isolate, FunctionTemplateInfo* info,
25+
JSReceiver* receiver) {
2626
Object* recv_type = info->signature();
2727
// No signature, return holder.
2828
if (!recv_type->IsFunctionTemplateInfo()) return receiver;
29+
// A Proxy cannot have been created from the signature template.
30+
if (!receiver->IsJSObject()) return nullptr;
31+
32+
JSObject* js_obj_receiver = JSObject::cast(receiver);
2933
FunctionTemplateInfo* signature = FunctionTemplateInfo::cast(recv_type);
3034

3135
// Check the receiver. Fast path for receivers with no hidden prototypes.
32-
if (signature->IsTemplateFor(receiver)) return receiver;
33-
if (!receiver->map()->has_hidden_prototype()) return nullptr;
34-
for (PrototypeIterator iter(isolate, receiver, kStartAtPrototype,
36+
if (signature->IsTemplateFor(js_obj_receiver)) return receiver;
37+
if (!js_obj_receiver->map()->has_hidden_prototype()) return nullptr;
38+
for (PrototypeIterator iter(isolate, js_obj_receiver, kStartAtPrototype,
3539
PrototypeIterator::END_AT_NON_HIDDEN);
3640
!iter.IsAtEnd(); iter.Advance()) {
3741
JSObject* current = iter.GetCurrent<JSObject>();
@@ -45,8 +49,8 @@ MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(
4549
Isolate* isolate, Handle<HeapObject> function,
4650
Handle<HeapObject> new_target, Handle<FunctionTemplateInfo> fun_data,
4751
Handle<Object> receiver, BuiltinArguments args) {
48-
Handle<JSObject> js_receiver;
49-
JSObject* raw_holder;
52+
Handle<JSReceiver> js_receiver;
53+
JSReceiver* raw_holder;
5054
if (is_construct) {
5155
DCHECK(args.receiver()->IsTheHole(isolate));
5256
if (fun_data->instance_template()->IsUndefined(isolate)) {
@@ -68,21 +72,18 @@ MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(
6872
raw_holder = *js_receiver;
6973
} else {
7074
DCHECK(receiver->IsJSReceiver());
71-
72-
if (!receiver->IsJSObject()) {
73-
// This function cannot be called with the given receiver. Abort!
74-
THROW_NEW_ERROR(
75-
isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object);
76-
}
77-
78-
js_receiver = Handle<JSObject>::cast(receiver);
75+
js_receiver = Handle<JSReceiver>::cast(receiver);
7976

8077
if (!fun_data->accept_any_receiver() &&
81-
js_receiver->IsAccessCheckNeeded() &&
82-
!isolate->MayAccess(handle(isolate->context()), js_receiver)) {
83-
isolate->ReportFailedAccessCheck(js_receiver);
84-
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
85-
return isolate->factory()->undefined_value();
78+
js_receiver->IsAccessCheckNeeded()) {
79+
// Proxies never need access checks.
80+
DCHECK(js_receiver->IsJSObject());
81+
Handle<JSObject> js_obj_receiver = Handle<JSObject>::cast(js_receiver);
82+
if (!isolate->MayAccess(handle(isolate->context()), js_obj_receiver)) {
83+
isolate->ReportFailedAccessCheck(js_obj_receiver);
84+
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
85+
return isolate->factory()->undefined_value();
86+
}
8687
}
8788

8889
raw_holder = GetCompatibleReceiver(isolate, *fun_data, *js_receiver);

deps/v8/test/cctest/test-api.cc

+28
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,34 @@ THREADED_PROFILED_TEST(FunctionTemplate) {
10881088
TestFunctionTemplateAccessor(construct_callback, Return239Callback);
10891089
}
10901090

1091+
static void FunctionCallbackForProxyTest(
1092+
const v8::FunctionCallbackInfo<Value>& info) {
1093+
info.GetReturnValue().Set(info.This());
1094+
}
1095+
1096+
THREADED_TEST(FunctionTemplateWithProxy) {
1097+
LocalContext env;
1098+
v8::Isolate* isolate = env->GetIsolate();
1099+
v8::HandleScope scope(isolate);
1100+
1101+
v8::Local<v8::FunctionTemplate> function_template =
1102+
v8::FunctionTemplate::New(isolate, FunctionCallbackForProxyTest);
1103+
v8::Local<v8::Function> function =
1104+
function_template->GetFunction(env.local()).ToLocalChecked();
1105+
CHECK((*env)->Global()->Set(env.local(), v8_str("f"), function).FromJust());
1106+
v8::Local<v8::Value> proxy =
1107+
CompileRun("var proxy = new Proxy({}, {}); proxy");
1108+
CHECK(proxy->IsProxy());
1109+
1110+
v8::Local<v8::Value> result = CompileRun("f(proxy)");
1111+
CHECK(result->Equals(env.local(), (*env)->Global()).FromJust());
1112+
1113+
result = CompileRun("f.call(proxy)");
1114+
CHECK(result->Equals(env.local(), proxy).FromJust());
1115+
1116+
result = CompileRun("Reflect.apply(f, proxy, [1])");
1117+
CHECK(result->Equals(env.local(), proxy).FromJust());
1118+
}
10911119

10921120
static void SimpleCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
10931121
ApiTestFuzzer::Fuzz();

0 commit comments

Comments
 (0)