Chromium Code Reviews| 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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 124 } | 124 } |
| 125 | 125 |
| 126 | 126 |
| 127 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 127 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
| 128 ASSERT(node_sequence_ == NULL); | 128 ASSERT(node_sequence_ == NULL); |
| 129 ASSERT(node_sequence != NULL); | 129 ASSERT(node_sequence != NULL); |
| 130 node_sequence_ = node_sequence; | 130 node_sequence_ = node_sequence; |
| 131 } | 131 } |
| 132 | 132 |
| 133 | 133 |
| 134 LocalVariable* ParsedFunction::GetSavedArgumentsDescriptorVar() const { | |
| 135 const int num_parameters = function().NumParameters(); | |
| 136 LocalScope* scope = node_sequence()->scope(); | |
| 137 if (scope->num_variables() > num_parameters) { | |
| 138 LocalVariable* saved_args_desc_var = scope->VariableAt(num_parameters); | |
| 139 ASSERT(saved_args_desc_var != NULL); | |
| 140 // The scope of the formal parameters may also contain at this position | |
| 141 // an alias for the saved arguments descriptor variable of the enclosing | |
| 142 // function (check its scope owner) or an internal variable such as the | |
| 143 // expression temp variable or the saved entry context variable (check its | |
| 144 // name). | |
| 145 if ((saved_args_desc_var->owner() == scope) && | |
| 146 saved_args_desc_var->name().StartsWith( | |
| 147 Symbols::SavedArgDescVarPrefix())) { | |
| 148 return saved_args_desc_var; | |
| 149 } | |
| 150 } | |
| 151 return NULL; | |
| 152 } | |
| 153 | |
| 154 | |
| 155 void ParsedFunction::AllocateVariables() { | 134 void ParsedFunction::AllocateVariables() { |
| 156 LocalScope* scope = node_sequence()->scope(); | 135 LocalScope* scope = node_sequence()->scope(); |
| 157 const intptr_t num_fixed_params = function().num_fixed_parameters(); | 136 const intptr_t num_fixed_params = function().num_fixed_parameters(); |
| 158 const intptr_t num_opt_params = function().NumOptionalParameters(); | 137 const intptr_t num_opt_params = function().NumOptionalParameters(); |
| 159 intptr_t num_params = num_fixed_params + num_opt_params; | 138 intptr_t num_params = num_fixed_params + num_opt_params; |
|
regis
2013/06/27 01:06:27
const?
Ivan Posva
2013/06/27 18:36:44
Done.
| |
| 160 // Compute start indices to parameters and locals, and the number of | 139 // Compute start indices to parameters and locals, and the number of |
| 161 // parameters to copy. | 140 // parameters to copy. |
| 162 if (num_opt_params == 0) { | 141 if (num_opt_params == 0) { |
| 163 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and | 142 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and |
| 164 // local variable j will be at fp[kFirstLocalSlotFromFp - j]. | 143 // local variable j will be at fp[kFirstLocalSlotFromFp - j]. |
| 165 ASSERT(GetSavedArgumentsDescriptorVar() == NULL); | |
| 166 first_parameter_index_ = kParamEndSlotFromFp + num_params; | 144 first_parameter_index_ = kParamEndSlotFromFp + num_params; |
| 167 first_stack_local_index_ = kFirstLocalSlotFromFp; | 145 first_stack_local_index_ = kFirstLocalSlotFromFp; |
| 168 num_copied_params_ = 0; | 146 num_copied_params_ = 0; |
| 169 } else { | 147 } else { |
| 170 // Parameter i will be at fp[kFirstLocalSlotFromFp - i] and local variable | 148 // Parameter i will be at fp[kFirstLocalSlotFromFp - i] and local variable |
| 171 // j will be at fp[kFirstLocalSlotFromFp - num_params - j]. | 149 // j will be at fp[kFirstLocalSlotFromFp - num_params - j]. |
| 172 // The saved arguments descriptor variable must be allocated similarly to | |
| 173 // a parameter, so that it gets both a frame slot and a context slot when | |
| 174 // captured. | |
| 175 if (GetSavedArgumentsDescriptorVar() != NULL) { | |
| 176 num_params += 1; | |
| 177 } | |
| 178 first_parameter_index_ = kFirstLocalSlotFromFp; | 150 first_parameter_index_ = kFirstLocalSlotFromFp; |
| 179 first_stack_local_index_ = first_parameter_index_ - num_params; | 151 first_stack_local_index_ = first_parameter_index_ - num_params; |
| 180 num_copied_params_ = num_params; | 152 num_copied_params_ = num_params; |
| 181 } | 153 } |
| 182 | 154 |
| 183 // Allocate parameters and local variables, either in the local frame or | 155 // Allocate parameters and local variables, either in the local frame or |
| 184 // in the context(s). | 156 // in the context(s). |
| 185 LocalScope* context_owner = NULL; // No context needed yet. | 157 LocalScope* context_owner = NULL; // No context needed yet. |
| 186 int next_free_frame_index = | 158 int next_free_frame_index = |
| 187 scope->AllocateVariables(first_parameter_index_, | 159 scope->AllocateVariables(first_parameter_index_, |
| (...skipping 7879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8067 LocalVariable* Parser::LookupLocalScope(const String& ident) { | 8039 LocalVariable* Parser::LookupLocalScope(const String& ident) { |
| 8068 if (current_block_ == NULL) { | 8040 if (current_block_ == NULL) { |
| 8069 return NULL; | 8041 return NULL; |
| 8070 } | 8042 } |
| 8071 // A found name is treated as accessed and possibly marked as captured. | 8043 // A found name is treated as accessed and possibly marked as captured. |
| 8072 const bool kTestOnly = false; | 8044 const bool kTestOnly = false; |
| 8073 return current_block_->scope->LookupVariable(ident, kTestOnly); | 8045 return current_block_->scope->LookupVariable(ident, kTestOnly); |
| 8074 } | 8046 } |
| 8075 | 8047 |
| 8076 | 8048 |
| 8077 // Returns true if ident resolves to a formal parameter of the current function | |
| 8078 // or of one of its enclosing functions. | |
| 8079 // Make sure not to capture the formal parameter, since it is not accessed. | |
| 8080 bool Parser::IsFormalParameter(const String& ident, | |
| 8081 Function* owner_function, | |
| 8082 LocalScope** owner_scope, | |
| 8083 intptr_t* local_index) { | |
| 8084 if (current_block_ == NULL) { | |
| 8085 return false; | |
| 8086 } | |
| 8087 if (ident.Equals(Symbols::This())) { | |
| 8088 // 'this' is not a formal parameter that can be tested with '?this'. | |
| 8089 return false; | |
| 8090 } | |
| 8091 // Since an argument definition test does not use the value of the formal | |
| 8092 // parameter, there is no reason to capture it. | |
| 8093 const bool kTestOnly = true; // No capturing. | |
| 8094 LocalVariable* local = | |
| 8095 current_block_->scope->LookupVariable(ident, kTestOnly); | |
| 8096 if ((local == NULL) || | |
| 8097 (local->owner()->HasContextLevel() && | |
| 8098 (local->owner()->context_level() < 1))) { | |
| 8099 if ((local == NULL) && !current_function().IsLocalFunction()) { | |
| 8100 // We are not generating code for a local function, so all locals, | |
| 8101 // captured or not, are in scope. However, 'ident' was not found, so it | |
| 8102 // does not exist. | |
| 8103 return false; | |
| 8104 } | |
| 8105 // The formal parameter belongs to an enclosing function and may not have | |
| 8106 // been captured, so it was not included in the context scope and it cannot | |
| 8107 // be found by LookupVariable. | |
| 8108 ASSERT((local == NULL) || local->is_captured()); | |
| 8109 // 'ident' necessarily refers to the formal parameter of one of the | |
| 8110 // enclosing functions, or a compile error would have prevented the | |
| 8111 // outermost enclosing function to be executed and we would not be compiling | |
| 8112 // this local function. | |
| 8113 // Therefore, look for ident directly in the formal parameter lists of the | |
| 8114 // enclosing functions. | |
| 8115 // There is no need to return the owner_scope, since the caller will not | |
| 8116 // create the saved_arguments_descriptor variable, which already exists. | |
| 8117 Function& function = Function::Handle(innermost_function().raw()); | |
| 8118 String& param_name = String::Handle(); | |
| 8119 do { | |
| 8120 const int num_parameters = function.NumParameters(); | |
| 8121 for (intptr_t i = 0; i < num_parameters; i++) { | |
| 8122 param_name = function.ParameterNameAt(i); | |
| 8123 if (ident.Equals(param_name)) { | |
| 8124 *owner_function = function.raw(); | |
| 8125 *owner_scope = NULL; | |
| 8126 *local_index = i; | |
| 8127 return true; | |
| 8128 } | |
| 8129 } | |
| 8130 function = function.parent_function(); | |
| 8131 } while (!function.IsNull()); | |
| 8132 UNREACHABLE(); | |
| 8133 } | |
| 8134 // Verify that local is a formal parameter of the current function or of one | |
| 8135 // of its enclosing functions. | |
| 8136 // Note that scopes are not yet associated to functions. | |
| 8137 Function& function = Function::Handle(innermost_function().raw()); | |
| 8138 LocalScope* scope = current_block_->scope; | |
| 8139 while (scope != NULL) { | |
| 8140 ASSERT(!function.IsNull()); | |
| 8141 // Find the top scope for this function level. | |
| 8142 while ((scope->parent() != NULL) && | |
| 8143 (scope->parent()->function_level() == scope->function_level())) { | |
| 8144 scope = scope->parent(); | |
| 8145 } | |
| 8146 if (scope == local->owner()) { | |
| 8147 // Scope contains 'local' and the formal parameters of 'function'. | |
| 8148 const int num_parameters = function.NumParameters(); | |
| 8149 for (intptr_t i = 0; i < num_parameters; i++) { | |
| 8150 if (scope->VariableAt(i) == local) { | |
| 8151 *owner_function = function.raw(); | |
| 8152 *owner_scope = scope; | |
| 8153 *local_index = i; | |
| 8154 return true; | |
| 8155 } | |
| 8156 } | |
| 8157 // The variable 'local' is not a formal parameter. | |
| 8158 return false; | |
| 8159 } | |
| 8160 scope = scope->parent(); | |
| 8161 function = function.parent_function(); | |
| 8162 } | |
| 8163 // The variable 'local' does not belong to a function top scope. | |
| 8164 return false; | |
| 8165 } | |
| 8166 | |
| 8167 | |
| 8168 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, | 8049 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, |
| 8169 const String& field_name) { | 8050 const String& field_name) { |
| 8170 // Fields are not accessible from a static function, except from a | 8051 // Fields are not accessible from a static function, except from a |
| 8171 // constructor, which is considered as non-static by the compiler. | 8052 // constructor, which is considered as non-static by the compiler. |
| 8172 if (current_function().is_static()) { | 8053 if (current_function().is_static()) { |
| 8173 ErrorMsg(field_pos, | 8054 ErrorMsg(field_pos, |
| 8174 "cannot access instance field '%s' from a static function", | 8055 "cannot access instance field '%s' from a static function", |
| 8175 field_name.ToCString()); | 8056 field_name.ToCString()); |
| 8176 } | 8057 } |
| 8177 } | 8058 } |
| (...skipping 1464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9642 values_list); | 9523 values_list); |
| 9643 interpolate_arg->Add(values); | 9524 interpolate_arg->Add(values); |
| 9644 primary = MakeStaticCall(Symbols::StringBase(), | 9525 primary = MakeStaticCall(Symbols::StringBase(), |
| 9645 PrivateCoreLibName(Symbols::Interpolate()), | 9526 PrivateCoreLibName(Symbols::Interpolate()), |
| 9646 interpolate_arg); | 9527 interpolate_arg); |
| 9647 } | 9528 } |
| 9648 return primary; | 9529 return primary; |
| 9649 } | 9530 } |
| 9650 | 9531 |
| 9651 | 9532 |
| 9652 AstNode* Parser::ParseArgumentDefinitionTest() { | |
| 9653 const intptr_t test_pos = TokenPos(); | |
| 9654 ConsumeToken(); | |
| 9655 const intptr_t ident_pos = TokenPos(); | |
| 9656 String* ident = ExpectIdentifier("parameter name expected"); | |
| 9657 Function& owner_function = Function::Handle(); | |
| 9658 LocalScope* owner_scope; | |
| 9659 intptr_t param_index; | |
| 9660 if (!IsFormalParameter(*ident, &owner_function, &owner_scope, ¶m_index)) { | |
| 9661 ErrorMsg(ident_pos, "formal parameter name expected"); | |
| 9662 } | |
| 9663 if (param_index < owner_function.num_fixed_parameters()) { | |
| 9664 // The formal parameter is not optional, therefore the corresponding | |
| 9665 // argument is always passed and defined. | |
| 9666 return new LiteralNode(test_pos, Bool::True()); | |
| 9667 } | |
| 9668 char name[64]; | |
| 9669 OS::SNPrint(name, 64, "%s_%"Pd"", | |
| 9670 Symbols::Name(Symbols::kSavedArgDescVarPrefixId), | |
| 9671 owner_function.token_pos()); | |
| 9672 const String& saved_args_desc_name = String::ZoneHandle(Symbols::New(name)); | |
| 9673 LocalVariable* saved_args_desc_var = LookupLocalScope(saved_args_desc_name); | |
| 9674 if (saved_args_desc_var == NULL) { | |
| 9675 ASSERT(owner_scope != NULL); | |
| 9676 saved_args_desc_var = | |
| 9677 new LocalVariable(owner_function.token_pos(), | |
| 9678 saved_args_desc_name, | |
| 9679 Type::ZoneHandle(Type::ArrayType())); | |
| 9680 saved_args_desc_var->set_is_final(); | |
| 9681 // The saved arguments descriptor variable must be added just after the | |
| 9682 // formal parameters. This simplifies the 2-step saving of a captured | |
| 9683 // arguments descriptor. | |
| 9684 // At this time, the owner scope should only contain formal parameters. | |
| 9685 ASSERT(owner_scope->num_variables() == owner_function.NumParameters()); | |
| 9686 bool success = owner_scope->AddVariable(saved_args_desc_var); | |
| 9687 ASSERT(success); | |
| 9688 // Capture the saved arguments descriptor variable if necessary. | |
| 9689 LocalVariable* local = LookupLocalScope(saved_args_desc_name); | |
| 9690 ASSERT(local == saved_args_desc_var); | |
| 9691 } | |
| 9692 // If we currently generate code for the local function of an enclosing owner | |
| 9693 // function, the saved arguments descriptor variable must have been captured | |
| 9694 // by the above lookup. | |
| 9695 ASSERT((owner_function.raw() == innermost_function().raw()) || | |
| 9696 saved_args_desc_var->is_captured()); | |
| 9697 const String& param_name = String::ZoneHandle(Symbols::New(*ident)); | |
| 9698 return new ArgumentDefinitionTestNode( | |
| 9699 test_pos, param_index, param_name, saved_args_desc_var); | |
| 9700 } | |
| 9701 | |
| 9702 | |
| 9703 AstNode* Parser::ParsePrimary() { | 9533 AstNode* Parser::ParsePrimary() { |
| 9704 TRACE_PARSER("ParsePrimary"); | 9534 TRACE_PARSER("ParsePrimary"); |
| 9705 ASSERT(!is_top_level_); | 9535 ASSERT(!is_top_level_); |
| 9706 AstNode* primary = NULL; | 9536 AstNode* primary = NULL; |
| 9707 if (IsFunctionLiteral()) { | 9537 if (IsFunctionLiteral()) { |
| 9708 // The name of a literal function is visible from inside the function, but | 9538 // The name of a literal function is visible from inside the function, but |
| 9709 // must not collide with names in the scope declaring the literal. | 9539 // must not collide with names in the scope declaring the literal. |
| 9710 OpenBlock(); | 9540 OpenBlock(); |
| 9711 primary = ParseFunctionStatement(true); | 9541 primary = ParseFunctionStatement(true); |
| 9712 CloseBlock(); | 9542 CloseBlock(); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9823 } else { | 9653 } else { |
| 9824 primary = ParseSuperFieldAccess(ident); | 9654 primary = ParseSuperFieldAccess(ident); |
| 9825 } | 9655 } |
| 9826 } else if ((CurrentToken() == Token::kLBRACK) || | 9656 } else if ((CurrentToken() == Token::kLBRACK) || |
| 9827 Token::CanBeOverloaded(CurrentToken()) || | 9657 Token::CanBeOverloaded(CurrentToken()) || |
| 9828 (CurrentToken() == Token::kNE)) { | 9658 (CurrentToken() == Token::kNE)) { |
| 9829 primary = ParseSuperOperator(); | 9659 primary = ParseSuperOperator(); |
| 9830 } else { | 9660 } else { |
| 9831 primary = new PrimaryNode(TokenPos(), Symbols::Super()); | 9661 primary = new PrimaryNode(TokenPos(), Symbols::Super()); |
| 9832 } | 9662 } |
| 9833 } else if (CurrentToken() == Token::kCONDITIONAL) { | |
| 9834 primary = ParseArgumentDefinitionTest(); | |
| 9835 } else { | 9663 } else { |
| 9836 UnexpectedToken(); | 9664 UnexpectedToken(); |
| 9837 } | 9665 } |
| 9838 return primary; | 9666 return primary; |
| 9839 } | 9667 } |
| 9840 | 9668 |
| 9841 | 9669 |
| 9842 // Evaluate expression in expr and return the value. The expression must | 9670 // Evaluate expression in expr and return the value. The expression must |
| 9843 // be a compile time constant. | 9671 // be a compile time constant. |
| 9844 const Instance& Parser::EvaluateConstExpr(AstNode* expr) { | 9672 const Instance& Parser::EvaluateConstExpr(AstNode* expr) { |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10024 } else { | 9852 } else { |
| 10025 SkipNewOperator(); | 9853 SkipNewOperator(); |
| 10026 } | 9854 } |
| 10027 break; | 9855 break; |
| 10028 case Token::kLT: | 9856 case Token::kLT: |
| 10029 case Token::kLBRACE: | 9857 case Token::kLBRACE: |
| 10030 case Token::kLBRACK: | 9858 case Token::kLBRACK: |
| 10031 case Token::kINDEX: | 9859 case Token::kINDEX: |
| 10032 SkipCompoundLiteral(); | 9860 SkipCompoundLiteral(); |
| 10033 break; | 9861 break; |
| 10034 case Token::kCONDITIONAL: | |
| 10035 ConsumeToken(); | |
| 10036 if (IsIdentifier()) { | |
| 10037 ConsumeToken(); | |
| 10038 } | |
| 10039 break; | |
| 10040 default: | 9862 default: |
| 10041 if (IsIdentifier()) { | 9863 if (IsIdentifier()) { |
| 10042 ConsumeToken(); // Handle pseudo-keyword identifiers. | 9864 ConsumeToken(); // Handle pseudo-keyword identifiers. |
| 10043 } else { | 9865 } else { |
| 10044 UnexpectedToken(); | 9866 UnexpectedToken(); |
| 10045 UNREACHABLE(); | 9867 UNREACHABLE(); |
| 10046 } | 9868 } |
| 10047 break; | 9869 break; |
| 10048 } | 9870 } |
| 10049 } | 9871 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10152 void Parser::SkipQualIdent() { | 9974 void Parser::SkipQualIdent() { |
| 10153 ASSERT(IsIdentifier()); | 9975 ASSERT(IsIdentifier()); |
| 10154 ConsumeToken(); | 9976 ConsumeToken(); |
| 10155 if (CurrentToken() == Token::kPERIOD) { | 9977 if (CurrentToken() == Token::kPERIOD) { |
| 10156 ConsumeToken(); // Consume the kPERIOD token. | 9978 ConsumeToken(); // Consume the kPERIOD token. |
| 10157 ExpectIdentifier("identifier expected after '.'"); | 9979 ExpectIdentifier("identifier expected after '.'"); |
| 10158 } | 9980 } |
| 10159 } | 9981 } |
| 10160 | 9982 |
| 10161 } // namespace dart | 9983 } // namespace dart |
| OLD | NEW |