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