-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add specialized JS-interop method calls #39740
Comments
I wonder if we could use a type parameter to combine T callMethodX<T>(String name, dynamic arg1, ..., dynamic argX); On an offline discussion @jakemac53 was suggesting to do a kernel transformer to make this more transparent. We'd add all the methods above, but a transformer would convert callMethod(name, [1, 2, 3]);
var y = callMethod(name, [1, 2])
into callVoid3(name, 1, 2, 3);
var y = callMethod2(name, 1, 2); Because at the kernel level we can generate code accessing private members, we could in fact add all these methods as private members instead. This would mean that our changes would not be visible and it would be possible to change it again in the future without a breaking change if we are not satisfied with it. |
I'm not sure. The effect I'm looking for is that we do not call |
I'm am not saying I like this, but one could do: return T == Null ? null : _convertToDart(r); The decision is made at runtime at that point. |
At that point we might as well add a named parameter to indicate whether you want the return value converted :) |
Adding a |
unfortunately, I believe we can't use |
ya it would require some compiler magic |
Adding I would be careful relying on Do we need all the features of |
I too would prefer we go down the route of making it possible to use The minimum change here would be to move @yjbanov - do |
@hterkelsen just checked, and |
Can it actually land in our current state of affairs? That is, |
I think the proposal was to create a Then we could rewrite the package:js usage when creating the SDK. |
Yes - I just misunderstood @yjbanov message and thought he was implying that you were planning on landing it before we do the work to move things into the |
Sorry for the confusion. What I meant was we're poised to adopt this new feature as soon as it's available. Currently JS interop is the single biggest performance killer for our WASM backend. We're basically just sitting and refreshing this page waiting for the status of this issue to go from open to fixed 😃 |
BTW, the more I look at our profiles the more I'm convinced that moving js.JsObject makeSkRect(ui.Rect rect) {
return js.JsObject(canvasKit['LTRBRect'],
<double>[rect.left, rect.top, rect.right, rect.bottom]);
}
js.JsObject makeSkRRect(ui.RRect rrect) {
return js.JsObject.jsify({
'rect': makeSkRect(rrect.outerRect),
'rx1': rrect.tlRadiusX,
'ry1': rrect.tlRadiusY,
'rx2': rrect.trRadiusX,
'ry2': rrect.trRadiusY,
'rx3': rrect.brRadiusX,
'ry3': rrect.brRadiusY,
'rx4': rrect.blRadiusX,
'ry4': rrect.blRadiusY,
});
} Profile: |
@sigmundch @rakudrama @natebosch - (1) Would moving (2) We'd need to modify DDC and Dart2JS to special case |
If we decide to not break existing JS interop, and we we decide that the future of JS interop looks slightly different then moving it now will add technical debt that we need to live with until Dart 3. In any place we need to understand the presence of an If the exported version of the annotation becomes our golden path, we risk breaking old usages if we forget to check for both sources somewhere. We won't have test coverage of the old |
Yes, I don't see any reason we couldn't make it work. As long as we keep the @natebosch is correct that we'll have some tax to lookup either annotation to preserve the backward compatibility with the old package:js, but I feel that's a small price to pay. *1 note: there is a different
True, we could invest in adding a way to test in the sdk some code with the old package:js (using an old pinned copy) I imagine the new
Same - I don't expect this to be a hard change. |
I've always been bad with names. :-)
For DDC, it may suffice to just add an additional test for https://github.com/dart-lang/sdk/blob/master/pkg/dev_compiler/lib/src/kernel/js_interop.dart#L14 |
quick follow up - in a design discussion today we made a determination: rather than reexporting them from The compiler work to support both annotations is needed regardless to be backwards compatible, but creating a second copy makes it easier to be future compatible and avoid a breaking change until we decide what the future of |
Thanks for the follow-up. Will the duplicate annotations' API surface and semantics be identical to that of |
Yes, that's would be the goal - Since the library is private, for a long time you'll be the only user of those annotations (from dart:ui), so we'll make sure it works for you :) |
@sigmundch @natebosch @rakudrama - can we list the breaking changes we are considering? E.g., support for dynamic dispatch, extending JS, implementing JS, etc. |
Thanks for the reminder @vsmenon We are planning changes for js-interop in the next few months. We still have to iron out the design, so we don't plan to enforce any new checks at this time. However, it would be great if any uses you have in
|
Those restrictions look fine to me. What's the difference between the "no is" and "all anonymous" restrictions? |
Almost no practical difference, but we may be removing bits that affect each one separately. non-anonymous js-interop classes expose a constructor name to dart, both dart2js and ddc use it to construct the instances, and only ddc uses it for is checks. Avoiding them will make it easier to ensure that you are under the same semantics in ddc and dart2js today. We haven't decided whether we intend to keep the constructor capability in the future. For |
Attempt at fixing #39740 to allow the flutter web engine to use @js interop to avoid the overhead of the SDK available js interop. Bug: 39740 Change-Id: I7ba9c8981e639cd267bee3086ba900b89bfc0d6f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150501 Reviewed-by: Stephen Adams <sra@google.com> Commit-Queue: Harry Terkelsen <het@google.com>
Closing this as |
In Flutter we see quite a bit of overhead in JS-interop method calls when using
JsObject.callMethod
. Currently on our CanvasKit rendering backend the call overhead can reach up to 80% of the total time it takes to do all the rendering work in our paint phase.Here's a sample profile (notice the blue gaps of activity in between the yellow/green of useful work):
Here's a zoom in into a sequence of value conversions that are happening:
As you can see there are a lot of conversions happening, particularly around wrapping and unwrapping argument lists, and unwrapping return values.
In most cases we know exactly the method we call and the number of arguments we pass, so there's no need to wrap arguments in a list. In many cases there is no return value (
void
) and so there is no need to wrap it.Proposal
Add specialized
callMethodX
andcallVoidX
methods toJsObject
with the following signatures:These methods should all be efficient and inlineable.
Examples of Flutter engine code that does a lot of JS interop:
/cc @sigmundch @rakudrama @jakemac53 @natebosch @jonahwilliams
The text was updated successfully, but these errors were encountered: