[turbofan] Fix several OSR entries within class literals.

With do-expressions any expression used within literals can turn into an
OSR entry-point. This means the literal object being constructed is then
renamed to an OSR value and needs to be reloaded from the environment.

R=rossberg@chromium.org
TEST=mjsunit/regress/regress-osr-in-literal

Review URL: https://codereview.chromium.org/1452193003

Cr-Commit-Position: refs/heads/master@{#32048}
This commit is contained in:
mstarzinger 2015-11-17 06:51:04 -08:00 committed by Commit bot
parent f8a7236119
commit 0c1c80b2af
3 changed files with 13 additions and 8 deletions

View File

@ -1555,18 +1555,18 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
// The prototype is ensured to exist by Runtime_DefineClass. No access check
// is needed here since the constructor is created by the class literal.
Node* proto =
Node* prototype =
BuildLoadObjectField(literal, JSFunction::kPrototypeOrInitialMapOffset);
// The class literal and the prototype are both expected on the operand stack
// during evaluation of the method values.
environment()->Push(literal);
environment()->Push(proto);
environment()->Push(prototype);
// Create nodes to store method values into the literal.
for (int i = 0; i < expr->properties()->length(); i++) {
ObjectLiteral::Property* property = expr->properties()->at(i);
environment()->Push(property->is_static() ? literal : proto);
environment()->Push(environment()->Peek(property->is_static() ? 1 : 0));
VisitForValue(property->key());
Node* name = BuildToName(environment()->Pop(), expr->GetIdForProperty(i));
@ -1619,11 +1619,11 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
// Set both the prototype and constructor to have fast properties, and also
// freeze them in strong mode.
environment()->Pop(); // proto
environment()->Pop(); // literal
prototype = environment()->Pop();
literal = environment()->Pop();
const Operator* op =
javascript()->CallRuntime(Runtime::kFinalizeClassDefinition, 2);
literal = NewNode(op, literal, proto);
literal = NewNode(op, literal, prototype);
// Assign to class variable.
if (expr->class_variable_proxy() != nullptr) {

View File

@ -126,6 +126,7 @@ void ALAA::VisitClassLiteral(ClassLiteral* e) {
VisitIfNotNull(e->constructor());
ZoneList<ObjectLiteralProperty*>* properties = e->properties();
for (int i = 0; i < properties->length(); i++) {
Visit(properties->at(i)->key());
Visit(properties->at(i)->value());
}
}

View File

@ -4,6 +4,8 @@
// Flags: --allow-natives-syntax --harmony-do-expressions
"use strict";
var p = {};
var testCases = [
{ s:"[1, do { _OSR_ 2 }, 3]", r:[1, 2, 3] },
@ -14,11 +16,13 @@ var testCases = [
{ s:"{ [do { _OSR_ 'b' }]: 3 }", r:{ b:3 } },
{ s:"{ [do { _OSR_ 'b' }]: 3, c: 4 }", r:{ b:3, c:4 } },
{ s:"{ [do { _OSR_ 'b' }]: 3, __proto__:p }", r:{ b:3, __proto__:p } },
{ s:"class { [do { _OSR_ 'f' }]() {} }" },
{ s:"class { [do { _OSR_ 'f' }]() {}; g() {} }" },
];
for (var i = 0; i < testCases.length; ++i) {
var source = "(function f" + i + "(x) { return " + testCases[i].s + "})";
var osr = "for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); }";
var fun = eval(source.replace("_OSR_", osr));
assertEquals(testCases[i].r, fun(23));
var result = eval(source.replace("_OSR_", osr))();
if (testCases[i].r) assertEquals(testCases[i].r, result);
}