-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[dart2wasm] Support try
/catch
/finally
in sync*
functions
#51343
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is being implemented in https://dart-review.googlesource.com/c/sdk/+/294480. |
In this implementation do we need separate blocks for An alternative is to have two variables (which can be combined into one) for the whole CFG:
In a finalizer, after running the finalizer code, we check (1). If it's non-zero we decrement it and continue with the parent finalizer. If it's zero we check (2). If the value is 0 we return. If it's 1 we rethrow. Otherwise the value minus one gives us the target block index (used in I don't know how easy it is to create a synthetic local currently (can I update We can also combine these two variables into one by adding a single |
We discussed this with @askeksa-google offline, I'm implementing the plan with two suspend state varibles described in my comment above. |
The approach I describe above does not work, we need a stack of continuation variables for nested finalizers. For example: (Code below is
Here in the nested finalizer we need to save parent finalizer's continuation and restore it on fallthrough (i.e. when the nested finalizer does not override the continuation with So we need a stack of continuation variables. This can be implemented by (conceptually) adding a local for each I think we still need a global (within a function) "number of finalizers to run" variable as described in my previous comment, to be able to implement The code that jumps to a finalizer block will set the finalizer's continuation variable. The only difference here is that we will have a variable specific to the finalizer block, not a single variable. Normally these continuation variables don't need to be in the context (heap-allocated sync/async function state) always, but currently we put all locals in the context, so I'll try a simpler implementation that doesn't require creating a kernel variable declaration for |
We can avoid this variable if we set continuation variables of all parent finalizers when changing control flow (instead of just the continuation variable of the parent finalizer). For example, |
We have a correct implementation of this in |
Hello @osa1! |
Hi @meg4cyberc4t. This is not really abandoned, we just had better things to work on as |
I'm fixing the remaining |
…x sync* This is the last part of the series of patches to implement missing sync* features and fix bugs. Move common code generation functions between async and sync* code generators to the state_machine library, with the name `StateMachineCodeGenerator`. This class allows overriding parts that differ between the async and sync* code generators. Fixes tests: - co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_sync_t05 - language/sync_star/generator3_test/test1 - language/sync_star/generator3_test/test2 - language/sync_star/sync_star_exception_iterator_test - language/sync_star/sync_star_exception_nested_test - language/sync_star/sync_star_exception_test - language/sync_star/sync_star_exception_current_test Fixes dart-lang#51343. Fixes dart-lang#51342.
…x sync* This is the last part of the series of patches to implement missing sync* features and fix bugs. Move common code generation functions between async and sync* code generators to the state_machine library, with the name `StateMachineCodeGenerator`. This class allows overriding parts that differ between the async and sync* code generators. Fixes tests: - co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_sync_t05 - language/sync_star/generator3_test/test1 - language/sync_star/generator3_test/test2 - language/sync_star/sync_star_exception_iterator_test - language/sync_star/sync_star_exception_nested_test - language/sync_star/sync_star_exception_test - language/sync_star/sync_star_exception_current_test Fixes dart-lang#51343. Fixes dart-lang#51342. Change-Id: Ife6eab43b2721b003ebf9bc0f03796748fd5df46
This cherry-picks commits: 6de879e - [dart2wasm] Fix exception handling in async functions 7e237a1 - [dart2wasm] Small refactoring in async code generator eabb2b3 - [dart2wasm] Catch JS exceptions in async functions e44bc22 - [dart2wasm] Fix bug in restoration of `this` in async functions. 350954a - [dart2wasm] Fix `this` restoration code in sync* handling. 8ccb412 - [dart2wasm] Move type parameter bounds checks & parameter type check logic together with logic setting up variables e7dde83 - [dart2wasm] Port VM fix for #52083 (sync*) 3863e78 - [dart2wasm] Move yield finder to a shared library 829261e - [dart2wasm] Move async compiler utilities to state_machine library fab56db - [dart2wasm] Move common code generation routines to state_machine, fix sync* Bugs: #55347, #55457, #51343, #51342 Cherry-pick: https://dart-review.googlesource.com/c/sdk/+/368300 Cherry-pick-request: #55847 Change-Id: I0a4186533fbdf4c5727911295ad48696a90f715f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/368300 Commit-Queue: Ömer Ağacan <[email protected]> Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Martin Kustermann <[email protected]>
The
sync*
implementation in dart2wasm currently does not supporttry
statements.To implement these via the
sync*
CFG, eachtry
block needs to be split into individual Wasmtry
blocks covering each of thesync*
CFG blocks that are covered by the originaltry
.The
catch
blocks need not be duplicated. They can be separate CFG blocks targeted by thetry
blocks.Also,
finally
blocks can probably be reused between the various control flow chains (normal completion, exception thrown, return from function) rather than being duplicated as in the normal implementation. One local for eachfinally
block could contain the target index of where the execution needs to go after the execution of thefinally
block completes. Care must be taken to make this interact properly with normalfinally
blocks (those not containing anyyield
oryield*
and therefore translated by the normal code generator). Either the CFG-basedfinally
statements must properly maintain the stack of finalizers for the normal code generator, such that it properly duplicates these finalizers onreturn
or exceptions, or alltry
/finally
statements in async*
functions must be translated via the CFG, even if they do not contain anyyield
oryield*
.The text was updated successfully, but these errors were encountered: