@@ -2,6 +2,7 @@ import CodeMirror from "codemirror";
22
33import "codemirror/mode/swift/swift" ;
44import "codemirror/lib/codemirror.css" ;
5+ import { SwiftRuntime } from "javascript-kit-swift" ;
56import kDefaultDemoScript from './demo.swift?raw' ;
67
78const kCompileApi = "https://swiftwasm-compiler-api-mgv5x4syda-uc.a.run.app" ;
@@ -111,6 +112,25 @@ async function compileCode(code: string): Promise<CompilationResult> {
111112 }
112113}
113114
115+ export const wrapWASI = ( wasiObject : any ) => {
116+ // PATCH: @wasmer -js/wasi@0.x forgets to call `refreshMemory` in `clock_res_get`,
117+ // which writes its result to memory view. Without the refresh the memory view,
118+ // it accesses a detached array buffer if the memory is grown by malloc.
119+ // But they wasmer team discarded the 0.x codebase at all and replaced it with
120+ // a new implementation written in Rust. The new version 1.x is really unstable
121+ // and not production-ready as far as katei investigated in Apr 2022.
122+ // So override the broken implementation of `clock_res_get` here instead of
123+ // fixing the wasi polyfill.
124+ // Reference: https://github.com/wasmerio/wasmer-js/blob/55fa8c17c56348c312a8bd23c69054b1aa633891/packages/wasi/src/index.ts#L557
125+ const original_clock_res_get = wasiObject . wasiImport [ "clock_res_get" ] ;
126+
127+ wasiObject . wasiImport [ "clock_res_get" ] = function ( ) {
128+ wasiObject . refreshMemory ( ) ;
129+ return Reflect . apply ( original_clock_res_get , this , arguments ) ;
130+ } ;
131+ return wasiObject . wasiImport ;
132+ } ;
133+
114134async function runWasm ( wasmBuffer : ArrayBuffer ) {
115135 writeOutputArea ( "Running WebAssembly...\n" ) ;
116136 const { WasmFs } = await import ( "@wasmer/wasmfs" ) ;
@@ -137,28 +157,20 @@ async function runWasm(wasmBuffer: ArrayBuffer) {
137157 fs : wasmFs . fs ,
138158 } ,
139159 } ) ;
140-
141- let _instance : WebAssembly . Instance ;
142- const importObject = {
143- env : {
144- executeScript : ( ptr : number , len : number ) => {
145- const uint8Memory = new Uint8Array (
146- ( _instance . exports . memory as any ) . buffer
147- ) ;
148- const script = decoder . decode ( uint8Memory . subarray ( ptr , ptr + len ) ) ;
149- new Function ( script ) ( ) ;
150- } ,
151- } ,
152- } ;
160+ const swift = new SwiftRuntime ( ) ;
153161
154162 const { instance } = await WebAssembly . instantiate ( wasmBuffer , {
155163 wasi_snapshot_preview1 : wasi . wasiImport ,
156164 wasi_unstable : wasi . wasiImport ,
157- ... importObject ,
165+ javascript_kit : swift . wasmImports as any ,
158166 } ) ;
159167
160- _instance = instance ;
161- wasi . start ( instance ) ;
168+ wasi . setMemory ( instance . exports . memory as any ) ;
169+ ( instance . exports . _initialize as any ) ( ) ;
170+ if ( instance . exports . swjs_library_version ) {
171+ swift . setInstance ( instance ) ;
172+ }
173+ ( instance . exports . main as any ) ( ) ;
162174}
163175
164176function populateResultsArea ( compileResult : CompilationResult ) {
0 commit comments