Chromium Code Reviews

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

Issue 382893003: Implement basic code generation for arrow functions (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 193 matching lines...)
204 const char* source = 204 const char* source =
205 "var x = 42;" 205 "var x = 42;"
206 "function foo(a) { return function nolazy(b) { return a + b; } }" 206 "function foo(a) { return function nolazy(b) { return a + b; } }"
207 "function bar(a) { if (a) return function lazy(b) { return b; } }" 207 "function bar(a) { if (a) return function lazy(b) { return b; } }"
208 "var z = {'string': 'string literal', bareword: 'propertyName', " 208 "var z = {'string': 'string literal', bareword: 'propertyName', "
209 " 42: 'number literal', for: 'keyword as propertyName', " 209 " 42: 'number literal', for: 'keyword as propertyName', "
210 " f\\u006fr: 'keyword propertyname with escape'};" 210 " f\\u006fr: 'keyword propertyname with escape'};"
211 "var v = /RegExp Literal/;" 211 "var v = /RegExp Literal/;"
212 "var w = /RegExp Literal\\u0020With Escape/gin;" 212 "var w = /RegExp Literal\\u0020With Escape/gin;"
213 "var y = { get getter() { return 42; }, " 213 "var y = { get getter() { return 42; }, "
214 " set setter(v) { this.value = v; }};"; 214 " set setter(v) { this.value = v; }};"
215 "var f = a => function (b) { return a + b; };"
216 "var g = a => b => a + b;";
215 int source_length = i::StrLength(source); 217 int source_length = i::StrLength(source);
216 218
217 // ScriptResource will be deleted when the corresponding String is GCd. 219 // ScriptResource will be deleted when the corresponding String is GCd.
218 v8::ScriptCompiler::Source script_source(v8::String::NewExternal( 220 v8::ScriptCompiler::Source script_source(v8::String::NewExternal(
219 isolate, new ScriptResource(source, source_length))); 221 isolate, new ScriptResource(source, source_length)));
222 i::FLAG_harmony_arrow_functions = true;
220 i::FLAG_min_preparse_length = 0; 223 i::FLAG_min_preparse_length = 0;
221 v8::ScriptCompiler::Compile(isolate, &script_source, 224 v8::ScriptCompiler::Compile(isolate, &script_source,
222 v8::ScriptCompiler::kProduceDataToCache); 225 v8::ScriptCompiler::kProduceDataToCache);
223 CHECK(script_source.GetCachedData()); 226 CHECK(script_source.GetCachedData());
224 227
225 // Compile the script again, using the cached data. 228 // Compile the script again, using the cached data.
226 bool lazy_flag = i::FLAG_lazy; 229 bool lazy_flag = i::FLAG_lazy;
227 i::FLAG_lazy = true; 230 i::FLAG_lazy = true;
228 v8::ScriptCompiler::Compile(isolate, &script_source); 231 v8::ScriptCompiler::Compile(isolate, &script_source);
229 i::FLAG_lazy = false; 232 i::FLAG_lazy = false;
230 v8::ScriptCompiler::CompileUnbound(isolate, &script_source); 233 v8::ScriptCompiler::CompileUnbound(isolate, &script_source);
231 i::FLAG_lazy = lazy_flag; 234 i::FLAG_lazy = lazy_flag;
232 } 235 }
233 236
234 237
235 TEST(PreparseFunctionDataIsUsed) { 238 TEST(PreparseFunctionDataIsUsed) {
236 // This tests that we actually do use the function data generated by the 239 // This tests that we actually do use the function data generated by the
237 // preparser. 240 // preparser.
238 241
239 // Make preparsing work for short scripts. 242 // Make preparsing work for short scripts.
240 i::FLAG_min_preparse_length = 0; 243 i::FLAG_min_preparse_length = 0;
244 i::FLAG_harmony_arrow_functions = true;
241 245
242 v8::Isolate* isolate = CcTest::isolate(); 246 v8::Isolate* isolate = CcTest::isolate();
243 v8::HandleScope handles(isolate); 247 v8::HandleScope handles(isolate);
244 v8::Local<v8::Context> context = v8::Context::New(isolate); 248 v8::Local<v8::Context> context = v8::Context::New(isolate);
245 v8::Context::Scope context_scope(context); 249 v8::Context::Scope context_scope(context);
246 CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() - 250 CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
247 128 * 1024); 251 128 * 1024);
248 252
249 const char* good_code = 253 const char* good_code[] = {
250 "function this_is_lazy() { var a; } function foo() { return 25; } foo();"; 254 "function this_is_lazy() { var a; } function foo() { return 25; } foo();",
255 "var this_is_lazy = () => { var a; }; var foo = () => 25; foo();",
256 NULL
rossberg 2014/07/14 13:55:46 Nit: Don't use NULL, use the ARRAY_SIZE macro inst
257 };
251 258
252 // Insert a syntax error inside the lazy function. 259 // Insert a syntax error inside the lazy function.
253 const char* bad_code = 260 const char* bad_code[] = {
254 "function this_is_lazy() { if ( } function foo() { return 25; } foo();"; 261 "function this_is_lazy() { if ( } function foo() { return 25; } foo();",
262 "var this_is_lazy = () => { if ( }; var foo = () => 25; foo();",
263 NULL
264 };
255 265
256 v8::ScriptCompiler::Source good_source(v8_str(good_code)); 266 for (int i = 0; good_code[i]; i++) {
257 v8::ScriptCompiler::Compile(isolate, &good_source, 267 v8::ScriptCompiler::Source good_source(v8_str(good_code[i]));
258 v8::ScriptCompiler::kProduceDataToCache); 268 v8::ScriptCompiler::Compile(isolate, &good_source,
269 v8::ScriptCompiler::kProduceDataToCache);
259 270
260 const v8::ScriptCompiler::CachedData* cached_data = 271 const v8::ScriptCompiler::CachedData* cached_data =
261 good_source.GetCachedData(); 272 good_source.GetCachedData();
262 CHECK(cached_data->data != NULL); 273 CHECK(cached_data->data != NULL);
263 CHECK_GT(cached_data->length, 0); 274 CHECK_GT(cached_data->length, 0);
264 275
265 // Now compile the erroneous code with the good preparse data. If the preparse 276 // Now compile the erroneous code with the good preparse data. If the
266 // data is used, the lazy function is skipped and it should compile fine. 277 // preparse data is used, the lazy function is skipped and it should
267 v8::ScriptCompiler::Source bad_source( 278 // compile fine.
268 v8_str(bad_code), new v8::ScriptCompiler::CachedData( 279 v8::ScriptCompiler::Source bad_source(
269 cached_data->data, cached_data->length)); 280 v8_str(bad_code[i]), new v8::ScriptCompiler::CachedData(
270 v8::Local<v8::Value> result = 281 cached_data->data, cached_data->length));
271 v8::ScriptCompiler::Compile(isolate, &bad_source)->Run(); 282 v8::Local<v8::Value> result =
272 CHECK(result->IsInt32()); 283 v8::ScriptCompiler::Compile(isolate, &bad_source)->Run();
273 CHECK_EQ(25, result->Int32Value()); 284 CHECK(result->IsInt32());
285 CHECK_EQ(25, result->Int32Value());
286 }
274 } 287 }
275 288
276 289
277 TEST(StandAlonePreParser) { 290 TEST(StandAlonePreParser) {
278 v8::V8::Initialize(); 291 v8::V8::Initialize();
279 292
280 CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() - 293 CcTest::i_isolate()->stack_guard()->SetStackLimit(GetCurrentStackPosition() -
281 128 * 1024); 294 128 * 1024);
282 295
283 const char* programs[] = { 296 const char* programs[] = {
(...skipping 188 matching lines...)
472 485
473 i::Utf8ToUtf16CharacterStream stream( 486 i::Utf8ToUtf16CharacterStream stream(
474 reinterpret_cast<const i::byte*>(program.get()), 487 reinterpret_cast<const i::byte*>(program.get()),
475 static_cast<unsigned>(kProgramSize)); 488 static_cast<unsigned>(kProgramSize));
476 i::CompleteParserRecorder log; 489 i::CompleteParserRecorder log;
477 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); 490 i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
478 scanner.Initialize(&stream); 491 scanner.Initialize(&stream);
479 492
480 i::PreParser preparser(&scanner, &log, stack_limit); 493 i::PreParser preparser(&scanner, &log, stack_limit);
481 preparser.set_allow_lazy(true); 494 preparser.set_allow_lazy(true);
495 preparser.set_allow_arrow_functions(true);
482 i::PreParser::PreParseResult result = preparser.PreParseProgram(); 496 i::PreParser::PreParseResult result = preparser.PreParseProgram();
483 CHECK_EQ(i::PreParser::kPreParseStackOverflow, result); 497 CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
484 } 498 }
485 499
486 500
487 class TestExternalResource: public v8::String::ExternalStringResource { 501 class TestExternalResource: public v8::String::ExternalStringResource {
488 public: 502 public:
489 explicit TestExternalResource(uint16_t* data, int length) 503 explicit TestExternalResource(uint16_t* data, int length)
490 : data_(data), length_(static_cast<size_t>(length)) { } 504 : data_(data), length_(static_cast<size_t>(length)) { }
491 505
(...skipping 457 matching lines...)
949 " }", "\n" 963 " }", "\n"
950 " more;", i::BLOCK_SCOPE, i::STRICT }, 964 " more;", i::BLOCK_SCOPE, i::STRICT },
951 { " start;\n" 965 { " start;\n"
952 " function fun", "(a,b) { infunction; }", " more;", 966 " function fun", "(a,b) { infunction; }", " more;",
953 i::FUNCTION_SCOPE, i::SLOPPY }, 967 i::FUNCTION_SCOPE, i::SLOPPY },
954 { " start;\n" 968 { " start;\n"
955 " function fun", "(a,b) {\n" 969 " function fun", "(a,b) {\n"
956 " infunction;\n" 970 " infunction;\n"
957 " }", "\n" 971 " }", "\n"
958 " more;", i::FUNCTION_SCOPE, i::SLOPPY }, 972 " more;", i::FUNCTION_SCOPE, i::SLOPPY },
959 { " (function fun", "(a,b) { infunction; }", ")();", 973 // TODO(aperez): Change to use i::ARROW_SCOPE when implemented
974 { " start;\n", "(a,b) => a + b", "; more;",
975 i::FUNCTION_SCOPE, i::SLOPPY },
976 { " start;\n", "(a,b) => { return a+b; }", "\nmore;",
977 i::FUNCTION_SCOPE, i::SLOPPY },
978 { " start;\n"
979 " (function fun", "(a,b) { infunction; }", ")();",
960 i::FUNCTION_SCOPE, i::SLOPPY }, 980 i::FUNCTION_SCOPE, i::SLOPPY },
961 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;", 981 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;",
962 i::BLOCK_SCOPE, i::STRICT }, 982 i::BLOCK_SCOPE, i::STRICT },
963 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;", 983 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;",
964 i::BLOCK_SCOPE, i::STRICT }, 984 i::BLOCK_SCOPE, i::STRICT },
965 { " for ", "(let x = 1 ; x < 10; ++ x) {\n" 985 { " for ", "(let x = 1 ; x < 10; ++ x) {\n"
966 " block;\n" 986 " block;\n"
967 " }", "\n" 987 " }", "\n"
968 " more;", i::BLOCK_SCOPE, i::STRICT }, 988 " more;", i::BLOCK_SCOPE, i::STRICT },
969 { " for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;", 989 { " for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;",
(...skipping 132 matching lines...)
1102 1122
1103 // Parse program source. 1123 // Parse program source.
1104 i::Handle<i::String> source = factory->NewStringFromUtf8( 1124 i::Handle<i::String> source = factory->NewStringFromUtf8(
1105 i::CStrVector(program.start())).ToHandleChecked(); 1125 i::CStrVector(program.start())).ToHandleChecked();
1106 CHECK_EQ(source->length(), kProgramSize); 1126 CHECK_EQ(source->length(), kProgramSize);
1107 i::Handle<i::Script> script = factory->NewScript(source); 1127 i::Handle<i::Script> script = factory->NewScript(source);
1108 i::CompilationInfoWithZone info(script); 1128 i::CompilationInfoWithZone info(script);
1109 i::Parser parser(&info); 1129 i::Parser parser(&info);
1110 parser.set_allow_lazy(true); 1130 parser.set_allow_lazy(true);
1111 parser.set_allow_harmony_scoping(true); 1131 parser.set_allow_harmony_scoping(true);
1132 parser.set_allow_arrow_functions(true);
1112 info.MarkAsGlobal(); 1133 info.MarkAsGlobal();
1113 info.SetStrictMode(source_data[i].strict_mode); 1134 info.SetStrictMode(source_data[i].strict_mode);
1114 parser.Parse(); 1135 parser.Parse();
1115 CHECK(info.function() != NULL); 1136 CHECK(info.function() != NULL);
1116 1137
1117 // Check scope types and positions. 1138 // Check scope types and positions.
1118 i::Scope* scope = info.function()->scope(); 1139 i::Scope* scope = info.function()->scope();
1119 CHECK(scope->is_global_scope()); 1140 CHECK(scope->is_global_scope());
1120 CHECK_EQ(scope->start_position(), 0); 1141 CHECK_EQ(scope->start_position(), 0);
1121 CHECK_EQ(scope->end_position(), kProgramSize); 1142 CHECK_EQ(scope->end_position(), kProgramSize);
(...skipping 2013 matching lines...)
3135 3156
3136 // Arrow has more precedence, this is the same as: foo ? bar : (baz = {}) 3157 // Arrow has more precedence, this is the same as: foo ? bar : (baz = {})
3137 "foo ? bar : baz => {}", 3158 "foo ? bar : baz => {}",
3138 NULL 3159 NULL
3139 }; 3160 };
3140 3161
3141 static const ParserFlag always_flags[] = {kAllowArrowFunctions}; 3162 static const ParserFlag always_flags[] = {kAllowArrowFunctions};
3142 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, 3163 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
3143 always_flags, ARRAY_SIZE(always_flags)); 3164 always_flags, ARRAY_SIZE(always_flags));
3144 } 3165 }
OLDNEW

Powered by Google App Engine