Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Semantics of dart:js_interops Function.toJS extension #55515

Closed
mkustermann opened this issue Apr 19, 2024 · 2 comments
Closed

Semantics of dart:js_interops Function.toJS extension #55515

mkustermann opened this issue Apr 19, 2024 · 2 comments
Assignees
Labels
area-web Use area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop. web-js-interop Issues that impact all js interop

Comments

@mkustermann
Copy link
Member

The toJS extension method on Function from dart:js_interop seems to behave differently across backends:

  • In wasm we simply make a JS function that will call the wasm function - handled via kernel transformer on callsites
    => See here & here
  • In ddc it seems to use allowInterop() and therefore maintain identity (allowInterop uses Expandos in ddc)
    => See here & here
  • In dart2js it seems to also use allowInterop() and therefore maintain identity (allowInterop uses different mechanism, not Expandos here)
    => See here and here

From the discussion at flutter/flutter#143396 I infer that allowInterop shouldn't be needed in the new static interop world. Meaning we don't want to maintain identities when things flow back into dart.

For performance reasons it's also much better not to use Expandos etc when making a callback.

So

  • either dart2js/ddc can avoid maintaining identity for dart:js_interops Function.toJS extension method implementation
  • or we we need to make dart2wasm maintain identities, in which case I'm going to ask for a new API that does not require maintaining identities

/cc @srujzs @sigmundch

@mkustermann mkustermann added the area-web Use area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop. label Apr 19, 2024
@sigmundch sigmundch added the web-js-interop Issues that impact all js interop label Apr 19, 2024
@sigmundch
Copy link
Member

Sounds great to me to use an alternative to allowinterop.

@srujzs and I were discussing this also for a separate reason: the default implementation of allowInterop uses Function.apply when the callback is invoked from JS. This is expensive and we can clearly do better here. We'd like to have specialized conversions for very common callbacks (e.g. callbacks of 0, 1, and 2 args), which can then avoid using the dynamic Function.apply dispatch mechanism.

Small piece of context: for the old package:js interop, allowInterop needed the expando to provide consistent semantics between DDC and dart2js. Without it, DDC was being more permissive than dart2js, which is a bad recipe: we want to detect any issues early during development. Dart2js uses a different representation of closures and needed allowInterop to convert the representation. However, because in DDC Dart closures are JavaScript closures, missing the allowInterop on an API call used to go undetected. We added the expando to properly check that allowInterop was used.

The new interop can make this distinction statically, so it shouldn't need that mechanism anymore.

@srujzs
Copy link
Contributor

srujzs commented Apr 22, 2024

Agreed that we should be consistent here with identity. A potentially common instance where this might come up that might be an issue is event listeners. addEventListener(f.toJS); removeEventListener(f.toJS); will do different things depending on the platform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-web Use area-web for Dart web related issues, including the DDC and dart2js compilers and JS interop. web-js-interop Issues that impact all js interop
Projects
Status: Done
Development

No branches or pull requests

3 participants