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 20 matching lines...) Expand all Loading... | |
31 #include "vm/scopes.h" | 31 #include "vm/scopes.h" |
32 #include "vm/stack_frame.h" | 32 #include "vm/stack_frame.h" |
33 #include "vm/symbols.h" | 33 #include "vm/symbols.h" |
34 #include "vm/tags.h" | 34 #include "vm/tags.h" |
35 #include "vm/timer.h" | 35 #include "vm/timer.h" |
36 #include "vm/zone.h" | 36 #include "vm/zone.h" |
37 | 37 |
38 namespace dart { | 38 namespace dart { |
39 | 39 |
40 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); | 40 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); |
41 DEFINE_FLAG(bool, enable_mirrors, true, | |
42 "Disable to make importing dart:mirrors an error."); | |
41 DEFINE_FLAG(bool, load_deferred_eagerly, false, | 43 DEFINE_FLAG(bool, load_deferred_eagerly, false, |
42 "Load deferred libraries eagerly."); | 44 "Load deferred libraries eagerly."); |
43 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 45 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
44 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); | 46 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); |
47 | |
48 DECLARE_FLAG(bool, lazy_dispatchers); | |
49 DECLARE_FLAG(bool, load_deferred_eagerly); | |
45 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 50 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
46 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 51 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
47 DEFINE_FLAG(bool, enable_mirrors, true, | |
48 "Disable to make importing dart:mirrors an error."); | |
49 DECLARE_FLAG(bool, lazy_dispatchers); | |
50 | 52 |
51 // Quick access to the current isolate and zone. | 53 // Quick access to the current isolate and zone. |
52 #define I (isolate()) | 54 #define I (isolate()) |
53 #define Z (zone()) | 55 #define Z (zone()) |
54 | 56 |
55 | 57 |
56 #if defined(DEBUG) | 58 #if defined(DEBUG) |
57 class TraceParser : public ValueObject { | 59 class TraceParser : public ValueObject { |
58 public: | 60 public: |
59 TraceParser(intptr_t token_pos, | 61 TraceParser(intptr_t token_pos, |
(...skipping 9993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10053 const Error& error = Error::Handle(Z, type.error()); | 10055 const Error& error = Error::Handle(Z, type.error()); |
10054 ASSERT(!error.IsNull()); | 10056 ASSERT(!error.IsNull()); |
10055 arguments->Add(new(Z) LiteralNode(type_pos, String::ZoneHandle(Z, | 10057 arguments->Add(new(Z) LiteralNode(type_pos, String::ZoneHandle(Z, |
10056 Symbols::New(error.ToErrorCString())))); | 10058 Symbols::New(error.ToErrorCString())))); |
10057 return MakeStaticCall(Symbols::TypeError(), | 10059 return MakeStaticCall(Symbols::TypeError(), |
10058 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 10060 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
10059 arguments); | 10061 arguments); |
10060 } | 10062 } |
10061 | 10063 |
10062 | 10064 |
10065 // If 'prefix' is not NULL, then it will be passed to _throwNewIfNotLoaded. | |
10063 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, | 10066 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, |
10064 const Class& cls, | 10067 const Class& cls, |
10065 const String& function_name, | 10068 const String& function_name, |
10066 ArgumentListNode* function_arguments, | 10069 ArgumentListNode* function_arguments, |
10067 InvocationMirror::Call im_call, | 10070 InvocationMirror::Call im_call, |
10068 InvocationMirror::Type im_type, | 10071 InvocationMirror::Type im_type, |
10069 const Function* func) { | 10072 const Function* func, |
10073 const LibraryPrefix* prefix) { | |
10070 ArgumentListNode* arguments = new(Z) ArgumentListNode(call_pos); | 10074 ArgumentListNode* arguments = new(Z) ArgumentListNode(call_pos); |
10075 | |
10076 String& method_name = String::Handle(); | |
10077 if (prefix == NULL) { | |
10078 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); | |
10079 } else { | |
10080 arguments->Add(new(Z) LiteralNode(call_pos, *prefix)); | |
10081 method_name = Library::PrivateCoreLibName( | |
10082 Symbols::ThrowNewIfNotLoaded()).raw(); | |
10083 } | |
10071 // Object receiver. | 10084 // Object receiver. |
10072 // If the function is external and dynamic, pass the actual receiver, | 10085 // If the function is external and dynamic, pass the actual receiver, |
10073 // otherwise, pass a class literal of the unresolved method's owner. | 10086 // otherwise, pass a class literal of the unresolved method's owner. |
10074 if ((func != NULL) && !func->IsNull() && | 10087 if ((func != NULL) && !func->IsNull() && |
10075 func->is_external() && !func->is_static()) { | 10088 func->is_external() && !func->is_static()) { |
10076 arguments->Add(LoadReceiver(func->token_pos())); | 10089 arguments->Add(LoadReceiver(func->token_pos())); |
10077 } else { | 10090 } else { |
10078 Type& type = Type::ZoneHandle(Z, | 10091 Type& type = Type::ZoneHandle(Z, |
10079 Type::New(cls, TypeArguments::Handle(Z), call_pos, Heap::kOld)); | 10092 Type::New(cls, TypeArguments::Handle(Z), call_pos, Heap::kOld)); |
10080 type ^= ClassFinalizer::FinalizeType( | 10093 type ^= ClassFinalizer::FinalizeType( |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10133 // descriptive string here and pass it as the only element of the | 10146 // descriptive string here and pass it as the only element of the |
10134 // "existingArgumentNames" array of the NoSuchMethodError constructor. | 10147 // "existingArgumentNames" array of the NoSuchMethodError constructor. |
10135 // TODO(13471): Separate the implementations of NoSuchMethodError | 10148 // TODO(13471): Separate the implementations of NoSuchMethodError |
10136 // between dart2js and VM. Update the constructor to accept a string | 10149 // between dart2js and VM. Update the constructor to accept a string |
10137 // describing the formal parameters of an incompatible call target. | 10150 // describing the formal parameters of an incompatible call target. |
10138 array = Array::New(1, Heap::kOld); | 10151 array = Array::New(1, Heap::kOld); |
10139 array.SetAt(0, String::Handle(Z, function.UserVisibleFormalParameters())); | 10152 array.SetAt(0, String::Handle(Z, function.UserVisibleFormalParameters())); |
10140 } | 10153 } |
10141 arguments->Add(new(Z) LiteralNode(call_pos, array)); | 10154 arguments->Add(new(Z) LiteralNode(call_pos, array)); |
10142 | 10155 |
10143 return MakeStaticCall(Symbols::NoSuchMethodError(), | 10156 return MakeStaticCall(Symbols::NoSuchMethodError(), method_name, arguments); |
10144 Library::PrivateCoreLibName(Symbols::ThrowNew()), | |
10145 arguments); | |
10146 } | 10157 } |
10147 | 10158 |
10148 | 10159 |
10149 AstNode* Parser::ParseBinaryExpr(int min_preced) { | 10160 AstNode* Parser::ParseBinaryExpr(int min_preced) { |
10150 TRACE_PARSER("ParseBinaryExpr"); | 10161 TRACE_PARSER("ParseBinaryExpr"); |
10151 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); | 10162 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); |
10152 AstNode* left_operand = ParseUnaryExpr(); | 10163 AstNode* left_operand = ParseUnaryExpr(); |
10153 if (left_operand->IsPrimaryNode() && | 10164 if (left_operand->IsPrimaryNode() && |
10154 (left_operand->AsPrimaryNode()->IsSuper())) { | 10165 (left_operand->AsPrimaryNode()->IsSuper())) { |
10155 ReportError(left_operand->token_pos(), "illegal use of 'super'"); | 10166 ReportError(left_operand->token_pos(), "illegal use of 'super'"); |
(...skipping 1653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11809 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { | 11820 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { |
11810 // Private names are not exported by libraries. The name mangling | 11821 // Private names are not exported by libraries. The name mangling |
11811 // of private names with a library-specific suffix usually ensures | 11822 // of private names with a library-specific suffix usually ensures |
11812 // that _x in library A is not found when looked up from library B. | 11823 // that _x in library A is not found when looked up from library B. |
11813 // In the pathological case where a library imports itself with | 11824 // In the pathological case where a library imports itself with |
11814 // a prefix, the name mangling would not help in hiding the private | 11825 // a prefix, the name mangling would not help in hiding the private |
11815 // name, so we need to explicitly reject private names here. | 11826 // name, so we need to explicitly reject private names here. |
11816 return NULL; | 11827 return NULL; |
11817 } | 11828 } |
11818 Object& obj = Object::Handle(Z); | 11829 Object& obj = Object::Handle(Z); |
11819 if (prefix.is_loaded()) { | 11830 if (prefix.is_loaded()) { |
hausner
2015/07/08 18:19:58
This should maybe be prefix.is_loaded() || FLAG_lo
srdjan
2015/07/09 16:41:44
Done.
| |
11820 obj = prefix.LookupObject(ident); | 11831 obj = prefix.LookupObject(ident); |
11821 } else { | 11832 } else { |
11822 // Remember that this function depends on an import prefix of an | 11833 // Remember that this function depends on an import prefix of an |
11823 // unloaded deferred library. Note that parsed_function() can be | 11834 // unloaded deferred library. Note that parsed_function() can be |
11824 // NULL when parsing expressions outside the scope of a function. | 11835 // NULL when parsing expressions outside the scope of a function. |
11825 if (parsed_function() != NULL) { | 11836 if (parsed_function() != NULL) { |
11826 parsed_function()->AddDeferredPrefix(prefix); | 11837 parsed_function()->AddDeferredPrefix(prefix); |
hausner
2015/07/08 18:19:58
It's not necessary (or even wrong) to make code de
srdjan
2015/07/09 16:41:44
By adding '|| FLAG_load_deferred_eagerly' above as
| |
11827 } | 11838 } |
11839 if (FLAG_load_deferred_eagerly) { | |
11840 obj = prefix.LookupObject(ident); | |
11841 } | |
11828 } | 11842 } |
11829 const bool is_deferred = prefix.is_deferred_load(); | 11843 const bool is_deferred = prefix.is_deferred_load(); |
11830 if (obj.IsNull()) { | 11844 if (obj.IsNull()) { |
11831 // Unresolved prefixed primary identifier. | 11845 // Unresolved prefixed primary identifier. |
11832 return NULL; | 11846 return NULL; |
11833 } else if (obj.IsClass()) { | 11847 } else if (obj.IsClass()) { |
11834 const Class& cls = Class::Cast(obj); | 11848 const Class& cls = Class::Cast(obj); |
11835 PrimaryNode* primary = | 11849 PrimaryNode* primary = |
11836 new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); | 11850 new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); |
11837 primary->set_is_deferred(is_deferred); | 11851 primary->set_is_deferred(is_deferred); |
(...skipping 1238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13076 CurrentToken() == Token::kLPAREN ? | 13090 CurrentToken() == Token::kLPAREN ? |
13077 InvocationMirror::kMethod : InvocationMirror::kGetter; | 13091 InvocationMirror::kMethod : InvocationMirror::kGetter; |
13078 primary = ThrowNoSuchMethodError(qual_ident_pos, | 13092 primary = ThrowNoSuchMethodError(qual_ident_pos, |
13079 current_class(), | 13093 current_class(), |
13080 qualified_name, | 13094 qualified_name, |
13081 NULL, // No arguments. | 13095 NULL, // No arguments. |
13082 InvocationMirror::kTopLevel, | 13096 InvocationMirror::kTopLevel, |
13083 call_type, | 13097 call_type, |
13084 NULL); // No existing function. | 13098 NULL); // No existing function. |
13085 } | 13099 } |
13100 } else if (FLAG_load_deferred_eagerly && prefix.is_deferred_load()) { | |
13101 // primary != NULL. | |
13102 String& qualified_name = String::ZoneHandle(Z, prefix.name()); | |
13103 qualified_name = String::Concat(qualified_name, Symbols::Dot()); | |
13104 qualified_name = String::Concat(qualified_name, ident); | |
13105 qualified_name = Symbols::New(qualified_name); | |
13106 InvocationMirror::Type call_type = | |
13107 CurrentToken() == Token::kLPAREN ? | |
13108 InvocationMirror::kMethod : InvocationMirror::kGetter; | |
13109 current_block_->statements->Add(ThrowNoSuchMethodError( | |
hausner
2015/07/08 18:19:58
Can you add a comment here that reminds that addin
srdjan
2015/07/09 16:41:44
Done.
| |
13110 qual_ident_pos, | |
13111 current_class(), | |
13112 qualified_name, | |
13113 NULL, // No arguments. | |
13114 InvocationMirror::kTopLevel, | |
13115 call_type, | |
13116 NULL, // No existing function. | |
13117 &prefix)); | |
13086 } | 13118 } |
13087 } | 13119 } |
13088 ASSERT(primary != NULL); | 13120 ASSERT(primary != NULL); |
13089 } else if (token == Token::kTHIS) { | 13121 } else if (token == Token::kTHIS) { |
13090 LocalVariable* local = LookupLocalScope(Symbols::This()); | 13122 LocalVariable* local = LookupLocalScope(Symbols::This()); |
13091 if (local == NULL) { | 13123 if (local == NULL) { |
13092 ReportError("receiver 'this' is not in scope"); | 13124 ReportError("receiver 'this' is not in scope"); |
13093 } | 13125 } |
13094 primary = new(Z) LoadLocalNode(TokenPos(), local); | 13126 primary = new(Z) LoadLocalNode(TokenPos(), local); |
13095 ConsumeToken(); | 13127 ConsumeToken(); |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13556 void Parser::SkipQualIdent() { | 13588 void Parser::SkipQualIdent() { |
13557 ASSERT(IsIdentifier()); | 13589 ASSERT(IsIdentifier()); |
13558 ConsumeToken(); | 13590 ConsumeToken(); |
13559 if (CurrentToken() == Token::kPERIOD) { | 13591 if (CurrentToken() == Token::kPERIOD) { |
13560 ConsumeToken(); // Consume the kPERIOD token. | 13592 ConsumeToken(); // Consume the kPERIOD token. |
13561 ExpectIdentifier("identifier expected after '.'"); | 13593 ExpectIdentifier("identifier expected after '.'"); |
13562 } | 13594 } |
13563 } | 13595 } |
13564 | 13596 |
13565 } // namespace dart | 13597 } // namespace dart |
OLD | NEW |