| 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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 } | 147 } |
| 148 return NULL; | 148 return NULL; |
| 149 } | 149 } |
| 150 | 150 |
| 151 | 151 |
| 152 void ParsedFunction::AllocateVariables() { | 152 void ParsedFunction::AllocateVariables() { |
| 153 LocalScope* scope = node_sequence()->scope(); | 153 LocalScope* scope = node_sequence()->scope(); |
| 154 const intptr_t num_fixed_params = function().num_fixed_parameters(); | 154 const intptr_t num_fixed_params = function().num_fixed_parameters(); |
| 155 const intptr_t num_opt_params = function().NumOptionalParameters(); | 155 const intptr_t num_opt_params = function().NumOptionalParameters(); |
| 156 intptr_t num_params = num_fixed_params + num_opt_params; | 156 intptr_t num_params = num_fixed_params + num_opt_params; |
| 157 const bool is_native_instance_closure = | |
| 158 function().is_native() && function().IsImplicitInstanceClosureFunction(); | |
| 159 // Compute start indices to parameters and locals, and the number of | 157 // Compute start indices to parameters and locals, and the number of |
| 160 // parameters to copy. | 158 // parameters to copy. |
| 161 if ((num_opt_params == 0) && !is_native_instance_closure) { | 159 if (num_opt_params == 0) { |
| 162 // Parameter i will be at fp[1 + num_params - i] and local variable | 160 // Parameter i will be at fp[1 + num_params - i] and local variable |
| 163 // j will be at fp[kFirstLocalSlotIndex - j]. | 161 // j will be at fp[kFirstLocalSlotIndex - j]. |
| 164 ASSERT(GetSavedArgumentsDescriptorVar() == NULL); | 162 ASSERT(GetSavedArgumentsDescriptorVar() == NULL); |
| 165 first_parameter_index_ = 1 + num_params; | 163 first_parameter_index_ = 1 + num_params; |
| 166 first_stack_local_index_ = kFirstLocalSlotIndex; | 164 first_stack_local_index_ = kFirstLocalSlotIndex; |
| 167 num_copied_params_ = 0; | 165 num_copied_params_ = 0; |
| 168 } else { | 166 } else { |
| 169 // Parameter i will be at fp[kFirstLocalSlotIndex - i] and local variable | 167 // Parameter i will be at fp[kFirstLocalSlotIndex - i] and local variable |
| 170 // j will be at fp[kFirstLocalSlotIndex - num_params - j]. | 168 // j will be at fp[kFirstLocalSlotIndex - num_params - j]. |
| 171 // The saved argument descriptor variable must be allocated similarly to | 169 // The saved argument descriptor variable must be allocated similarly to |
| 172 // a parameter, so that it gets both a frame slot and a context slot when | 170 // a parameter, so that it gets both a frame slot and a context slot when |
| 173 // captured. | 171 // captured. |
| 174 if (GetSavedArgumentsDescriptorVar() != NULL) { | 172 if (GetSavedArgumentsDescriptorVar() != NULL) { |
| 175 num_params += 1; | 173 num_params += 1; |
| 176 } | 174 } |
| 177 first_parameter_index_ = kFirstLocalSlotIndex; | 175 first_parameter_index_ = kFirstLocalSlotIndex; |
| 178 first_stack_local_index_ = first_parameter_index_ - num_params; | 176 first_stack_local_index_ = first_parameter_index_ - num_params; |
| 179 num_copied_params_ = num_params; | 177 num_copied_params_ = num_params; |
| 180 if (is_native_instance_closure) { | |
| 181 num_copied_params_ += 1; | |
| 182 first_parameter_index_ -= 1; | |
| 183 first_stack_local_index_ -= 1; | |
| 184 } | |
| 185 } | 178 } |
| 186 | 179 |
| 187 // Allocate parameters and local variables, either in the local frame or | 180 // Allocate parameters and local variables, either in the local frame or |
| 188 // in the context(s). | 181 // in the context(s). |
| 189 LocalScope* context_owner = NULL; // No context needed yet. | 182 LocalScope* context_owner = NULL; // No context needed yet. |
| 190 int next_free_frame_index = | 183 int next_free_frame_index = |
| 191 scope->AllocateVariables(first_parameter_index_, | 184 scope->AllocateVariables(first_parameter_index_, |
| 192 num_params, | 185 num_params, |
| 193 first_stack_local_index_, | 186 first_stack_local_index_, |
| 194 scope, | 187 scope, |
| (...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1162 // This parameter is probably a closure. If we saw the keyword 'var' | 1155 // This parameter is probably a closure. If we saw the keyword 'var' |
| 1163 // or 'final', a closure is not legal here and we ignore the | 1156 // or 'final', a closure is not legal here and we ignore the |
| 1164 // opening parens. | 1157 // opening parens. |
| 1165 if (!var_seen && !parameter.is_final) { | 1158 if (!var_seen && !parameter.is_final) { |
| 1166 // The parsed parameter type is actually the function result type. | 1159 // The parsed parameter type is actually the function result type. |
| 1167 const AbstractType& result_type = | 1160 const AbstractType& result_type = |
| 1168 AbstractType::Handle(parameter.type->raw()); | 1161 AbstractType::Handle(parameter.type->raw()); |
| 1169 | 1162 |
| 1170 // Finish parsing the function type parameter. | 1163 // Finish parsing the function type parameter. |
| 1171 ParamList func_params; | 1164 ParamList func_params; |
| 1165 |
| 1166 // Add implicit closure object parameter. |
| 1167 func_params.AddFinalParameter( |
| 1168 TokenPos(), |
| 1169 &String::ZoneHandle(Symbols::ClosureParameter()), |
| 1170 &Type::ZoneHandle(Type::DynamicType())); |
| 1171 |
| 1172 const bool no_explicit_default_values = false; | 1172 const bool no_explicit_default_values = false; |
| 1173 ParseFormalParameterList(no_explicit_default_values, &func_params); | 1173 ParseFormalParameterList(no_explicit_default_values, &func_params); |
| 1174 | 1174 |
| 1175 // The field 'is_static' has no meaning for signature functions. | 1175 // The field 'is_static' has no meaning for signature functions. |
| 1176 const Function& signature_function = Function::Handle( | 1176 const Function& signature_function = Function::Handle( |
| 1177 Function::New(*parameter.name, | 1177 Function::New(*parameter.name, |
| 1178 RawFunction::kSignatureFunction, | 1178 RawFunction::kSignatureFunction, |
| 1179 /* is_static = */ false, | 1179 /* is_static = */ false, |
| 1180 /* is_const = */ false, | 1180 /* is_const = */ false, |
| 1181 /* is_abstract = */ false, | 1181 /* is_abstract = */ false, |
| (...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2272 if (func.IsConstructor()) { | 2272 if (func.IsConstructor()) { |
| 2273 SequenceNode* statements = ParseConstructor(func, default_parameter_values); | 2273 SequenceNode* statements = ParseConstructor(func, default_parameter_values); |
| 2274 innermost_function_ = saved_innermost_function.raw(); | 2274 innermost_function_ = saved_innermost_function.raw(); |
| 2275 return statements; | 2275 return statements; |
| 2276 } | 2276 } |
| 2277 | 2277 |
| 2278 ASSERT(!func.IsConstructor()); | 2278 ASSERT(!func.IsConstructor()); |
| 2279 OpenFunctionBlock(func); // Build local scope for function. | 2279 OpenFunctionBlock(func); // Build local scope for function. |
| 2280 | 2280 |
| 2281 ParamList params; | 2281 ParamList params; |
| 2282 // Static functions do not have a receiver. | 2282 // An instance closure function may capture and access the receiver, but via |
| 2283 // An instance closure may capture and access the receiver, but via the | 2283 // the context and not via the first formal parameter. |
| 2284 // context and not via the first formal parameter. | 2284 if (func.IsClosureFunction()) { |
| 2285 // The first parameter of a factory is the AbstractTypeArguments vector of | 2285 // The first parameter of a closure function is the closure object. |
| 2286 // the type of the instance to be allocated. | 2286 ASSERT(!func.is_const()); // Closure functions cannot be const. |
| 2287 if (!func.is_static() && !func.IsClosureFunction()) { | 2287 params.AddFinalParameter( |
| 2288 TokenPos(), |
| 2289 &String::ZoneHandle(Symbols::ClosureParameter()), |
| 2290 &Type::ZoneHandle(Type::DynamicType())); |
| 2291 } else if (!func.is_static()) { |
| 2292 // Static functions do not have a receiver. |
| 2288 ASSERT(current_class().raw() == func.Owner()); | 2293 ASSERT(current_class().raw() == func.Owner()); |
| 2289 params.AddReceiver(ReceiverType(TokenPos())); | 2294 params.AddReceiver(ReceiverType(TokenPos())); |
| 2290 } else if (func.IsFactory()) { | 2295 } else if (func.IsFactory()) { |
| 2296 // The first parameter of a factory is the AbstractTypeArguments vector of |
| 2297 // the type of the instance to be allocated. |
| 2291 params.AddFinalParameter( | 2298 params.AddFinalParameter( |
| 2292 TokenPos(), | 2299 TokenPos(), |
| 2293 &String::ZoneHandle(Symbols::TypeArgumentsParameter()), | 2300 &String::ZoneHandle(Symbols::TypeArgumentsParameter()), |
| 2294 &Type::ZoneHandle(Type::DynamicType())); | 2301 &Type::ZoneHandle(Type::DynamicType())); |
| 2295 } | 2302 } |
| 2296 ASSERT((CurrentToken() == Token::kLPAREN) || func.IsGetterFunction()); | 2303 ASSERT((CurrentToken() == Token::kLPAREN) || func.IsGetterFunction()); |
| 2297 const bool allow_explicit_default_values = true; | 2304 const bool allow_explicit_default_values = true; |
| 2298 if (!func.IsGetterFunction()) { | 2305 if (!func.IsGetterFunction()) { |
| 2299 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 2306 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
| 2300 } else { | 2307 } else { |
| (...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3429 if (!result_type.IsNull()) { | 3436 if (!result_type.IsNull()) { |
| 3430 ResolveTypeFromClass(alias_owner, | 3437 ResolveTypeFromClass(alias_owner, |
| 3431 ClassFinalizer::kTryResolve, | 3438 ClassFinalizer::kTryResolve, |
| 3432 &result_type); | 3439 &result_type); |
| 3433 } | 3440 } |
| 3434 // Parse the formal parameters of the function type. | 3441 // Parse the formal parameters of the function type. |
| 3435 if (CurrentToken() != Token::kLPAREN) { | 3442 if (CurrentToken() != Token::kLPAREN) { |
| 3436 ErrorMsg("formal parameter list expected"); | 3443 ErrorMsg("formal parameter list expected"); |
| 3437 } | 3444 } |
| 3438 ParamList func_params; | 3445 ParamList func_params; |
| 3446 |
| 3447 // Add implicit closure object parameter. |
| 3448 func_params.AddFinalParameter( |
| 3449 TokenPos(), |
| 3450 &String::ZoneHandle(Symbols::ClosureParameter()), |
| 3451 &Type::ZoneHandle(Type::DynamicType())); |
| 3452 |
| 3439 const bool no_explicit_default_values = false; | 3453 const bool no_explicit_default_values = false; |
| 3440 ParseFormalParameterList(no_explicit_default_values, &func_params); | 3454 ParseFormalParameterList(no_explicit_default_values, &func_params); |
| 3441 // The field 'is_static' has no meaning for signature functions. | 3455 // The field 'is_static' has no meaning for signature functions. |
| 3442 Function& signature_function = Function::Handle( | 3456 Function& signature_function = Function::Handle( |
| 3443 Function::New(*alias_name, | 3457 Function::New(*alias_name, |
| 3444 RawFunction::kSignatureFunction, | 3458 RawFunction::kSignatureFunction, |
| 3445 /* is_static = */ false, | 3459 /* is_static = */ false, |
| 3446 /* is_const = */ false, | 3460 /* is_const = */ false, |
| 3447 /* is_abstract = */ false, | 3461 /* is_abstract = */ false, |
| 3448 /* is_external = */ false, | 3462 /* is_external = */ false, |
| (...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4719 } | 4733 } |
| 4720 } | 4734 } |
| 4721 | 4735 |
| 4722 | 4736 |
| 4723 // Builds ReturnNode/NativeBodyNode for a native function. | 4737 // Builds ReturnNode/NativeBodyNode for a native function. |
| 4724 void Parser::ParseNativeFunctionBlock(const ParamList* params, | 4738 void Parser::ParseNativeFunctionBlock(const ParamList* params, |
| 4725 const Function& func) { | 4739 const Function& func) { |
| 4726 func.set_is_native(true); | 4740 func.set_is_native(true); |
| 4727 TRACE_PARSER("ParseNativeFunctionBlock"); | 4741 TRACE_PARSER("ParseNativeFunctionBlock"); |
| 4728 const Class& cls = Class::Handle(func.Owner()); | 4742 const Class& cls = Class::Handle(func.Owner()); |
| 4729 const int num_parameters = params->parameters->length(); | 4743 ASSERT(func.NumParameters() == params->parameters->length()); |
| 4730 const bool is_instance_closure = func.IsImplicitInstanceClosureFunction(); | |
| 4731 int num_params_for_resolution = num_parameters; | |
| 4732 | 4744 |
| 4733 // Parse the function name out. | 4745 // Parse the function name out. |
| 4734 const intptr_t native_pos = TokenPos(); | 4746 const intptr_t native_pos = TokenPos(); |
| 4735 const String& native_name = ParseNativeDeclaration(); | 4747 const String& native_name = ParseNativeDeclaration(); |
| 4736 | 4748 |
| 4737 if (is_instance_closure) { | |
| 4738 num_params_for_resolution += 1; // account for 'this' when resolving. | |
| 4739 } | |
| 4740 // Now resolve the native function to the corresponding native entrypoint. | 4749 // Now resolve the native function to the corresponding native entrypoint. |
| 4750 const int num_params = NativeArguments::ParameterCountForResolution(func); |
| 4741 NativeFunction native_function = NativeEntry::ResolveNative( | 4751 NativeFunction native_function = NativeEntry::ResolveNative( |
| 4742 cls, native_name, num_params_for_resolution); | 4752 cls, native_name, num_params); |
| 4743 if (native_function == NULL) { | 4753 if (native_function == NULL) { |
| 4744 ErrorMsg(native_pos, "native function '%s' cannot be found", | 4754 ErrorMsg(native_pos, "native function '%s' cannot be found", |
| 4745 native_name.ToCString()); | 4755 native_name.ToCString()); |
| 4746 } | 4756 } |
| 4747 | 4757 |
| 4748 const bool has_opt_params = (params->num_optional_parameters > 0); | |
| 4749 | |
| 4750 // Now add the NativeBodyNode and return statement. | 4758 // Now add the NativeBodyNode and return statement. |
| 4751 current_block_->statements->Add( | 4759 current_block_->statements->Add( |
| 4752 new ReturnNode(TokenPos(), new NativeBodyNode(TokenPos(), | 4760 new ReturnNode(TokenPos(), |
| 4753 native_name, | 4761 new NativeBodyNode(TokenPos(), |
| 4754 native_function, | 4762 Function::ZoneHandle(func.raw()), |
| 4755 num_parameters, | 4763 native_name, |
| 4756 has_opt_params, | 4764 native_function))); |
| 4757 is_instance_closure))); | |
| 4758 } | 4765 } |
| 4759 | 4766 |
| 4760 | 4767 |
| 4761 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { | 4768 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { |
| 4762 ASSERT(!current_function().is_static()); | 4769 ASSERT(!current_function().is_static()); |
| 4763 const String& this_name = String::Handle(Symbols::This()); | 4770 const String& this_name = String::Handle(Symbols::This()); |
| 4764 return from_scope->LookupVariable(this_name, test_only); | 4771 return from_scope->LookupVariable(this_name, test_only); |
| 4765 } | 4772 } |
| 4766 | 4773 |
| 4767 | 4774 |
| (...skipping 5183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9951 void Parser::SkipQualIdent() { | 9958 void Parser::SkipQualIdent() { |
| 9952 ASSERT(IsIdentifier()); | 9959 ASSERT(IsIdentifier()); |
| 9953 ConsumeToken(); | 9960 ConsumeToken(); |
| 9954 if (CurrentToken() == Token::kPERIOD) { | 9961 if (CurrentToken() == Token::kPERIOD) { |
| 9955 ConsumeToken(); // Consume the kPERIOD token. | 9962 ConsumeToken(); // Consume the kPERIOD token. |
| 9956 ExpectIdentifier("identifier expected after '.'"); | 9963 ExpectIdentifier("identifier expected after '.'"); |
| 9957 } | 9964 } |
| 9958 } | 9965 } |
| 9959 | 9966 |
| 9960 } // namespace dart | 9967 } // namespace dart |
| OLD | NEW |