• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4const assert = require('assert');
5const vm = require('vm');
6const { WASI } = require('wasi');
7
8const fixtures = require('../common/fixtures');
9const bufferSource = fixtures.readSync('simple.wasm');
10
11(async () => {
12  {
13    // Verify that a WebAssembly.Instance is passed in.
14    const wasi = new WASI();
15
16    assert.throws(
17      () => { wasi.initialize(); },
18      {
19        code: 'ERR_INVALID_ARG_TYPE',
20        message: /"instance" argument must be of type object/,
21      },
22    );
23  }
24
25  {
26    // Verify that the passed instance has an exports objects.
27    const wasi = new WASI({});
28    const wasm = await WebAssembly.compile(bufferSource);
29    const instance = await WebAssembly.instantiate(wasm);
30
31    Object.defineProperty(instance, 'exports', { get() { return null; } });
32    assert.throws(
33      () => { wasi.initialize(instance); },
34      {
35        code: 'ERR_INVALID_ARG_TYPE',
36        message: /"instance\.exports" property must be of type object/,
37      },
38    );
39  }
40
41  {
42    // Verify that a _initialize() export was passed.
43    const wasi = new WASI({});
44    const wasm = await WebAssembly.compile(bufferSource);
45    const instance = await WebAssembly.instantiate(wasm);
46
47    Object.defineProperty(instance, 'exports', {
48      get() {
49        return {
50          _initialize: 5,
51          memory: new WebAssembly.Memory({ initial: 1 }),
52        };
53      },
54    });
55    assert.throws(
56      () => { wasi.initialize(instance); },
57      {
58        code: 'ERR_INVALID_ARG_TYPE',
59        message: /"instance\.exports\._initialize" property must be of type function/,
60      },
61    );
62  }
63
64  {
65    // Verify that a _start export was not passed.
66    const wasi = new WASI({});
67    const wasm = await WebAssembly.compile(bufferSource);
68    const instance = await WebAssembly.instantiate(wasm);
69
70    Object.defineProperty(instance, 'exports', {
71      get() {
72        return {
73          _start() {},
74          _initialize() {},
75          memory: new WebAssembly.Memory({ initial: 1 }),
76        };
77      },
78    });
79    assert.throws(
80      () => { wasi.initialize(instance); },
81      {
82        code: 'ERR_INVALID_ARG_TYPE',
83        message: 'The "instance.exports._start" property must be' +
84          ' undefined. Received function _start',
85      },
86    );
87  }
88
89  {
90    // Verify that a memory export was passed.
91    const wasi = new WASI({});
92    const wasm = await WebAssembly.compile(bufferSource);
93    const instance = await WebAssembly.instantiate(wasm);
94
95    Object.defineProperty(instance, 'exports', {
96      get() { return { _initialize() {} }; },
97    });
98    assert.throws(
99      () => { wasi.initialize(instance); },
100      {
101        code: 'ERR_INVALID_ARG_TYPE',
102        message: /"instance\.exports\.memory" property must be a WebAssembly\.Memory object/,
103      },
104    );
105  }
106
107  {
108    // Verify that a WebAssembly.Instance from another VM context is accepted.
109    const wasi = new WASI({});
110    const instance = await vm.runInNewContext(`
111      (async () => {
112        const wasm = await WebAssembly.compile(bufferSource);
113        const instance = await WebAssembly.instantiate(wasm);
114
115        Object.defineProperty(instance, 'exports', {
116          get() {
117            return {
118              _initialize() {},
119              memory: new WebAssembly.Memory({ initial: 1 })
120            };
121          }
122        });
123
124        return instance;
125      })()
126    `, { bufferSource });
127
128    wasi.initialize(instance);
129  }
130
131  {
132    // Verify that initialize() can only be called once.
133    const wasi = new WASI({});
134    const wasm = await WebAssembly.compile(bufferSource);
135    const instance = await WebAssembly.instantiate(wasm);
136
137    Object.defineProperty(instance, 'exports', {
138      get() {
139        return {
140          _initialize() {},
141          memory: new WebAssembly.Memory({ initial: 1 }),
142        };
143      },
144    });
145    wasi.initialize(instance);
146    assert.throws(
147      () => { wasi.initialize(instance); },
148      {
149        code: 'ERR_WASI_ALREADY_STARTED',
150        message: /^WASI instance has already started$/,
151      },
152    );
153  }
154})().then(common.mustCall());
155