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

Unexpected capture of EngineLayer when capturing int value #50593

Closed
gaaclarke opened this issue Dec 1, 2022 · 3 comments
Closed

Unexpected capture of EngineLayer when capturing int value #50593

gaaclarke opened this issue Dec 1, 2022 · 3 comments

Comments

@gaaclarke
Copy link
Contributor

observed behavior

The following code executes fine:

  @override
  void initState() {
    super.initState();
    _getAgent().then((agent) async {
      final String? decoded =
          await agent.query((state) => state.decodedMessages[0]);
      if (mounted) {
        setState(() {
          _text = decoded;
        });
      }
    });
  }

If I change the integer literal to index, the app errors:

  @override
  void initState() {
    super.initState();
    final int index = widget.index;
    _getAgent().then((agent) async {
      final String? decoded =
          await agent.query((state) => state.decodedMessages[index]);
      if (mounted) {
        setState(() {
          _text = decoded;
        });
      }
    });
  }

error log

[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): Illegal argument in isolate message: (object extends NativeWrapper - Library:'dart:ui' Class: EngineLayer)
#0      _SendPort._sendInternal (dart:isolate-patch/isolate_patch.dart:249:43)
#1      _SendPort.send (dart:isolate-patch/isolate_patch.dart:230:5)
#2      Agent.query (package:isolate_agents/isolate_agents.dart:104:15)
#3      _MessageState.initState.<anonymous closure> (package:romeo_juliet/main.dart:144:23)
<asynchronous suspension>

expected behavior

Since I am copying the widget.index value to its own integer, I expect that to get captured, not the widget and thus no error about capturing and sending ui elements to an Isolate.

@mraleph
Copy link
Member

mraleph commented Dec 1, 2022

Duplicate of #36983

@mraleph mraleph marked this as a duplicate of #36983 Dec 1, 2022
@mraleph mraleph closed this as completed Dec 1, 2022
@mraleph
Copy link
Member

mraleph commented Dec 1, 2022

tldr: Dart VM creates contexts from scopes, rather than creating a context pre-closure. This makes closures that share the same scope overcapture things, e.g.

void f() {
  var x, y;
  foo() => x;
  bar() => y;
}
// Both [foo] and [bar] capture x & y.

@gaaclarke
Copy link
Contributor Author

I moved the crux of this issue over to that one since I think this is a novel problem for a known issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants