ethanblake4 / dart_eval

Extensible Dart interpreter for Dart with full interop
https://pub.dev/packages/dart_eval
BSD 3-Clause "New" or "Revised" License
334 stars 40 forks source link

default parameter boxing error #170

Closed Noobware1 closed 9 months ago

Noobware1 commented 9 months ago

Test case

 final runtime = Compiler().compileWriteAndLoad({
    'example': {
      'main.dart': '''
            import 'dart:convert';

            String main () {
              return getAccessToken();
            }

           String getAccessToken([bool force = false])  {
             final String token = '';
             if (!force && token.isNotEmpty) {
               return jsonDecode(token).toString();
             }
             final bool useLocalToken = force;
             if (!useLocalToken) {
               return 'token';
             } else {
               return 'notToken';
             }
           }
          '''
    }
  });

  print(runtime.executeLib('package:example/main.dart', 'main'));

Error

Unhandled exception:
dart_eval runtime exception: type 'bool' is not a subtype of type '$Value' in type cast
#0      Unbox.run (package:dart_eval/src/eval/runtime/ops/primitives.dart:335:48)
#1      Runtime.execute (package:dart_eval/src/eval/runtime/runtime.dart:826:12)
#2      Runtime.executeLib (package:dart_eval/src/eval/runtime/runtime.dart:813:12)
at getAccessToken()
at main()

RUNTIME STATE
=============
Program offset: 35
Stack sample: [L0: false, L1: $"", L2: false, *L3: ${false}, L4: false, L5: null, L6: null, L7: null, L8: null, L9: null]
Args sample: []
Call stack: [0, -1, 5]
TRACE:
29: InvokeDynamic (L6.C3)
30: PushReturnValue ()
31: Return (L7)
32: Pop (3)
33: PushNull ()
34: CopyValue (L2 <-- L0)
35: Unbox (L2)  <<< EXCEPTION
36: LogicalNot (L2)
37: JumpIfFalse (@42 if L3 == false)
38: PushConstant (C4)

The current fix I am using tho it's probably wrong code

Noobware1 commented 9 months ago

update is this solution valid? it also passed all test.

code

ethanblake4 commented 9 months ago

That fix looks good to me, if you want to go ahead and submit a PR I'll accept it.

Noobware1 commented 9 months ago

The above fix does the fix the above error but not the original one sadly. can you help me with it. This is the original case.

class AccessTokenInterceptor {
  final String crUrl;
  final SharedPreferences preferences;
  final String PREF_USE_LOCAL_Token;

  AccessTokenInterceptor({
    required this.crUrl,
    required this.preferences,
    required this.PREF_USE_LOCAL_Token,
  });

  Future<Response> intercept(Chain chain) async {
    final accessTokenN = await getAccessToken();
    final request = newRequestWithAccessToken(chain.request, accessTokenN);

    final response = await chain.proceed(request);

    if (response.statusCode == HttpStatus.unauthorized) {
      final refreshedToken = await getAccessToken(true);

      return chain.proceed(
        newRequestWithAccessToken(chain.request, refreshedToken),
      );
    }
    return response;
  }

  Future<AccessToken> getAccessToken([bool force = false]) async {
    final String? token =
        this.preferences.getString(AccessTokenInterceptor._TOKEN_PREF_KEY);
    if (!force && token != null) {
      return AccessToken.decode(token);
    } else {
      final bool useLocalToken = this.preferences.getBool(PREF_USE_LOCAL_Token, false)!;
      if (!useLocalToken) {
        return refreshAccessToken();
      } else {
        return refreshAccessToken(false);
      }
    }
  }
Unhandled exception:
OkHttpException(OkHttpException(dart_eval runtime exception: type 'bool' is not a subtype of type '$Value' in type cast
#0      Unbox.run (package:dart_eval/src/eval/runtime/ops/primitives.dart:335:48)
#1      Runtime.bridgeCall (package:dart_eval/src/eval/runtime/runtime.dart:849:12)
#2      EvalFunctionPtr.call (package:dart_eval/src/eval/runtime/function.dart:59:13)
at AccessTokenInterceptor.getAccessToken()
at AccessTokenInterceptor.intercept()
at <anonymous closure>

RUNTIME STATE
=============
Program offset: 1323
Stack sample: [L0: Instance of '$InstanceImpl', L1: false, L2: Instance of '$Completer<dynamic>', L3: Instance of '$SharedPreferences', L4: $"access_token_data", L5: null, L6: Instance of '$null', *L7: null, L8: null, L9: null]
Args sample: []
Call stack: [0, -1, 81, 1260]
TRACE:
1317: PushReturnValue ()
1318: PushNull ()
1319: PushArg (L4)
1320: PushArg (L5)
1321: InvokeDynamic (L3.C105)
1322: PushReturnValue ()
1323: Unbox (L1)  <<< EXCEPTION
1324: LogicalNot (L1)
1325: PushNull ()
1326: BoxNull (L8)
, null, null, null, null, null), OkHttpException(dart_eval runtime exception: type 'bool' is not a subtype of type '$Value' in type cast
#0      Unbox.run (package:dart_eval/src/eval/runtime/ops/primitives.dart:335:48)
#1      Runtime.bridgeCall (package:dart_eval/src/eval/runtime/runtime.dart:849:12)
#2      EvalFunctionPtr.call (package:dart_eval/src/eval/runtime/function.dart:59:13)
at AccessTokenInterceptor.getAccessToken()
at AccessTokenInterceptor.intercept()
at <anonymous closure>
ethanblake4 commented 9 months ago

Fixed in v0.7.8 (I also fixed this original case you mentioned)