| 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 20 matching lines...) Expand all Loading... |
| 31 | 31 |
| 32 #include "src/v8.h" | 32 #include "src/v8.h" |
| 33 | 33 |
| 34 #include "src/ast-value-factory.h" | 34 #include "src/ast-value-factory.h" |
| 35 #include "src/compiler.h" | 35 #include "src/compiler.h" |
| 36 #include "src/execution.h" | 36 #include "src/execution.h" |
| 37 #include "src/isolate.h" | 37 #include "src/isolate.h" |
| 38 #include "src/objects.h" | 38 #include "src/objects.h" |
| 39 #include "src/parser.h" | 39 #include "src/parser.h" |
| 40 #include "src/preparser.h" | 40 #include "src/preparser.h" |
| 41 #include "src/rewriter.h" | |
| 42 #include "src/scanner-character-streams.h" | 41 #include "src/scanner-character-streams.h" |
| 43 #include "src/token.h" | 42 #include "src/token.h" |
| 44 #include "src/utils.h" | 43 #include "src/utils.h" |
| 45 #include "test/cctest/cctest.h" | 44 #include "test/cctest/cctest.h" |
| 46 | 45 |
| 47 TEST(ScanKeywords) { | 46 TEST(ScanKeywords) { |
| 48 struct KeywordToken { | 47 struct KeywordToken { |
| 49 const char* keyword; | 48 const char* keyword; |
| 50 i::Token::Value token; | 49 i::Token::Value token; |
| 51 }; | 50 }; |
| (...skipping 2556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2608 v8::Isolate* isolate = CcTest::isolate(); | 2607 v8::Isolate* isolate = CcTest::isolate(); |
| 2609 v8::HandleScope scope(isolate); | 2608 v8::HandleScope scope(isolate); |
| 2610 LocalContext env; | 2609 LocalContext env; |
| 2611 i::FLAG_lazy = true; | 2610 i::FLAG_lazy = true; |
| 2612 i::FLAG_min_preparse_length = 0; | 2611 i::FLAG_min_preparse_length = 0; |
| 2613 CompileRun("function this_is_lazy() {\n" | 2612 CompileRun("function this_is_lazy() {\n" |
| 2614 " break p;\n" | 2613 " break p;\n" |
| 2615 "}\n" | 2614 "}\n" |
| 2616 "this_is_lazy();\n"); | 2615 "this_is_lazy();\n"); |
| 2617 } | 2616 } |
| 2618 | |
| 2619 | |
| 2620 TEST(InnerAssignment) { | |
| 2621 i::Isolate* isolate = CcTest::i_isolate(); | |
| 2622 i::Factory* factory = isolate->factory(); | |
| 2623 i::HandleScope scope(isolate); | |
| 2624 LocalContext env; | |
| 2625 | |
| 2626 const char* prefix = "function f() {"; | |
| 2627 const char* midfix = " function g() {"; | |
| 2628 const char* suffix = "}}"; | |
| 2629 struct { const char* source; bool assigned; bool strict; } outers[] = { | |
| 2630 // Actual assignments. | |
| 2631 { "var x; var x = 5;", true, false }, | |
| 2632 { "var x; { var x = 5; }", true, false }, | |
| 2633 { "'use strict'; let x; x = 6;", true, true }, | |
| 2634 { "var x = 5; function x() {}", true, false }, | |
| 2635 // Actual non-assignments. | |
| 2636 { "var x;", false, false }, | |
| 2637 { "var x = 5;", false, false }, | |
| 2638 { "'use strict'; let x;", false, true }, | |
| 2639 { "'use strict'; let x = 6;", false, true }, | |
| 2640 { "'use strict'; var x = 0; { let x = 6; }", false, true }, | |
| 2641 { "'use strict'; var x = 0; { let x; x = 6; }", false, true }, | |
| 2642 { "'use strict'; let x = 0; { let x = 6; }", false, true }, | |
| 2643 { "'use strict'; let x = 0; { let x; x = 6; }", false, true }, | |
| 2644 { "var x; try {} catch (x) { x = 5; }", false, false }, | |
| 2645 { "function x() {}", false, false }, | |
| 2646 // Eval approximation. | |
| 2647 { "var x; eval('');", true, false }, | |
| 2648 { "eval(''); var x;", true, false }, | |
| 2649 { "'use strict'; let x; eval('');", true, true }, | |
| 2650 { "'use strict'; eval(''); let x;", true, true }, | |
| 2651 // Non-assignments not recognized, because the analysis is approximative. | |
| 2652 { "var x; var x;", true, false }, | |
| 2653 { "var x = 5; var x;", true, false }, | |
| 2654 { "var x; { var x; }", true, false }, | |
| 2655 { "var x; function x() {}", true, false }, | |
| 2656 { "function x() {}; var x;", true, false }, | |
| 2657 { "var x; try {} catch (x) { var x = 5; }", true, false }, | |
| 2658 }; | |
| 2659 struct { const char* source; bool assigned; bool with; } inners[] = { | |
| 2660 // Actual assignments. | |
| 2661 { "x = 1;", true, false }, | |
| 2662 { "x++;", true, false }, | |
| 2663 { "++x;", true, false }, | |
| 2664 { "x--;", true, false }, | |
| 2665 { "--x;", true, false }, | |
| 2666 { "{ x = 1; }", true, false }, | |
| 2667 { "'use strict'; { let x; }; x = 0;", true, false }, | |
| 2668 { "'use strict'; { const x = 1; }; x = 0;", true, false }, | |
| 2669 { "'use strict'; { function x() {} }; x = 0;", true, false }, | |
| 2670 { "with ({}) { x = 1; }", true, true }, | |
| 2671 { "eval('');", true, false }, | |
| 2672 { "'use strict'; { let y; eval('') }", true, false }, | |
| 2673 { "function h() { x = 0; }", true, false }, | |
| 2674 { "(function() { x = 0; })", true, false }, | |
| 2675 { "(function() { x = 0; })", true, false }, | |
| 2676 { "with ({}) (function() { x = 0; })", true, true }, | |
| 2677 // Actual non-assignments. | |
| 2678 { "", false, false }, | |
| 2679 { "x;", false, false }, | |
| 2680 { "var x;", false, false }, | |
| 2681 { "var x = 8;", false, false }, | |
| 2682 { "var x; x = 8;", false, false }, | |
| 2683 { "'use strict'; let x;", false, false }, | |
| 2684 { "'use strict'; let x = 8;", false, false }, | |
| 2685 { "'use strict'; let x; x = 8;", false, false }, | |
| 2686 { "'use strict'; const x = 8;", false, false }, | |
| 2687 { "function x() {}", false, false }, | |
| 2688 { "function x() { x = 0; }", false, false }, | |
| 2689 { "function h(x) { x = 0; }", false, false }, | |
| 2690 { "'use strict'; { let x; x = 0; }", false, false }, | |
| 2691 { "{ var x; }; x = 0;", false, false }, | |
| 2692 { "with ({}) {}", false, true }, | |
| 2693 { "var x; { with ({}) { x = 1; } }", false, true }, | |
| 2694 { "try {} catch(x) { x = 0; }", false, false }, | |
| 2695 { "try {} catch(x) { with ({}) { x = 1; } }", false, true }, | |
| 2696 // Eval approximation. | |
| 2697 { "eval('');", true, false }, | |
| 2698 { "function h() { eval(''); }", true, false }, | |
| 2699 { "(function() { eval(''); })", true, false }, | |
| 2700 // Shadowing not recognized because of eval approximation. | |
| 2701 { "var x; eval('');", true, false }, | |
| 2702 { "'use strict'; let x; eval('');", true, false }, | |
| 2703 { "try {} catch(x) { eval(''); }", true, false }, | |
| 2704 { "function x() { eval(''); }", true, false }, | |
| 2705 { "(function(x) { eval(''); })", true, false }, | |
| 2706 }; | |
| 2707 | |
| 2708 int prefix_len = Utf8LengthHelper(prefix); | |
| 2709 int midfix_len = Utf8LengthHelper(midfix); | |
| 2710 int suffix_len = Utf8LengthHelper(suffix); | |
| 2711 for (unsigned i = 0; i < ARRAY_SIZE(outers); ++i) { | |
| 2712 const char* outer = outers[i].source; | |
| 2713 int outer_len = Utf8LengthHelper(outer); | |
| 2714 for (unsigned j = 0; j < ARRAY_SIZE(inners); ++j) { | |
| 2715 if (outers[i].strict && inners[j].with) continue; | |
| 2716 const char* inner = inners[j].source; | |
| 2717 int inner_len = Utf8LengthHelper(inner); | |
| 2718 int len = prefix_len + outer_len + midfix_len + inner_len + suffix_len; | |
| 2719 i::ScopedVector<char> program(len + 1); | |
| 2720 i::SNPrintF(program, "%s%s%s%s%s", prefix, outer, midfix, inner, suffix); | |
| 2721 i::Handle<i::String> source = | |
| 2722 factory->InternalizeUtf8String(program.start()); | |
| 2723 source->PrintOn(stdout); | |
| 2724 printf("\n"); | |
| 2725 | |
| 2726 i::Handle<i::Script> script = factory->NewScript(source); | |
| 2727 i::CompilationInfoWithZone info(script); | |
| 2728 i::Parser parser(&info); | |
| 2729 parser.set_allow_harmony_scoping(true); | |
| 2730 CHECK(parser.Parse()); | |
| 2731 CHECK(i::Rewriter::Rewrite(&info)); | |
| 2732 CHECK(i::Scope::Analyze(&info)); | |
| 2733 CHECK(info.function() != NULL); | |
| 2734 | |
| 2735 i::Scope* scope = info.function()->scope(); | |
| 2736 CHECK_EQ(scope->inner_scopes()->length(), 1); | |
| 2737 i::Scope* inner_scope = scope->inner_scopes()->at(0); | |
| 2738 const i::AstRawString* var_name = | |
| 2739 info.ast_value_factory()->GetOneByteString("x"); | |
| 2740 i::Variable* var = inner_scope->Lookup(var_name); | |
| 2741 bool expected = outers[i].assigned || inners[j].assigned; | |
| 2742 CHECK(var != NULL); | |
| 2743 CHECK(var->is_used() || !expected); | |
| 2744 CHECK(var->maybe_assigned() == expected); | |
| 2745 } | |
| 2746 } | |
| 2747 } | |
| OLD | NEW |