| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent bc664cb commit d22346d
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,7 +11,7 @@ | |||
| 11 | 11 | #define V8_MAJOR_VERSION 5 | |
| 12 | 12 | #define V8_MINOR_VERSION 5 | |
| 13 | 13 | #define V8_BUILD_NUMBER 372 | |
| 14 | - #define V8_PATCH_LEVEL 42 | ||
| 14 | + #define V8_PATCH_LEVEL 43 | ||
| 15 | 15 | ||
| 16 | 16 | // Use 1 for candidates and 0 otherwise. | |
| 17 | 17 | // (Boolean macro values are not supported by all preprocessors.) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -411,14 +411,23 @@ class ParserBase { | |||
| 411 | 411 | } | |
| 412 | 412 | ||
| 413 | 413 | void set_promise_variable(typename Types::Variable* variable) { | |
| 414 | - DCHECK(variable != NULL); | ||
| 414 | + DCHECK_NOT_NULL(variable); | ||
| 415 | 415 | DCHECK(IsAsyncFunction(kind())); | |
| 416 | 416 | promise_variable_ = variable; | |
| 417 | 417 | } | |
| 418 | 418 | typename Types::Variable* promise_variable() const { | |
| 419 | 419 | return promise_variable_; | |
| 420 | 420 | } | |
| 421 | 421 | ||
| 422 | + void set_async_return_variable(typename Types::Variable* variable) { | ||
| 423 | + DCHECK_NOT_NULL(variable); | ||
| 424 | + DCHECK(IsAsyncFunction(kind())); | ||
| 425 | + async_return_variable_ = variable; | ||
| 426 | + } | ||
| 427 | + typename Types::Variable* async_return_variable() const { | ||
| 428 | + return async_return_variable_; | ||
| 429 | + } | ||
| 430 | + | ||
| 422 | 431 | const ZoneList<DestructuringAssignment>& | |
| 423 | 432 | destructuring_assignments_to_rewrite() const { | |
| 424 | 433 | return destructuring_assignments_to_rewrite_; | |
@@ -488,6 +497,8 @@ class ParserBase { | |||
| 488 | 497 | // For async functions, this variable holds a temporary for the Promise | |
| 489 | 498 | // being created as output of the async function. | |
| 490 | 499 | Variable* promise_variable_; | |
| 500 | + Variable* async_return_variable_; | ||
| 501 | + Variable* is_rejection_variable_; | ||
| 491 | 502 | ||
| 492 | 503 | FunctionState** function_state_stack_; | |
| 493 | 504 | FunctionState* outer_function_state_; | |
@@ -1468,6 +1479,8 @@ ParserBase<Impl>::FunctionState::FunctionState( | |||
| 1468 | 1479 | expected_property_count_(0), | |
| 1469 | 1480 | generator_object_variable_(nullptr), | |
| 1470 | 1481 | promise_variable_(nullptr), | |
| 1482 | + async_return_variable_(nullptr), | ||
| 1483 | + is_rejection_variable_(nullptr), | ||
| 1471 | 1484 | function_state_stack_(function_state_stack), | |
| 1472 | 1485 | outer_function_state_(*function_state_stack), | |
| 1473 | 1486 | destructuring_assignments_to_rewrite_(16, scope->zone()), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1701,10 +1701,17 @@ Expression* Parser::RewriteReturn(Expression* return_value, int pos) { | |||
| 1701 | 1701 | return_value = factory()->NewConditional(is_undefined, ThisExpression(pos), | |
| 1702 | 1702 | is_object_conditional, pos); | |
| 1703 | 1703 | } | |
| 1704 | + | ||
| 1704 | 1705 | if (is_generator()) { | |
| 1705 | 1706 | return_value = BuildIteratorResult(return_value, true); | |
| 1706 | 1707 | } else if (is_async_function()) { | |
| 1707 | - return_value = BuildResolvePromise(return_value, return_value->position()); | ||
| 1708 | + // In an async function, | ||
| 1709 | + // return expr; | ||
| 1710 | + // is rewritten as | ||
| 1711 | + // return .async_return_value = expr; | ||
| 1712 | + return_value = factory()->NewAssignment( | ||
| 1713 | + Token::ASSIGN, factory()->NewVariableProxy(AsyncReturnVariable()), | ||
| 1714 | + return_value, kNoSourcePosition); | ||
| 1708 | 1715 | } | |
| 1709 | 1716 | return return_value; | |
| 1710 | 1717 | } | |
@@ -2991,72 +2998,168 @@ Block* Parser::BuildParameterInitializationBlock( | |||
| 2991 | 2998 | return init_block; | |
| 2992 | 2999 | } | |
| 2993 | 3000 | ||
| 3001 | + Block* Parser::BuildRejectPromiseOnExceptionForParameters(Block* inner_block) { | ||
| 3002 | + // .promise = %AsyncFunctionPromiseCreate(); | ||
| 3003 | + // try { | ||
| 3004 | + // <inner_block> | ||
| 3005 | + // } catch (.catch) { | ||
| 3006 | + // return %RejectPromise(.promise, .catch), .promise; | ||
| 3007 | + // } | ||
| 3008 | + Block* result = factory()->NewBlock(nullptr, 2, true, kNoSourcePosition); | ||
| 3009 | + { | ||
| 3010 | + // .promise = %AsyncFunctionPromiseCreate(); | ||
| 3011 | + Expression* create_promise = factory()->NewCallRuntime( | ||
| 3012 | + Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX, | ||
| 3013 | + new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition); | ||
| 3014 | + Assignment* assign_promise = factory()->NewAssignment( | ||
| 3015 | + Token::INIT, factory()->NewVariableProxy(PromiseVariable()), | ||
| 3016 | + create_promise, kNoSourcePosition); | ||
| 3017 | + Statement* set_promise = | ||
| 3018 | + factory()->NewExpressionStatement(assign_promise, kNoSourcePosition); | ||
| 3019 | + result->statements()->Add(set_promise, zone()); | ||
| 3020 | + } | ||
| 3021 | + // catch (.catch) { | ||
| 3022 | + // return %RejectPromise(.promise, .catch), .promise; | ||
| 3023 | + // } | ||
| 3024 | + Scope* catch_scope = NewScope(CATCH_SCOPE); | ||
| 3025 | + catch_scope->set_is_hidden(); | ||
| 3026 | + Variable* catch_variable = | ||
| 3027 | + catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, | ||
| 3028 | + kCreatedInitialized, NORMAL_VARIABLE); | ||
| 3029 | + Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | ||
| 3030 | + { | ||
| 3031 | + // return %RejectPromise(.promise, .catch), .promise; | ||
| 3032 | + Expression* reject_return_promise = factory()->NewBinaryOperation( | ||
| 3033 | + Token::COMMA, BuildRejectPromise(catch_variable), | ||
| 3034 | + factory()->NewVariableProxy(PromiseVariable(), kNoSourcePosition), | ||
| 3035 | + kNoSourcePosition); | ||
| 3036 | + catch_block->statements()->Add( | ||
| 3037 | + factory()->NewReturnStatement(reject_return_promise, kNoSourcePosition), | ||
| 3038 | + zone()); | ||
| 3039 | + } | ||
| 3040 | + TryStatement* try_catch_statement = | ||
| 3041 | + factory()->NewTryCatchStatementForAsyncAwait(inner_block, catch_scope, | ||
| 3042 | + catch_variable, catch_block, | ||
| 3043 | + kNoSourcePosition); | ||
| 3044 | + result->statements()->Add(try_catch_statement, zone()); | ||
| 3045 | + return result; | ||
| 3046 | + } | ||
| 3047 | + | ||
| 2994 | 3048 | Block* Parser::BuildRejectPromiseOnException(Block* inner_block, bool* ok) { | |
| 3049 | + // .is_rejection = false; | ||
| 2995 | 3050 | // .promise = %AsyncFunctionPromiseCreate(); | |
| 2996 | 3051 | // try { | |
| 2997 | 3052 | // <inner_block> | |
| 2998 | 3053 | // } catch (.catch) { | |
| 2999 | - // %RejectPromise(.promise, .catch); | ||
| 3000 | - // return .promise; | ||
| 3054 | + // .is_rejection = true; | ||
| 3055 | + // .async_return_value = .catch; | ||
| 3001 | 3056 | // } finally { | |
| 3057 | + // .is_rejection | ||
| 3058 | + // ? %RejectPromise(.promise, .async_return_value) | ||
| 3059 | + // : %ResolvePromise(.promise, .async_return_value); | ||
| 3002 | 3060 | // %AsyncFunctionPromiseRelease(.promise); | |
| 3061 | + // return .promise; | ||
| 3003 | 3062 | // } | |
| 3004 | - Block* result = factory()->NewBlock(nullptr, 2, true, kNoSourcePosition); | ||
| 3063 | + Block* result = factory()->NewBlock(nullptr, 3, true, kNoSourcePosition); | ||
| 3005 | 3064 | ||
| 3006 | - // .promise = %AsyncFunctionPromiseCreate(); | ||
| 3007 | - Statement* set_promise; | ||
| 3065 | + Variable* is_rejection_var = | ||
| 3066 | + scope()->NewTemporary(ast_value_factory()->empty_string()); | ||
| 3008 | 3067 | { | |
| 3068 | + // .is_rejection = false; | ||
| 3069 | + Assignment* set_is_rejection = factory()->NewAssignment( | ||
| 3070 | + Token::INIT, factory()->NewVariableProxy(is_rejection_var), | ||
| 3071 | + factory()->NewBooleanLiteral(false, kNoSourcePosition), | ||
| 3072 | + kNoSourcePosition); | ||
| 3073 | + result->statements()->Add( | ||
| 3074 | + factory()->NewExpressionStatement(set_is_rejection, kNoSourcePosition), | ||
| 3075 | + zone()); | ||
| 3076 | + // .promise = %AsyncFunctionPromiseCreate(); | ||
| 3009 | 3077 | Expression* create_promise = factory()->NewCallRuntime( | |
| 3010 | 3078 | Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX, | |
| 3011 | 3079 | new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition); | |
| 3012 | 3080 | Assignment* assign_promise = factory()->NewAssignment( | |
| 3013 | 3081 | Token::INIT, factory()->NewVariableProxy(PromiseVariable()), | |
| 3014 | 3082 | create_promise, kNoSourcePosition); | |
| 3015 | - set_promise = | ||
| 3083 | + Statement* set_promise = | ||
| 3016 | 3084 | factory()->NewExpressionStatement(assign_promise, kNoSourcePosition); | |
| 3085 | + result->statements()->Add(set_promise, zone()); | ||
| 3017 | 3086 | } | |
| 3018 | - result->statements()->Add(set_promise, zone()); | ||
| 3019 | 3087 | ||
| 3020 | - // catch (.catch) { return %RejectPromise(.promise, .catch), .promise } | ||
| 3088 | + // catch (.catch) { | ||
| 3089 | + // .is_rejection = true; | ||
| 3090 | + // .async_return_value = .catch; | ||
| 3091 | + // } | ||
| 3021 | 3092 | Scope* catch_scope = NewScope(CATCH_SCOPE); | |
| 3022 | 3093 | catch_scope->set_is_hidden(); | |
| 3023 | 3094 | Variable* catch_variable = | |
| 3024 | 3095 | catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, | |
| 3025 | 3096 | kCreatedInitialized, NORMAL_VARIABLE); | |
| 3026 | 3097 | Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | |
| 3027 | - | ||
| 3028 | - Expression* promise_reject = BuildRejectPromise( | ||
| 3029 | - factory()->NewVariableProxy(catch_variable), kNoSourcePosition); | ||
| 3030 | - ReturnStatement* return_promise_reject = | ||
| 3031 | - factory()->NewReturnStatement(promise_reject, kNoSourcePosition); | ||
| 3032 | - catch_block->statements()->Add(return_promise_reject, zone()); | ||
| 3098 | + { | ||
| 3099 | + // .is_rejection = true; | ||
| 3100 | + DCHECK_NOT_NULL(is_rejection_var); | ||
| 3101 | + Assignment* set_is_rejection = factory()->NewAssignment( | ||
| 3102 | + Token::ASSIGN, factory()->NewVariableProxy(is_rejection_var), | ||
| 3103 | + factory()->NewBooleanLiteral(true, kNoSourcePosition), | ||
| 3104 | + kNoSourcePosition); | ||
| 3105 | + catch_block->statements()->Add( | ||
| 3106 | + factory()->NewExpressionStatement(set_is_rejection, kNoSourcePosition), | ||
| 3107 | + zone()); | ||
| 3108 | + // .async_return_value = .catch; | ||
| 3109 | + Assignment* set_async_return_var = factory()->NewAssignment( | ||
| 3110 | + Token::ASSIGN, factory()->NewVariableProxy(AsyncReturnVariable()), | ||
| 3111 | + factory()->NewVariableProxy(catch_variable), kNoSourcePosition); | ||
| 3112 | + catch_block->statements()->Add(factory()->NewExpressionStatement( | ||
| 3113 | + set_async_return_var, kNoSourcePosition), | ||
| 3114 | + zone()); | ||
| 3115 | + } | ||
| 3033 | 3116 | ||
| 3034 | 3117 | TryStatement* try_catch_statement = | |
| 3035 | 3118 | factory()->NewTryCatchStatementForAsyncAwait(inner_block, catch_scope, | |
| 3036 | 3119 | catch_variable, catch_block, | |
| 3037 | 3120 | kNoSourcePosition); | |
| 3038 | - | ||
| 3039 | - // There is no TryCatchFinally node, so wrap it in an outer try/finally | ||
| 3040 | 3121 | Block* outer_try_block = | |
| 3041 | 3122 | factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | |
| 3042 | 3123 | outer_try_block->statements()->Add(try_catch_statement, zone()); | |
| 3043 | 3124 | ||
| 3044 | - // finally { %AsyncFunctionPromiseRelease(.promise) } | ||
| 3125 | + // finally { | ||
| 3126 | + // .is_rejection | ||
| 3127 | + // ? %RejectPromise(.promise, .async_return_value) | ||
| 3128 | + // : %ResolvePromise(.promise, .async_return_value); | ||
| 3129 | + // %AsyncFunctionPromiseRelease(.promise); | ||
| 3130 | + // return .promise; | ||
| 3131 | + // } | ||
| 3045 | 3132 | Block* finally_block = | |
| 3046 | 3133 | factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | |
| 3047 | 3134 | { | |
| 3135 | + // .is_rejection | ||
| 3136 | + // ? %RejectPromise(.promise, .async_return_value) | ||
| 3137 | + // : %ResolvePromise(.promise, .async_return_value); | ||
| 3138 | + Expression* resolve_or_reject_promise = | ||
| 3139 | + factory()->NewConditional(factory()->NewVariableProxy(is_rejection_var), | ||
| 3140 | + BuildRejectPromise(AsyncReturnVariable()), | ||
| 3141 | + BuildResolvePromise(), kNoSourcePosition); | ||
| 3142 | + finally_block->statements()->Add( | ||
| 3143 | + factory()->NewExpressionStatement(resolve_or_reject_promise, | ||
| 3144 | + kNoSourcePosition), | ||
| 3145 | + zone()); | ||
| 3146 | + // %AsyncFunctionPromiseRelease(.promise); | ||
| 3048 | 3147 | ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); | |
| 3049 | 3148 | args->Add(factory()->NewVariableProxy(PromiseVariable()), zone()); | |
| 3050 | 3149 | Expression* call_promise_release = factory()->NewCallRuntime( | |
| 3051 | 3150 | Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition); | |
| 3052 | 3151 | Statement* promise_release = factory()->NewExpressionStatement( | |
| 3053 | 3152 | call_promise_release, kNoSourcePosition); | |
| 3054 | 3153 | finally_block->statements()->Add(promise_release, zone()); | |
| 3154 | + | ||
| 3155 | + // return .promise; | ||
| 3156 | + Statement* return_promise = factory()->NewReturnStatement( | ||
| 3157 | + factory()->NewVariableProxy(PromiseVariable()), kNoSourcePosition); | ||
| 3158 | + finally_block->statements()->Add(return_promise, zone()); | ||
| 3055 | 3159 | } | |
| 3056 | 3160 | ||
| 3057 | 3161 | Statement* try_finally_statement = factory()->NewTryFinallyStatement( | |
| 3058 | 3162 | outer_try_block, finally_block, kNoSourcePosition); | |
| 3059 | - | ||
| 3060 | 3163 | result->statements()->Add(try_finally_statement, zone()); | |
| 3061 | 3164 | return result; | |
| 3062 | 3165 | } | |
@@ -3072,31 +3175,25 @@ Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) { | |||
| 3072 | 3175 | pos); | |
| 3073 | 3176 | } | |
| 3074 | 3177 | ||
| 3075 | - Expression* Parser::BuildResolvePromise(Expression* value, int pos) { | ||
| 3076 | - // %ResolvePromise(.promise, value), .promise | ||
| 3178 | + Expression* Parser::BuildResolvePromise() { | ||
| 3179 | + // %ResolvePromise(.promise, .async_return_variable), .promise | ||
| 3077 | 3180 | ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); | |
| 3078 | 3181 | args->Add(factory()->NewVariableProxy(PromiseVariable()), zone()); | |
| 3079 | - args->Add(value, zone()); | ||
| 3080 | - Expression* call_runtime = | ||
| 3081 | - factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, pos); | ||
| 3082 | - return factory()->NewBinaryOperation( | ||
| 3083 | - Token::COMMA, call_runtime, | ||
| 3084 | - factory()->NewVariableProxy(PromiseVariable()), pos); | ||
| 3182 | + args->Add(factory()->NewVariableProxy(AsyncReturnVariable()), zone()); | ||
| 3183 | + return factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, | ||
| 3184 | + kNoSourcePosition); | ||
| 3085 | 3185 | } | |
| 3086 | 3186 | ||
| 3087 | - Expression* Parser::BuildRejectPromise(Expression* value, int pos) { | ||
| 3088 | - // %RejectPromiseNoDebugEvent(.promise, value, true), .promise | ||
| 3187 | + Expression* Parser::BuildRejectPromise(Variable* value) { | ||
| 3188 | + // %RejectPromiseNoDebugEvent(.promise, .value, true) | ||
| 3089 | 3189 | // The NoDebugEvent variant disables the additional debug event for the | |
| 3090 | 3190 | // rejection since a debug event already happened for the exception that got | |
| 3091 | 3191 | // us here. | |
| 3092 | 3192 | ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); | |
| 3093 | 3193 | args->Add(factory()->NewVariableProxy(PromiseVariable()), zone()); | |
| 3094 | - args->Add(value, zone()); | ||
| 3095 | - Expression* call_runtime = factory()->NewCallRuntime( | ||
| 3096 | - Context::REJECT_PROMISE_NO_DEBUG_EVENT_INDEX, args, pos); | ||
| 3097 | - return factory()->NewBinaryOperation( | ||
| 3098 | - Token::COMMA, call_runtime, | ||
| 3099 | - factory()->NewVariableProxy(PromiseVariable()), pos); | ||
| 3194 | + args->Add(factory()->NewVariableProxy(value), zone()); | ||
| 3195 | + return factory()->NewCallRuntime( | ||
| 3196 | + Context::REJECT_PROMISE_NO_DEBUG_EVENT_INDEX, args, kNoSourcePosition); | ||
| 3100 | 3197 | } | |
| 3101 | 3198 | ||
| 3102 | 3199 | Variable* Parser::PromiseVariable() { | |
@@ -3111,6 +3208,19 @@ Variable* Parser::PromiseVariable() { | |||
| 3111 | 3208 | return promise; | |
| 3112 | 3209 | } | |
| 3113 | 3210 | ||
| 3211 | + Variable* Parser::AsyncReturnVariable() { | ||
| 3212 | + // Based on the various compilation paths, there are many different | ||
| 3213 | + // code paths which may be the first to access the return value | ||
| 3214 | + // temporary. Whichever comes first should create it and stash it in | ||
| 3215 | + // the FunctionState. | ||
| 3216 | + Variable* async_return = function_state_->async_return_variable(); | ||
| 3217 | + if (async_return == nullptr) { | ||
| 3218 | + async_return = scope()->NewTemporary(ast_value_factory()->empty_string()); | ||
| 3219 | + function_state_->set_async_return_variable(async_return); | ||
| 3220 | + } | ||
| 3221 | + return async_return; | ||
| 3222 | + } | ||
| 3223 | + | ||
| 3114 | 3224 | Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) { | |
| 3115 | 3225 | Expression* allocation = BuildCreateJSGeneratorObject(pos, kind); | |
| 3116 | 3226 | VariableProxy* init_proxy = | |
@@ -3235,7 +3345,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | |||
| 3235 | 3345 | ||
| 3236 | 3346 | // TODO(littledan): Merge the two rejection blocks into one | |
| 3237 | 3347 | if (IsAsyncFunction(kind)) { | |
| 3238 | - init_block = BuildRejectPromiseOnException(init_block, CHECK_OK); | ||
| 3348 | + init_block = BuildRejectPromiseOnExceptionForParameters(init_block); | ||
| 3239 | 3349 | } | |
| 3240 | 3350 | ||
| 3241 | 3351 | DCHECK_NOT_NULL(init_block); | |
@@ -4176,14 +4286,16 @@ void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block, | |||
| 4176 | 4286 | // .generator_object = %CreateGeneratorObject(); | |
| 4177 | 4287 | // BuildRejectPromiseOnException({ | |
| 4178 | 4288 | // ... block ... | |
| 4179 | - // return %ResolvePromise(.promise, expr), .promise; | ||
| 4289 | + // .async_return_var = expr; | ||
| 4180 | 4290 | // }) | |
| 4181 | 4291 | // } | |
| 4182 | 4292 | ||
| 4183 | - return_value = BuildResolvePromise(return_value, return_value->position()); | ||
| 4184 | - block->statements()->Add( | ||
| 4185 | - factory()->NewReturnStatement(return_value, return_value->position()), | ||
| 4186 | - zone()); | ||
| 4293 | + Assignment* set_async_return_var = factory()->NewAssignment( | ||
| 4294 | + Token::ASSIGN, factory()->NewVariableProxy(AsyncReturnVariable()), | ||
| 4295 | + return_value, kNoSourcePosition); | ||
| 4296 | + block->statements()->Add(factory()->NewExpressionStatement( | ||
| 4297 | + set_async_return_var, kNoSourcePosition), | ||
| 4298 | + zone()); | ||
| 4187 | 4299 | block = BuildRejectPromiseOnException(block, CHECK_OK_VOID); | |
| 4188 | 4300 | body->Add(block, zone()); | |
| 4189 | 4301 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -491,6 +491,7 @@ class Parser : public ParserBase<Parser> { | |||
| 491 | 491 | Block* BuildParameterInitializationBlock( | |
| 492 | 492 | const ParserFormalParameters& parameters, bool* ok); | |
| 493 | 493 | Block* BuildRejectPromiseOnException(Block* block, bool* ok); | |
| 494 | + Block* BuildRejectPromiseOnExceptionForParameters(Block* block); | ||
| 494 | 495 | ||
| 495 | 496 | // Consumes the ending }. | |
| 496 | 497 | ZoneList<Statement*>* ParseEagerFunctionBody( | |
@@ -576,9 +577,10 @@ class Parser : public ParserBase<Parser> { | |||
| 576 | 577 | ||
| 577 | 578 | Expression* BuildInitialYield(int pos, FunctionKind kind); | |
| 578 | 579 | Expression* BuildCreateJSGeneratorObject(int pos, FunctionKind kind); | |
| 579 | - Expression* BuildResolvePromise(Expression* value, int pos); | ||
| 580 | - Expression* BuildRejectPromise(Expression* value, int pos); | ||
| 580 | + Expression* BuildResolvePromise(); | ||
| 581 | + Expression* BuildRejectPromise(Variable* value); | ||
| 581 | 582 | Variable* PromiseVariable(); | |
| 583 | + Variable* AsyncReturnVariable(); | ||
| 582 | 584 | ||
| 583 | 585 | // Generic AST generator for throwing errors from compiled code. | |
| 584 | 586 | Expression* NewThrowError(Runtime::FunctionId function_id, | |
@@ -983,8 +985,7 @@ class Parser : public ParserBase<Parser> { | |||
| 983 | 985 | auto* init_block = BuildParameterInitializationBlock(parameters, ok); | |
| 984 | 986 | if (!*ok) return; | |
| 985 | 987 | if (is_async) { | |
| 986 | - init_block = BuildRejectPromiseOnException(init_block, ok); | ||
| 987 | - if (!*ok) return; | ||
| 988 | + init_block = BuildRejectPromiseOnExceptionForParameters(init_block); | ||
| 988 | 989 | } | |
| 989 | 990 | if (init_block != nullptr) body->Add(init_block, zone()); | |
| 990 | 991 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,14 @@ | |||
| 1 | + // Copyright 2017 the V8 project authors. All rights reserved. | ||
| 2 | + // Use of this source code is governed by a BSD-style license that can be | ||
| 3 | + // found in the LICENSE file. | ||
| 4 | + // Flags: --allow-natives-syntax | ||
| 5 | + async function foo() { | ||
| 6 | + try { | ||
| 7 | + return 1; | ||
| 8 | + } finally { | ||
| 9 | + return Promise.resolve().then(() => { return 2; }); | ||
| 10 | + } | ||
| 11 | + } | ||
| 12 | + foo() | ||
| 13 | + .then(value => { found = value; assertEquals(2, value) }) | ||
| 14 | + .catch((e) => { %AbortJS(''+e); }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments