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

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

Issue 2063933002: Always capture instantiator in async functions (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Merge branch 'master' into instant Created 4 years, 6 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
« no previous file with comments | « no previous file | no next file » | 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 #include "vm/flags.h" 6 #include "vm/flags.h"
7 7
8 #ifndef DART_PRECOMPILED_RUNTIME 8 #ifndef DART_PRECOMPILED_RUNTIME
9 9
10 #include "lib/invocation_mirror.h" 10 #include "lib/invocation_mirror.h"
(...skipping 6803 matching lines...) Expand 10 before | Expand all | Expand 10 after
6814 Type& signature_type = Type::Handle(Z, closure.SignatureType()); 6814 Type& signature_type = Type::Handle(Z, closure.SignatureType());
6815 signature_type ^= ClassFinalizer::FinalizeType( 6815 signature_type ^= ClassFinalizer::FinalizeType(
6816 current_class(), signature_type, ClassFinalizer::kCanonicalize); 6816 current_class(), signature_type, ClassFinalizer::kCanonicalize);
6817 closure.SetSignatureType(signature_type); 6817 closure.SetSignatureType(signature_type);
6818 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); 6818 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved());
6819 ASSERT(closure.NumParameters() == closure_params.parameters->length()); 6819 ASSERT(closure.NumParameters() == closure_params.parameters->length());
6820 } 6820 }
6821 OpenFunctionBlock(closure); 6821 OpenFunctionBlock(closure);
6822 AddFormalParamsToScope(&closure_params, current_block_->scope); 6822 AddFormalParamsToScope(&closure_params, current_block_->scope);
6823 async_temp_scope_ = current_block_->scope; 6823 async_temp_scope_ = current_block_->scope;
6824
6825 // Capture instantiator in case it may be needed to generate the type
6826 // check of the return value. (C.f. handling of Token::kRETURN.)
6827 ASSERT(FunctionLevel() > 0);
6828 if (I->type_checks() && IsInstantiatorRequired()) {
6829 CaptureInstantiator();
6830 }
6824 return closure.raw(); 6831 return closure.raw();
6825 } 6832 }
6826 6833
6827 6834
6828 void Parser::AddContinuationVariables() { 6835 void Parser::AddContinuationVariables() {
6829 // Add to current block's scope: 6836 // Add to current block's scope:
6830 // var :await_jump_var; 6837 // var :await_jump_var;
6831 // var :await_ctx_var; 6838 // var :await_ctx_var;
6832 LocalVariable* await_jump_var = new (Z) LocalVariable( 6839 LocalVariable* await_jump_var = new (Z) LocalVariable(
6833 TokenPosition::kNoSource, 6840 TokenPosition::kNoSource,
(...skipping 3304 matching lines...) Expand 10 before | Expand all | Expand 10 after
10138 if (current_function().IsGenerativeConstructor() && 10145 if (current_function().IsGenerativeConstructor() &&
10139 (function_level == 0)) { 10146 (function_level == 0)) {
10140 ReportError(expr_pos, 10147 ReportError(expr_pos,
10141 "return of a value is not allowed in constructors"); 10148 "return of a value is not allowed in constructors");
10142 } else if (current_function().IsGeneratorClosure() && 10149 } else if (current_function().IsGeneratorClosure() &&
10143 (function_level == 0)) { 10150 (function_level == 0)) {
10144 ReportError(expr_pos, "generator functions may not return a value"); 10151 ReportError(expr_pos, "generator functions may not return a value");
10145 } 10152 }
10146 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); 10153 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
10147 if (I->type_checks() && 10154 if (I->type_checks() &&
10148 (((function_level == 0) && current_function().IsAsyncClosure()) || 10155 (((function_level == 0) && current_function().IsAsyncClosure()))) {
10149 ((function_level > 0) && current_function().IsAsyncFunction()))) {
10150 // In checked mode, when the declared result type is Future<T>, verify 10156 // In checked mode, when the declared result type is Future<T>, verify
10151 // that the returned expression is of type T or Future<T> as follows: 10157 // that the returned expression is of type T or Future<T> as follows:
10152 // return temp = expr, temp is Future ? temp as Future<T> : temp as T; 10158 // return temp = expr, temp is Future ? temp as Future<T> : temp as T;
10153 // In case of a mismatch, we need a TypeError and not a CastError, so 10159 // In case of a mismatch, we need a TypeError and not a CastError, so
10154 // we do not actually implement an "as" test, but an "assignable" test. 10160 // we do not actually implement an "as" test, but an "assignable" test.
10155 Function& async_func = Function::Handle(Z, current_function().raw()); 10161 Function& async_func =
10156 if (function_level == 0) { 10162 Function::Handle(Z, current_function().parent_function());
10157 async_func = async_func.parent_function();
10158 }
10159 const AbstractType& result_type = 10163 const AbstractType& result_type =
10160 AbstractType::ZoneHandle(Z, async_func.result_type()); 10164 AbstractType::ZoneHandle(Z, async_func.result_type());
10161 const Class& future_class = 10165 const Class& future_class =
10162 Class::ZoneHandle(Z, I->object_store()->future_class()); 10166 Class::ZoneHandle(Z, I->object_store()->future_class());
10163 ASSERT(!future_class.IsNull()); 10167 ASSERT(!future_class.IsNull());
10164 if (result_type.type_class() == future_class.raw()) { 10168 if (result_type.type_class() == future_class.raw()) {
10165 const TypeArguments& result_type_args = 10169 const TypeArguments& result_type_args =
10166 TypeArguments::ZoneHandle(Z, result_type.arguments()); 10170 TypeArguments::ZoneHandle(Z, result_type.arguments());
10167 if (!result_type_args.IsNull() && (result_type_args.Length() == 1)) { 10171 if (!result_type_args.IsNull() && (result_type_args.Length() == 1)) {
10168 const AbstractType& result_type_arg = 10172 const AbstractType& result_type_arg =
10169 AbstractType::ZoneHandle(Z, result_type_args.TypeAt(0)); 10173 AbstractType::ZoneHandle(Z, result_type_args.TypeAt(0));
10170 if (function_level == 0) { 10174 LetNode* checked_expr = new(Z) LetNode(expr_pos);
10171 // Parsing and generating code for async closure. 10175 LocalVariable* temp = checked_expr->AddInitializer(expr);
10172 LetNode* checked_expr = new(Z) LetNode(expr_pos); 10176 temp->set_is_final();
10173 LocalVariable* temp = checked_expr->AddInitializer(expr); 10177 const AbstractType& future_type =
10174 temp->set_is_final(); 10178 AbstractType::ZoneHandle(Z, future_class.RareType());
10175 const AbstractType& future_type = 10179 AstNode* is_future = new(Z) LoadLocalNode(expr_pos, temp);
10176 AbstractType::ZoneHandle(Z, future_class.RareType()); 10180 is_future = new(Z) ComparisonNode(expr_pos,
10177 AstNode* is_future = new(Z) LoadLocalNode(expr_pos, temp); 10181 Token::kIS,
10178 is_future = new(Z) ComparisonNode(expr_pos, 10182 is_future,
10179 Token::kIS, 10183 new(Z) TypeNode(expr_pos,
10180 is_future, 10184 future_type));
10181 new(Z) TypeNode(expr_pos, 10185 AstNode* as_future_t = new(Z) LoadLocalNode(expr_pos, temp);
10182 future_type)); 10186 as_future_t = new(Z) AssignableNode(expr_pos,
10183 AstNode* as_future_t = new(Z) LoadLocalNode(expr_pos, temp); 10187 as_future_t,
10184 as_future_t = new(Z) AssignableNode(expr_pos, 10188 result_type,
10185 as_future_t, 10189 Symbols::FunctionResult());
10186 result_type, 10190 AstNode* as_t = new(Z) LoadLocalNode(expr_pos, temp);
10187 Symbols::FunctionResult()); 10191 as_t = new(Z) AssignableNode(expr_pos,
10188 AstNode* as_t = new(Z) LoadLocalNode(expr_pos, temp); 10192 as_t,
10189 as_t = new(Z) AssignableNode(expr_pos, 10193 result_type_arg,
10190 as_t, 10194 Symbols::FunctionResult());
10191 result_type_arg, 10195 checked_expr->AddNode(new(Z) ConditionalExprNode(expr_pos,
10192 Symbols::FunctionResult()); 10196 is_future,
10193 checked_expr->AddNode(new(Z) ConditionalExprNode(expr_pos, 10197 as_future_t,
10194 is_future, 10198 as_t));
10195 as_future_t, 10199 expr = checked_expr;
10196 as_t));
10197 expr = checked_expr;
10198 } else {
10199 // Parsing async function, but not generating async closure code.
10200 if (!result_type_arg.IsInstantiated()) {
10201 // Make sure that the instantiator is captured.
10202 CaptureInstantiator();
10203 }
10204 }
10205 } 10200 }
10206 } 10201 }
10207 } 10202 }
10208 statement = new(Z) ReturnNode(statement_pos, expr); 10203 statement = new(Z) ReturnNode(statement_pos, expr);
10209 } else { 10204 } else {
10210 if (current_function().IsSyncGenClosure() && 10205 if (current_function().IsSyncGenClosure() &&
10211 (FunctionLevel() == 0)) { 10206 (FunctionLevel() == 0)) {
10212 // In a synchronous generator, return without an expression 10207 // In a synchronous generator, return without an expression
10213 // returns false, signaling that the iterator terminates and 10208 // returns false, signaling that the iterator terminates and
10214 // did not yield a value. 10209 // did not yield a value.
(...skipping 4415 matching lines...) Expand 10 before | Expand all | Expand 10 after
14630 const ArgumentListNode& function_args, 14625 const ArgumentListNode& function_args,
14631 const LocalVariable* temp_for_last_arg, 14626 const LocalVariable* temp_for_last_arg,
14632 bool is_super_invocation) { 14627 bool is_super_invocation) {
14633 UNREACHABLE(); 14628 UNREACHABLE();
14634 return NULL; 14629 return NULL;
14635 } 14630 }
14636 14631
14637 } // namespace dart 14632 } // namespace dart
14638 14633
14639 #endif // DART_PRECOMPILED_RUNTIME 14634 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698