[parsing/test] Skipping inner funcs: add more (structured tests).
Test both cases where the interesting constructs occur at the laziness boundary and cases where they occur deeper. BUG=v8:5501 R=vogelheim@chromium.org Change-Id: I99e32cb0c829616011bf7d1f389a8d309b54d67e Reviewed-on: https://chromium-review.googlesource.com/441844 Reviewed-by: Daniel Vogelheim <vogelheim@chromium.org> Commit-Queue: Marja Hölttä <marja@chromium.org> Cr-Commit-Position: refs/heads/master@{#43157}
This commit is contained in:
parent
cb7e3d39fd
commit
8c449e39b5
@ -20,17 +20,56 @@ TEST(PreParserScopeAnalysis) {
|
||||
i::HandleScope scope(isolate);
|
||||
LocalContext env;
|
||||
|
||||
// FIXME(marja): Add tests where the test cases are deeper (in a second-level
|
||||
// inner function or second-level inner arrow function). Remove redundant test
|
||||
// cases.
|
||||
const char* prefix = "(function outer() { ";
|
||||
const char* suffix = " })();";
|
||||
int prefix_len = Utf8LengthHelper(prefix);
|
||||
int suffix_len = Utf8LengthHelper(suffix);
|
||||
/* Test the following cases:
|
||||
1)
|
||||
(function outer() {
|
||||
function test() { ... }
|
||||
})();
|
||||
against:
|
||||
(function outer() {
|
||||
(function test() { ... })();
|
||||
})();
|
||||
|
||||
// The scope start positions must match; note the extra space in lazy_inner.
|
||||
const char* lazy_inner = " function inner(%s) { %s }";
|
||||
const char* eager_inner = "(function inner(%s) { %s })()";
|
||||
2)
|
||||
(function outer() {
|
||||
function inner() { function test() { ... } }
|
||||
})();
|
||||
against:
|
||||
(function outer() {
|
||||
(function inner() { function test() { ... } })();
|
||||
})();
|
||||
(Modified function is deeper inside the laziness boundary.)
|
||||
|
||||
3)
|
||||
(function outer() {
|
||||
function inner() { () => { ... } }
|
||||
})();
|
||||
against:
|
||||
(function outer() {
|
||||
(function inner() { () => { ... } })();
|
||||
})();
|
||||
|
||||
Inner arrow functions are never lazy, so the corresponding case is missing.
|
||||
*/
|
||||
|
||||
struct {
|
||||
const char* prefix;
|
||||
const char* suffix;
|
||||
const char* lazy_inner;
|
||||
const char* eager_inner;
|
||||
} outers[] = {
|
||||
// The scope start positions must match; note the extra space in
|
||||
// lazy_inner.
|
||||
{"(function outer() { ", "})();", " function test(%s) { %s }",
|
||||
"(function test(%s) { %s })()"},
|
||||
{"(function outer() { ", "})();",
|
||||
" function inner() { function test(%s) { %s } }",
|
||||
"(function inner() { function test(%s) { %s } })()"},
|
||||
// FIXME(marja): enable test for arrow functions once it passes.
|
||||
// {"(function outer() { ", "})();",
|
||||
// " function inner() { (%s) => { %s } }",
|
||||
// "(function inner() { (%s) => { %s } })()"},
|
||||
};
|
||||
|
||||
struct Inner {
|
||||
Inner(const char* s) : source(s) {} // NOLINT
|
||||
@ -97,12 +136,9 @@ TEST(PreParserScopeAnalysis) {
|
||||
{"arguments = 5;"},
|
||||
{"if (true) { arguments; }"},
|
||||
{"if (true) { arguments = 5; }"},
|
||||
{"function f() { arguments; }"},
|
||||
{"function f() { arguments = 5; }"},
|
||||
|
||||
{"this;"},
|
||||
{"if (true) { this; }"},
|
||||
{"function f() { this; }"},
|
||||
|
||||
// Variable called "arguments"
|
||||
{"var arguments;"},
|
||||
@ -154,16 +190,15 @@ TEST(PreParserScopeAnalysis) {
|
||||
{"const {var1: var2, var3: [var4, var5]} = {var1: 1, var3: [2, 3]};"},
|
||||
|
||||
// Referencing the function variable.
|
||||
{"inner;"},
|
||||
{"test;"},
|
||||
{"function f1() { f1; }"},
|
||||
{"function f1() { inner; }"},
|
||||
{"function f1() { function f2() { f1; } }"},
|
||||
{"function arguments() {}"},
|
||||
{"function f1() {} function f1() {}"},
|
||||
{"var f1; function f1() {}"},
|
||||
|
||||
// Assigning to the function variable.
|
||||
{"inner = 3;"},
|
||||
{"test = 3;"},
|
||||
{"function f1() { f1 = 3; }"},
|
||||
{"function f1() { f1; } f1 = 3;"},
|
||||
{"function arguments() {} arguments = 8"},
|
||||
@ -282,9 +317,6 @@ TEST(PreParserScopeAnalysis) {
|
||||
{"if (true) { function f1() {} f1 = 3; function foo() { f1; } }"},
|
||||
{"if (true) { function f1() {} f1 = 3; } function foo() { f1; }"},
|
||||
|
||||
{"function inner2() { if (true) { function f1() {} } }"},
|
||||
{"function inner2() { if (true) { function f1() {} f1 = 3; } }"},
|
||||
|
||||
{"var f1 = 1; if (true) { function f1() {} }"},
|
||||
{"var f1 = 1; if (true) { function f1() {} } function foo() { f1; }"},
|
||||
|
||||
@ -316,70 +348,77 @@ TEST(PreParserScopeAnalysis) {
|
||||
// value, locals shadowing params.
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < arraysize(inners); ++i) {
|
||||
// First compile with the lazy inner function and extract the scope data.
|
||||
const char* inner_function = lazy_inner;
|
||||
int inner_function_len = Utf8LengthHelper(inner_function) - 4;
|
||||
for (unsigned outer_ix = 0; outer_ix < arraysize(outers); ++outer_ix) {
|
||||
for (unsigned inner_ix = 0; inner_ix < arraysize(inners); ++inner_ix) {
|
||||
const char* prefix = outers[outer_ix].prefix;
|
||||
const char* suffix = outers[outer_ix].suffix;
|
||||
int prefix_len = Utf8LengthHelper(prefix);
|
||||
int suffix_len = Utf8LengthHelper(suffix);
|
||||
|
||||
int params_len = Utf8LengthHelper(inners[i].params);
|
||||
int source_len = Utf8LengthHelper(inners[i].source);
|
||||
int len =
|
||||
prefix_len + inner_function_len + params_len + source_len + suffix_len;
|
||||
// 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;
|
||||
|
||||
i::ScopedVector<char> lazy_program(len + 1);
|
||||
i::SNPrintF(lazy_program, "%s", prefix);
|
||||
i::SNPrintF(lazy_program + prefix_len, inner_function, inners[i].params,
|
||||
inners[i].source);
|
||||
i::SNPrintF(lazy_program + prefix_len + inner_function_len + params_len +
|
||||
source_len,
|
||||
"%s", suffix);
|
||||
int params_len = Utf8LengthHelper(inners[inner_ix].params);
|
||||
int source_len = Utf8LengthHelper(inners[inner_ix].source);
|
||||
int len = prefix_len + inner_function_len + params_len + source_len +
|
||||
suffix_len;
|
||||
|
||||
i::Handle<i::String> source =
|
||||
factory->InternalizeUtf8String(lazy_program.start());
|
||||
source->PrintOn(stdout);
|
||||
printf("\n");
|
||||
i::ScopedVector<char> lazy_program(len + 1);
|
||||
i::SNPrintF(lazy_program, "%s", prefix);
|
||||
i::SNPrintF(lazy_program + prefix_len, inner_function,
|
||||
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::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo lazy_info(script);
|
||||
i::Handle<i::String> source =
|
||||
factory->InternalizeUtf8String(lazy_program.start());
|
||||
source->PrintOn(stdout);
|
||||
printf("\n");
|
||||
|
||||
// No need to run scope analysis; preparser scope data is produced when
|
||||
// parsing.
|
||||
CHECK(i::parsing::ParseProgram(&lazy_info));
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo lazy_info(script);
|
||||
|
||||
// Then parse eagerly and check against the scope data.
|
||||
inner_function = eager_inner;
|
||||
inner_function_len = Utf8LengthHelper(inner_function) - 4;
|
||||
len =
|
||||
prefix_len + inner_function_len + params_len + source_len + suffix_len;
|
||||
// No need to run scope analysis; preparser scope data is produced when
|
||||
// parsing.
|
||||
CHECK(i::parsing::ParseProgram(&lazy_info));
|
||||
|
||||
i::ScopedVector<char> eager_program(len + 1);
|
||||
i::SNPrintF(eager_program, "%s", prefix);
|
||||
i::SNPrintF(eager_program + prefix_len, inner_function, inners[i].params,
|
||||
inners[i].source);
|
||||
i::SNPrintF(eager_program + prefix_len + inner_function_len + params_len +
|
||||
source_len,
|
||||
"%s", suffix);
|
||||
// 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;
|
||||
|
||||
source = factory->InternalizeUtf8String(eager_program.start());
|
||||
source->PrintOn(stdout);
|
||||
printf("\n");
|
||||
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);
|
||||
|
||||
script = factory->NewScript(source);
|
||||
i::ParseInfo eager_info(script);
|
||||
eager_info.set_allow_lazy_parsing(false);
|
||||
source = factory->InternalizeUtf8String(eager_program.start());
|
||||
source->PrintOn(stdout);
|
||||
printf("\n");
|
||||
|
||||
CHECK(i::parsing::ParseProgram(&eager_info));
|
||||
CHECK(i::Compiler::Analyze(&eager_info));
|
||||
script = factory->NewScript(source);
|
||||
i::ParseInfo eager_info(script);
|
||||
eager_info.set_allow_lazy_parsing(false);
|
||||
|
||||
i::Scope* scope =
|
||||
eager_info.literal()->scope()->inner_scope()->inner_scope();
|
||||
DCHECK_NOT_NULL(scope);
|
||||
DCHECK_NULL(scope->sibling());
|
||||
DCHECK(scope->is_function_scope());
|
||||
CHECK(i::parsing::ParseProgram(&eager_info));
|
||||
CHECK(i::Compiler::Analyze(&eager_info));
|
||||
|
||||
size_t index = 0;
|
||||
i::ScopeTestHelper::CompareScopeToData(
|
||||
scope, lazy_info.preparsed_scope_data(), index,
|
||||
inners[i].precise_maybe_assigned);
|
||||
i::Scope* scope =
|
||||
eager_info.literal()->scope()->inner_scope()->inner_scope();
|
||||
DCHECK_NOT_NULL(scope);
|
||||
DCHECK_NULL(scope->sibling());
|
||||
DCHECK(scope->is_function_scope());
|
||||
|
||||
size_t index = 0;
|
||||
i::ScopeTestHelper::CompareScopeToData(
|
||||
scope, lazy_info.preparsed_scope_data(), index,
|
||||
inners[inner_ix].precise_maybe_assigned);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user