Skip to content

Unexpected Unbox in async functions #273

@Zverik

Description

@Zverik

As you can see, I got Unbox(L-1).

RUNTIME STATE
=============
Program offset: 3521
Stack sample: [L4: $"", L5: $1, L6: null, L7: 0, L8: $StatelessWidget$bridge, L9: 0, L10:
$StatelessWidget$bridge, *L11: null, L12: null, L13: null]
Args sample: []
Call stack: [0, -1]
TRACE:
(Added some more lines for context)
PushScope (F87:371, 'MyWidget.test()')
PushObjectProperty (L1.C0)
PushReturnValue ()
InvokeDynamic (L2.C1)
PushReturnValue ()
PushConstant (C2)
BoxString (L4)
PushArg (L4)
InvokeDynamic (L3.C3)
3515: PushReturnValue ()
3516: Return (L5)
3517: Pop (1)
3518: PushScope (F87:484, 'MyWidget.filterByString()')
3519: PushObjectProperty (L0.C4)
3520: PushReturnValue ()
3521: Unbox (L-1)  <<< EXCEPTION
3522: JumpConstant (@3534)
3523: PushScope (F87:371, '<test() tearoff>')
3524: PushConstantInt (0)
IndexList (L0[L2])
PushArg (L3)
PushArg (L1)
PushConstantInt (0)
IndexList (L0[L4])
InvokeDynamic (L5.C5)
PushReturnValue ()

Here are the functions in question (methods of a class):

          bool test(Option o) {
            return o.title.toLowerCase().contains('cha');
          }
          
          Iterable<Option> filterByString(String text) {
            return List.of(_options.where(test));
          }

This is a deep stage of trying to circumvent this issue. Before that, the method looked like this:

         Iterable<Option> filterByString(String text) {
            return List.of(_options.where((o) => o.title.toLowerCase().contains(text)));
          }

and the stack was similar, but with positive L7, however wrong, given it tried to unbox a function:

The following RuntimeException was thrown running a test:
dart_eval runtime exception: UnimplementedError
#0      EvalFunction.$value (package:dart_eval/src/eval/runtime/function.dart:41:25)
#1      Unbox.run (package:dart_eval/src/eval/runtime/ops/primitives.dart:356:59)
#2      Runtime.bridgeCall (package:dart_eval/src/eval/runtime/runtime.dart:831:12)
at MyWidget.filterByString()
at <anonymous closure>

RUNTIME STATE
=============
Program offset: 3534
Stack sample: [L4: $"", L5: $1, L6: null, L7: 0, L8: $StatelessWidget$bridge, L9: 0, L10:
$StatelessWidget$bridge, *L11: null, L12: null, L13: null]
Args sample: []
Call stack: [0, -1]
TRACE:
(Added some more lines)
PushScope (F87:371, 'MyWidget.filterByString()')
PushObjectProperty (L0.C0)
PushReturnValue ()
JumpConstant (@3525)
PushScope (F87:460, '<anonymous closure>')
PushObjectProperty (L1.C1)
PushReturnValue ()
PushArg (L2)
InvokeDynamic (L2.C2)
PushReturnValue ()
PushConstantInt (1)
IndexList (L0[L4])
Unbox (L5)
PushArg (L3)
PushArg (L5)
InvokeDynamic (L3.C3)
PushReturnValue ()
Return (L6)
Pop (5)
3525: PushConstantInt (1)
3526: PushArg (L3)
3527: PushConstantInt (4)
3528: PushArg (L4)
3529: PushConstantInt (5)
3530: PushArg (L5)
3531: PushConstantInt (6)
3532: PushArg (L6)
3533: PushFunctionPtr (@3510)
3534: Unbox (L7)  <<< EXCEPTION
3535: PushArg (L2)
3536: PushArg (L7)
3537: InvokeDynamic (L2.C7)
PushReturnValue ()
PushNull ()
PushArg (L8)
PushArg (L9)
InvokeExternal (Ex#24)
PushReturnValue ()
Return (L10)

The initial-initial version was me binding the Autocomplete Flutter widget, and having it tested:

                  Autocomplete<Option>(
                    onTap: onTap,
                    child: Text('Click me'),
                    optionsBuilder: (value) async {
                      final text = value.text.toLowerCase();
                      return _options.where((o) => o.title.toLowerCase().contains(text))
                    }, ...)

The stack is the same, some unexpected Unbox call:

dart_eval runtime exception: UnimplementedError
#0      EvalFunction.$value (package:dart_eval/src/eval/runtime/function.dart:41:25)
#1      Unbox.run (package:dart_eval/src/eval/runtime/ops/primitives.dart:356:59)
#2      Runtime.bridgeCall (package:dart_eval/src/eval/runtime/runtime.dart:831:12)
at <anonymous closure>

RUNTIME STATE
=============
Program offset: 3590
Stack sample: [L6: $StatelessWidget$bridge, L7: [L0: Instance of '$InstanceImpl', L1: Instance of
'$InstanceImpl', L2: Instance of '$InstanceImpl'], L8: 1, L9: 4, L10: 5, L11: 6, L12:
EvalFunctionPtr{offset: 3566, prev: [L0: [L0: $StatelessWidget$bridge, L1: Instance of
'$BuildContext', L2: null], L1: Instance of '$TextEditingValue', L2: Instance of
'$Completer<dynamic>', L3: $""], rPAC: 1, pAT: [Instance of 'RuntimeType'], sNA: [], sNAT: []},
*L13: null, L14: null, L15: null]
Args sample: []
Call stack: [0, -1]
TRACE:
(I've added some more lines)
PushScope (F87:859, '<anonymous closure>')
InvokeExternal (Ex#99)
PushReturnValue ()
PushObjectProperty (L1.C8)
PushReturnValue ()
InvokeDynamic (L3.C2)
PushReturnValue ()
PushConstantInt (0)
IndexList (L0[L5])
PushObjectProperty (L6.C0)
PushReturnValue ()
JumpConstant (@3581)
PushScope (F87:980, '<anonymous closure>')
PushObjectProperty (L1.C1)
PushReturnValue ()
PushArg (L2)
InvokeDynamic (L2.C2)
PushReturnValue ()
PushConstantInt (4)
IndexList (L0[L4])
Unbox (L5)
PushArg (L3)
PushArg (L5)
InvokeDynamic (L3.C3)
PushReturnValue ()
Return (L6)
Pop (5)
3581: PushConstantInt (1)
3582: PushArg (L8)
3583: PushConstantInt (4)
3584: PushArg (L9)
3585: PushConstantInt (5)
3586: PushArg (L10)
3587: PushConstantInt (6)
3588: PushArg (L11)
3589: PushFunctionPtr (@3566)
3590: Unbox (L12)  <<< EXCEPTION
3591: PushArg (L7)
3592: PushArg (L12)
3593: InvokeDynamic (L7.C7)
PushReturnValue ()
ReturnAsync (L13, completer L2)

Currently I'm a bit lost. I'm not sure those values even should be unboxed.

The full test code is at the bottom of flutter_eval_test.dart in ethanblake4/flutter_eval#135.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions