Skip to content

jco transpile --js output unusable for u64/s64 params/returns #1393

@QuantumSegfault

Description

@QuantumSegfault

The --js flag of transpile runs the core Wasm modules of the component through wasm2js, translating Wasm to the asm.js subset of JS.

asm.js does not support 64-bit integers, so such values and operations are split into 32-bit ones by wasm2js. For instance:

(func (;0;) (type 0) (param i64 i64) (result i64)
  local.get 0
  local.get 1
  i64.add
)

becomes

var setTempRet0 = env.setTempRet0;
var i64toi32_i32$HIGH_BITS = 0;
function legalstub$0($0, $1, $2, $3) {
  $1 = $1 + $3 | 0;
  $0 = $0 + $2 | 0;
  i64toi32_i32$HIGH_BITS = $0 >>> 0 < $2 >>> 0 ? $1 + 1 | 0 : $1;
  setTempRet0(i64toi32_i32$HIGH_BITS | 0);
  return $0;
}

The problem is that this interface (i64 split into i32) no longer matches WebAssembly. Wasm has used BigInt for i64 in JS integration for many years now.

This is evident in the compoenent-level wrapper generated around it to call the export from other JS code (some parts omitted for brevity):

function add(arg0, arg1) {
      ...
      const hostProvided = false;
      
      const [task, _wasm_call_currentTaskID] = ...
      
      const started = task.enterSync();
      let ret =   _withGlobalCurrentTaskMeta({
        ...
        fn: () => exports0Add(toUint64(arg0), toUint64(arg1)),
      });
      
      ...
      task.resolve([BigInt.asUintN(64, BigInt(ret))]);
      task.exit();
      return BigInt.asUintN(64, BigInt(ret));
    }
    ({ exports: exports0 } = yield instantiateCore(yield module0));
    exports0Add = exports0.add;
    
    return { add,  };
  })();

Currently this means the using jco transpile --js on componets using u64 or s64 in the interface (e.g. export add: func(a: u64, b: u64) -> u64;) will not produce valid/usable code for such exports.

The wrapper will try to call a export expecting 4 x Number with 2 x BigInt (and returns Number instead of BigInt).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions