Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(506)

Unified Diff: test/cctest/test-parsing.cc

Issue 422923004: Track usage of "this" and "arguments" in Scope (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix nits Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/scopes.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-parsing.cc
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index 3556c649f11bcc9bfef78dbc70d1210749e22f97..d33d0377c939b1de6bd4271f382b91cde5d9b257 100644
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -917,6 +917,122 @@ static int Utf8LengthHelper(const char* s) {
}
+TEST(ScopeUsesThisAndArguments) {
+ static const struct {
+ const char* prefix;
+ const char* suffix;
+ } surroundings[] = {
+ { "function f() {", "}" },
+ { "var 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 x => this + x",
+ 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 },
+ // Multiple nesting levels must work as well.
+ { "while (true) { while (true) { while (true) return this } }",
+ true, false, false, false },
+ { "if (1) { return () => { while (true) new this() } }",
+ false, false, true, false },
+ // Note that propagation of the inner_uses_this() value does not
+ // cross boundaries of normal functions onto parent scopes.
+ { "return function (x) { return this + x }",
+ false, false, false, false },
+ { "var x = function () { this.foo = 42 };",
+ false, false, false, false },
+ { "if (1) { return function () { while (true) new this() } }",
+ false, false, false, false },
+ { "return function (x) { return () => this }",
+ false, false, false, false },
+ // Flags must be correctly set when using block scoping.
+ { "\"use strict\"; while (true) { let x; this, arguments; }",
+ false, false, true, true },
+ { "\"use strict\"; if (foo()) { let x; this.f() }",
+ false, false, true, false },
+ { "\"use strict\"; if (1) {"
+ " let x; return function () { return this + arguments }"
+ "}",
+ false, false, false, false },
+ };
+
+ 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(i::GetCurrentStackPosition() -
+ 128 * 1024);
+
+ for (unsigned j = 0; j < arraysize(surroundings); ++j) {
+ for (unsigned i = 0; i < arraysize(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::ParseInfo parse_info = {isolate->stack_guard()->real_climit(),
+ isolate->heap()->HashSeed(),
+ isolate->unicode_cache()};
+ i::Parser parser(&info, &parse_info);
+ parser.set_allow_arrow_functions(true);
+ parser.set_allow_harmony_scoping(true);
+ info.MarkAsGlobal();
+ parser.Parse();
+ CHECK(i::Rewriter::Rewrite(&info));
+ CHECK(i::Scope::Analyze(&info));
+ CHECK(info.function() != NULL);
+
+ i::Scope* global_scope = info.function()->scope();
+ CHECK(global_scope->is_global_scope());
+ CHECK_EQ(1, global_scope->inner_scopes()->length());
+
+ i::Scope* scope = global_scope->inner_scopes()->at(0);
+ CHECK_EQ(source_data[i].uses_this, scope->uses_this());
+ CHECK_EQ(source_data[i].uses_arguments, scope->uses_arguments());
+ CHECK_EQ(source_data[i].inner_uses_this, scope->inner_uses_this());
+ CHECK_EQ(source_data[i].inner_uses_arguments,
+ scope->inner_uses_arguments());
+ }
+ }
+}
+
+
TEST(ScopePositions) {
v8::internal::FLAG_harmony_scoping = true;
@@ -974,11 +1090,10 @@ TEST(ScopePositions) {
" infunction;\n"
" }", "\n"
" more;", i::FUNCTION_SCOPE, i::SLOPPY },
- // TODO(aperez): Change to use i::ARROW_SCOPE when implemented
{ " start;\n", "(a,b) => a + b", "; more;",
- i::FUNCTION_SCOPE, i::SLOPPY },
+ i::ARROW_SCOPE, i::SLOPPY },
{ " start;\n", "(a,b) => { return a+b; }", "\nmore;",
- i::FUNCTION_SCOPE, i::SLOPPY },
+ i::ARROW_SCOPE, i::SLOPPY },
{ " start;\n"
" (function fun", "(a,b) { infunction; }", ")();",
i::FUNCTION_SCOPE, i::SLOPPY },
« no previous file with comments | « src/scopes.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698