instantiate-module-basic.js 8.21 KB
Newer Older
1 2 3 4
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
// Flags: --expose-wasm --allow-natives-syntax
6

7 8
load('test/mjsunit/wasm/wasm-constants.js');
load('test/mjsunit/wasm/wasm-module-builder.js');
9

10
let kReturnValue = 17;
11

rossberg's avatar
rossberg committed
12 13
let buffer = (() => {
  let builder = new WasmModuleBuilder();
14
  builder.addMemory(1, 1, true);
15 16 17
  builder.addFunction('main', kSig_i_v)
      .addBody([kExprI32Const, kReturnValue])
      .exportFunc();
18

rossberg's avatar
rossberg committed
19
  return builder.toBuffer();
20
})();
rossberg's avatar
rossberg committed
21 22 23 24 25

function CheckInstance(instance) {
  assertFalse(instance === undefined);
  assertFalse(instance === null);
  assertFalse(instance === 0);
26
  assertEquals('object', typeof instance);
rossberg's avatar
rossberg committed
27

28 29 30 31
  // Check the exports object is frozen.
  assertFalse(Object.isExtensible(instance.exports));
  assertTrue(Object.isFrozen(instance.exports));

mtrofin's avatar
mtrofin committed
32
  // Check the memory is WebAssembly.Memory.
rossberg's avatar
rossberg committed
33 34 35 36
  var mem = instance.exports.memory;
  assertFalse(mem === undefined);
  assertFalse(mem === null);
  assertFalse(mem === 0);
37
  assertEquals('object', typeof mem);
38 39 40 41 42
  assertTrue(mem instanceof WebAssembly.Memory);
  var buf = mem.buffer;
  assertTrue(buf instanceof ArrayBuffer);
  assertEquals(65536, buf.byteLength);
  for (var i = 0; i < 4; i++) {
rossberg's avatar
rossberg committed
43
    instance.exports.memory = 0;  // should be ignored
44
    mem.buffer = 0;               // should be ignored
rossberg's avatar
rossberg committed
45
    assertSame(mem, instance.exports.memory);
46
    assertSame(buf, mem.buffer);
rossberg's avatar
rossberg committed
47 48 49 50 51 52 53
  }

  // Check the properties of the main function.
  let main = instance.exports.main;
  assertFalse(main === undefined);
  assertFalse(main === null);
  assertFalse(main === 0);
54
  assertEquals('function', typeof main);
rossberg's avatar
rossberg committed
55 56

  assertEquals(kReturnValue, main());
57 58
}

rossberg's avatar
rossberg committed
59
// Official API
60
(function BasicJSAPITest() {
61
  print('sync module compile...');
62
  let module = new WebAssembly.Module(buffer);
63
  print('sync module instantiate...');
64
  CheckInstance(new WebAssembly.Instance(module));
65

66
  print('async module compile...');
67
  let promise = WebAssembly.compile(buffer);
68 69
  assertPromiseResult(
      promise, module => CheckInstance(new WebAssembly.Instance(module)));
70

71
  print('async instantiate...');
72
  let instance_promise = WebAssembly.instantiate(buffer);
73
  assertPromiseResult(instance_promise, pair => CheckInstance(pair.instance));
74
})();
75

76 77 78 79
// Check that validate works correctly for a module.
assertTrue(WebAssembly.validate(buffer));
assertFalse(WebAssembly.validate(bytes(88, 88, 88, 88, 88, 88, 88, 88)));

80 81
// Negative tests.
(function InvalidModules() {
82 83
  print('InvalidModules...');
  let invalid_cases = [undefined, 1, '', 'a', {some: 1, obj: 'b'}];
84 85 86
  let len = invalid_cases.length;
  for (var i = 0; i < len; ++i) {
    try {
87
      let instance = new WebAssembly.Instance(invalid_cases[i]);
88
      assertUnreachable('should not be able to instantiate invalid modules.');
89
    } catch (e) {
90
      assertContains('Argument 0', e.toString());
91 92 93 94 95 96
    }
  }
})();

// Compile async an invalid blob.
(function InvalidBinaryAsyncCompilation() {
97
  print('InvalidBinaryAsyncCompilation...');
98
  let builder = new WasmModuleBuilder();
99
  builder.addFunction('f', kSig_i_i).addBody([kExprCallFunction, 0]);
100
  let promise = WebAssembly.compile(builder.toBuffer());
101 102 103 104
  assertPromiseResult(
      promise, compiled => assertUnreachable(
                   'should not be able to compile invalid blob.'),
      e => assertInstanceof(e, WebAssembly.CompileError));
105 106 107 108
})();

// Multiple instances tests.
(function ManyInstances() {
109
  print('ManyInstances...');
110 111 112 113 114 115 116
  let compiled_module = new WebAssembly.Module(buffer);
  let instance_1 = new WebAssembly.Instance(compiled_module);
  let instance_2 = new WebAssembly.Instance(compiled_module);
  assertTrue(instance_1 != instance_2);
})();

(function ManyInstancesAsync() {
117
  print('ManyInstancesAsync...');
118
  let promise = WebAssembly.compile(buffer);
119 120 121 122 123
  assertPromiseResult(promise, compiled_module => {
    let instance_1 = new WebAssembly.Instance(compiled_module);
    let instance_2 = new WebAssembly.Instance(compiled_module);
    assertTrue(instance_1 != instance_2);
  });
124 125 126
})();

(function InstancesAreIsolatedFromEachother() {
127
  print('InstancesAreIsolatedFromEachother...');
128
  var builder = new WasmModuleBuilder();
129
  builder.addImportedMemory('', 'memory', 1);
130
  var kSig_v_i = makeSig([kWasmI32], []);
131
  var signature = builder.addType(kSig_v_i);
132 133 134 135 136 137 138 139 140 141
  builder.addImport('m', 'some_value', kSig_i_v);
  builder.addImport('m', 'writer', signature);

  builder.addFunction('main', kSig_i_i)
      .addBody([
        kExprGetLocal, 0, kExprI32LoadMem, 0, 0, kExprI32Const, 1,
        kExprCallIndirect, signature, kTableZero, kExprGetLocal, 0,
        kExprI32LoadMem, 0, 0, kExprCallFunction, 0, kExprI32Add
      ])
      .exportFunc();
142 143 144

  // writer(mem[i]);
  // return mem[i] + some_value();
145 146 147
  builder.addFunction('_wrap_writer', signature).addBody([
    kExprGetLocal, 0, kExprCallFunction, 1
  ]);
148
  builder.appendToTable([2, 3]);
149 150

  var module = new WebAssembly.Module(builder.toBuffer());
151 152 153 154
  var mem_1 = new WebAssembly.Memory({initial: 1});
  var mem_2 = new WebAssembly.Memory({initial: 1});
  var view_1 = new Int32Array(mem_1.buffer);
  var view_2 = new Int32Array(mem_2.buffer);
155 156 157 158 159 160

  view_1[0] = 42;
  view_2[0] = 1000;

  var outval_1;
  var outval_2;
161 162 163 164
  var i1 = new WebAssembly.Instance(module, {
    m: {some_value: () => 1, writer: (x) => outval_1 = x},
    '': {memory: mem_1}
  });
mtrofin's avatar
mtrofin committed
165

166 167 168 169
  var i2 = new WebAssembly.Instance(module, {
    m: {some_value: () => 2, writer: (x) => outval_2 = x},
    '': {memory: mem_2}
  });
170 171 172 173 174 175 176

  assertEquals(43, i1.exports.main(0));
  assertEquals(1002, i2.exports.main(0));

  assertEquals(42, outval_1);
  assertEquals(1000, outval_2);
})();
177 178

(function GlobalsArePrivateToTheInstance() {
179 180 181 182 183 184
  print('GlobalsArePrivateToTheInstance...');
  var builder = new WasmModuleBuilder();
  builder.addGlobal(kWasmI32, true);
  builder.addFunction('read', kSig_i_v)
      .addBody([kExprGetGlobal, 0])
      .exportFunc();
185

186 187 188 189 190 191 192 193 194 195 196 197
  builder.addFunction('write', kSig_v_i)
      .addBody([kExprGetLocal, 0, kExprSetGlobal, 0])
      .exportFunc();

  var module = new WebAssembly.Module(builder.toBuffer());
  var i1 = new WebAssembly.Instance(module);
  var i2 = new WebAssembly.Instance(module);
  i1.exports.write(1);
  i2.exports.write(2);
  assertEquals(1, i1.exports.read());
  assertEquals(2, i2.exports.read());
})();
198

199
(function InstanceMemoryIsIsolated() {
200
  print('InstanceMemoryIsIsolated...');
201
  var builder = new WasmModuleBuilder();
202
  builder.addImportedMemory('', 'memory', 1);
203

204 205 206
  builder.addFunction('f', kSig_i_v)
      .addBody([kExprI32Const, 0, kExprI32LoadMem, 0, 0])
      .exportFunc();
207

208 209 210 211
  var mem_1 = new WebAssembly.Memory({initial: 1});
  var mem_2 = new WebAssembly.Memory({initial: 1});
  var view_1 = new Int32Array(mem_1.buffer);
  var view_2 = new Int32Array(mem_2.buffer);
212 213
  view_1[0] = 1;
  view_2[0] = 1000;
214 215

  var module = new WebAssembly.Module(builder.toBuffer());
216 217
  var i1 = new WebAssembly.Instance(module, {'': {memory: mem_1}});
  var i2 = new WebAssembly.Instance(module, {'': {memory: mem_2}});
218 219 220

  assertEquals(1, i1.exports.f());
  assertEquals(1000, i2.exports.f());
221
})();
222 223

(function MustBeMemory() {
224
  print('MustBeMemory...');
225
  var memory = new ArrayBuffer(65536);
mtrofin's avatar
mtrofin committed
226
  let builder = new WasmModuleBuilder();
227
  builder.addImportedMemory('', 'memory');
mtrofin's avatar
mtrofin committed
228 229 230

  let module = new WebAssembly.Module(builder.toBuffer());

231 232 233
  assertThrows(
      () => new WebAssembly.Instance(module, {'': {memory: memory}}),
      WebAssembly.LinkError);
234
})();
235 236 237 238 239 240

(function TestNoMemoryToExport() {
  let builder = new WasmModuleBuilder();
  builder.exportMemoryAs('memory');
  assertThrows(() => builder.instantiate(), WebAssembly.CompileError);
})();
241 242

(function TestIterableExports() {
243
  print('TestIterableExports...');
244
  let builder = new WasmModuleBuilder;
245 246 247 248 249
  builder.addExport('a', builder.addFunction('', kSig_v_v).addBody([]));
  builder.addExport('b', builder.addFunction('', kSig_v_v).addBody([]));
  builder.addExport('c', builder.addFunction('', kSig_v_v).addBody([]));
  builder.addExport('d', builder.addFunction('', kSig_v_v).addBody([]));
  builder.addExport('e', builder.addGlobal(kWasmI32, false));
250 251 252 253 254 255 256 257 258

  let module = new WebAssembly.Module(builder.toBuffer());
  let instance = new WebAssembly.Instance(module);

  let exports_count = 0;
  for (var e in instance.exports) ++exports_count;

  assertEquals(5, exports_count);
})();