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 11040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11934 const int kNumArguments = 0; // no arguments. | 11933 const int kNumArguments = 0; // no arguments. |
11935 const Function& func = Function::Handle(Z, | 11934 const Function& func = Function::Handle(Z, |
11936 Resolver::ResolveStatic(field_owner, | 11935 Resolver::ResolveStatic(field_owner, |
11937 getter_name, | 11936 getter_name, |
11938 kNumArguments, | 11937 kNumArguments, |
11939 Object::empty_array())); | 11938 Object::empty_array())); |
11940 ASSERT(!func.IsNull()); | 11939 ASSERT(!func.IsNull()); |
11941 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); | 11940 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); |
11942 Object& const_value = Object::Handle(Z); | 11941 Object& const_value = Object::Handle(Z); |
11943 { | 11942 { |
11944 PAUSETIMERSCOPE(I, time_compilation); | 11943 PAUSETIMERSCOPE(T, time_compilation); |
11945 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); | 11944 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); |
11946 } | 11945 } |
11947 if (const_value.IsError()) { | 11946 if (const_value.IsError()) { |
11948 const Error& error = Error::Cast(const_value); | 11947 const Error& error = Error::Cast(const_value); |
11949 if (error.IsUnhandledException()) { | 11948 if (error.IsUnhandledException()) { |
11950 // An exception may not occur in every parse attempt, i.e., the | 11949 // An exception may not occur in every parse attempt, i.e., the |
11951 // generated AST is not deterministic. Therefore mark the function as | 11950 // generated AST is not deterministic. Therefore mark the function as |
11952 // not optimizable. | 11951 // not optimizable. |
11953 current_function().SetIsOptimizable(false); | 11952 current_function().SetIsOptimizable(false); |
11954 field.set_value(Object::null_instance()); | 11953 field.set_value(Object::null_instance()); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12015 for (int i = 0; i < arguments->length(); i++) { | 12014 for (int i = 0; i < arguments->length(); i++) { |
12016 AstNode* arg = arguments->NodeAt(i); | 12015 AstNode* arg = arguments->NodeAt(i); |
12017 // Arguments have been evaluated to a literal value already. | 12016 // Arguments have been evaluated to a literal value already. |
12018 ASSERT(arg->IsLiteralNode()); | 12017 ASSERT(arg->IsLiteralNode()); |
12019 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); | 12018 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); |
12020 } | 12019 } |
12021 const Array& args_descriptor = Array::Handle(Z, | 12020 const Array& args_descriptor = Array::Handle(Z, |
12022 ArgumentsDescriptor::New(num_arguments, arguments->names())); | 12021 ArgumentsDescriptor::New(num_arguments, arguments->names())); |
12023 Object& result = Object::Handle(Z); | 12022 Object& result = Object::Handle(Z); |
12024 { | 12023 { |
12025 PAUSETIMERSCOPE(I, time_compilation); | 12024 PAUSETIMERSCOPE(T, time_compilation); |
12026 result = DartEntry::InvokeFunction( | 12025 result = DartEntry::InvokeFunction( |
12027 constructor, arg_values, args_descriptor); | 12026 constructor, arg_values, args_descriptor); |
12028 } | 12027 } |
12029 if (result.IsError()) { | 12028 if (result.IsError()) { |
12030 // An exception may not occur in every parse attempt, i.e., the | 12029 // An exception may not occur in every parse attempt, i.e., the |
12031 // generated AST is not deterministic. Therefore mark the function as | 12030 // generated AST is not deterministic. Therefore mark the function as |
12032 // not optimizable. | 12031 // not optimizable. |
12033 current_function().SetIsOptimizable(false); | 12032 current_function().SetIsOptimizable(false); |
12034 if (result.IsUnhandledException()) { | 12033 if (result.IsUnhandledException()) { |
12035 return result.raw(); | 12034 return result.raw(); |
(...skipping 1440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13476 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); | 13475 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); |
13477 } | 13476 } |
13478 | 13477 |
13479 // Build argument array to pass to the interpolation function. | 13478 // Build argument array to pass to the interpolation function. |
13480 const Array& interpolate_arg = Array::Handle(Z, Array::New(1)); | 13479 const Array& interpolate_arg = Array::Handle(Z, Array::New(1)); |
13481 interpolate_arg.SetAt(0, value_arr); | 13480 interpolate_arg.SetAt(0, value_arr); |
13482 | 13481 |
13483 // Call interpolation function. | 13482 // Call interpolation function. |
13484 Object& result = Object::Handle(Z); | 13483 Object& result = Object::Handle(Z); |
13485 { | 13484 { |
13486 PAUSETIMERSCOPE(I, time_compilation); | 13485 PAUSETIMERSCOPE(T, time_compilation); |
13487 result = DartEntry::InvokeFunction(func, interpolate_arg); | 13486 result = DartEntry::InvokeFunction(func, interpolate_arg); |
13488 } | 13487 } |
13489 if (result.IsUnhandledException()) { | 13488 if (result.IsUnhandledException()) { |
13490 ReportError("%s", Error::Cast(result).ToErrorCString()); | 13489 ReportError("%s", Error::Cast(result).ToErrorCString()); |
13491 } | 13490 } |
13492 String& concatenated = String::ZoneHandle(Z); | 13491 String& concatenated = String::ZoneHandle(Z); |
13493 concatenated ^= result.raw(); | 13492 concatenated ^= result.raw(); |
13494 concatenated = Symbols::New(concatenated); | 13493 concatenated = Symbols::New(concatenated); |
13495 return concatenated; | 13494 return concatenated; |
13496 } | 13495 } |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14192 void Parser::SkipQualIdent() { | 14191 void Parser::SkipQualIdent() { |
14193 ASSERT(IsIdentifier()); | 14192 ASSERT(IsIdentifier()); |
14194 ConsumeToken(); | 14193 ConsumeToken(); |
14195 if (CurrentToken() == Token::kPERIOD) { | 14194 if (CurrentToken() == Token::kPERIOD) { |
14196 ConsumeToken(); // Consume the kPERIOD token. | 14195 ConsumeToken(); // Consume the kPERIOD token. |
14197 ExpectIdentifier("identifier expected after '.'"); | 14196 ExpectIdentifier("identifier expected after '.'"); |
14198 } | 14197 } |
14199 } | 14198 } |
14200 | 14199 |
14201 } // namespace dart | 14200 } // namespace dart |
OLD | NEW |