bytecodealliance / jco

JavaScript toolchain for working with WebAssembly Components
https://bytecodealliance.github.io/jco/
Apache License 2.0
642 stars 65 forks source link

Lifting `list<borrow<res>>` during transpilation emits invalid code #428

Closed kateinoigakukun closed 7 months ago

kateinoigakukun commented 7 months ago

Reproducer

$ cat check.wit
package jco:test;

interface foo {
  resource bar {}
  take-list-of-handles: func(values: list<borrow<bar>>);
}

world check {
  import foo;
}

$ touch source.js
$ jco componentize source.js -w ./ -o component.wasm
$ jco transpile component.wasm
// Transpiled .js
const handleTable0 = [T_FLAG, 0];
const captureTable0= new Map();
let captureCnt0 = 0; 'captureCnt0' is declared but its value is never read.
handleTables[0] = handleTable0;

function trampoline23(arg0, arg1) {
  var len3 = arg1;
  var base3 = arg0;
  var result3 = [];
  for (let i = 0; i < len3; i++) {
    const base = base3 + i * 4;
    var handle1 = dataView(memory0).getInt32(base + 0, true);
    var rep2 = handleTable0[(handle1 << 1) + 1] & ~T_FLAG;
    var rsc0 = captureTable0.get(rep2);
    if (!rsc0) {
      rsc0 = Object.create(Bar.prototype);
      Object.defineProperty(rsc0, symbolRscHandle, { writable: true, value: handle1});
      Object.defineProperty(rsc0, symbolRscRep, { writable: true, value: rep2});
    }
    result3.push(rsc0);
  }
  takeListOfHandles(result3);
  rsc0[symbolRscHandle] = null;
}

The problem here is deactivation code rsc0[symbolRscHandle] = null; refers rsc0, which is defined inside the loop. Thus passing empty list to the function leads rsc0 to be undefined and raises exception at the deactivation line.

kateinoigakukun commented 7 months ago

I guess there are the same problems in other container-like types like result

guybedford commented 7 months ago

I've posted a fix in https://github.com/bytecodealliance/jco/pull/429 moving to runtime borrow tracking.

Note that for generating dummy components you can also use the --dummy option in component embed:

jco embed --dummy --wit check.wit -o check.wasm
jco new check.wasm --wasi-reactor -o check.component.wasm
kateinoigakukun commented 7 months ago

Thank you!