v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
test-parsing.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
27 
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 
32 #include "v8.h"
33 
34 #include "cctest.h"
35 #include "compiler.h"
36 #include "execution.h"
37 #include "isolate.h"
38 #include "parser.h"
39 #include "preparser.h"
41 #include "token.h"
42 #include "utils.h"
43 
44 TEST(ScanKeywords) {
45  struct KeywordToken {
46  const char* keyword;
47  i::Token::Value token;
48  };
49 
50  static const KeywordToken keywords[] = {
51 #define KEYWORD(t, s, d) { s, i::Token::t },
53 #undef KEYWORD
54  { NULL, i::Token::IDENTIFIER }
55  };
56 
57  KeywordToken key_token;
58  i::UnicodeCache unicode_cache;
59  i::byte buffer[32];
60  for (int i = 0; (key_token = keywords[i]).keyword != NULL; i++) {
61  const i::byte* keyword =
62  reinterpret_cast<const i::byte*>(key_token.keyword);
63  int length = i::StrLength(key_token.keyword);
64  CHECK(static_cast<int>(sizeof(buffer)) >= length);
65  {
66  i::Utf8ToUtf16CharacterStream stream(keyword, length);
67  i::Scanner scanner(&unicode_cache);
68  // The scanner should parse Harmony keywords for this test.
69  scanner.SetHarmonyScoping(true);
70  scanner.SetHarmonyModules(true);
71  scanner.Initialize(&stream);
72  CHECK_EQ(key_token.token, scanner.Next());
73  CHECK_EQ(i::Token::EOS, scanner.Next());
74  }
75  // Removing characters will make keyword matching fail.
76  {
77  i::Utf8ToUtf16CharacterStream stream(keyword, length - 1);
78  i::Scanner scanner(&unicode_cache);
79  scanner.Initialize(&stream);
80  CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
81  CHECK_EQ(i::Token::EOS, scanner.Next());
82  }
83  // Adding characters will make keyword matching fail.
84  static const char chars_to_append[] = { 'z', '0', '_' };
85  for (int j = 0; j < static_cast<int>(ARRAY_SIZE(chars_to_append)); ++j) {
86  memmove(buffer, keyword, length);
87  buffer[length] = chars_to_append[j];
88  i::Utf8ToUtf16CharacterStream stream(buffer, length + 1);
89  i::Scanner scanner(&unicode_cache);
90  scanner.Initialize(&stream);
91  CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
92  CHECK_EQ(i::Token::EOS, scanner.Next());
93  }
94  // Replacing characters will make keyword matching fail.
95  {
96  memmove(buffer, keyword, length);
97  buffer[length - 1] = '_';
98  i::Utf8ToUtf16CharacterStream stream(buffer, length);
99  i::Scanner scanner(&unicode_cache);
100  scanner.Initialize(&stream);
101  CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
102  CHECK_EQ(i::Token::EOS, scanner.Next());
103  }
104  }
105 }
106 
107 
108 TEST(ScanHTMLEndComments) {
110 
111  // Regression test. See:
112  // http://code.google.com/p/chromium/issues/detail?id=53548
113  // Tests that --> is correctly interpreted as comment-to-end-of-line if there
114  // is only whitespace before it on the line (with comments considered as
115  // whitespace, even a multiline-comment containing a newline).
116  // This was not the case if it occurred before the first real token
117  // in the input.
118  const char* tests[] = {
119  // Before first real token.
120  "--> is eol-comment\nvar y = 37;\n",
121  "\n --> is eol-comment\nvar y = 37;\n",
122  "/* precomment */ --> is eol-comment\nvar y = 37;\n",
123  "\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
124  // After first real token.
125  "var x = 42;\n--> is eol-comment\nvar y = 37;\n",
126  "var x = 42;\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
127  NULL
128  };
129 
130  const char* fail_tests[] = {
131  "x --> is eol-comment\nvar y = 37;\n",
132  "\"\\n\" --> is eol-comment\nvar y = 37;\n",
133  "x/* precomment */ --> is eol-comment\nvar y = 37;\n",
134  "x/* precomment\n */ --> is eol-comment\nvar y = 37;\n",
135  "var x = 42; --> is eol-comment\nvar y = 37;\n",
136  "var x = 42; /* precomment\n */ --> is eol-comment\nvar y = 37;\n",
137  NULL
138  };
139 
140  // Parser/Scanner needs a stack limit.
141  int marker;
142  i::Isolate::Current()->stack_guard()->SetStackLimit(
143  reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
144 
145  for (int i = 0; tests[i]; i++) {
146  v8::ScriptData* data =
147  v8::ScriptData::PreCompile(tests[i], i::StrLength(tests[i]));
148  CHECK(data != NULL && !data->HasError());
149  delete data;
150  }
151 
152  for (int i = 0; fail_tests[i]; i++) {
153  v8::ScriptData* data =
154  v8::ScriptData::PreCompile(fail_tests[i], i::StrLength(fail_tests[i]));
155  CHECK(data == NULL || data->HasError());
156  delete data;
157  }
158 }
159 
160 
162  public:
163  ScriptResource(const char* data, size_t length)
164  : data_(data), length_(length) { }
165 
166  const char* data() const { return data_; }
167  size_t length() const { return length_; }
168 
169  private:
170  const char* data_;
171  size_t length_;
172 };
173 
174 
175 TEST(Preparsing) {
176  v8::HandleScope handles;
178  v8::Context::Scope context_scope(context);
179  int marker;
180  i::Isolate::Current()->stack_guard()->SetStackLimit(
181  reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
182 
183  // Source containing functions that might be lazily compiled and all types
184  // of symbols (string, propertyName, regexp).
185  const char* source =
186  "var x = 42;"
187  "function foo(a) { return function nolazy(b) { return a + b; } }"
188  "function bar(a) { if (a) return function lazy(b) { return b; } }"
189  "var z = {'string': 'string literal', bareword: 'propertyName', "
190  " 42: 'number literal', for: 'keyword as propertyName', "
191  " f\\u006fr: 'keyword propertyname with escape'};"
192  "var v = /RegExp Literal/;"
193  "var w = /RegExp Literal\\u0020With Escape/gin;"
194  "var y = { get getter() { return 42; }, "
195  " set setter(v) { this.value = v; }};";
196  int source_length = i::StrLength(source);
197  const char* error_source = "var x = y z;";
198  int error_source_length = i::StrLength(error_source);
199 
200  v8::ScriptData* preparse =
201  v8::ScriptData::PreCompile(source, source_length);
202  CHECK(!preparse->HasError());
203  bool lazy_flag = i::FLAG_lazy;
204  {
205  i::FLAG_lazy = true;
206  ScriptResource* resource = new ScriptResource(source, source_length);
207  v8::Local<v8::String> script_source = v8::String::NewExternal(resource);
208  v8::Script::Compile(script_source, NULL, preparse);
209  }
210 
211  {
212  i::FLAG_lazy = false;
213 
214  ScriptResource* resource = new ScriptResource(source, source_length);
215  v8::Local<v8::String> script_source = v8::String::NewExternal(resource);
216  v8::Script::New(script_source, NULL, preparse, v8::Local<v8::String>());
217  }
218  delete preparse;
219  i::FLAG_lazy = lazy_flag;
220 
221  // Syntax error.
222  v8::ScriptData* error_preparse =
223  v8::ScriptData::PreCompile(error_source, error_source_length);
224  CHECK(error_preparse->HasError());
225  i::ScriptDataImpl *pre_impl =
226  reinterpret_cast<i::ScriptDataImpl*>(error_preparse);
227  i::Scanner::Location error_location =
228  pre_impl->MessageLocation();
229  // Error is at "z" in source, location 10..11.
230  CHECK_EQ(10, error_location.beg_pos);
231  CHECK_EQ(11, error_location.end_pos);
232  // Should not crash.
233  const char* message = pre_impl->BuildMessage();
234  pre_impl->BuildArgs();
235  CHECK_GT(strlen(message), 0);
236 }
237 
238 
239 TEST(StandAlonePreParser) {
241 
242  int marker;
243  i::Isolate::Current()->stack_guard()->SetStackLimit(
244  reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
245 
246  const char* programs[] = {
247  "{label: 42}",
248  "var x = 42;",
249  "function foo(x, y) { return x + y; }",
250  "%ArgleBargle(glop);",
251  "var x = new new Function('this.x = 42');",
252  NULL
253  };
254 
255  uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
256  for (int i = 0; programs[i]; i++) {
257  const char* program = programs[i];
259  reinterpret_cast<const i::byte*>(program),
260  static_cast<unsigned>(strlen(program)));
262  i::Scanner scanner(i::Isolate::Current()->unicode_cache());
263  scanner.Initialize(&stream);
264 
268  &log,
269  flags,
270  stack_limit);
272  i::ScriptDataImpl data(log.ExtractData());
273  CHECK(!data.has_error());
274  }
275 }
276 
277 
278 TEST(StandAlonePreParserNoNatives) {
280 
281  int marker;
282  i::Isolate::Current()->stack_guard()->SetStackLimit(
283  reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
284 
285  const char* programs[] = {
286  "%ArgleBargle(glop);",
287  "var x = %_IsSmi(42);",
288  NULL
289  };
290 
291  uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
292  for (int i = 0; programs[i]; i++) {
293  const char* program = programs[i];
295  reinterpret_cast<const i::byte*>(program),
296  static_cast<unsigned>(strlen(program)));
298  i::Scanner scanner(i::Isolate::Current()->unicode_cache());
299  scanner.Initialize(&stream);
300 
301  // Flags don't allow natives syntax.
304  &log,
306  stack_limit);
308  i::ScriptDataImpl data(log.ExtractData());
309  // Data contains syntax error.
310  CHECK(data.has_error());
311  }
312 }
313 
314 
315 TEST(RegressChromium62639) {
317 
318  int marker;
319  i::Isolate::Current()->stack_guard()->SetStackLimit(
320  reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
321 
322  const char* program = "var x = 'something';\n"
323  "escape: function() {}";
324  // Fails parsing expecting an identifier after "function".
325  // Before fix, didn't check *ok after Expect(Token::Identifier, ok),
326  // and then used the invalid currently scanned literal. This always
327  // failed in debug mode, and sometimes crashed in release mode.
328 
330  reinterpret_cast<const i::byte*>(program),
331  static_cast<unsigned>(strlen(program)));
332  i::ScriptDataImpl* data =
333  i::ParserApi::PreParse(&stream, NULL, false);
334  CHECK(data->HasError());
335  delete data;
336 }
337 
338 
339 TEST(Regress928) {
341 
342  // Preparsing didn't consider the catch clause of a try statement
343  // as with-content, which made it assume that a function inside
344  // the block could be lazily compiled, and an extra, unexpected,
345  // entry was added to the data.
346  int marker;
347  i::Isolate::Current()->stack_guard()->SetStackLimit(
348  reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
349 
350  const char* program =
351  "try { } catch (e) { var foo = function () { /* first */ } }"
352  "var bar = function () { /* second */ }";
353 
354  v8::HandleScope handles;
355  i::Handle<i::String> source(
356  FACTORY->NewStringFromAscii(i::CStrVector(program)));
357  i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
358  i::ScriptDataImpl* data = i::ParserApi::PreParse(&stream, NULL, false);
359  CHECK(!data->HasError());
360 
361  data->Initialize();
362 
363  int first_function =
364  static_cast<int>(strstr(program, "function") - program);
365  int first_lbrace = first_function + i::StrLength("function () ");
366  CHECK_EQ('{', program[first_lbrace]);
367  i::FunctionEntry entry1 = data->GetFunctionEntry(first_lbrace);
368  CHECK(!entry1.is_valid());
369 
370  int second_function =
371  static_cast<int>(strstr(program + first_lbrace, "function") - program);
372  int second_lbrace =
373  second_function + i::StrLength("function () ");
374  CHECK_EQ('{', program[second_lbrace]);
375  i::FunctionEntry entry2 = data->GetFunctionEntry(second_lbrace);
376  CHECK(entry2.is_valid());
377  CHECK_EQ('}', program[entry2.end_pos() - 1]);
378  delete data;
379 }
380 
381 
382 TEST(PreParseOverflow) {
384 
385  int marker;
386  i::Isolate::Current()->stack_guard()->SetStackLimit(
387  reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
388 
389  size_t kProgramSize = 1024 * 1024;
391  reinterpret_cast<char*>(malloc(kProgramSize + 1)));
392  memset(*program, '(', kProgramSize);
393  program[kProgramSize] = '\0';
394 
395  uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
396 
398  reinterpret_cast<const i::byte*>(*program),
399  static_cast<unsigned>(kProgramSize));
401  i::Scanner scanner(i::Isolate::Current()->unicode_cache());
402  scanner.Initialize(&stream);
403 
404 
407  &log,
408  true,
409  stack_limit);
411 }
412 
413 
415  public:
417  : data_(data), length_(static_cast<size_t>(length)) { }
418 
420 
421  const uint16_t* data() const {
422  return data_;
423  }
424 
425  size_t length() const {
426  return length_;
427  }
428  private:
429  uint16_t* data_;
430  size_t length_;
431 };
432 
433 
434 #define CHECK_EQU(v1, v2) CHECK_EQ(static_cast<int>(v1), static_cast<int>(v2))
435 
436 void TestCharacterStream(const char* ascii_source,
437  unsigned length,
438  unsigned start = 0,
439  unsigned end = 0) {
440  if (end == 0) end = length;
441  unsigned sub_length = end - start;
442  i::HandleScope test_scope;
443  i::SmartArrayPointer<i::uc16> uc16_buffer(new i::uc16[length]);
444  for (unsigned i = 0; i < length; i++) {
445  uc16_buffer[i] = static_cast<i::uc16>(ascii_source[i]);
446  }
447  i::Vector<const char> ascii_vector(ascii_source, static_cast<int>(length));
448  i::Handle<i::String> ascii_string(
449  FACTORY->NewStringFromAscii(ascii_vector));
450  TestExternalResource resource(*uc16_buffer, length);
451  i::Handle<i::String> uc16_string(
452  FACTORY->NewExternalStringFromTwoByte(&resource));
453 
455  i::Handle<i::ExternalTwoByteString>::cast(uc16_string), start, end);
456  i::GenericStringUtf16CharacterStream string_stream(ascii_string, start, end);
457  i::Utf8ToUtf16CharacterStream utf8_stream(
458  reinterpret_cast<const i::byte*>(ascii_source), end);
459  utf8_stream.SeekForward(start);
460 
461  unsigned i = start;
462  while (i < end) {
463  // Read streams one char at a time
464  CHECK_EQU(i, uc16_stream.pos());
465  CHECK_EQU(i, string_stream.pos());
466  CHECK_EQU(i, utf8_stream.pos());
467  int32_t c0 = ascii_source[i];
468  int32_t c1 = uc16_stream.Advance();
469  int32_t c2 = string_stream.Advance();
470  int32_t c3 = utf8_stream.Advance();
471  i++;
472  CHECK_EQ(c0, c1);
473  CHECK_EQ(c0, c2);
474  CHECK_EQ(c0, c3);
475  CHECK_EQU(i, uc16_stream.pos());
476  CHECK_EQU(i, string_stream.pos());
477  CHECK_EQU(i, utf8_stream.pos());
478  }
479  while (i > start + sub_length / 4) {
480  // Pushback, re-read, pushback again.
481  int32_t c0 = ascii_source[i - 1];
482  CHECK_EQU(i, uc16_stream.pos());
483  CHECK_EQU(i, string_stream.pos());
484  CHECK_EQU(i, utf8_stream.pos());
485  uc16_stream.PushBack(c0);
486  string_stream.PushBack(c0);
487  utf8_stream.PushBack(c0);
488  i--;
489  CHECK_EQU(i, uc16_stream.pos());
490  CHECK_EQU(i, string_stream.pos());
491  CHECK_EQU(i, utf8_stream.pos());
492  int32_t c1 = uc16_stream.Advance();
493  int32_t c2 = string_stream.Advance();
494  int32_t c3 = utf8_stream.Advance();
495  i++;
496  CHECK_EQU(i, uc16_stream.pos());
497  CHECK_EQU(i, string_stream.pos());
498  CHECK_EQU(i, utf8_stream.pos());
499  CHECK_EQ(c0, c1);
500  CHECK_EQ(c0, c2);
501  CHECK_EQ(c0, c3);
502  uc16_stream.PushBack(c0);
503  string_stream.PushBack(c0);
504  utf8_stream.PushBack(c0);
505  i--;
506  CHECK_EQU(i, uc16_stream.pos());
507  CHECK_EQU(i, string_stream.pos());
508  CHECK_EQU(i, utf8_stream.pos());
509  }
510  unsigned halfway = start + sub_length / 2;
511  uc16_stream.SeekForward(halfway - i);
512  string_stream.SeekForward(halfway - i);
513  utf8_stream.SeekForward(halfway - i);
514  i = halfway;
515  CHECK_EQU(i, uc16_stream.pos());
516  CHECK_EQU(i, string_stream.pos());
517  CHECK_EQU(i, utf8_stream.pos());
518 
519  while (i < end) {
520  // Read streams one char at a time
521  CHECK_EQU(i, uc16_stream.pos());
522  CHECK_EQU(i, string_stream.pos());
523  CHECK_EQU(i, utf8_stream.pos());
524  int32_t c0 = ascii_source[i];
525  int32_t c1 = uc16_stream.Advance();
526  int32_t c2 = string_stream.Advance();
527  int32_t c3 = utf8_stream.Advance();
528  i++;
529  CHECK_EQ(c0, c1);
530  CHECK_EQ(c0, c2);
531  CHECK_EQ(c0, c3);
532  CHECK_EQU(i, uc16_stream.pos());
533  CHECK_EQU(i, string_stream.pos());
534  CHECK_EQU(i, utf8_stream.pos());
535  }
536 
537  int32_t c1 = uc16_stream.Advance();
538  int32_t c2 = string_stream.Advance();
539  int32_t c3 = utf8_stream.Advance();
540  CHECK_LT(c1, 0);
541  CHECK_LT(c2, 0);
542  CHECK_LT(c3, 0);
543 }
544 
545 
546 TEST(CharacterStreams) {
547  v8::HandleScope handles;
549  v8::Context::Scope context_scope(context);
550 
551  TestCharacterStream("abc\0\n\r\x7f", 7);
552  static const unsigned kBigStringSize = 4096;
553  char buffer[kBigStringSize + 1];
554  for (unsigned i = 0; i < kBigStringSize; i++) {
555  buffer[i] = static_cast<char>(i & 0x7f);
556  }
557  TestCharacterStream(buffer, kBigStringSize);
558 
559  TestCharacterStream(buffer, kBigStringSize, 576, 3298);
560 
561  TestCharacterStream("\0", 1);
562  TestCharacterStream("", 0);
563 }
564 
565 
566 TEST(Utf8CharacterStream) {
567  static const unsigned kMaxUC16CharU = unibrow::Utf8::kMaxThreeByteChar;
568  static const int kMaxUC16Char = static_cast<int>(kMaxUC16CharU);
569 
570  static const int kAllUtf8CharsSize =
574  static const unsigned kAllUtf8CharsSizeU =
575  static_cast<unsigned>(kAllUtf8CharsSize);
576 
577  char buffer[kAllUtf8CharsSizeU];
578  unsigned cursor = 0;
579  for (int i = 0; i <= kMaxUC16Char; i++) {
580  cursor += unibrow::Utf8::Encode(buffer + cursor,
581  i,
583  }
584  ASSERT(cursor == kAllUtf8CharsSizeU);
585 
586  i::Utf8ToUtf16CharacterStream stream(reinterpret_cast<const i::byte*>(buffer),
587  kAllUtf8CharsSizeU);
588  for (int i = 0; i <= kMaxUC16Char; i++) {
589  CHECK_EQU(i, stream.pos());
590  int32_t c = stream.Advance();
591  CHECK_EQ(i, c);
592  CHECK_EQU(i + 1, stream.pos());
593  }
594  for (int i = kMaxUC16Char; i >= 0; i--) {
595  CHECK_EQU(i + 1, stream.pos());
596  stream.PushBack(i);
597  CHECK_EQU(i, stream.pos());
598  }
599  int i = 0;
600  while (stream.pos() < kMaxUC16CharU) {
601  CHECK_EQU(i, stream.pos());
602  unsigned progress = stream.SeekForward(12);
603  i += progress;
604  int32_t c = stream.Advance();
605  if (i <= kMaxUC16Char) {
606  CHECK_EQ(i, c);
607  } else {
608  CHECK_EQ(-1, c);
609  }
610  i += 1;
611  CHECK_EQU(i, stream.pos());
612  }
613 }
614 
615 #undef CHECK_EQU
616 
618  i::Token::Value* expected_tokens,
619  int skip_pos = 0, // Zero means not skipping.
620  int skip_to = 0) {
621  i::Scanner scanner(i::Isolate::Current()->unicode_cache());
622  scanner.Initialize(stream);
623 
624  int i = 0;
625  do {
626  i::Token::Value expected = expected_tokens[i];
627  i::Token::Value actual = scanner.Next();
628  CHECK_EQ(i::Token::String(expected), i::Token::String(actual));
629  if (scanner.location().end_pos == skip_pos) {
630  scanner.SeekForward(skip_to);
631  }
632  i++;
633  } while (expected_tokens[i] != i::Token::ILLEGAL);
634 }
635 
636 TEST(StreamScanner) {
638 
639  const char* str1 = "{ foo get for : */ <- \n\n /*foo*/ bib";
640  i::Utf8ToUtf16CharacterStream stream1(reinterpret_cast<const i::byte*>(str1),
641  static_cast<unsigned>(strlen(str1)));
642  i::Token::Value expectations1[] = {
643  i::Token::LBRACE,
644  i::Token::IDENTIFIER,
645  i::Token::IDENTIFIER,
646  i::Token::FOR,
647  i::Token::COLON,
650  i::Token::LT,
652  i::Token::IDENTIFIER,
653  i::Token::EOS,
654  i::Token::ILLEGAL
655  };
656  TestStreamScanner(&stream1, expectations1, 0, 0);
657 
658  const char* str2 = "case default const {THIS\nPART\nSKIPPED} do";
659  i::Utf8ToUtf16CharacterStream stream2(reinterpret_cast<const i::byte*>(str2),
660  static_cast<unsigned>(strlen(str2)));
661  i::Token::Value expectations2[] = {
662  i::Token::CASE,
665  i::Token::LBRACE,
666  // Skipped part here
667  i::Token::RBRACE,
668  i::Token::DO,
669  i::Token::EOS,
670  i::Token::ILLEGAL
671  };
672  ASSERT_EQ('{', str2[19]);
673  ASSERT_EQ('}', str2[37]);
674  TestStreamScanner(&stream2, expectations2, 20, 37);
675 
676  const char* str3 = "{}}}}";
677  i::Token::Value expectations3[] = {
678  i::Token::LBRACE,
679  i::Token::RBRACE,
680  i::Token::RBRACE,
681  i::Token::RBRACE,
682  i::Token::RBRACE,
683  i::Token::EOS,
684  i::Token::ILLEGAL
685  };
686  // Skip zero-four RBRACEs.
687  for (int i = 0; i <= 4; i++) {
688  expectations3[6 - i] = i::Token::ILLEGAL;
689  expectations3[5 - i] = i::Token::EOS;
691  reinterpret_cast<const i::byte*>(str3),
692  static_cast<unsigned>(strlen(str3)));
693  TestStreamScanner(&stream3, expectations3, 1, 1 + i);
694  }
695 }
696 
697 
698 void TestScanRegExp(const char* re_source, const char* expected) {
700  reinterpret_cast<const i::byte*>(re_source),
701  static_cast<unsigned>(strlen(re_source)));
702  i::Scanner scanner(i::Isolate::Current()->unicode_cache());
703  scanner.Initialize(&stream);
704 
705  i::Token::Value start = scanner.peek();
706  CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV);
707  CHECK(scanner.ScanRegExpPattern(start == i::Token::ASSIGN_DIV));
708  scanner.Next(); // Current token is now the regexp literal.
709  CHECK(scanner.is_literal_ascii());
710  i::Vector<const char> actual = scanner.literal_ascii_string();
711  for (int i = 0; i < actual.length(); i++) {
712  CHECK_NE('\0', expected[i]);
713  CHECK_EQ(expected[i], actual[i]);
714  }
715 }
716 
717 
718 TEST(RegExpScanning) {
720 
721  // RegExp token with added garbage at the end. The scanner should only
722  // scan the RegExp until the terminating slash just before "flipperwald".
723  TestScanRegExp("/b/flipperwald", "b");
724  // Incomplete escape sequences doesn't hide the terminating slash.
725  TestScanRegExp("/\\x/flipperwald", "\\x");
726  TestScanRegExp("/\\u/flipperwald", "\\u");
727  TestScanRegExp("/\\u1/flipperwald", "\\u1");
728  TestScanRegExp("/\\u12/flipperwald", "\\u12");
729  TestScanRegExp("/\\u123/flipperwald", "\\u123");
730  TestScanRegExp("/\\c/flipperwald", "\\c");
731  TestScanRegExp("/\\c//flipperwald", "\\c");
732  // Slashes inside character classes are not terminating.
733  TestScanRegExp("/[/]/flipperwald", "[/]");
734  TestScanRegExp("/[\\s-/]/flipperwald", "[\\s-/]");
735  // Incomplete escape sequences inside a character class doesn't hide
736  // the end of the character class.
737  TestScanRegExp("/[\\c/]/flipperwald", "[\\c/]");
738  TestScanRegExp("/[\\c]/flipperwald", "[\\c]");
739  TestScanRegExp("/[\\x]/flipperwald", "[\\x]");
740  TestScanRegExp("/[\\x1]/flipperwald", "[\\x1]");
741  TestScanRegExp("/[\\u]/flipperwald", "[\\u]");
742  TestScanRegExp("/[\\u1]/flipperwald", "[\\u1]");
743  TestScanRegExp("/[\\u12]/flipperwald", "[\\u12]");
744  TestScanRegExp("/[\\u123]/flipperwald", "[\\u123]");
745  // Escaped ']'s wont end the character class.
746  TestScanRegExp("/[\\]/]/flipperwald", "[\\]/]");
747  // Escaped slashes are not terminating.
748  TestScanRegExp("/\\//flipperwald", "\\/");
749  // Starting with '=' works too.
750  TestScanRegExp("/=/", "=");
751  TestScanRegExp("/=?/", "=?");
752 }
753 
754 
755 static int Utf8LengthHelper(const char* s) {
756  int len = i::StrLength(s);
757  int character_length = len;
758  for (int i = 0; i < len; i++) {
759  unsigned char c = s[i];
760  int input_offset = 0;
761  int output_adjust = 0;
762  if (c > 0x7f) {
763  if (c < 0xc0) continue;
764  if (c >= 0xf0) {
765  if (c >= 0xf8) {
766  // 5 and 6 byte UTF-8 sequences turn into a kBadChar for each UTF-8
767  // byte.
768  continue; // Handle first UTF-8 byte.
769  }
770  if ((c & 7) == 0 && ((s[i + 1] & 0x30) == 0)) {
771  // This 4 byte sequence could have been coded as a 3 byte sequence.
772  // Record a single kBadChar for the first byte and continue.
773  continue;
774  }
775  input_offset = 3;
776  // 4 bytes of UTF-8 turn into 2 UTF-16 code units.
777  character_length -= 2;
778  } else if (c >= 0xe0) {
779  if ((c & 0xf) == 0 && ((s[i + 1] & 0x20) == 0)) {
780  // This 3 byte sequence could have been coded as a 2 byte sequence.
781  // Record a single kBadChar for the first byte and continue.
782  continue;
783  }
784  input_offset = 2;
785  // 3 bytes of UTF-8 turn into 1 UTF-16 code unit.
786  output_adjust = 2;
787  } else {
788  if ((c & 0x1e) == 0) {
789  // This 2 byte sequence could have been coded as a 1 byte sequence.
790  // Record a single kBadChar for the first byte and continue.
791  continue;
792  }
793  input_offset = 1;
794  // 2 bytes of UTF-8 turn into 1 UTF-16 code unit.
795  output_adjust = 1;
796  }
797  bool bad = false;
798  for (int j = 1; j <= input_offset; j++) {
799  if ((s[i + j] & 0xc0) != 0x80) {
800  // Bad UTF-8 sequence turns the first in the sequence into kBadChar,
801  // which is a single UTF-16 code unit.
802  bad = true;
803  break;
804  }
805  }
806  if (!bad) {
807  i += input_offset;
808  character_length -= output_adjust;
809  }
810  }
811  }
812  return character_length;
813 }
814 
815 
816 TEST(ScopePositions) {
817  // Test the parser for correctly setting the start and end positions
818  // of a scope. We check the scope positions of exactly one scope
819  // nested in the global scope of a program. 'inner source' is the
820  // source code that determines the part of the source belonging
821  // to the nested scope. 'outer_prefix' and 'outer_suffix' are
822  // parts of the source that belong to the global scope.
823  struct SourceData {
824  const char* outer_prefix;
825  const char* inner_source;
826  const char* outer_suffix;
827  i::ScopeType scope_type;
828  i::LanguageMode language_mode;
829  };
830 
831  const SourceData source_data[] = {
832  { " with ({}) ", "{ block; }", " more;", i::WITH_SCOPE, i::CLASSIC_MODE },
833  { " with ({}) ", "{ block; }", "; more;", i::WITH_SCOPE, i::CLASSIC_MODE },
834  { " with ({}) ", "{\n"
835  " block;\n"
836  " }", "\n"
837  " more;", i::WITH_SCOPE, i::CLASSIC_MODE },
838  { " with ({}) ", "statement;", " more;", i::WITH_SCOPE, i::CLASSIC_MODE },
839  { " with ({}) ", "statement", "\n"
840  " more;", i::WITH_SCOPE, i::CLASSIC_MODE },
841  { " with ({})\n"
842  " ", "statement;", "\n"
843  " more;", i::WITH_SCOPE, i::CLASSIC_MODE },
844  { " try {} catch ", "(e) { block; }", " more;",
846  { " try {} catch ", "(e) { block; }", "; more;",
848  { " try {} catch ", "(e) {\n"
849  " block;\n"
850  " }", "\n"
851  " more;", i::CATCH_SCOPE, i::CLASSIC_MODE },
852  { " try {} catch ", "(e) { block; }", " finally { block; } more;",
854  { " start;\n"
855  " ", "{ let block; }", " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
856  { " start;\n"
857  " ", "{ let block; }", "; more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
858  { " start;\n"
859  " ", "{\n"
860  " let block;\n"
861  " }", "\n"
862  " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
863  { " start;\n"
864  " function fun", "(a,b) { infunction; }", " more;",
866  { " start;\n"
867  " function fun", "(a,b) {\n"
868  " infunction;\n"
869  " }", "\n"
870  " more;", i::FUNCTION_SCOPE, i::CLASSIC_MODE },
871  { " (function fun", "(a,b) { infunction; }", ")();",
873  { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;",
875  { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;",
877  { " for ", "(let x = 1 ; x < 10; ++ x) {\n"
878  " block;\n"
879  " }", "\n"
880  " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
881  { " for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;",
883  { " for ", "(let x = 1 ; x < 10; ++ x) statement", "\n"
884  " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
885  { " for ", "(let x = 1 ; x < 10; ++ x)\n"
886  " statement;", "\n"
887  " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
888  { " for ", "(let x in {}) { block; }", " more;",
890  { " for ", "(let x in {}) { block; }", "; more;",
892  { " for ", "(let x in {}) {\n"
893  " block;\n"
894  " }", "\n"
895  " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
896  { " for ", "(let x in {}) statement;", " more;",
898  { " for ", "(let x in {}) statement", "\n"
899  " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
900  { " for ", "(let x in {})\n"
901  " statement;", "\n"
902  " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
903  // Check that 6-byte and 4-byte encodings of UTF-8 strings do not throw
904  // the preparser off in terms of byte offsets.
905  // 6 byte encoding.
906  { " 'foo\355\240\201\355\260\211';\n"
907  " (function fun", "(a,b) { infunction; }", ")();",
909  // 4 byte encoding.
910  { " 'foo\360\220\220\212';\n"
911  " (function fun", "(a,b) { infunction; }", ")();",
913  // 3 byte encoding of \u0fff.
914  { " 'foo\340\277\277';\n"
915  " (function fun", "(a,b) { infunction; }", ")();",
917  // Broken 6 byte encoding with missing last byte.
918  { " 'foo\355\240\201\355\211';\n"
919  " (function fun", "(a,b) { infunction; }", ")();",
921  // Broken 3 byte encoding of \u0fff with missing last byte.
922  { " 'foo\340\277';\n"
923  " (function fun", "(a,b) { infunction; }", ")();",
925  // Broken 3 byte encoding of \u0fff with missing 2 last bytes.
926  { " 'foo\340';\n"
927  " (function fun", "(a,b) { infunction; }", ")();",
929  // Broken 3 byte encoding of \u00ff should be a 2 byte encoding.
930  { " 'foo\340\203\277';\n"
931  " (function fun", "(a,b) { infunction; }", ")();",
933  // Broken 3 byte encoding of \u007f should be a 2 byte encoding.
934  { " 'foo\340\201\277';\n"
935  " (function fun", "(a,b) { infunction; }", ")();",
937  // Unpaired lead surrogate.
938  { " 'foo\355\240\201';\n"
939  " (function fun", "(a,b) { infunction; }", ")();",
941  // Unpaired lead surrogate where following code point is a 3 byte sequence.
942  { " 'foo\355\240\201\340\277\277';\n"
943  " (function fun", "(a,b) { infunction; }", ")();",
945  // Unpaired lead surrogate where following code point is a 4 byte encoding
946  // of a trail surrogate.
947  { " 'foo\355\240\201\360\215\260\211';\n"
948  " (function fun", "(a,b) { infunction; }", ")();",
950  // Unpaired trail surrogate.
951  { " 'foo\355\260\211';\n"
952  " (function fun", "(a,b) { infunction; }", ")();",
954  // 2 byte encoding of \u00ff.
955  { " 'foo\303\277';\n"
956  " (function fun", "(a,b) { infunction; }", ")();",
958  // Broken 2 byte encoding of \u00ff with missing last byte.
959  { " 'foo\303';\n"
960  " (function fun", "(a,b) { infunction; }", ")();",
962  // Broken 2 byte encoding of \u007f should be a 1 byte encoding.
963  { " 'foo\301\277';\n"
964  " (function fun", "(a,b) { infunction; }", ")();",
966  // Illegal 5 byte encoding.
967  { " 'foo\370\277\277\277\277';\n"
968  " (function fun", "(a,b) { infunction; }", ")();",
970  // Illegal 6 byte encoding.
971  { " 'foo\374\277\277\277\277\277';\n"
972  " (function fun", "(a,b) { infunction; }", ")();",
974  // Illegal 0xfe byte
975  { " 'foo\376\277\277\277\277\277\277';\n"
976  " (function fun", "(a,b) { infunction; }", ")();",
978  // Illegal 0xff byte
979  { " 'foo\377\277\277\277\277\277\277\277';\n"
980  " (function fun", "(a,b) { infunction; }", ")();",
982  { " 'foo';\n"
983  " (function fun", "(a,b) { 'bar\355\240\201\355\260\213'; }", ")();",
985  { " 'foo';\n"
986  " (function fun", "(a,b) { 'bar\360\220\220\214'; }", ")();",
989  };
990 
991  v8::HandleScope handles;
993  v8::Context::Scope context_scope(context);
994 
995  int marker;
996  i::Isolate::Current()->stack_guard()->SetStackLimit(
997  reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
998  i::FLAG_harmony_scoping = true;
999 
1000  for (int i = 0; source_data[i].outer_prefix; i++) {
1001  int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix);
1002  int kInnerLen = Utf8LengthHelper(source_data[i].inner_source);
1003  int kSuffixLen = Utf8LengthHelper(source_data[i].outer_suffix);
1004  int kPrefixByteLen = i::StrLength(source_data[i].outer_prefix);
1005  int kInnerByteLen = i::StrLength(source_data[i].inner_source);
1006  int kSuffixByteLen = i::StrLength(source_data[i].outer_suffix);
1007  int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen;
1008  int kProgramByteSize = kPrefixByteLen + kInnerByteLen + kSuffixByteLen;
1009  i::Vector<char> program = i::Vector<char>::New(kProgramByteSize + 1);
1010  i::OS::SNPrintF(program, "%s%s%s",
1011  source_data[i].outer_prefix,
1012  source_data[i].inner_source,
1013  source_data[i].outer_suffix);
1014 
1015  // Parse program source.
1016  i::Handle<i::String> source(
1017  FACTORY->NewStringFromUtf8(i::CStrVector(program.start())));
1018  CHECK_EQ(source->length(), kProgramSize);
1019  i::Handle<i::Script> script = FACTORY->NewScript(source);
1020  i::CompilationInfoWithZone info(script);
1021  i::Parser parser(&info, i::kAllowLazy | i::EXTENDED_MODE, NULL, NULL);
1022  info.MarkAsGlobal();
1023  info.SetLanguageMode(source_data[i].language_mode);
1024  i::FunctionLiteral* function = parser.ParseProgram();
1025  CHECK(function != NULL);
1026 
1027  // Check scope types and positions.
1028  i::Scope* scope = function->scope();
1029  CHECK(scope->is_global_scope());
1030  CHECK_EQ(scope->start_position(), 0);
1031  CHECK_EQ(scope->end_position(), kProgramSize);
1032  CHECK_EQ(scope->inner_scopes()->length(), 1);
1033 
1034  i::Scope* inner_scope = scope->inner_scopes()->at(0);
1035  CHECK_EQ(inner_scope->type(), source_data[i].scope_type);
1036  CHECK_EQ(inner_scope->start_position(), kPrefixLen);
1037  // The end position of a token is one position after the last
1038  // character belonging to that token.
1039  CHECK_EQ(inner_scope->end_position(), kPrefixLen + kInnerLen);
1040  }
1041 }
1042 
1043 
1045  uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
1046  bool harmony_scoping = ((i::kLanguageModeMask & flags) == i::EXTENDED_MODE);
1047 
1048  // Preparse the data.
1050  i::Scanner scanner(i::Isolate::Current()->unicode_cache());
1051  i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
1052  scanner.SetHarmonyScoping(harmony_scoping);
1053  scanner.Initialize(&stream);
1056  &scanner, &log, flags, stack_limit);
1058  i::ScriptDataImpl data(log.ExtractData());
1059 
1060  // Parse the data
1061  i::Handle<i::Script> script = FACTORY->NewScript(source);
1062  bool save_harmony_scoping = i::FLAG_harmony_scoping;
1063  i::FLAG_harmony_scoping = harmony_scoping;
1064  i::CompilationInfoWithZone info(script);
1065  i::Parser parser(&info, flags, NULL, NULL);
1066  info.MarkAsGlobal();
1067  i::FunctionLiteral* function = parser.ParseProgram();
1068  i::FLAG_harmony_scoping = save_harmony_scoping;
1069 
1070  i::String* type_string = NULL;
1071  if (function == NULL) {
1072  // Extract exception from the parser.
1073  i::Handle<i::String> type_symbol = FACTORY->LookupAsciiSymbol("type");
1074  CHECK(i::Isolate::Current()->has_pending_exception());
1075  i::MaybeObject* maybe_object = i::Isolate::Current()->pending_exception();
1076  i::JSObject* exception = NULL;
1077  CHECK(maybe_object->To(&exception));
1078 
1079  // Get the type string.
1080  maybe_object = exception->GetProperty(*type_symbol);
1081  CHECK(maybe_object->To(&type_string));
1082  }
1083 
1084  // Check that preparsing fails iff parsing fails.
1085  if (data.has_error() && function != NULL) {
1086  i::OS::Print(
1087  "Preparser failed on:\n"
1088  "\t%s\n"
1089  "with error:\n"
1090  "\t%s\n"
1091  "However, the parser succeeded",
1092  *source->ToCString(), data.BuildMessage());
1093  CHECK(false);
1094  } else if (!data.has_error() && function == NULL) {
1095  i::OS::Print(
1096  "Parser failed on:\n"
1097  "\t%s\n"
1098  "with error:\n"
1099  "\t%s\n"
1100  "However, the preparser succeeded",
1101  *source->ToCString(), *type_string->ToCString());
1102  CHECK(false);
1103  }
1104 
1105  // Check that preparser and parser produce the same error.
1106  if (function == NULL) {
1107  if (!type_string->IsEqualTo(i::CStrVector(data.BuildMessage()))) {
1108  i::OS::Print(
1109  "Expected parser and preparser to produce the same error on:\n"
1110  "\t%s\n"
1111  "However, found the following error messages\n"
1112  "\tparser: %s\n"
1113  "\tpreparser: %s\n",
1114  *source->ToCString(), *type_string->ToCString(), data.BuildMessage());
1115  CHECK(false);
1116  }
1117  }
1118 }
1119 
1120 
1122  static const int kFlagsCount = 6;
1123  const int flags[kFlagsCount] = {
1130  };
1131 
1132  for (int k = 0; k < kFlagsCount; ++k) {
1133  TestParserSync(source, flags[k]);
1134  }
1135 }
1136 
1137 
1138 TEST(ParserSync) {
1139  const char* context_data[][2] = {
1140  { "", "" },
1141  { "{", "}" },
1142  { "if (true) ", " else {}" },
1143  { "if (true) {} else ", "" },
1144  { "if (true) ", "" },
1145  { "do ", " while (false)" },
1146  { "while (false) ", "" },
1147  { "for (;;) ", "" },
1148  { "with ({})", "" },
1149  { "switch (12) { case 12: ", "}" },
1150  { "switch (12) { default: ", "}" },
1151  { "switch (12) { ", "case 12: }" },
1152  { "label2: ", "" },
1153  { NULL, NULL }
1154  };
1155 
1156  const char* statement_data[] = {
1157  "{}",
1158  "var x",
1159  "var x = 1",
1160  "const x",
1161  "const x = 1",
1162  ";",
1163  "12",
1164  "if (false) {} else ;",
1165  "if (false) {} else {}",
1166  "if (false) {} else 12",
1167  "if (false) ;"
1168  "if (false) {}",
1169  "if (false) 12",
1170  "do {} while (false)",
1171  "for (;;) ;",
1172  "for (;;) {}",
1173  "for (;;) 12",
1174  "continue",
1175  "continue label",
1176  "continue\nlabel",
1177  "break",
1178  "break label",
1179  "break\nlabel",
1180  "return",
1181  "return 12",
1182  "return\n12",
1183  "with ({}) ;",
1184  "with ({}) {}",
1185  "with ({}) 12",
1186  "switch ({}) { default: }"
1187  "label3: "
1188  "throw",
1189  "throw 12",
1190  "throw\n12",
1191  "try {} catch(e) {}",
1192  "try {} finally {}",
1193  "try {} catch(e) {} finally {}",
1194  "debugger",
1195  NULL
1196  };
1197 
1198  const char* termination_data[] = {
1199  "",
1200  ";",
1201  "\n",
1202  ";\n",
1203  "\n;",
1204  NULL
1205  };
1206 
1207  v8::HandleScope handles;
1209  v8::Context::Scope context_scope(context);
1210 
1211  int marker;
1212  i::Isolate::Current()->stack_guard()->SetStackLimit(
1213  reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1214 
1215  for (int i = 0; context_data[i][0] != NULL; ++i) {
1216  for (int j = 0; statement_data[j] != NULL; ++j) {
1217  for (int k = 0; termination_data[k] != NULL; ++k) {
1218  int kPrefixLen = i::StrLength(context_data[i][0]);
1219  int kStatementLen = i::StrLength(statement_data[j]);
1220  int kTerminationLen = i::StrLength(termination_data[k]);
1221  int kSuffixLen = i::StrLength(context_data[i][1]);
1222  int kProgramSize = kPrefixLen + kStatementLen + kTerminationLen
1223  + kSuffixLen + i::StrLength("label: for (;;) { }");
1224 
1225  // Plug the source code pieces together.
1226  i::Vector<char> program = i::Vector<char>::New(kProgramSize + 1);
1227  int length = i::OS::SNPrintF(program,
1228  "label: for (;;) { %s%s%s%s }",
1229  context_data[i][0],
1230  statement_data[j],
1231  termination_data[k],
1232  context_data[i][1]);
1233  CHECK(length == kProgramSize);
1234  i::Handle<i::String> source =
1235  FACTORY->NewStringFromAscii(i::CStrVector(program.start()));
1236  TestParserSyncWithFlags(source);
1237  }
1238  }
1239  }
1240 }
1241 
1242 
1243 TEST(PreparserStrictOctal) {
1244  // Test that syntax error caused by octal literal is reported correctly as
1245  // such (issue 2220).
1246  v8::internal::FLAG_min_preparse_length = 1; // Force preparsing.
1248  v8::HandleScope scope;
1249  v8::Context::Scope context_scope(v8::Context::New());
1250  v8::TryCatch try_catch;
1251  const char* script =
1252  "\"use strict\"; \n"
1253  "a = function() { \n"
1254  " b = function() { \n"
1255  " 01; \n"
1256  " }; \n"
1257  "}; \n";
1259  CHECK(try_catch.HasCaught());
1260  v8::String::Utf8Value exception(try_catch.Exception());
1261  CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.",
1262  *exception);
1263 }
bool is_global_scope() const
Definition: scopes.h:278
static Local< Script > Compile(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *pre_data=NULL, Handle< String > script_data=Handle< String >())
Definition: api.cc:1568
static ScriptDataImpl * PreParse(Utf16CharacterStream *source, v8::Extension *extension, int flags)
Definition: parser.cc:5909
const char * data() const
#define CHECK_EQ(expected, value)
Definition: checks.h:219
TestExternalResource(uint16_t *data, int length)
Local< Value > Exception() const
Definition: api.cc:1720
#define CHECK_GT(a, b)
Definition: checks.h:227
bool HasCaught() const
Definition: api.cc:1703
static const unsigned kMaxTwoByteChar
Definition: unicode.h:165
static V8EXPORT Local< String > New(const char *data, int length=-1)
Definition: api.cc:4779
void SetHarmonyScoping(bool scoping)
Definition: scanner.h:410
#define IGNORE_TOKEN(name, string, precedence)
Definition: token.h:49
int int32_t
Definition: unicode.cc:47
#define CHECK_LT(a, b)
Definition: checks.h:229
TEST(ScanKeywords)
Definition: test-parsing.cc:44
#define ASSERT(condition)
Definition: checks.h:270
unsigned short uint16_t
Definition: unicode.cc:46
#define CHECK(condition)
Definition: checks.h:56
void SetHarmonyModules(bool modules)
Definition: scanner.h:416
void SetLanguageMode(LanguageMode language_mode)
Definition: compiler.h:86
#define TOKEN_LIST(T, K)
Definition: token.h:51
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage including flags
void TestStreamScanner(i::Utf16CharacterStream *stream, i::Token::Value *expected_tokens, int skip_pos=0, int skip_to=0)
size_t length() const
FunctionLiteral * ParseProgram()
Definition: parser.cc:568
void TestParserSyncWithFlags(i::Handle< i::String > source)
#define KEYWORD(t, s, d)
uint8_t byte
Definition: globals.h:156
SmartArrayPointer< char > ToCString(AllowNullsFlag allow_nulls, RobustnessFlag robustness_flag, int offset, int length, int *length_output=0)
Definition: objects.cc:6233
static Local< Script > New(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *pre_data=NULL, Handle< String > script_data=Handle< String >())
Definition: api.cc:1506
int start_position() const
Definition: scopes.h:262
static ScriptData * PreCompile(const char *input, int length)
Definition: api.cc:1462
T * start() const
Definition: utils.h:390
virtual bool HasError()=0
#define CHECK_EQU(v1, v2)
int Utf8LengthHelper(String *input, int from, int to, bool followed_by_surrogate, int max_recursion, bool *failure, bool *starts_with_surrogate)
Definition: handles.cc:888
static const char * String(Value tok)
Definition: token.h:275
ZoneList< Scope * > * inner_scopes()
Definition: scopes.h:345
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage message
void SeekForward(int pos)
Definition: scanner.cc:593
bool is_literal_ascii()
Definition: scanner.h:345
int end_position() const
Definition: scopes.h:266
static Vector< T > New(int length)
Definition: utils.h:370
#define CHECK_NE(unexpected, value)
Definition: checks.h:223
void Initialize(Utf16CharacterStream *source)
Definition: scanner.cc:48
Vector< const char > CStrVector(const char *data)
Definition: utils.h:526
static unsigned Encode(char *out, uchar c, int previous)
Definition: unicode-inl.h:82
int StrLength(const char *string)
Definition: utils.h:234
static void Print(const char *format,...)
virtual Vector< unsigned > ExtractData()
static int SNPrintF(Vector< char > str, const char *format,...)
Location location() const
Definition: scanner.h:330
void TestCharacterStream(const char *ascii_source, unsigned length, unsigned start=0, unsigned end=0)
uint16_t uc16
Definition: globals.h:259
Scanner::Location MessageLocation()
Definition: parser.cc:371
size_t length() const
MUST_USE_RESULT MaybeObject * GetProperty(String *key)
Definition: objects-inl.h:859
#define ASSERT_EQ(v1, v2)
Definition: checks.h:271
static PreParseResult PreParseProgram(i::Scanner *scanner, i::ParserRecorder *log, int flags, uintptr_t stack_limit)
Definition: preparser.h:140
Vector< const char > literal_ascii_string()
Definition: scanner.h:337
static const unsigned kMaxThreeByteChar
Definition: unicode.h:166
void TestScanRegExp(const char *re_source, const char *expected)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
static const unsigned kMaxOneByteChar
Definition: unicode.h:164
const uint16_t * data() const
Token::Value peek() const
Definition: scanner.h:367
ScriptResource(const char *data, size_t length)
#define FACTORY
Definition: isolate.h:1434
static Persistent< Context > New(ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
Definition: api.cc:4411
Token::Value Next()
Definition: scanner.cc:224
bool IsEqualTo(Vector< const char > str)
Definition: objects.cc:7163
void TestParserSync(i::Handle< i::String > source, int flags)
static V8EXPORT Local< String > NewExternal(ExternalStringResource *resource)
Definition: api.cc:4871
unsigned SeekForward(unsigned code_unit_count)
Definition: scanner.h:110
bool ScanRegExpPattern(bool seen_equal)
Definition: scanner.cc:993
#define ARRAY_SIZE(a)
Definition: globals.h:281
Definition: v8.h:106
virtual bool HasError()
Definition: parser.cc:5833
static bool Initialize()
Definition: api.cc:4269
static const int kNoPreviousCharacter
Definition: unicode.h:132