Commit a07c14f6 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[super] Fix: receiver can be null / undefined

When accessing a super property which is a getter, the receiver
is not restricted the same way as when doing normal property access.

In particular, the receiver can be null / undefined.

Bug: v8:9237, chromium:1148758, v8:11161
Change-Id: Ic6bc2053e5d046d4b19e868312aa9b50025256a1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2549941
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71281}
parent 3a21030f
......@@ -2195,9 +2195,9 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreProperty(Node* node) {
}
Node* JSNativeContextSpecialization::InlinePropertyGetterCall(
Node* receiver, Node* context, Node* frame_state, Node** effect,
Node** control, ZoneVector<Node*>* if_exceptions,
PropertyAccessInfo const& access_info) {
Node* receiver, ConvertReceiverMode receiver_mode, Node* context,
Node* frame_state, Node** effect, Node** control,
ZoneVector<Node*>* if_exceptions, PropertyAccessInfo const& access_info) {
ObjectRef constant(broker(), access_info.constant());
Node* target = jsgraph()->Constant(constant);
FrameStateInfo const& frame_info = FrameStateInfoOf(frame_state->op());
......@@ -2208,7 +2208,7 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall(
value = *effect = *control = graph()->NewNode(
jsgraph()->javascript()->Call(JSCallNode::ArityForArgc(0),
CallFrequency(), FeedbackSource(),
ConvertReceiverMode::kNotNullOrUndefined),
receiver_mode),
target, receiver, feedback, context, frame_state, *effect, *control);
} else {
Node* holder = access_info.holder().is_null()
......@@ -2343,8 +2343,13 @@ JSNativeContextSpecialization::BuildPropertyLoad(
if (access_info.IsNotFound()) {
value = jsgraph()->UndefinedConstant();
} else if (access_info.IsAccessorConstant()) {
value = InlinePropertyGetterCall(receiver, context, frame_state, &effect,
&control, if_exceptions, access_info);
ConvertReceiverMode receiver_mode =
receiver == lookup_start_object
? ConvertReceiverMode::kNotNullOrUndefined
: ConvertReceiverMode::kAny;
value =
InlinePropertyGetterCall(receiver, receiver_mode, context, frame_state,
&effect, &control, if_exceptions, access_info);
} else if (access_info.IsModuleExport()) {
Node* cell = jsgraph()->Constant(
ObjectRef(broker(), access_info.constant()).AsCell());
......
......@@ -174,9 +174,10 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
PropertyAccessInfo const& access_info);
// Helpers for accessor inlining.
Node* InlinePropertyGetterCall(Node* receiver, Node* context,
Node* frame_state, Node** effect,
Node** control,
Node* InlinePropertyGetterCall(Node* receiver,
ConvertReceiverMode receiver_mode,
Node* context, Node* frame_state,
Node** effect, Node** control,
ZoneVector<Node*>* if_exceptions,
PropertyAccessInfo const& access_info);
void InlinePropertySetterCall(Node* receiver, Node* value, Node* context,
......
// Copyright 2020 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.
// Flags: --interrupt-budget=100
var caught = 0;
function runManyTimes(f) {
for (let i = 0; i < 1000; ++i) {
try {
// Seems to be important that this is inside a try catch.
f();
} catch (e) {
assertUnreachable();
}
}
}
let A = {
get foo() {
return 0;
}
};
let B = {
__proto__: A,
aa() {
"use strict";
super.foo;
}
};
var superAccessingFunc = B.aa;
runManyTimes(function () {
try {
superAccessingFunc();
} catch (e) {
caught++;
}
});
assertEquals(0, caught);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment