Commit Graph

2495 Commits

Author SHA1 Message Date
Jens Johansen abfa152cfc [kernel/DDC] DDC shouldn't crash when trying to translate line/column to offset for expresion compilation
Follow-up to https://dart-review.googlesource.com/c/sdk/+/446042.

Change-Id: Icfbaa763a6d6089a74f62088602c07c478520741
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/446420
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-08-24 23:50:07 -07:00
Nate Biggs e6f188b3fa [ddc] Avoid revisiting subexpressions during hot reload invocation rewriting.
In extreme cases with deeply nested invocations in closures, this can lead to an exponential recursive call pattern.

For example: https://github.com/spebbe/dartz/blob/8bf79e746d11e6a66c868027e5e1a25fdd270f45/lib/src/either.dart#L108

Moves all nested checks onto a single branch so that there is a single branch with no checks when the generation is the same, and another branch with all the necessary checks when the generation is different.

Bug: https://github.com/flutter/flutter/issues/173700
Change-Id: I3167a96e3ead67fd1d5c763ef2a7309d82c1a7c6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/445540
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-08-22 20:48:35 -07:00
Jens Johansen a79b7c6c35 [kernel/CFE/DDC] Remove old DartScopeBuilder; use new one
Change-Id: I4805c47958e2d4fbc19acbdada23cad014c3a747
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/446042
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
2025-08-21 23:14:41 -07:00
Srujan Gaddam 3b39c2637b [ddc] Separate _emitObjectLiteral out from _emitArgumentList
Currently _emitArgumentList handles arguments for Dart
members, JS interop members, and object literal constructors.
It requires an Arguments node, which we end up synthesizing,
which messes with parent pointers erroneously. We also have
to separate out the arguments and do additional checks later
to detect whether the arguments passed correspond to an
object literal constructor.

Instead, we should create the resulting expression directly
in a helper method. A map is passed so that the names of
arguments can be easily changed when we handle @JS renaming
on object literal constructors. Lastly, we need to avoid
wrapping the values with assertInterop in the case where the
constructor is from a dart:js_interop interface. That library
only statically allows Functions to be passed if they're
externalized, in which case we shouldn't tell users to wrap
the Function with allowInterop (which doesn't exist anyways in
dart:js_interop).

Change-Id: If6fdc706e80837ab2b698cca704ffd9f08aed28a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/446184
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
2025-08-21 15:25:57 -07:00
Jens Johansen 3175e427d8 [CFE] Keep const locals by default; expression evaluation can evaluate const locals
Note: Const locals are still off for VM aot and dart2js for the entry
points I've found in an attempt to retain the old behaviour there.
It might be better if those targets could remove such locals in a
whole-world analysis instead.

 * Keep const locals by default (except as noted above). Update the
   verifier to accept that. For the platforms this has increased the
   size by at most 6584 bytes. With this the VM will pass in any const
   locals as it does normal locals, but as the variable is never
   captured it will never pass a const local defined in a method when
   inside a local function in that method.
 * Change the dart scope calculation(s) to return the found variables
   instead of just the types of the found variables.
 * When the incremental compilers expression compilation - via the dart
   scope calculation - finds a const local that it wasn't told about, it
   will pass it on as an extra variable that it knows about, allowing
   for evaluating const locals in the case not covered by the first
   bullet.

With luck this can in future CLs be extended to know about other
variables that we're not told about, allowing to give a message saying
something like
"yes, we know what 'foo' is, but you can't currently use it" as wanted
in for instance https://github.com/dart-lang/sdk/issues/60316 and
https://github.com/dart-lang/sdk/issues/53996.

Tested: Existing tests for existing functionality; new tests for the new
Change-Id: I1ec24350273e6f81574bb2888f6bf46e3b8b1b47
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/445461
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
2025-08-19 04:30:41 -07:00
Paul Berry a0f467f0e9 Rename CFE Severity enum.
The analyzer already has an enum with the same name, but a slightly
different declaration. (The analyzer's enum declares only severities
of `error`, `warning`, and `info`, whereas the CFE's enum also
declares severities of `context`, `ignored`, and `internalProblem`).

I'm currently embarking on an arc of work that I hope will eventually
culminate in unifying the analyzer and CFE diagnostic message
representations (and their severities) into a single set of
classes. Until that unification is complete, both representations will
have to co-exist in the `_fe_analyzer_shared` package. To reduce
confusion during that time period, I would like the classes to have
distinct names.

Since the analyzer's `Severity` enum is exposed through the analyzer
public API, analyzer clients may depend on the name. So it makes sense
to rename the CFE's `Severity` enum.

Tested: standard trybots
Change-Id: I95622950f49b1754267e441e4636e046045629bb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/442102
Reviewed-by: Liam Appelbe <liama@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2025-08-04 14:23:39 -07:00
Paul Berry 111e84b958 Rename CFE DiagnosticMessage class.
The analyzer already has a class with the same name, but a slightly
different purpose. (The analyzer's class represents a single message
associated with a source location, whereas the CFE's class represents
a message along with related context messages).

I'm currently embarking on an arc of work that I hope will eventually
culminate in unifying the analyzer and CFE diagnostic message
representations into a single set of classes. Until that unification
is complete, both representations will have to co-exist in the
`_fe_analyzer_shared` package. To reduce confusion during that time
period, I would like the classes to have distinct names.

Since the analyzer's `DiagnosticMessage` class is exposed through the
analyzer public API, analyzer clients may depend on the name. So it
makes sense to rename the CFE's `DiagnosticMessage` class.

Tested: standard trybots
Change-Id: I6b6948fe9da18c7b6688333fa12ffeea8e81436f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/441831
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2025-08-04 11:20:23 -07:00
Paul Berry 7ac80be476 [front end] Remove type argument from class Code.
This type argument was never used. Removing it should make it easier
to make changes to the front end error message logic (and associated
code generator), which I intend to do as part of a long term plan to
make the analyzer and front end error reporting systems more
consistent, and eventually merge them.

Change-Id: I994cd2a74c5fd77df192f6a1f2dde46ba8a31883
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/442723
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2025-07-30 12:38:27 -07:00
Nicholas Shahan eb4619d139 [ddc] Add hot reload checks for instance methods
Handles errors and type changes on a hot reload when call sites
that were statically valid are retained and run after the reload.

Change-Id: I8bebbd7bc7acc97f55ff930e8f456f99146fbf21
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/440082
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
2025-07-28 16:16:06 -07:00
Nicholas Shahan 41ff6c38a6 [ddc] Refactor visitInstanceInvocation
This is in preparation to handle extra hot reload checks various
instance method invocations.

Change-Id: I9aaa9a29ec76c44466ce4b384a42ca980e7d8ca6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/440081
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
2025-07-28 16:16:06 -07:00
Nicholas Shahan b9d83b91d7 [ddc] Share some helpers methods
Moves helpers from local functions and instance methods in the compiler
to static extensions on kernel nodes. These can be shared between the
old and new compilers.

Change-Id: Ifc2b5fe8945753823d7671171673c6c7add1e8cd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/439806
Reviewed-by: Mark Zhou <markzipan@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
2025-07-28 16:16:06 -07:00
Nicholas Shahan 14bb2be360 [ddc] Optimize building type environments at runtime
* Avoids retrieving the instance type in more cases. In static class
  methods (including constructor tear offs)
  `dart_rti.instanceType(this)` was being used as the base of the
  environment binding. In these cases the result was the reified type
  of the JavaScript function. This worked as long as the base type of
  the binding is ignored, but it was not intuitive and had to fall
  through all the other cases before settling on that result.

* Avoids parsing a recipe for the `dynamic` every time when we already
  can have it available in our type table.

Compiled code examples:
Building the type `A<R, S>` from function type parameters `R` and `S`:

Now:
  `T.dynamic()[_bind](R)[_bind](S)[_eval]("A<1,2>")`
Previously:
  `dart_rti.instanceType(this)[_bind](R)[_bind](S)[_eval]("A<1,2>")`

Building the type `B<R>` from function type parameters `R`:

Now:
  `R[_eval]("B<0>")`
Previously:
  `dart_rti.instanceType(this)[_bind](R)[_eval]("B<N+1>")`
   where N is the number of type arguments of the enclosing class.

``
Change-Id: I213666edd7c6427f0d42d958541e53a798e8877c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/439460
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-07-10 13:08:45 -07:00
Chloe Stefantsova 433c0998d0 [cfe] Remove Nullability.legacy
TEST=existing

Change-Id: Id924e4ef64ddabc1986cb885f558382ff139b481
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/436620
Reviewed-by: Mayank Patke <fishythefish@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-07-02 23:50:12 -07:00
Nicholas Shahan 113df82c9f [ddc] Add validation to instance setter calls
Ensures soundness for instance setter calls after a hot reload.

Issue: https://github.com/dart-lang/sdk/issues/60100
Issue: https://github.com/dart-lang/sdk/issues/60112
Change-Id: Ie6736d002752076e5526bd37ae9f103040ed8cdd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/437124
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-06-30 17:46:09 -07:00
Nicholas Shahan 884a48c988 [ddc] Delete macro options and cli arguments
Change-Id: I83bd63f707758e82ac23a80b7442d57746f6b125
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/436941
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-06-25 15:21:55 -07:00
MarkZ 3d22f36b74 [ddc] Fixing cross module private name symbols redefining each other when used as function default values.
Fixes #60968

Change-Id: I0686da16b182f8a42e5fa0b55ced918671bdedca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/436001
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
2025-06-20 14:40:47 -07:00
Chloe Stefantsova 39810ffbe4 [cfe] Cleanup interface of subtype queries
Under the hood, there is no difference between
`isSubtypeWhenUsingNullabilities` and
`isSubtypeWhenIgnoringNullabilities` by now. This CL makes the
corresponding renames and removals in the CFE and its clients.

TEST=existing

Change-Id: I22060c29834179c30ba62562aa254146b1d7530d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/433480
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2025-06-13 02:02:54 -07:00
Nate Biggs 31dc969da2 [ddc] Test DartPad-like hot reload workflow.
Refactors the hot reload test suite to support non-FE server based hot reload. Similar to DartPad it uses a DDC process running in '--persistent_worker' mode and sends bazel requests for each reload.

I call this "stateless" mode because the compilation process itself is not maintaining any state. The necessary metadata is passed from one compilation to the other via a delta dill. This differs from the "stateful" mode where the FE server persists a kernel AST in memory from one compilation to the next.

Disregarding the browsers there are effectively 3 run modes now:
- web stateful
- web stateless (new)
- vm stateful

One key difference between the "stateless" and "stateful" modes is the output format of the JS files. In stateful mode DDC emits a file per library being re-compiled. In stateless mode DDC is emitting a single file with all the libraries.

DartPad's workflow is slightly simpler than what's seen in the stateless mode here. It only supports editing a single library so we skip processing any metadata. To simulate this I've added the special 'main_only' which passes a single library for each reload generation. I've verified that this would fail if not for the change recently made to ddc_module_loader.js.

Change-Id: If05da6dbeded4dd20e9e6d9dfaed52151541a19b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/434340
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
Reviewed-by: Kevin Moore <kevmoo@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-06-12 17:18:30 -07:00
MarkZ 40bf581c79 [ddc] Adding extraDdcOptions forwarder to frontend server.
Change-Id: Ie2ee13b6089f4f24957e9865d6c2fd7296ed7c30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/433261
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-06-12 14:43:52 -07:00
Nicholas Shahan 9cdc4a1963 [ddc] Reformat pkg/dev_compiler
Something seems wrong with the previous formatting. This change formats
with language version 3.8 again.

Change-Id: I077d635d815fa82ddf1153122ee3082787e1dd73
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/433301
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
2025-06-06 09:14:23 -07:00
MarkZ bbc99947c9 [ddc] Rolling internal dart_library.js into the external module loader.
Change-Id: If25fd9ac78d795d16b7edca507df0b806a0ebf39
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/433262
Commit-Queue: Mark Zhou <markzipan@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-06-06 07:20:10 -07:00
Nicholas Shahan 60d418034a [ddc] Bump language version to 3.8
* Reformat pkg/dev_compiler.
* Re-flow some comments to keep them within 80 characters.

Change-Id: I0849ce113ecf3dce4a2b4405c2b09a17dee4df76
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/433081
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-06-05 10:40:57 -07:00
Nicholas Shahan 6697075645 [ddc] Fix spelling typos
Change-Id: Iafcf14be1fd3032381b4ced2610230538100ce52
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/433080
Reviewed-by: Mark Zhou <markzipan@google.com>
2025-06-05 10:40:57 -07:00
Nate Biggs f7068a415e [ddc] Relax conditions on allowed defineLibrary calls during hot reload.
The current conditions make it so that every library transitively reachable from a reload target (and therefore included in the DDC output) must be known in the client when `dartDevEmbedder.hotReload` is called.

While this is the case for pages running with DWDS, it's an unnecessary constraint. Some users may only care about reloading a specific subset of known libraries. As is the case in dart-pad when we only need to reload the main library as we know this is the only code that can have changed.

Any new libraries must also registered and initialized as this is new code not yet in the page. This would happen if a new import was added to the code.

Change-Id: I164f59a6931fd809867716c164cb467880806f8c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/432440
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-06-03 12:02:03 -07:00
Nicholas Shahan 44e0d326a7 [ddc] Fix expression evaluation with wildcards
When wildcard method arguments should be removed from the scope before
attempting to evaluate an expression. Otherwise their names are invalid
and cause a Dart compile time error.

Add tests for all forms of wildcards in expression evaluation.

Change-Id: I21a7676a1495383926552a1039789f7d29256a67
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/431951
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-06-02 16:09:51 -07:00
Nicholas Shahan 1806e4ce65 [ddc] Use direct cast methods for primitive casts
The `_as` methods for primitive types are designed to be called from
both the `_as` selector and directly from generated code.

For the primitive types that are known at compile time and cannot change
via linking or hot reload, we can generate direct calls.

Adapted from https://dart-review.googlesource.com/c/sdk/+/420380

In addition to the base change:
* Remove `int` cast helpers from DDC only code in favor of the
  versions from dart:_rti.
* Moves existing optimizations from `visitAsExpression` to `_emitCast`
  to apply them consistently.

Change-Id: I13d24e3756400f2358556812728db17bc73f544a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427040
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
2025-05-28 10:07:26 -07:00
MarkZ b4ac0a183b Adding support for non-hot-reloadable packages in DDC.
These packages can be specified with the `non-hot-reloadable-package` flag and will be compiled without their members being properly hot reloadable. In exchange, we can perform additional optimizations (such as avoiding levels of indirection/checks in anticipation of their being updated).

This additionally overhauls our memory compiler to use the incremental compiler for proper state-passing hot reload testing + adds tests for this functionality.

Change-Id: Ief65896410f32655f064bd15728703629faa4051
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/428343
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
2025-05-23 17:37:20 -07:00
Nicholas Shahan f4c87f2ae8 [ddc] Add hot reload checks to instance getter accesses
Checks the compile and current hot reload generations. If they are not
equal the value is checked to have a getter of the expected name and
if so it gets called. If not, `.noSuchMethod` is invoked instead.

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

Change-Id: Ib80582b45f87f2ab41b943e0f263167b38601e0a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429066
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-05-22 13:27:31 -07:00
Nate Biggs e688981385 [ddc] Fix capture issue with temp names within async scopes.
`needsCapture` will ensure that any variables used within an async scope get included in the 'asyncScope' object that's created for that scope.

The variables used to lower Dart late variables in particular get emitted separately. But they can still be used across async scopes so they need the special capture logic as well.

Bug: https://github.com/dart-lang/sdk/issues/60748
Change-Id: I2486fce41f88f186fd799029c2cc59635f7ad8f5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429780
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
2025-05-21 17:49:22 -07:00
Nicholas Shahan 626b91344f [ddc] Delete _emitPropertySet
Move the specific implementation paths into `visitDynamicSet` and
`visitInstanceSet`.

Change-Id: I392f27c76c4f05df3dcfb7ed35ab9c390388f92e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429581
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-05-20 09:44:29 -07:00
Nate Biggs 0ccd9637bb [ddc] Add caching of ground type RTI objects in a module-local type table.
Change-Id: Ifcc8f5da277207bbb228ef30ca47d1ec42a67eb5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429180
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
2025-05-19 20:34:40 -07:00
Srujan Gaddam 55c5febc6a [DDC] Renamed captureHotReloadEndHandler to capturedHotReloadEndHandler
Keeping it consistent with capturedMainHandler.

Change-Id: I9fd05321fd6a49811739a8d07fa0e27558f03f27
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429541
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Auto-Submit: Srujan Gaddam <srujzs@google.com>
2025-05-19 15:01:43 -07:00
Srujan Gaddam 8f8ad12af6 [DDC] Allow deferring of hotReloadEnd via callback
This allows the application to set breakpoints in the
new scripts before pushing them into the Dart runtime.

Change-Id: Ica4613e061bf7db05b3e17366d3f3a4e0e46685d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429422
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Auto-Submit: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-05-19 12:46:50 -07:00
Nate Biggs b528c3fd60 [ddc] Inline code generated type universe lookups.
Change-Id: I6b0e3b8efee3318fffd200ae1a789565926948f1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429065
Commit-Queue: Mark Zhou <markzipan@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-05-19 11:13:38 -07:00
Nate Biggs 1326d75d58 [ddc] Add logic to expression compiler to look up variables in async scopes when available.
Bug: https://github.com/flutter/flutter/issues/168641
Change-Id: I1dec222ad8bedcec63656c3d3340d632591b65b1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/428720
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
2025-05-15 13:50:20 -07:00
Nicholas Shahan a2f785c3b7 [ddc] Update source mapping for static invocations
when they have been rewritten to include hot reload checks. Appears to
fix the issue detected in the dwds test failure.

Issue: https://github.com/dart-lang/webdev/issues/2617.

The new mapping ensures breakpoints applied to the call site in the Dart
source are the call site instead of the the generation check.

Allows the tooling to set a breakpoint on the static method call site,
and then when paused, a step-into will action will advance the program
into the static method.

In the future we will need to reevaluate how we generate code where a
single branch of execution in Dart source produces multiple branches in
JavaScript. I believe right now the tooling will not support creating
breakpoints in both branches even when they both have a mapping to the
same Dart source location.

Change-Id: I1ea0548768d8213dc7eefc332814d3bda7c81535
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427567
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
2025-05-13 13:46:14 -07:00
Nicholas Shahan 2ddf0c64f6 [ddc] Use prototype trick for better chrome performance
After emitting a library, creates a dummy function for each library and
sets the library object as the `.prototype` of the dummy function.

Reverses the performance degradation seen after adding one too many
members to the `dart:_runtime` library in:
https://golem.corp.goog/PerformanceChanges?repository=dart&revision=116131

According to sra@ this serves as a signal to V8 that the members of the
library should get optimized for fast lookup. These golem runs show
performance improvements that support this.

dartdevc performance improvements:
https://golem.corp.goog/Comparison?repository=dart#targetA%3Ddartdevc%3BmachineTypeA%3Dlinux-x64%3BrevisionA%3D116273%3BpatchA%3Dnshahan--ddc--WIP-library-as-prototype-optimization-1%3BtargetB%3Ddartdevc%3BmachineTypeB%3Dlinux-x64%3BrevisionB%3D116238%3BpatchB%3DNone

dartdevc-canary performance improvements:
https://golem.corp.goog/Comparison?repository=dart#targetA%3Ddartdevc-canary%3BmachineTypeA%3Dlinux-x64%3BrevisionA%3D116273%3BpatchA%3Dnshahan--ddc--WIP-library-as-prototype-optimization-1%3BtargetB%3Ddartdevc-canary%3BmachineTypeB%3Dlinux-x64%3BrevisionB%3D116238%3BpatchB%3DNone

Change-Id: Ifee464e393609c30eff4ea7c19da511134eccdcf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427822
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-05-12 16:41:38 -07:00
Nicholas Shahan b03f3b7b8d [ddc] Reland refactor visitInstanceGetterInvocation()
Moves the remaining special case logic out of `_emitMethodCall()`
simplifying the reasoning about where so hot reload soundness checks
can be added.

The original change exposed a latent soundness bug that allowed for
some dynamic getter invocations to be performed without runtime checks.

This reland adds adds a note about the newly enforced runtime checks to
the CHANGELOG.

Change-Id: I387438b8615e60f73dfc5e3b883b8c6d5a9993da
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425942
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
2025-05-02 16:57:28 -07:00
MarkZ 028914a3ef [ddc] Emitting embedder link functions via symbol property.
Fixes errors when top level 'link' members exist.

Change-Id: I0a339298ff9f51f6cd1f6af7c983eeda4a013956
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426002
Commit-Queue: Mark Zhou <markzipan@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-05-02 15:00:17 -07:00
Nicholas Shahan 6127d6cb8f [ddc] Add checks to static invocations in closures
Previously, code in a closure was compiled with the assumption that
invocations known to be statically sound didn't need any runtime checks
to guaranty soundness.

Now, if the code is retained from an earlier compile and executed after
a hot reload, any assumptions regarding soundness may be invalid.

This change transforms what was an invocation expression into a larger
expression that performs additional checks (similar to a dynamic call).

All checks are skipped if the compile generation matches the current hot
reload generation at runtime.

The soundness checks are handled by a new runtime helper method
`hotReloadCorrectnessChecks`. Any argument expressions are hoisted into
let variables to preserve their evaluation order and to ensure they are
only evaluated once. The helper checks for the existence of the
invocation target, the shape of the method signature, and runtime type
of the passed arguments. Mismatches result in an invocation of
`NoSuchMethod`. Any returned value is cast to the expected static type
of the original invocation.

Change-Id: If925f1a9b475d5ac581b2526403ab7c95753ffef
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421640
Reviewed-by: Jens Johansen <jensj@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-05-02 12:52:05 -07:00
MarkZ 2284e20fcf [ddc] Adding IndexedDB to auto-loaded libraries with global side effects.
Change-Id: If5e0fdd6c269c1933018b741813d180c8d62c660
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425660
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
2025-04-30 11:37:22 -07:00
Srujan Gaddam c497d099db [ddc] Add hot restart initializers to a pending map instead
It is possible with the way the library manager is written
today that during a hot restart, a previously defined library
may be initialized. Because the manager uses the same map
to store the initializers for the non-hot restart case and
the hot restart case, we may end up using a newer version of
code in an older generation. Instead, this CL adds a pending
map that stores the hot restart initializers so that we can
later add them to the general map of initializers right before
we call main during a hot restart and during synchronous code.
This should avoid that race condition.

Change-Id: Ib40cbe5bec400035276ebd6fca12efed7077a2b8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425190
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-04-29 17:11:45 -07:00
Srujan Gaddam 8ac1fbdd07 [ddc] Emit call to register source maps in DDC library bundle format
- Sets the name field in the emitted LibraryBundle node to
to the provided module name. We tried to avoid providing a
module name as the notion doesn't map cleanly to library
bundles, but we need to respect the provided module name.
- Emits a call to set the source map for a given library
bundle url. We don't need the full trackLibraries call so we
don't use it.
- Adds a check to avoid redefining libraries outside of a hot
reload or a hot restart. This was handled in the same code
where we emitted trackLibraries calls in the old compiler
for dynamic modules, but we want this for all code, regardless
of whether dynamic modules is enabled. So, add this check in
the library manager instead.

Change-Id: Ic4e86dbfca2b3eefa99cce44fae0973164ab77a5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423620
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-04-29 17:11:45 -07:00
Nicholas Shahan c31a282435 Revert "[ddc] Refactor visitInstanceGetterInvocation()"
This reverts commit 776c0586aa.

Reason for revert: Broke test in google3

Original change's description:
> [ddc] Refactor `visitInstanceGetterInvocation()`
>
> Moves the remaining special case logic out of `_emitMethodCall()`
> simplifying the reasoning about where so hot reload soundness checks
> can be added.
>
> Change-Id: I13e2f451e61f6e067ea689bcc35039cf92946492
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423603
> Reviewed-by: Mark Zhou <markzipan@google.com>
> Reviewed-by: Nate Biggs <natebiggs@google.com>
> Commit-Queue: Nicholas Shahan <nshahan@google.com>

Change-Id: I67d35d085e9b9510547aff8fb16ac0a8ed44d6df
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425404
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
2025-04-29 14:16:38 -07:00
Nicholas Shahan be6d2e3a00 [ddc] Cancel futures after a hot restart
Outstanding async code now checks and cancels itself if it was created
in a previous version of the application from before a hot restart
operation. This includes outstanding `Future`s created by calling the
`dart:js_util` helper `promiseToFuture`.

Issue: https://github.com/flutter/flutter/issues/166004
Change-Id: I342bbd2f8eda6b58d2f0fdaf3c00f55f03561b1a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423961
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-04-28 23:25:56 -07:00
Nicholas Shahan 776c0586aa [ddc] Refactor visitInstanceGetterInvocation()
Moves the remaining special case logic out of `_emitMethodCall()`
simplifying the reasoning about where so hot reload soundness checks
can be added.

Change-Id: I13e2f451e61f6e067ea689bcc35039cf92946492
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423603
Reviewed-by: Mark Zhou <markzipan@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-04-28 17:42:43 -07:00
Nicholas Shahan 29b6a03388 [ddc] Refactor visitDynamicInvocation()
Create a new helper `_emitArgumentGroups()` used for the calling
conventions where arguments are not passed in a flattened list.

Towards reducing the variety of code that flows through
`_emitMethodCall()` so hot reload soundness checks can be added when
they are appropriate.

Change-Id: I50ef9c4d54d71408d71b76fc2ca0acb73ef2af08
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/422367
Reviewed-by: Mark Zhou <markzipan@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-04-28 16:34:10 -07:00
Nicholas Shahan 8fb9578d95 [ddc] Refactor function invocation visitors
`visitFunctionInvocation()` and `visitLocalFunctionInvocation()` now
emit code directly.

Towards reducing the variety of code that flows through
`_emitMethodCall()` so hot reload soundness checks can be added when
they are appropriate.

Change-Id: I11e7fef6a454509a18f570bc2a316e81b9e09f2a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/422365
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
2025-04-24 14:43:29 -07:00
MarkZ cd20b29917 [reload_test] Resolving d8 timer problems in the reload suite.
d8 tests weren't executing code after a hot restart due to several factors:
1) subsequent calls to `main` after a hot restart weren't being added to an event loop.
2) periodic timers, which use `setInterval` weren't updated to check for the hot restart generation.
3) d8's simulated timers run synchronously, which interacts poorly with our async implementation. Periodic timers never cede to the async task that handles changing hot restart generation, so they would run forever whenever an error was thrown.

Changes:
* Added a helper to d8.js that cancels all timers.
* d8 now cancels all timers if an async main registers an error (via a handler on main).
* `setInterval` is now implemented.
* The embedder now accepts a publicly modifiable config object. `capturedMainHandler` and `mainErrorCallback` can be set via this object.

Change-Id: I523752ea69e8fd1f1ec0f6f585a484b670534cfc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421680
Commit-Queue: Mark Zhou <markzipan@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
2025-04-18 15:08:48 -07:00
MarkZ 23cefd8aa9 [ddc] Adding support for hot reloaded super getters.
This removes the 'bind' and 'bindCall' methods in our runtime in favor of extending 'tearoff' to support their behavior. Also introduces 'superTearoff' for invoking torn off super members late.

Change-Id: I52ab797558a225c57cc2c6197c7b1bfa7f05a3c6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/416763
Commit-Queue: Mark Zhou <markzipan@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
2025-04-04 11:17:56 -07:00