ffi-error.js 7.2 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
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([
16 17
        kExprLocalGet, 0,      // --
        kExprLocalGet, 1,      // --
18 19 20 21
        kExprCallFunction, 0,  // --
      ])                       // --
      .exportFunc();
  return builder;
22 23
}

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

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

33 34
function checkFailingInstantiation(
    builder, ffi, error, message, prepend_context = true) {
35
  // Test synchronous instantiation.
36 37 38
  assertThrows(
      _ => builder.instantiate(ffi), error,
      (prepend_context ? 'WebAssembly.Instance(): ' : '') + message);
39

40
  // Test asynchronous instantiation.
41 42 43
  assertThrowsAsync(
      builder.asyncInstantiate(ffi), error,
      (prepend_context ? 'WebAssembly.instantiate(): ' : '') + message);
44
}
45

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

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

71 72 73 74 75 76 77 78
(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([
79
        kExprLocalGet,
80 81 82
        0,
      ])  // --
      .exportFunc();
83

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

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

99 100
  checkFailingInstantiation(
      CreateDefaultBuilder(), ffi, Error, 'my_exception', false);
101
})();
102

103 104 105 106 107 108 109 110 111 112 113
// "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();
114

115
  let exported = builder.instantiate().exports.exp;
116

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

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

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

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

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

  builder.addMemory(1, 1, true);
146
  builder.addFunction('function_with_invalid_signature', kSig_i_l)
147
      .addBody([kExprLocalGet, 0, kExprI32ConvertI64])
148
      .exportFunc();
149

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

})();
157 158

(function I64JSImportThrows() {
159 160 161 162 163 164 165
  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([
166
        kExprLocalGet, 0, kExprI64SConvertI32, kExprCallFunction, index  // --
167 168 169 170 171 172 173 174 175
      ])                                                                 // --
      .exportFunc();

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

176
})();
177

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

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

194 195
})();

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

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

212 213
})();

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

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