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

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

Issue 8271008: Set type argument vector at run time in instantiated closure objects. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 years, 2 months 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
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 820 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 // opening parens. 831 // opening parens.
832 if (!var_seen && !parameter.is_final) { 832 if (!var_seen && !parameter.is_final) {
833 // The parsed parameter type is actually the function result type. 833 // The parsed parameter type is actually the function result type.
834 const Type& result_type = Type::Handle(parameter.type->raw()); 834 const Type& result_type = Type::Handle(parameter.type->raw());
835 // Finish parsing the function type parameter. 835 // Finish parsing the function type parameter.
836 ParamList func_params; 836 ParamList func_params;
837 const bool no_explicit_default_values = false; 837 const bool no_explicit_default_values = false;
838 ParseFormalParameterList(no_explicit_default_values, &func_params); 838 ParseFormalParameterList(no_explicit_default_values, &func_params);
839 // Change the name of the parameter type to be the signature of the 839 // Change the name of the parameter type to be the signature of the
840 // function type. 840 // function type.
841 // Note that the function type signature may involve parameters of a type
842 // that is a type parameter of the enclosing class, so we parameterize the
843 // signature with the type parameters of the enclosing class, if any.
844 // TODO(regis): Revisit if this is not the right thing to do.
845 const bool is_static = 841 const bool is_static =
846 current_function().IsNull() || current_function().is_static(); 842 current_function().IsNull() || current_function().is_static();
847 const Function& signature_function = Function::Handle( 843 const Function& signature_function = Function::Handle(
848 Function::New(*parameter.name, 844 Function::New(*parameter.name,
849 RawFunction::kSignatureFunction, 845 RawFunction::kSignatureFunction,
850 is_static, 846 is_static,
851 /* is_const = */ false, 847 /* is_const = */ false,
852 parameter.name_pos)); 848 parameter.name_pos));
853 signature_function.set_owner(current_class()); 849 signature_function.set_owner(current_class());
854 signature_function.set_result_type(result_type); 850 signature_function.set_result_type(result_type);
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 1119
1124 1120
1125 AstNode* Parser::CreateImplicitClosureNode(const Function& func, 1121 AstNode* Parser::CreateImplicitClosureNode(const Function& func,
1126 intptr_t token_pos, 1122 intptr_t token_pos,
1127 AstNode* receiver) { 1123 AstNode* receiver) {
1128 Function& implicit_closure_function = 1124 Function& implicit_closure_function =
1129 Function::ZoneHandle(func.ImplicitClosureFunction()); 1125 Function::ZoneHandle(func.ImplicitClosureFunction());
1130 if (receiver == NULL) { 1126 if (receiver == NULL) {
1131 return new ImplicitStaticClosureNode(token_pos, implicit_closure_function); 1127 return new ImplicitStaticClosureNode(token_pos, implicit_closure_function);
1132 } else { 1128 } else {
1129 // If we create an implicit instance closure from inside a closure of a
1130 // parameterized class, make sure that the receiver is captured as
1131 // instantiator.
1132 if (current_block_->scope->function_level() > 0) {
1133 const Class& signature_class = Class::Handle(func.signature_class());
1134 if (signature_class.IsParameterized()) {
1135 CaptureReceiver();
1136 }
1137 }
1133 return new ImplicitInstanceClosureNode(token_pos, 1138 return new ImplicitInstanceClosureNode(token_pos,
1134 implicit_closure_function, 1139 implicit_closure_function,
1135 receiver); 1140 receiver);
1136 } 1141 }
1137 } 1142 }
1138 1143
1139 1144
1140 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) { 1145 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) {
1141 const intptr_t field_pos = token_index_; 1146 const intptr_t field_pos = token_index_;
1142 const Class& super_class = Class::Handle(current_class().SuperClass()); 1147 const Class& super_class = Class::Handle(current_class().SuperClass());
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
1580 ParseConstructorRedirection(cls, receiver); 1585 ParseConstructorRedirection(cls, receiver);
1581 } else { 1586 } else {
1582 ParseInitializers(cls, receiver); 1587 ParseInitializers(cls, receiver);
1583 } 1588 }
1584 } 1589 }
1585 if (initialized_check_needed) { 1590 if (initialized_check_needed) {
1586 CheckConstFieldsInitialized(cls); 1591 CheckConstFieldsInitialized(cls);
1587 } 1592 }
1588 } 1593 }
1589 1594
1590 if (current_block_->scope->function_level() > 0) { 1595 if (FLAG_enable_type_checks &&
1596 (current_block_->scope->function_level() > 0)) {
1591 // We are parsing, but not compiling, a local function. 1597 // We are parsing, but not compiling, a local function.
1592 // The instantiator may be required at run time for generic type checks or 1598 // The instantiator may be required at run time for generic type checks.
1593 // allocation of generic types.
1594 if (current_class().IsParameterized() && 1599 if (current_class().IsParameterized() &&
1595 (!current_function().is_static() || 1600 (!current_function().is_static() ||
1596 current_function().IsInFactoryScope())) { 1601 current_function().IsInFactoryScope())) {
1597 // Make sure that the receiver of the enclosing instance function 1602 // Make sure that the receiver of the enclosing instance function
1598 // (or implicit first parameter of an enclosing factory) is marked as 1603 // (or implicit first parameter of an enclosing factory) is marked as
1599 // captured if type checks are enabled, because they may access the 1604 // captured if type checks are enabled, because they may access the
1600 // receiver to instantiate types. 1605 // receiver to instantiate types.
1601 if (FLAG_enable_type_checks) { 1606 CaptureReceiver();
1602 CaptureReceiver();
1603 }
1604 } 1607 }
1605 } 1608 }
1606 1609
1607 if (CurrentToken() == Token::kLBRACE) { 1610 if (CurrentToken() == Token::kLBRACE) {
1608 ConsumeToken(); 1611 ConsumeToken();
1609 ParseStatementSequence(); 1612 ParseStatementSequence();
1610 ExpectToken(Token::kRBRACE); 1613 ExpectToken(Token::kRBRACE);
1611 } else if (CurrentToken() == Token::kARROW) { 1614 } else if (CurrentToken() == Token::kARROW) {
1612 ConsumeToken(); 1615 ConsumeToken();
1613 intptr_t expr_pos = token_index_; 1616 intptr_t expr_pos = token_index_;
(...skipping 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after
3360 ASSERT(ident_pos >= 0); 3363 ASSERT(ident_pos >= 0);
3361 3364
3362 if (CurrentToken() != Token::kLPAREN) { 3365 if (CurrentToken() != Token::kLPAREN) {
3363 ErrorMsg("'(' expected"); 3366 ErrorMsg("'(' expected");
3364 } 3367 }
3365 Function& function = Function::ZoneHandle( 3368 Function& function = Function::ZoneHandle(
3366 Function::NewClosureFunction(*function_name, 3369 Function::NewClosureFunction(*function_name,
3367 current_function(), 3370 current_function(),
3368 token_index_)); 3371 token_index_));
3369 function.set_result_type(result_type); 3372 function.set_result_type(result_type);
3373
3374 // The function type does not need to be determined at compile time, unless
3375 // the closure is assigned to a function variable and type checks are enabled.
3376 // At run time, the function type is derived from the signature class of the
3377 // closure function and from the type arguments of the instantiator.
3378
3370 LocalVariable* function_variable = NULL; 3379 LocalVariable* function_variable = NULL;
3371 ParameterizedType& function_type = ParameterizedType::ZoneHandle(); 3380 ParameterizedType& function_type = ParameterizedType::ZoneHandle();
3372 if (variable_name != NULL) { 3381 if (variable_name != NULL) {
3373 // Add the function variable to the scope before parsing the function in 3382 // Since the function type depends on the signature of the closure function,
3374 // order to allow self reference from inside the function. 3383 // it cannot be determined before the formal parameter list of the closure
3375 // The type of the implicitly declared const variable is defined by the 3384 // function is parsed. Therefore, we set the function type to a new
3376 // local function signature class and the type arguments of the current 3385 // parameterized type to be patched after the actual type is known.
3377 // receiver (if in a non-static scope). However, the signature is not yet 3386 // We temporarily use the class of the Function interface.
3378 // known, since the formal parameter list is not parsed yet. Therefore, we
3379 // set the type to a new parameterized type to be patched after the actual
3380 // type is known. We temporarily use the class of the Function interface.
3381 const Class& unknown_signature_class = Class::Handle( 3387 const Class& unknown_signature_class = Class::Handle(
3382 Type::Handle(Type::FunctionInterface()).type_class()); 3388 Type::Handle(Type::FunctionInterface()).type_class());
3383 function_type = ParameterizedType::New(unknown_signature_class, 3389 function_type = ParameterizedType::New(unknown_signature_class,
3384 TypeArguments::Handle()); 3390 TypeArguments::Handle());
3385 function_type.set_is_finalized(); // No real finalization needed. 3391 function_type.set_is_finalized(); // No real finalization needed.
3392
3393 // Add the function variable to the scope before parsing the function in
3394 // order to allow self reference from inside the function.
3386 function_variable = new LocalVariable(ident_pos, 3395 function_variable = new LocalVariable(ident_pos,
3387 *variable_name, 3396 *variable_name,
3388 function_type); 3397 function_type);
3389 function_variable->set_is_final(); 3398 function_variable->set_is_final();
3390 ASSERT(current_block_ != NULL); 3399 ASSERT(current_block_ != NULL);
3391 ASSERT(current_block_->scope != NULL); 3400 ASSERT(current_block_->scope != NULL);
3392 if (!current_block_->scope->AddVariable(function_variable)) { 3401 if (!current_block_->scope->AddVariable(function_variable)) {
3393 ErrorMsg(ident_pos, "identifier '%s' already defined", 3402 ErrorMsg(ident_pos, "identifier '%s' already defined",
3394 function_variable->name().ToCString()); 3403 function_variable->name().ToCString());
3395 } 3404 }
(...skipping 17 matching lines...) Expand all
3413 library_.AddClass(signature_class); 3422 library_.AddClass(signature_class);
3414 } 3423 }
3415 ASSERT(!Function::Handle(signature_class.signature_function()).IsNull()); 3424 ASSERT(!Function::Handle(signature_class.signature_function()).IsNull());
3416 ASSERT(Class::Handle(function.signature_class()).IsNull()); 3425 ASSERT(Class::Handle(function.signature_class()).IsNull());
3417 function.set_signature_class(signature_class); 3426 function.set_signature_class(signature_class);
3418 3427
3419 // Local functions are not registered in the enclosing class, which is already 3428 // Local functions are not registered in the enclosing class, which is already
3420 // finalized. 3429 // finalized.
3421 ASSERT(current_class().is_finalized()); 3430 ASSERT(current_class().is_finalized());
3422 3431
3423 if (function_variable != NULL) { 3432 // Make sure that the instantiator is captured.
3424 ASSERT(function_variable->type().raw() == function_type.raw()); 3433 if (signature_class.IsParameterized() &&
3425 // Patch the function variable type now that the signature is known. 3434 (current_block_->scope->function_level() > 0)) {
3435 CaptureReceiver();
3436 }
3437
3438 if (variable_name != NULL) {
3439 // Patch the function type now that the signature is known.
3426 // We need to create a new type for proper finalization, since the existing 3440 // We need to create a new type for proper finalization, since the existing
3427 // type is already marked as finalized. 3441 // type is already marked as finalized.
3428 // TODO(regis): Set proper signature_type_arguments if in non-static scope 3442 TypeArguments& signature_type_arguments = TypeArguments::Handle();
3429 // and if the signature involves generic types. 3443 if (signature_class.IsParameterized()) {
3430 const TypeArguments& signature_type_arguments = TypeArguments::Handle(); 3444 const intptr_t num_type_params = signature_class.NumTypeParameters();
3445 const Array& type_params = Array::Handle(
3446 signature_class.type_parameters());
3447 signature_type_arguments = TypeArguments::NewTypeArray(num_type_params);
3448 String& type_param_name = String::Handle();
3449 Type& type_param = Type::Handle();
3450 for (int i = 0; i < num_type_params; i++) {
3451 type_param_name ^= type_params.At(i);
3452 type_param = Type::NewTypeParameter(i, type_param_name);
3453 signature_type_arguments.SetTypeAt(i, type_param);
3454 }
3455 }
3456 const ParameterizedType& actual_function_type = ParameterizedType::Handle(
3457 ParameterizedType::New(signature_class, signature_type_arguments));
3431 const String& errmsg = String::Handle( 3458 const String& errmsg = String::Handle(
3432 ClassFinalizer::FinalizeTypeWhileParsing(ParameterizedType::Handle( 3459 ClassFinalizer::FinalizeTypeWhileParsing(actual_function_type));
3433 ParameterizedType::New(signature_class,
3434 signature_type_arguments))));
3435 if (!errmsg.IsNull()) { 3460 if (!errmsg.IsNull()) {
3436 ErrorMsg(errmsg.ToCString()); 3461 ErrorMsg(errmsg.ToCString());
3437 } 3462 }
3463 // The call to ClassFinalizer::FinalizeTypeWhileParsing may have extended
3464 // the vector of type arguments.
3465 signature_type_arguments = actual_function_type.arguments();
3466 ASSERT(signature_type_arguments.IsNull() ||
3467 (signature_type_arguments.Length() ==
3468 signature_class.NumTypeArguments()));
3469 // The signature_class should not have changed.
3470 ASSERT(actual_function_type.type_class() == signature_class.raw());
3471
3472 // Now patch the function type of the variable.
3438 function_type.set_type_class(signature_class); 3473 function_type.set_type_class(signature_class);
3439 function_type.set_arguments(signature_type_arguments); 3474 function_type.set_arguments(signature_type_arguments);
3475
3476 // The function variable type should have been patched above.
3477 ASSERT((function_variable == NULL) ||
3478 (function_variable->type().raw() == function_type.raw()));
3440 } 3479 }
3441 3480
3442 // The code generator does not compile the closure function when visiting 3481 // The code generator does not compile the closure function when visiting
3443 // a ClosureNode. The generated code allocates a new Closure object containing 3482 // a ClosureNode. The generated code allocates a new Closure object containing
3444 // the current context. The type of the Closure object refers to the closure 3483 // the current context. The type of the Closure object refers to the closure
3445 // function, which will be compiled on first invocation of the closure object. 3484 // function, which will be compiled on first invocation of the closure object.
3446 // Therefore, we ignore the parsed default_parameter_values and the 3485 // Therefore, we ignore the parsed default_parameter_values and the
3447 // node_sequence representing the body of the closure function, which will be 3486 // node_sequence representing the body of the closure function, which will be
3448 // parsed again when compiled later. 3487 // parsed again when compiled later.
3449 // The only purpose of parsing the function now (besides reporting obvious 3488 // The only purpose of parsing the function now (besides reporting obvious
(...skipping 3532 matching lines...) Expand 10 before | Expand all | Expand 10 after
6982 } 7021 }
6983 7022
6984 7023
6985 void Parser::SkipNestedExpr() { 7024 void Parser::SkipNestedExpr() {
6986 const bool saved_mode = SetAllowFunctionLiterals(true); 7025 const bool saved_mode = SetAllowFunctionLiterals(true);
6987 SkipExpr(); 7026 SkipExpr();
6988 SetAllowFunctionLiterals(saved_mode); 7027 SetAllowFunctionLiterals(saved_mode);
6989 } 7028 }
6990 7029
6991 } // namespace dart 7030 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698