50 static const KeywordToken keywords[] = {
51 #define KEYWORD(t, s, d) { s, i::Token::t },
54 {
NULL, i::Token::IDENTIFIER }
57 KeywordToken key_token;
60 for (
int i = 0; (key_token = keywords[i]).keyword !=
NULL; i++) {
62 reinterpret_cast<const i::byte*
>(key_token.keyword);
64 CHECK(static_cast<int>(
sizeof(buffer)) >= length);
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];
96 memmove(buffer, keyword, length);
97 buffer[length - 1] =
'_';
118 const char* tests[] = {
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",
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",
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",
142 i::Isolate::Current()->stack_guard()->SetStackLimit(
143 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
145 for (
int i = 0; tests[i]; i++) {
152 for (
int i = 0; fail_tests[i]; i++) {
164 : data_(data), length_(length) { }
166 const char*
data()
const {
return data_; }
167 size_t length()
const {
return length_; }
180 i::Isolate::Current()->stack_guard()->SetStackLimit(
181 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
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; }};";
197 const char* error_source =
"var x = y z;";
203 bool lazy_flag = i::FLAG_lazy;
212 i::FLAG_lazy =
false;
219 i::FLAG_lazy = lazy_flag;
227 i::Scanner::Location error_location =
230 CHECK_EQ(10, error_location.beg_pos);
231 CHECK_EQ(11, error_location.end_pos);
233 const char* message = pre_impl->BuildMessage();
234 pre_impl->BuildArgs();
243 i::Isolate::Current()->stack_guard()->SetStackLimit(
244 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
246 const char* programs[] = {
249 "function foo(x, y) { return x + y; }",
250 "%ArgleBargle(glop);",
251 "var x = new new Function('this.x = 42');",
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());
273 CHECK(!data.has_error());
278 TEST(StandAlonePreParserNoNatives) {
282 i::Isolate::Current()->stack_guard()->SetStackLimit(
283 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
285 const char* programs[] = {
286 "%ArgleBargle(glop);",
287 "var x = %_IsSmi(42);",
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());
310 CHECK(data.has_error());
319 i::Isolate::Current()->stack_guard()->SetStackLimit(
320 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
322 const char* program =
"var x = 'something';\n"
323 "escape: function() {}";
330 reinterpret_cast<const i::byte*>(program),
331 static_cast<unsigned>(strlen(program)));
347 i::Isolate::Current()->stack_guard()->SetStackLimit(
348 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
350 const char* program =
351 "try { } catch (e) { var foo = function () { /* first */ } }"
352 "var bar = function () { /* second */ }";
358 CHECK(!data->HasError());
363 static_cast<int>(strstr(program,
"function") - program);
364 int first_lbrace = first_function +
i::StrLength(
"function () ");
365 CHECK_EQ(
'{', program[first_lbrace]);
366 i::FunctionEntry entry1 = data->GetFunctionEntry(first_lbrace);
367 CHECK(!entry1.is_valid());
369 int second_function =
370 static_cast<int>(strstr(program + first_lbrace,
"function") - program);
373 CHECK_EQ(
'{', program[second_lbrace]);
374 i::FunctionEntry entry2 = data->GetFunctionEntry(second_lbrace);
375 CHECK(entry2.is_valid());
376 CHECK_EQ(
'}', program[entry2.end_pos() - 1]);
385 i::Isolate::Current()->stack_guard()->SetStackLimit(
386 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
388 size_t kProgramSize = 1024 * 1024;
390 reinterpret_cast<char*>(malloc(kProgramSize + 1)));
391 memset(*program,
'(', kProgramSize);
392 program[kProgramSize] =
'\0';
394 uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
397 reinterpret_cast<const i::byte*>(*program),
398 static_cast<unsigned>(kProgramSize));
400 i::Scanner scanner(i::Isolate::Current()->unicode_cache());
416 : data_(data), length_(static_cast<size_t>(length)) { }
433 #define CHECK_EQU(v1, v2) CHECK_EQ(static_cast<int>(v1), static_cast<int>(v2))
439 if (end == 0) end = length;
440 unsigned sub_length = end - start;
443 for (
unsigned i = 0; i < length; i++) {
444 uc16_buffer[i] =
static_cast<i::uc16>(ascii_source[i]);
448 FACTORY->NewStringFromAscii(ascii_vector));
451 FACTORY->NewExternalStringFromTwoByte(&resource));
457 reinterpret_cast<const i::byte*>(ascii_source), end);
467 int32_t c1 = uc16_stream.Advance();
478 while (i > start + sub_length / 4) {
480 int32_t c0 = ascii_source[i - 1];
484 uc16_stream.PushBack(c0);
491 int32_t c1 = uc16_stream.Advance();
501 uc16_stream.PushBack(c0);
509 unsigned halfway = start + sub_length / 2;
510 uc16_stream.SeekForward(halfway - i);
524 int32_t c1 = uc16_stream.Advance();
536 int32_t c1 = uc16_stream.Advance();
551 static const unsigned kBigStringSize = 4096;
552 char buffer[kBigStringSize + 1];
553 for (
unsigned i = 0; i < kBigStringSize; i++) {
554 buffer[i] =
static_cast<char>(i & 0x7f);
567 static const int kMaxUC16Char =
static_cast<int>(kMaxUC16CharU);
569 static const int kAllUtf8CharsSize =
573 static const unsigned kAllUtf8CharsSizeU =
574 static_cast<unsigned>(kAllUtf8CharsSize);
576 char buffer[kAllUtf8CharsSizeU];
578 for (
int i = 0; i <= kMaxUC16Char; i++) {
583 ASSERT(cursor == kAllUtf8CharsSizeU);
587 for (
int i = 0; i <= kMaxUC16Char; i++) {
593 for (
int i = kMaxUC16Char; i >= 0; i--) {
599 while (stream.
pos() < kMaxUC16CharU) {
604 if (i <= kMaxUC16Char) {
620 i::Scanner scanner(i::Isolate::Current()->unicode_cache());
632 }
while (expected_tokens[i] != i::Token::ILLEGAL);
638 const char* str1 =
"{ foo get for : */ <- \n\n /*foo*/ bib";
640 static_cast<unsigned>(strlen(str1)));
643 i::Token::IDENTIFIER,
644 i::Token::IDENTIFIER,
651 i::Token::IDENTIFIER,
657 const char* str2 =
"case default const {THIS\nPART\nSKIPPED} do";
659 static_cast<unsigned>(strlen(str2)));
675 const char* str3 =
"{}}}}";
686 for (
int i = 0; i <= 4; i++) {
687 expectations3[6 - i] = i::Token::ILLEGAL;
688 expectations3[5 - i] = i::Token::EOS;
690 reinterpret_cast<const i::byte*>(str3),
691 static_cast<unsigned>(strlen(str3)));
699 reinterpret_cast<const i::byte*>(re_source),
700 static_cast<unsigned>(strlen(re_source)));
701 i::Scanner scanner(i::Isolate::Current()->unicode_cache());
710 for (
int i = 0; i < actual.length(); i++) {
756 int character_length = len;
757 for (
int i = 0; i < len; i++) {
758 unsigned char c = s[i];
759 int input_offset = 0;
760 int output_adjust = 0;
762 if (c < 0xc0)
continue;
769 if ((c & 7) == 0 && ((s[i + 1] & 0x30) == 0)) {
776 character_length -= 2;
777 }
else if (c >= 0xe0) {
778 if ((c & 0xf) == 0 && ((s[i + 1] & 0x20) == 0)) {
787 if ((c & 0x1e) == 0) {
797 for (
int j = 1; j <= input_offset; j++) {
798 if ((s[i + j] & 0xc0) != 0x80) {
807 character_length -= output_adjust;
811 return character_length;
823 const char* outer_prefix;
824 const char* inner_source;
825 const char* outer_suffix;
830 const SourceData source_data[] = {
833 {
" with ({}) ",
"{\n"
838 {
" with ({}) ",
"statement",
"\n"
841 " ",
"statement;",
"\n"
843 {
" try {} catch ",
"(e) { block; }",
" more;",
845 {
" try {} catch ",
"(e) { block; }",
"; more;",
847 {
" try {} catch ",
"(e) {\n"
851 {
" try {} catch ",
"(e) { block; }",
" finally { block; } more;",
863 " function fun",
"(a,b) { infunction; }",
" more;",
866 " function fun",
"(a,b) {\n"
870 {
" (function fun",
"(a,b) { infunction; }",
")();",
872 {
" for ",
"(let x = 1 ; x < 10; ++ x) { block; }",
" more;",
874 {
" for ",
"(let x = 1 ; x < 10; ++ x) { block; }",
"; more;",
876 {
" for ",
"(let x = 1 ; x < 10; ++ x) {\n"
880 {
" for ",
"(let x = 1 ; x < 10; ++ x) statement;",
" more;",
882 {
" for ",
"(let x = 1 ; x < 10; ++ x) statement",
"\n"
884 {
" for ",
"(let x = 1 ; x < 10; ++ x)\n"
887 {
" for ",
"(let x in {}) { block; }",
" more;",
889 {
" for ",
"(let x in {}) { block; }",
"; more;",
891 {
" for ",
"(let x in {}) {\n"
895 {
" for ",
"(let x in {}) statement;",
" more;",
897 {
" for ",
"(let x in {}) statement",
"\n"
899 {
" for ",
"(let x in {})\n"
905 {
" 'foo\355\240\201\355\260\211';\n"
906 " (function fun",
"(a,b) { infunction; }",
")();",
909 {
" 'foo\360\220\220\212';\n"
910 " (function fun",
"(a,b) { infunction; }",
")();",
913 {
" 'foo\340\277\277';\n"
914 " (function fun",
"(a,b) { infunction; }",
")();",
917 {
" 'foo\355\240\201\355\211';\n"
918 " (function fun",
"(a,b) { infunction; }",
")();",
921 {
" 'foo\340\277';\n"
922 " (function fun",
"(a,b) { infunction; }",
")();",
926 " (function fun",
"(a,b) { infunction; }",
")();",
929 {
" 'foo\340\203\277';\n"
930 " (function fun",
"(a,b) { infunction; }",
")();",
933 {
" 'foo\340\201\277';\n"
934 " (function fun",
"(a,b) { infunction; }",
")();",
937 {
" 'foo\355\240\201';\n"
938 " (function fun",
"(a,b) { infunction; }",
")();",
941 {
" 'foo\355\240\201\340\277\277';\n"
942 " (function fun",
"(a,b) { infunction; }",
")();",
946 {
" 'foo\355\240\201\360\215\260\211';\n"
947 " (function fun",
"(a,b) { infunction; }",
")();",
950 {
" 'foo\355\260\211';\n"
951 " (function fun",
"(a,b) { infunction; }",
")();",
954 {
" 'foo\303\277';\n"
955 " (function fun",
"(a,b) { infunction; }",
")();",
959 " (function fun",
"(a,b) { infunction; }",
")();",
962 {
" 'foo\301\277';\n"
963 " (function fun",
"(a,b) { infunction; }",
")();",
966 {
" 'foo\370\277\277\277\277';\n"
967 " (function fun",
"(a,b) { infunction; }",
")();",
970 {
" 'foo\374\277\277\277\277\277';\n"
971 " (function fun",
"(a,b) { infunction; }",
")();",
974 {
" 'foo\376\277\277\277\277\277\277';\n"
975 " (function fun",
"(a,b) { infunction; }",
")();",
978 {
" 'foo\377\277\277\277\277\277\277\277';\n"
979 " (function fun",
"(a,b) { infunction; }",
")();",
982 " (function fun",
"(a,b) { 'bar\355\240\201\355\260\213'; }",
")();",
985 " (function fun",
"(a,b) { 'bar\360\220\220\214'; }",
")();",
995 i::Isolate::Current()->stack_guard()->SetStackLimit(
996 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
997 i::FLAG_harmony_scoping =
true;
999 for (
int i = 0; source_data[i].outer_prefix; i++) {
1000 int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix);
1001 int kInnerLen = Utf8LengthHelper(source_data[i].inner_source);
1002 int kSuffixLen = Utf8LengthHelper(source_data[i].outer_suffix);
1003 int kPrefixByteLen =
i::StrLength(source_data[i].outer_prefix);
1004 int kInnerByteLen =
i::StrLength(source_data[i].inner_source);
1005 int kSuffixByteLen =
i::StrLength(source_data[i].outer_suffix);
1006 int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen;
1007 int kProgramByteSize = kPrefixByteLen + kInnerByteLen + kSuffixByteLen;
1010 source_data[i].outer_prefix,
1011 source_data[i].inner_source,
1012 source_data[i].outer_suffix);
1017 CHECK_EQ(source->length(), kProgramSize);
1020 i::Isolate::Current()->zone());
1021 i::CompilationInfo info(script);
1022 info.MarkAsGlobal();
1023 info.SetLanguageMode(source_data[i].language_mode);
1028 i::Scope* scope =
function->scope();
1035 CHECK_EQ(inner_scope->type(), source_data[i].scope_type);
1036 CHECK_EQ(inner_scope->start_position(), kPrefixLen);
1039 CHECK_EQ(inner_scope->end_position(), kPrefixLen + kInnerLen);
1045 uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
1050 i::Scanner scanner(i::Isolate::Current()->unicode_cache());
1056 &scanner, &log, flags, stack_limit);
1062 bool save_harmony_scoping = i::FLAG_harmony_scoping;
1063 i::FLAG_harmony_scoping = harmony_scoping;
1065 i::CompilationInfo info(script);
1066 info.MarkAsGlobal();
1068 i::FLAG_harmony_scoping = save_harmony_scoping;
1071 if (
function ==
NULL) {
1074 CHECK(i::Isolate::Current()->has_pending_exception());
1075 i::MaybeObject* maybe_object = i::Isolate::Current()->pending_exception();
1077 CHECK(maybe_object->To(&exception));
1080 maybe_object = exception->
GetProperty(*type_symbol);
1081 CHECK(maybe_object->To(&type_string));
1085 if (data.has_error() &&
function !=
NULL) {
1087 "Preparser failed on:\n"
1091 "However, the parser succeeded",
1092 *source->ToCString(), data.BuildMessage());
1094 }
else if (!data.has_error() &&
function ==
NULL) {
1096 "Parser failed on:\n"
1100 "However, the preparser succeeded",
1101 *source->ToCString(), *type_string->
ToCString());
1106 if (
function ==
NULL) {
1109 "Expected parser and preparser to produce the same error on:\n"
1111 "However, found the following error messages\n"
1113 "\tpreparser: %s\n",
1114 *source->ToCString(), *type_string->
ToCString(), data.BuildMessage());
1122 static const int kFlagsCount = 6;
1123 const int flags[kFlagsCount] = {
1132 for (
int k = 0; k < kFlagsCount; ++k) {
1139 const char* context_data[][2] = {
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: ",
"}" },
1155 const char* statement_data[] = {
1163 "if (false) {} else ;",
1164 "if (false) {} else {}",
1165 "if (false) {} else 12",
1169 "do {} while (false)",
1185 "switch ({}) { default: }"
1190 "try {} catch(e) {}",
1191 "try {} finally {}",
1192 "try {} catch(e) {} finally {}",
1197 const char* termination_data[] = {
1211 i::Isolate::Current()->stack_guard()->SetStackLimit(
1212 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1214 for (
int i = 0; context_data[i][0] !=
NULL; ++i) {
1215 for (
int j = 0; statement_data[j] !=
NULL; ++j) {
1216 for (
int k = 0; termination_data[k] !=
NULL; ++k) {
1219 int kTerminationLen =
i::StrLength(termination_data[k]);
1221 int kProgramSize = kPrefixLen + kStatementLen + kTerminationLen
1227 "label: for (;;) { %s%s%s%s }",
1230 termination_data[k],
1231 context_data[i][1]);
1232 CHECK(length == kProgramSize);
bool is_global_scope() const
static ScriptDataImpl * PartialPreParse(Handle< String > source, v8::Extension *extension, int flags)
static Local< Script > Compile(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *pre_data=NULL, Handle< String > script_data=Handle< String >())
static ScriptDataImpl * PreParse(Utf16CharacterStream *source, v8::Extension *extension, int flags)
const char * data() const
#define CHECK_EQ(expected, value)
TestExternalResource(uint16_t *data, int length)
static const unsigned kMaxTwoByteChar
void SetHarmonyScoping(bool scoping)
#define IGNORE_TOKEN(name, string, precedence)
FunctionLiteral * ParseProgram(CompilationInfo *info)
#define ASSERT(condition)
void SetHarmonyModules(bool modules)
void TestStreamScanner(i::Utf16CharacterStream *stream, i::Token::Value *expected_tokens, int skip_pos=0, int skip_to=0)
void TestParserSyncWithFlags(i::Handle< i::String > source)
SmartArrayPointer< char > ToCString(AllowNullsFlag allow_nulls, RobustnessFlag robustness_flag, int offset, int length, int *length_output=0)
static Local< Script > New(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *pre_data=NULL, Handle< String > script_data=Handle< String >())
int start_position() const
static ScriptData * PreCompile(const char *input, int length)
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)
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 trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt 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 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
static const char * String(Value tok)
ZoneList< Scope * > * inner_scopes()
void SeekForward(int pos)
static Vector< T > New(int length)
#define CHECK_NE(unexpected, value)
void Initialize(Utf16CharacterStream *source)
Vector< const char > CStrVector(const char *data)
static unsigned Encode(char *out, uchar c, int previous)
int StrLength(const char *string)
static void Print(const char *format,...)
virtual Vector< unsigned > ExtractData()
static int SNPrintF(Vector< char > str, const char *format,...)
Location location() const
void TestCharacterStream(const char *ascii_source, unsigned length, unsigned start=0, unsigned end=0)
Scanner::Location MessageLocation()
MUST_USE_RESULT MaybeObject * GetProperty(String *key)
#define ASSERT_EQ(v1, v2)
static PreParseResult PreParseProgram(i::Scanner *scanner, i::ParserRecorder *log, int flags, uintptr_t stack_limit)
Vector< const char > literal_ascii_string()
static const unsigned kMaxThreeByteChar
void TestScanRegExp(const char *re_source, const char *expected)
static const unsigned kMaxOneByteChar
const uint16_t * data() const
Token::Value peek() const
ScriptResource(const char *data, size_t length)
static Persistent< Context > New(ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
bool IsEqualTo(Vector< const char > str)
void TestParserSync(i::Handle< i::String > source, int flags)
static V8EXPORT Local< String > NewExternal(ExternalStringResource *resource)
unsigned SeekForward(unsigned code_unit_count)
bool ScanRegExpPattern(bool seen_equal)
static const int kNoPreviousCharacter
virtual void PushBack(uc32 character)