Commit Graph

53 Commits

Author SHA1 Message Date
Johnni Winther e30cd0322c [cfe][Contexts] Split VariableDeclaration and VariableStatement
This separates VariableDeclaration from Statement. VariableDeclaration no longer implements Statement and variable declared in a block or in a for-statement are now wrapped by a VariableStatement.

Currently there are two VariableStatement implementations; LegacyVariableStatement for variables in the current model, called LegacyVariable, and VariableInitialization for variables used in the new, still experimental, encoding that supports scope computation.

This CL is a step towards realigning the AST nodes to the new model in which each kind of variable has its own distinct subclass. (LocalVariable, PositionalParameter, NamedParameter, SyntheticVariable, etc.)

Note that it is not the intent to use VariableStatement in ForStatement going forward but that will be handled in a follow-up.

TEST=existing.

Change-Id: I5b309cd62c9b138f95b74fb054686edffa49a393
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/502681
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
2026-05-18 05:49:28 -07:00
Nate Biggs f31923beee [dart2wasm] Fix async* stream not forwarding errors to listener cancel.
Set up a cancellation Completer that we forward errors to if the stream
has been cancelled.

Also add `isDone` which will avoid forwarding registering the
cancellation logic if the stream has already finished.

Fixes test
co19/Language/Expressions/Function_Invocation/async_generator_invokation_t10.dart
on wasm targets. This test already passes for all other backends.

Fixes: https://github.com/dart-lang/sdk/issues/63123
Change-Id: I8a3d87c3ea7b4ebb3a7b82ab064fb57034aa6f4a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495200
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
2026-05-08 15:39:19 -07:00
Martin Kustermann 4ee6a66270 [dart2wasm] Format pkg/dart2wasm after language version was increased
The change in [0] increased the language version of pkg/dart2wasm. That
in return changes how the package is formatted by the autoformatter.

This CL runs now the formatter to re-format the code. Unfortunately this
makes blame lists worse. But not doing it will make us have to disable
auto-formatting before saving files which is very annoying.

[0] https://dart-review.googlesource.com/c/sdk/+/487944

Change-Id: I6953fe0d6a824b2b79a26bbadb0bb977cec70b7a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/490821
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2026-03-26 04:32:19 -07:00
Martin Kustermann f6b74c35b1 [dart2wasm] Retain CFE inserted deferred loading nodes for TFA
TFA has handling of the `LoadLibrary` & `CheckLibraryIsLoaded` nodes. It
does logic based on them. For example it will ensure to that if one of
these nodes is retained in the AST that we also retain the deferred
library itself as well as the deferred library import.

For now dart2wasm lowered those two nodes during modular
transformations. This means TFA didn't see those nodes and weird things
can happen (e.g. a `checkLibraryLoad()` call without that library
existing anymore). Other interesting things that can happen: TFA
sees only one call to `checklibraryLoad` and constant propagates
the argument into the body & changes signature, ...

We could keep the existing behavior and make TFA aware of the dart2wasm
lowering (directly which is very hacky or via e.g. `Target`
indirection). Though this seems too complex.

So instead of making TFA aware of the lowerings, we move them to be
after TFA. Though we want precise TFA results if we don't use deferred
loading. So the approach is: If we actually need the runtime functions
we'll inject `@pragma('wasm:entry-point')` annotations before running
TFA and then lower those nodes after TFA.

This also means we avoid the ugly CFE nodes lowering followed by
lowering of the lowering (for load ids). Instead there's one place where
we lower those two nodes and we choose either to lower to "load id"
methods or the normal methods.

This is part of moving constants to deferred modules.

Issue https://github.com/dart-lang/sdk/issues/61727

Change-Id: Icebaf5a9495e00a8f85ecbf161b6ef891ea179ea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/457700
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2025-10-28 01:48:51 -07:00
Ömer Ağacan 91374ffb12 [dart2wasm] Minify more errors
Transform front-end generated `throw` expressions (as indicated by the
kernel node's `forErrorHandling` flag) to error throwing functions that,
in minify mode, throw without details.

ACX demo sizes: (`-O2 --minify`)

- Before: 12,841,863 bytes
- After: 12,396,399 bytes
- Diff: -445,464 bytes, -3.46%

Issue: https://github.com/dart-lang/sdk/issues/60432
Change-Id: I3c0bfebd5a9cb460af312dafb63b5a0c9aeda22e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/430380
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2025-05-23 03:31:36 -07:00
Ömer Ağacan e4676d5b56 [dart2wasm] Convert simple async function bodies to sync Future.value calls
This transforms functions like

    async foo() => const ...;

to

    foo() => Future.value(const ...);

The transformation is done when the async function body is a `const`
expression or a basic literal (string, int, double, bool).

These expressions don't have side effects and they cannot throw, so it's
safe to convert them to `Future.value`s.

This makes the generated code in the ACX demo 2.5% smaller: (`-O4` with
symbol names removed)

- Before: 9,040,020 bytes
- After: 8,805,471 bytes
- Diff: -234,549 bytes, -2.59%

With this we also remove the same special case in the backend to avoid
generating a state machine for these functions, as the special case
handled before the backend now and backend never sees this kind of
functions.

(Technically with inlining or other backend optimizations it could still
see these cases, but the pattern it matches is too strict, and currently
the special case in the backend doesn't do anything on the ACX demo.)

Note: I tried implementing the same in dart2js's await lowering pass in
https://dart-review.googlesource.com/c/sdk/+/422061 and reusing that
pass in https://dart-review.googlesource.com/c/sdk/+/420140.

However while that transformed simple programs as expected, in ACX demo
it still introduced a lot of `Future.sync` calls and made the overall
binary larger. I think we never want to introduce `Future.sync` calls
(at least until we improve code size for closures, see relevant issue
https://github.com/dart-lang/sdk/issues/60458), so for now we don't
reuse dart2js's pass.

Issue: https://github.com/dart-lang/sdk/issues/60433
Change-Id: I206ac8c6081201041f67e7fc91776077e52180a0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/422120
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2025-04-15 02:41:05 -07:00
Ömer Ağacan cf9f45f1d4 [dart2wasm] Copy VM's map and set factory transformers
Transform factory calls to default map and set classes to the
constructor calls to the classes to improve kernel.

Also remove some redundant null checks in VM's transformer.

`source_map_simple_optimized_test.dart` is updated: with improved kernel
wasm-opt now eliminates the `testMain` function, so the stack trace
doesn't mention it.

Fixes https://github.com/dart-lang/sdk/issues/60343.
Tested: minor refactoring in VM doesn't need testing. Wasm tested with
existing tests.
Change-Id: Ie448d1374ff0e1b278859f22bc250899e0e4cfd0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/416640
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2025-03-19 08:10:16 -07:00
Nate Biggs f8f10b8407 [dart2wasm] Add annotations to member and static intrinsics.
Each annotation corresponds to an enum value in the compiler that then dictates the generated code.

This is only done for static call and member intrinsics and not instance call intrinsics. This is because the target member of an instance intrinsic maybe be an interface rather than the annotated implementation of a method.

Change-Id: Iff8fe09b5078d81940cb1813fb65de50473519b1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/402960
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2025-01-09 07:59:09 -08:00
Ömer Sinan Ağacan 34a6cbc03b [dart2wasm] Use a Wasm array directly in chunked JSON parser state stack
Update `popWasmArray` desugaring to only clear the popped slot when the
element type is nullable.

Use `push/popWasmArray` in `_ChunkedJsonParserState.states` stack to
avoid indirection.

Change-Id: I641b4a78b85640b3676ef935bfd98b8cd5f7789d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/394483
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2024-11-13 10:38:30 +00:00
Devon Carew 1f8aea0c81 Bump lints to a97011b4b031b1df94765dbacd7d92b0b765c8b9
Changes:
```
> git log --format="%C(auto) %h %s" af68bf0..a97011b
 https://dart.googlesource.com/lints.git/+/a97011b add unintended_html_in_doc_comment; rev to 5.1.0 (211)

```

Diff: https://dart.googlesource.com/lints.git/+/af68bf0cbad88002a2ae19ee8db37b64eb120c32..a97011b4b031b1df94765dbacd7d92b0b765c8b9/
Change-Id: I998d73f5f72e94d5f2922b0751d31620a837555e
Tested: analysis only change
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/387601
Reviewed-by: Nate Bosch <nbosch@google.com>
Commit-Queue: Devon Carew <devoncarew@google.com>
2024-09-30 21:48:03 +00:00
Nate Biggs c936c0fdd2 [dart2wasm] Add deferred loading support to dart2wasm (11/X).
This is the final CL for deferred loading. It wires up the library-module analysis logic to the compiler. With all the Translator module predicates implemented, code should now be generated in separate modules (assuming the flag is enabled).

This also handles the module naming scheme. For an invocation of dart2wasm like `dart2wasm main.dart out.wasm` this will produce files like `out.mjs, out.wasm, out_module1.wasm, out_module2.wasm, ...`. `out.wasm` is the main module that gets loaded on initialization. When the flag is disabled this will always be the only output.

If the flag is disabled then the `_importMapping` in `deferred.dart` will be empty and we will default to the same behavior as today which will be to just return an empty `Future`. When enabled, `loadLibrary` will fetch and instantiate the new module(s) before proceeding.

Change-Id: I0dd136c0af61b916be2a24b3d79052ff1b786b52
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/380440
Reviewed-by: Martin Kustermann <kustermann@google.com>
2024-09-04 21:58:12 +00:00
Ömer Sinan Ağacan d0c6fc840f [dart2wasm] Remove a redundant helper to get kernel function types
531e4ca added a helper to get function type of a kernel procedure. Use
it and remove the copy of the helper in dart2wasm.

Change-Id: I1436933aaf3d1a43a35ffa56733113a186b197f0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/383320
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2024-09-03 11:22:34 +00:00
Lasse R.H. Nielsen 310d91aee8 Make async error injection set stack trace on errors.
Also removed a bunch of `CheckNotNullable`s that shouldn't be necessary any more. Any remaining non-sound-null-safety code runs today, and no more should be written. (And if it is, it'll mostly just err somewhere else, with a worse error message.)

Tested: New test added. Removed older tests checking for unsound null-safety.
Change-Id: I28626909cd8c1f91db6c61fc2b93042ed1b085dd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/380780
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
2024-08-27 12:51:26 +00:00
Martin Kustermann 8c07aa5117 [dart2wasm] Handle is/as checks that only require nullability check in backend.
Up to Patchset 4 reverts commit 36fb02deca

Remaining Patchsets implement specialized support in is/as check
implementation to handle cases where only a null check is required. The
most common case in iterators:

  class <...>Iterator<T> {
    T? _current;

    T get current => _current as T;
  }

This ensures we're never emitting the general subtype checking code as
this only requres checking whether the object is non-`null` or whether
the destination type is declared nullable.

The asymmetry between `is` and `as` checks comes due to the fact that
the `as` checks have to (for the slow case) materialize a type object
for a nice error message.


Issue https://github.com/dart-lang/sdk/issues/55516

Change-Id: Ie4a845816ec4eda37a5a2e78cac0aeda0e411abd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/381482
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2024-08-22 11:05:46 +00:00
Nate Biggs 3217fb1590 [dart2wasm] Fix popWasmArray positional arguments assert.
popWasmArray is called with 2 arguments, not 4:
https://github.com/dart-lang/sdk/blob/main/sdk/lib/_internal/wasm/lib/convert_patch.dart#L103

Change-Id: I848a26d7213af88cf070184ef139bd26010d28bd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/381560
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
2024-08-21 07:32:26 +00:00
Ömer Sinan Ağacan 65a4cb9340 [dart2wasm] Use Wasm arrays directly for _JsonListener state
Improves bytes/second in an internal JSON decoding benchmark from
227,791,937 to 246,298,043 (+8%).

The container stack (`_JsonListener.stack`) could hold the pair `(array,
array length)`, however since records are also heap allocated, and size
of the record would be the same as `GrowableList`, I've reused the
`GrowableList` type for the stack elements.

To avoid duplicating the code for growing the Wasm arrays in class
fields, a new intrinsic `pushWasmArray` implemented as a macro. It's
implemented as a kernel transform and it copies the arguments as
expressions in the transformed code to grow the Wasm array when it's
full.

To change as little is possible in one CL (to be able to measure
impact), growth strategy for the arrays are kept the same.

Change-Id: I2e6ba7704a83e6e6d8ada5d9015e208069737170
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/380705
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2024-08-20 13:57:18 +00:00
Ömer Sinan Ağacan b9216c5804 [dart2wasm] Remove unused diagnosticReporter argument
Change-Id: Ia9ba761773b1d246886c1cf15196dcb7bb8015a7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/368401
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2024-05-29 08:21:05 +00:00
Martin Kustermann e6e9b4e595 [dart2wasm] Only share type parameter fields if nullability allows
Closes https://github.com/dart-lang/sdk/issues/55741

Change-Id: I1e542041496d07714431ed40871031a117030736
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/366940
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2024-05-17 12:07:56 +00:00
Johnni Winther ae03b57cbb [cfe] Remove .isNonNullableByDefault from package:kernel
This removes the .isNonNullableByDefault properties and similar from
the AST nodes in package:kernel. NNBD is now always enabled so these
properties are trivial.

TEST=existing

Change-Id: I75ca0551ac4b5910ea63530dd0c9c2e68bd01aff
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/366320
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
2024-05-15 08:31:38 +00:00
Martin Kustermann 785dd5723c [dart2wasm] Make use of TFA-inferred types in more cases
Avoid falling back to variable type if the variable is `final` and has a
more precise inferred type.

Use unboxing information on methods to make unboxed return types
when TFA concludes it's int/double.

This will partially fix a performance regression in SplayHarder
benchmark where a parameter of type `num` was unboxed to `double` but
the local variable was kept as `num` and therefore always caused a box
allocation. After this change the box allocation is moved to the place
where we call `double.toString()`.

TEST=Updated expectation files.

Change-Id: I0252cf86ada9a8affbb46a31e913504930057650
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/365560
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2024-05-08 11:23:14 +00:00
Martin Kustermann 36fb02deca [dart2wasm] Use vm's modular transformers as-optimization lowering
Currently `-O4` drops explicit as-checks. Before changing this, we have
to do more optimizations on type checks. As a start, we call out to the
VM's lowering of as-checks in the modular transformer.

Issue https://github.com/dart-lang/sdk/issues/55516

Change-Id: I71f35a95ab41cc7a30f7dea088d9d41ac5243f59
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/365141
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2024-05-01 11:44:11 +00:00
Ömer Sinan Ağacan b449e99118 [dart2wasm] Fix async* transformation of nested async* functions
With nested `async*` functions, the state of whether we're in an
`async*` function should be restored as the previous state after leaving
the nested function, instead of as `false`.

Fixes #55397.

Change-Id: I5f2a964847ae34e98584f3adad6df7857b81e474
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/361600
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2024-04-08 12:42:29 +00:00
Kevin Moore 24ee108404 [dart2wasm] code cleanup
Upgrade to latest recommended lints (excluding a few)
Moved to switch expressions
Added a couple of lints about directives

Change-Id: Ibe84f97e84fb50132e61ac38903090447b058d84
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/355547
Commit-Queue: Kevin Moore <kevmoo@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2024-03-05 16:57:47 +00:00
Ömer Sinan Ağacan a2b833ede4 [dart2wasm] New async* desugaring
See `_lowerAsyncStar` for the desugaring plan.

Fixes tests:

co19/Language/Expressions/Function_Invocation/async_generator_invokation_t04
co19/Language/Expressions/Function_Invocation/async_generator_invokation_t08
co19/Language/Statements/Yield_and_Yield_Each/Yield/execution_async_A01_t07
co19/Language/Statements/Yield_and_Yield_Each/Yield/execution_async_A03_t04
co19/Language/Statements/Yield_and_Yield_Each/Yield/execution_async_A03_t05
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t03
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t07
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t08
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t09
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t11
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t12
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t14
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t15
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t16
language/async_star/async_star_await_for_test
language/async_star/async_star_cancel_test
language/async_star/async_star_test
language/async_star/throw_in_catch_test
language/async_star/yield_test
language/async_star/yieldstar_test
lib/async/async_await_zones_test

Fixes #55025.
Fixes #55018.
Fixes #52464.

Change-Id: I9d51564698710993cb7d2cc64b3bb8c26d6d4c77
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/355360
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2024-03-05 11:56:00 +00:00
Lasse R.H. Nielsen f0aeebd0e7 Make all platforms return null from Error.stackTrace until thrown.
The web platforms used to invent a spurious stack trace when reading
`Error.stackTrace` before the object was thrown.
They now return `null` instead, if there is no underlying JS error object,
matching specified behavior.

Fixed bugs in async error throwing in dart2wasm:
* `throw` in an async function did not set the stack trace on an error.
  Now calls `Error._throw` instead of just a direct Wasm "throw".
* `async*` functions did not capture the stack trace of a throw
  that ended the function body, which means it called
  `StreamController.addError` with only one argument.
  That then resused the stack trace from an `Error` throw instead
  of the correct stack trace.

Added tests.

Change-Id: I1d9fa8d9e18076a7fe28254b60b950866cd550a7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/354021
Reviewed-by: Stephen Adams <sra@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
2024-02-27 23:01:06 +00:00
Ömer Sinan Ağacan 72fd1e01d2 [dart2wasm] Simplify and fix async* element type computation
Fixes tests:

- co19/Language/Functions/element_type_A02_t03
- co19/Language/Functions/element_type_A02_t04

Change-Id: Ifc186cb463fee26c59f81012c6da8925d902d9d9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/342561
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2023-12-20 08:31:25 +00:00
Chloe Stefantsova 3eeba4a4e2 [cfe] Refactor FunctionNode.futureValueType into emitted value type
Previously we would encode the type of the value returned in `async`
functions as the field `futureValueType` on `FunctionNode`. For all
other kinds of functions, such as `sync`, `sync*`, and `async*`, that
field would be null. This CL renames `futureValueType` into
`emittedVAlueType`, and for functions of kinds `async`, `sync*`, and
`async*` that is expected to be the type of values emitted via
`return` or `yield` statements. For `sync` functions that field is
supposed to contain `null`.

In response to https://github.com/dart-lang/sdk/issues/54159

TEST=existing

Change-Id: I1efdbcc4e75d150f5618c7ca50cfe49a0e54fce6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/341662
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
2023-12-19 08:44:43 +00:00
Martin Kustermann bdefe5fa7e Move Wasm{Object,Int,Float}Array -> WasmArray, use extensions on WasmArray for static dispatc0h
The dart2wasm compiler treats wasm arrays of objects/ints/floats pretty
much the same, there's no reason to have complicated class hierarchy and
different kinds of wasm array classes.

Also: We rely on all operations on wasm arrays (and other built-in
types) to be handled on the call site. Wasm arrays are not dart objects,
don't support virtual dispatch. So we make operations operating on the
wasm types extensions.

This also makes now loads and stores into the wasm arrays simple `[]` and
`[]=` operations. We still have special extensions for reading/writing
to integer/double arrays that not only read/write but also
sign-extend/zero-extend and operate on Dart's `int` / `double`.

The compiler will allow `WasmArray<X>(length)` for types `X` that have
default-value in wasm arrays (nullable / integer / double types) and
have another `WasmArray<X>.filled(length, X)` for non-nullable reference
types.

Overall this reduces LOCs and simplifies things

Change-Id: I885bed3dfd1c602dc7b0747c69927d464376383d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/340881
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
2023-12-12 17:05:49 +00:00
Ömer Sinan Ağacan d548c07996 [dart2wasm] Fix async* stream types when fn return type is not Stream
Fixes #53234.

Change-Id: I97aec5d61bf442ecdaeb2ea2dc61d499ab167dd2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/340862
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-12-12 14:13:08 +00:00
Alexander Markov 927091e8ac [dart2wasm] Fix invalid closure return type in async* lowering
dart2wasm lowering of async* methods includes call to Stream.where
which takes a closure. The return type of that closure was incorrectly
set to Object?, while it should be bool.

This incorrect static type becomes a problem with more precise
handling of closures in TFA.

Issue: https://github.com/dart-lang/sdk/issues/39692
Change-Id: I35a8a6b198413d564e091a935a8beaff15d6d541
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/339200
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
2023-12-01 14:06:18 +00:00
Alexander Markov e7c8363900 [dart2wasm/tfa] Improve inference for binary int operations
Because of the special language rules (int +/-/* int = int),
static type for binary int operations can be more precise than
inferred result type (in case of dart2wasm, int binary operations
are declared as external methods returning num).

So, for dart2wasm it is useful to narrow result of a call by its
static type, if it is different from return type of the call target.

Also, this change fixes an incorrect static type which is
created during dart2wasm async* transformation.

TEST=pkg/vm/testcases/transformations/type_flow/transformer/int_operations_dart2wasm.dart
Fixes https://github.com/dart-lang/sdk/issues/53921

Change-Id: Id6a5a2cffac47918c4e92f996267bf7fae713416
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/333580
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
2023-11-03 13:39:43 +00:00
Alexander Markov 4b9c7c05d4 [vm, dart2wasm] Early lowering of FunctionTearOff nodes
FunctionTearOff node represents a tear-off of the 'call' method of
a Function, so it is basically a no-op:

  FunctionTearOff(receiver) == receiver

So we can remove this node early, during lowering transformation on
kernel AST and clean up handling of FunctionTearOff nodes from the VM
and dart2wasm compilation pipelines.

TEST=ci

Change-Id: Ia1500a066a0261076162e018ff0ab502258f606f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/325924
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2023-09-15 16:54:08 +00:00
Aske Simon Christensen 36d6676833 [dart2wasm] Use Wasm array for type arguments in interface type
This avoids the overhead of Dart lists in subtype checks. It also
alleviates a potential source of infinite recursion by avoiding some
list operations with implicit type checks inside the type check code
(though there are still more of these).

With this change, we no longer have the const object cycle between
the empty list of `_Type` objects and the interface type object for
`_Type`. In combination with the the `struct.new` optimization, this
enables type argument fields to become non-nullable and immutable.

Change-Id: Ib46ea70a078a0c580713090163fecd63fe363bd9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/322900
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Jess Lally <jessicalally@google.com>
2023-09-07 05:29:30 +00:00
Ömer Sinan Ağacan 605b5a2e61 [dart2wasm] Transform List factory calls to implementation class calls
This is mainly used in [1] to allow using unboxed int lists when a
factory type argument is `int`, which then allows inlining unboxed int
list `[]` and `[]=` and storing and loading `int` values unboxed.

This implementation is mostly a copy of VM's transformer with the same
name. However we can't reuse VM's pass as we do different
transformations in [1].

[1]: https://dart-review.googlesource.com/c/sdk/+/318680

Change-Id: I16c06fc2b2edb1a5498807fc5c0fee839c003965
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/318921
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
2023-08-09 09:31:59 +00:00
Srujan Gaddam 79df0b2789 [dart2wasm] Mark _typeArguments as synthetic
Fixes b/293426600

This synthetic procedure is added on every class with type args.
Mark it as synthetic so the JS interop checks don't trigger on
it.

Change-Id: I5b04fe4340b409a4ab1eb5c32e37fe6ff37df4b0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/316702
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Joshua Litt <joshualitt@google.com>
Auto-Submit: Srujan Gaddam <srujzs@google.com>
2023-07-27 22:54:58 +00:00
Johnni Winther 5476e3bd6e [kernel] Rename InterfaceType.className to classReference
+ Name.libraryName -> libraryReference

Change-Id: I25b5022ea87f92fb5837f03d29f1671f0e68261b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304740
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
2023-06-01 06:43:46 +00:00
Ömer Sinan Ağacan c7dcbff358 [dart2wasm] Fix a bug in async* desugaring
The desugared code uses `Completer<bool>` values to suspend the `async*`
function, but we can't use a type test and to check if a value is the
`Completer<bool>` value for the suspension or a user-emitted value as
the `async*` function can also yield `Completer<bool>` values. Update
the test from `value is Completer<bool>` to `!isEven`.

Change-Id: I74f54b838e6a2aab942154ec7f3e667e291523e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304880
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-05-23 21:24:16 +00:00
Ömer Sinan Ağacan 9d1dd89768 [dart2wasm] Handle exceptions and returns in async* functions
New passing tests:

- co19/Language/Expressions/Function_Invocation/async_cleanup_t07
- co19/Language/Expressions/Function_Invocation/async_cleanup_t08
- co19/Language/Expressions/Function_Invocation/async_generator_invokation_t05
- co19/Language/Expressions/Function_Invocation/async_generator_invokation_t09
- co19/Language/Statements/Rethrow/execution_t04
- co19/Language/Statements/Return/syntax_t10
- co19/Language/Statements/Return/syntax_t11
- co19/Language/Statements/Return/syntax_t12
- co19/Language/Statements/Return/syntax_t13
- co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A01_t01
- language/async/return_types_runtime_test
- language/async_star/basic_test
- language/async_star/yield_statement_context_test
- lib/async/stream_from_iterable_test

Change-Id: Id03cc0abe150dadfcd753c4e74a282d46260a1f8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304501
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-05-22 20:31:38 +00:00
Ömer Sinan Ağacan e20d2d2103 [dart2wasm] Fix completer.future type in for-in lowering
Currently the `InstanceGet` node result type for for
`Completer<bool>.future` is `Future<bool> Function()`, but it should be
`Future<bool>`.

This causes problems in CL 301020 where we generate temporaries for
nested `await` expressions and use the expression type for the types of
those temporaries. Incorrect expression type in `completer.future`
causes a temporary with incorrect type to be generated.

Change-Id: Ib8193c66afee9454a275c00fb958c11fd35cd3eb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/301382
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-05-04 19:15:28 +00:00
Aske Simon Christensen d1d232776a [dart2wasm] Rename the dart:wasm library to dart:_wasm.
This is an internal library not meant to be used in application code.

CoreLibraryReviewExempt: Changes only Wasm specific libraries.
Change-Id: I2f5b463382d35a442e782067ef7d9063183fe5e3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292021
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Aske Simon Christensen <askesc@google.com>
2023-04-04 11:52:18 +00:00
Aske Simon Christensen 85dfcd8601 [dart2wasm] Compute instance method parameter types from Wasm types.
This improves the precision of the Wasm types for Dart function types
in instance method signatures.

It could in principle also improve the precision of the receiver
parameter from the LUB of the representation types to the LUB of the
actual structs for the classes implementing the member. However,
if at a call site the receiver parameter type is more precise than the
representation type of the receiver, the call site will need to cast
the receiver to the more precise type. This gives rise to more casts
in practice than the ones saved inside the methods by the more precise
receiver parameter type. For this reason, the receiver parameter type
is kept at the LUB of the representation types of the classes
implementing the member.

This change is also a stepping stone towards not having `ClassInfo`
for the special Wasm types.

CoreLibraryReviewExempt: Only affects Wasm-specific libraries.
Change-Id: I81ca5aa1107f1c04ed7729a758e983698492a106
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/288400
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Aske Simon Christensen <askesc@google.com>
2023-03-31 07:25:08 +00:00
Johnni Winther 04e6f4c282 [kernel] Add VariableDeclaration.isSynthesized
This adds an [isSynthesized] flag to the [VariableDeclaration] the
signal when the variable doesn't correspond to a variable in the
source code.

The name of a variable can only be `null` if it is synthesized.

Partially in response to
https://github.com/dart-lang/sdk/issues/51554

TEST=existing

Change-Id: I94591971f11da09d210c8b25a2d05e22ca05dc62
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/286961
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2023-03-10 11:13:36 +00:00
Aske Simon Christensen 321f2e9b65 [dart2wasm] Implement sync*
This is an implementation of `sync*` via two main mechanisms:

- The closure context infrastructure is used for preserving local
  state. All local variables in `sync*` functions are implicitly
  captured in the contexts even if they are not captured by a lambda.

- Suspension and resumption of the body is implemented via a state
  machine as a switch in a loop. This allows for an arbitrary control
  flow graph that can be resumed at any point. A subclass of the code
  generator generates control constructs containing any `yield` or
  `yield*` statements as jumps around this CFG while delegating the
  rest of the code generation to the normal member code generator.

This version does not support `switch` or `try` inside a `sync*`
function. Support for these statements will be added later.

Change-Id: Iec8236f64500d823f574aa628ddb0d22fe4ac2d0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/280166
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2023-02-09 11:07:01 +00:00
Josh Soref 84e3c8b50f Spelling tests
Closes https://github.com/dart-lang/sdk/pull/50920

GitOrigin-RevId: fa87531bd0f52b69485c9d02ff9e44a4a29c6a91
Change-Id: I0ae8574a5b77087895e004079f221201bb550cf3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278535
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Thomas <athom@google.com>
Commit-Queue: Alexander Thomas <athom@google.com>
2023-01-19 16:24:29 +00:00
Aske Simon Christensen cffd49e97c [dart2wasm] Report warning on sync*
Change-Id: If5b0492438830b8813d86a031193fa8d64ed1b1c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/279017
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2023-01-16 14:05:08 +00:00
Joshua Litt 2af123778b [dart2wasm] Cleanup comment.
Change-Id: I3144171a14d47e1df3e6bf6306784203e8d7d1b3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/267283
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
2022-11-15 22:07:22 +00:00
Joshua Litt dee7aa0a91 [dart2wasm] Implement async* via lowering.
Change-Id: Iebd4d215b71aed8a7e8cff751902f8fa48ff5ae9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/262627
Reviewed-by: Aske Simon Christensen <askesc@google.com>
2022-11-02 19:46:48 +00:00
Joshua Litt b8b70decec [dart2wasm] Cancel stream in await-for via try/finally.
Change-Id: I91e2fd5bffe4ea149606a257bace965ce75e6167
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256702
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Joshua Litt <joshualitt@google.com>
2022-10-05 00:59:30 +00:00
Joshua Litt 6052fe0ca2 [dart2wasm] Implement await / for as lowering.
Change-Id: Ic41f016490c993f27c3e5873ad1a4b3e8a902f13
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255822
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Joshua Litt <joshualitt@google.com>
2022-08-22 18:08:31 +00:00
Joshua Litt 2c891cda56 [dart2wasm] Fix bug in algorithm to reuse super _typeArguments.
language/type_variable/promotion_test starts failing because
`joinReplaceAllResult` isn't implemented yet.

Change-Id: Ifd7ff6d94486499b8cf398dd2c749d10500e242a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250480
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
2022-07-21 01:57:33 +00:00