Commit graph

362 commits

Author SHA1 Message Date
Ö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
Ömer Sinan Ağacan e61c6dc620 [dart2wasm] Improve wasm:class-id pragma error messages
Change-Id: Id9d073557738548d41e6fd90d8973d8e5d5c0748
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/318920
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-08-08 15:39:27 +00:00
Jess Lally 700c7e3b3f [dart2wasm] Remove Closures dependency on CodeGenerator
Change-Id: Ie18bdc704ca8a3459bde1bd27e8ed7866239b737
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/318942
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Jess Lally <jessicalally@google.com>
2023-08-08 14:54:43 +00:00
Srujan Gaddam a56642e9a1 [dart:js_util] Handle type parameters in export/mocks.
Several changes are made:

- createDartExport now does not export methods that define type parameters.
- createStaticInteropMock adds conformance checks to make sure implementing
members can handle all possible values of a type parameter in an interop
member. An error is added to reduce confusion around this.
- Export creator now uses dart:js_interop_unsafe for a lot of its lowering
as the dart:js_util equivalents are buggy when it comes to calling exported
functions in JS with JS types.
- Small code changes are added to backends to handle the above changes.

Change-Id: Ie3b6b157930537267f270b60373b2b17e0a14344
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/316141
Reviewed-by: Joshua Litt <joshualitt@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
2023-08-04 21:45:29 +00:00
Ömer Sinan Ağacan 28453a6255 [dart2wasm] Handle unchecked as expressions
Fixes #53104.

Change-Id: I8a1a47775226f73445551ca4bd9f471c8dedfe93
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/318220
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
Auto-Submit: Ömer Ağacan <omersa@google.com>
2023-08-04 14:06:49 +00:00
Aske Simon Christensen 698b5448e1 [dart2wasm] Use new br_on_cast[_fail] encoding with input type
Change-Id: Ie00cdaf30b97f009b4474a032a6b00bddb848ff7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/317541
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Aske Simon Christensen <askesc@google.com>
2023-08-03 16:56:15 +00:00
Ömer Sinan Ağacan a1d7f7284b [dart2wasm] Give descriptive names to tear-off and trampoline functions
Currently a function, its tear-off generator, and the trampolines of the
tear-offs have the same Wasm name. This makes it difficult to
distinguish them in .wat outputs.

This CL gives them separate names:

- Function names are same as before: "f".

- Tear-off generators have the suffix "tear-off": "f tear-off".

- Trampolines have the suffix "tear-off trampoline":
  "f tear-off trampoline".

Change-Id: I2459f7d2fd359e72ace7cc4e7790a3e6e64d1f31
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/317640
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-08-02 11:24:06 +00:00
Ömer Sinan Ağacan 39fe8f458a [dart2wasm] Remove unnecessary initializer list collectContexts call
The `collectContexts(member)` already visits initializer lists when
visiting constructors, so no need to call it separately for
initializers.

Change-Id: Ida51a0e8c4003f19cd7b533a2847946926237bc0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/317101
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
2023-08-01 10:53:09 +00:00
Johnni Winther a76f4d5c34 [cfe] Rename InlineClass to ExtensionTypeDeclaration
This renames InlineClass to ExtensionTypeDeclaration, and InlineType
to ExtensionType. Members of extension type declarations are called
extension type members instead of extension type declaration members
for "brevity".

TEST=existing

Change-Id: I91ed62533ddd345644492f04dc3310d007460288
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/316780
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2023-08-01 09:04:38 +00:00
Joshua Litt 96d6c2e0d3 [wasm_builder] Refactor to a builder / built pattern.
This CL mostly just moves code around. There are three broad changes in this CL:
1) Reify the builder / built pattern that exists implicitly in the existing code. Builders now live in `src/builder`, while the built ir lives in `src/ir`.
2) Reify the module subsections.
3) `pkg/dart2wasm` has been updated to use the new API.

There is only one minor logic change in the entire CL, we now defer serialization of a module until the bytes are actually required, as opposed to serializing eagerly.

This change is designed to make the wasm_builder more robust. By clearly delineating which parts of the AST are mutable and which parts are immutable, then it should make it easier for users of the wasm_builder to avoid undefined behavior, i.e. holding on to something that can change.

Change-Id: I676107b867aa74fabf413108673e170126bdb5c1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/316280
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Joshua Litt <joshualitt@google.com>
2023-07-31 15:27:58 +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
Ömer Sinan Ağacan 7fec037b6b [dart2wasm] Split more patch files into patch + implementation files
Following the refactoring we started in previous CLs, this splits string
and int patch files into (1) patch files that only patch and don't add
implementation classes (2) files for implementation classes (3) helpers.

Changes:

- `string_patch` is split into `string.dart` and `string_patch.dart`.

- VM's `integers_patch.dart` copied as `int_patch.dart` and updated.
  This was needed as `integers_patch` requires VM's library paths in
  imports.

  We needed to copy this file to be able to optimize based on
  dart2wasm's implementation classes. However in this CL we copy the
  file as-is and update import paths.

- VM's `string_buffer_patch.dart` copied to be able to use the string
  implementation classes from the new library.
  `string_buffer_create.dart` is merged ino `string_buffer_patch.dart`.

- `getHash` and `setHash` to set object identity moved to
  `object_helper.dart`, to be able to use in string implementations.

- Redundant `new` keywords in copied files removed.

One TODO added in `string_buffer_patch.dart` when allocating a new
string to the buffer:

    // _parts = _GrowableList.withCapacity(10)..add(str);
    // TODO(omersa): Uncomment the line above after moving list
    // implementations to a library.
    _parts = [str];

We can enable the old code again after moving list implementations to a
library.

Change-Id: Ice5dba40b3ba894797028987d4b42cb0c0f0c230
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/315821
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
2023-07-24 16:58:52 +00:00
Jia Hao Goh 11d0f060ef [dart2wasm] Fix location RangeError when using part
Here's a minimal repro that this CL fixes:

`ui.dart`

```dart
library dart.ui;

import 'dart:ffi';

part 'foo.dart';
```

`foo.dart`

```dart
part of dart.ui;

@Native<Void Function()>(symbol: 'foo_func', isLeaf: true)
external void foo_func();
```

When compiling with `compile_platform.dart` with `--target=dart2wasm`, the following error appears:


```
Unhandled exception:
Verification error: Target=wasm, VerificationStage.afterModularTransformations: Invalid location with target 'wasm' on FunctionNode() (FunctionNode): RangeError (offset): Invalid value: Not in inclusive range 0..56: 91
Context: 'foo_func_$import'.
Node: 'FunctionNode()'.
#0      VerificationErrorListener.reportError (package:kernel/verifier.dart:81:5)
#1      VerifyingVisitor.problem (package:kernel/verifier.dart:222:14)
#2      VerifyingVisitor._getLocation (package:kernel/verifier.dart:1361:7)
#3      VerifyingVisitor._hasLocation (package:kernel/verifier.dart:1370:26)
#4      VerifyingVisitor.getSameLibraryLastSeenTreeNode (package:kernel/verifier.dart:1342:28)
#5      VerifyingVisitor.localContext (package:kernel/verifier.dart:1382:24)
#6      VerifyingVisitor.defaultDartType (package:kernel/verifier.dart:1491:41)
#7      Visitor.visitVoidType (package:kernel/visitor.dart:1309:37)
#8      VoidType.accept (package:kernel/ast.dart:11190:42)
#9      FunctionNode.visitChildren (package:kernel/ast.dart:3919:16)
#10     VerifyingVisitor.visitChildren (package:kernel/verifier.dart:259:10)
#11     VerifyingVisitor.visitWithLocalScope (package:kernel/verifier.dart:266:5)
#12     VerifyingVisitor.visitFunctionNode (package:kernel/verifier.dart:721:5)
#13     FunctionNode.accept (package:kernel/ast.dart:3908:38)
#14     VerifyingVisitor.visitProcedure (package:kernel/verifier.dart:620:19)
#15     Procedure.accept (package:kernel/ast.dart:3311:40)
#16     visitList (package:kernel/ast.dart:14488:14)
#17     Library.visitChildren (package:kernel/ast.dart:591:5)
#18     VerifyingVisitor.visitChildren (package:kernel/verifier.dart:259:10)
#19     VerifyingVisitor.defaultTreeNode (package:kernel/verifier.dart:196:5)
#20     TreeVisitor.visitLibrary (package:kernel/visitor.dart:503:35)
#21     VerifyingVisitor.visitLibrary (package:kernel/verifier.dart:367:11)
#22     Library.accept (package:kernel/ast.dart:577:38)
#23     visitList (package:kernel/ast.dart:14488:14)
#24     Component.visitChildren (package:kernel/ast.dart:14320:5)
#25     VerifyingVisitor.visitChildren (package:kernel/verifier.dart:259:10)
#26     VerifyingVisitor.visitComponent (package:kernel/verifier.dart:342:7)
#27     Component.accept (package:kernel/ast.dart:14313:38)
#28     VerifyingVisitor.check (package:kernel/verifier.dart:171:15)
#29     verifyComponent (package:kernel/verifier.dart:69:20)
...
```

The issue seems to be that after doing this native transformation, the node's `fileUri` references the enclosing library (`ui.dart` above), but the `node.location` references the actual source file (`foo.dart` above) indirectly through `node.fileOffset`.

This ends up being an issue when compiling the platform dill in Google3,   but I didn't look into why `flutter build web --wasm` isn't broken.

Internal bug: b/292172146

Change-Id: I2b8d7d215b2c36354860257ce651d50168e9523d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/315360
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Jia Hao Goh <jiahaog@google.com>
2023-07-21 23:08:28 +00:00
Ömer Sinan Ağacan 37581cb79e [dart2wasm] Fix names of dynamic call entry functions
Currently all closure dynamic call entries have the same name. This
makes it difficult to find locations of crashes. Example:

    wasm-function[677]:0x1de1d: RuntimeError: illegal cast
    RuntimeError: illegal cast
        at dynamic call entry (wasm://wasm/000909b2:wasm-function[677]:0x1de1d)
        at method forwarder for 'call' (wasm://wasm/000909b2:wasm-function[583]:0x1b474)
        ...

With this we now add the function name before "dynamic call entry":

  wasm-function[677]:0x1de1d: RuntimeError: illegal cast
  RuntimeError: illegal cast
      at C.m1 tear-off dynamic call entry (wasm://wasm/000921c6:wasm-function[677]:0x1de1d)
      at method forwarder for 'call' (wasm://wasm/000921c6:wasm-function[583]:0x1b474)
      ...

Which makes it easy to find the function in .wat output as there is only
one function with the name "C.m1 tear-off dyamic call entry".

Change-Id: Iea726b695fc29b361a347b64194d5c09601a0999
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/315440
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-07-21 17:48:38 +00:00
Ömer Sinan Ağacan 463e251334 [dart2wasm] Optimize some list operations
- Use `array.copy` and `array.fill` when possible.

- Use the Wasm array directly (instead of `[]` and `[]=`) when possible
  to avoid redundant bounds checks.

- `_GrowableList.insert` is rewritten to avoid a redundant write when
  the element is not added to the end.

- Remove redundant bounds checks when calling `Lists.copy`.

Change-Id: I08d96b56201cbb4ff24ca969b7fde8bcc1315e4b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/315120
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-07-21 10:29:46 +00:00
Joshua Litt 63786015f3 [dart2wasm|jscm] Move typed data to JS.
Change-Id: Ic4381818be9fdf3725a7eef8455451447a210b8b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313281
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
2023-07-20 20:31:38 +00:00
Ömer Sinan Ağacan 0f54180b51 [dart2wasm] New typed data implementation
New typed data implementation that optimizes the common cases.

This uses the best possible representation for the fast case with a
representation like:

    class _I32List implements Int32List {
      final WasmIntArray<WasmI32> _data;

      int operator [](int index) {
        // range check
        return _data.read(index);
      }

      void operator []=(int index, int value) {
        // range check
        _data.writeSigned(index, value);
      }

      ...
    }

This gives us the best possible runtime performance in the common cases
of:

- The list is used directly.
- The list is used via a view of the same Wasm element type (e.g. a
  `Uint32List` view of a `Int32List`) and with aligned byte offset.

All other classes (`ByteBuffer`, `ByteData`, and view classes)
implemented to be able to support this representation.

Summary of classes:

- One list class per Dart typed data list, with the matching Wasm array
  as the buffer (as shown in the example above): `_I8List`, `_U8List`,
  `_U8ClampedList`, `_I16List`, `_U16List`, ...

- One list class per Dart typed data list, with mismatching Wasm array
  as the buffer. These classes are used when a view is created from a
  list, and the original list has a Wasm array with different element
  type than the view needs. `_SlowI8List`, `_SlowU8List`, ...

  These classes use `ByteData` interface to update the buffer.

- One list class for each of the classes listed above, for immutable
  views. `_UnmodifiableI32List`, `_UnmodifiableSlowU64List`, ...

  These classes inherit from their modifiable list classes and override
  update methods using a mixin.

- One `ByteData` class for each Wasm array type: `_I8ByteData`,
  `_I16ByteData`,
  ...

- One immutable `ByteData` view for each `ByteData` class.

- One `ByteBuffer` class for each Wasm array type: `_I8ByteBuffer`,
  `_I16ByteBuffer`, ...

- A single `ByteBuffer` class for the immutable view of a byte buffer.

  We don't need one immutable `ByteBuffer` view class per Wasm array
  type as `ByteBuffer` API does not provide direct access to the buffer.

Other optimizations:

- `setRange` now uses `array.copy` when possible, which causes a huge
  performance win in some benchmarks.

- The new implementation is pure Dart and needs no support or special
  cases from the compiler other than the Wasm array type support and
  intrinsics like `array.copy`. As a result this removes a bunch of
  `entry-point` pragmas and significantly reduces code size in some
  cases.

Other changes:

- Patch and implementation files for typed data and SIMD types are split
  into separate files. `typed_data_patch.dart` and `simd_patch.dart` now
  only contains patched factories. Implementation classes are moved to
  `typed_data.dart` and `simd.dart` as libraries `dart:_typed_data` and
  `dart:_simd`.

Benchmark results:

This CL significantly improves common cases. New implementation is only
slower than the current implementation when a view uses a Wasm array
type with incompatible element type (for example, `Uint32List` created
from a `Uint64List`).

These cases can still be improved by overriding the relevant `ByteData`
methods. For example, in the example of `Uint32List` view of a
`Uint64List`, by overriding `_I64ByteData.getUint32` to do a single read
then requested bytes don't cross element boundaries in the Wasm array.
These optimizations are left as future work.

Some sample benchmarks:

vector_math matrix_bench before:

    Binary size: 133,104 bytes.
    MatrixMultiply(RunTime): 201 us.
    SIMDMatrixMultiply(RunTime): 3,608 us.
    VectorTransform(RunTime): 94 us.
    SIMDVectorTransform(RunTime): 833 us.
    setViewMatrix(RunTime): 506 us.
    aabb2Transform(RunTime): 987 us.
    aabb2Rotate(RunTime): 721 us.
    aabb3Transform(RunTime): 1,710 us.
    aabb3Rotate(RunTime): 1,156 us.
    Matrix3.determinant(RunTime): 171 us.
    Matrix3.transform(Vector3)(RunTime): 8,550 us.
    Matrix3.transform(Vector2)(RunTime): 3924 us.
    Matrix3.transposeMultiply(RunTime): 201 us.

vector_math matrix_bench after:

    Binary size: 135,198 bytes.
    MatrixMultiply(RunTime): 42 us.
    SIMDMatrixMultiply(RunTime): 2,068 us.
    VectorTransform(RunTime): 12 us.
    SIMDVectorTransform(RunTime): 272 us.
    setViewMatrix(RunTime): 82 us.
    aabb2Transform(RunTime): 167 us.
    aabb2Rotate(RunTime): 147 us.
    aabb3Transform(RunTime): 194 us.
    aabb3Rotate(RunTime): 199 us.
    Matrix3.determinant(RunTime): 70 us.
    Matrix3.transform(Vector3)(RunTime): 726 us.
    Matrix3.transform(Vector2)(RunTime): 504 us.
    Matrix3.transposeMultiply(RunTime): 53 us.

FluidMotion before:

    Binary size: 121,130 bytes.
    FluidMotion(RunTime): 270,625 us.

FluidMotion after:

    Binary size: 110,674 bytes.
    FluidMotion(RunTime): 71,357 us.

With bound checks omitted (not in this CL), FluidMotion becomes
competitive with `dart2js -O4`:

FluidMotion dart2js -O4:

    FluidMotion(RunTime): 47,813 us.

FluidMotion this CL + boud checks omitted:

    FluidMotion(RunTime): 51,289 us.

Fixes #52710.

Tested: With existing tests.
Change-Id: I33bf5585c3be5d3919a99af857659cf7d9393df0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312907
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-07-20 09:47:39 +00:00
Joshua Litt 5016361ccd [dart2wasm] Refactor core.dart to make it easier to patch.
Now that we no longer need to put boxes in `core.dart`, it makes sense to move them out of `core.dart` so that we can patch these classes and their helper functions. This CL moves `BoxedInt` and `BoxedDouble` out of core patch, and moves some of their intrinsics / helpers to side libraries.

Tested: Dart2Wasm internal refactor of patch files.
Change-Id: I1dac95089a8bd9e2c8ee4f467a0d6f2792f9d665
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313900
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
2023-07-19 17:05:36 +00:00
Joshua Litt 9e37c2b480 [dart2wasm] Add JS compatibility mode.
The purpose of the wasm_js_compatibility target is to facilitate experiments with a JS compatibility mode for Dart2Wasm. Initially, we're just going to focus on typed data, but this will give us a place to experiment with moving List and String to JS as well.

In addition, someday down the road we hope to experiment with two additional compatibility changes:
1) Exclusively using double for all Dart numbers
2) Allowing undefined to flow as null.

The two major benefits of this approach are:
1) Much faster JS interop
2) To make it easier to bring up Dart2JS applications on Dart2Wasm

The only downside will be access overhead on the Wasm side, but the JS builtins proposal could potentially bring us close to parity with Wasm builtins someday.

Tested: Wasm specific trivial refactor.
Change-Id: I2c09426b6999507c1de6e584e9bc7072a088bda9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313240
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: William Hesse <whesse@google.com>
2023-07-18 19:34:38 +00:00
Ömer Sinan Ağacan 1d8dde36e1 [dart2wasm] Add array.copy instruction and intrinsics
`array.copy` is used in [1] in `setRange` when source and destinations
are both typed arrays with the same Wasm array type.

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

Change-Id: Iaeecea43c22805eca64b7d98751a52e607210a70
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/314080
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-07-17 16:51:25 +00:00
Joshua Litt 465d35fac9 [dart2wasm|js] Add support for JS backed subtypes of 64 bit typed data.
Change-Id: I534e946ffdfa6708af0c0ffdecb345adbc9561aa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313286
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
2023-07-13 15:29:37 +00:00
Joshua Litt 50c810e12c [js|dart2wasm] Add JS backed subtypes of Dart typed array classes.
Change-Id: I19a6d47bf857969abe2205e6b505b3a1dead5e3a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/310480
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
2023-07-10 18:11:02 +00:00
Liam Appelbe 13ec07415b [vm] Async FFI callbacks
More details about the design:
https://docs.google.com/document/d/1QDjyY_6wOTOgURwpeYMKU9qEz0gKxx2MUrdruC6Kp6c/edit?usp=sharing

Change-Id: Ie3985d86dca7f5010044ca46c33ca177588c0f69
Bug: #37022
CoreLibraryReviewExempt: Reviewed by vm and api groups. web and wasm groups not affected because FFI isn't on those platforms.
TEST=async_void_function_callbacks_test.dart, ffi_callback_metadata_test.cc, other front end tests
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/305900
Commit-Queue: Liam Appelbe <liama@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2023-06-28 01:00:18 +00:00
Devon Carew 9216f830c6 [deps] rev package:lints to the latest; address lints
Change-Id: I64032a39c589c291297decade18f6a46c08f9c5e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/310966
Commit-Queue: Devon Carew <devoncarew@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
2023-06-27 17:03:37 +00:00
Ömer Sinan Ağacan f041dd4af4 [dart2wasm] Simplify a list intrinsic
Change-Id: I769d33ac838a09350427dcdc14e3c2a6daf37cc0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311381
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-06-27 14:50:00 +00:00
Joshua Litt 64290e1052 [js] Add JSStringImpl box for JSString.
Change-Id: I63a2ecdf3fd2331f91632ae5b2cc51813cd44c66
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307961
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
2023-06-26 17:15:24 +00:00
Srujan Gaddam e985d991b1 [dart:js_interop] Fix JSNumber conversions/semantics and JSBoxedDartObject
- Adds toDartInt and toDartDouble to JSNumber
- Changes semantics of int on external functions from truncate to
assert integer value
- Adds tests for number semantics
- Renames JSExportedDartObject -> JSBoxedDartObject to avoid confusion
with @JSExport
- Adds Object.toJSBox

JSNumber.toDart and Object.toJS will be removed in a future CL once
migrations are complete.

CoreLibraryReviewExempt: Backend-specific library.
Change-Id: I8ff26ee5624c52703e49dd8483f62e829cb6fff0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/309081
Reviewed-by: Joshua Litt <joshualitt@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
2023-06-22 02:51:13 +00:00
Aske Simon Christensen 5838562040 [dart2wasm] Add option and target for stringref.
This adds basic infrastructure for a stringref implementation in
dart2wasm:

- A `--[no-]stringref` option to the compiler
- An option in the `WasmTarget`, controlling the name of the target
- Separate sets of patch files for the two targets
- Separate platform dill files for the two targets

For now, the patch file contents are the same, and the compiler flag
is not used by the backend (only by the `dart2wasm` script to select
the appropriate platform dill file). Both of these will change as the
implementation progresses.

Tested: ci + manual check that the option selects the correct dill
Change-Id: I2c9bb95ba06fd3de3f7007703ef545e3f0c728ba
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/310621
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
2023-06-21 14:25:38 +00:00
Ömer Sinan Ağacan 87a3de41b1 [dart2wasm] Implement micro-task scheduling
Use JS `setTimeout` for events and `queueMicrotask` for micro-tasks.

dart2js event loop implementation is copied in `run_wasm.js` to be able
to use `clearTimeout`, `setInterval`, `clearInterval`, and
`scheduleMicrotask`, which are not not available in d8, and `setTimeout`
in d8 does not wait before calling a callback.

New passing d8 tests:

- co19/LibTest/async/Future/Future.delayed_A01_t02
- co19/LibTest/async/Stream/Stream.periodic_A01_t01
- co19/LibTest/async/Stream/Stream.periodic_all_t01
- co19/LibTest/async/Stream/Stream.periodic_all_t02
- co19/LibTest/async/Stream/timeout_A04_t01
- co19/LibTest/async/StreamController/stream_all_A01_t01
- co19/LibTest/async/StreamController/stream_all_A01_t02
- co19/LibTest/async/StreamController/stream_all_A02_t01
- co19/LibTest/async/StreamController/stream_all_A02_t02
- co19/LibTest/async/StreamController/StreamController.broadcast_Stream_all_A01_t01
- co19/LibTest/async/StreamController/StreamController.broadcast_Stream_all_A01_t02
- co19/LibTest/async/StreamController/StreamController.broadcast_Stream_all_A02_t01
- co19/LibTest/async/StreamController/StreamController.broadcast_Stream_all_A02_t02
- co19/LibTest/async/Timer/Timer.periodic_A01_t01
- co19/LibTest/async/Timer/Timer_A01_t01
- co19/LibTest/core/Stopwatch/elapsedTicks_A01_t01
- language/async/call_test
- language/regress/regress21795_test
- lib/async/multiple_timer_test
- lib/async/periodic_timer2_test
- lib/async/periodic_timer3_test
- lib/async/periodic_timer4_test
- lib/async/schedule_microtask3_test
- lib/async/schedule_microtask_test
- lib/async/stream_timeout_test
- lib/async/timer_isActive_test
- lib/async/timer_repeat_test
- lib/async/timer_test

New passing Chrome tests:

- co19/LibTest/async/Stream/timeout_A04_t01
- language/async/call_test
- lib/async/schedule_microtask3_test

Tests below fail because of async* desugaring issues and will be fixed
separately:

- language/async_star/no_cancel2_test
- language/async_star/no_cancel_test

Tests below fail because of an existing issue (#29615):

- co19/LibTest/async/StreamController/StreamController.broadcast_Stream_all_A01_t03
- co19/LibTest/async/StreamController/StreamController.broadcast_Stream_all_A02_t03
- co19/LibTest/async/StreamController/stream_all_A02_t03

Fixes #51599.

Change-Id: Ib313e99bf3b3cb3bebeddc9e47dc77425ef94481
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/305201
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-06-19 10:21:35 +00:00
Srujan Gaddam 8f48ac3723 [dart:js_interop] Allow interop inline classes to elide @JS
Determines the ultimate representation type of an inline class to
determine if it can use external members. This allows users to
elide @JS if they don't need renaming. This CL adds some static
errors around inline interop members so its clearer that the
inline class should have an interop representation type.

There's a bit of cleanup in this CL too around interop members,
where extension members on @Native classes are now correctly
considered as interop members by the error checker.

Change-Id: I4d870d204933ea11b347ab5bb2e3de1b962f5ea3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308249
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
2023-06-13 23:27:23 +00:00
Ömer Sinan Ağacan b123b29335 [dart2wasm] Fix continue compilation in switch in async code generator
`continue` in `switch` statements need to be compiled the same way as
normal `continue`/`break` to run finalizers between the jump target and
the `continue`.

New passing test: co19/Language/Statements/Continue/async_loops_t10

Change-Id: I0cdff74b8b296691c8a90404b424487b00343427
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307780
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-06-08 17:12:51 +00:00
Ömer Sinan Ağacan e8f370ca4e [dart2wasm] Implement noSuchMethod on null receivers
New passing tests:

- language/closure/tearoff_dynamic_test
- language/no_such_method/native_test

Change-Id: I42449f3e238ab5ecd02504d65ff1a696a76bb7a3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307800
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-06-08 08:44:36 +00:00
Ömer Sinan Ağacan 8144a29966 [dart2wasm] Fix initializing exception variables
Currently setting exception variables in `catch` blocks assumes that the
variables are not captured and always creates a new local for the
variable.

This CL adds a new function for initializing a variables. The
implementation is similar to `VariableDeclration` visitor and handles
captured (updated or not updated) and non-captured variables. This
function is then used in `catch` blocks to initialize exception and
stack trace variables.

New passing tests:

- co19/LibTest/async/Zone/handleUncaughtError_A01_t04
- lib/async/future_test

Fixes #52556.

Change-Id: I428d8f30ab1509b5b4439f8136190134741dd4ba
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307042
Reviewed-by: Joshua Litt <joshualitt@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-06-07 09:34:17 +00:00
Srujan Gaddam 5b3a57908d [dart:js_interop] Remove ObjectLiteral
This annotation is unneeded as named arg external constructors
is enough to determine if an object literal is created. The one
exception is an empty object literal, but our guidance is to use
utility functions to create one instead. This is a better fit for
that purpose too as an interface for an empty object literal is
more uncommon.

CoreLibraryReviewExempt: Backend-specific library.
Change-Id: I10cf891601b28ff7e56129842d099ea28863626d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307506
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
2023-06-06 20:50:36 +00:00
Ömer Sinan Ağacan 877fe38f0c [dart2wasm] Fix runtime type tests
This was originally implemented in a289c4d but then reverted in dc33261
as it broke Flutter: https://github.com/flutter/flutter/issues/124282.

The problematic code in Flutter was updated, so landing the fix again.

Original commit message:

`emitTypeTest` optimizes a test like `x is List<T>` where `x :
Iterable<T>`, i.e. tested-against type is a subtype of the operand's
static type. In these cases we can check just the class ID of the
operand without checking the type arguments.

However this optimization cannot be done when the types don't have same
number of type arguments. Example:

    class H1<T> {}

    bool test(Object o) {
      return o is H1<num>;
    }

    void main() {
      print(test(H1<Object>()));
    }

Here `H1<num> <: Object`, but we still need to check the type parameter.

This CL checks that the types have the same number of type arguments
before optimizing the test.

Fixes #51187.

This fix reveals another bug in `static_interop_test`, which is tracked
in #51200. The test is updated to work around the bug for now.

New passing tests:

- co19/LanguageFeatures/Patterns/matching_cast_A01_t01
- co19/LanguageFeatures/Patterns/matching_list_A01_t01
- co19/LanguageFeatures/Patterns/matching_list_A01_t02
- co19/LanguageFeatures/Patterns/matching_list_A01_t03
- co19/LanguageFeatures/Patterns/matching_map_A01_t01
- co19/LanguageFeatures/Patterns/matching_map_A01_t02
- co19/LanguageFeatures/Patterns/matching_object_A01_t01
- co19/LanguageFeatures/Patterns/matching_object_A01_t02
- co19/LanguageFeatures/Patterns/record_A01_t03
- co19/LanguageFeatures/Patterns/record_A01_t06
- co19/LanguageFeatures/Patterns/record_A01_t07
- co19/LanguageFeatures/Patterns/record_A01_t08
- co19/LanguageFeatures/Patterns/record_A01_t09
- language/generic/deep_test
- language/generic_methods/type_expression_test
- language/patterns/object_pattern_inference_test

Change-Id: Ia08ef466f74c3c55a61d4dbf0088e4b43713ee1d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307046
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
2023-06-02 16:20:31 +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 0f49f23be4 [dart2wasm] Add support for testing in Chrome
d8 doesn't have some of the JS and HTML functions we need for event and
micro-task scheduling. In [1] we add mock functions to allow running in
d8, but that means the mock event loop can run differently than the
actual Chrome event loop, so we need to test in Chrome. This CL adds
support for this.

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

New failing tests with the new configuration:

language/nnbd/static_errors/unchecked_use_of_nullable_test/30 broke (RuntimeError -> Pass, expected RuntimeError)
language/regress/regress24935_test/01 broke (RuntimeError -> Pass, expected RuntimeError)
language/unsorted/flatten_test/01 broke (RuntimeError -> Pass, expected RuntimeError)
language/unsorted/flatten_test/05 broke (RuntimeError -> Pass, expected RuntimeError)
language/unsorted/flatten_test/09 broke (RuntimeError -> Pass, expected RuntimeError)
lib/js/export/static_interop_mock/proto_test is new and failed (CompileTimeError, expected Pass)
lib/js/static_interop_test/constants_test is new and failed (CompileTimeError, expected Pass)
lib/js/static_interop_test/futurevaluetype_test is new and failed (CompileTimeError, expected Pass)
lib/js/static_interop_test/supertype_transform_test is new and failed (CompileTimeError, expected Pass)

New passing tests with the new configuration:

co19/Language/Expressions/Function_Invocation/async_generator_invokation_t10 was fixed (Fail -> Pass)
co19/Language/Libraries_and_Scripts/Scripts/top_level_main_t01 was fixed (RuntimeError -> Pass)
co19/Language/Libraries_and_Scripts/Scripts/top_level_main_t06 was fixed (RuntimeError -> Pass)
co19/Language/Statements/Yield_and_Yield_Each/Yield/execution_async_A01_t07 was fixed (RuntimeError -> Pass)
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t03 was fixed (Fail -> Pass)
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t07 was fixed (Fail -> Pass)
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t08 was fixed (RuntimeError -> Pass)
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t09 was fixed (RuntimeError -> Pass)
co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_A03_t11 was fixed (Fail -> Pass)
co19/LibTest/async/Future/Future.delayed_A01_t02 was fixed (RuntimeError -> Pass)
co19/LibTest/async/Stream/Stream.periodic_A01_t01 was fixed (RuntimeError -> Pass)
co19/LibTest/async/Stream/Stream.periodic_all_t01 was fixed (RuntimeError -> Pass)
co19/LibTest/async/Stream/Stream.periodic_all_t02 was fixed (RuntimeError -> Pass)
co19/LibTest/async/Stream/Stream.periodic_all_t03 was fixed (RuntimeError -> Pass)
co19/LibTest/async/StreamController/StreamController.broadcast_Stream_all_A01_t01 was fixed (RuntimeError -> Pass)
co19/LibTest/async/StreamController/StreamController.broadcast_Stream_all_A01_t02 was fixed (RuntimeError -> Pass)
co19/LibTest/async/StreamController/StreamController.broadcast_Stream_all_A01_t03 was fixed (RuntimeError -> Pass)
co19/LibTest/async/StreamController/StreamController.broadcast_Stream_all_A02_t01 was fixed (RuntimeError -> Pass)
co19/LibTest/async/StreamController/StreamController.broadcast_Stream_all_A02_t02 was fixed (RuntimeError -> Pass)
co19/LibTest/async/StreamController/StreamController.broadcast_Stream_all_A02_t03 was fixed (RuntimeError -> Pass)
co19/LibTest/async/StreamController/stream_all_A01_t01 was fixed (RuntimeError -> Pass)
co19/LibTest/async/StreamController/stream_all_A01_t02 was fixed (RuntimeError -> Pass)
co19/LibTest/async/StreamController/stream_all_A02_t01 was fixed (RuntimeError -> Pass)
co19/LibTest/async/StreamController/stream_all_A02_t02 was fixed (RuntimeError -> Pass)
co19/LibTest/async/StreamController/stream_all_A02_t03 was fixed (RuntimeError -> Pass)
co19/LibTest/async/Timer/Timer.periodic_A01_t01 was fixed (RuntimeError -> Pass)
co19/LibTest/async/Timer/Timer_A01_t01 was fixed (RuntimeError -> Pass)
co19/LibTest/core/Stopwatch/elapsedTicks_A01_t01 was fixed (RuntimeError -> Pass)
corelib/throw_half_surrogate_pair_test/01 was fixed (NonUtf8Output -> RuntimeError)
corelib/throw_half_surrogate_pair_test/02 was fixed (NonUtf8Output -> RuntimeError)
language/async/return_throw_test was fixed (RuntimeError -> Pass)
language/async_star/async_star_await_for_test was fixed (RuntimeError -> Pass)
language/async_star/async_star_test was fixed (RuntimeError -> Pass)
language/async_star/yield_test was fixed (Fail -> Pass)
language/async_star/yieldstar_test was fixed (Fail -> Pass)
language/import/conditional_string_test is new and succeeded (Pass)
language/regress/regress21795_test was fixed (RuntimeError -> Pass)
language/regress/regress23244_test was fixed (RuntimeError -> Pass)
lib/async/multiple_timer_test was fixed (RuntimeError -> Pass)
lib/async/periodic_timer2_test was fixed (RuntimeError -> Pass)
lib/async/periodic_timer3_test was fixed (RuntimeError -> Pass)
lib/async/periodic_timer4_test was fixed (RuntimeError -> Pass)
lib/async/schedule_microtask_test was fixed (RuntimeError -> Pass)
lib/async/slow_consumer2_test succeeded again (Pass -> skipped)
lib/async/stream_timeout_test was fixed (RuntimeError -> skipped)
lib/async/timer_isActive_test was fixed (RuntimeError -> Pass)
lib/async/timer_repeat_test was fixed (RuntimeError -> Pass)
lib/async/timer_test was fixed (RuntimeError -> Pass)

Change-Id: I2c2f837b4a6093a1a9aad357df21a04a6907ab6f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/305941
Reviewed-by: Alexander Thomas <athom@google.com>
Reviewed-by: Jackson Gardner <jacksongardner@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-05-31 18:06:55 +00:00
Jackson Gardner 4a01368935 Add a flag to ConstConditionalSimplifier for removing asserts.
Change-Id: Ica31e595436181f013565516339ca1b97f6d5303
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/306305
Reviewed-by: Mayank Patke <fishythefish@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Jackson Gardner <jacksongardner@google.com>
2023-05-30 21:39:58 +00:00
Ömer Sinan Ağacan 0358d35db0 [dart2wasm] Fix completer type in async functions when the return type is FutureOr
New passing test: language/await/await_test

Change-Id: I44ac5a8d100e6b299cb9ebdc825e1e0562e15ba7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304920
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-05-24 08:49:29 +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
Srujan Gaddam 0d20f408d7 [pkg:_js_interop_checks] Refactor js_interop_checks
Does the following refactoring:

- Pares down visitor functions and moves larger blocks of logic into
helper functions
- Adds local functions for reporting to reduce the size of code that
reports diagnostics (all the 'report' functions)
- Organizes helper functions based on node type
- Adds static const variables for literals
- Marks variables that can be final as final
- Fixes/adds documentation for helper functions

There are some possible additional cleanups, like moving helper
functions to extensions and separating out state to mixins, but that
isn't necessary for now.

Change-Id: Ieebc1614aa427308d4aa4ef22c7577b05f4f4b4d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/302900
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
2023-05-23 16:05:08 +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 c74387a3a2 [dart2wasm] New async implementation
This CL re-implements the async function compilation without using JSPI
or any other platform features.

This implementation is faster than the JSPI-based one in all benchmarks,
in some cases up to 200x (benchmark results at the end). So we remove
the JSPI-based implementation as there's no point in maintaining a much
slower implementation and supporting two implementations at the same
time (which is tricky because these implementations need different
libraries, all scripts need to support two modes etc.) that also
requires experimental platform features.

# Main changes

- A new pass `AwaitTransformer` transforms `await` expressions to
  top-level statements in form `var <fresh variable> = await <simple
  expr>`, where `<simple expr>` is an expression without `await`.

  After this pass all `await` expressions have the simple continuation
  of "assign the value of the awaited future to this variable and
  continue with the next statement". This simplifies `await`
  compilation.

- A new code generator `AsyncCodeGenerator` (inherits from
  `CodeGenerator`) compiles `async` functions. The `_YieldFinder` class
  is copied from `sync*` code generator but modified to handle `async`
  expressions.

- Mentions to the V8 flag `--experimental-wasm-stack-switching` is
  removed from all scripts and documents.

# Future work

- Control flow handling in `AsyncCodeGenerator` needs to be implemented
  in a similar way in `SyncStarCodeGenerator`. Doing this without
  duplicating a lot of code will require some refactoring.

# New passing tests

- co19/Language/Statements/Yield_and_Yield_Each/Yield/execution_async_A05_t01
- co19/Language/Statements/For/Asynchronous_For_in/execution_A02_t02
- language/regress/regress23996_test
- language/sync_star/dcall_type_test

# Benchmarks

Current implementation:

```
AsyncLiveVars.LiveObj1(RunTime): 1586000.0 us.
AsyncLiveVars.LiveObj2(RunTime): 2114000.0 us.
AsyncLiveVars.LiveObj4(RunTime): 1972500.0 us.
AsyncLiveVars.LiveObj8(RunTime): 2212000.0 us.
AsyncLiveVars.LiveObj16(RunTime): 2238000.0 us.
AsyncLiveVars.LiveInt1(RunTime): 2362000.0 us.
AsyncLiveVars.LiveInt4(RunTime): 2470000.0 us.
AsyncLiveVars.LiveObj2Int2(RunTime): 2575000.0 us.
AsyncLiveVars.LiveObj4Int4(RunTime): 2820000.0 us.
Calls.AwaitAsyncCall(RunTimeRaw): 35676.15658362989 ns.
Calls.AwaitAsyncCallClosureTargetPolymorphic(RunTimeRaw): 38934.108527131786 ns.
Calls.AwaitAsyncCallInstanceTargetPolymorphic(RunTimeRaw): 42617.02127659575 ns.
Calls.AwaitFutureCall(RunTimeRaw): 2832.058906825262 ns.
Calls.AwaitFutureCallClosureTargetPolymorphic(RunTimeRaw): 3665.8125915080527 ns.
Calls.AwaitFutureCallInstanceTargetPolymorphic(RunTimeRaw): 4420.449537241076 ns.
Calls.AwaitFutureOrCall(RunTimeRaw): 3692.7621861152143 ns.
Calls.AwaitFutureOrCallClosureTargetPolymorphic(RunTimeRaw): 4625.346901017576 ns.
Calls.AwaitFutureOrCallInstanceTargetPolymorphic(RunTimeRaw): 4514.6726862302485 ns.
Calls.AwaitFutureOrCallInstanceTargetPolymorphicManyAwaits(RunTimeRaw): 345172.4137931034 ns.
Calls.AwaitForAsyncStarStreamPolymorphic(RunTimeRaw): 697000.0 ns.
Calls.AwaitForAsyncStarStreamPolymorphicManyYields(RunTimeRaw): 704666.6666666666 ns.
Calls.AwaitForManualStreamPolymorphic(RunTimeRaw): 11010.989010989011 ns.
Calls.SyncCall(RunTimeRaw): 0.40275240996973316 ns.
Calls.SyncCallClosureTarget(RunTimeRaw): 0.3989591156672242 ns.
Calls.SyncCallInstanceTargetPolymorphic(RunTimeRaw): 3.2632549336335526 ns.
Calls.IterableSyncStarIterablePolymorphic(RunTimeRaw): 353.3980582524272 ns.
Calls.IterableManualIterablePolymorphic(RunTimeRaw): 332.1161825726141 ns.
Calls.IterableManualIterablePolymorphicManyYields(RunTimeRaw): 354.28067078552516 ns.
```

New implementation:

```
AsyncLiveVars.LiveObj1(RunTime): 11327.683615819209 us.
AsyncLiveVars.LiveObj2(RunTime): 10923.91304347826 us.
AsyncLiveVars.LiveObj4(RunTime): 10956.284153005465 us.
AsyncLiveVars.LiveObj8(RunTime): 11286.516853932584 us.
AsyncLiveVars.LiveObj16(RunTime): 11445.714285714286 us.
AsyncLiveVars.LiveInt1(RunTime): 11016.483516483517 us.
AsyncLiveVars.LiveInt4(RunTime): 11327.683615819209 us.
AsyncLiveVars.LiveObj2Int2(RunTime): 10918.478260869566 us.
AsyncLiveVars.LiveObj4Int4(RunTime): 10737.967914438503 us.
Calls.AwaitAsyncCall(RunTimeRaw): 1082.2510822510822 ns.
Calls.AwaitAsyncCallClosureTargetPolymorphic(RunTimeRaw): 1056.4124234100993 ns.
Calls.AwaitAsyncCallInstanceTargetPolymorphic(RunTimeRaw): 1134.1726210729273 ns.
Calls.AwaitFutureCall(RunTimeRaw): 865.6509695290858 ns.
Calls.AwaitFutureCallClosureTargetPolymorphic(RunTimeRaw): 841.3967185527977 ns.
Calls.AwaitFutureCallInstanceTargetPolymorphic(RunTimeRaw): 839.066957543212 ns.
Calls.AwaitFutureOrCall(RunTimeRaw): 397.9941096871766 ns.
Calls.AwaitFutureOrCallClosureTargetPolymorphic(RunTimeRaw): 406.17384240454913 ns.
Calls.AwaitFutureOrCallInstanceTargetPolymorphic(RunTimeRaw): 393.7472929873607 ns.
Calls.AwaitFutureOrCallInstanceTargetPolymorphicManyAwaits(RunTimeRaw): 1095.0503723171266 ns.
Calls.AwaitForAsyncStarStreamPolymorphic(RunTimeRaw): 6643.426294820717 ns.
Calls.AwaitForAsyncStarStreamPolymorphicManyYields(RunTimeRaw): 7178.750897343863 ns.
Calls.AwaitForManualStreamPolymorphic(RunTimeRaw): 1456.23998835008 ns.
Calls.SyncCall(RunTimeRaw): 0.3919935321067202 ns.
Calls.SyncCallClosureTarget(RunTimeRaw): 0.3906669661780074 ns.
Calls.SyncCallInstanceTargetPolymorphic(RunTimeRaw): 3.1676143112814583 ns.
Calls.IterableSyncStarIterablePolymorphic(RunTimeRaw): 104.4932079414838 ns.
Calls.IterableManualIterablePolymorphic(RunTimeRaw): 104.57516339869281 ns.
Calls.IterableManualIterablePolymorphicManyYields(RunTimeRaw): 116.92487576731949 ns.
```

TEST=ci
CoreLibraryReviewExempt: Added entry-point pragmas.
Change-Id: I02fbd08141f51c00fb37b6fa0304dc25d6afdb71
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/301020
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: William Hesse <whesse@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
2023-05-22 08:32:12 +00:00
Srujan Gaddam eb8e3d549a [dart:js_interop] Add new diagnostic reporter so we can avoid transforms
Adds a delegating reporter so we can keep track of whether there are
interop errors. If there are, we do not do the transforms on the JS
backends.

Change-Id: Ib0f36b748443cb7fe8f8bb427692d653557d59fa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304261
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
2023-05-18 18:53:03 +00:00
Zach Anderson 1b9198c679 Revert "[dart:js_interop] Disallow ffi and JS interop in the same library"
This reverts commit 1c5d23e8a2.

Reason for revert: https://github.com/flutter/flutter/issues/127027

Original change's description:
> [dart:js_interop] Disallow ffi and JS interop in the same library
>
> dart2wasm can use both dart:ffi and JS interop libraries. To avoid
> confusion around external members, this disallows JS interop from
> being used in the same library as dart:ffi.
>
> Change-Id: I53e0426306be99c43b2bbfc14d65075128f0d5c5
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/301200
> Reviewed-by: Johnni Winther <johnniwinther@google.com>
> Reviewed-by: Joshua Litt <joshualitt@google.com>
> Commit-Queue: Srujan Gaddam <srujzs@google.com>

Change-Id: I1fd872e6d0cd679ec9c1842557745647385ec3af
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304100
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Zach Anderson <zra@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
2023-05-17 16:15:36 +00:00
Srujan Gaddam 1c5d23e8a2 [dart:js_interop] Disallow ffi and JS interop in the same library
dart2wasm can use both dart:ffi and JS interop libraries. To avoid
confusion around external members, this disallows JS interop from
being used in the same library as dart:ffi.

Change-Id: I53e0426306be99c43b2bbfc14d65075128f0d5c5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/301200
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
2023-05-16 22:50:46 +00:00
Ömer Sinan Ağacan 7bbe675971 [dart2wasm] Specify finalizer map concrete type
The map `breakFinalizers` need to have insertion-ordered iteration
otherwise creation of Wasm blocks when compiling try-finally blocks
won't work. Update the map type from `Map` to `LinkedHashMap` to make
this clear.

This doesn't change the concrete map type used as non-constant map
literals are already compiled to `LinkedHashMap`s, just makes the type
more precise for clarity.

Change-Id: Idebffe2f0f75232f5ef41729538ad3d2508c74c1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/294760
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
2023-05-12 09:31:28 +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
Joshua Litt e82a5a2ff3 [dart2wasm] Move entrypoint into the lib directory.
This CL will make it easier to consume `dart2wasm` as a library. Specifically, users can import `package:dart2wasm/dart2wasm.dart`, and call `main` from Dart libraries.

Change-Id: I9f5d5ab539677af2604df9d4b0e1e2d82db7485f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/300780
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
2023-05-03 16:45:32 +00:00
Srujan Gaddam c4d354dc2a Reland "[pkg:js/dart:js_interop] Move annotations to dart:_js_annotations"
This reverts commit 4919729f00.

This CL also adds back in logic to handle older package:js versions to avoid
failures in our static checking. It also supports dart:js_interop's @JS
annotation since it can now be used for @staticInterop classes.

CoreLibraryReviewExempt: Reland of backend-specific library changes.
Change-Id: I104653a9a6b2593f6bab658808287e2074c18550
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/294130
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
2023-05-02 15:24:18 +00:00