Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(565)

Side by Side Diff: runtime/vm/parser.cc

Issue 11360116: Pass closure object as first implicit argument to closure functions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/stub_code_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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, &params); 2306 ParseFormalParameterList(allow_explicit_default_values, &params);
2300 } else { 2307 } else {
(...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/stub_code_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698