05207b098a
Removes the --ignition flag which is now on by default. Adds a --stress-fullcodegen flag which enables running all functions supported by fullcodegen to be compiled by fullcodegen. This will enable moving parser internalization later when we are not stressing fullcodegen or compiling asm.js functions. BUG=v8:5203, v8:6409, v8:6589 Change-Id: I7fa68016d4e734755434ec0b4e749ef65ffa7f4e Reviewed-on: https://chromium-review.googlesource.com/565569 Commit-Queue: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Michael Achenbach <machenbach@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#46635}
461 lines
11 KiB
JavaScript
461 lines
11 KiB
JavaScript
// Copyright 2016 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: --no-stress-fullcodegen
|
|
// The functions used for testing backtraces. They are at the top to make the
|
|
// testing of source line/column easier.
|
|
|
|
var Debug = debug.Debug;
|
|
|
|
var test_name;
|
|
var exception;
|
|
var begin_test_count = 0;
|
|
var end_test_count = 0;
|
|
|
|
// Initialize for a new test.
|
|
function BeginTest(name) {
|
|
test_name = name;
|
|
exception = null;
|
|
begin_test_count++;
|
|
}
|
|
|
|
// Check result of a test.
|
|
function EndTest() {
|
|
assertNull(exception, test_name + " / " + exception);
|
|
end_test_count++;
|
|
}
|
|
|
|
// Check that two scope are the same.
|
|
function assertScopeMirrorEquals(scope1, scope2) {
|
|
assertEquals(scope1.scopeType(), scope2.scopeType());
|
|
assertEquals(scope1.scopeIndex(), scope2.scopeIndex());
|
|
assertPropertiesEqual(scope1.scopeObject().value(),
|
|
scope2.scopeObject().value());
|
|
}
|
|
|
|
// Check that the scope chain contains the expected types of scopes.
|
|
function CheckScopeChain(scopes, gen) {
|
|
var all_scopes = Debug.generatorScopes(gen);
|
|
assertEquals(scopes.length, Debug.generatorScopeCount(gen));
|
|
assertEquals(scopes.length, all_scopes.length,
|
|
"FrameMirror.allScopes length");
|
|
for (var i = 0; i < scopes.length; i++) {
|
|
var scope = all_scopes[i];
|
|
assertEquals(scopes[i], scope.scopeType(),
|
|
`Scope ${i} has unexpected type`);
|
|
|
|
// Check the global object when hitting the global scope.
|
|
if (scopes[i] == debug.ScopeType.Global) {
|
|
// Objects don't have same class (one is "global", other is "Object",
|
|
// so just check the properties directly.
|
|
assertPropertiesEqual(this, scope.scopeObject().value());
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check that the content of the scope is as expected. For functions just check
|
|
// that there is a function.
|
|
function CheckScopeContent(content, number, gen) {
|
|
var scope = Debug.generatorScope(gen, number);
|
|
var count = 0;
|
|
for (var p in content) {
|
|
var property_mirror = scope.scopeObject().property(p);
|
|
if (content[p] === undefined) {
|
|
assertTrue(property_mirror === undefined);
|
|
} else {
|
|
assertFalse(property_mirror === undefined,
|
|
'property ' + p + ' not found in scope');
|
|
}
|
|
if (typeof(content[p]) === 'function') {
|
|
assertTrue(typeof property_mirror == "function");
|
|
} else {
|
|
assertEquals(content[p], property_mirror,
|
|
'property ' + p + ' has unexpected value');
|
|
}
|
|
count++;
|
|
}
|
|
|
|
// 'arguments' and might be exposed in the local and closure scope. Just
|
|
// ignore this.
|
|
var scope_size = scope.scopeObject().properties().length;
|
|
if (scope.scopeObject().property('arguments') !== undefined) {
|
|
scope_size--;
|
|
}
|
|
// Ditto for 'this'.
|
|
if (scope.scopeObject().property('this') !== undefined) {
|
|
scope_size--;
|
|
}
|
|
// Temporary variables introduced by the parser have not been materialized.
|
|
assertTrue(scope.scopeObject().property('') === undefined);
|
|
|
|
if (count != scope_size) {
|
|
print('Names found in scope:');
|
|
var names = scope.scopeObject().propertyNames();
|
|
for (var i = 0; i < names.length; i++) {
|
|
print(names[i]);
|
|
}
|
|
}
|
|
assertEquals(count, scope_size);
|
|
}
|
|
|
|
// Simple empty closure scope.
|
|
|
|
function *gen1() {
|
|
yield 1;
|
|
return 2;
|
|
}
|
|
|
|
var g = gen1();
|
|
CheckScopeChain([debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({}, 0, g);
|
|
|
|
// Closure scope with a parameter.
|
|
|
|
function *gen2(a) {
|
|
yield a;
|
|
return 2;
|
|
}
|
|
|
|
g = gen2(42);
|
|
CheckScopeChain([debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({a: 42}, 0, g);
|
|
|
|
// Closure scope with a parameter.
|
|
|
|
function *gen3(a) {
|
|
var b = 1
|
|
yield a;
|
|
return b;
|
|
}
|
|
|
|
g = gen3(0);
|
|
CheckScopeChain([debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({a: 0, b: undefined}, 0, g);
|
|
|
|
g.next(); // Create b.
|
|
CheckScopeContent({a: 0, b: 1}, 0, g);
|
|
|
|
// Closure scope with a parameter.
|
|
|
|
function *gen4(a, b) {
|
|
var x = 2;
|
|
yield a;
|
|
var y = 3;
|
|
yield a;
|
|
return b;
|
|
}
|
|
|
|
g = gen4(0, 1);
|
|
CheckScopeChain([debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({a: 0, b: 1, x: undefined, y: undefined}, 0, g);
|
|
|
|
g.next(); // Create x.
|
|
CheckScopeContent({a: 0, b: 1, x: 2, y: undefined}, 0, g);
|
|
|
|
g.next(); // Create y.
|
|
CheckScopeContent({a: 0, b: 1, x: 2, y: 3}, 0, g);
|
|
|
|
// Closure introducing local variable using eval.
|
|
|
|
function *gen5(a) {
|
|
eval('var b = 2');
|
|
yield a;
|
|
return b;
|
|
}
|
|
|
|
g = gen5(1);
|
|
g.next();
|
|
CheckScopeChain([debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({a: 1, b: 2}, 0, g);
|
|
|
|
// Single empty with block.
|
|
|
|
function *gen6() {
|
|
with({}) {
|
|
yield 1;
|
|
}
|
|
yield 2;
|
|
return 3;
|
|
}
|
|
|
|
g = gen6();
|
|
g.next();
|
|
CheckScopeChain([debug.ScopeType.With,
|
|
debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({}, 0, g);
|
|
|
|
g.next();
|
|
CheckScopeChain([debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
|
|
// Nested empty with blocks.
|
|
|
|
function *gen7() {
|
|
with({}) {
|
|
with({}) {
|
|
yield 1;
|
|
}
|
|
yield 2;
|
|
}
|
|
return 3;
|
|
}
|
|
|
|
g = gen7();
|
|
g.next();
|
|
CheckScopeChain([debug.ScopeType.With,
|
|
debug.ScopeType.With,
|
|
debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({}, 0, g);
|
|
|
|
// Nested with blocks using in-place object literals.
|
|
|
|
function *gen8() {
|
|
with({a: 1,b: 2}) {
|
|
with({a: 2,b: 1}) {
|
|
yield a;
|
|
}
|
|
yield a;
|
|
}
|
|
return 3;
|
|
}
|
|
|
|
g = gen8();
|
|
g.next();
|
|
CheckScopeChain([debug.ScopeType.With,
|
|
debug.ScopeType.With,
|
|
debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({a: 2, b: 1}, 0, g);
|
|
|
|
g.next();
|
|
CheckScopeContent({a: 1, b: 2}, 0, g);
|
|
|
|
// Catch block.
|
|
|
|
function *gen9() {
|
|
try {
|
|
throw 42;
|
|
} catch (e) {
|
|
yield e;
|
|
}
|
|
return 3;
|
|
}
|
|
|
|
g = gen9();
|
|
g.next();
|
|
CheckScopeChain([debug.ScopeType.Catch,
|
|
debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({e: 42}, 0, g);
|
|
|
|
// For statement with block scope.
|
|
|
|
function *gen10() {
|
|
for (let i = 0; i < 42; i++) yield i;
|
|
return 3;
|
|
}
|
|
|
|
g = gen10();
|
|
g.next();
|
|
CheckScopeChain([debug.ScopeType.Block,
|
|
debug.ScopeType.Block,
|
|
debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({i: 0}, 1, g);
|
|
|
|
g.next();
|
|
CheckScopeContent({i: 1}, 1, g);
|
|
|
|
// Nested generators.
|
|
|
|
var gen12;
|
|
function *gen11() {
|
|
var b = 2;
|
|
gen12 = function*() {
|
|
var a = 1;
|
|
yield 1;
|
|
return b;
|
|
}();
|
|
|
|
var a = 0;
|
|
yield* gen12;
|
|
}
|
|
|
|
gen11().next();
|
|
g = gen12;
|
|
|
|
CheckScopeChain([debug.ScopeType.Local,
|
|
debug.ScopeType.Closure,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({a: 1}, 0, g);
|
|
CheckScopeContent({b: 2}, 1, g);
|
|
|
|
// Set a variable in an empty scope.
|
|
|
|
function *gen13() {
|
|
yield 1;
|
|
return 2;
|
|
}
|
|
|
|
var g = gen13();
|
|
assertThrows(() => Debug.generatorScope(g, 0).setVariableValue("a", 42));
|
|
CheckScopeContent({}, 0, g);
|
|
|
|
// Set a variable in a simple scope.
|
|
|
|
function *gen14() {
|
|
var a = 0;
|
|
yield 1;
|
|
yield a;
|
|
return 2;
|
|
}
|
|
|
|
var g = gen14();
|
|
assertEquals(1, g.next().value);
|
|
|
|
CheckScopeContent({a: 0}, 0, g);
|
|
|
|
Debug.generatorScope(g, 0).setVariableValue("a", 1);
|
|
CheckScopeContent({a: 1}, 0, g);
|
|
|
|
assertEquals(1, g.next().value);
|
|
|
|
// Set a variable in nested with blocks using in-place object literals.
|
|
|
|
function *gen15() {
|
|
var c = 3;
|
|
with({a: 1,b: 2}) {
|
|
var d = 4;
|
|
yield a;
|
|
var e = 5;
|
|
}
|
|
yield e;
|
|
return e;
|
|
}
|
|
|
|
var g = gen15();
|
|
assertEquals(1, g.next().value);
|
|
|
|
CheckScopeChain([debug.ScopeType.With,
|
|
debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({a: 1, b: 2}, 0, g);
|
|
CheckScopeContent({c: 3, d: 4, e: undefined}, 1, g);
|
|
|
|
// Variables don't exist in given scope.
|
|
assertThrows(() => Debug.generatorScope(g, 0).setVariableValue("c", 42));
|
|
assertThrows(() => Debug.generatorScope(g, 1).setVariableValue("a", 42));
|
|
|
|
// Variables in with scope are immutable.
|
|
assertThrows(() => Debug.generatorScope(g, 0).setVariableValue("a", 3));
|
|
assertThrows(() => Debug.generatorScope(g, 0).setVariableValue("b", 3));
|
|
|
|
Debug.generatorScope(g, 1).setVariableValue("c", 1);
|
|
Debug.generatorScope(g, 1).setVariableValue("e", 42);
|
|
|
|
CheckScopeContent({a: 1, b: 2}, 0, g);
|
|
CheckScopeContent({c: 1, d: 4, e: 42}, 1, g);
|
|
assertEquals(5, g.next().value); // Initialized after set.
|
|
|
|
CheckScopeChain([debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
|
|
Debug.generatorScope(g, 0).setVariableValue("e", 42);
|
|
|
|
CheckScopeContent({c: 1, d: 4, e: 42}, 0, g);
|
|
assertEquals(42, g.next().value);
|
|
|
|
// Set a variable in nested with blocks using in-place object literals plus a
|
|
// nested block scope.
|
|
|
|
function *gen16() {
|
|
var c = 3;
|
|
with({a: 1,b: 2}) {
|
|
let d = 4;
|
|
yield a;
|
|
let e = 5;
|
|
yield d;
|
|
}
|
|
return 3;
|
|
}
|
|
|
|
var g = gen16();
|
|
g.next();
|
|
|
|
CheckScopeChain([debug.ScopeType.Block,
|
|
debug.ScopeType.With,
|
|
debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({d: 4, e: undefined}, 0, g);
|
|
CheckScopeContent({a: 1, b: 2}, 1, g);
|
|
CheckScopeContent({c: 3}, 2, g);
|
|
|
|
Debug.generatorScope(g, 0).setVariableValue("d", 1);
|
|
CheckScopeContent({d: 1, e: undefined}, 0, g);
|
|
|
|
assertEquals(1, g.next().value);
|
|
|
|
// Set variable in catch block.
|
|
|
|
var yyzyzzyz = 4829;
|
|
let xxxyyxxyx = 42284;
|
|
function *gen17() {
|
|
try {
|
|
throw 42;
|
|
} catch (e) {
|
|
yield e;
|
|
yield e;
|
|
}
|
|
return 3;
|
|
}
|
|
|
|
g = gen17();
|
|
g.next();
|
|
|
|
CheckScopeChain([debug.ScopeType.Catch,
|
|
debug.ScopeType.Local,
|
|
debug.ScopeType.Script,
|
|
debug.ScopeType.Global], g);
|
|
CheckScopeContent({e: 42}, 0, g);
|
|
CheckScopeContent({xxxyyxxyx: 42284,
|
|
printProtocolMessages : printProtocolMessages,
|
|
activeWrapper : activeWrapper,
|
|
DebugWrapper : DebugWrapper
|
|
}, 2, g);
|
|
|
|
Debug.generatorScope(g, 0).setVariableValue("e", 1);
|
|
CheckScopeContent({e: 1}, 0, g);
|
|
|
|
assertEquals(1, g.next().value);
|
|
|
|
// Script scope.
|
|
Debug.generatorScope(g, 2).setVariableValue("xxxyyxxyx", 42);
|
|
assertEquals(42, xxxyyxxyx);
|
|
|
|
// Global scope.
|
|
assertThrows(() => Debug.generatorScope(g, 3).setVariableValue("yyzyzzyz", 42));
|
|
assertEquals(4829, yyzyzzyz);
|