OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3274 | 3274 |
3275 | 3275 |
3276 TEST(InnerAssignment) { | 3276 TEST(InnerAssignment) { |
3277 i::Isolate* isolate = CcTest::i_isolate(); | 3277 i::Isolate* isolate = CcTest::i_isolate(); |
3278 i::Factory* factory = isolate->factory(); | 3278 i::Factory* factory = isolate->factory(); |
3279 i::HandleScope scope(isolate); | 3279 i::HandleScope scope(isolate); |
3280 LocalContext env; | 3280 LocalContext env; |
3281 | 3281 |
3282 const char* prefix = "function f() {"; | 3282 const char* prefix = "function f() {"; |
3283 const char* midfix = " function g() {"; | 3283 const char* midfix = " function g() {"; |
3284 const char* suffix = "}}"; | 3284 const char* suffix = "}}; f"; |
3285 struct { const char* source; bool assigned; bool strict; } outers[] = { | 3285 struct { const char* source; bool assigned; bool strict; } outers[] = { |
3286 // Actual assignments. | 3286 // Actual assignments. |
3287 { "var x; var x = 5;", true, false }, | 3287 { "var x; var x = 5;", true, false }, |
3288 { "var x; { var x = 5; }", true, false }, | 3288 { "var x; { var x = 5; }", true, false }, |
3289 { "'use strict'; let x; x = 6;", true, true }, | 3289 { "'use strict'; let x; x = 6;", true, true }, |
3290 { "var x = 5; function x() {}", true, false }, | 3290 { "var x = 5; function x() {}", true, false }, |
3291 // Actual non-assignments. | 3291 // Actual non-assignments. |
3292 { "var x;", false, false }, | 3292 { "var x;", false, false }, |
3293 { "var x = 5;", false, false }, | 3293 { "var x = 5;", false, false }, |
3294 { "'use strict'; let x;", false, true }, | 3294 { "'use strict'; let x;", false, true }, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3354 { "function h() { eval(''); }", true, false }, | 3354 { "function h() { eval(''); }", true, false }, |
3355 { "(function() { eval(''); })", true, false }, | 3355 { "(function() { eval(''); })", true, false }, |
3356 // Shadowing not recognized because of eval approximation. | 3356 // Shadowing not recognized because of eval approximation. |
3357 { "var x; eval('');", true, false }, | 3357 { "var x; eval('');", true, false }, |
3358 { "'use strict'; let x; eval('');", true, false }, | 3358 { "'use strict'; let x; eval('');", true, false }, |
3359 { "try {} catch(x) { eval(''); }", true, false }, | 3359 { "try {} catch(x) { eval(''); }", true, false }, |
3360 { "function x() { eval(''); }", true, false }, | 3360 { "function x() { eval(''); }", true, false }, |
3361 { "(function(x) { eval(''); })", true, false }, | 3361 { "(function(x) { eval(''); })", true, false }, |
3362 }; | 3362 }; |
3363 | 3363 |
3364 // Used to trigger lazy parsing of the outer function. | |
3365 int comment_len = 2048; | |
3366 i::ScopedVector<char> comment(comment_len + 1); | |
3367 i::SNPrintF(comment, "/*%0*d*/", comment_len - 4, 0); | |
3368 int prefix_len = Utf8LengthHelper(prefix); | 3364 int prefix_len = Utf8LengthHelper(prefix); |
3369 int midfix_len = Utf8LengthHelper(midfix); | 3365 int midfix_len = Utf8LengthHelper(midfix); |
3370 int suffix_len = Utf8LengthHelper(suffix); | 3366 int suffix_len = Utf8LengthHelper(suffix); |
3371 for (unsigned i = 0; i < arraysize(outers); ++i) { | 3367 for (unsigned i = 0; i < arraysize(outers); ++i) { |
3372 const char* outer = outers[i].source; | 3368 const char* outer = outers[i].source; |
3373 int outer_len = Utf8LengthHelper(outer); | 3369 int outer_len = Utf8LengthHelper(outer); |
3374 for (unsigned j = 0; j < arraysize(inners); ++j) { | 3370 for (unsigned j = 0; j < arraysize(inners); ++j) { |
3375 for (unsigned lazy = 0; lazy < 2; ++lazy) { | 3371 for (unsigned lazy = 0; lazy < 2; ++lazy) { |
3376 if (outers[i].strict && inners[j].with) continue; | 3372 if (outers[i].strict && inners[j].with) continue; |
3377 const char* inner = inners[j].source; | 3373 const char* inner = inners[j].source; |
3378 int inner_len = Utf8LengthHelper(inner); | 3374 int inner_len = Utf8LengthHelper(inner); |
3379 | 3375 |
3380 const char* comment_chars = lazy ? comment.start() : ""; | 3376 int len = prefix_len + outer_len + midfix_len + inner_len + suffix_len; |
3381 int len = prefix_len + (lazy ? comment_len : 0) + outer_len + | |
3382 midfix_len + inner_len + suffix_len; | |
3383 i::ScopedVector<char> program(len + 1); | 3377 i::ScopedVector<char> program(len + 1); |
3384 | 3378 |
3385 i::SNPrintF(program, "%s%s%s%s%s%s", comment_chars, prefix, outer, | 3379 i::SNPrintF(program, "%s%s%s%s%s", prefix, outer, midfix, inner, |
3386 midfix, inner, suffix); | 3380 suffix); |
3387 i::Handle<i::String> source = | |
3388 factory->InternalizeUtf8String(program.start()); | |
3389 source->PrintOn(stdout); | |
3390 printf("\n"); | |
3391 | 3381 |
3392 i::Handle<i::Script> script = factory->NewScript(source); | |
3393 i::Zone zone(CcTest::i_isolate()->allocator()); | 3382 i::Zone zone(CcTest::i_isolate()->allocator()); |
3394 i::ParseInfo info(&zone, script); | 3383 std::unique_ptr<i::ParseInfo> info; |
3395 i::Parser parser(&info); | 3384 if (lazy) { |
3396 CHECK(parser.Parse(&info)); | 3385 printf("%s\n", program.start()); |
3397 CHECK(i::Compiler::Analyze(&info)); | 3386 v8::Local<v8::Value> v = CompileRun(program.start()); |
3398 CHECK(info.literal() != NULL); | 3387 i::Handle<i::Object> o = v8::Utils::OpenHandle(*v); |
| 3388 i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o); |
| 3389 info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(&zone, f)); |
| 3390 } else { |
| 3391 i::Handle<i::String> source = |
| 3392 factory->InternalizeUtf8String(program.start()); |
| 3393 source->PrintOn(stdout); |
| 3394 printf("\n"); |
| 3395 i::Handle<i::Script> script = factory->NewScript(source); |
| 3396 info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(&zone, script)); |
| 3397 } |
| 3398 i::Parser parser(info.get()); |
| 3399 CHECK(parser.Parse(info.get())); |
| 3400 CHECK(i::Compiler::Analyze(info.get())); |
| 3401 CHECK(info->literal() != NULL); |
3399 | 3402 |
3400 i::Scope* scope = info.literal()->scope(); | 3403 i::Scope* scope = info->literal()->scope(); |
3401 i::Scope* inner_scope = scope->inner_scope(); | 3404 if (!lazy) { |
3402 DCHECK_NOT_NULL(inner_scope); | 3405 scope = scope->inner_scope(); |
3403 DCHECK_NULL(inner_scope->sibling()); | 3406 } |
| 3407 DCHECK_NOT_NULL(scope); |
| 3408 DCHECK_NULL(scope->sibling()); |
| 3409 DCHECK(scope->is_function_scope()); |
3404 const i::AstRawString* var_name = | 3410 const i::AstRawString* var_name = |
3405 info.ast_value_factory()->GetOneByteString("x"); | 3411 info->ast_value_factory()->GetOneByteString("x"); |
3406 i::Variable* var = inner_scope->Lookup(var_name); | 3412 i::Variable* var = scope->Lookup(var_name); |
3407 bool expected = outers[i].assigned || inners[j].assigned; | 3413 bool expected = outers[i].assigned || inners[j].assigned; |
3408 CHECK(var != NULL); | 3414 CHECK(var != NULL); |
3409 CHECK(var->is_used() || !expected); | 3415 CHECK(var->is_used() || !expected); |
3410 bool is_maybe_assigned = var->maybe_assigned() == i::kMaybeAssigned; | 3416 bool is_maybe_assigned = var->maybe_assigned() == i::kMaybeAssigned; |
3411 if (i::FLAG_lazy_inner_functions) { | 3417 if (i::FLAG_lazy_inner_functions) { |
3412 // If we parse inner functions lazily, allow being pessimistic about | 3418 // If we parse inner functions lazily, allow being pessimistic about |
3413 // maybe_assigned. | 3419 // maybe_assigned. |
3414 CHECK(is_maybe_assigned || (is_maybe_assigned == expected)); | 3420 CHECK(is_maybe_assigned || (is_maybe_assigned == expected)); |
3415 } else { | 3421 } else { |
3416 CHECK(is_maybe_assigned == expected); | 3422 CHECK(is_maybe_assigned == expected); |
(...skipping 4909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8326 const char* data[] = { | 8332 const char* data[] = { |
8327 "const arguments = 1", | 8333 "const arguments = 1", |
8328 "let arguments", | 8334 "let arguments", |
8329 "var arguments", | 8335 "var arguments", |
8330 NULL | 8336 NULL |
8331 }; | 8337 }; |
8332 // clang-format on | 8338 // clang-format on |
8333 RunParserSyncTest(context_data, data, kSuccess); | 8339 RunParserSyncTest(context_data, data, kSuccess); |
8334 } | 8340 } |
8335 } | 8341 } |
OLD | NEW |