11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ciconst vm = require('vm');
61cb0ef41Sopenharmony_ciconst { WASI } = require('wasi');
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
91cb0ef41Sopenharmony_ciconst bufferSource = fixtures.readSync('simple.wasm');
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci(async () => {
121cb0ef41Sopenharmony_ci  {
131cb0ef41Sopenharmony_ci    // Verify that a WebAssembly.Instance is passed in.
141cb0ef41Sopenharmony_ci    const wasi = new WASI();
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci    assert.throws(
171cb0ef41Sopenharmony_ci      () => { wasi.start(); },
181cb0ef41Sopenharmony_ci      {
191cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
201cb0ef41Sopenharmony_ci        message: /"instance" argument must be of type object/,
211cb0ef41Sopenharmony_ci      },
221cb0ef41Sopenharmony_ci    );
231cb0ef41Sopenharmony_ci  }
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci  {
261cb0ef41Sopenharmony_ci    // Verify that the passed instance has an exports objects.
271cb0ef41Sopenharmony_ci    const wasi = new WASI({});
281cb0ef41Sopenharmony_ci    const wasm = await WebAssembly.compile(bufferSource);
291cb0ef41Sopenharmony_ci    const instance = await WebAssembly.instantiate(wasm);
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci    Object.defineProperty(instance, 'exports', { get() { return null; } });
321cb0ef41Sopenharmony_ci    assert.throws(
331cb0ef41Sopenharmony_ci      () => { wasi.start(instance); },
341cb0ef41Sopenharmony_ci      {
351cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
361cb0ef41Sopenharmony_ci        message: /"instance\.exports" property must be of type object/,
371cb0ef41Sopenharmony_ci      },
381cb0ef41Sopenharmony_ci    );
391cb0ef41Sopenharmony_ci  }
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci  {
421cb0ef41Sopenharmony_ci    // Verify that a _start() export was passed.
431cb0ef41Sopenharmony_ci    const wasi = new WASI({});
441cb0ef41Sopenharmony_ci    const wasm = await WebAssembly.compile(bufferSource);
451cb0ef41Sopenharmony_ci    const instance = await WebAssembly.instantiate(wasm);
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci    Object.defineProperty(instance, 'exports', {
481cb0ef41Sopenharmony_ci      get() {
491cb0ef41Sopenharmony_ci        return { memory: new WebAssembly.Memory({ initial: 1 }) };
501cb0ef41Sopenharmony_ci      },
511cb0ef41Sopenharmony_ci    });
521cb0ef41Sopenharmony_ci    assert.throws(
531cb0ef41Sopenharmony_ci      () => { wasi.start(instance); },
541cb0ef41Sopenharmony_ci      {
551cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
561cb0ef41Sopenharmony_ci        message: /"instance\.exports\._start" property must be of type function/,
571cb0ef41Sopenharmony_ci      },
581cb0ef41Sopenharmony_ci    );
591cb0ef41Sopenharmony_ci  }
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  {
621cb0ef41Sopenharmony_ci    // Verify that an _initialize export was not passed.
631cb0ef41Sopenharmony_ci    const wasi = new WASI({});
641cb0ef41Sopenharmony_ci    const wasm = await WebAssembly.compile(bufferSource);
651cb0ef41Sopenharmony_ci    const instance = await WebAssembly.instantiate(wasm);
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci    Object.defineProperty(instance, 'exports', {
681cb0ef41Sopenharmony_ci      get() {
691cb0ef41Sopenharmony_ci        return {
701cb0ef41Sopenharmony_ci          _start() {},
711cb0ef41Sopenharmony_ci          _initialize() {},
721cb0ef41Sopenharmony_ci          memory: new WebAssembly.Memory({ initial: 1 }),
731cb0ef41Sopenharmony_ci        };
741cb0ef41Sopenharmony_ci      },
751cb0ef41Sopenharmony_ci    });
761cb0ef41Sopenharmony_ci    assert.throws(
771cb0ef41Sopenharmony_ci      () => { wasi.start(instance); },
781cb0ef41Sopenharmony_ci      {
791cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
801cb0ef41Sopenharmony_ci        message: 'The "instance.exports._initialize" property must be' +
811cb0ef41Sopenharmony_ci          ' undefined. Received function _initialize',
821cb0ef41Sopenharmony_ci      },
831cb0ef41Sopenharmony_ci    );
841cb0ef41Sopenharmony_ci  }
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  {
871cb0ef41Sopenharmony_ci    // Verify that a memory export was passed.
881cb0ef41Sopenharmony_ci    const wasi = new WASI({});
891cb0ef41Sopenharmony_ci    const wasm = await WebAssembly.compile(bufferSource);
901cb0ef41Sopenharmony_ci    const instance = await WebAssembly.instantiate(wasm);
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci    Object.defineProperty(instance, 'exports', {
931cb0ef41Sopenharmony_ci      get() { return { _start() {} }; },
941cb0ef41Sopenharmony_ci    });
951cb0ef41Sopenharmony_ci    assert.throws(
961cb0ef41Sopenharmony_ci      () => { wasi.start(instance); },
971cb0ef41Sopenharmony_ci      {
981cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
991cb0ef41Sopenharmony_ci        message: /"instance\.exports\.memory" property must be a WebAssembly\.Memory object/,
1001cb0ef41Sopenharmony_ci      },
1011cb0ef41Sopenharmony_ci    );
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  {
1051cb0ef41Sopenharmony_ci    // Verify that a WebAssembly.Instance from another VM context is accepted.
1061cb0ef41Sopenharmony_ci    const wasi = new WASI({});
1071cb0ef41Sopenharmony_ci    const instance = await vm.runInNewContext(`
1081cb0ef41Sopenharmony_ci      (async () => {
1091cb0ef41Sopenharmony_ci        const wasm = await WebAssembly.compile(bufferSource);
1101cb0ef41Sopenharmony_ci        const instance = await WebAssembly.instantiate(wasm);
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci        Object.defineProperty(instance, 'exports', {
1131cb0ef41Sopenharmony_ci          get() {
1141cb0ef41Sopenharmony_ci            return {
1151cb0ef41Sopenharmony_ci              _start() {},
1161cb0ef41Sopenharmony_ci              memory: new WebAssembly.Memory({ initial: 1 })
1171cb0ef41Sopenharmony_ci            };
1181cb0ef41Sopenharmony_ci          }
1191cb0ef41Sopenharmony_ci        });
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci        return instance;
1221cb0ef41Sopenharmony_ci      })()
1231cb0ef41Sopenharmony_ci    `, { bufferSource });
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci    wasi.start(instance);
1261cb0ef41Sopenharmony_ci  }
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  {
1291cb0ef41Sopenharmony_ci    // Verify that start() can only be called once.
1301cb0ef41Sopenharmony_ci    const wasi = new WASI({});
1311cb0ef41Sopenharmony_ci    const wasm = await WebAssembly.compile(bufferSource);
1321cb0ef41Sopenharmony_ci    const instance = await WebAssembly.instantiate(wasm);
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci    Object.defineProperty(instance, 'exports', {
1351cb0ef41Sopenharmony_ci      get() {
1361cb0ef41Sopenharmony_ci        return {
1371cb0ef41Sopenharmony_ci          _start() {},
1381cb0ef41Sopenharmony_ci          memory: new WebAssembly.Memory({ initial: 1 }),
1391cb0ef41Sopenharmony_ci        };
1401cb0ef41Sopenharmony_ci      },
1411cb0ef41Sopenharmony_ci    });
1421cb0ef41Sopenharmony_ci    wasi.start(instance);
1431cb0ef41Sopenharmony_ci    assert.throws(
1441cb0ef41Sopenharmony_ci      () => { wasi.start(instance); },
1451cb0ef41Sopenharmony_ci      {
1461cb0ef41Sopenharmony_ci        code: 'ERR_WASI_ALREADY_STARTED',
1471cb0ef41Sopenharmony_ci        message: /^WASI instance has already started$/,
1481cb0ef41Sopenharmony_ci      },
1491cb0ef41Sopenharmony_ci    );
1501cb0ef41Sopenharmony_ci  }
1511cb0ef41Sopenharmony_ci})().then(common.mustCall());
152