ffi-error.js 7.31 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 6
// Flags: --expose-wasm

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
load('test/mjsunit/wasm/wasm-constants.js');
load('test/mjsunit/wasm/wasm-module-builder.js');

function CreateDefaultBuilder() {
  const builder = new WasmModuleBuilder();

  const sig_index = kSig_i_dd;
  builder.addImport('mod', 'fun', sig_index);
  builder.addFunction('main', sig_index)
      .addBody([
        kExprGetLocal, 0,      // --
        kExprGetLocal, 1,      // --
        kExprCallFunction, 0,  // --
      ])                       // --
      .exportFunc();
  return builder;
23 24
}

25 26 27 28
function checkSuccessfulInstantiation(builder, ffi, handler) {
  // Test synchronous instantiation.
  const instance = builder.instantiate(ffi);
  if (handler) handler(instance);
29

30 31 32
  // Test asynchronous instantiation.
  assertPromiseResult(builder.asyncInstantiate(ffi), handler);
}
33

34 35 36
function checkFailingInstantiation(builder, ffi, error, message) {
  // Test synchronous instantiation.
  assertThrows(_ => builder.instantiate(ffi), error, message);
37

38 39 40 41 42 43
  // Test asynchronous instantiation.
  assertPromiseResult(builder.asyncInstantiate(ffi), assertUnreachable, e => {
    assertInstanceof(e, error);
    assertEquals(message, e.message);
  });
}
44

45 46 47 48 49
(function testValidFFI() {
  print(arguments.callee.name);
  let ffi = {'mod': {fun: print}};
  checkSuccessfulInstantiation(CreateDefaultBuilder(), ffi, undefined);
})();
50

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
(function testInvalidFFIs() {
  print(arguments.callee.name);
  checkFailingInstantiation(
      CreateDefaultBuilder(), 17, TypeError,
      'WebAssembly Instantiation: Argument 1 must be an object');
  checkFailingInstantiation(
      CreateDefaultBuilder(), {}, TypeError,
      'WebAssembly Instantiation: Import #0 module="mod" error: module is not an object or function');
  checkFailingInstantiation(
      CreateDefaultBuilder(), {mod: {}}, WebAssembly.LinkError,
      'WebAssembly Instantiation: Import #0 module="mod" function="fun" error: function import requires a callable');
  checkFailingInstantiation(
      CreateDefaultBuilder(), {mod: {fun: {}}}, WebAssembly.LinkError,
      'WebAssembly Instantiation: Import #0 module="mod" function="fun" error: function import requires a callable');
  checkFailingInstantiation(
      CreateDefaultBuilder(), {mod: {fun: 0}}, WebAssembly.LinkError,
      'WebAssembly Instantiation: Import #0 module="mod" function="fun" error: function import requires a callable');
})();
69

70 71 72 73 74 75 76 77 78 79 80 81
(function testImportWithInvalidSignature() {
  print(arguments.callee.name);
  // "fun" should have signature "i_dd"
  let builder = new WasmModuleBuilder();

  let sig_index = kSig_i_dd;
  builder.addFunction('exp', kSig_i_i)
      .addBody([
        kExprGetLocal,
        0,
      ])  // --
      .exportFunc();
82

83 84 85 86 87
  let exported = builder.instantiate().exports.exp;
  checkFailingInstantiation(
      CreateDefaultBuilder(), {mod: {fun: exported}}, WebAssembly.LinkError,
      'WebAssembly Instantiation: Import #0 module="mod" function="fun" error: imported function does not match the expected type');
})();
88

89 90 91 92 93 94 95 96
(function regression870646() {
  print(arguments.callee.name);
  const ffi = {mod: {fun: function() {}}};
  Object.defineProperty(ffi, 'mod', {
    get: function() {
      throw new Error('my_exception');
    }
  });
97

98 99
  checkFailingInstantiation(CreateDefaultBuilder(), ffi, Error, 'my_exception');
})();
100

101 102 103 104 105 106 107 108 109 110 111
// "fun" matches signature "i_dd"
(function testImportWithValidSignature() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();

  builder.addFunction('exp', kSig_i_dd)
      .addBody([
        kExprI32Const,
        33,
      ])  // --
      .exportFunc();
112

113
  let exported = builder.instantiate().exports.exp;
114

115 116 117
  checkSuccessfulInstantiation(
      CreateDefaultBuilder(), {mod: {fun: exported}},
      instance => assertEquals(33, instance.exports.main()));
118
})();
119 120

(function I64InSignatureThrows() {
121 122
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
123 124

  builder.addMemory(1, 1, true);
125
  builder.addFunction('function_with_invalid_signature', kSig_l_ll)
126 127 128 129 130 131
    .addBody([           // --
      kExprGetLocal, 0,  // --
      kExprGetLocal, 1,  // --
      kExprI64Sub])      // --
    .exportFunc()

132 133 134 135 136
  checkSuccessfulInstantiation(
      builder, undefined,
      instance => assertThrows(function() {
        instance.exports.function_with_invalid_signature(33, 88);
      }, TypeError, 'wasm function signature contains illegal type'));
137
})();
138

139
(function I64ParamsInSignatureThrows() {
140 141
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
142 143

  builder.addMemory(1, 1, true);
144 145 146
  builder.addFunction('function_with_invalid_signature', kSig_i_l)
      .addBody([kExprGetLocal, 0, kExprI32ConvertI64])
      .exportFunc();
147

148 149 150 151 152
  checkSuccessfulInstantiation(
      builder, undefined,
      instance => assertThrows(
          _ => instance.exports.function_with_invalid_signature(12), TypeError,
          'wasm function signature contains illegal type'));
153 154

})();
155 156

(function I64JSImportThrows() {
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let sig_index = builder.addType(kSig_i_i);
  let sig_i64_index = builder.addType(kSig_i_l);
  let index = builder.addImport('', 'func', sig_i64_index);
  builder.addFunction('main', sig_index)
      .addBody([
        kExprGetLocal, 0, kExprI64SConvertI32, kExprCallFunction, index  // --
      ])                                                                 // --
      .exportFunc();

  checkSuccessfulInstantiation(
      builder, {'': {func: _ => {}}},
      instance => assertThrows(
          instance.exports.main, TypeError,
          'wasm function signature contains illegal type'));

174
})();
175

176
(function ImportI64ParamWithF64ReturnThrows() {
177
  print(arguments.callee.name);
178 179
  // This tests that we generate correct code by using the correct return
  // register. See bug 6096.
180
  let builder = new WasmModuleBuilder();
181 182 183 184 185
  builder.addImport('', 'f', makeSig([kWasmI64], [kWasmF64]));
  builder.addFunction('main', kSig_v_v)
      .addBody([kExprI64Const, 0, kExprCallFunction, 0, kExprDrop])
      .exportFunc();

186 187 188 189 190 191
  checkSuccessfulInstantiation(
      builder, {'': {f: i => i}},
      instance => assertThrows(
          instance.exports.main, TypeError,
          'wasm function signature contains illegal type'));

192 193
})();

194
(function ImportI64Return() {
195
  print(arguments.callee.name);
196 197
  // This tests that we generate correct code by using the correct return
  // register(s). See bug 6104.
198
  let builder = new WasmModuleBuilder();
199 200 201 202 203
  builder.addImport('', 'f', makeSig([], [kWasmI64]));
  builder.addFunction('main', kSig_v_v)
      .addBody([kExprCallFunction, 0, kExprDrop])
      .exportFunc();

204 205 206 207 208 209
  checkSuccessfulInstantiation(
      builder, {'': {f: _ => 1}},
      instance => assertThrows(
          instance.exports.main, TypeError,
          'wasm function signature contains illegal type'));

210 211
})();

212
(function ImportSymbolToNumberThrows() {
213 214 215 216
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let index = builder.addImport('', 'f', kSig_i_v);
  builder.addFunction('main', kSig_i_v)
217 218
      .addBody([kExprCallFunction, 0])
      .exportFunc();
219 220 221 222 223 224

  checkSuccessfulInstantiation(
      builder, {'': {f: _ => Symbol()}},
      instance => assertThrows(
          instance.exports.main, TypeError,
          'Cannot convert a Symbol value to a number'));
225
})();