Skip to content

allowInterop is no longer idempotent in DDC in dev build #38311

@greglittlefield-wf

Description

@greglittlefield-wf

Calling allowInterop on the return value of allowInterop used to return the same function but it doesn't in DDC in the dev build of the SDK.

Reproduced with

  • Dart SDK 2.6.0-dev.0.0
  • build_web_compilers 2.3.0

Reduced test case:

function() {}
final once = allowInterop(function);
final twice = allowInterop(once);
print(identical(once, twice)); // prints false

This issue does not reproduce in dart2js, or in 2.5.0 DDC/dart2js.

allowInterop implementation and compiled result, for reference

DDC source code for allowInterop:

F allowInterop<F extends Function>(F f) {
var ret = _interopExpando[f];
if (ret == null) {
ret = JS(
'',
'function (...args) {'
' return #(#, args);'
'}',
dart.dcall,
f);
_interopExpando[f] = ret;
}
return ret;
}

DDC-compiled code for allowInterop:

  js.allowInterop = function allowInterop(F, f) {
    let ret = js._interopExpando._get(f);
    if (ret == null) {
      ret = function(...args) {
        return dart.dcall(f, args);
      };
      js._interopExpando._set(f, ret);
    }
    return F._check(ret);
  };

Could the issue be that the F._check check on the return value is creating a new instance that the expando doesn't know about? Edit: never mind, I was thinking about the Expando wrong. It stores the converted function on f, not ret.

Metadata

Metadata

Assignees

Labels

P2A bug or feature request we're likely to work onarea-web-jsIssues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop.web-js-interopIssues that impact all js interop

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions