Index: test/cctest/test-parsing.cc |
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc |
index b82b7c44ac184ac143357001135ab96e3cc466d9..e1c076e62abd6ced90b427ffdea5d1e4b1b0f9e7 100644 |
--- a/test/cctest/test-parsing.cc |
+++ b/test/cctest/test-parsing.cc |
@@ -914,6 +914,103 @@ static int Utf8LengthHelper(const char* s) { |
} |
+TEST(ScopeUsesThisAndArguments) { |
+ static const struct { |
+ const char* prefix; |
+ const char* suffix; |
+ } surroundings[] = { |
+ { "function f() {", "}" }, |
+ { "function f() { \"use strict\";", "}" }, |
+ { "\"use strict\"; function f() {", "}" }, |
+ { "f = () => {", "}" }, |
+ { "f = () => { \"use strict\";", "}" }, |
+ { "\"use strict\"; f = () => {", "}" }, |
+ }; |
+ |
+ static const struct { |
+ const char* body; |
+ bool uses_this; |
+ bool uses_arguments; |
+ bool inner_uses_this; |
+ bool inner_uses_arguments; |
+ } source_data[] = { |
+ { "", |
+ false, false, false, false }, |
+ { "return this;", |
+ true, false, false, false }, |
+ { "return arguments;", |
+ false, true, false, false }, |
+ { "return arguments[0];", |
+ false, true, false, false }, |
+ { "return this + arguments[0];", |
+ true, true, false, false }, |
+ { "return () => this;", |
+ false, false, true, false }, |
+ { "var x = function () { this.foo = 42 };", |
+ false, false, true, false }, |
+ { "this.foo = 42;", |
+ true, false, false, false }, |
+ { "this.foo();", |
+ true, false, false, false }, |
+ { "if (foo()) { this.f() }", |
+ true, false, false, false }, |
+ { "if (arguments.length) { this.f() }", |
+ true, true, false, false }, |
+ { "while (true) { this.f() }", |
+ true, false, false, false }, |
+ { "if (true) { while (true) this.foo(arguments) }", |
+ true, true, false, false }, |
+ { "var f = function () { return this }", |
+ false, false, true, false }, |
+ { "var f = function () { return arguments[0] }", |
+ false, false, false, true }, |
+ }; |
+ |
+ i::Isolate* isolate = CcTest::i_isolate(); |
+ i::Factory* factory = isolate->factory(); |
+ |
+ v8::HandleScope handles(CcTest::isolate()); |
+ v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); |
+ v8::Context::Scope context_scope(context); |
+ |
+ isolate->stack_guard()->SetStackLimit(GetCurrentStackPosition() - 128 * 1024); |
+ |
+ for (unsigned j = 0; j < ARRAY_SIZE(surroundings); ++j) { |
+ for (unsigned i = 0; i < ARRAY_SIZE(source_data); ++i) { |
+ int kProgramByteSize = i::StrLength(surroundings[j].prefix) + |
+ i::StrLength(surroundings[j].suffix) + |
+ i::StrLength(source_data[i].body); |
+ i::ScopedVector<char> program(kProgramByteSize + 1); |
+ i::SNPrintF(program, "%s%s%s", surroundings[j].prefix, |
+ source_data[i].body, surroundings[j].suffix); |
+ i::Handle<i::String> source = |
+ factory->NewStringFromUtf8(i::CStrVector(program.start())) |
+ .ToHandleChecked(); |
+ i::Handle<i::Script> script = factory->NewScript(source); |
+ i::CompilationInfoWithZone info(script); |
+ i::Parser parser(&info); |
+ parser.set_allow_arrow_functions(true); |
+ info.MarkAsGlobal(); |
+ parser.Parse(); |
+ CHECK(i::Rewriter::Rewrite(&info)); |
+ CHECK(i::Scope::Analyze(&info)); |
+ CHECK(info.function() != NULL); |
+ |
+ i::Scope* scope = info.function()->scope(); |
+ CHECK(scope->is_global_scope()); |
+ CHECK_EQ(1, scope->inner_scopes()->length()); |
+ |
+ i::Scope* inner_scope = scope->inner_scopes()->at(0); |
+ CHECK_EQ(source_data[i].uses_this, inner_scope->uses_this()); |
+ CHECK_EQ(source_data[i].uses_arguments, inner_scope->uses_arguments()); |
+ CHECK_EQ(source_data[i].inner_uses_this, inner_scope->inner_uses_this()); |
+ CHECK_EQ(source_data[i].inner_uses_arguments, |
+ inner_scope->inner_uses_arguments()); |
+ } |
+ } |
+} |
+ |
+ |
TEST(ScopePositions) { |
v8::internal::FLAG_harmony_scoping = true; |