Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: test/cctest/test-parsing.cc

Issue 225743002: Update tests to use the new compilation API. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebased Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « test/cctest/test-api.cc ('k') | tools/parser-shell.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 "x/* precomment\n */ --> is eol-comment\nvar y = 37;\n", 137 "x/* precomment\n */ --> is eol-comment\nvar y = 37;\n",
138 "var x = 42; --> is eol-comment\nvar y = 37;\n", 138 "var x = 42; --> is eol-comment\nvar y = 37;\n",
139 "var x = 42; /* precomment\n */ --> is eol-comment\nvar y = 37;\n", 139 "var x = 42; /* precomment\n */ --> is eol-comment\nvar y = 37;\n",
140 NULL 140 NULL
141 }; 141 };
142 142
143 // Parser/Scanner needs a stack limit. 143 // Parser/Scanner needs a stack limit.
144 int marker; 144 int marker;
145 CcTest::i_isolate()->stack_guard()->SetStackLimit( 145 CcTest::i_isolate()->stack_guard()->SetStackLimit(
146 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); 146 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
147 147 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
148 for (int i = 0; tests[i]; i++) { 148 for (int i = 0; tests[i]; i++) {
149 v8::Handle<v8::String> source = v8::String::NewFromUtf8( 149 const i::byte* source =
150 isolate, tests[i], v8::String::kNormalString, i::StrLength(tests[i])); 150 reinterpret_cast<const i::byte*>(tests[i]);
151 v8::ScriptData* data = v8::ScriptData::PreCompile(source); 151 i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(tests[i]));
152 CHECK(data != NULL && !data->HasError()); 152 i::CompleteParserRecorder log;
153 delete data; 153 i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
154 scanner.Initialize(&stream);
155 i::PreParser preparser(&scanner, &log, stack_limit);
156 preparser.set_allow_lazy(true);
157 i::PreParser::PreParseResult result = preparser.PreParseProgram();
158 CHECK_EQ(i::PreParser::kPreParseSuccess, result);
159 i::ScriptDataImpl data(log.ExtractData());
160 CHECK(!data.has_error());
154 } 161 }
155 162
156 for (int i = 0; fail_tests[i]; i++) { 163 for (int i = 0; fail_tests[i]; i++) {
157 v8::Handle<v8::String> source = 164 const i::byte* source =
158 v8::String::NewFromUtf8(isolate, 165 reinterpret_cast<const i::byte*>(fail_tests[i]);
159 fail_tests[i], 166 i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(fail_tests[i]));
160 v8::String::kNormalString, 167 i::CompleteParserRecorder log;
161 i::StrLength(fail_tests[i])); 168 i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
162 v8::ScriptData* data = v8::ScriptData::PreCompile(source); 169 scanner.Initialize(&stream);
163 CHECK(data == NULL || data->HasError()); 170 i::PreParser preparser(&scanner, &log, stack_limit);
164 delete data; 171 preparser.set_allow_lazy(true);
172 i::PreParser::PreParseResult result = preparser.PreParseProgram();
173 // Even in the case of a syntax error, kPreParseSuccess is returned.
174 CHECK_EQ(i::PreParser::kPreParseSuccess, result);
175 i::ScriptDataImpl data(log.ExtractData());
176 CHECK(data.has_error());
165 } 177 }
166 } 178 }
167 179
168 180
169 class ScriptResource : public v8::String::ExternalAsciiStringResource { 181 class ScriptResource : public v8::String::ExternalAsciiStringResource {
170 public: 182 public:
171 ScriptResource(const char* data, size_t length) 183 ScriptResource(const char* data, size_t length)
172 : data_(data), length_(length) { } 184 : data_(data), length_(length) { }
173 185
174 const char* data() const { return data_; } 186 const char* data() const { return data_; }
175 size_t length() const { return length_; } 187 size_t length() const { return length_; }
176 188
177 private: 189 private:
178 const char* data_; 190 const char* data_;
179 size_t length_; 191 size_t length_;
180 }; 192 };
181 193
182 194
183 TEST(Preparsing) { 195 TEST(UsingCachedData) {
184 v8::Isolate* isolate = CcTest::isolate(); 196 v8::Isolate* isolate = CcTest::isolate();
185 v8::HandleScope handles(isolate); 197 v8::HandleScope handles(isolate);
186 v8::Local<v8::Context> context = v8::Context::New(isolate); 198 v8::Local<v8::Context> context = v8::Context::New(isolate);
187 v8::Context::Scope context_scope(context); 199 v8::Context::Scope context_scope(context);
188 int marker; 200 int marker;
189 CcTest::i_isolate()->stack_guard()->SetStackLimit( 201 CcTest::i_isolate()->stack_guard()->SetStackLimit(
190 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); 202 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
191 203
192 // Source containing functions that might be lazily compiled and all types 204 // Source containing functions that might be lazily compiled and all types
193 // of symbols (string, propertyName, regexp). 205 // of symbols (string, propertyName, regexp).
194 const char* source = 206 const char* source =
195 "var x = 42;" 207 "var x = 42;"
196 "function foo(a) { return function nolazy(b) { return a + b; } }" 208 "function foo(a) { return function nolazy(b) { return a + b; } }"
197 "function bar(a) { if (a) return function lazy(b) { return b; } }" 209 "function bar(a) { if (a) return function lazy(b) { return b; } }"
198 "var z = {'string': 'string literal', bareword: 'propertyName', " 210 "var z = {'string': 'string literal', bareword: 'propertyName', "
199 " 42: 'number literal', for: 'keyword as propertyName', " 211 " 42: 'number literal', for: 'keyword as propertyName', "
200 " f\\u006fr: 'keyword propertyname with escape'};" 212 " f\\u006fr: 'keyword propertyname with escape'};"
201 "var v = /RegExp Literal/;" 213 "var v = /RegExp Literal/;"
202 "var w = /RegExp Literal\\u0020With Escape/gin;" 214 "var w = /RegExp Literal\\u0020With Escape/gin;"
203 "var y = { get getter() { return 42; }, " 215 "var y = { get getter() { return 42; }, "
204 " set setter(v) { this.value = v; }};"; 216 " set setter(v) { this.value = v; }};";
205 int source_length = i::StrLength(source); 217 int source_length = i::StrLength(source);
206 const char* error_source = "var x = y z;";
207 int error_source_length = i::StrLength(error_source);
208 218
209 v8::ScriptData* preparse = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( 219 // ScriptResource will be deleted when the corresponding String is GCd.
210 isolate, source, v8::String::kNormalString, source_length)); 220 v8::ScriptCompiler::Source script_source(v8::String::NewExternal(
211 CHECK(!preparse->HasError()); 221 isolate, new ScriptResource(source, source_length)));
222 i::FLAG_min_preparse_length = 0;
223 v8::ScriptCompiler::Compile(isolate, &script_source,
224 v8::ScriptCompiler::kProduceDataToCache);
225 CHECK(script_source.GetCachedData());
226
227 // Compile the script again, using the cached data.
212 bool lazy_flag = i::FLAG_lazy; 228 bool lazy_flag = i::FLAG_lazy;
213 { 229 i::FLAG_lazy = true;
214 i::FLAG_lazy = true; 230 v8::ScriptCompiler::Compile(isolate, &script_source);
215 ScriptResource* resource = new ScriptResource(source, source_length); 231 i::FLAG_lazy = false;
216 v8::ScriptCompiler::Source script_source( 232 v8::ScriptCompiler::CompileUnbound(isolate, &script_source);
217 v8::String::NewExternal(isolate, resource),
218 new v8::ScriptCompiler::CachedData(
219 reinterpret_cast<const uint8_t*>(preparse->Data()),
220 preparse->Length()));
221 v8::ScriptCompiler::Compile(isolate,
222 &script_source);
223 }
224
225 {
226 i::FLAG_lazy = false;
227
228 ScriptResource* resource = new ScriptResource(source, source_length);
229 v8::ScriptCompiler::Source script_source(
230 v8::String::NewExternal(isolate, resource),
231 new v8::ScriptCompiler::CachedData(
232 reinterpret_cast<const uint8_t*>(preparse->Data()),
233 preparse->Length()));
234 v8::ScriptCompiler::CompileUnbound(isolate, &script_source);
235 }
236 delete preparse;
237 i::FLAG_lazy = lazy_flag; 233 i::FLAG_lazy = lazy_flag;
238
239 // Syntax error.
240 v8::ScriptData* error_preparse = v8::ScriptData::PreCompile(
241 v8::String::NewFromUtf8(isolate,
242 error_source,
243 v8::String::kNormalString,
244 error_source_length));
245 CHECK(error_preparse->HasError());
246 i::ScriptDataImpl *pre_impl =
247 reinterpret_cast<i::ScriptDataImpl*>(error_preparse);
248 i::Scanner::Location error_location =
249 pre_impl->MessageLocation();
250 // Error is at "z" in source, location 10..11.
251 CHECK_EQ(10, error_location.beg_pos);
252 CHECK_EQ(11, error_location.end_pos);
253 // Should not crash.
254 const char* message = pre_impl->BuildMessage();
255 i::Vector<const char*> args = pre_impl->BuildArgs();
256 CHECK_GT(strlen(message), 0);
257 args.Dispose();
258 i::DeleteArray(message);
259 delete error_preparse;
260 } 234 }
261 235
262 236
263 TEST(PreparseFunctionDataIsUsed) { 237 TEST(PreparseFunctionDataIsUsed) {
264 // This tests that we actually do use the function data generated by the 238 // This tests that we actually do use the function data generated by the
265 // preparser. 239 // preparser.
266 240
267 // Make preparsing work for short scripts. 241 // Make preparsing work for short scripts.
268 i::FLAG_min_preparse_length = 0; 242 i::FLAG_min_preparse_length = 0;
269 243
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 namespace internal { 439 namespace internal {
466 440
467 struct CompleteParserRecorderFriend { 441 struct CompleteParserRecorderFriend {
468 static void FakeWritingSymbolIdInPreParseData(CompleteParserRecorder* log, 442 static void FakeWritingSymbolIdInPreParseData(CompleteParserRecorder* log,
469 int number) { 443 int number) {
470 log->WriteNumber(number); 444 log->WriteNumber(number);
471 if (log->symbol_id_ < number + 1) { 445 if (log->symbol_id_ < number + 1) {
472 log->symbol_id_ = number + 1; 446 log->symbol_id_ = number + 1;
473 } 447 }
474 } 448 }
475 static int symbol_position(CompleteParserRecorder* log) {
476 return log->symbol_store_.size();
477 }
478 static int symbol_ids(CompleteParserRecorder* log) {
479 return log->symbol_id_;
480 }
481 static int function_position(CompleteParserRecorder* log) {
482 return log->function_store_.size();
483 }
484 }; 449 };
485 450
486 } 451 }
487 } 452 }
488 453
489 454
490 TEST(StoringNumbersInPreParseData) { 455 TEST(StoringNumbersInPreParseData) {
491 // Symbol IDs are split into chunks of 7 bits for storing. This is a 456 // Symbol IDs are split into chunks of 7 bits for storing. This is a
492 // regression test for a bug where a symbol id was incorrectly stored if some 457 // regression test for a bug where a symbol id was incorrectly stored if some
493 // of the chunks in the middle were all zeros. 458 // of the chunks in the middle were all zeros.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 const char* program = "var x = 'something';\n" 494 const char* program = "var x = 'something';\n"
530 "escape: function() {}"; 495 "escape: function() {}";
531 // Fails parsing expecting an identifier after "function". 496 // Fails parsing expecting an identifier after "function".
532 // Before fix, didn't check *ok after Expect(Token::Identifier, ok), 497 // Before fix, didn't check *ok after Expect(Token::Identifier, ok),
533 // and then used the invalid currently scanned literal. This always 498 // and then used the invalid currently scanned literal. This always
534 // failed in debug mode, and sometimes crashed in release mode. 499 // failed in debug mode, and sometimes crashed in release mode.
535 500
536 i::Utf8ToUtf16CharacterStream stream( 501 i::Utf8ToUtf16CharacterStream stream(
537 reinterpret_cast<const i::byte*>(program), 502 reinterpret_cast<const i::byte*>(program),
538 static_cast<unsigned>(strlen(program))); 503 static_cast<unsigned>(strlen(program)));
539 i::ScriptDataImpl* data = i::PreParserApi::PreParse(isolate, &stream); 504 i::CompleteParserRecorder log;
540 CHECK(data->HasError()); 505 i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
541 delete data; 506 scanner.Initialize(&stream);
507 i::PreParser preparser(&scanner, &log,
508 CcTest::i_isolate()->stack_guard()->real_climit());
509 preparser.set_allow_lazy(true);
510 i::PreParser::PreParseResult result = preparser.PreParseProgram();
511 // Even in the case of a syntax error, kPreParseSuccess is returned.
512 CHECK_EQ(i::PreParser::kPreParseSuccess, result);
513 i::ScriptDataImpl data(log.ExtractData());
514 CHECK(data.has_error());
542 } 515 }
543 516
544 517
545 TEST(Regress928) { 518 TEST(Regress928) {
546 v8::V8::Initialize(); 519 v8::V8::Initialize();
547 i::Isolate* isolate = CcTest::i_isolate(); 520 i::Isolate* isolate = CcTest::i_isolate();
548 i::Factory* factory = isolate->factory(); 521 i::Factory* factory = isolate->factory();
549 522
550 // Preparsing didn't consider the catch clause of a try statement 523 // Preparsing didn't consider the catch clause of a try statement
551 // as with-content, which made it assume that a function inside 524 // as with-content, which made it assume that a function inside
552 // the block could be lazily compiled, and an extra, unexpected, 525 // the block could be lazily compiled, and an extra, unexpected,
553 // entry was added to the data. 526 // entry was added to the data.
554 int marker; 527 int marker;
555 isolate->stack_guard()->SetStackLimit( 528 isolate->stack_guard()->SetStackLimit(
556 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); 529 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
557 530
558 const char* program = 531 const char* program =
559 "try { } catch (e) { var foo = function () { /* first */ } }" 532 "try { } catch (e) { var foo = function () { /* first */ } }"
560 "var bar = function () { /* second */ }"; 533 "var bar = function () { /* second */ }";
561 534
562 v8::HandleScope handles(CcTest::isolate()); 535 v8::HandleScope handles(CcTest::isolate());
563 i::Handle<i::String> source( 536 i::Handle<i::String> source(
564 factory->NewStringFromAscii(i::CStrVector(program))); 537 factory->NewStringFromAscii(i::CStrVector(program)));
565 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); 538 i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
566 i::ScriptDataImpl* data = i::PreParserApi::PreParse(isolate, &stream); 539 i::CompleteParserRecorder log;
567 CHECK(!data->HasError()); 540 i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
568 541 scanner.Initialize(&stream);
569 data->Initialize(); 542 i::PreParser preparser(&scanner, &log,
543 CcTest::i_isolate()->stack_guard()->real_climit());
544 preparser.set_allow_lazy(true);
545 i::PreParser::PreParseResult result = preparser.PreParseProgram();
546 CHECK_EQ(i::PreParser::kPreParseSuccess, result);
547 i::ScriptDataImpl data(log.ExtractData());
548 CHECK(!data.has_error());
549 data.Initialize();
570 550
571 int first_function = 551 int first_function =
572 static_cast<int>(strstr(program, "function") - program); 552 static_cast<int>(strstr(program, "function") - program);
573 int first_lbrace = first_function + i::StrLength("function () "); 553 int first_lbrace = first_function + i::StrLength("function () ");
574 CHECK_EQ('{', program[first_lbrace]); 554 CHECK_EQ('{', program[first_lbrace]);
575 i::FunctionEntry entry1 = data->GetFunctionEntry(first_lbrace); 555 i::FunctionEntry entry1 = data.GetFunctionEntry(first_lbrace);
576 CHECK(!entry1.is_valid()); 556 CHECK(!entry1.is_valid());
577 557
578 int second_function = 558 int second_function =
579 static_cast<int>(strstr(program + first_lbrace, "function") - program); 559 static_cast<int>(strstr(program + first_lbrace, "function") - program);
580 int second_lbrace = 560 int second_lbrace =
581 second_function + i::StrLength("function () "); 561 second_function + i::StrLength("function () ");
582 CHECK_EQ('{', program[second_lbrace]); 562 CHECK_EQ('{', program[second_lbrace]);
583 i::FunctionEntry entry2 = data->GetFunctionEntry(second_lbrace); 563 i::FunctionEntry entry2 = data.GetFunctionEntry(second_lbrace);
584 CHECK(entry2.is_valid()); 564 CHECK(entry2.is_valid());
585 CHECK_EQ('}', program[entry2.end_pos() - 1]); 565 CHECK_EQ('}', program[entry2.end_pos() - 1]);
586 delete data;
587 } 566 }
588 567
589 568
590 TEST(PreParseOverflow) { 569 TEST(PreParseOverflow) {
591 v8::V8::Initialize(); 570 v8::V8::Initialize();
592 571
593 int marker; 572 int marker;
594 CcTest::i_isolate()->stack_guard()->SetStackLimit( 573 CcTest::i_isolate()->stack_guard()->SetStackLimit(
595 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); 574 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
596 575
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 // the combinatorial explosion. 1528 // the combinatorial explosion.
1550 static const ParserFlag flags2[] = { kAllowHarmonyNumericLiterals }; 1529 static const ParserFlag flags2[] = { kAllowHarmonyNumericLiterals };
1551 TestParserSync("0o1234", flags2, ARRAY_SIZE(flags2)); 1530 TestParserSync("0o1234", flags2, ARRAY_SIZE(flags2));
1552 TestParserSync("0b1011", flags2, ARRAY_SIZE(flags2)); 1531 TestParserSync("0b1011", flags2, ARRAY_SIZE(flags2));
1553 1532
1554 static const ParserFlag flags3[] = { kAllowNativesSyntax }; 1533 static const ParserFlag flags3[] = { kAllowNativesSyntax };
1555 TestParserSync("%DebugPrint(123)", flags3, ARRAY_SIZE(flags3)); 1534 TestParserSync("%DebugPrint(123)", flags3, ARRAY_SIZE(flags3));
1556 } 1535 }
1557 1536
1558 1537
1559 TEST(PreparserStrictOctal) { 1538 TEST(StrictOctal) {
1560 // Test that syntax error caused by octal literal is reported correctly as 1539 // Test that syntax error caused by octal literal is reported correctly as
1561 // such (issue 2220). 1540 // such (issue 2220).
1562 v8::internal::FLAG_min_preparse_length = 1; // Force preparsing.
1563 v8::V8::Initialize(); 1541 v8::V8::Initialize();
1564 v8::HandleScope scope(CcTest::isolate()); 1542 v8::HandleScope scope(CcTest::isolate());
1565 v8::Context::Scope context_scope( 1543 v8::Context::Scope context_scope(
1566 v8::Context::New(CcTest::isolate())); 1544 v8::Context::New(CcTest::isolate()));
1567 v8::TryCatch try_catch; 1545 v8::TryCatch try_catch;
1568 const char* script = 1546 const char* script =
1569 "\"use strict\"; \n" 1547 "\"use strict\"; \n"
1570 "a = function() { \n" 1548 "a = function() { \n"
1571 " b = function() { \n" 1549 " b = function() { \n"
1572 " 01; \n" 1550 " 01; \n"
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
2079 "var foo = {}; foo.eval;", 2057 "var foo = {}; foo.eval;",
2080 "var foo = {}; foo.arguments;", 2058 "var foo = {}; foo.arguments;",
2081 NULL 2059 NULL
2082 }; 2060 };
2083 2061
2084 RunParserSyncTest(context_data, statement_data, kSuccess); 2062 RunParserSyncTest(context_data, statement_data, kSuccess);
2085 } 2063 }
2086 2064
2087 2065
2088 TEST(DontRegressPreParserDataSizes) { 2066 TEST(DontRegressPreParserDataSizes) {
2089 // These tests make sure that PreParser doesn't start producing less data. 2067 // These tests make sure that Parser doesn't start producing less "preparse
2068 // data" (data which the embedder can cache).
2069 v8::V8::Initialize();
2070 v8::Isolate* isolate = CcTest::isolate();
2071 v8::HandleScope handles(isolate);
2090 2072
2091 v8::V8::Initialize();
2092 int marker; 2073 int marker;
2093 CcTest::i_isolate()->stack_guard()->SetStackLimit( 2074 CcTest::i_isolate()->stack_guard()->SetStackLimit(
2094 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); 2075 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
2095 2076
2096 struct TestCase { 2077 struct TestCase {
2097 const char* program; 2078 const char* program;
2098 int symbols; 2079 int symbols;
2099 int functions; 2080 int functions;
2100 } test_cases[] = { 2081 } test_cases[] = {
2101 // Labels and variables are recorded as symbols. 2082 // Labels and variables are recorded as symbols.
2102 {"{label: 42}", 1, 0}, {"{label: 42; label2: 43}", 2, 0}, 2083 {"{label: 42}", 1, 0}, {"{label: 42; label2: 43}", 2, 0},
2103 {"var x = 42;", 1, 0}, {"var x = 42, y = 43;", 2, 0}, 2084 {"var x = 42;", 1, 0}, {"var x = 42, y = 43;", 2, 0},
2104 {"var x = {y: 1};", 2, 0}, 2085 {"var x = {y: 1};", 2, 0},
2105 {"var x = {}; x.y = 1", 2, 0}, 2086 {"var x = {}; x.y = 1", 2, 0},
2106 // "get" is recorded as a symbol too. 2087 // "get" is recorded as a symbol too.
2107 {"var x = {get foo(){} };", 3, 1}, 2088 {"var x = {get foo(){} };", 3, 1},
2108 // When keywords are used as identifiers, they're logged as symbols, too: 2089 // When keywords are used as identifiers, they're logged as symbols, too:
2109 {"var x = {if: 1};", 2, 0}, 2090 {"var x = {if: 1};", 2, 0},
2110 {"var x = {}; x.if = 1", 2, 0}, 2091 {"var x = {}; x.if = 1", 2, 0},
2111 {"var x = {get if(){} };", 3, 1}, 2092 {"var x = {get if(){} };", 3, 1},
2112 // Functions 2093 // Functions
2113 {"function foo() {}", 1, 1}, {"function foo() {} function bar() {}", 2, 2}, 2094 {"function foo() {}", 1, 1}, {"function foo() {} function bar() {}", 2, 2},
2114 // Labels, variables and functions insize lazy functions are not recorded. 2095 // Labels, variables and functions insize lazy functions are not recorded.
2115 {"function lazy() { var a, b, c; }", 1, 1}, 2096 {"function lazy() { var a, b, c; }", 1, 1},
2116 {"function lazy() { a: 1; b: 2; c: 3; }", 1, 1}, 2097 {"function lazy() { a: 1; b: 2; c: 3; }", 1, 1},
2117 {"function lazy() { function a() {} function b() {} function c() {} }", 1, 2098 {"function lazy() { function a() {} function b() {} function c() {} }", 1,
2118 1}, 2099 1},
2119 {NULL, 0, 0} 2100 {NULL, 0, 0}
2120 }; 2101 };
2121 // Each function adds 5 elements to the preparse function data.
2122 const int kDataPerFunction = 5;
2123 2102
2124 typedef i::CompleteParserRecorderFriend F;
2125 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
2126 for (int i = 0; test_cases[i].program; i++) { 2103 for (int i = 0; test_cases[i].program; i++) {
2127 const char* program = test_cases[i].program; 2104 const char* program = test_cases[i].program;
2128 i::Utf8ToUtf16CharacterStream stream( 2105 i::Factory* factory = CcTest::i_isolate()->factory();
2129 reinterpret_cast<const i::byte*>(program), 2106 i::Handle<i::String> source(
2130 static_cast<unsigned>(strlen(program))); 2107 factory->NewStringFromUtf8(i::CStrVector(program)));
2131 i::CompleteParserRecorder log; 2108 i::Handle<i::Script> script = factory->NewScript(source);
2132 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); 2109 i::CompilationInfoWithZone info(script);
2133 scanner.Initialize(&stream); 2110 i::ScriptDataImpl* data = NULL;
2111 info.SetCachedData(&data, i::PRODUCE_CACHED_DATA);
2112 i::Parser::Parse(&info, true);
2113 CHECK(data);
2114 CHECK(!data->HasError());
2134 2115
2135 i::PreParser preparser(&scanner, &log, stack_limit); 2116 if (data->symbol_count() != test_cases[i].symbols) {
2136 preparser.set_allow_lazy(true);
2137 preparser.set_allow_natives_syntax(true);
2138 i::PreParser::PreParseResult result = preparser.PreParseProgram();
2139 CHECK_EQ(i::PreParser::kPreParseSuccess, result);
2140 if (F::symbol_ids(&log) != test_cases[i].symbols) {
2141 i::OS::Print( 2117 i::OS::Print(
2142 "Expected preparse data for program:\n" 2118 "Expected preparse data for program:\n"
2143 "\t%s\n" 2119 "\t%s\n"
2144 "to contain %d symbols, however, received %d symbols.\n", 2120 "to contain %d symbols, however, received %d symbols.\n",
2145 program, test_cases[i].symbols, F::symbol_ids(&log)); 2121 program, test_cases[i].symbols, data->symbol_count());
2146 CHECK(false); 2122 CHECK(false);
2147 } 2123 }
2148 if (F::function_position(&log) != 2124 if (data->function_count() != test_cases[i].functions) {
2149 test_cases[i].functions * kDataPerFunction) {
2150 i::OS::Print( 2125 i::OS::Print(
2151 "Expected preparse data for program:\n" 2126 "Expected preparse data for program:\n"
2152 "\t%s\n" 2127 "\t%s\n"
2153 "to contain %d functions, however, received %d functions.\n", 2128 "to contain %d functions, however, received %d functions.\n",
2154 program, test_cases[i].functions, 2129 program, test_cases[i].functions,
2155 F::function_position(&log) / kDataPerFunction); 2130 data->function_count());
2156 CHECK(false); 2131 CHECK(false);
2157 } 2132 }
2158 i::ScriptDataImpl data(log.ExtractData());
2159 CHECK(!data.has_error());
2160 } 2133 }
2161 } 2134 }
2162 2135
2163 2136
2164 TEST(FunctionDeclaresItselfStrict) { 2137 TEST(FunctionDeclaresItselfStrict) {
2165 // Tests that we produce the right kinds of errors when a function declares 2138 // Tests that we produce the right kinds of errors when a function declares
2166 // itself strict (we cannot produce there errors as soon as we see the 2139 // itself strict (we cannot produce there errors as soon as we see the
2167 // offending identifiers, because we don't know at that point whether the 2140 // offending identifiers, because we don't know at that point whether the
2168 // function is strict or not). 2141 // function is strict or not).
2169 const char* context_data[][2] = { 2142 const char* context_data[][2] = {
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
2597 RunParserSyncTest(assignment_context_data, bad_statement_data_common, kError); 2570 RunParserSyncTest(assignment_context_data, bad_statement_data_common, kError);
2598 RunParserSyncTest(assignment_context_data, bad_statement_data_for_assignment, 2571 RunParserSyncTest(assignment_context_data, bad_statement_data_for_assignment,
2599 kError); 2572 kError);
2600 2573
2601 RunParserSyncTest(prefix_context_data, good_statement_data, kSuccess); 2574 RunParserSyncTest(prefix_context_data, good_statement_data, kSuccess);
2602 RunParserSyncTest(prefix_context_data, bad_statement_data_common, kError); 2575 RunParserSyncTest(prefix_context_data, bad_statement_data_common, kError);
2603 2576
2604 RunParserSyncTest(postfix_context_data, good_statement_data, kSuccess); 2577 RunParserSyncTest(postfix_context_data, good_statement_data, kSuccess);
2605 RunParserSyncTest(postfix_context_data, bad_statement_data_common, kError); 2578 RunParserSyncTest(postfix_context_data, bad_statement_data_common, kError);
2606 } 2579 }
OLDNEW
« no previous file with comments | « test/cctest/test-api.cc ('k') | tools/parser-shell.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698