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) { ...@@ -2195,9 +2195,9 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreProperty(Node* node) {
} }
Node* JSNativeContextSpecialization::InlinePropertyGetterCall( Node* JSNativeContextSpecialization::InlinePropertyGetterCall(
Node* receiver, Node* context, Node* frame_state, Node** effect, Node* receiver, ConvertReceiverMode receiver_mode, Node* context,
Node** control, ZoneVector<Node*>* if_exceptions, Node* frame_state, Node** effect, Node** control,
PropertyAccessInfo const& access_info) { ZoneVector<Node*>* if_exceptions, PropertyAccessInfo const& access_info) {
ObjectRef constant(broker(), access_info.constant()); ObjectRef constant(broker(), access_info.constant());
Node* target = jsgraph()->Constant(constant); Node* target = jsgraph()->Constant(constant);
FrameStateInfo const& frame_info = FrameStateInfoOf(frame_state->op()); FrameStateInfo const& frame_info = FrameStateInfoOf(frame_state->op());
...@@ -2208,7 +2208,7 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall( ...@@ -2208,7 +2208,7 @@ Node* JSNativeContextSpecialization::InlinePropertyGetterCall(
value = *effect = *control = graph()->NewNode( value = *effect = *control = graph()->NewNode(
jsgraph()->javascript()->Call(JSCallNode::ArityForArgc(0), jsgraph()->javascript()->Call(JSCallNode::ArityForArgc(0),
CallFrequency(), FeedbackSource(), CallFrequency(), FeedbackSource(),
ConvertReceiverMode::kNotNullOrUndefined), receiver_mode),
target, receiver, feedback, context, frame_state, *effect, *control); target, receiver, feedback, context, frame_state, *effect, *control);
} else { } else {
Node* holder = access_info.holder().is_null() Node* holder = access_info.holder().is_null()
...@@ -2343,8 +2343,13 @@ JSNativeContextSpecialization::BuildPropertyLoad( ...@@ -2343,8 +2343,13 @@ JSNativeContextSpecialization::BuildPropertyLoad(
if (access_info.IsNotFound()) { if (access_info.IsNotFound()) {
value = jsgraph()->UndefinedConstant(); value = jsgraph()->UndefinedConstant();
} else if (access_info.IsAccessorConstant()) { } else if (access_info.IsAccessorConstant()) {
value = InlinePropertyGetterCall(receiver, context, frame_state, &effect, ConvertReceiverMode receiver_mode =
&control, if_exceptions, access_info); 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()) { } else if (access_info.IsModuleExport()) {
Node* cell = jsgraph()->Constant( Node* cell = jsgraph()->Constant(
ObjectRef(broker(), access_info.constant()).AsCell()); ObjectRef(broker(), access_info.constant()).AsCell());
......
...@@ -174,9 +174,10 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final ...@@ -174,9 +174,10 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
PropertyAccessInfo const& access_info); PropertyAccessInfo const& access_info);
// Helpers for accessor inlining. // Helpers for accessor inlining.
Node* InlinePropertyGetterCall(Node* receiver, Node* context, Node* InlinePropertyGetterCall(Node* receiver,
Node* frame_state, Node** effect, ConvertReceiverMode receiver_mode,
Node** control, Node* context, Node* frame_state,
Node** effect, Node** control,
ZoneVector<Node*>* if_exceptions, ZoneVector<Node*>* if_exceptions,
PropertyAccessInfo const& access_info); PropertyAccessInfo const& access_info);
void InlinePropertySetterCall(Node* receiver, Node* value, Node* context, 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