AssemblyScript/assemblyscript

wasm2js throws Fatal: error in validating input

guest271314 opened this issue · 3 comments

Bug description

wasm2js throws Fatal: error in validating input.

Steps to reproduce

node_modules/.bin/asc --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json  module.ts -o module.wasm

module.ts

/** Calculates the n-th Fibonacci number. */
export function array_nth_permutation(len: i32, n: i32): void { //Array<f64>
  let lex = n;
  let b: number[] = []; // copy of the set a.slice()
  for (let x: i32 = 0; x < len; x++) {
    b[x] = x;
  }
  // let len = a; // length of the set
  const res: number[] = []; // return value, undefined
  let i: i32 = 1;
  let f: i32 = 1;

  // compute f = factorial(len)
  for (; i <= len; i++) {
    f *= i;
  }

  let fac = f;
  // if the permutation number is within range
  if (n >= 0 && n < f) {
    // start with the empty set, loop for len elements
    // let result_len = 0;
    for (; len > 0; len--) {
      // determine the next element:
      // there are f/len subsets for each possible element,
      f /= len;
      // a simple division gives the leading element index
      i = (n - n % f) / f; // Math.floor(n / f);
      // alternately: i = (n - n % f) / f;
      // res[(result_len)++] = b[i];
      // for (let j = i; j < len; j++) {
      //   b[j] = b[j + 1]; // shift elements left
      // }
      res.push(b.splice(i, 1)[0]);
      // reduce n for the remaining subset:
      // compute the remainder of the above division
      n %= f;
      // extract the i-th element from b and push it at the end of res
    }

    let result: string = "[";
    for (let x: i32 = 0; x < res.length; x++) {
      let m: string = res[x].toString();
      let i: i32 = 0;
      do {
        result += m[i];
        i++;
      } while (m[i] !== ".");
      if (x < res.length -1) {
        result += ",";
      }
    }
    result += "]";
    process.stdout.write(
      `${lex} of ${fac - 1} (0-indexed, factorial ${fac}) => ${result}\n`,
    );

    process.exit(0);
  } else {
    if (n === 0) {
      process.stdout.write(`${n} = 0`);
    }
    process.stdout.write(`${n} >= 0 && ${n} < ${f}: ${n >= 0 && n < f}`);
    process.exit(1);
  }
}

let input: string = "0";
let lex: string = "0";

if (process.argv.length > 1) {
  input = process.argv.at(-2);
  lex = process.argv.at(-1);
} else {
  let stdin = process.stdin;
  let buffer = new ArrayBuffer(64);
  let n: number = stdin.read(buffer);
  if (n > 0) {
    let data = String.UTF8.decode(buffer);
    input = data.slice(0, data.indexOf(" "));
    lex = data.slice(data.indexOf(" "), data.length);
  }
}

input = input.trim();
lex = lex.trim();

if (<i32> parseInt(input) < 2 || <i32> parseInt(lex) < 0) {
  process.stdout.write(`Expected n > 2, m >= 0, got ${input}, ${lex}`); // eval(input)
  process.exit(1);
}

array_nth_permutation(<i32> parseInt(input), <i32> parseInt(lex));

wasm2js

../binaryen/bin/wasm2js --enable-bulk-memory module.wasm -o module.js
[wasm-validator error in function 82] unexpected false: all used features should be allowed, on 
(i32.trunc_sat_f64_s
 (local.get $23)
)
[wasm-validator error in function 132] unexpected false: all used features should be allowed, on 
(i32.trunc_sat_f64_s
 (call $118
  (local.get $5)
  (i32.const 0)
 )
)
[wasm-validator error in function 132] unexpected false: all used features should be allowed, on 
(i32.trunc_sat_f64_s
 (call $118
  (local.get $5)
  (i32.const 0)
 )
)
[wasm-validator error in function 132] unexpected false: all used features should be allowed, on 
(i32.trunc_sat_f64_s
 (call $118
  (local.get $5)
  (i32.const 0)
 )
)
[wasm-validator error in function 132] unexpected false: all used features should be allowed, on 
(i32.trunc_sat_f64_s
 (call $118
  (local.get $5)
  (i32.const 0)
 )
)

;; ...

Fatal: error in validating input

AssemblyScript version

0.27.32

Oh, I think that's just you forgetting to do --enable-nontrapping-float-to-int.

The AssemblyScript wasm2js version just hangs.

import process from "node:process";
import fs from "node:fs";
import WASI from "./wasi.js";

const wasi = new WASI({
  args:[,'4', '5']
});

var memasmFunc = new ArrayBuffer(0);
var retasmFunc = asmFunc({
  //array_nth_permutation,
  "wasi_snapshot_preview1": wasi.exports,
  memory: { buffer: memasmFunc },
});
export var array_nth_permutation = retasmFunc.array_nth_permutation;
export var memory = retasmFunc.memory;
export var _start = retasmFunc._start;
wasi.memory = memory;
// export var _start = retasmFunc._start;
_start();

I can do this with the output of Bytecode Alliance's Javy

echo '4 5' | node ../nm_javy_permutations.js
5 of 23 (0-indexed, factorial 24) => [0,3,2,1]
import { readFile } from "node:fs/promises";
import process from "node:process";
// import { WASI } from "./wasi-minimal-min.js";
import * as fs from "node:fs";
class WASI extends Module {
  constructor(options) {
    super(options);
  }
};
let wasi = new WASI({
  env: {},
  args: [],
  fds: [
    {
      type: 2,
      handle: fs,
    },
    {
      type: 2,
      handle: fs,
    },
    {
      type: 2,
      handle: fs,
    },
  ],
});
const pluginBytes = await readFile(new URL("./plugin.wasm", import.meta.url));
const pluginModule = await WebAssembly.compile(pluginBytes);
const pluginInstance = await WebAssembly.instantiate(
  pluginModule,
  { "wasi_snapshot_preview1": wasi.exports },
);
wasi.memory = pluginInstance.exports.memory;
var memasmFunc = new ArrayBuffer(0);
var retasmFunc = asmFunc({
  "javy_quickjs_provider_v3": {
    memory: { buffer: memasmFunc },
    ...pluginInstance.exports,
  },
});
export var _start = retasmFunc._start;
_start();

@CountBleck Do I need to use AssemblyScript's wasi-shim implementation to successfully execute the JavaScript resulting from Binaryen's wasm2js?