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 19 matching lines...) Expand all Loading... | |
30 #include <string.h> | 30 #include <string.h> |
31 | 31 |
32 #include "src/v8.h" | 32 #include "src/v8.h" |
33 | 33 |
34 #include "src/compiler.h" | 34 #include "src/compiler.h" |
35 #include "src/execution.h" | 35 #include "src/execution.h" |
36 #include "src/isolate.h" | 36 #include "src/isolate.h" |
37 #include "src/objects.h" | 37 #include "src/objects.h" |
38 #include "src/parser.h" | 38 #include "src/parser.h" |
39 #include "src/preparser.h" | 39 #include "src/preparser.h" |
40 #include "src/rewriter.h" | |
40 #include "src/scanner-character-streams.h" | 41 #include "src/scanner-character-streams.h" |
41 #include "src/token.h" | 42 #include "src/token.h" |
42 #include "src/utils.h" | 43 #include "src/utils.h" |
43 #include "test/cctest/cctest.h" | 44 #include "test/cctest/cctest.h" |
44 | 45 |
45 TEST(ScanKeywords) { | 46 TEST(ScanKeywords) { |
46 struct KeywordToken { | 47 struct KeywordToken { |
47 const char* keyword; | 48 const char* keyword; |
48 i::Token::Value token; | 49 i::Token::Value token; |
49 }; | 50 }; |
(...skipping 2492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2542 v8::Local<v8::String> source = | 2543 v8::Local<v8::String> source = |
2543 v8::String::NewFromTwoByte(isolate, two_byte_source); | 2544 v8::String::NewFromTwoByte(isolate, two_byte_source); |
2544 v8::Local<v8::Value> result = CompileRun(source); | 2545 v8::Local<v8::Value> result = CompileRun(source); |
2545 CHECK(result->IsString()); | 2546 CHECK(result->IsString()); |
2546 v8::Local<v8::String> expected_name = | 2547 v8::Local<v8::String> expected_name = |
2547 v8::String::NewFromTwoByte(isolate, two_byte_name); | 2548 v8::String::NewFromTwoByte(isolate, two_byte_name); |
2548 CHECK(result->Equals(expected_name)); | 2549 CHECK(result->Equals(expected_name)); |
2549 i::DeleteArray(two_byte_source); | 2550 i::DeleteArray(two_byte_source); |
2550 i::DeleteArray(two_byte_name); | 2551 i::DeleteArray(two_byte_name); |
2551 } | 2552 } |
2553 | |
2554 | |
2555 TEST(InnerAssignment) { | |
2556 i::Isolate* isolate = CcTest::i_isolate(); | |
2557 i::Factory* factory = isolate->factory(); | |
2558 i::HandleScope scope(isolate); | |
2559 LocalContext env; | |
2560 | |
2561 const char* prefix = "function f() {"; | |
2562 const char* midfix = " function g() {"; | |
2563 const char* suffix = "}}"; | |
2564 struct { const char* source; bool strict; } outers[] = { | |
2565 { "var x;", false }, | |
2566 { "var x = 5;", false }, | |
2567 { "var x; x = 5;", false }, | |
2568 { "var x; var x = 5;", false }, | |
2569 { "'use strict'; let x;", true }, | |
2570 { "'use strict'; let x = 6;", true }, | |
2571 { "'use strict'; let x; x = 6;", true }, | |
2572 { "function x() {}", false }, | |
2573 }; | |
2574 struct { const char* source; bool assigned; } inners[] = { | |
2575 { "x = 1;", true }, | |
2576 { "x++;", true }, | |
2577 { "++x;", true }, | |
2578 { "x--;", true }, | |
2579 { "--x;", true }, | |
2580 { "{ x = 1; }", true }, | |
2581 { "'use strict'; { let x; }; x = 0;", true }, | |
2582 { "'use strict'; { const x = 1; }; x = 0;", true }, | |
2583 { "'use strict'; { function x() {} }; x = 0;", true }, | |
2584 { "with ({}) { x = 1; }", true }, | |
2585 { "eval('');", true }, | |
2586 { "'use strict'; { let y; eval('') }", true }, | |
2587 { "function h() { x = 0; }", true }, | |
2588 { "(function() { x = 0; })", true }, | |
2589 { "(function() { x = 0; })", true }, | |
2590 { "with ({}) (function() { x = 0; })", true }, | |
2591 { "", false }, | |
2592 { "x;", false }, | |
2593 { "var x;", false }, | |
2594 { "var x = 8;", false }, | |
2595 { "var x; x = 8;", false }, | |
2596 { "'use strict'; let x;", false }, | |
2597 { "'use strict'; let x = 8;", false }, | |
2598 { "'use strict'; let x; x = 8;", false }, | |
2599 { "'use strict'; const x = 8;", false }, | |
2600 { "function x() {}", false }, | |
2601 { "function x() { x = 0; }", false }, | |
2602 { "'use strict'; { let x; x = 0; }", false }, | |
2603 { "{ var x; }; x = 0;", false }, | |
2604 { "with ({}) {}", false }, | |
2605 { "var x; { with ({}) { x = 1; } }", false }, | |
2606 { "try {} catch(x) { x = 0; }", false }, | |
2607 { "try {} catch(x) { with ({}) { x = 1; } }", false }, | |
2608 // For simplicity, eval unconditionally sets flag to true. | |
2609 { "var x; { eval('') }", true }, | |
2610 { "'use strict'; let x; { eval('') }", true }, | |
2611 { "'use strict'; { let x; eval('') }", true }, | |
2612 { "try {} catch(x) { eval(''); }", true }, | |
2613 }; | |
2614 i::Handle<i::String> var_name = | |
2615 factory->NewStringFromUtf8(i::CStrVector("x")).ToHandleChecked(); | |
titzer
2014/06/23 13:03:19
factory->InternalizeUtf8String()?
rossberg
2014/06/24 13:40:43
Done (also below).
| |
2616 | |
2617 int prefix_len = Utf8LengthHelper(prefix); | |
2618 int midfix_len = Utf8LengthHelper(midfix); | |
2619 int suffix_len = Utf8LengthHelper(suffix); | |
2620 for (unsigned i = 0; i < ARRAY_SIZE(outers); ++i) { | |
2621 const char* outer = outers[i].source; | |
2622 int outer_len = Utf8LengthHelper(outer); | |
2623 for (unsigned j = 0; j < ARRAY_SIZE(inners); ++j) { | |
2624 const char* inner = inners[j].source; | |
2625 int inner_len = Utf8LengthHelper(inner); | |
2626 int len = prefix_len + outer_len + midfix_len + inner_len + suffix_len; | |
2627 i::ScopedVector<char> program(len + 1); | |
2628 i::SNPrintF(program, "%s%s%s%s%s", prefix, outer, midfix, inner, suffix); | |
2629 i::Handle<i::String> source = factory->NewStringFromUtf8( | |
2630 i::CStrVector(program.start())).ToHandleChecked(); | |
2631 | |
2632 i::Handle<i::Script> script = factory->NewScript(source); | |
2633 i::CompilationInfoWithZone info(script); | |
2634 i::Parser parser(&info); | |
2635 parser.set_allow_harmony_scoping(true); | |
2636 if (!parser.Parse()) { | |
2637 // Some combinations (strict + with) cause static errors, ignore. | |
2638 ASSERT(outers[i].strict); | |
2639 printf("Skipping "); | |
2640 source->Print(); | |
2641 printf("\n"); | |
2642 continue; | |
2643 } | |
2644 CHECK(i::Rewriter::Rewrite(&info)); | |
2645 CHECK(i::Scope::Analyze(&info)); | |
2646 CHECK(info.function() != NULL); | |
2647 | |
2648 i::Scope* scope = info.function()->scope(); | |
2649 CHECK_EQ(scope->inner_scopes()->length(), 1); | |
2650 i::Scope* inner_scope = scope->inner_scopes()->at(0); | |
2651 i::Variable* var = inner_scope->Lookup(var_name); | |
2652 CHECK(var != NULL); | |
2653 CHECK(var->is_used() || !inners[j].assigned); | |
2654 CHECK(var->is_assigned_in_inner_function() == inners[j].assigned); | |
2655 } | |
2656 } | |
2657 } | |
OLD | NEW |