| 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 |