pointerFromFunctionImpl<T extends Function> function

Pointer<NativeFunction<T>> pointerFromFunctionImpl<T extends Function>(
  1. Function func,
  2. WasmTable table,
  3. Memory memory
)

Implementation

Pointer<NativeFunction<T>> pointerFromFunctionImpl<T extends Function>(
    /* TODO: @DartRepresentationOf('T')  */
    Function func,
    WasmTable table,
    Memory memory) {
  // TODO: garbage collect

  return exportedFunctions.putIfAbsent(func, () {
    developer.log('marshal from: ${func.runtimeType} to $T');
    final String dartSignature = func.runtimeType.toString();
    final String argTypes = dartSignature.split('=>').first.trim();
    final List<String> argT =
        argTypes.substring(1, argTypes.length - 1).split(', ');
    developer.log('arg types: $argT');
    final List<Function> marshallers = argTypes
        .substring(1, argTypes.length - 1)
        .split(', ')
        .map((arg) => marshaller(arg))
        .toList();

    final String wasmSignature = _getWasmSignature<T>();

    developer.log('wasm sig: $wasmSignature');

    // ignore: prefer_function_declarations_over_variables
    final Function wrapper1 = (List args) {
      developer.log('wrapper of $T called with $args');
      final marshalledArgs =
          marshallers.mapIndexed((i, m) => m(args[i], memory)).toList();
      developer.log('which is $marshalledArgs on $func');
      Function.apply(func, marshalledArgs);
      developer.log('done!');
    };
    final Function wrapper2 = callbackHelpers[argT.length](wrapper1);

    // theFunctions.add(wrapper);

    final wasmFunc = _toWasmFunction(wasmSignature, wrapper2);
    table.grow(1.toJS);
    table.set((table.length.toDartInt - 1).toJS, wasmFunc);
    developer.log('created callback with index ${table.length.toDartInt - 1}');
    return Pointer<NativeFunction<T>>.fromAddress(
        table.length.toDartInt - 1, memory);
  }) as Pointer<NativeFunction<T>>;
}