LCOV - code coverage report
Current view: top level - src - wrapper.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 149 158 94.3 %
Date: 2021-03-31 22:28:15 Functions: 0 0 -

          Line data    Source code
       1             : /*
       2             :  * @Description: wrapper
       3             :  * @Author: ekibun
       4             :  * @Date: 2020-09-19 22:07:47
       5             :  * @LastEditors: ekibun
       6             :  * @LastEditTime: 2020-12-02 11:14:03
       7             :  */
       8             : part of '../flutter_qjs.dart';
       9             : 
      10           2 : dynamic _parseJSException(Pointer<JSContext> ctx, [Pointer<JSValue>? perr]) {
      11           2 :   final e = perr ?? jsGetException(ctx);
      12             :   var err;
      13             :   try {
      14           2 :     err = _jsToDart(ctx, e);
      15             :   } catch (exception) {
      16             :     err = exception;
      17             :   }
      18           1 :   if (perr == null) jsFreeValue(ctx, e);
      19             :   return err;
      20             : }
      21             : 
      22           2 : void _definePropertyValue(
      23             :   Pointer<JSContext> ctx,
      24             :   Pointer<JSValue> obj,
      25             :   dynamic key,
      26             :   dynamic val, {
      27             :   Map<dynamic, Pointer<JSValue>>? cache,
      28             : }) {
      29           2 :   final jsAtomVal = _dartToJs(ctx, key, cache: cache);
      30           4 :   final jsAtom = jsValueToAtom(ctx, jsAtomVal);
      31           4 :   jsDefinePropertyValue(
      32             :     ctx,
      33             :     obj,
      34             :     jsAtom,
      35           2 :     _dartToJs(ctx, val, cache: cache),
      36             :     JSProp.C_W_E,
      37             :   );
      38           4 :   jsFreeAtom(ctx, jsAtom);
      39           2 :   jsFreeValue(ctx, jsAtomVal);
      40             : }
      41             : 
      42           3 : Pointer<JSValue> _jsGetPropertyValue(
      43             :   Pointer<JSContext> ctx,
      44             :   Pointer<JSValue> obj,
      45             :   dynamic key, {
      46             :   Map<dynamic, Pointer<JSValue>>? cache,
      47             : }) {
      48           3 :   final jsAtomVal = _dartToJs(ctx, key, cache: cache);
      49           6 :   final jsAtom = jsValueToAtom(ctx, jsAtomVal);
      50           6 :   final jsProp = jsGetProperty(ctx, obj, jsAtom);
      51           6 :   jsFreeAtom(ctx, jsAtom);
      52           3 :   jsFreeValue(ctx, jsAtomVal);
      53             :   return jsProp;
      54             : }
      55             : 
      56           3 : Pointer<JSValue> _dartToJs(Pointer<JSContext> ctx, dynamic val,
      57             :     {Map<dynamic, Pointer<JSValue>>? cache}) {
      58           6 :   if (val == null) return jsUNDEFINED();
      59           3 :   if (val is Error) return _dartToJs(ctx, JSError(val, val.stackTrace));
      60           3 :   if (val is Exception) return _dartToJs(ctx, JSError(val));
      61           3 :   if (val is JSError) {
      62           4 :     final ret = jsNewError(ctx);
      63           2 :     _definePropertyValue(ctx, ret, "name", "");
      64           4 :     _definePropertyValue(ctx, ret, "message", val.message);
      65           4 :     _definePropertyValue(ctx, ret, "stack", val.stack);
      66             :     return ret;
      67             :   }
      68          12 :   if (val is _JSObject) return jsDupValue(ctx, val._val!);
      69           3 :   if (val is Future) {
      70           9 :     final resolvingFunc = malloc<Uint8>(sizeOfJSValue * 2).cast<JSValue>();
      71             :     final resolvingFunc2 =
      72          12 :         Pointer<JSValue>.fromAddress(resolvingFunc.address + sizeOfJSValue);
      73           6 :     final ret = jsNewPromiseCapability(ctx, resolvingFunc);
      74           3 :     final _JSFunction res = _jsToDart(ctx, resolvingFunc);
      75           3 :     final _JSFunction rej = _jsToDart(ctx, resolvingFunc2);
      76           3 :     jsFreeValue(ctx, resolvingFunc, free: false);
      77           3 :     jsFreeValue(ctx, resolvingFunc2, free: false);
      78           3 :     malloc.free(resolvingFunc);
      79           3 :     final refRes = _DartObject(ctx, res);
      80           3 :     final refRej = _DartObject(ctx, rej);
      81           3 :     res.free();
      82           3 :     rej.free();
      83           6 :     val.then((value) {
      84           6 :       res.invoke([value]);
      85           2 :     }, onError: (e) {
      86           4 :       rej.invoke([e]);
      87           6 :     }).whenComplete(() {
      88           3 :       refRes.free();
      89           3 :       refRej.free();
      90             :     });
      91             :     return ret;
      92             :   }
      93           3 :   if (cache == null) cache = Map();
      94           7 :   if (val is bool) return jsNewBool(ctx, val ? 1 : 0);
      95           7 :   if (val is int) return jsNewInt64(ctx, val);
      96           7 :   if (val is double) return jsNewFloat64(ctx, val);
      97           6 :   if (val is String) return jsNewString(ctx, val);
      98           3 :   if (val is Uint8List) {
      99           0 :     final ptr = malloc<Uint8>(val.length);
     100           0 :     final byteList = ptr.asTypedList(val.length);
     101           0 :     byteList.setAll(0, val);
     102           0 :     final ret = jsNewArrayBufferCopy(ctx, ptr, val.length);
     103           0 :     malloc.free(ptr);
     104             :     return ret;
     105             :   }
     106           3 :   if (cache.containsKey(val)) {
     107           6 :     return jsDupValue(ctx, cache[val]!);
     108             :   }
     109           3 :   if (val is List) {
     110           4 :     final ret = jsNewArray(ctx);
     111           2 :     cache[val] = ret;
     112           6 :     for (int i = 0; i < val.length; ++i) {
     113           4 :       _definePropertyValue(ctx, ret, i, val[i], cache: cache);
     114             :     }
     115             :     return ret;
     116             :   }
     117           3 :   if (val is Map) {
     118           4 :     final ret = jsNewObject(ctx);
     119           2 :     cache[val] = ret;
     120           4 :     for (MapEntry<dynamic, dynamic> entry in val.entries) {
     121           6 :       _definePropertyValue(ctx, ret, entry.key, entry.value, cache: cache);
     122             :     }
     123             :     return ret;
     124             :   }
     125             :   // wrap Function to JSInvokable
     126           3 :   final valWrap = JSInvokable._wrap(val);
     127             :   final dartObjectClassId =
     128          15 :       runtimeOpaques[jsGetRuntime(ctx)]?.dartObjectClassId ?? 0;
     129           3 :   if (dartObjectClassId == 0) return jsUNDEFINED();
     130           6 :   final dartObject = jsNewObjectClass(
     131             :     ctx,
     132             :     dartObjectClassId,
     133           6 :     identityHashCode(_DartObject(ctx, valWrap)),
     134             :   );
     135           3 :   if (valWrap is JSInvokable) {
     136           6 :     final ret = jsNewCFunction(ctx, dartObject);
     137           3 :     jsFreeValue(ctx, dartObject);
     138             :     return ret;
     139             :   }
     140             :   return dartObject;
     141             : }
     142             : 
     143           3 : dynamic _jsToDart(Pointer<JSContext> ctx, Pointer<JSValue> val,
     144             :     {Map<int, dynamic>? cache}) {
     145           3 :   if (cache == null) cache = Map();
     146           6 :   final tag = jsValueGetTag(val);
     147           9 :   if (jsTagIsFloat64(tag) != 0) {
     148           4 :     return jsToFloat64(ctx, val);
     149             :   }
     150             :   switch (tag) {
     151           3 :     case JSTag.BOOL:
     152           6 :       return jsToBool(ctx, val) != 0;
     153           3 :     case JSTag.INT:
     154           4 :       return jsToInt64(ctx, val);
     155           3 :     case JSTag.STRING:
     156           3 :       return jsToCString(ctx, val);
     157           3 :     case JSTag.OBJECT:
     158           6 :       final rt = jsGetRuntime(ctx);
     159           9 :       final dartObjectClassId = runtimeOpaques[rt]?.dartObjectClassId;
     160             :       if (dartObjectClassId != null) {
     161           3 :         final dartObject = _DartObject.fromAddress(
     162           6 :             rt, jsGetObjectOpaque(val, dartObjectClassId));
     163           3 :         if (dartObject != null) return dartObject._obj;
     164             :       }
     165             :       final psize = malloc<IntPtr>();
     166           6 :       final buf = jsGetArrayBuffer(ctx, psize, val);
     167           3 :       final size = psize.value;
     168           3 :       malloc.free(psize);
     169           6 :       if (buf.address != 0) {
     170           0 :         return Uint8List.fromList(buf.asTypedList(size));
     171             :       }
     172           6 :       final valptr = jsValueGetPtr(val);
     173           3 :       if (cache.containsKey(valptr)) {
     174           2 :         return cache[valptr];
     175             :       }
     176           9 :       if (jsIsFunction(ctx, val) != 0) {
     177           3 :         return _JSFunction(ctx, val);
     178           9 :       } else if (jsIsError(ctx, val) != 0) {
     179           2 :         final err = jsToCString(ctx, val);
     180           2 :         final pstack = _jsGetPropertyValue(ctx, val, 'stack');
     181             :         final stack =
     182           8 :             jsToBool(ctx, pstack) != 0 ? jsToCString(ctx, pstack) : null;
     183           2 :         jsFreeValue(ctx, pstack);
     184           2 :         return JSError(err, stack);
     185           9 :       } else if (jsIsPromise(ctx, val) != 0) {
     186           3 :         final jsPromiseThen = _jsGetPropertyValue(ctx, val, 'then');
     187             :         final _JSFunction promiseThen =
     188           3 :             _jsToDart(ctx, jsPromiseThen, cache: cache);
     189           3 :         jsFreeValue(ctx, jsPromiseThen);
     190           3 :         final completer = Completer();
     191           8 :         completer.future.catchError((e) {});
     192           3 :         final jsPromise = _JSObject(ctx, val);
     193           6 :         final jsRet = promiseThen._invoke([
     194           3 :           (v) {
     195           3 :             JSRef.dupRecursive(v);
     196           6 :             if (!completer.isCompleted) completer.complete(v);
     197             :           },
     198           2 :           (e) {
     199           2 :             JSRef.dupRecursive(e);
     200           4 :             if (!completer.isCompleted) completer.completeError(e);
     201             :           },
     202             :         ], jsPromise);
     203           3 :         jsPromise.free();
     204           3 :         promiseThen.free();
     205           9 :         final isException = jsIsException(jsRet) != 0;
     206           3 :         jsFreeValue(ctx, jsRet);
     207           0 :         if (isException) throw _parseJSException(ctx);
     208           3 :         return completer.future;
     209           6 :       } else if (jsIsArray(ctx, val) != 0) {
     210           2 :         final jslength = _jsGetPropertyValue(ctx, val, 'length');
     211           4 :         final length = jsToInt64(ctx, jslength);
     212           2 :         final ret = [];
     213           2 :         cache[valptr] = ret;
     214           4 :         for (var i = 0; i < length; ++i) {
     215           2 :           final jsProp = _jsGetPropertyValue(ctx, val, i);
     216           4 :           ret.add(_jsToDart(ctx, jsProp, cache: cache));
     217           2 :           jsFreeValue(ctx, jsProp);
     218             :         }
     219             :         return ret;
     220             :       } else {
     221             :         final ptab = malloc<Pointer<JSPropertyEnum>>();
     222             :         final plen = malloc<Uint32>();
     223           8 :         if (jsGetOwnPropertyNames(ctx, ptab, plen, val, -1) != 0) {
     224           0 :           malloc.free(plen);
     225           0 :           malloc.free(ptab);
     226             :           return null;
     227             :         }
     228           2 :         final len = plen.value;
     229           2 :         malloc.free(plen);
     230           2 :         final ret = Map();
     231           2 :         cache[valptr] = ret;
     232           4 :         for (var i = 0; i < len; ++i) {
     233           6 :           final jsAtom = jsPropertyEnumGetAtom(ptab.value, i);
     234           4 :           final jsAtomValue = jsAtomToValue(ctx, jsAtom);
     235           4 :           final jsProp = jsGetProperty(ctx, val, jsAtom);
     236           4 :           ret[_jsToDart(ctx, jsAtomValue, cache: cache)] =
     237           2 :               _jsToDart(ctx, jsProp, cache: cache);
     238           2 :           jsFreeValue(ctx, jsAtomValue);
     239           2 :           jsFreeValue(ctx, jsProp);
     240           4 :           jsFreeAtom(ctx, jsAtom);
     241             :         }
     242           6 :         jsFree(ctx, ptab.value);
     243           2 :         malloc.free(ptab);
     244             :         return ret;
     245             :       }
     246             :     default:
     247             :   }
     248             :   return null;
     249             : }

Generated by: LCOV version 1.14