diff --git a/lib/wasm/WasmFinalizeExportsPlugin.js b/lib/wasm/WasmFinalizeExportsPlugin.js index 942f53ca8..cca46c4b6 100644 --- a/lib/wasm/WasmFinalizeExportsPlugin.js +++ b/lib/wasm/WasmFinalizeExportsPlugin.js @@ -4,46 +4,47 @@ */ "use strict"; -const Queue = require("../util/Queue"); -const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency"); const UnsupportedWebAssemblyFeatureError = require("../wasm/UnsupportedWebAssemblyFeatureError"); +const error = new UnsupportedWebAssemblyFeatureError( + "JavaScript modules can not use a WebAssembly export with an incompatible type signature" +); + class WasmFinalizeExportsPlugin { apply(compiler) { compiler.hooks.compilation.tap("WasmFinalizeExportsPlugin", compilation => { compilation.hooks.finishModules.tap( "WasmFinalizeExportsPlugin", modules => { - const queue = new Queue(); - - let module; - let jsIncompatibleExports = []; - for (const module of modules) { - if (module.buildMeta.jsIncompatibleExports) { - jsIncompatibleExports.push( - ...module.buildMeta.jsIncompatibleExports - ); + const jsIncompatibleExports = + module.buildMeta.jsIncompatibleExports; + + if ( + typeof jsIncompatibleExports === "undefined" || + jsIncompatibleExports.length === 0 + ) { + continue; } - queue.enqueue(module); - } + // 1. if a WebAssembly module + if (module.type.startsWith("webassembly") === true) { + for (const reason of module.reasons) { + // 2. is referenced by a non-WebAssembly module + if (reason.module.type.startsWith("webassembly") === false) { + // const ref = reason.dependency.getReference(); - while (queue.length > 0) { - module = queue.dequeue(); + // ref.importedNames // returns true? - // 1. if a non WebAssembly module - if (module.type.startsWith("webassembly") === false) { - for (const dep of module.dependencies) { - // 2. imports a WebAssembly module - // FIXME(sven): pseudo code from here - if (dep.type === "webassembly") { - // 3. if the used import is flaged as invalid - if (jsIncompatibleExports.indexOf(dep.usedName)) { - throw new UnsupportedWebAssemblyFeatureError( - "JavaScript modules can not use WebAssembly export with an incompatible type signature" - ); - } + const names = []; + + names.forEach(name => { + // 3. and uses a func with an incompatible JS signature + if (jsIncompatibleExports.indexOf(name) !== -1) { + // 4. error + compilation.errors.push(error); + } + }); } } } diff --git a/test/cases/wasm/js-incompatible-type/index.js b/test/cases/wasm/js-incompatible-type/index.js index ded1dfce2..15c3274cb 100644 --- a/test/cases/wasm/js-incompatible-type/index.js +++ b/test/cases/wasm/js-incompatible-type/index.js @@ -1,11 +1,15 @@ it("should disallow exporting a func signature with result i64", function() { - return expect(import("./export-i64-result.wat")).rejects.toThrow(/invalid type/); + return import("./export-i64-result.wat").then(({a}) => { + expect(a).toThrow(/invalid type/); + }); }); it("should disallow exporting a func signature with param i64", function() { - return expect(import("./export-i64-param.wat")).rejects.toThrow(/invalid type/); + return import("./export-i64-param.wat").then(({a}) => { + expect(a).toThrow(/invalid type/); + }); }); it("should disallow importing a value type of i64", function() { - return expect(import("./import-i64.wat")).rejects.toThrow(/invalid type/); + return expect(import("./import-i64.wat")).rejects.toThrow(/invalid type/); });