wasm-opt doesn't optimize `0 < x || x > y` when y is known to be
positive (e.g. a positive integer constant), so we do it manually.
We also do it in a few places where `y` is not known to be positive in
the Wasm code, but we know it's always positive, for example when it's a
length.
Example improvement in the wasm-opt output:
```
(func $_newArrayLengthCheck (;426;) (param $var0 i64) (result i64)
local.get $var0
i64.const 2147483647
- i64.le_s
- local.get $var0
- i64.const 0
- i64.ge_s
- i32.and
- i32.eqz
+ i64.gt_u
if
i32.const 46
i32.const 0
@@ -19190,13 +19172,8 @@
i64.const 97
i64.sub
local.tee $var3
- i64.const 0
- i64.ge_s
- local.get $var3
i64.const 5
- i64.le_s
- i32.and
- i32.eqz
+ i64.gt_u
if
local.get $var0
local.get $var6
@@ -19810,10 +19787,10 @@
global.get $global4
array.new_fixed $Array<_Type> 2
)
```
Closes#56083.
Change-Id: Idb1dd0d0809b26be8aec3d082aa341c59e1a353d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/373663
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
In the previous version of this change, if the user had 'dart' on their
PATH and invoked 'dart compile js' (which spawns the VM service after
compilation completes), the VM service would attempt to spawn DDS using
'./dart' as the executable path instead of 'dart'. This would result in
DDS failing to start, causing the VM to print an error and hang.
This updated change checks to see if the parent directory of
`Platform.executable` is '.' and then verifies if './dart' exists or
not. If it doesn't, 'dart' is likely on the user's PATH and should be
used directly as the executable path.
See https://github.com/dart-lang/sdk/issues/56087 for details.
This reverts commit 4b88698e48.
TEST=pkg/dds/test/control_web_server_starts_dds_with_dart_on_path_test.dart
Change-Id: Id0f1dadd01d9202cbf7717f31393b43171cf3968
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/373561
Auto-Submit: Ben Konyi <bkonyi@google.com>
Reviewed-by: Derek Xu <derekx@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
Since null safety, all static fields with initializers are implicitly
late. This change cleans up transition_sentinel which was used in
the detection of cyclic initialization of legacy static fields.
TEST=ci
Change-Id: I6a990dc8ba030f5bd40eb0b86706cbfb0f725e33
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/373520
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
The docs are currently broken because the inherited docs contain
references to the parameter, `newLength`, but in the overridden
setters, there is no such parameter:
https://api.dart.dev/stable/3.4.4/dart-svg/NumberList/length.html
CoreLibraryReviewExempt: No-op.
Change-Id: I27388847109adeef66cdc1ef2e4faedeac5390d9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372522
Commit-Queue: Sam Rawlins <srawlins@google.com>
Auto-Submit: Sam Rawlins <srawlins@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Lowers these extension methods to some helper functions instead of
allowInterop to improve performance and get consistent semantics.
Specifically:
- Function.toJS no longer gives you the same JSFunction when calling
toJS on the same function multiple times in the JS compilers.
- Adds fast calling syntax for functions with 0-5 args in the JS
compilers.
- Allows additional args to be passed to converted functions that
are omitted in the JS compilers.
- The static type now determines the number of args that can be
passed to the JS function in the JS compilers.
- Fixes an issue in dart2wasm where if too few arguments are
passed, the call may succeed due to conversion of undefined to
null.
- Adds throws when a user tries to wrap a JS function that
returned from Function.toJS in the JS compilers.
Closes https://github.com/dart-lang/sdk/issues/55515
Addresses https://github.com/dart-lang/sdk/issues/48186
CoreLibraryReviewExempt: Changes to docs only in API surface.
Change-Id: I41d864dc5e02b597d9f1c16c88e3c04872f28225
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/368065
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This reverts commit 64d4689a78.
Reason for revert: Platform.executable doesn't return a path, just an executable name, which can cause breakages.
TEST=ci
Original change's description:
> [ Service ] Start DDS and serve DevTools when the VM service is started via dart:developer
>
> TEST=pkg/dds/test/control_web_server_starts_dds_test.dart
>
> Change-Id: I2e51783592912e5a719685f2ab5e7537b7a59586
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/366560
> Commit-Queue: Ben Konyi <bkonyi@google.com>
> Reviewed-by: Derek Xu <derekx@google.com>
Change-Id: I4ceaee4b5ca8f5557e90cd914ee69fe9aa5f85a7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/373381
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Derek Xu <derekx@google.com>
Commit-Queue: Siva Annamalai <asiva@google.com>
Closes https://github.com/dart-lang/sdk/issues/55342
Closes https://github.com/dart-lang/sdk/issues/55536
Closes https://github.com/dart-lang/sdk/issues/56015
- Adds a type parameter T that extends Object? to
ExternalDartReference to capture the type of the value
that was externalized.
-- In the JS compilers, the representation type of
ExternalDartReference is now T.
-- In dart2wasm, the representation type is now JSValue?.
- ExternalDartReference no longer implements Object.
- Return type of toDartObject is now T.
- ObjectToExternalDartReference and
ExternalDartReferenceToObject both now are on a T that is
bound to Object?.
- Internal patches for WeakReference and Finalizer are
updated.
Change-Id: Ic2dc834b17ec6a4eb2122cba3c495a6e0a1eae6e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/370663
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
If a `String` is not a `StringBase` it must be a `JSStringImpl`.
Using `unsafeCast` instead of `as` improves generated code as it avoids
calling the "as" function for casting to `JSStringImpl`.
Change-Id: Idba4f44fc44b7715c4433262dd0eab25d062d2d0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/373244
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Since these operators can't be written by users, prefer
to keep them as JS types.
Closes https://github.com/dart-lang/sdk/issues/55267
Change-Id: Ifb9b581fb82e057ba14c669a5a3934f9c502d06f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/359181
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
This fixes an issue with runtime blob that created arguments
array for `main()`: the JS referenced a now (after [0]) no longer
existing `stringToDartString` function.
Instead of having a runtime blob at all for the dealing of `main` we
simply give the JS array to the `invokeMain` function which can use
normal JS interop to transform it to a `List<String>`.
=> This avoids the need to export `$getMain`, `$makeStringList` and the
`buildArgsList` JS function.
[0] https://dart-review.googlesource.com/c/sdk/+/372660
Change-Id: I665e60ab93a4f8ed9de5fc135ed0e68514f2af5a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372461
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
The single loader does the same thing here:
ef59500e6f/sdk/lib/_internal/js_runtime/lib/js_helper.dart (L3257)
This retry token acts as a cache-buster for requests where the download succeeded but the part file was corrupted and failed to initialize. In that case Chrome has to re-download the file, it can't use the cached file.
I just missed passing this parameter when I added the new multiloader.
b/348644880
Change-Id: I26f4bc0da6c7e6fd714f442df8d32b8f10678047
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372700
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
Auto-Submit: Nate Biggs <natebiggs@google.com>
This removes the special runtime blob for string conversions, instead we
make 2 functions for conversions use our built-in `JS<>()` support.
This will allow specializing the implementation in a future CL.
Change-Id: I06df25ed805042c0a3e2efb966eaebd1ce67dc0c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372660
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
This WasmArray-backed list classes to `dart:_list`, similar to
`dart:_string` and `dart:_typed_data`
This will allow having internally-public list members like unchecked
getters and setters that we will use in the rest of the standard
library.
This CL doesn't add anything new, just renames things.
- `dart.core._ListBase` -> `dart._list.WasmListBase`
This is to avoid confusion with `dart.core.ListBase` (defined by Dart
standard library), and also to be consistent with `WasmTypedDataBase`
and `WasmStringBase`.
- `dart.core._List` -> `dart._list.ModifiableFixedLengthList`
Similar to the above, to avoid confusion with `dart.core.List`.
- `GrowableList.ofOther` -> `GrowableList.fromIterable`
`ofOther` sounds like it should make a growable list from another
growable list, but the type is more general than that. To reflect what
it actually does we call it `fromIterable`.
Tested: Existing tests.
Change-Id: I24398765e1b0d549fc70b03ba94161479c5fc54c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372622
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Since sound null safety, 'vm:non-nullable-result-type' pragma is
no longer useful as the same information is conveyed by a non-nullable
return type.
TEST=ci
Change-Id: Ie6a61aca38cfea47cb005b12ca7f0d7631791024
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372200
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
CoreLibraryReviewExempt: Trivial change.
Change-Id: I5c23641ed562efe51c0c7c35517ba75fffdd05ad
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372503
Reviewed-by: Kevin Moore <kevmoo@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
Add new string extensions with unchecked `codeUnitAt` and `substring`
methods.
Replace old unchecked functions `oneByteStringCodeUnitAtUnchecked` and
others with the extension methods.
Most of the CL replaces old functions with extensions. New uses are only
introduced in `dart:convert`.
Change-Id: I44151bbc65c0bf4467d88911f8a088bbe1910eaa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372443
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
This moves `JSStringImpl` class from `dart:_js_types` to `dart:_string`.
This allows implementing a common base class with unchecked operations
to all string classes as internal methods (so users won't be able to
call them via `dyanmic`), and extension methods to call these unchecked
methods in libraries like `dart:convert`.
Uses of these methods are introduced in
https://dart-review.googlesource.com/c/sdk/+/372443.
Change-Id: Ie4cfe778654c42d62bc4a90391fe349fa783a42c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372442
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
Currently code uses `double` to represent array indices, array lengths
etc. This seems wrong because `double`s can loose precision. This is
also a high overhead.
Understandably one could use `double` and only start to loose precision
with more than 32 bits, but realistically string lenghts, array lengths
cannot exceed 31-bits (i.e. 2 GBs) in practice.
=> Use Wasmi32 to represent array indices, array lengths, bytes loaded
from integer arrays, ...
Change-Id: Ife540622c85118d890a8e487677db56e2ce06f5a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372424
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
Adds an interface which implements both `TypedData`
and `List`. That allows abstracting over types that are both
`List` and `TypedData` without losing access to one of the
interfaces.
Tested: typed_data_interface_test.dart
Change-Id: Idbdfc084ea5d2d9a072887973e2e9d29a5fd94ce
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371100
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
Reviewed-by: Nate Bosch <nbosch@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
Flow graph builder implementation of certain dart:math and Double
methods is now used unconditionally, so corresponding native
methods are never used and can be removed.
This is a follow-up to
https://dart-review.googlesource.com/c/sdk/+/371980.
TEST=ci
Change-Id: Ibca2729f70f39af26a899d99724ce62efc3c8dae
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372180
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
18994e6e46 removed unmodifiable view classes in the standard library
that can make any implementation of `ByteData` and other typed_data
types unmodifiable.
Add a `_immutable` field to `JSDataViewImpl`, implement
`asUnmodifiableView`.
An alternative implementation would be adding a subcalss with overridden
setters. However I think a simple boolean flag check should be better,
as adding a subtype can make call sites polymorphic and prevent direct
calls and inlining.
(We can't do the same in native typed_data types because we allocate
Wasm arrays with different element types for the fastest possible
implementation in the common cases, so we need different `ByteData`
implementations for different Wasm array types.)
Bug: #56014
Change-Id: I674121cff14559128bc2a9deb318a3bc6adf316d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372082
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
This removes the outer check in `List<int>` element check:
```
if (allowMalformed) {
... check code units in `List<int>`, write 0xFF for invalid bytes ...
} else {
... check code units in `List<int>`, throw for invalid bytes ...
}
```
and moves the `allowMalformed` check to the inside of the loop, when the
`int` value is negative or more then 255.
`allowMalformed` in UTF8 is used for two things:
1. To allow invalid bytes in `List<int>` argument.
2. To allow invalid UTF-8 encodings.
Both of these will happen rarely, but (1) will almost never happen as
any code that cares about performance will pass a `Uint8List`. So it
makes sense to assume that (1) will hold very rarely, and optimize based
on that.
Change-Id: I3ecec24d29d1cc2ec8f986a87ac3e7d609002d89
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372060
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
In theory, such casts should be optimized out, but in some
cases, they might not be (DDC or lower optimization flags).
Instead, we should use the primary constructor and
representation field to go between the representation type
and the JS type. Similarly, we do unnecessary casts in
dart2wasm to convert JSValue to the right JS type. We can
avoid those by directly calling the primary constructor.
Change-Id: I8fdac18f6d634b379e70951fe5d3a1ed7ad4bf15
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371423
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
The Dart != check lowers to !== in JS. The RTI property doesn't
exist in the JS function, so the result is undefined. However,
undefined !== null returns true, so JS functions are accidentally
treated as Dart functions. This fixes that.
Change-Id: I4c4e0018768c0ac29f4b5ee228c504b7cb0b7232
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/369200
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Use `U16List` instead of `Uint16List` as the character buffer type.
Access the Wasm array directly when writing characters and converting
the final buffer to a String. This avoids bounds checks and uses
`array.copy` when allocating the final string.
Change-Id: I570494e8349adc7a268544544516c9947abc8604
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371681
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
This affects very common string interpolation expressions where we now
avoid creating arrays and looping over arrays and casting references
when getting things out of arrays.
e.g. `StringBuffer.write()` uses "$obj" in it's implementation
which will benefit from this.
Change-Id: Ie6615e5f76a4a8ccb4ff9aa85c05c7e39eab6f00
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371660
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
The buffer type is always `Uint8List`, improve the type from `List<int>`
to `Uint8List`.
Tested: existing tests
Change-Id: I03ad84a0f1fe1ade8a46719545f3c33eeccd99b7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371402
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
In most cases, the (now removed) SDK class was patched so that the constructor redirected to a platform-specific implementation of the unmodifiable view. Uses of the SDK class in the platform code could be rewritten to the more direct use of the implementation class.
The big +/- file changes are from moving the implementation classes from the patch file (typed_data_patch.dart), where they are no longer needed, to the internal file (typed_data.dart).
TEST=ci
Bug: #53785
Change-Id: Iaa7370de25b7fc2d26b24f7733c2892868e593cb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/370661
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Brian Quinlan <bquinlan@google.com>
- Use unchecked reads when reading from `U8List` chunks.
- Use unchecked reads when reading from "transition table" in UTF16 decoder.
- Fix a typo in a comment.
Tested: performance refactoring, covered by existing tests.
Change-Id: I1b90781f2b419188d6a560994159b48faad16075
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371301
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
The flutter platform file is compiled slightly differently from the way
we compile the normal SDK platform file. This slight difference -
somehow related to how -D environments are used in CFE - results in a
constant `VariableDeclaration` to stay in the kernel in flutter's case
but not in the Dart SDK's case.
(All usages of constant variables / fields will be
`ConstantExpression(<const>)` instead of
`VariableGet(<constant-variable>)`)
That in itself causes the kernel verifier AST visitor (which we call
from `pkg/dart2wasm/lib/compile.dart` in assertion mode enabled) to
report an error.
=> To work around this issue we hoist the only variable affected by this
to top-level.
=> That will allow us to run the dart2wasm compiler in assertions mode
on flutter apps without hitting the verifier problem.
(This has very likely to do with the fact that in flutter's case the
variable must result in an `UnevaluatedConstant` which then at a later
stage gets evaluated whereas in Dart's case we do that eagerly).
There's no easy way to write a test for this, as normal test files will
have an environment and therefore don't result in unevaluated constants
afaik.
Change-Id: I883b91bdc37ede8b45e35a15d0dddc296d9da9ba
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371340
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This CL adds a new --interop-null-assertions flag (cf.
--native-null-assertions) with the goal of validating that JS interop
APIs with non-nullable static return types do not return null values.
This flag is currently disabled by default but is intended to assist in
sound null safety migrations.
In general, we don't guarantee type soundness of package:js interop
since users can write incorrect static types which are not backed by
any runtime checks. However, it is likely that during the null safety
migration, some interop APIs which should have been made nullable
weren't. Therefore, we want to offer some additional (but limited)
checking for this case.
For static invocations of functions with non-nullable return types, we
can simply perform a null check on the result of the call.
For instance methods (which could be invoked virtually/dynamically), we
want to perform a null check on the return value in the callee (the
interceptor method) itself when possible.
It's possible for multiple interop bindings to share the same
interceptor method. We produce a null check in the interceptor method
body if all the methods have non-nullable return types. Otherwise, we
insert checks at callsites when appropriate.
Change-Id: Ifd155d7f8326152b6d57d61199e0b7973c4a1211
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/369784
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Mayank Patke <fishythefish@google.com>
Use `WasmArray<WasmI8>` for number buffer when decoding numbers.
This saves one allocation when growing the number buffer and on initial
allocation of the buffer, and eliminates one layer of indirection when
writing to the buffer.
Change-Id: Ic210bc13072f0dd34918361a1bee8c7b29ce61cd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371064
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Removes risk of DDS connection information being split across two stream
events, causing JSON decoding to fail.
Also updates DDS to close stderr, even in the error case.
TEST=Existing service and dartdev tests
Change-Id: I5cceab899aac1fa63bd7578dd658b34096722bd3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371000
Reviewed-by: Derek Xu <derekx@google.com>