Currently a dynamic call will call a helper which will create
3 array objects (for type, positional and named arguments).
It will then pass those wasm arrays to type checker methods.
Those will then get values out of the array, type check and call
the target.
We change this now such that in the normal case (**) we avoid
the array creations. Instead we make a dynamic forwarder function
per target and call shape.
We also outline the array creation when creating `Invocation`
objects. So for simple caller shapes - such as `clone()` the
creation of an `Invocation` object is a call without arguments
instead of various array creations.
Issue https://github.com/dart-lang/sdk/issues/62640
(**) If the dynamic call could be call-via-field we still create
those arrays, as we use them for closure type checking.
Change-Id: Ia8f3f3cd95f650bd8706a15ed68a43db4de80a6e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/487020
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Adding in an extra test just to make sure this isn't
possible. Don't know if we already have a test for this,
but I couldn't find anything.
Change-Id: Id2ce089e070cc139389e805f1b8b7f987a438bfd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486525
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
This uses MemberLookupResult instead of Builder as the result for BodyBuilderContext.lookupConstructor. This allows for a more precise handling of error cases and avoids reporting cascading error in case of duplicate constructors.
Change-Id: I465747883af594870cb0663e80a188e6dd1b552b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486202
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
This adds isRedirectingInitializer and isSuperInitializer to the Initializer hierarchy and adds flags to InvalidInitializer to signal when the InvalidInitializer should be taking as a redirecting or super initializer. This allows us to avoid miscatergorizing such declarations when they are erroneous.
Part of #61700
TEST=existing
Change-Id: If0fabbda10b72304999a5380fce74f9e8fa91ca4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486180
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Language tests for the following:
- A compile-time error occurs if an assignment to a primary parameter
occurs in the initializer list of the body part of a primary
constructor.
- A compile-time error occurs if an instance variable declaration has an
initializing expression, and it is also initialized by an element in the
initializer list of the body part, or by an initializing formal of the
primary constructor.
- The modifier `final` on a parameter in a declaring constructor
specifies that the instance variable declaration which is induced by
this declaring constructor parameter is `final`.
- A compile-time error occurs if a class, enum, or extension type has a
primary constructor whose name is also the name of a constructor
declared in the body.
- Extension types are allowed to have non-redirecting generative
constructors, implicitly or explicitly initializing the representation
variable.
- A compile-time error occurs if a class, mixin class, enum, or
extension type declares a primary constructor whose name is `C.n`, and
the body declares a static member whose basename is `n`.
- Consider a factory constructor declaration of the form `factory C(...`
optionally starting with the modifier `const`. Assume that `C` is the
name of the enclosing class, mixin class, enum, or extension type. In
this situation, the declaration declares a constructor whose name is
`C`. The rule which is being tested here is also applicable when the
declaration has some of the keywords external and augment, but we don't
test those kinds of constructors here.
- It is an error to have multiple primary constructor bodies.
- Tests for type inference of declaring parameters in primary
constructors, including override inference and inference from default
values.
Bug: https://github.com/dart-lang/sdk/issues/61687
Change-Id: If804c99c317ab53643420e00d6dc266720bca2f1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/483626
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Dart2wasm started using RTA to significantly speed up compilation.
However, a side effect of this is less exact type info during TFA.
In _invokeMain we conditionally use some js-interop logic when a
program's main takes arguments. On the web, most programs don't expect
any arguments so this is usually dead code. However, RTA sees
_invokeInternal is live and blindly treats all reachable classes as live
including the unused interop helper types in the other branches.
This code refactors the patching logic to make sure only the relevant
entry point is considered live.
This change uncovered a different bug that was suppressed by these
implicitly instantiated types. Dart2wasm was not marking some internally
instantiated classes as allocated in the function logic so entries in
the dispatch table were empty for those types. Instead any time we
generate the code for a constructor (which may not be reached via a
ConstructorInvocation like we were assuming before), we record the class
as allocated.
Change-Id: I556d3733c00b4a3e3455fa1ee2c90206d54c81f4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/484540
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Validate @Native annotations on extension and extension type instance
members by modeling the receiver as the first Dart parameter when
checking the full function type against the FFI signature.
This aligns analyzer diagnostics with CFE behavior for extension-like
members (issue #60250), while preserving the pointer-receiver
restriction diagnostic behavior introduced by #62716.
Fixes: https://github.com/dart-lang/sdk/issues/60250
TEST=tests/ffi/static_checks/regress_60250_test.dart
TEST=tests/ffi/static_checks/regress_62716_test.dart
TEST=pkg/analyzer/test/src/diagnostics/ffi_native_test.dart
R=davidmorgan@google.com
Change-Id: I688f338f47aa1f6670afce2cb4d4d4f88e3816ab
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/482160
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Auto-Submit: Shanu Kumawat <shanu.kumawat.dev@gmail.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
dart2js and DDC implement `identical` using JS `===`. This means for
interop values the objects will be compared using JS strict equality
semantics. For Strings in particular this means value equality rather
than reference equality.
In wasm we use equality on the struct reference wrapping the JS value.
This leads to differing semantics between JS and wasm when using
identical on these JS wrapped values.
`jsIdentical` provides a way to have consistent semantics between JS and
wasm.
Change-Id: I207fbbb294254798372924a55cdb2691094a5461
CoreLibraryReviewExempt: Just updating web-related code.
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/483440
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
As a preparation for evaluating instance field initializers in classes
with primary constructors, where you can reference formal parameters of
these primary constructors.
Change-Id: I8c1276ec9ae7b2f5950a1abefb7cb8492a736dfd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/483843
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Closes https://github.com/dart-lang/sdk/issues/62573
isA<JSExportedDartFunction>() used to just check if the object
was a function, leading to a possible runtime error if `toDart`
is called. Fixes that by introducing some helpers and moving
around some functions in the JS compilers to other internal
libraries (public members can't be added to
js_allow_interop_patch.dart). Also fixes a minor issue in dart2js
where `allowInterop`ed functions could successfully invoke
`JSExportedDartFunction.toDart`.
CoreLibraryReviewExempt: Documentation change.
Change-Id: I5a9d7c31d3143eb3fb6ebd3273a4bf06ca329479
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/482967
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
This updates JS exception catching as discussed in #55481:
- Only catch JS exceptions when the exception type is `dynamic`,
`Object`, or an extension of `JSValue`. (nullable or not)
(Previously we also caught JS exceptions when the type is `Error`.)
- When the JS value caught in Wasm is `null` or `undefined`, box it as a
non-interop class. For compatibility with dart2js, this class is
copied from dart2js and has the same `toString` as the dart2js class.
- In other cases: box the JS values as `JSValue`. This means the value
can be passed as any of the interop types, and can be passed back to
JS without manual jsification.
Fixes#55481.
Issue: https://github.com/dart-lang/sdk/issues/55481
Change-Id: I23e73074729f740b90df2ca8b3c713fb39966556
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/479640
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
A forwarding stub can have a covariant type parameter while the same
type parameter in its forwarding stub target is non-covariant.
We should still check bounds of such type parameters
(the bound to check is taken from the forwarding stub target).
TEST=tests/language/regress/regress62664_test.dart
Fixes https://github.com/dart-lang/sdk/issues/62664
Change-Id: I86eeb9f8a537c22fb473388f9b17f55084af6366
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/482480
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Adds a language test and a flow analysis unit test to cover a flow
analysis behavior of post-increment and post-decrement operators that
wasn't previously covered.
The tests verify that the expressions `x++` and `x--` demote `x` in
the same way that `x = x + 1` and `x = x - 1` would. This demotion is
only user-visible if the type of `x` is a user-defined type.
In the process of writing these tests, I noticed that the "mini-AST"
implementation of post-increment (which is used solely for flow
analysis unit testing) was not correct; it presumed that the type read
from the target, the type written to it, and the type of the whole
expression were all the same. This is not correct; the type written to
the target is determined by the return type of the `+` operator. I've
fixed this as part of this CL so that the unit test properly exercises
flow analysis.
I will follow this up with some refactoring of how flow analysis
handles post increment/decrement operations. Landing the test first
allows us to be confident that the refactor won't change the tested
behavior.
Change-Id: I6a6a6964417b48db0c1681c06d7418bd79e96357
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/482342
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Tests the following:
- A compile-time error occurs if an assignment to a primary parameter
occurs in the initializing expression of a non-late instance variable.
- A compile-time error occurs if a declaration has a primary constructor
with an initializing formal and no instance variable of the same name.
- Declaring parameters named `_` cannot be declared multiple times in a primary constructor.
- Wildcard variables cannot be referenced in the initializing
expressions of non-late instance variables or in the initializer list of
the body part of the primary constructor.
- Declaring parameters named `_` are allowed. Accessing `_` is valid in
the body part of a primary constructor if there's an instance variable
with the name `_`.
Bug: https://github.com/dart-lang/language/issues/4634, https://github.com/dart-lang/sdk/issues/61687
Change-Id: Id2cb98bd78e31292894610b595174fa682bdc1ae
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/481321
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
- The dependencies of a class should also include the initializers for its fields. These are used to initialize the class object. And they are not represented in the constructor Initializers list.
- Super gets/sets/invocations should all visit their children as well. These aren't leaf nodes.
Change-Id: I552bc87cf1bbc35b11b0dd7bcbd167b2fa5bcbe7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/481680
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This CL adds implementation of the static analysis of anonymous methods
whose body is of the form `=> e`. Block bodies are still rejected by a
`UnimplementedError` exception.
Flow analysis is rudimentary, but this might be sufficiuent for the
particular kind of anonymous methods which are covered by this CL. In
particular, it does not cause assigned local variables to be marked as
non-promotable in enclosing scopes, and it does allow local variables
promoted in the anonymous method body to preserve their promotions after
the anonymous method invocation.
Note that the change in `_resolveReceiver` is needed because the old code relied on looking up the syntactically enclosing class or extension in order to determine the type of `this`, but that is incorrect when `this` may be the type of the receiver of an enclosing anonymous method.
Change-Id: I3d2bd6d104015a6e310e9ce061c7b4109002a1b2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/480840
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
Fixes https://github.com/dart-lang/sdk/issues/56905
Instead of just supporting isJSAny and isJSObject, we
can support isA for all objects. Depending on the static
type, we include an intrinsic _isJSAny function first in
the transformation. For fast paths for JSObjects, we also
now call an intrinsic function which has the added benefit
of now correctly returning true for objects with no prototype.
The intrinsic functions in dart2wasm need to be careful to
not treat ExternalDartReferences as JS values, so JSValue
is amended to include a field that determines if the value
is a Dart value (and caches it if not set already). JSValue
constructions are updated to pass false for this field if
we know for sure this value isn't an externalized Dart value.
CoreLibraryReviewExempt: Backend-specific function changes.
Change-Id: Ib2a6e74b4130632791375fcda9a5b85198ad64af
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/478241
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Today "dummy values" are generated per-module to stand in for things
like default parameter sentinels (where a given selector has multiple
default values for an optional parameter).
However, these values can end up crossing between modules. The logic is
set up to use ref_eq to check if an argument is one of these dummy
values. However, if one of these dummy values crosses between modules,
the passed value vs the ref_eq checked value will be different. Since
each module has its own canonical dummy value per type.
This new layout simplifies our handling of these dummy values by
treating them as Constants so that our normal module canonicalization
logic applies to them. We already have plenty of logic to canonicalize
constants across modules. This avoids the need for custom handling of
these dummy value globals.
Change-Id: Ia9c79923c788d7712b16705193ffbf3142141b5d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/480320
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
Add more Wasm SIMD intrinsics and instructions to support efficient
vector operations, specifically targeting the requirements of types
like Offset and Size.
- Implement new intrinsics in `dart2wasm`:
- `anyTrue` for V128.
- `allTrue` for I64x2.
- `pmin`/`pmax` (pseudo-minimum/maximum) for F64x2.
- `fromLaneValues` for F32x4 and F64x2.
- `shuffle` for F64x2.
- Update `wasm_builder` with support for the following instructions:
- `v128.any_true`
- `i8x16.all_true`, `i16x8.all_true`, `i32x4.all_true`, `i64x2.all_true`
- `i8x16.shuffle` (including serialization and deserialization)
- Add `tests/web/wasm/simd/vector_test.dart`, which implements `Offset`
and `Size` using these new SIMD intrinsics, demonstrating their
practical utility and correctness.
- Update `tests/web/wasm/simd/simd_test.dart` with additional coverage.
Change-Id: Ifa5ba0fb265b0fa46c0a3469d9331f32a025c9ec
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/478860
Commit-Queue: Kevin Moore <kevmoo@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Not removing from any file with a language marker.
Also not touching anything in `tests/language/primary_constructors`
or `.../private_named_parameters`, which are both assumed to be
primary constructor feature aware.
Two files rewritten from multi-test to error-test.
Change-Id: I43d444a35a41c7734f266794e9f167655692473f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/480640
Reviewed-by: Nate Bosch <nbosch@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
If a mixin application class gets copies of the members of a mixin, the
copies may reside in a different library. That means the copied member
body's references to import prefixes are "dangling" (or "pointing" to a
prefix of a different library).
We had a fast case: If there's no deferred import in a library we didn't
visit the body to lower `CheckLibraryIsLoaded` AST nodes.
=> We remove this optimization which will fix the bug.
=> Long term libraries may be allowed to refer prefixes of other
libraries (as part of work on [0])
[0] https://github.com/dart-lang/sdk/issues/61764
Fixes https://github.com/dart-lang/sdk/issues/62683
Change-Id: I74e81418ff2df176ff5481ea36f3b68ab3df4d4b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/480940
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
Ensure loop-local variables introduced by `for` parts are bound
consistently during resolution, while still reporting reads that occur
before the declaration point.
The resolver now predeclares `ForPartsWithDeclarations` variables in the
loop’s local scope before traversing the initializer/condition/updaters.
This makes lexical lookup within `forLoopParts` resolve to the
loop-local element (even in `var x = x`), and allows later verification
to correctly report `REFERENCED_BEFORE_DECLARATION` instead of treating
the name as outer/undefined.
Also align foreach resolution by defining the declared loop variable
only after visiting the iterable expression, and update error
verification to hide not-yet-declared elements consistently for blocks,
switch members, and `for` parts via a generalized
`HiddenElements.forElements` helper.
Change-Id: Ifab327737bb033fe05f1d765196796924378ac5e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/480120
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>