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 Parser parser(script, library); | 232 Parser parser(script, library); |
232 if (FLAG_compiler_stats) { | 233 if (FLAG_compiler_stats) { |
233 CompilerStats::parser_timer.Start(); | 234 CompilerStats::parser_timer.Start(); |
234 } | 235 } |
235 parser.ParseTopLevel(); | 236 parser.ParseTopLevel(); |
236 if (FLAG_compiler_stats) { | 237 if (FLAG_compiler_stats) { |
237 CompilerStats::parser_timer.Stop(); | 238 CompilerStats::parser_timer.Stop(); |
238 CompilerStats::num_tokens_total += parser.tokens_.Length(); | 239 CompilerStats::num_tokens_total += parser.tokens_.Length(); |
239 } | 240 } |
240 } | 241 } |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
550 (seq->NodeAt(seq->length() - 1)->IsSequenceNode())) { | 551 (seq->NodeAt(seq->length() - 1)->IsSequenceNode())) { |
551 return HasReturnNode(seq->NodeAt(seq->length() - 1)->AsSequenceNode()); | 552 return HasReturnNode(seq->NodeAt(seq->length() - 1)->AsSequenceNode()); |
552 } else { | 553 } else { |
553 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); | 554 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); |
554 } | 555 } |
555 } | 556 } |
556 | 557 |
557 | 558 |
558 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 559 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
559 Isolate* isolate = Isolate::Current(); | 560 Isolate* isolate = Isolate::Current(); |
561 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | |
560 // Compilation can be nested, preserve the ast node id. | 562 // Compilation can be nested, preserve the ast node id. |
561 const int prev_ast_node_id = isolate->ast_node_id(); | 563 const int prev_ast_node_id = isolate->ast_node_id(); |
562 isolate->set_ast_node_id(0); | 564 isolate->set_ast_node_id(0); |
563 ASSERT(parsed_function != NULL); | 565 ASSERT(parsed_function != NULL); |
564 const Function& func = parsed_function->function(); | 566 const Function& func = parsed_function->function(); |
565 const Class& cls = Class::Handle(isolate, func.owner()); | 567 const Class& cls = Class::Handle(isolate, func.owner()); |
566 const Script& script = Script::Handle(isolate, cls.script()); | 568 const Script& script = Script::Handle(isolate, cls.script()); |
567 Parser parser(script, func, func.token_index()); | 569 Parser parser(script, func, func.token_index()); |
568 if (FLAG_compiler_stats) { | 570 if (FLAG_compiler_stats) { |
569 CompilerStats::parser_timer.Start(); | 571 CompilerStats::parser_timer.Start(); |
(...skipping 5783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6353 const int kNumArguments = 0; // no arguments. | 6355 const int kNumArguments = 0; // no arguments. |
6354 const Array& kNoArgumentNames = Array::Handle(); | 6356 const Array& kNoArgumentNames = Array::Handle(); |
6355 const Function& func = | 6357 const Function& func = |
6356 Function::Handle(Resolver::ResolveStatic(cls, | 6358 Function::Handle(Resolver::ResolveStatic(cls, |
6357 getter_name, | 6359 getter_name, |
6358 kNumArguments, | 6360 kNumArguments, |
6359 kNoArgumentNames, | 6361 kNoArgumentNames, |
6360 Resolver::kIsQualified)); | 6362 Resolver::kIsQualified)); |
6361 ASSERT(!func.IsNull()); | 6363 ASSERT(!func.IsNull()); |
6362 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); | 6364 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); |
6363 Instance& const_value = Instance::Handle( | 6365 Object& const_value = Object::Handle( |
6364 DartEntry::InvokeStatic(func, arguments, kNoArgumentNames)); | 6366 DartEntry::InvokeStatic(func, arguments, kNoArgumentNames)); |
6365 if (const_value.IsUnhandledException()) { | 6367 if (const_value.IsError()) { |
6366 ErrorMsg("exception thrown in Parser::RunStaticFieldInitializer"); | 6368 if (const_value.IsUnhandledException()) { |
6369 ErrorMsg("exception thrown in Parser::RunStaticFieldInitializer"); | |
6370 } else { | |
6371 Error& error = Error::Handle(); | |
6372 error ^= const_value.raw(); | |
6373 Isolate::Current()->long_jump_base()->Jump(1, error); | |
6374 } | |
6367 } | 6375 } |
6368 if (!const_value.IsNull()) { | 6376 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
6369 const_value ^= const_value.Canonicalize(); | 6377 Instance& instance = Instance::Handle(); |
6378 instance ^= const_value.raw(); | |
6379 if (!instance.IsNull()) { | |
6380 instance ^= instance.Canonicalize(); | |
6370 } | 6381 } |
6371 field.set_value(const_value); | 6382 field.set_value(instance); |
6372 } | 6383 } |
6373 } | 6384 } |
6374 | 6385 |
6375 | 6386 |
6376 RawInstance* Parser::EvaluateConstConstructorCall( | 6387 RawObject* Parser::EvaluateConstConstructorCall( |
6377 const Class& type_class, | 6388 const Class& type_class, |
6378 const AbstractTypeArguments& type_arguments, | 6389 const AbstractTypeArguments& type_arguments, |
6379 const Function& constructor, | 6390 const Function& constructor, |
6380 ArgumentListNode* arguments) { | 6391 ArgumentListNode* arguments) { |
6381 // +2 for implicit receiver and construction phase arguments. | 6392 // +2 for implicit receiver and construction phase arguments. |
6382 GrowableArray<const Object*> arg_values(arguments->length() + 2); | 6393 GrowableArray<const Object*> arg_values(arguments->length() + 2); |
6383 Instance& instance = Instance::Handle(); | 6394 Instance& instance = Instance::Handle(); |
6384 if (!constructor.IsFactory()) { | 6395 if (!constructor.IsFactory()) { |
6385 instance = Instance::New(type_class); | 6396 instance = Instance::New(type_class); |
6386 if (!type_arguments.IsNull()) { | 6397 if (!type_arguments.IsNull()) { |
(...skipping 10 matching lines...) Expand all Loading... | |
6397 ASSERT(type_arguments.IsZoneHandle()); | 6408 ASSERT(type_arguments.IsZoneHandle()); |
6398 arg_values.Add(&type_arguments); | 6409 arg_values.Add(&type_arguments); |
6399 } | 6410 } |
6400 for (int i = 0; i < arguments->length(); i++) { | 6411 for (int i = 0; i < arguments->length(); i++) { |
6401 AstNode* arg = arguments->NodeAt(i); | 6412 AstNode* arg = arguments->NodeAt(i); |
6402 // Arguments have been evaluated to a literal value already. | 6413 // Arguments have been evaluated to a literal value already. |
6403 ASSERT(arg->IsLiteralNode()); | 6414 ASSERT(arg->IsLiteralNode()); |
6404 arg_values.Add(&arg->AsLiteralNode()->literal()); | 6415 arg_values.Add(&arg->AsLiteralNode()->literal()); |
6405 } | 6416 } |
6406 const Array& opt_arg_names = arguments->names(); | 6417 const Array& opt_arg_names = arguments->names(); |
6407 const Instance& result = Instance::Handle( | 6418 const Object& result = Object::Handle( |
6408 DartEntry::InvokeStatic(constructor, arg_values, opt_arg_names)); | 6419 DartEntry::InvokeStatic(constructor, arg_values, opt_arg_names)); |
6409 if (result.IsUnhandledException()) { | 6420 if (result.IsError()) { |
6410 instance = result.raw(); | 6421 if (result.IsUnhandledException()) { |
6422 return result.raw(); | |
6423 } else { | |
6424 Error& error = Error::Handle(); | |
6425 error ^= result.raw(); | |
6426 Isolate::Current()->long_jump_base()->Jump(1, error); | |
6427 UNREACHABLE(); | |
6428 } | |
6411 } else { | 6429 } else { |
6412 if (constructor.IsFactory()) { | 6430 if (constructor.IsFactory()) { |
6413 // The factory method returns the allocated object. | 6431 // The factory method returns the allocated object. |
6414 instance = result.raw(); | 6432 instance ^= result.raw(); |
6415 } | 6433 } |
6416 if (!instance.IsNull()) { | 6434 if (!instance.IsNull()) { |
6417 instance ^= instance.Canonicalize(); | 6435 instance ^= instance.Canonicalize(); |
6418 } | 6436 } |
6437 return instance.raw(); | |
6419 } | 6438 } |
6420 return instance.raw(); | |
6421 } | 6439 } |
6422 | 6440 |
6423 | 6441 |
6424 // Do a lookup for the identifier in the block scope and the class scope | 6442 // Do a lookup for the identifier in the block scope and the class scope |
6425 // return true if the identifier is found, false otherwise. | 6443 // return true if the identifier is found, false otherwise. |
6426 // If node is non NULL return an AST node corresponding to the identifier. | 6444 // If node is non NULL return an AST node corresponding to the identifier. |
6427 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, | 6445 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, |
6428 const String &ident, | 6446 const String &ident, |
6429 AstNode** node) { | 6447 AstNode** node) { |
6430 TRACE_PARSER("ResolveIdentInLocalScope"); | 6448 TRACE_PARSER("ResolveIdentInLocalScope"); |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7042 const Class& immutable_map_class = | 7060 const Class& immutable_map_class = |
7043 Class::Handle(LookupImplClass(immutable_map_class_name)); | 7061 Class::Handle(LookupImplClass(immutable_map_class_name)); |
7044 ASSERT(!immutable_map_class.IsNull()); | 7062 ASSERT(!immutable_map_class.IsNull()); |
7045 ArgumentListNode* constr_args = new ArgumentListNode(token_index_); | 7063 ArgumentListNode* constr_args = new ArgumentListNode(token_index_); |
7046 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); | 7064 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); |
7047 const String& constr_name = | 7065 const String& constr_name = |
7048 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); | 7066 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); |
7049 const Function& map_constr = Function::ZoneHandle( | 7067 const Function& map_constr = Function::ZoneHandle( |
7050 immutable_map_class.LookupConstructor(constr_name)); | 7068 immutable_map_class.LookupConstructor(constr_name)); |
7051 ASSERT(!map_constr.IsNull()); | 7069 ASSERT(!map_constr.IsNull()); |
7052 const Instance& const_instance = Instance::ZoneHandle( | 7070 const Object& constructor_result = Object::ZoneHandle( |
siva
2012/01/31 00:52:34
Why does this have to be a ZoneHandle?
turnidge
2012/01/31 21:56:31
I was cribbing code here. Fixed.
| |
7053 EvaluateConstConstructorCall(immutable_map_class, | 7071 EvaluateConstConstructorCall(immutable_map_class, |
7054 map_type_arguments, | 7072 map_type_arguments, |
7055 map_constr, | 7073 map_constr, |
7056 constr_args)); | 7074 constr_args)); |
7057 if (const_instance.IsUnhandledException()) { | 7075 if (constructor_result.IsUnhandledException()) { |
7058 return CreateEvalConstConstructorThrow(literal_pos, const_instance); | 7076 return CreateEvalConstConstructorThrow(literal_pos, constructor_result); |
7059 } else { | 7077 } else { |
7078 Instance& const_instance = Instance::ZoneHandle(); | |
7079 const_instance ^= constructor_result.raw(); | |
7060 return new LiteralNode(literal_pos, const_instance); | 7080 return new LiteralNode(literal_pos, const_instance); |
7061 } | 7081 } |
7062 } else { | 7082 } else { |
7063 // Factory call at runtime. | 7083 // Factory call at runtime. |
7064 String& map_literal_factory_class_name = String::Handle( | 7084 String& map_literal_factory_class_name = String::Handle( |
7065 String::NewSymbol(kMapLiteralFactoryClassName)); | 7085 String::NewSymbol(kMapLiteralFactoryClassName)); |
7066 const Class& map_literal_factory_class = | 7086 const Class& map_literal_factory_class = |
7067 Class::Handle(LookupCoreClass(map_literal_factory_class_name)); | 7087 Class::Handle(LookupCoreClass(map_literal_factory_class_name)); |
7068 ASSERT(!map_literal_factory_class.IsNull()); | 7088 ASSERT(!map_literal_factory_class.IsNull()); |
7069 const String& map_literal_factory_name = | 7089 const String& map_literal_factory_name = |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7294 } | 7314 } |
7295 | 7315 |
7296 type_arguments ^= type_arguments.Canonicalize(); | 7316 type_arguments ^= type_arguments.Canonicalize(); |
7297 // Make the constructor call. | 7317 // Make the constructor call. |
7298 AstNode* new_object = NULL; | 7318 AstNode* new_object = NULL; |
7299 if (is_const) { | 7319 if (is_const) { |
7300 if (!constructor.is_const()) { | 7320 if (!constructor.is_const()) { |
7301 ErrorMsg("'const' requires const constructor: '%s'", | 7321 ErrorMsg("'const' requires const constructor: '%s'", |
7302 String::Handle(constructor.name()).ToCString()); | 7322 String::Handle(constructor.name()).ToCString()); |
7303 } | 7323 } |
7304 const Instance& const_instance = Instance::ZoneHandle( | 7324 const Object& constructor_result = Object::ZoneHandle( |
siva
2012/01/31 00:52:34
Ditto...
turnidge
2012/01/31 21:56:31
Fixed.
| |
7305 EvaluateConstConstructorCall(type_class, | 7325 EvaluateConstConstructorCall(type_class, |
7306 type_arguments, | 7326 type_arguments, |
7307 constructor, | 7327 constructor, |
7308 arguments)); | 7328 arguments)); |
7309 if (const_instance.IsUnhandledException()) { | 7329 if (constructor_result.IsUnhandledException()) { |
7310 new_object = CreateEvalConstConstructorThrow(new_pos, const_instance); | 7330 new_object = CreateEvalConstConstructorThrow(new_pos, constructor_result); |
7311 } else { | 7331 } else { |
7332 Instance& const_instance = Instance::ZoneHandle(); | |
7333 const_instance ^= constructor_result.raw(); | |
7312 new_object = new LiteralNode(new_pos, const_instance); | 7334 new_object = new LiteralNode(new_pos, const_instance); |
7313 } | 7335 } |
7314 } else { | 7336 } else { |
7315 CheckFunctionIsCallable(new_pos, constructor); | 7337 CheckFunctionIsCallable(new_pos, constructor); |
7316 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 7338 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
7317 if (!type_arguments.IsNull() && | 7339 if (!type_arguments.IsNull() && |
7318 !type_arguments.IsInstantiated() && | 7340 !type_arguments.IsInstantiated() && |
7319 (current_block_->scope->function_level() > 0)) { | 7341 (current_block_->scope->function_level() > 0)) { |
7320 // Make sure that the instantiator is captured. | 7342 // Make sure that the instantiator is captured. |
7321 CaptureReceiver(); | 7343 CaptureReceiver(); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7511 return expr->AsLiteralNode()->literal(); | 7533 return expr->AsLiteralNode()->literal(); |
7512 } else { | 7534 } else { |
7513 ASSERT(expr->EvalConstExpr() != NULL); | 7535 ASSERT(expr->EvalConstExpr() != NULL); |
7514 ReturnNode* ret = new ReturnNode(expr->token_index(), expr); | 7536 ReturnNode* ret = new ReturnNode(expr->token_index(), expr); |
7515 // Compile time constant expressions cannot reference anything from a | 7537 // Compile time constant expressions cannot reference anything from a |
7516 // local scope. | 7538 // local scope. |
7517 LocalScope* empty_scope = new LocalScope(NULL, 0, 0); | 7539 LocalScope* empty_scope = new LocalScope(NULL, 0, 0); |
7518 SequenceNode* seq = new SequenceNode(expr->token_index(), empty_scope); | 7540 SequenceNode* seq = new SequenceNode(expr->token_index(), empty_scope); |
7519 seq->Add(ret); | 7541 seq->Add(ret); |
7520 | 7542 |
7521 Instance& value = Instance::ZoneHandle(Compiler::ExecuteOnce(seq)); | 7543 Object& result = Object::ZoneHandle(Compiler::ExecuteOnce(seq)); |
siva
2012/01/31 00:52:34
Ditto.
turnidge
2012/01/31 21:56:31
Fixed. Also changed for Error below.
| |
7544 if (result.IsError()) { | |
7545 // Propagate the compilation error. | |
7546 Error& error = Error::ZoneHandle(); | |
7547 error ^= result.raw(); | |
7548 Isolate::Current()->long_jump_base()->Jump(1, error); | |
7549 UNREACHABLE(); | |
7550 } | |
7551 ASSERT(result.IsInstance()); | |
7552 Instance& value = Instance::ZoneHandle(); | |
7553 value ^= result.raw(); | |
7522 if (value.IsNull()) { | 7554 if (value.IsNull()) { |
7523 value ^= value.Canonicalize(); | 7555 value ^= value.Canonicalize(); |
7524 } | 7556 } |
7525 return value; | 7557 return value; |
7526 } | 7558 } |
7527 } | 7559 } |
7528 | 7560 |
7529 | 7561 |
7530 void Parser::SkipFunctionLiteral() { | 7562 void Parser::SkipFunctionLiteral() { |
7531 if (IsIdentifier()) { | 7563 if (IsIdentifier()) { |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7760 } | 7792 } |
7761 | 7793 |
7762 | 7794 |
7763 void Parser::SkipNestedExpr() { | 7795 void Parser::SkipNestedExpr() { |
7764 const bool saved_mode = SetAllowFunctionLiterals(true); | 7796 const bool saved_mode = SetAllowFunctionLiterals(true); |
7765 SkipExpr(); | 7797 SkipExpr(); |
7766 SetAllowFunctionLiterals(saved_mode); | 7798 SetAllowFunctionLiterals(saved_mode); |
7767 } | 7799 } |
7768 | 7800 |
7769 } // namespace dart | 7801 } // namespace dart |
OLD | NEW |