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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 #include "src/parsing/parser.h" | 46 #include "src/parsing/parser.h" |
47 #include "src/parsing/parsing.h" | 47 #include "src/parsing/parsing.h" |
48 #include "src/parsing/preparser.h" | 48 #include "src/parsing/preparser.h" |
49 #include "src/parsing/rewriter.h" | 49 #include "src/parsing/rewriter.h" |
50 #include "src/parsing/scanner-character-streams.h" | 50 #include "src/parsing/scanner-character-streams.h" |
51 #include "src/parsing/token.h" | 51 #include "src/parsing/token.h" |
52 #include "src/unicode-cache.h" | 52 #include "src/unicode-cache.h" |
53 #include "src/utils.h" | 53 #include "src/utils.h" |
54 | 54 |
55 #include "test/cctest/cctest.h" | 55 #include "test/cctest/cctest.h" |
| 56 #include "test/cctest/scope-test-helper.h" |
| 57 #include "test/cctest/unicode-helpers.h" |
56 | 58 |
57 TEST(ScanKeywords) { | 59 TEST(ScanKeywords) { |
58 struct KeywordToken { | 60 struct KeywordToken { |
59 const char* keyword; | 61 const char* keyword; |
60 i::Token::Value token; | 62 i::Token::Value token; |
61 }; | 63 }; |
62 | 64 |
63 static const KeywordToken keywords[] = { | 65 static const KeywordToken keywords[] = { |
64 #define KEYWORD(t, s, d) { s, i::Token::t }, | 66 #define KEYWORD(t, s, d) { s, i::Token::t }, |
65 TOKEN_LIST(IGNORE_TOKEN, KEYWORD) | 67 TOKEN_LIST(IGNORE_TOKEN, KEYWORD) |
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 TestScanRegExp("/[\\u123]/flipperwald", "[\\u123]"); | 697 TestScanRegExp("/[\\u123]/flipperwald", "[\\u123]"); |
696 // Escaped ']'s wont end the character class. | 698 // Escaped ']'s wont end the character class. |
697 TestScanRegExp("/[\\]/]/flipperwald", "[\\]/]"); | 699 TestScanRegExp("/[\\]/]/flipperwald", "[\\]/]"); |
698 // Escaped slashes are not terminating. | 700 // Escaped slashes are not terminating. |
699 TestScanRegExp("/\\//flipperwald", "\\/"); | 701 TestScanRegExp("/\\//flipperwald", "\\/"); |
700 // Starting with '=' works too. | 702 // Starting with '=' works too. |
701 TestScanRegExp("/=/", "="); | 703 TestScanRegExp("/=/", "="); |
702 TestScanRegExp("/=?/", "=?"); | 704 TestScanRegExp("/=?/", "=?"); |
703 } | 705 } |
704 | 706 |
705 static int Ucs2CharLength(unibrow::uchar c) { | |
706 if (c == unibrow::Utf8::kIncomplete || c == unibrow::Utf8::kBufferEmpty) { | |
707 return 0; | |
708 } else if (c < 0xffff) { | |
709 return 1; | |
710 } else { | |
711 return 2; | |
712 } | |
713 } | |
714 | |
715 static int Utf8LengthHelper(const char* s) { | |
716 unibrow::Utf8::Utf8IncrementalBuffer buffer(unibrow::Utf8::kBufferEmpty); | |
717 int length = 0; | |
718 for (; *s != '\0'; s++) { | |
719 unibrow::uchar tmp = unibrow::Utf8::ValueOfIncremental(*s, &buffer); | |
720 length += Ucs2CharLength(tmp); | |
721 } | |
722 unibrow::uchar tmp = unibrow::Utf8::ValueOfIncrementalFinish(&buffer); | |
723 length += Ucs2CharLength(tmp); | |
724 return length; | |
725 } | |
726 | |
727 | |
728 TEST(ScopeUsesArgumentsSuperThis) { | 707 TEST(ScopeUsesArgumentsSuperThis) { |
729 static const struct { | 708 static const struct { |
730 const char* prefix; | 709 const char* prefix; |
731 const char* suffix; | 710 const char* suffix; |
732 } surroundings[] = { | 711 } surroundings[] = { |
733 { "function f() {", "}" }, | 712 { "function f() {", "}" }, |
734 { "var f = () => {", "};" }, | 713 { "var f = () => {", "};" }, |
735 { "class C { constructor() {", "} }" }, | 714 { "class C { constructor() {", "} }" }, |
736 }; | 715 }; |
737 | 716 |
(...skipping 8081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8819 "const arguments = 1", | 8798 "const arguments = 1", |
8820 "let arguments", | 8799 "let arguments", |
8821 "var arguments", | 8800 "var arguments", |
8822 NULL | 8801 NULL |
8823 }; | 8802 }; |
8824 // clang-format on | 8803 // clang-format on |
8825 RunParserSyncTest(context_data, data, kSuccess); | 8804 RunParserSyncTest(context_data, data, kSuccess); |
8826 } | 8805 } |
8827 } | 8806 } |
8828 | 8807 |
8829 namespace v8 { | |
8830 namespace internal { | |
8831 | |
8832 class ScopeTestHelper { | |
8833 public: | |
8834 static bool MustAllocateInContext(Variable* var) { | |
8835 return var->scope()->MustAllocateInContext(var); | |
8836 } | |
8837 | |
8838 // True if the scope is and its entire subscope tree are hidden. | |
8839 static bool ScopeTreeIsHidden(Scope* scope) { | |
8840 if (!scope->is_hidden()) { | |
8841 return false; | |
8842 } | |
8843 for (Scope* inner = scope->inner_scope(); inner != nullptr; | |
8844 inner = inner->sibling()) { | |
8845 if (!ScopeTreeIsHidden(inner)) { | |
8846 return false; | |
8847 } | |
8848 } | |
8849 return true; | |
8850 } | |
8851 | |
8852 static void CompareScopeToData(Scope* scope, const PreParsedScopeData* data, | |
8853 size_t& index) { | |
8854 CHECK_EQ(data->backing_store_[index++], scope->scope_type()); | |
8855 CHECK_EQ(data->backing_store_[index++], scope->start_position()); | |
8856 CHECK_EQ(data->backing_store_[index++], scope->end_position()); | |
8857 | |
8858 int inner_scope_count = 0; | |
8859 for (Scope* inner = scope->inner_scope(); inner != nullptr; | |
8860 inner = inner->sibling()) { | |
8861 // FIXME(marja): This is probably not the right condition for knowing what | |
8862 // scopes are present in the preparse data. | |
8863 if (!ScopeTreeIsHidden(inner)) { | |
8864 ++inner_scope_count; | |
8865 } | |
8866 } | |
8867 CHECK_EQ(data->backing_store_[index++], inner_scope_count); | |
8868 | |
8869 int variable_count = 0; | |
8870 for (Variable* local : scope->locals_) { | |
8871 if (local->mode() == VAR || local->mode() == LET || | |
8872 local->mode() == CONST) { | |
8873 ++variable_count; | |
8874 } | |
8875 } | |
8876 | |
8877 CHECK_EQ(data->backing_store_[index++], variable_count); | |
8878 | |
8879 for (Variable* local : scope->locals_) { | |
8880 if (local->mode() == VAR || local->mode() == LET || | |
8881 local->mode() == CONST) { | |
8882 #ifdef DEBUG | |
8883 const AstRawString* local_name = local->raw_name(); | |
8884 int name_length = data->backing_store_[index++]; | |
8885 CHECK_EQ(name_length, local_name->length()); | |
8886 for (int i = 0; i < name_length; ++i) { | |
8887 CHECK_EQ(data->backing_store_[index++], local_name->raw_data()[i]); | |
8888 } | |
8889 #endif | |
8890 CHECK_EQ(data->backing_store_[index++], local->location()); | |
8891 CHECK_EQ(data->backing_store_[index++], local->maybe_assigned()); | |
8892 } | |
8893 } | |
8894 | |
8895 for (Scope* inner = scope->inner_scope(); inner != nullptr; | |
8896 inner = inner->sibling()) { | |
8897 if (!ScopeTreeIsHidden(inner)) { | |
8898 CompareScopeToData(inner, data, index); | |
8899 } | |
8900 } | |
8901 } | |
8902 }; | |
8903 } // namespace internal | |
8904 } // namespace v8 | |
8905 | 8808 |
8906 // Test that lazily parsed inner functions don't result in overly pessimistic | 8809 // Test that lazily parsed inner functions don't result in overly pessimistic |
8907 // context allocations. | 8810 // context allocations. |
8908 TEST(NoPessimisticContextAllocation) { | 8811 TEST(NoPessimisticContextAllocation) { |
8909 i::FLAG_lazy_inner_functions = true; | 8812 i::FLAG_lazy_inner_functions = true; |
8910 i::Isolate* isolate = CcTest::i_isolate(); | 8813 i::Isolate* isolate = CcTest::i_isolate(); |
8911 i::Factory* factory = isolate->factory(); | 8814 i::Factory* factory = isolate->factory(); |
8912 i::HandleScope scope(isolate); | 8815 i::HandleScope scope(isolate); |
8913 LocalContext env; | 8816 LocalContext env; |
8914 | 8817 |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9182 DCHECK_NULL(scope->sibling()); | 9085 DCHECK_NULL(scope->sibling()); |
9183 DCHECK(scope->is_function_scope()); | 9086 DCHECK(scope->is_function_scope()); |
9184 const i::AstRawString* var_name = | 9087 const i::AstRawString* var_name = |
9185 info.ast_value_factory()->GetOneByteString("my_var"); | 9088 info.ast_value_factory()->GetOneByteString("my_var"); |
9186 i::Variable* var = scope->Lookup(var_name); | 9089 i::Variable* var = scope->Lookup(var_name); |
9187 CHECK_EQ(inners[i].ctxt_allocate, | 9090 CHECK_EQ(inners[i].ctxt_allocate, |
9188 i::ScopeTestHelper::MustAllocateInContext(var)); | 9091 i::ScopeTestHelper::MustAllocateInContext(var)); |
9189 } | 9092 } |
9190 } | 9093 } |
9191 } | 9094 } |
9192 | |
9193 TEST(PreParserScopeAnalysis) { | |
9194 i::FLAG_lazy_inner_functions = true; | |
9195 i::FLAG_preparser_scope_analysis = true; | |
9196 i::Isolate* isolate = CcTest::i_isolate(); | |
9197 i::Factory* factory = isolate->factory(); | |
9198 i::HandleScope scope(isolate); | |
9199 LocalContext env; | |
9200 | |
9201 const char* prefix = "(function outer() { "; | |
9202 const char* suffix = " })();"; | |
9203 int prefix_len = Utf8LengthHelper(prefix); | |
9204 int suffix_len = Utf8LengthHelper(suffix); | |
9205 | |
9206 // The scope start positions must match; note the extra space in lazy_inner. | |
9207 const char* lazy_inner = " function inner(%s) { %s }"; | |
9208 const char* eager_inner = "(function inner(%s) { %s })()"; | |
9209 | |
9210 struct { | |
9211 const char* params; | |
9212 const char* source; | |
9213 } inners[] = { | |
9214 // Simple cases | |
9215 {"", "var1;"}, | |
9216 {"", "var1 = 5;"}, | |
9217 {"", "if (true) {}"}, | |
9218 {"", "function f1() {}"}, | |
9219 | |
9220 // Var declarations and assignments. | |
9221 {"", "var var1;"}, | |
9222 {"", "var var1; var1 = 5;"}, | |
9223 {"", "if (true) { var var1; }"}, | |
9224 {"", "if (true) { var var1; var1 = 5; }"}, | |
9225 {"", "var var1; function f() { var1; }"}, | |
9226 {"", "var var1; var1 = 5; function f() { var1; }"}, | |
9227 {"", "var var1; function f() { var1 = 5; }"}, | |
9228 | |
9229 // Let declarations and assignments. | |
9230 {"", "let var1;"}, | |
9231 {"", "let var1; var1 = 5;"}, | |
9232 {"", "if (true) { let var1; }"}, | |
9233 {"", "if (true) { let var1; var1 = 5; }"}, | |
9234 {"", "let var1; function f() { var1; }"}, | |
9235 {"", "let var1; var1 = 5; function f() { var1; }"}, | |
9236 {"", "let var1; function f() { var1 = 5; }"}, | |
9237 | |
9238 // Const declarations. | |
9239 {"", "const var1 = 5;"}, | |
9240 {"", "if (true) { const var1 = 5; }"}, | |
9241 {"", "const var1 = 5; function f() { var1; }"}, | |
9242 | |
9243 // Redeclarations. | |
9244 {"", "var var1; var var1;"}, | |
9245 {"", "var var1; var var1; var1 = 5;"}, | |
9246 {"", "var var1; if (true) { var var1; }"}, | |
9247 {"", "if (true) { var var1; var var1; }"}, | |
9248 {"", "var var1; if (true) { var var1; var1 = 5; }"}, | |
9249 {"", "if (true) { var var1; var var1; var1 = 5; }"}, | |
9250 {"", "var var1; var var1; function f() { var1; }"}, | |
9251 {"", "var var1; var var1; function f() { var1 = 5; }"}, | |
9252 | |
9253 // Shadowing declarations. | |
9254 {"", "var var1; if (true) { var var1; }"}, | |
9255 {"", "var var1; if (true) { let var1; }"}, | |
9256 {"", "let var1; if (true) { let var1; }"}, | |
9257 | |
9258 {"", "var var1; if (true) { const var1 = 0; }"}, | |
9259 {"", "const var1 = 0; if (true) { const var1 = 0; }"}, | |
9260 | |
9261 // Arguments and this. | |
9262 {"", "arguments;"}, | |
9263 {"", "arguments = 5;"}, | |
9264 {"", "if (true) { arguments; }"}, | |
9265 {"", "if (true) { arguments = 5; }"}, | |
9266 {"", "function f() { arguments; }"}, | |
9267 {"", "function f() { arguments = 5; }"}, | |
9268 | |
9269 {"", "this;"}, | |
9270 {"", "if (true) { this; }"}, | |
9271 {"", "function f() { this; }"}, | |
9272 | |
9273 // Variable called "arguments" | |
9274 {"", "var arguments;"}, | |
9275 {"", "var arguments; arguments = 5;"}, | |
9276 {"", "if (true) { var arguments; }"}, | |
9277 {"", "if (true) { var arguments; arguments = 5; }"}, | |
9278 {"", "var arguments; function f() { arguments; }"}, | |
9279 {"", "var arguments; arguments = 5; function f() { arguments; }"}, | |
9280 {"", "var arguments; function f() { arguments = 5; }"}, | |
9281 | |
9282 {"", "let arguments;"}, | |
9283 {"", "let arguments; arguments = 5;"}, | |
9284 {"", "if (true) { let arguments; }"}, | |
9285 {"", "if (true) { let arguments; arguments = 5; }"}, | |
9286 {"", "let arguments; function f() { arguments; }"}, | |
9287 {"", "let arguments; arguments = 5; function f() { arguments; }"}, | |
9288 {"", "let arguments; function f() { arguments = 5; }"}, | |
9289 | |
9290 {"", "const arguments = 5;"}, | |
9291 {"", "if (true) { const arguments = 5; }"}, | |
9292 {"", "const arguments = 5; function f() { arguments; }"}, | |
9293 | |
9294 // Destructuring declarations. | |
9295 {"", "var [var1, var2] = [1, 2];"}, | |
9296 {"", "var [var1, var2, [var3, var4]] = [1, 2, [3, 4]];"}, | |
9297 {"", "var [{var1: var2}, {var3: var4}] = [{var1: 1}, {var3: 2}];"}, | |
9298 {"", "var [var1, ...var2] = [1, 2, 3];"}, | |
9299 | |
9300 {"", "var {var1: var2, var3: var4} = {var1: 1, var3: 2};"}, | |
9301 {"", | |
9302 "var {var1: var2, var3: {var4: var5}} = {var1: 1, var3: {var4: 2}};"}, | |
9303 {"", "var {var1: var2, var3: [var4, var5]} = {var1: 1, var3: [2, 3]};"}, | |
9304 | |
9305 {"", "let [var1, var2] = [1, 2];"}, | |
9306 {"", "let [var1, var2, [var3, var4]] = [1, 2, [3, 4]];"}, | |
9307 {"", "let [{var1: var2}, {var3: var4}] = [{var1: 1}, {var3: 2}];"}, | |
9308 {"", "let [var1, ...var2] = [1, 2, 3];"}, | |
9309 | |
9310 {"", "let {var1: var2, var3: var4} = {var1: 1, var3: 2};"}, | |
9311 {"", | |
9312 "let {var1: var2, var3: {var4: var5}} = {var1: 1, var3: {var4: 2}};"}, | |
9313 {"", "let {var1: var2, var3: [var4, var5]} = {var1: 1, var3: [2, 3]};"}, | |
9314 | |
9315 {"", "const [var1, var2] = [1, 2];"}, | |
9316 {"", "const [var1, var2, [var3, var4]] = [1, 2, [3, 4]];"}, | |
9317 {"", "const [{var1: var2}, {var3: var4}] = [{var1: 1}, {var3: 2}];"}, | |
9318 {"", "const [var1, ...var2] = [1, 2, 3];"}, | |
9319 | |
9320 {"", "const {var1: var2, var3: var4} = {var1: 1, var3: 2};"}, | |
9321 {"", | |
9322 "const {var1: var2, var3: {var4: var5}} = {var1: 1, var3: {var4: 2}};"}, | |
9323 {"", "const {var1: var2, var3: [var4, var5]} = {var1: 1, var3: [2, 3]};"}, | |
9324 | |
9325 // Referencing the function variable. | |
9326 {"", "inner;"}, | |
9327 {"", "function f1() { f1; }"}, | |
9328 {"", "function f1() { inner; }"}, | |
9329 {"", "function f1() { function f2() { f1; } }"}, | |
9330 {"", "function arguments() {}"}, | |
9331 {"", "function f1() {} function f1() {}"}, | |
9332 {"", "var f1; function f1() {}"}, | |
9333 | |
9334 // Assigning to the function variable. | |
9335 {"", "inner = 3;"}, | |
9336 {"", "function f1() { f1 = 3; }"}, | |
9337 {"", "function f1() { f1; } f1 = 3;"}, | |
9338 {"", "function arguments() {} arguments = 8"}, | |
9339 {"", "function f1() {} f1 = 3; function f1() {}"}, | |
9340 | |
9341 // Evals. | |
9342 {"", "var var1; eval('');"}, | |
9343 {"", "var var1; function f1() { eval(''); }"}, | |
9344 {"", "let var1; eval('');"}, | |
9345 {"", "let var1; function f1() { eval(''); }"}, | |
9346 {"", "const var1 = 10; eval('');"}, | |
9347 {"", "const var1 = 10; function f1() { eval(''); }"}, | |
9348 | |
9349 // Standard for loops. | |
9350 {"", "for (var var1 = 0; var1 < 10; ++var1) { }"}, | |
9351 {"", "for (let var1 = 0; var1 < 10; ++var1) { }"}, | |
9352 {"", "for (const var1 = 0; var1 < 10; ++var1) { }"}, | |
9353 | |
9354 {"", | |
9355 "for (var var1 = 0; var1 < 10; ++var1) { function foo() { var1; } }"}, | |
9356 {"", | |
9357 "for (let var1 = 0; var1 < 10; ++var1) { function foo() { var1; } }"}, | |
9358 {"", | |
9359 "for (const var1 = 0; var1 < 10; ++var1) { function foo() { var1; } }"}, | |
9360 {"", | |
9361 "'use strict'; for (var var1 = 0; var1 < 10; ++var1) { function foo() { " | |
9362 "var1; } }"}, | |
9363 {"", | |
9364 "'use strict'; for (let var1 = 0; var1 < 10; ++var1) { function foo() { " | |
9365 "var1; } }"}, | |
9366 {"", | |
9367 "'use strict'; for (const var1 = 0; var1 < 10; ++var1) { function foo() " | |
9368 "{ var1; } }"}, | |
9369 | |
9370 // For of loops | |
9371 {"", "for (var1 of [1, 2]) { }"}, | |
9372 {"", "for (var var1 of [1, 2]) { }"}, | |
9373 {"", "for (let var1 of [1, 2]) { }"}, | |
9374 {"", "for (const var1 of [1, 2]) { }"}, | |
9375 | |
9376 {"", "for (var1 of [1, 2]) { var1; }"}, | |
9377 {"", "for (var var1 of [1, 2]) { var1; }"}, | |
9378 {"", "for (let var1 of [1, 2]) { var1; }"}, | |
9379 {"", "for (const var1 of [1, 2]) { var1; }"}, | |
9380 | |
9381 {"", "for (var1 of [1, 2]) { var1 = 0; }"}, | |
9382 {"", "for (var var1 of [1, 2]) { var1 = 0; }"}, | |
9383 {"", "for (let var1 of [1, 2]) { var1 = 0; }"}, | |
9384 {"", "for (const var1 of [1, 2]) { var1 = 0; }"}, | |
9385 | |
9386 {"", "for (var1 of [1, 2]) { function foo() { var1; } }"}, | |
9387 {"", "for (var var1 of [1, 2]) { function foo() { var1; } }"}, | |
9388 {"", "for (let var1 of [1, 2]) { function foo() { var1; } }"}, | |
9389 {"", "for (const var1 of [1, 2]) { function foo() { var1; } }"}, | |
9390 | |
9391 {"", "for (var1 of [1, 2]) { function foo() { var1 = 0; } }"}, | |
9392 {"", "for (var var1 of [1, 2]) { function foo() { var1 = 0; } }"}, | |
9393 {"", "for (let var1 of [1, 2]) { function foo() { var1 = 0; } }"}, | |
9394 {"", "for (const var1 of [1, 2]) { function foo() { var1 = 0; } }"}, | |
9395 | |
9396 // For in loops | |
9397 {"", "for (var1 in {a: 6}) { }"}, | |
9398 {"", "for (var var1 in {a: 6}) { }"}, | |
9399 {"", "for (let var1 in {a: 6}) { }"}, | |
9400 {"", "for (const var1 in {a: 6}) { }"}, | |
9401 | |
9402 {"", "for (var1 in {a: 6}) { var1; }"}, | |
9403 {"", "for (var var1 in {a: 6}) { var1; }"}, | |
9404 {"", "for (let var1 in {a: 6}) { var1; }"}, | |
9405 {"", "for (const var1 in {a: 6}) { var1; }"}, | |
9406 | |
9407 {"", "for (var1 in {a: 6}) { var1 = 0; }"}, | |
9408 {"", "for (var var1 in {a: 6}) { var1 = 0; }"}, | |
9409 {"", "for (let var1 in {a: 6}) { var1 = 0; }"}, | |
9410 {"", "for (const var1 in {a: 6}) { var1 = 0; }"}, | |
9411 | |
9412 {"", "for (var1 in {a: 6}) { function foo() { var1; } }"}, | |
9413 {"", "for (var var1 in {a: 6}) { function foo() { var1; } }"}, | |
9414 {"", "for (let var1 in {a: 6}) { function foo() { var1; } }"}, | |
9415 {"", "for (const var1 in {a: 6}) { function foo() { var1; } }"}, | |
9416 | |
9417 {"", "for (var1 in {a: 6}) { function foo() { var1 = 0; } }"}, | |
9418 {"", "for (var var1 in {a: 6}) { function foo() { var1 = 0; } }"}, | |
9419 {"", "for (let var1 in {a: 6}) { function foo() { var1 = 0; } }"}, | |
9420 {"", "for (const var1 in {a: 6}) { function foo() { var1 = 0; } }"}, | |
9421 | |
9422 {"", "for (var1 in {a: 6}) { function foo() { var1 = 0; } }"}, | |
9423 {"", "for (var var1 in {a: 6}) { function foo() { var1 = 0; } }"}, | |
9424 {"", "for (let var1 in {a: 6}) { function foo() { var1 = 0; } }"}, | |
9425 {"", "for (const var1 in {a: 6}) { function foo() { var1 = 0; } }"}, | |
9426 | |
9427 // Loops without declarations | |
9428 {"", "var var1 = 0; for ( ; var1 < 2; ++var1) { }"}, | |
9429 {"", | |
9430 "var var1 = 0; for ( ; var1 < 2; ++var1) { function foo() { var1; } }"}, | |
9431 {"", "var var1 = 0; for ( ; var1 > 2; ) { }"}, | |
9432 {"", "var var1 = 0; for ( ; var1 > 2; ) { function foo() { var1; } }"}, | |
9433 {"", | |
9434 "var var1 = 0; for ( ; var1 > 2; ) { function foo() { var1 = 6; } }"}, | |
9435 | |
9436 {"", "var var1 = 0; for(var1; var1 < 2; ++var1) { }"}, | |
9437 {"", | |
9438 "var var1 = 0; for (var1; var1 < 2; ++var1) { function foo() { var1; } " | |
9439 "}"}, | |
9440 {"", "var var1 = 0; for (var1; var1 > 2; ) { }"}, | |
9441 {"", "var var1 = 0; for (var1; var1 > 2; ) { function foo() { var1; } }"}, | |
9442 {"", | |
9443 "var var1 = 0; for (var1; var1 > 2; ) { function foo() { var1 = 6; } }"}, | |
9444 | |
9445 // Sloppy block functions. | |
9446 {"", "if (true) { function f1() {} }"}, | |
9447 {"", "if (true) { function f1() {} function f1() {} }"}, | |
9448 {"", "if (true) { if (true) { function f1() {} } }"}, | |
9449 {"", "if (true) { if (true) { function f1() {} function f1() {} } }"}, | |
9450 {"", "if (true) { function f1() {} f1 = 3; }"}, | |
9451 | |
9452 {"", "if (true) { function f1() {} function foo() { f1; } }"}, | |
9453 {"", "if (true) { function f1() {} } function foo() { f1; }"}, | |
9454 {"", | |
9455 "if (true) { function f1() {} function f1() {} function foo() { f1; } " | |
9456 "}"}, | |
9457 {"", | |
9458 "if (true) { function f1() {} function f1() {} } function foo() { f1; " | |
9459 "}"}, | |
9460 {"", | |
9461 "if (true) { if (true) { function f1() {} } function foo() { f1; } }"}, | |
9462 {"", | |
9463 "if (true) { if (true) { function f1() {} function f1() {} } function " | |
9464 "foo() { f1; } }"}, | |
9465 {"", "if (true) { function f1() {} f1 = 3; function foo() { f1; } }"}, | |
9466 {"", "if (true) { function f1() {} f1 = 3; } function foo() { f1; }"}, | |
9467 | |
9468 {"", "function inner2() { if (true) { function f1() {} } }"}, | |
9469 {"", "function inner2() { if (true) { function f1() {} f1 = 3; } }"}, | |
9470 | |
9471 {"", "var f1 = 1; if (true) { function f1() {} }"}, | |
9472 {"", "var f1 = 1; if (true) { function f1() {} } function foo() { f1; }"}, | |
9473 }; | |
9474 | |
9475 for (unsigned i = 0; i < arraysize(inners); ++i) { | |
9476 // First compile with the lazy inner function and extract the scope data. | |
9477 const char* inner_function = lazy_inner; | |
9478 int inner_function_len = Utf8LengthHelper(inner_function) - 4; | |
9479 | |
9480 int params_len = Utf8LengthHelper(inners[i].params); | |
9481 int source_len = Utf8LengthHelper(inners[i].source); | |
9482 int len = | |
9483 prefix_len + inner_function_len + params_len + source_len + suffix_len; | |
9484 | |
9485 i::ScopedVector<char> lazy_program(len + 1); | |
9486 i::SNPrintF(lazy_program, "%s", prefix); | |
9487 i::SNPrintF(lazy_program + prefix_len, inner_function, inners[i].params, | |
9488 inners[i].source); | |
9489 i::SNPrintF(lazy_program + prefix_len + inner_function_len + params_len + | |
9490 source_len, | |
9491 "%s", suffix); | |
9492 | |
9493 i::Handle<i::String> source = | |
9494 factory->InternalizeUtf8String(lazy_program.start()); | |
9495 source->PrintOn(stdout); | |
9496 printf("\n"); | |
9497 | |
9498 i::Handle<i::Script> script = factory->NewScript(source); | |
9499 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); | |
9500 i::ParseInfo lazy_info(&zone, script); | |
9501 | |
9502 // No need to run scope analysis; preparser scope data is produced when | |
9503 // parsing. | |
9504 CHECK(i::parsing::ParseProgram(&lazy_info)); | |
9505 | |
9506 // Then parse eagerly and check against the scope data. | |
9507 inner_function = eager_inner; | |
9508 inner_function_len = Utf8LengthHelper(inner_function) - 4; | |
9509 len = | |
9510 prefix_len + inner_function_len + params_len + source_len + suffix_len; | |
9511 | |
9512 i::ScopedVector<char> eager_program(len + 1); | |
9513 i::SNPrintF(eager_program, "%s", prefix); | |
9514 i::SNPrintF(eager_program + prefix_len, inner_function, inners[i].params, | |
9515 inners[i].source); | |
9516 i::SNPrintF(eager_program + prefix_len + inner_function_len + params_len + | |
9517 source_len, | |
9518 "%s", suffix); | |
9519 | |
9520 source = factory->InternalizeUtf8String(eager_program.start()); | |
9521 source->PrintOn(stdout); | |
9522 printf("\n"); | |
9523 | |
9524 script = factory->NewScript(source); | |
9525 i::ParseInfo eager_info(&zone, script); | |
9526 eager_info.set_allow_lazy_parsing(false); | |
9527 | |
9528 CHECK(i::parsing::ParseProgram(&eager_info)); | |
9529 CHECK(i::Compiler::Analyze(&eager_info)); | |
9530 | |
9531 i::Scope* scope = | |
9532 eager_info.literal()->scope()->inner_scope()->inner_scope(); | |
9533 DCHECK_NOT_NULL(scope); | |
9534 DCHECK_NULL(scope->sibling()); | |
9535 DCHECK(scope->is_function_scope()); | |
9536 | |
9537 size_t index = 0; | |
9538 i::ScopeTestHelper::CompareScopeToData( | |
9539 scope, lazy_info.preparsed_scope_data(), index); | |
9540 } | |
9541 } | |
OLD | NEW |