OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
6 | 6 |
7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 for (int i = 0; i < objs.length(); i++) { | 92 for (int i = 0; i < objs.length(); i++) { |
93 a.SetTypeAt(i, *objs[i]); | 93 a.SetTypeAt(i, *objs[i]); |
94 } | 94 } |
95 // Cannot canonicalize TypeArgument yet as its types may not have been | 95 // Cannot canonicalize TypeArgument yet as its types may not have been |
96 // finalized yet. | 96 // finalized yet. |
97 return a.raw(); | 97 return a.raw(); |
98 } | 98 } |
99 | 99 |
100 | 100 |
101 static ThrowNode* CreateEvalConstConstructorThrow(intptr_t token_pos, | 101 static ThrowNode* CreateEvalConstConstructorThrow(intptr_t token_pos, |
102 const Instance& instance) { | 102 const Object& obj) { |
103 UnhandledException& excp = UnhandledException::Handle(); | 103 UnhandledException& excp = UnhandledException::Handle(); |
104 excp ^= instance.raw(); | 104 excp ^= obj.raw(); |
105 const Instance& exception = Instance::ZoneHandle(excp.exception()); | 105 const Instance& exception = Instance::ZoneHandle(excp.exception()); |
106 const Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace()); | 106 const Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace()); |
107 return new ThrowNode(token_pos, | 107 return new ThrowNode(token_pos, |
108 new LiteralNode(token_pos, exception), | 108 new LiteralNode(token_pos, exception), |
109 new LiteralNode(token_pos, stack_trace)); | 109 new LiteralNode(token_pos, stack_trace)); |
110 } | 110 } |
111 | 111 |
112 | 112 |
113 struct Parser::Block : public ZoneAllocated { | 113 struct Parser::Block : public ZoneAllocated { |
114 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) | 114 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 if (position < token_index_ && position != 0) { | 221 if (position < token_index_ && position != 0) { |
222 CompilerStats::num_tokens_rewind += (token_index_ - position); | 222 CompilerStats::num_tokens_rewind += (token_index_ - position); |
223 } | 223 } |
224 token_index_ = position; | 224 token_index_ = position; |
225 token_kind_ = Token::kILLEGAL; | 225 token_kind_ = Token::kILLEGAL; |
226 } | 226 } |
227 | 227 |
228 | 228 |
229 void Parser::ParseCompilationUnit(const Library& library, | 229 void Parser::ParseCompilationUnit(const Library& library, |
230 const Script& script) { | 230 const Script& script) { |
| 231 ASSERT(Isolate::Current()->long_jump_base()->IsSafeToJump()); |
231 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 232 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
232 Parser parser(script, library); | 233 Parser parser(script, library); |
233 parser.ParseTopLevel(); | 234 parser.ParseTopLevel(); |
234 if (FLAG_compiler_stats) { | 235 if (FLAG_compiler_stats) { |
235 CompilerStats::num_tokens_total += parser.tokens_.Length(); | 236 CompilerStats::num_tokens_total += parser.tokens_.Length(); |
236 } | 237 } |
237 } | 238 } |
238 | 239 |
239 | 240 |
240 Token::Kind Parser::CurrentToken() { | 241 Token::Kind Parser::CurrentToken() { |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 return HasReturnNode(seq->NodeAt(seq->length() - 1)->AsSequenceNode()); | 545 return HasReturnNode(seq->NodeAt(seq->length() - 1)->AsSequenceNode()); |
545 } else { | 546 } else { |
546 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); | 547 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); |
547 } | 548 } |
548 } | 549 } |
549 | 550 |
550 | 551 |
551 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 552 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
552 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 553 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
553 Isolate* isolate = Isolate::Current(); | 554 Isolate* isolate = Isolate::Current(); |
| 555 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
554 // Compilation can be nested, preserve the ast node id. | 556 // Compilation can be nested, preserve the ast node id. |
555 const int prev_ast_node_id = isolate->ast_node_id(); | 557 const int prev_ast_node_id = isolate->ast_node_id(); |
556 isolate->set_ast_node_id(0); | 558 isolate->set_ast_node_id(0); |
557 ASSERT(parsed_function != NULL); | 559 ASSERT(parsed_function != NULL); |
558 const Function& func = parsed_function->function(); | 560 const Function& func = parsed_function->function(); |
559 const Class& cls = Class::Handle(isolate, func.owner()); | 561 const Class& cls = Class::Handle(isolate, func.owner()); |
560 const Script& script = Script::Handle(isolate, cls.script()); | 562 const Script& script = Script::Handle(isolate, cls.script()); |
561 Parser parser(script, func, func.token_index()); | 563 Parser parser(script, func, func.token_index()); |
562 SequenceNode* node_sequence = NULL; | 564 SequenceNode* node_sequence = NULL; |
563 Array& default_parameter_values = Array::Handle(isolate, Array::null()); | 565 Array& default_parameter_values = Array::Handle(isolate, Array::null()); |
(...skipping 5763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6327 const int kNumArguments = 0; // no arguments. | 6329 const int kNumArguments = 0; // no arguments. |
6328 const Array& kNoArgumentNames = Array::Handle(); | 6330 const Array& kNoArgumentNames = Array::Handle(); |
6329 const Function& func = | 6331 const Function& func = |
6330 Function::Handle(Resolver::ResolveStatic(cls, | 6332 Function::Handle(Resolver::ResolveStatic(cls, |
6331 getter_name, | 6333 getter_name, |
6332 kNumArguments, | 6334 kNumArguments, |
6333 kNoArgumentNames, | 6335 kNoArgumentNames, |
6334 Resolver::kIsQualified)); | 6336 Resolver::kIsQualified)); |
6335 ASSERT(!func.IsNull()); | 6337 ASSERT(!func.IsNull()); |
6336 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); | 6338 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); |
6337 Instance& const_value = Instance::Handle( | 6339 Object& const_value = Object::Handle( |
6338 DartEntry::InvokeStatic(func, arguments, kNoArgumentNames)); | 6340 DartEntry::InvokeStatic(func, arguments, kNoArgumentNames)); |
6339 if (const_value.IsUnhandledException()) { | 6341 if (const_value.IsError()) { |
6340 ErrorMsg("exception thrown in Parser::RunStaticFieldInitializer"); | 6342 if (const_value.IsUnhandledException()) { |
| 6343 ErrorMsg("exception thrown in Parser::RunStaticFieldInitializer"); |
| 6344 } else { |
| 6345 Error& error = Error::Handle(); |
| 6346 error ^= const_value.raw(); |
| 6347 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 6348 } |
6341 } | 6349 } |
6342 if (!const_value.IsNull()) { | 6350 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
6343 const_value ^= const_value.Canonicalize(); | 6351 Instance& instance = Instance::Handle(); |
| 6352 instance ^= const_value.raw(); |
| 6353 if (!instance.IsNull()) { |
| 6354 instance ^= instance.Canonicalize(); |
6344 } | 6355 } |
6345 field.set_value(const_value); | 6356 field.set_value(instance); |
6346 } | 6357 } |
6347 } | 6358 } |
6348 | 6359 |
6349 | 6360 |
6350 RawInstance* Parser::EvaluateConstConstructorCall( | 6361 RawObject* Parser::EvaluateConstConstructorCall( |
6351 const Class& type_class, | 6362 const Class& type_class, |
6352 const AbstractTypeArguments& type_arguments, | 6363 const AbstractTypeArguments& type_arguments, |
6353 const Function& constructor, | 6364 const Function& constructor, |
6354 ArgumentListNode* arguments) { | 6365 ArgumentListNode* arguments) { |
6355 // +2 for implicit receiver and construction phase arguments. | 6366 // +2 for implicit receiver and construction phase arguments. |
6356 GrowableArray<const Object*> arg_values(arguments->length() + 2); | 6367 GrowableArray<const Object*> arg_values(arguments->length() + 2); |
6357 Instance& instance = Instance::Handle(); | 6368 Instance& instance = Instance::Handle(); |
6358 if (!constructor.IsFactory()) { | 6369 if (!constructor.IsFactory()) { |
6359 instance = Instance::New(type_class); | 6370 instance = Instance::New(type_class); |
6360 if (!type_arguments.IsNull()) { | 6371 if (!type_arguments.IsNull()) { |
(...skipping 10 matching lines...) Expand all Loading... |
6371 ASSERT(type_arguments.IsZoneHandle()); | 6382 ASSERT(type_arguments.IsZoneHandle()); |
6372 arg_values.Add(&type_arguments); | 6383 arg_values.Add(&type_arguments); |
6373 } | 6384 } |
6374 for (int i = 0; i < arguments->length(); i++) { | 6385 for (int i = 0; i < arguments->length(); i++) { |
6375 AstNode* arg = arguments->NodeAt(i); | 6386 AstNode* arg = arguments->NodeAt(i); |
6376 // Arguments have been evaluated to a literal value already. | 6387 // Arguments have been evaluated to a literal value already. |
6377 ASSERT(arg->IsLiteralNode()); | 6388 ASSERT(arg->IsLiteralNode()); |
6378 arg_values.Add(&arg->AsLiteralNode()->literal()); | 6389 arg_values.Add(&arg->AsLiteralNode()->literal()); |
6379 } | 6390 } |
6380 const Array& opt_arg_names = arguments->names(); | 6391 const Array& opt_arg_names = arguments->names(); |
6381 const Instance& result = Instance::Handle( | 6392 const Object& result = Object::Handle( |
6382 DartEntry::InvokeStatic(constructor, arg_values, opt_arg_names)); | 6393 DartEntry::InvokeStatic(constructor, arg_values, opt_arg_names)); |
6383 if (result.IsUnhandledException()) { | 6394 if (result.IsError()) { |
6384 instance = result.raw(); | 6395 if (result.IsUnhandledException()) { |
| 6396 return result.raw(); |
| 6397 } else { |
| 6398 Error& error = Error::Handle(); |
| 6399 error ^= result.raw(); |
| 6400 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 6401 UNREACHABLE(); |
| 6402 return Object::null(); |
| 6403 } |
6385 } else { | 6404 } else { |
6386 if (constructor.IsFactory()) { | 6405 if (constructor.IsFactory()) { |
6387 // The factory method returns the allocated object. | 6406 // The factory method returns the allocated object. |
6388 instance = result.raw(); | 6407 instance ^= result.raw(); |
6389 } | 6408 } |
6390 if (!instance.IsNull()) { | 6409 if (!instance.IsNull()) { |
6391 instance ^= instance.Canonicalize(); | 6410 instance ^= instance.Canonicalize(); |
6392 } | 6411 } |
| 6412 return instance.raw(); |
6393 } | 6413 } |
6394 return instance.raw(); | |
6395 } | 6414 } |
6396 | 6415 |
6397 | 6416 |
6398 // Do a lookup for the identifier in the block scope and the class scope | 6417 // Do a lookup for the identifier in the block scope and the class scope |
6399 // return true if the identifier is found, false otherwise. | 6418 // return true if the identifier is found, false otherwise. |
6400 // If node is non NULL return an AST node corresponding to the identifier. | 6419 // If node is non NULL return an AST node corresponding to the identifier. |
6401 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, | 6420 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, |
6402 const String &ident, | 6421 const String &ident, |
6403 AstNode** node) { | 6422 AstNode** node) { |
6404 TRACE_PARSER("ResolveIdentInLocalScope"); | 6423 TRACE_PARSER("ResolveIdentInLocalScope"); |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7006 const Class& immutable_map_class = | 7025 const Class& immutable_map_class = |
7007 Class::Handle(LookupImplClass(immutable_map_class_name)); | 7026 Class::Handle(LookupImplClass(immutable_map_class_name)); |
7008 ASSERT(!immutable_map_class.IsNull()); | 7027 ASSERT(!immutable_map_class.IsNull()); |
7009 ArgumentListNode* constr_args = new ArgumentListNode(token_index_); | 7028 ArgumentListNode* constr_args = new ArgumentListNode(token_index_); |
7010 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); | 7029 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); |
7011 const String& constr_name = | 7030 const String& constr_name = |
7012 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); | 7031 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); |
7013 const Function& map_constr = Function::ZoneHandle( | 7032 const Function& map_constr = Function::ZoneHandle( |
7014 immutable_map_class.LookupConstructor(constr_name)); | 7033 immutable_map_class.LookupConstructor(constr_name)); |
7015 ASSERT(!map_constr.IsNull()); | 7034 ASSERT(!map_constr.IsNull()); |
7016 const Instance& const_instance = Instance::ZoneHandle( | 7035 const Object& constructor_result = Object::Handle( |
7017 EvaluateConstConstructorCall(immutable_map_class, | 7036 EvaluateConstConstructorCall(immutable_map_class, |
7018 map_type_arguments, | 7037 map_type_arguments, |
7019 map_constr, | 7038 map_constr, |
7020 constr_args)); | 7039 constr_args)); |
7021 if (const_instance.IsUnhandledException()) { | 7040 if (constructor_result.IsUnhandledException()) { |
7022 return CreateEvalConstConstructorThrow(literal_pos, const_instance); | 7041 return CreateEvalConstConstructorThrow(literal_pos, constructor_result); |
7023 } else { | 7042 } else { |
| 7043 Instance& const_instance = Instance::ZoneHandle(); |
| 7044 const_instance ^= constructor_result.raw(); |
7024 return new LiteralNode(literal_pos, const_instance); | 7045 return new LiteralNode(literal_pos, const_instance); |
7025 } | 7046 } |
7026 } else { | 7047 } else { |
7027 // Factory call at runtime. | 7048 // Factory call at runtime. |
7028 String& map_literal_factory_class_name = String::Handle( | 7049 String& map_literal_factory_class_name = String::Handle( |
7029 String::NewSymbol(kMapLiteralFactoryClassName)); | 7050 String::NewSymbol(kMapLiteralFactoryClassName)); |
7030 const Class& map_literal_factory_class = | 7051 const Class& map_literal_factory_class = |
7031 Class::Handle(LookupCoreClass(map_literal_factory_class_name)); | 7052 Class::Handle(LookupCoreClass(map_literal_factory_class_name)); |
7032 ASSERT(!map_literal_factory_class.IsNull()); | 7053 ASSERT(!map_literal_factory_class.IsNull()); |
7033 const String& map_literal_factory_name = | 7054 const String& map_literal_factory_name = |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7254 } | 7275 } |
7255 | 7276 |
7256 type_arguments ^= type_arguments.Canonicalize(); | 7277 type_arguments ^= type_arguments.Canonicalize(); |
7257 // Make the constructor call. | 7278 // Make the constructor call. |
7258 AstNode* new_object = NULL; | 7279 AstNode* new_object = NULL; |
7259 if (is_const) { | 7280 if (is_const) { |
7260 if (!constructor.is_const()) { | 7281 if (!constructor.is_const()) { |
7261 ErrorMsg("'const' requires const constructor: '%s'", | 7282 ErrorMsg("'const' requires const constructor: '%s'", |
7262 String::Handle(constructor.name()).ToCString()); | 7283 String::Handle(constructor.name()).ToCString()); |
7263 } | 7284 } |
7264 const Instance& const_instance = Instance::ZoneHandle( | 7285 const Object& constructor_result = Object::Handle( |
7265 EvaluateConstConstructorCall(constructor_class, | 7286 EvaluateConstConstructorCall(constructor_class, |
7266 type_arguments, | 7287 type_arguments, |
7267 constructor, | 7288 constructor, |
7268 arguments)); | 7289 arguments)); |
7269 if (const_instance.IsUnhandledException()) { | 7290 if (constructor_result.IsUnhandledException()) { |
7270 new_object = CreateEvalConstConstructorThrow(new_pos, const_instance); | 7291 new_object = CreateEvalConstConstructorThrow(new_pos, constructor_result); |
7271 } else { | 7292 } else { |
| 7293 Instance& const_instance = Instance::ZoneHandle(); |
| 7294 const_instance ^= constructor_result.raw(); |
7272 new_object = new LiteralNode(new_pos, const_instance); | 7295 new_object = new LiteralNode(new_pos, const_instance); |
7273 } | 7296 } |
7274 } else { | 7297 } else { |
7275 CheckFunctionIsCallable(new_pos, constructor); | 7298 CheckFunctionIsCallable(new_pos, constructor); |
7276 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 7299 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
7277 if (!type_arguments.IsNull() && | 7300 if (!type_arguments.IsNull() && |
7278 !type_arguments.IsInstantiated() && | 7301 !type_arguments.IsInstantiated() && |
7279 (current_block_->scope->function_level() > 0)) { | 7302 (current_block_->scope->function_level() > 0)) { |
7280 // Make sure that the instantiator is captured. | 7303 // Make sure that the instantiator is captured. |
7281 CaptureReceiver(); | 7304 CaptureReceiver(); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7470 return expr->AsLiteralNode()->literal(); | 7493 return expr->AsLiteralNode()->literal(); |
7471 } else { | 7494 } else { |
7472 ASSERT(expr->EvalConstExpr() != NULL); | 7495 ASSERT(expr->EvalConstExpr() != NULL); |
7473 ReturnNode* ret = new ReturnNode(expr->token_index(), expr); | 7496 ReturnNode* ret = new ReturnNode(expr->token_index(), expr); |
7474 // Compile time constant expressions cannot reference anything from a | 7497 // Compile time constant expressions cannot reference anything from a |
7475 // local scope. | 7498 // local scope. |
7476 LocalScope* empty_scope = new LocalScope(NULL, 0, 0); | 7499 LocalScope* empty_scope = new LocalScope(NULL, 0, 0); |
7477 SequenceNode* seq = new SequenceNode(expr->token_index(), empty_scope); | 7500 SequenceNode* seq = new SequenceNode(expr->token_index(), empty_scope); |
7478 seq->Add(ret); | 7501 seq->Add(ret); |
7479 | 7502 |
7480 Instance& value = Instance::ZoneHandle(Compiler::ExecuteOnce(seq)); | 7503 Object& result = Object::Handle(Compiler::ExecuteOnce(seq)); |
| 7504 if (result.IsError()) { |
| 7505 // Propagate the compilation error. |
| 7506 Error& error = Error::Handle(); |
| 7507 error ^= result.raw(); |
| 7508 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 7509 UNREACHABLE(); |
| 7510 } |
| 7511 ASSERT(result.IsInstance()); |
| 7512 Instance& value = Instance::ZoneHandle(); |
| 7513 value ^= result.raw(); |
7481 if (value.IsNull()) { | 7514 if (value.IsNull()) { |
7482 value ^= value.Canonicalize(); | 7515 value ^= value.Canonicalize(); |
7483 } | 7516 } |
7484 return value; | 7517 return value; |
7485 } | 7518 } |
7486 } | 7519 } |
7487 | 7520 |
7488 | 7521 |
7489 void Parser::SkipFunctionLiteral() { | 7522 void Parser::SkipFunctionLiteral() { |
7490 if (IsIdentifier()) { | 7523 if (IsIdentifier()) { |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7734 void Parser::SkipQualIdent() { | 7767 void Parser::SkipQualIdent() { |
7735 ASSERT(IsIdentifier()); | 7768 ASSERT(IsIdentifier()); |
7736 ConsumeToken(); | 7769 ConsumeToken(); |
7737 if (CurrentToken() == Token::kPERIOD) { | 7770 if (CurrentToken() == Token::kPERIOD) { |
7738 ConsumeToken(); // Consume the kPERIOD token. | 7771 ConsumeToken(); // Consume the kPERIOD token. |
7739 ExpectIdentifier("identifier expected after '.'"); | 7772 ExpectIdentifier("identifier expected after '.'"); |
7740 } | 7773 } |
7741 } | 7774 } |
7742 | 7775 |
7743 } // namespace dart | 7776 } // namespace dart |
OLD | NEW |