v8/test/mjsunit/regress/regress-crbug-1171195.js
Marja Hölttä 31d2bb8670 Reland2 [super] Store home object in Context instead of JSFunction
Fix 1: Track Scope::needs_home_object and Scope::uses_super_property
accurately. When "eval" is seen, figure out whether it can access
"super" and if yes, set the corresponding home object as needed.

Fix 2: The object literal scope shouldn't be entered for things
inside spreads.

Original: https://chromium-review.googlesource.com/c/v8/v8/+/2563275
Previous reland: https://chromium-review.googlesource.com/c/v8/v8/+/2637220

This saves memory (the home object doesn't need to be stored for each
method, but only once per class) and hopefully makes the home object
a constant in the optimized code.

Detailed documentation of the changes:
https://docs.google.com/document/d/1ZVXcoQdf9IdMsnRI9iyUjyq9NDoEyx9nA3XqMgwflMs/edit?usp=sharing

Bug: v8:9237
Bug: chromium:1167918
Bug: chromium:1167981
Bug: chromium:1167988
Bug: chromium:1168055
Bug: chromium:1171195
Bug: chromium:1171600
Change-Id: I9686e0d90cd0c1128757eca440a88748897ee91e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2655509
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72422}
2021-01-29 09:19:23 +00:00

161 lines
2.8 KiB
JavaScript

// Copyright 2021 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.
(function OriginalRegressionTest() {
function lazy() {
class X {
static x = function() {
function f() { eval(); }
};
}
}
lazy();
})();
(function TestEvalInsideFunctionInsideInitializer() {
function lazy() {
class A {}
class B extends A {
x = function() {
eval('super.y');
};
}
return B;
}
let c = lazy();
let o = new c();
assertThrows(() => {o.x()});
})();
(function TestEvalInsideArrowFunctionInsideInitializer() {
let result;
function lazy() {
class A {}
A.prototype.y = 42;
class B extends A {
x = () => {
eval('result = super.y');
};
}
return B;
}
let c = lazy();
let o = new c();
o.x();
assertEquals(42, result);
})();
(function TestEvalInsideFunctionInsideMethod() {
class A {}
A.prototype.x = 42;
class B extends A {
m() {
function f() {
eval("super.x;");
}
return f;
}
}
let f = (new B()).m();
assertThrows(() => { f(); });
})();
// Same as the previous test, except for object literals.
(function TestEvalInsideFunctionInsideObjectLiteralMethod() {
let o = {
m() {
function f() {
eval("super.x;");
}
return f;
}
};
let f = o.m();
assertThrows(() => { f(); });
})();
(function TestEvalInsideArrowFunctionInsideMethod() {
let result;
class A {}
A.prototype.x = 42;
class B extends A {
m() {
let f = () => {
eval("result = super.x;");
}
return f;
}
}
let o = new B();
o.m()();
assertEquals(42, result);
})();
(function TestEvalInsideArrowFunctionInsideObjectLiteralMethod() {
let result;
let o = {
__proto__: {'x': 42},
m() {
let f = () => {
eval("result = super.x;");
}
return f;
}
};
o.m()();
assertEquals(42, result);
})();
(function TestSkippingMethodWithEvalInsideInnerFunc() {
function lazy() {
class MyClass {
test_method() {
var var1;
function f1() { eval(''); }
function skippable() { }
}
}
var o = new MyClass(); return o.test_method;
}
lazy();
})();
(function TestSkippingMethod() {
function lazy() {
class A {}
class B extends A {
skip_me() { return super.bar; }
}
}
lazy();
})();
(function TestSkippingObjectLiteralMethod() {
function lazy() {
let o = {
skip_me() { return super.bar; }
};
}
lazy();
})();
(function TestSkippingMethodWithEval() {
function lazy() {
class A {}
class B extends A {
skip_me() { eval(''); }
}
}
lazy();
})();
(function TestSkippingObjectLiteralMethodWithEval() {
function lazy() {
let o = {
skip_me() { eval(''); }
};
}
lazy();
})();