[parser] Skipping inner funcs: fix the test setup.
The test setup was as follows: - Preparse function test() { ... }, get scope allocation data. - Apply the scope allocation data to (function test() { ... })(); - Compare against normal scope allocation for (function test() { ... })(); But the IIFE is unnecessary - we already disable lazy parsing. Cleaning this up is needed because in the next CL, I want to fix the Scopes produced by PreParser in this case: let f = function g() { // Here we should declare g! } And that fix will make the variables in function test() { // Here we don't declare test } and (function test() { // Here we do declare test })(); not match any more, so it doesn't make sense to compare them against each other. BUG=v8:5516 Change-Id: I93d154c6977bb3cbe405b6ca193cf6283df297bc Reviewed-on: https://chromium-review.googlesource.com/543341 Reviewed-by: Daniel Vogelheim <vogelheim@chromium.org> Commit-Queue: Marja Hölttä <marja@chromium.org> Cr-Commit-Position: refs/heads/master@{#46128}
This commit is contained in:
parent
c5eec2d571
commit
2b730f6335
@ -39,70 +39,46 @@ TEST(PreParserScopeAnalysis) {
|
|||||||
(function outer() {
|
(function outer() {
|
||||||
function test() { ... }
|
function test() { ... }
|
||||||
})();
|
})();
|
||||||
against:
|
(Laziness boundary at "test".)
|
||||||
(function outer() {
|
|
||||||
(function test() { ... })();
|
|
||||||
})();
|
|
||||||
|
|
||||||
2)
|
2)
|
||||||
(function outer() {
|
(function outer() {
|
||||||
function inner() { function test() { ... } }
|
function inner() { function test() { ... } }
|
||||||
})();
|
})();
|
||||||
against:
|
(Laziness boundary at "test".)
|
||||||
(function outer() {
|
|
||||||
(function inner() { function test() { ... } })();
|
|
||||||
})();
|
|
||||||
(Modified function is deeper inside the laziness boundary.)
|
|
||||||
|
|
||||||
3)
|
3)
|
||||||
(function outer() {
|
(function outer() {
|
||||||
function inner() { () => { ... } }
|
function inner() { () => { ... } }
|
||||||
})();
|
})();
|
||||||
against:
|
|
||||||
(function outer() {
|
|
||||||
(function inner() { () => { ... } })();
|
|
||||||
})();
|
|
||||||
|
|
||||||
Inner arrow functions are never lazy, so the corresponding case is missing.
|
Inner arrow functions are never lazy, so the corresponding case is missing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
const char* prefix;
|
const char* code;
|
||||||
const char* suffix;
|
|
||||||
// The scope start positions must match; note the extra space in
|
|
||||||
// lazy_inner.
|
|
||||||
const char* lazy_inner;
|
|
||||||
const char* eager_inner;
|
|
||||||
bool strict_outer;
|
bool strict_outer;
|
||||||
bool strict_test_function;
|
bool strict_test_function;
|
||||||
bool arrow;
|
bool arrow;
|
||||||
std::vector<unsigned> location; // "Directions" to the relevant scope.
|
std::vector<unsigned> location; // "Directions" to the relevant scope.
|
||||||
} outers[] = {
|
} outers[] = {
|
||||||
// Normal case (test function at the laziness boundary):
|
// Normal case (test function at the laziness boundary):
|
||||||
{"(function outer() { ",
|
{"(function outer() { function test(%s) { %s } })();",
|
||||||
"})();",
|
|
||||||
" function test(%s) { %s }",
|
|
||||||
"(function test(%s) { %s })()",
|
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
{0, 0}},
|
{0, 0}},
|
||||||
|
|
||||||
// Test function deeper:
|
// Test function deeper:
|
||||||
{"(function outer() { ",
|
{"(function outer() { function inner() { "
|
||||||
"})();",
|
"function test(%s) { %s } } })();",
|
||||||
" function inner() { function test(%s) { %s } }",
|
|
||||||
"(function inner() { function test(%s) { %s } })()",
|
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
{0, 0}},
|
{0, 0}},
|
||||||
|
|
||||||
// Arrow functions (they can never be at the laziness boundary):
|
// Arrow functions (they can never be at the laziness boundary):
|
||||||
{"(function outer() { ",
|
{"(function outer() { function inner() { (%s) => { %s } } })();",
|
||||||
"})();",
|
|
||||||
" function inner() { (%s) => { %s } }",
|
|
||||||
"(function inner() { (%s) => { %s } })()",
|
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
@ -110,52 +86,38 @@ TEST(PreParserScopeAnalysis) {
|
|||||||
|
|
||||||
// Repeat the above mentioned cases w/ outer function declaring itself
|
// Repeat the above mentioned cases w/ outer function declaring itself
|
||||||
// strict:
|
// strict:
|
||||||
{"(function outer() { 'use strict'; ",
|
{"(function outer() { 'use strict'; function test(%s) { %s } })();",
|
||||||
"})();",
|
|
||||||
" function test(%s) { %s }",
|
|
||||||
"(function test(%s) { %s })()",
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
{0, 0}},
|
{0, 0}},
|
||||||
{"(function outer() { 'use strict'; ",
|
{"(function outer() { 'use strict'; function inner() { "
|
||||||
"})();",
|
"function test(%s) { %s } } })();",
|
||||||
" function inner() { function test(%s) { %s } }",
|
|
||||||
"(function inner() { function test(%s) { %s } })()",
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
{0, 0}},
|
{0, 0}},
|
||||||
{"(function outer() { 'use strict'; ",
|
{"(function outer() { 'use strict'; function inner() { "
|
||||||
"})();",
|
"(%s) => { %s } } })();",
|
||||||
" function inner() { (%s) => { %s } }",
|
|
||||||
"(function inner() { (%s) => { %s } })()",
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
{0, 0}},
|
{0, 0}},
|
||||||
|
|
||||||
// ... and with the test function declaring itself strict:
|
// ... and with the test function declaring itself strict:
|
||||||
{"(function outer() { ",
|
{"(function outer() { function test(%s) { 'use strict'; %s } })();",
|
||||||
"})();",
|
|
||||||
" function test(%s) { 'use strict'; %s }",
|
|
||||||
"(function test(%s) { 'use strict'; %s })()",
|
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
{0, 0}},
|
{0, 0}},
|
||||||
{"(function outer() { ",
|
{"(function outer() { function inner() { "
|
||||||
"})();",
|
"function test(%s) { 'use strict'; %s } } })();",
|
||||||
" function inner() { function test(%s) { 'use strict'; %s } }",
|
|
||||||
"(function inner() { function test(%s) { 'use strict'; %s } })()",
|
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
{0, 0}},
|
{0, 0}},
|
||||||
{"(function outer() { ",
|
{"(function outer() { function inner() { "
|
||||||
"})();",
|
"(%s) => { 'use strict'; %s } } })();",
|
||||||
" function inner() { (%s) => { 'use strict'; %s } }",
|
|
||||||
"(function inner() { (%s) => { 'use strict'; %s } })()",
|
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
@ -163,19 +125,13 @@ TEST(PreParserScopeAnalysis) {
|
|||||||
|
|
||||||
// Methods containing skippable functions. Cannot test at the laziness
|
// Methods containing skippable functions. Cannot test at the laziness
|
||||||
// boundary, since there's no way to force eager parsing of a method.
|
// boundary, since there's no way to force eager parsing of a method.
|
||||||
{"class MyClass { constructor() {",
|
{"class MyClass { constructor() { function test(%s) { %s } } }",
|
||||||
"} }",
|
|
||||||
" function test(%s) { %s }",
|
|
||||||
"(function test(%s) { %s })()",
|
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
{0, 0, 0}},
|
{0, 0, 0}},
|
||||||
|
|
||||||
{"class MyClass { mymethod() {",
|
{"class MyClass { mymethod() { function test(%s) { %s } } }",
|
||||||
"} }",
|
|
||||||
" function test(%s) { %s }",
|
|
||||||
"(function test(%s) { %s })()",
|
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
@ -621,6 +577,7 @@ TEST(PreParserScopeAnalysis) {
|
|||||||
{"try { } catch(var1) { var1 = 3; }"},
|
{"try { } catch(var1) { var1 = 3; }"},
|
||||||
{"try { } catch(var1) { function f() { var1; } }"},
|
{"try { } catch(var1) { function f() { var1; } }"},
|
||||||
{"try { } catch(var1) { function f() { var1 = 3; } }"},
|
{"try { } catch(var1) { function f() { var1 = 3; } }"},
|
||||||
|
// FIXME(marja): Add tests for destructuring catch.
|
||||||
|
|
||||||
// Shadowing the catch variable
|
// Shadowing the catch variable
|
||||||
{"try { } catch(var1) { var var1 = 3; }"},
|
{"try { } catch(var1) { var var1 = 3; }"},
|
||||||
@ -690,33 +647,23 @@ TEST(PreParserScopeAnalysis) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* prefix = outers[outer_ix].prefix;
|
const char* code = outers[outer_ix].code;
|
||||||
const char* suffix = outers[outer_ix].suffix;
|
int code_len = Utf8LengthHelper(code);
|
||||||
int prefix_len = Utf8LengthHelper(prefix);
|
|
||||||
int suffix_len = Utf8LengthHelper(suffix);
|
|
||||||
|
|
||||||
// First compile with the lazy inner function and extract the scope data.
|
|
||||||
const char* inner_function = outers[outer_ix].lazy_inner;
|
|
||||||
int inner_function_len = Utf8LengthHelper(inner_function) - 4;
|
|
||||||
|
|
||||||
int params_len = Utf8LengthHelper(inners[inner_ix].params);
|
int params_len = Utf8LengthHelper(inners[inner_ix].params);
|
||||||
int source_len = Utf8LengthHelper(inners[inner_ix].source);
|
int source_len = Utf8LengthHelper(inners[inner_ix].source);
|
||||||
int len = prefix_len + inner_function_len + params_len + source_len +
|
int len = code_len + params_len + source_len;
|
||||||
suffix_len;
|
|
||||||
|
|
||||||
i::ScopedVector<char> lazy_program(len + 1);
|
i::ScopedVector<char> program(len + 1);
|
||||||
i::SNPrintF(lazy_program, "%s", prefix);
|
i::SNPrintF(program, code, inners[inner_ix].params,
|
||||||
i::SNPrintF(lazy_program + prefix_len, inner_function,
|
inners[inner_ix].source);
|
||||||
inners[inner_ix].params, inners[inner_ix].source);
|
|
||||||
i::SNPrintF(lazy_program + prefix_len + inner_function_len + params_len +
|
|
||||||
source_len,
|
|
||||||
"%s", suffix);
|
|
||||||
|
|
||||||
i::Handle<i::String> source =
|
i::Handle<i::String> source =
|
||||||
factory->InternalizeUtf8String(lazy_program.start());
|
factory->InternalizeUtf8String(program.start());
|
||||||
source->PrintOn(stdout);
|
source->PrintOn(stdout);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
// First compile with the lazy inner function and extract the scope data.
|
||||||
i::Handle<i::Script> script = factory->NewScript(source);
|
i::Handle<i::Script> script = factory->NewScript(source);
|
||||||
i::ParseInfo lazy_info(script);
|
i::ParseInfo lazy_info(script);
|
||||||
|
|
||||||
@ -725,34 +672,17 @@ TEST(PreParserScopeAnalysis) {
|
|||||||
CHECK(i::parsing::ParseProgram(&lazy_info, isolate));
|
CHECK(i::parsing::ParseProgram(&lazy_info, isolate));
|
||||||
|
|
||||||
// Then parse eagerly and check against the scope data.
|
// Then parse eagerly and check against the scope data.
|
||||||
inner_function = outers[outer_ix].eager_inner;
|
|
||||||
inner_function_len = Utf8LengthHelper(inner_function) - 4;
|
|
||||||
len = prefix_len + inner_function_len + params_len + source_len +
|
|
||||||
suffix_len;
|
|
||||||
|
|
||||||
i::ScopedVector<char> eager_program(len + 1);
|
|
||||||
i::SNPrintF(eager_program, "%s", prefix);
|
|
||||||
i::SNPrintF(eager_program + prefix_len, inner_function,
|
|
||||||
inners[inner_ix].params, inners[inner_ix].source);
|
|
||||||
i::SNPrintF(eager_program + prefix_len + inner_function_len + params_len +
|
|
||||||
source_len,
|
|
||||||
"%s", suffix);
|
|
||||||
|
|
||||||
source = factory->InternalizeUtf8String(eager_program.start());
|
|
||||||
source->PrintOn(stdout);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
script = factory->NewScript(source);
|
script = factory->NewScript(source);
|
||||||
|
|
||||||
// Compare the allocation of the variables in two cases: 1) normal scope
|
|
||||||
// allocation 2) allocation based on the preparse data.
|
|
||||||
|
|
||||||
i::ParseInfo eager_normal(script);
|
i::ParseInfo eager_normal(script);
|
||||||
eager_normal.set_allow_lazy_parsing(false);
|
eager_normal.set_allow_lazy_parsing(false);
|
||||||
|
|
||||||
CHECK(i::parsing::ParseProgram(&eager_normal, isolate));
|
CHECK(i::parsing::ParseProgram(&eager_normal, isolate));
|
||||||
CHECK(i::Compiler::Analyze(&eager_normal, isolate));
|
CHECK(i::Compiler::Analyze(&eager_normal, isolate));
|
||||||
|
|
||||||
|
// Compare the allocation of the variables in two cases: 1) normal scope
|
||||||
|
// allocation 2) allocation based on the preparse data.
|
||||||
|
|
||||||
i::Scope* normal_scope = i::ScopeTestHelper::FindScope(
|
i::Scope* normal_scope = i::ScopeTestHelper::FindScope(
|
||||||
eager_normal.literal()->scope(), outers[outer_ix].location);
|
eager_normal.literal()->scope(), outers[outer_ix].location);
|
||||||
CHECK_NULL(normal_scope->sibling());
|
CHECK_NULL(normal_scope->sibling());
|
||||||
|
Loading…
Reference in New Issue
Block a user