Skip to content

Commit 03953f5

Browse files
isheludkoCommit bot
authored andcommitted
Convert receiver when calling an Api accessor.
BUG=chromium:590071 LOG=N Review URL: https://codereview.chromium.org/1856123005 Cr-Commit-Position: refs/heads/master@{#35282}
1 parent 7f34421 commit 03953f5

3 files changed

Lines changed: 61 additions & 11 deletions

File tree

src/builtins.cc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4366,6 +4366,20 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function,
43664366
Handle<Object> receiver,
43674367
int argc,
43684368
Handle<Object> args[]) {
4369+
Isolate* isolate = function->GetIsolate();
4370+
// Do proper receiver conversion for non-strict mode api functions.
4371+
if (!receiver->IsJSReceiver()) {
4372+
DCHECK(function->IsFunctionTemplateInfo() || function->IsJSFunction());
4373+
if (function->IsFunctionTemplateInfo() ||
4374+
is_sloppy(JSFunction::cast(*function)->shared()->language_mode())) {
4375+
if (receiver->IsUndefined() || receiver->IsNull()) {
4376+
receiver = handle(isolate->global_proxy(), isolate);
4377+
} else {
4378+
ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
4379+
Object::ToObject(isolate, receiver), Object);
4380+
}
4381+
}
4382+
}
43694383
// Construct BuiltinArguments object: function, arguments reversed, receiver.
43704384
const int kBufferSize = 32;
43714385
Object* small_argv[kBufferSize];
@@ -4382,7 +4396,6 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Handle<HeapObject> function,
43824396
argv[0] = *function;
43834397
MaybeHandle<Object> result;
43844398
{
4385-
auto isolate = function->GetIsolate();
43864399
RelocatableArguments arguments(isolate, argc + 2, &argv[argc + 1]);
43874400
result = HandleApiCallHelper<false>(isolate, arguments);
43884401
}

src/execution.cc

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,6 @@ MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
138138
Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
139139
SaveContext save(isolate);
140140
isolate->set_context(function->context());
141-
// Do proper receiver conversion for non-strict mode api functions.
142-
if (!receiver->IsJSReceiver() &&
143-
is_sloppy(function->shared()->language_mode())) {
144-
if (receiver->IsUndefined() || receiver->IsNull()) {
145-
receiver = handle(function->global_proxy(), isolate);
146-
} else {
147-
ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
148-
Object::ToObject(isolate, receiver), Object);
149-
}
150-
}
151141
DCHECK(function->context()->global_object()->IsJSGlobalObject());
152142
auto value = Builtins::InvokeApiFunction(function, receiver, argc, argv);
153143
bool has_exception = value.is_null();

test/cctest/test-api.cc

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24658,6 +24658,53 @@ TEST(CompatibleReceiverCheckOnCachedICHandler) {
2465824658
0);
2465924659
}
2466024660

24661+
THREADED_TEST(ReceiverConversionForAccessors) {
24662+
LocalContext env;
24663+
v8::Isolate* isolate = CcTest::isolate();
24664+
v8::HandleScope scope(isolate);
24665+
Local<v8::FunctionTemplate> acc =
24666+
v8::FunctionTemplate::New(isolate, Returns42);
24667+
CHECK(env->Global()
24668+
->Set(env.local(), v8_str("acc"),
24669+
acc->GetFunction(env.local()).ToLocalChecked())
24670+
.FromJust());
24671+
24672+
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
24673+
templ->SetAccessorProperty(v8_str("acc"), acc, acc);
24674+
Local<v8::Object> instance = templ->NewInstance(env.local()).ToLocalChecked();
24675+
24676+
CHECK(env->Global()->Set(env.local(), v8_str("p"), instance).FromJust());
24677+
CHECK(CompileRun("(p.acc == 42)")->BooleanValue(env.local()).FromJust());
24678+
CHECK(CompileRun("(p.acc = 7) == 7")->BooleanValue(env.local()).FromJust());
24679+
24680+
CHECK(!CompileRun("Number.prototype.__proto__ = p;"
24681+
"var a = 1;")
24682+
.IsEmpty());
24683+
CHECK(CompileRun("(a.acc == 42)")->BooleanValue(env.local()).FromJust());
24684+
CHECK(CompileRun("(a.acc = 7) == 7")->BooleanValue(env.local()).FromJust());
24685+
24686+
CHECK(!CompileRun("Boolean.prototype.__proto__ = p;"
24687+
"var a = true;")
24688+
.IsEmpty());
24689+
CHECK(CompileRun("(a.acc == 42)")->BooleanValue(env.local()).FromJust());
24690+
CHECK(CompileRun("(a.acc = 7) == 7")->BooleanValue(env.local()).FromJust());
24691+
24692+
CHECK(!CompileRun("String.prototype.__proto__ = p;"
24693+
"var a = 'foo';")
24694+
.IsEmpty());
24695+
CHECK(CompileRun("(a.acc == 42)")->BooleanValue(env.local()).FromJust());
24696+
CHECK(CompileRun("(a.acc = 7) == 7")->BooleanValue(env.local()).FromJust());
24697+
24698+
CHECK(CompileRun("acc.call(1) == 42")->BooleanValue(env.local()).FromJust());
24699+
CHECK(CompileRun("acc.call(true)==42")->BooleanValue(env.local()).FromJust());
24700+
CHECK(CompileRun("acc.call('aa')==42")->BooleanValue(env.local()).FromJust());
24701+
CHECK(
24702+
CompileRun("acc.call(null) == 42")->BooleanValue(env.local()).FromJust());
24703+
CHECK(CompileRun("acc.call(undefined) == 42")
24704+
->BooleanValue(env.local())
24705+
.FromJust());
24706+
}
24707+
2466124708
class FutexInterruptionThread : public v8::base::Thread {
2466224709
public:
2466324710
explicit FutexInterruptionThread(v8::Isolate* isolate)

0 commit comments

Comments
 (0)