/* Copied from *
 * https://github.com/WebAssembly/spec/blob/master/interpreter/host/js.ml */
'use strict';

let soft_validate = true;

let spectest = {
  print: print || ((...xs) => console.log(...xs)),
  global: 666,
  table: new WebAssembly.Table({initial: 10, maximum: 20, element: 'anyfunc'}),
  memory: new WebAssembly.Memory({initial: 1, maximum: 2}),};

let registry = {spectest};
let $$;

function register(name, instance) {
  registry[name] = instance.exports;
}

function module(bytes) {
  let buffer = new ArrayBuffer(bytes.length);
  let view = new Uint8Array(buffer);
  for (let i = 0; i < bytes.length; ++i) {
    view[i] = bytes.charCodeAt(i);
  }
  return new WebAssembly.Module(buffer);
}

function instance(bytes, imports = registry) {
  return new WebAssembly.Instance(module(bytes), imports);
}

function assert_malformed(bytes) {
  try { module(bytes) } catch (e) {
    if (e instanceof WebAssembly.CompileError) return;
  }
  throw new Error("Wasm decoding failure expected");
}

function assert_invalid(bytes) {
  try { module(bytes) } catch (e) {
    if (e instanceof WebAssembly.CompileError) return;
  }
  throw new Error("Wasm validation failure expected");
}

function assert_soft_invalid(bytes) {
  try { module(bytes) } catch (e) {
    if (e instanceof WebAssembly.CompileError) return;
    throw new Error("Wasm validation failure expected");
  }
  if (soft_validate)
    throw new Error("Wasm validation failure expected");
}

function assert_unlinkable(bytes) {
  let mod = module(bytes);
  try { new WebAssembly.Instance(mod, registry) } catch (e) {
    if (e instanceof TypeError) return;
  }
  throw new Error("Wasm linking failure expected");
}

function assert_uninstantiable(bytes) {
  let mod = module(bytes);
  try { new WebAssembly.Instance(mod, registry) } catch (e) {
    if (e instanceof WebAssembly.RuntimeError) return;
  }
  throw new Error("Wasm trap expected");
}

function assert_trap(action) {
  try { action() } catch (e) {
    if (e instanceof WebAssembly.RuntimeError) return;
  }
  throw new Error("Wasm trap expected");
}

function assert_return(action, expected) {
  let actual = action();
  if (!Object.is(actual, expected)) {
    throw new Error("Wasm return value " + expected + " expected, got " + actual);
  };
}

function assert_return_nan(action) {
  let actual = action();
  if (!Number.isNaN(actual)) {
    throw new Error("Wasm return value NaN expected, got " + actual);
  };
}

let f32 = Math.fround;

assert_invalid("\x00\x61\x73\x6d\x0d\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x08\x01\x01\x0a\x04\x01\x02\x00\x0b");
assert_invalid("\x00\x61\x73\x6d\x0d\x00\x00\x00\x01\x05\x01\x60\x00\x01\x7f\x03\x02\x01\x00\x08\x01\x00\x0a\x07\x01\x05\x00\x41\x00\x0f\x0b");
assert_invalid("\x00\x61\x73\x6d\x0d\x00\x00\x00\x01\x05\x01\x60\x01\x7f\x00\x03\x02\x01\x00\x08\x01\x00\x0a\x04\x01\x02\x00\x0b");
$$ = instance("\x00\x61\x73\x6d\x0d\x00\x00\x00\x01\x08\x02\x60\x00\x00\x60\x00\x01\x7f\x03\x04\x03\x00\x01\x00\x05\x04\x01\x01\x01\x01\x07\x0d\x02\x03\x69\x6e\x63\x00\x00\x03\x67\x65\x74\x00\x01\x08\x01\x02\x0a\x23\x03\x0f\x00\x41\x00\x41\x00\x2d\x00\x00\x41\x01\x6a\x3a\x00\x00\x0b\x08\x00\x41\x00\x2d\x00\x00\x0f\x0b\x08\x00\x10\x00\x10\x00\x10\x00\x0b\x0b\x07\x01\x00\x41\x00\x0b\x01\x41");
assert_return(() => $$.exports["get"](), 68);
$$.exports["inc"]();
assert_return(() => $$.exports["get"](), 69);
$$.exports["inc"]();
assert_return(() => $$.exports["get"](), 70);
$$ = instance("\x00\x61\x73\x6d\x0d\x00\x00\x00\x01\x08\x02\x60\x00\x00\x60\x00\x01\x7f\x03\x04\x03\x00\x01\x00\x05\x04\x01\x01\x01\x01\x07\x0d\x02\x03\x69\x6e\x63\x00\x00\x03\x67\x65\x74\x00\x01\x08\x01\x02\x0a\x23\x03\x0f\x00\x41\x00\x41\x00\x2d\x00\x00\x41\x01\x6a\x3a\x00\x00\x0b\x08\x00\x41\x00\x2d\x00\x00\x0f\x0b\x08\x00\x10\x00\x10\x00\x10\x00\x0b\x0b\x07\x01\x00\x41\x00\x0b\x01\x41");
assert_return(() => $$.exports["get"](), 68);
$$.exports["inc"]();
assert_return(() => $$.exports["get"](), 69);
$$.exports["inc"]();
assert_return(() => $$.exports["get"](), 70);
$$ = instance("\x00\x61\x73\x6d\x0d\x00\x00\x00\x01\x08\x02\x60\x01\x7f\x00\x60\x00\x00\x02\x12\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x70\x72\x69\x6e\x74\x00\x00\x03\x02\x01\x01\x08\x01\x01\x0a\x08\x01\x06\x00\x41\x01\x10\x00\x0b");
$$ = instance("\x00\x61\x73\x6d\x0d\x00\x00\x00\x01\x08\x02\x60\x01\x7f\x00\x60\x00\x00\x02\x12\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x70\x72\x69\x6e\x74\x00\x00\x03\x02\x01\x01\x08\x01\x01\x0a\x08\x01\x06\x00\x41\x02\x10\x00\x0b");
$$ = instance("\x00\x61\x73\x6d\x0d\x00\x00\x00\x01\x04\x01\x60\x00\x00\x02\x12\x01\x08\x73\x70\x65\x63\x74\x65\x73\x74\x05\x70\x72\x69\x6e\x74\x00\x00\x08\x01\x00");
assert_uninstantiable("\x00\x61\x73\x6d\x0d\x00\x00\x00\x01\x04\x01\x60\x00\x00\x03\x02\x01\x00\x08\x01\x00\x0a\x05\x01\x03\x00\x00\x0b");
