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.initialize(); },
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.initialize(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 _initialize() 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 {
501cb0ef41Sopenharmony_ci          _initialize: 5,
511cb0ef41Sopenharmony_ci          memory: new WebAssembly.Memory({ initial: 1 }),
521cb0ef41Sopenharmony_ci        };
531cb0ef41Sopenharmony_ci      },
541cb0ef41Sopenharmony_ci    });
551cb0ef41Sopenharmony_ci    assert.throws(
561cb0ef41Sopenharmony_ci      () => { wasi.initialize(instance); },
571cb0ef41Sopenharmony_ci      {
581cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
591cb0ef41Sopenharmony_ci        message: /"instance\.exports\._initialize" property must be of type function/,
601cb0ef41Sopenharmony_ci      },
611cb0ef41Sopenharmony_ci    );
621cb0ef41Sopenharmony_ci  }
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  {
651cb0ef41Sopenharmony_ci    // Verify that a _start export was not passed.
661cb0ef41Sopenharmony_ci    const wasi = new WASI({});
671cb0ef41Sopenharmony_ci    const wasm = await WebAssembly.compile(bufferSource);
681cb0ef41Sopenharmony_ci    const instance = await WebAssembly.instantiate(wasm);
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci    Object.defineProperty(instance, 'exports', {
711cb0ef41Sopenharmony_ci      get() {
721cb0ef41Sopenharmony_ci        return {
731cb0ef41Sopenharmony_ci          _start() {},
741cb0ef41Sopenharmony_ci          _initialize() {},
751cb0ef41Sopenharmony_ci          memory: new WebAssembly.Memory({ initial: 1 }),
761cb0ef41Sopenharmony_ci        };
771cb0ef41Sopenharmony_ci      },
781cb0ef41Sopenharmony_ci    });
791cb0ef41Sopenharmony_ci    assert.throws(
801cb0ef41Sopenharmony_ci      () => { wasi.initialize(instance); },
811cb0ef41Sopenharmony_ci      {
821cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
831cb0ef41Sopenharmony_ci        message: 'The "instance.exports._start" property must be' +
841cb0ef41Sopenharmony_ci          ' undefined. Received function _start',
851cb0ef41Sopenharmony_ci      },
861cb0ef41Sopenharmony_ci    );
871cb0ef41Sopenharmony_ci  }
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci  {
901cb0ef41Sopenharmony_ci    // Verify that a memory export was passed.
911cb0ef41Sopenharmony_ci    const wasi = new WASI({});
921cb0ef41Sopenharmony_ci    const wasm = await WebAssembly.compile(bufferSource);
931cb0ef41Sopenharmony_ci    const instance = await WebAssembly.instantiate(wasm);
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci    Object.defineProperty(instance, 'exports', {
961cb0ef41Sopenharmony_ci      get() { return { _initialize() {} }; },
971cb0ef41Sopenharmony_ci    });
981cb0ef41Sopenharmony_ci    assert.throws(
991cb0ef41Sopenharmony_ci      () => { wasi.initialize(instance); },
1001cb0ef41Sopenharmony_ci      {
1011cb0ef41Sopenharmony_ci        code: 'ERR_INVALID_ARG_TYPE',
1021cb0ef41Sopenharmony_ci        message: /"instance\.exports\.memory" property must be a WebAssembly\.Memory object/,
1031cb0ef41Sopenharmony_ci      },
1041cb0ef41Sopenharmony_ci    );
1051cb0ef41Sopenharmony_ci  }
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  {
1081cb0ef41Sopenharmony_ci    // Verify that a WebAssembly.Instance from another VM context is accepted.
1091cb0ef41Sopenharmony_ci    const wasi = new WASI({});
1101cb0ef41Sopenharmony_ci    const instance = await vm.runInNewContext(`
1111cb0ef41Sopenharmony_ci      (async () => {
1121cb0ef41Sopenharmony_ci        const wasm = await WebAssembly.compile(bufferSource);
1131cb0ef41Sopenharmony_ci        const instance = await WebAssembly.instantiate(wasm);
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci        Object.defineProperty(instance, 'exports', {
1161cb0ef41Sopenharmony_ci          get() {
1171cb0ef41Sopenharmony_ci            return {
1181cb0ef41Sopenharmony_ci              _initialize() {},
1191cb0ef41Sopenharmony_ci              memory: new WebAssembly.Memory({ initial: 1 })
1201cb0ef41Sopenharmony_ci            };
1211cb0ef41Sopenharmony_ci          }
1221cb0ef41Sopenharmony_ci        });
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci        return instance;
1251cb0ef41Sopenharmony_ci      })()
1261cb0ef41Sopenharmony_ci    `, { bufferSource });
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci    wasi.initialize(instance);
1291cb0ef41Sopenharmony_ci  }
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  {
1321cb0ef41Sopenharmony_ci    // Verify that initialize() can only be called once.
1331cb0ef41Sopenharmony_ci    const wasi = new WASI({});
1341cb0ef41Sopenharmony_ci    const wasm = await WebAssembly.compile(bufferSource);
1351cb0ef41Sopenharmony_ci    const instance = await WebAssembly.instantiate(wasm);
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci    Object.defineProperty(instance, 'exports', {
1381cb0ef41Sopenharmony_ci      get() {
1391cb0ef41Sopenharmony_ci        return {
1401cb0ef41Sopenharmony_ci          _initialize() {},
1411cb0ef41Sopenharmony_ci          memory: new WebAssembly.Memory({ initial: 1 }),
1421cb0ef41Sopenharmony_ci        };
1431cb0ef41Sopenharmony_ci      },
1441cb0ef41Sopenharmony_ci    });
1451cb0ef41Sopenharmony_ci    wasi.initialize(instance);
1461cb0ef41Sopenharmony_ci    assert.throws(
1471cb0ef41Sopenharmony_ci      () => { wasi.initialize(instance); },
1481cb0ef41Sopenharmony_ci      {
1491cb0ef41Sopenharmony_ci        code: 'ERR_WASI_ALREADY_STARTED',
1501cb0ef41Sopenharmony_ci        message: /^WASI instance has already started$/,
1511cb0ef41Sopenharmony_ci      },
1521cb0ef41Sopenharmony_ci    );
1531cb0ef41Sopenharmony_ci  }
1541cb0ef41Sopenharmony_ci})().then(common.mustCall());
155