OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 13 matching lines...) Expand all Loading... |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include <stdlib.h> | 28 #include <stdlib.h> |
29 #include <stdio.h> | 29 #include <stdio.h> |
30 #include <string.h> | 30 #include <string.h> |
31 | 31 |
32 #include "v8.h" | 32 #include "v8.h" |
33 | 33 |
| 34 #include "isolate.h" |
34 #include "token.h" | 35 #include "token.h" |
35 #include "scanner.h" | 36 #include "scanner.h" |
36 #include "parser.h" | 37 #include "parser.h" |
37 #include "utils.h" | 38 #include "utils.h" |
38 #include "execution.h" | 39 #include "execution.h" |
39 #include "preparser.h" | 40 #include "preparser.h" |
40 #include "cctest.h" | 41 #include "cctest.h" |
41 | 42 |
42 namespace i = ::v8::internal; | 43 namespace i = ::v8::internal; |
43 | 44 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 "/* precomment */ --> is eol-comment\nvar y = 37;\n", | 147 "/* precomment */ --> is eol-comment\nvar y = 37;\n", |
147 "\n/* precomment */ --> is eol-comment\nvar y = 37;\n", | 148 "\n/* precomment */ --> is eol-comment\nvar y = 37;\n", |
148 // After first real token. | 149 // After first real token. |
149 "var x = 42;\n--> is eol-comment\nvar y = 37;\n", | 150 "var x = 42;\n--> is eol-comment\nvar y = 37;\n", |
150 "var x = 42;\n/* precomment */ --> is eol-comment\nvar y = 37;\n", | 151 "var x = 42;\n/* precomment */ --> is eol-comment\nvar y = 37;\n", |
151 NULL | 152 NULL |
152 }; | 153 }; |
153 | 154 |
154 // Parser/Scanner needs a stack limit. | 155 // Parser/Scanner needs a stack limit. |
155 int marker; | 156 int marker; |
156 i::StackGuard::SetStackLimit( | 157 i::Isolate::Current()->stack_guard()->SetStackLimit( |
157 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); | 158 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); |
158 | 159 |
159 for (int i = 0; tests[i]; i++) { | 160 for (int i = 0; tests[i]; i++) { |
160 v8::ScriptData* data = | 161 v8::ScriptData* data = |
161 v8::ScriptData::PreCompile(tests[i], i::StrLength(tests[i])); | 162 v8::ScriptData::PreCompile(tests[i], i::StrLength(tests[i])); |
162 CHECK(data != NULL && !data->HasError()); | 163 CHECK(data != NULL && !data->HasError()); |
163 delete data; | 164 delete data; |
164 } | 165 } |
165 } | 166 } |
166 | 167 |
(...skipping 10 matching lines...) Expand all Loading... |
177 const char* data_; | 178 const char* data_; |
178 size_t length_; | 179 size_t length_; |
179 }; | 180 }; |
180 | 181 |
181 | 182 |
182 TEST(Preparsing) { | 183 TEST(Preparsing) { |
183 v8::HandleScope handles; | 184 v8::HandleScope handles; |
184 v8::Persistent<v8::Context> context = v8::Context::New(); | 185 v8::Persistent<v8::Context> context = v8::Context::New(); |
185 v8::Context::Scope context_scope(context); | 186 v8::Context::Scope context_scope(context); |
186 int marker; | 187 int marker; |
187 i::StackGuard::SetStackLimit( | 188 i::Isolate::Current()->stack_guard()->SetStackLimit( |
188 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); | 189 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); |
189 | 190 |
190 // Source containing functions that might be lazily compiled and all types | 191 // Source containing functions that might be lazily compiled and all types |
191 // of symbols (string, propertyName, regexp). | 192 // of symbols (string, propertyName, regexp). |
192 const char* source = | 193 const char* source = |
193 "var x = 42;" | 194 "var x = 42;" |
194 "function foo(a) { return function nolazy(b) { return a + b; } }" | 195 "function foo(a) { return function nolazy(b) { return a + b; } }" |
195 "function bar(a) { if (a) return function lazy(b) { return b; } }" | 196 "function bar(a) { if (a) return function lazy(b) { return b; } }" |
196 "var z = {'string': 'string literal', bareword: 'propertyName', " | 197 "var z = {'string': 'string literal', bareword: 'propertyName', " |
197 " 42: 'number literal', for: 'keyword as propertyName', " | 198 " 42: 'number literal', for: 'keyword as propertyName', " |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 CHECK_EQ(11, error_location.end_pos); | 239 CHECK_EQ(11, error_location.end_pos); |
239 // Should not crash. | 240 // Should not crash. |
240 const char* message = pre_impl->BuildMessage(); | 241 const char* message = pre_impl->BuildMessage(); |
241 i::Vector<const char*> args = pre_impl->BuildArgs(); | 242 i::Vector<const char*> args = pre_impl->BuildArgs(); |
242 CHECK_GT(strlen(message), 0); | 243 CHECK_GT(strlen(message), 0); |
243 } | 244 } |
244 | 245 |
245 | 246 |
246 TEST(StandAlonePreParser) { | 247 TEST(StandAlonePreParser) { |
247 int marker; | 248 int marker; |
248 i::StackGuard::SetStackLimit( | 249 i::Isolate::Current()->stack_guard()->SetStackLimit( |
249 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); | 250 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); |
250 | 251 |
251 const char* programs[] = { | 252 const char* programs[] = { |
252 "{label: 42}", | 253 "{label: 42}", |
253 "var x = 42;", | 254 "var x = 42;", |
254 "function foo(x, y) { return x + y; }", | 255 "function foo(x, y) { return x + y; }", |
255 "native function foo(); return %ArgleBargle(glop);", | 256 "native function foo(); return %ArgleBargle(glop);", |
256 "var x = new new Function('this.x = 42');", | 257 "var x = new new Function('this.x = 42');", |
257 NULL | 258 NULL |
258 }; | 259 }; |
259 | 260 |
260 uintptr_t stack_limit = i::StackGuard::real_climit(); | 261 uintptr_t stack_limit = ISOLATE->stack_guard()->real_climit(); |
261 for (int i = 0; programs[i]; i++) { | 262 for (int i = 0; programs[i]; i++) { |
262 const char* program = programs[i]; | 263 const char* program = programs[i]; |
263 i::Utf8ToUC16CharacterStream stream( | 264 i::Utf8ToUC16CharacterStream stream( |
264 reinterpret_cast<const i::byte*>(program), | 265 reinterpret_cast<const i::byte*>(program), |
265 static_cast<unsigned>(strlen(program))); | 266 static_cast<unsigned>(strlen(program))); |
266 i::CompleteParserRecorder log; | 267 i::CompleteParserRecorder log; |
267 i::V8JavaScriptScanner scanner; | 268 i::V8JavaScriptScanner scanner(ISOLATE); |
268 scanner.Initialize(&stream); | 269 scanner.Initialize(&stream); |
269 | 270 |
270 v8::preparser::PreParser::PreParseResult result = | 271 v8::preparser::PreParser::PreParseResult result = |
271 v8::preparser::PreParser::PreParseProgram(&scanner, | 272 v8::preparser::PreParser::PreParseProgram(&scanner, |
272 &log, | 273 &log, |
273 true, | 274 true, |
274 stack_limit); | 275 stack_limit); |
275 CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result); | 276 CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result); |
276 i::ScriptDataImpl data(log.ExtractData()); | 277 i::ScriptDataImpl data(log.ExtractData()); |
277 CHECK(!data.has_error()); | 278 CHECK(!data.has_error()); |
278 } | 279 } |
279 } | 280 } |
280 | 281 |
281 | 282 |
282 TEST(RegressChromium62639) { | 283 TEST(RegressChromium62639) { |
283 int marker; | 284 int marker; |
284 i::StackGuard::SetStackLimit( | 285 ISOLATE->stack_guard()->SetStackLimit( |
285 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); | 286 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); |
286 | 287 |
287 const char* program = "var x = 'something';\n" | 288 const char* program = "var x = 'something';\n" |
288 "escape: function() {}"; | 289 "escape: function() {}"; |
289 // Fails parsing expecting an identifier after "function". | 290 // Fails parsing expecting an identifier after "function". |
290 // Before fix, didn't check *ok after Expect(Token::Identifier, ok), | 291 // Before fix, didn't check *ok after Expect(Token::Identifier, ok), |
291 // and then used the invalid currently scanned literal. This always | 292 // and then used the invalid currently scanned literal. This always |
292 // failed in debug mode, and sometimes crashed in release mode. | 293 // failed in debug mode, and sometimes crashed in release mode. |
293 | 294 |
294 i::Utf8ToUC16CharacterStream stream(reinterpret_cast<const i::byte*>(program), | 295 i::Utf8ToUC16CharacterStream stream(reinterpret_cast<const i::byte*>(program), |
295 static_cast<unsigned>(strlen(program))); | 296 static_cast<unsigned>(strlen(program))); |
296 i::ScriptDataImpl* data = | 297 i::ScriptDataImpl* data = |
297 i::ParserApi::PreParse(&stream, NULL); | 298 i::ParserApi::PreParse(&stream, NULL); |
298 CHECK(data->HasError()); | 299 CHECK(data->HasError()); |
299 delete data; | 300 delete data; |
300 } | 301 } |
301 | 302 |
302 | 303 |
303 TEST(Regress928) { | 304 TEST(Regress928) { |
304 // Preparsing didn't consider the catch clause of a try statement | 305 // Preparsing didn't consider the catch clause of a try statement |
305 // as with-content, which made it assume that a function inside | 306 // as with-content, which made it assume that a function inside |
306 // the block could be lazily compiled, and an extra, unexpected, | 307 // the block could be lazily compiled, and an extra, unexpected, |
307 // entry was added to the data. | 308 // entry was added to the data. |
308 int marker; | 309 int marker; |
309 i::StackGuard::SetStackLimit( | 310 ISOLATE->stack_guard()->SetStackLimit( |
310 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); | 311 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); |
311 | 312 |
312 const char* program = | 313 const char* program = |
313 "try { } catch (e) { var foo = function () { /* first */ } }" | 314 "try { } catch (e) { var foo = function () { /* first */ } }" |
314 "var bar = function () { /* second */ }"; | 315 "var bar = function () { /* second */ }"; |
315 | 316 |
316 i::Utf8ToUC16CharacterStream stream(reinterpret_cast<const i::byte*>(program), | 317 i::Utf8ToUC16CharacterStream stream(reinterpret_cast<const i::byte*>(program), |
317 static_cast<unsigned>(strlen(program))); | 318 static_cast<unsigned>(strlen(program))); |
318 i::ScriptDataImpl* data = | 319 i::ScriptDataImpl* data = |
319 i::ParserApi::PartialPreParse(&stream, NULL); | 320 i::ParserApi::PartialPreParse(&stream, NULL); |
(...skipping 15 matching lines...) Expand all Loading... |
335 CHECK_EQ('{', program[second_lbrace]); | 336 CHECK_EQ('{', program[second_lbrace]); |
336 i::FunctionEntry entry2 = data->GetFunctionEntry(second_lbrace); | 337 i::FunctionEntry entry2 = data->GetFunctionEntry(second_lbrace); |
337 CHECK(entry2.is_valid()); | 338 CHECK(entry2.is_valid()); |
338 CHECK_EQ('}', program[entry2.end_pos() - 1]); | 339 CHECK_EQ('}', program[entry2.end_pos() - 1]); |
339 delete data; | 340 delete data; |
340 } | 341 } |
341 | 342 |
342 | 343 |
343 TEST(PreParseOverflow) { | 344 TEST(PreParseOverflow) { |
344 int marker; | 345 int marker; |
345 i::StackGuard::SetStackLimit( | 346 ISOLATE->stack_guard()->SetStackLimit( |
346 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); | 347 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); |
347 | 348 |
348 size_t kProgramSize = 1024 * 1024; | 349 size_t kProgramSize = 1024 * 1024; |
349 i::SmartPointer<char> program( | 350 i::SmartPointer<char> program( |
350 reinterpret_cast<char*>(malloc(kProgramSize + 1))); | 351 reinterpret_cast<char*>(malloc(kProgramSize + 1))); |
351 memset(*program, '(', kProgramSize); | 352 memset(*program, '(', kProgramSize); |
352 program[kProgramSize] = '\0'; | 353 program[kProgramSize] = '\0'; |
353 | 354 |
354 uintptr_t stack_limit = i::StackGuard::real_climit(); | 355 uintptr_t stack_limit = ISOLATE->stack_guard()->real_climit(); |
355 | 356 |
356 i::Utf8ToUC16CharacterStream stream( | 357 i::Utf8ToUC16CharacterStream stream( |
357 reinterpret_cast<const i::byte*>(*program), | 358 reinterpret_cast<const i::byte*>(*program), |
358 static_cast<unsigned>(kProgramSize)); | 359 static_cast<unsigned>(kProgramSize)); |
359 i::CompleteParserRecorder log; | 360 i::CompleteParserRecorder log; |
360 i::V8JavaScriptScanner scanner; | 361 i::V8JavaScriptScanner scanner(ISOLATE); |
361 scanner.Initialize(&stream); | 362 scanner.Initialize(&stream); |
362 | 363 |
363 | 364 |
364 v8::preparser::PreParser::PreParseResult result = | 365 v8::preparser::PreParser::PreParseResult result = |
365 v8::preparser::PreParser::PreParseProgram(&scanner, | 366 v8::preparser::PreParser::PreParseProgram(&scanner, |
366 &log, | 367 &log, |
367 true, | 368 true, |
368 stack_limit); | 369 stack_limit); |
369 CHECK_EQ(v8::preparser::PreParser::kPreParseStackOverflow, result); | 370 CHECK_EQ(v8::preparser::PreParser::kPreParseStackOverflow, result); |
370 } | 371 } |
(...skipping 27 matching lines...) Expand all Loading... |
398 unsigned end = 0) { | 399 unsigned end = 0) { |
399 if (end == 0) end = length; | 400 if (end == 0) end = length; |
400 unsigned sub_length = end - start; | 401 unsigned sub_length = end - start; |
401 i::HandleScope test_scope; | 402 i::HandleScope test_scope; |
402 i::SmartPointer<i::uc16> uc16_buffer(new i::uc16[length]); | 403 i::SmartPointer<i::uc16> uc16_buffer(new i::uc16[length]); |
403 for (unsigned i = 0; i < length; i++) { | 404 for (unsigned i = 0; i < length; i++) { |
404 uc16_buffer[i] = static_cast<i::uc16>(ascii_source[i]); | 405 uc16_buffer[i] = static_cast<i::uc16>(ascii_source[i]); |
405 } | 406 } |
406 i::Vector<const char> ascii_vector(ascii_source, static_cast<int>(length)); | 407 i::Vector<const char> ascii_vector(ascii_source, static_cast<int>(length)); |
407 i::Handle<i::String> ascii_string( | 408 i::Handle<i::String> ascii_string( |
408 i::Factory::NewStringFromAscii(ascii_vector)); | 409 FACTORY->NewStringFromAscii(ascii_vector)); |
409 TestExternalResource resource(*uc16_buffer, length); | 410 TestExternalResource resource(*uc16_buffer, length); |
410 i::Handle<i::String> uc16_string( | 411 i::Handle<i::String> uc16_string( |
411 i::Factory::NewExternalStringFromTwoByte(&resource)); | 412 FACTORY->NewExternalStringFromTwoByte(&resource)); |
412 | 413 |
413 i::ExternalTwoByteStringUC16CharacterStream uc16_stream( | 414 i::ExternalTwoByteStringUC16CharacterStream uc16_stream( |
414 i::Handle<i::ExternalTwoByteString>::cast(uc16_string), start, end); | 415 i::Handle<i::ExternalTwoByteString>::cast(uc16_string), start, end); |
415 i::GenericStringUC16CharacterStream string_stream(ascii_string, start, end); | 416 i::GenericStringUC16CharacterStream string_stream(ascii_string, start, end); |
416 i::Utf8ToUC16CharacterStream utf8_stream( | 417 i::Utf8ToUC16CharacterStream utf8_stream( |
417 reinterpret_cast<const i::byte*>(ascii_source), end); | 418 reinterpret_cast<const i::byte*>(ascii_source), end); |
418 utf8_stream.SeekForward(start); | 419 utf8_stream.SeekForward(start); |
419 | 420 |
420 unsigned i = start; | 421 unsigned i = start; |
421 while (i < end) { | 422 while (i < end) { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 CHECK_EQU(i, stream.pos()); | 569 CHECK_EQU(i, stream.pos()); |
569 } | 570 } |
570 } | 571 } |
571 | 572 |
572 #undef CHECK_EQU | 573 #undef CHECK_EQU |
573 | 574 |
574 void TestStreamScanner(i::UC16CharacterStream* stream, | 575 void TestStreamScanner(i::UC16CharacterStream* stream, |
575 i::Token::Value* expected_tokens, | 576 i::Token::Value* expected_tokens, |
576 int skip_pos = 0, // Zero means not skipping. | 577 int skip_pos = 0, // Zero means not skipping. |
577 int skip_to = 0) { | 578 int skip_to = 0) { |
578 i::V8JavaScriptScanner scanner; | 579 i::V8JavaScriptScanner scanner(ISOLATE); |
579 scanner.Initialize(stream); | 580 scanner.Initialize(stream); |
580 | 581 |
581 int i = 0; | 582 int i = 0; |
582 do { | 583 do { |
583 i::Token::Value expected = expected_tokens[i]; | 584 i::Token::Value expected = expected_tokens[i]; |
584 i::Token::Value actual = scanner.Next(); | 585 i::Token::Value actual = scanner.Next(); |
585 CHECK_EQ(i::Token::String(expected), i::Token::String(actual)); | 586 CHECK_EQ(i::Token::String(expected), i::Token::String(actual)); |
586 if (scanner.location().end_pos == skip_pos) { | 587 if (scanner.location().end_pos == skip_pos) { |
587 scanner.SeekForward(skip_to); | 588 scanner.SeekForward(skip_to); |
588 } | 589 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 static_cast<unsigned>(strlen(str3))); | 648 static_cast<unsigned>(strlen(str3))); |
648 TestStreamScanner(&stream3, expectations3, 1, 1 + i); | 649 TestStreamScanner(&stream3, expectations3, 1, 1 + i); |
649 } | 650 } |
650 } | 651 } |
651 | 652 |
652 | 653 |
653 void TestScanRegExp(const char* re_source, const char* expected) { | 654 void TestScanRegExp(const char* re_source, const char* expected) { |
654 i::Utf8ToUC16CharacterStream stream( | 655 i::Utf8ToUC16CharacterStream stream( |
655 reinterpret_cast<const i::byte*>(re_source), | 656 reinterpret_cast<const i::byte*>(re_source), |
656 static_cast<unsigned>(strlen(re_source))); | 657 static_cast<unsigned>(strlen(re_source))); |
657 i::V8JavaScriptScanner scanner; | 658 i::V8JavaScriptScanner scanner(ISOLATE); |
658 scanner.Initialize(&stream); | 659 scanner.Initialize(&stream); |
659 | 660 |
660 i::Token::Value start = scanner.peek(); | 661 i::Token::Value start = scanner.peek(); |
661 CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV); | 662 CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV); |
662 CHECK(scanner.ScanRegExpPattern(start == i::Token::ASSIGN_DIV)); | 663 CHECK(scanner.ScanRegExpPattern(start == i::Token::ASSIGN_DIV)); |
663 scanner.Next(); // Current token is now the regexp literal. | 664 scanner.Next(); // Current token is now the regexp literal. |
664 CHECK(scanner.is_literal_ascii()); | 665 CHECK(scanner.is_literal_ascii()); |
665 i::Vector<const char> actual = scanner.literal_ascii_string(); | 666 i::Vector<const char> actual = scanner.literal_ascii_string(); |
666 for (int i = 0; i < actual.length(); i++) { | 667 for (int i = 0; i < actual.length(); i++) { |
667 CHECK_NE('\0', expected[i]); | 668 CHECK_NE('\0', expected[i]); |
(...skipping 28 matching lines...) Expand all Loading... |
696 TestScanRegExp("/[\\u12]/flipperwald", "[\\u12]"); | 697 TestScanRegExp("/[\\u12]/flipperwald", "[\\u12]"); |
697 TestScanRegExp("/[\\u123]/flipperwald", "[\\u123]"); | 698 TestScanRegExp("/[\\u123]/flipperwald", "[\\u123]"); |
698 // Escaped ']'s wont end the character class. | 699 // Escaped ']'s wont end the character class. |
699 TestScanRegExp("/[\\]/]/flipperwald", "[\\]/]"); | 700 TestScanRegExp("/[\\]/]/flipperwald", "[\\]/]"); |
700 // Escaped slashes are not terminating. | 701 // Escaped slashes are not terminating. |
701 TestScanRegExp("/\\//flipperwald", "\\/"); | 702 TestScanRegExp("/\\//flipperwald", "\\/"); |
702 // Starting with '=' works too. | 703 // Starting with '=' works too. |
703 TestScanRegExp("/=/", "="); | 704 TestScanRegExp("/=/", "="); |
704 TestScanRegExp("/=?/", "=?"); | 705 TestScanRegExp("/=?/", "=?"); |
705 } | 706 } |
OLD | NEW |