| 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 |