[Wasi] Add default wasi ejs runner (for nodejs)

This commit is contained in:
Igor Yakovlev
2023-08-02 15:05:49 +02:00
committed by Space Team
parent f1efeff21b
commit 69c97688c0
@@ -22,6 +22,8 @@ import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.config.WasmTarget
import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver
import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder
import org.jetbrains.kotlin.name.FqName
@@ -34,7 +36,7 @@ import java.io.File
class WasmCompilerResult(
val wat: String?,
val jsUninstantiatedWrapper: String,
val jsUninstantiatedWrapper: String?,
val jsWrapper: String,
val wasm: ByteArray,
val sourceMap: String?
@@ -109,12 +111,6 @@ fun compileWasm(
null
}
val jsUninstantiatedWrapper = compiledWasmModule.generateAsyncJsWrapper(
"./$baseFileName.wasm",
backendContext.jsModuleAndQualifierReferences
)
val jsWrapper = generateEsmExportsWrapper("./$baseFileName.uninstantiated.mjs")
val os = ByteArrayOutputStream()
val sourceMapFileName = "$baseFileName.map".takeIf { generateSourceMaps }
@@ -134,6 +130,18 @@ fun compileWasm(
wasmIrToBinary.appendWasmModule()
val byteArray = os.toByteArray()
val jsUninstantiatedWrapper: String?
val jsWrapper: String
if (backendContext.configuration.get(JSConfigurationKeys.WASM_TARGET, WasmTarget.JS) == WasmTarget.JS) {
jsUninstantiatedWrapper = compiledWasmModule.generateAsyncJsWrapper(
"./$baseFileName.wasm",
backendContext.jsModuleAndQualifierReferences
)
jsWrapper = generateEsmExportsWrapper("./$baseFileName.uninstantiated.mjs")
} else {
jsUninstantiatedWrapper = null
jsWrapper = compiledWasmModule.generateAsyncWasiWrapper("./$baseFileName.wasm")
}
return WasmCompilerResult(
wat = wat,
@@ -177,6 +185,28 @@ private fun generateSourceMap(
return sourceMapBuilder.build()
}
fun WasmCompiledModuleFragment.generateAsyncWasiWrapper(wasmFilePath: String): String = """
import { WASI } from 'wasi';
import { argv, env } from 'node:process';
const wasi = new WASI({ version: 'preview1', args: argv, env, });
const module = await import(/* webpackIgnore: true */'node:module');
const require = module.default.createRequire(import.meta.url);
const fs = require('fs');
const path = require('path');
const url = require('url');
const filepath = url.fileURLToPath(import.meta.url);
const dirpath = path.dirname(filepath);
const wasmBuffer = fs.readFileSync(path.resolve(dirpath, '$wasmFilePath'));
const wasmModule = new WebAssembly.Module(wasmBuffer);
const wasmInstance = new WebAssembly.Instance(wasmModule, wasi.getImportObject());
wasi.initialize(wasmInstance);
export default wasmInstance.exports;
"""
fun WasmCompiledModuleFragment.generateAsyncJsWrapper(
wasmFilePath: String,
jsModuleAndQualifierReferences: Set<JsModuleAndQualifierReference>
@@ -341,7 +371,9 @@ fun writeCompilationResult(
}
File(dir, "$fileNameBase.wasm").writeBytes(result.wasm)
File(dir, "$fileNameBase.uninstantiated.mjs").writeText(result.jsUninstantiatedWrapper)
if (result.jsUninstantiatedWrapper != null) {
File(dir, "$fileNameBase.uninstantiated.mjs").writeText(result.jsUninstantiatedWrapper)
}
File(dir, "$fileNameBase.mjs").writeText(result.jsWrapper)
if (result.sourceMap != null) {