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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
9 #include "vm/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 45 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
46 DEFINE_FLAG(bool, supermixin, false, "Allow super calls in mixins."); | 46 DEFINE_FLAG(bool, supermixin, false, "Allow super calls in mixins."); |
47 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); | 47 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); |
48 | 48 |
49 DECLARE_FLAG(bool, lazy_dispatchers); | 49 DECLARE_FLAG(bool, lazy_dispatchers); |
50 DECLARE_FLAG(bool, load_deferred_eagerly); | 50 DECLARE_FLAG(bool, load_deferred_eagerly); |
51 DECLARE_FLAG(bool, profile_vm); | 51 DECLARE_FLAG(bool, profile_vm); |
52 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 52 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
53 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 53 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
54 | 54 |
55 // Quick access to the current isolate and zone. | 55 // Quick access to the current thread, isolate and zone. |
| 56 #define T (thread()) |
56 #define I (isolate()) | 57 #define I (isolate()) |
57 #define Z (zone()) | 58 #define Z (zone()) |
58 | 59 |
59 | 60 |
60 #if defined(DEBUG) | 61 #if defined(DEBUG) |
61 class TraceParser : public ValueObject { | 62 class TraceParser : public ValueObject { |
62 public: | 63 public: |
63 TraceParser(intptr_t token_pos, | 64 TraceParser(intptr_t token_pos, |
64 const Script& script, | 65 const Script& script, |
65 intptr_t* trace_indent, | 66 intptr_t* trace_indent, |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 void Parser::SetPosition(intptr_t position) { | 441 void Parser::SetPosition(intptr_t position) { |
441 tokens_iterator_.SetCurrentPosition(position); | 442 tokens_iterator_.SetCurrentPosition(position); |
442 token_kind_ = Token::kILLEGAL; | 443 token_kind_ = Token::kILLEGAL; |
443 } | 444 } |
444 | 445 |
445 | 446 |
446 void Parser::ParseCompilationUnit(const Library& library, | 447 void Parser::ParseCompilationUnit(const Library& library, |
447 const Script& script) { | 448 const Script& script) { |
448 Thread* thread = Thread::Current(); | 449 Thread* thread = Thread::Current(); |
449 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 450 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
450 CSTAT_TIMER_SCOPE(thread->isolate(), parser_timer); | 451 CSTAT_TIMER_SCOPE(thread, parser_timer); |
451 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); | 452 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); |
452 Parser parser(script, library, 0); | 453 Parser parser(script, library, 0); |
453 parser.ParseTopLevel(); | 454 parser.ParseTopLevel(); |
454 } | 455 } |
455 | 456 |
456 | 457 |
457 void Parser::ComputeCurrentToken() { | 458 void Parser::ComputeCurrentToken() { |
458 ASSERT(token_kind_ == Token::kILLEGAL); | 459 ASSERT(token_kind_ == Token::kILLEGAL); |
459 token_kind_ = tokens_iterator_.CurrentTokenKind(); | 460 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
460 if (token_kind_ == Token::kERROR) { | 461 if (token_kind_ == Token::kERROR) { |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
766 functions(GrowableObjectArray::Handle(GrowableObjectArray::New())) { } | 767 functions(GrowableObjectArray::Handle(GrowableObjectArray::New())) { } |
767 | 768 |
768 GrowableObjectArray& fields; | 769 GrowableObjectArray& fields; |
769 GrowableObjectArray& functions; | 770 GrowableObjectArray& functions; |
770 }; | 771 }; |
771 | 772 |
772 | 773 |
773 void Parser::ParseClass(const Class& cls) { | 774 void Parser::ParseClass(const Class& cls) { |
774 if (!cls.is_synthesized_class()) { | 775 if (!cls.is_synthesized_class()) { |
775 Thread* thread = Thread::Current(); | 776 Thread* thread = Thread::Current(); |
776 Isolate* isolate = thread->isolate(); | |
777 Zone* zone = thread->zone(); | 777 Zone* zone = thread->zone(); |
778 CSTAT_TIMER_SCOPE(isolate, parser_timer); | 778 CSTAT_TIMER_SCOPE(thread, parser_timer); |
779 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 779 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
780 const Script& script = Script::Handle(zone, cls.script()); | 780 const Script& script = Script::Handle(zone, cls.script()); |
781 const Library& lib = Library::Handle(zone, cls.library()); | 781 const Library& lib = Library::Handle(zone, cls.library()); |
782 Parser parser(script, lib, cls.token_pos()); | 782 Parser parser(script, lib, cls.token_pos()); |
783 parser.ParseClassDefinition(cls); | 783 parser.ParseClassDefinition(cls); |
784 } else if (cls.is_enum_class()) { | 784 } else if (cls.is_enum_class()) { |
785 Thread* thread = Thread::Current(); | 785 Thread* thread = Thread::Current(); |
786 Isolate* isolate = thread->isolate(); | |
787 Zone* zone = thread->zone(); | 786 Zone* zone = thread->zone(); |
788 CSTAT_TIMER_SCOPE(isolate, parser_timer); | 787 CSTAT_TIMER_SCOPE(thread, parser_timer); |
789 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 788 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
790 const Script& script = Script::Handle(zone, cls.script()); | 789 const Script& script = Script::Handle(zone, cls.script()); |
791 const Library& lib = Library::Handle(zone, cls.library()); | 790 const Library& lib = Library::Handle(zone, cls.library()); |
792 Parser parser(script, lib, cls.token_pos()); | 791 Parser parser(script, lib, cls.token_pos()); |
793 parser.ParseEnumDefinition(cls); | 792 parser.ParseEnumDefinition(cls); |
794 } | 793 } |
795 } | 794 } |
796 | 795 |
797 | 796 |
798 RawObject* Parser::ParseFunctionParameters(const Function& func) { | 797 RawObject* Parser::ParseFunctionParameters(const Function& func) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 UNREACHABLE(); | 872 UNREACHABLE(); |
874 return false; | 873 return false; |
875 } | 874 } |
876 | 875 |
877 | 876 |
878 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 877 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
879 Thread* thread = parsed_function->thread(); | 878 Thread* thread = parsed_function->thread(); |
880 ASSERT(thread == Thread::Current()); | 879 ASSERT(thread == Thread::Current()); |
881 Isolate* isolate = thread->isolate(); | 880 Isolate* isolate = thread->isolate(); |
882 Zone* zone = thread->zone(); | 881 Zone* zone = thread->zone(); |
883 CSTAT_TIMER_SCOPE(isolate, parser_timer); | 882 CSTAT_TIMER_SCOPE(thread, parser_timer); |
884 INC_STAT(isolate, num_functions_compiled, 1); | 883 INC_STAT(isolate, num_functions_compiled, 1); |
885 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, | 884 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, |
886 FLAG_profile_vm); | 885 FLAG_profile_vm); |
887 | 886 |
888 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 887 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
889 ASSERT(parsed_function != NULL); | 888 ASSERT(parsed_function != NULL); |
890 const Function& func = parsed_function->function(); | 889 const Function& func = parsed_function->function(); |
891 const Script& script = Script::Handle(zone, func.script()); | 890 const Script& script = Script::Handle(zone, func.script()); |
892 Parser parser(script, parsed_function, func.token_pos()); | 891 Parser parser(script, parsed_function, func.token_pos()); |
893 SequenceNode* node_sequence = NULL; | 892 SequenceNode* node_sequence = NULL; |
(...skipping 11035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11929 const int kNumArguments = 0; // no arguments. | 11928 const int kNumArguments = 0; // no arguments. |
11930 const Function& func = Function::Handle(Z, | 11929 const Function& func = Function::Handle(Z, |
11931 Resolver::ResolveStatic(field_owner, | 11930 Resolver::ResolveStatic(field_owner, |
11932 getter_name, | 11931 getter_name, |
11933 kNumArguments, | 11932 kNumArguments, |
11934 Object::empty_array())); | 11933 Object::empty_array())); |
11935 ASSERT(!func.IsNull()); | 11934 ASSERT(!func.IsNull()); |
11936 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); | 11935 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); |
11937 Object& const_value = Object::Handle(Z); | 11936 Object& const_value = Object::Handle(Z); |
11938 { | 11937 { |
11939 PAUSETIMERSCOPE(I, time_compilation); | 11938 PAUSETIMERSCOPE(T, time_compilation); |
11940 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); | 11939 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); |
11941 } | 11940 } |
11942 if (const_value.IsError()) { | 11941 if (const_value.IsError()) { |
11943 const Error& error = Error::Cast(const_value); | 11942 const Error& error = Error::Cast(const_value); |
11944 if (error.IsUnhandledException()) { | 11943 if (error.IsUnhandledException()) { |
11945 // An exception may not occur in every parse attempt, i.e., the | 11944 // An exception may not occur in every parse attempt, i.e., the |
11946 // generated AST is not deterministic. Therefore mark the function as | 11945 // generated AST is not deterministic. Therefore mark the function as |
11947 // not optimizable. | 11946 // not optimizable. |
11948 current_function().SetIsOptimizable(false); | 11947 current_function().SetIsOptimizable(false); |
11949 field.set_value(Object::null_instance()); | 11948 field.set_value(Object::null_instance()); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12010 for (int i = 0; i < arguments->length(); i++) { | 12009 for (int i = 0; i < arguments->length(); i++) { |
12011 AstNode* arg = arguments->NodeAt(i); | 12010 AstNode* arg = arguments->NodeAt(i); |
12012 // Arguments have been evaluated to a literal value already. | 12011 // Arguments have been evaluated to a literal value already. |
12013 ASSERT(arg->IsLiteralNode()); | 12012 ASSERT(arg->IsLiteralNode()); |
12014 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); | 12013 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); |
12015 } | 12014 } |
12016 const Array& args_descriptor = Array::Handle(Z, | 12015 const Array& args_descriptor = Array::Handle(Z, |
12017 ArgumentsDescriptor::New(num_arguments, arguments->names())); | 12016 ArgumentsDescriptor::New(num_arguments, arguments->names())); |
12018 Object& result = Object::Handle(Z); | 12017 Object& result = Object::Handle(Z); |
12019 { | 12018 { |
12020 PAUSETIMERSCOPE(I, time_compilation); | 12019 PAUSETIMERSCOPE(T, time_compilation); |
12021 result = DartEntry::InvokeFunction( | 12020 result = DartEntry::InvokeFunction( |
12022 constructor, arg_values, args_descriptor); | 12021 constructor, arg_values, args_descriptor); |
12023 } | 12022 } |
12024 if (result.IsError()) { | 12023 if (result.IsError()) { |
12025 // An exception may not occur in every parse attempt, i.e., the | 12024 // An exception may not occur in every parse attempt, i.e., the |
12026 // generated AST is not deterministic. Therefore mark the function as | 12025 // generated AST is not deterministic. Therefore mark the function as |
12027 // not optimizable. | 12026 // not optimizable. |
12028 current_function().SetIsOptimizable(false); | 12027 current_function().SetIsOptimizable(false); |
12029 if (result.IsUnhandledException()) { | 12028 if (result.IsUnhandledException()) { |
12030 return result.raw(); | 12029 return result.raw(); |
(...skipping 1440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13471 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); | 13470 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); |
13472 } | 13471 } |
13473 | 13472 |
13474 // Build argument array to pass to the interpolation function. | 13473 // Build argument array to pass to the interpolation function. |
13475 const Array& interpolate_arg = Array::Handle(Z, Array::New(1)); | 13474 const Array& interpolate_arg = Array::Handle(Z, Array::New(1)); |
13476 interpolate_arg.SetAt(0, value_arr); | 13475 interpolate_arg.SetAt(0, value_arr); |
13477 | 13476 |
13478 // Call interpolation function. | 13477 // Call interpolation function. |
13479 Object& result = Object::Handle(Z); | 13478 Object& result = Object::Handle(Z); |
13480 { | 13479 { |
13481 PAUSETIMERSCOPE(I, time_compilation); | 13480 PAUSETIMERSCOPE(T, time_compilation); |
13482 result = DartEntry::InvokeFunction(func, interpolate_arg); | 13481 result = DartEntry::InvokeFunction(func, interpolate_arg); |
13483 } | 13482 } |
13484 if (result.IsUnhandledException()) { | 13483 if (result.IsUnhandledException()) { |
13485 ReportError("%s", Error::Cast(result).ToErrorCString()); | 13484 ReportError("%s", Error::Cast(result).ToErrorCString()); |
13486 } | 13485 } |
13487 String& concatenated = String::ZoneHandle(Z); | 13486 String& concatenated = String::ZoneHandle(Z); |
13488 concatenated ^= result.raw(); | 13487 concatenated ^= result.raw(); |
13489 concatenated = Symbols::New(concatenated); | 13488 concatenated = Symbols::New(concatenated); |
13490 return concatenated; | 13489 return concatenated; |
13491 } | 13490 } |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14187 void Parser::SkipQualIdent() { | 14186 void Parser::SkipQualIdent() { |
14188 ASSERT(IsIdentifier()); | 14187 ASSERT(IsIdentifier()); |
14189 ConsumeToken(); | 14188 ConsumeToken(); |
14190 if (CurrentToken() == Token::kPERIOD) { | 14189 if (CurrentToken() == Token::kPERIOD) { |
14191 ConsumeToken(); // Consume the kPERIOD token. | 14190 ConsumeToken(); // Consume the kPERIOD token. |
14192 ExpectIdentifier("identifier expected after '.'"); | 14191 ExpectIdentifier("identifier expected after '.'"); |
14193 } | 14192 } |
14194 } | 14193 } |
14195 | 14194 |
14196 } // namespace dart | 14195 } // namespace dart |
OLD | NEW |