[Wasm] Support generating browser-compatible JS harness

* Use fetch and instantiateStreaming
* Call main export if it is present
* Produce a variable with module name that contains a
  promise of module exports
This commit is contained in:
Svyatoslav Kuzmich
2021-09-03 08:57:55 +03:00
parent e194a07358
commit 7e399202a2
@@ -38,6 +38,10 @@ import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
import org.jetbrains.kotlin.incremental.js.IncrementalNextRoundChecker import org.jetbrains.kotlin.incremental.js.IncrementalNextRoundChecker
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
import org.jetbrains.kotlin.ir.backend.js.* import org.jetbrains.kotlin.ir.backend.js.*
import org.jetbrains.kotlin.ir.backend.js.ic.actualizeCacheForModule
import org.jetbrains.kotlin.ir.backend.js.ic.buildCache
import org.jetbrains.kotlin.ir.backend.js.ic.checkCaches
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
import org.jetbrains.kotlin.ir.backend.js.ic.* import org.jetbrains.kotlin.ir.backend.js.ic.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
@@ -314,10 +318,11 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
outputWatFile.writeText(res.wat) outputWatFile.writeText(res.wat)
val runner = """ val runner = """
const wasmBinary = read(String.raw`${outputWasmFile.absoluteFile}`, 'binary'); const ${sanitizeName(moduleName)} = WebAssembly.instantiateStreaming(fetch('${outputWasmFile.name}'), { runtime, js_code }).then((it) => {
const wasmModule = new WebAssembly.Module(wasmBinary); wasmInstance = it.instance;
wasmInstance = new WebAssembly.Instance(wasmModule, { runtime, js_code }); wasmInstance.exports.main?.();
wasmInstance.exports.main(); return it.instance.exports;
});
""".trimIndent() """.trimIndent()
outputFile.writeText(res.js + "\n" + runner) outputFile.writeText(res.js + "\n" + runner)