1+ # await: *await*
2+
3+ require 'await'
4+
15class RubyEngine
26 class CRubyWASI < RubyEngine
7+ REQUIRED_SCRIPTS = [
8+ {
9+ src : "https://cdn.jsdelivr.net/npm/ruby-wasm-wasi@0.1.2/dist/index.umd.js" ,
10+ integrity : "sha256-cPmKu5S3jkz5j0NnceapOfiWkzhBQqiBovOLjeYXwA0=" ,
11+ crossorigin : "anonymous"
12+ } ,
13+ {
14+ src : "https://cdn.jsdelivr.net/npm/@wasmer/wasmfs@0.12.0/lib/index.iife.js" ,
15+ integrity : "sha256-sOd4ekxVsN4PXhR+cn/4uNAxeQOJRcsaW5qalYfvkTw=" ,
16+ crossorigin : "anonymous"
17+ } ,
18+ {
19+ src : "https://cdn.jsdelivr.net/npm/@wasmer/wasi@0.12.0/lib/index.iife.js" ,
20+ integrity : "sha256-FslFp/Vq4bDf2GXu+9QyBEDLtEWO3fkMjpyOaJMHJT8=" ,
21+ crossorigin : "anonymous"
22+ }
23+ ]
24+
325 def initialize ( ruby_wasm_url , version )
426 @ruby_wasm_url = ruby_wasm_url
527 @version = version
@@ -13,53 +35,63 @@ def engine_id
1335 "cruby-#{ @version } "
1436 end
1537
38+ # Below functions will be compiled as async functions
39+ def self . inject_scripts
40+ @injected ||= begin
41+ REQUIRED_SCRIPTS . map do |script |
42+ promise = PromiseV2 . new
43+ script = $document. create_element ( "script" , attrs : script )
44+ script . on ( "load" ) { promise . resolve }
45+ script . on ( "error" ) { promise . reject ( StandardError . new ( "failed to load #{ script [ :src ] } " ) ) }
46+ $document. head << script
47+ promise
48+ end . each_await ( &:itself )
49+ true
50+ end
51+ end
52+
1653 def wasm_module
17- return @module if @module
18- %x{
19- #{ @module } = (async function() {
20- const response = await fetch(#{ @ruby_wasm_url } );
21- const buffer = await response.arrayBuffer();
22- return await WebAssembly.compile(buffer);
23- })();
24- }
25- @module
54+ @module ||= begin
55+ response = `fetch(#{ @ruby_wasm_url } )` . await
56+ buffer = `response.arrayBuffer()` . await
57+ `WebAssembly.compile(buffer)` . await
58+ end
2659 end
2760
2861 def run ( source , writer )
29- %x{
30- async function instantiateVM() {
31- const $WASI = window["WASI"].WASI;
32- const $WasmFs = window["WasmFs"].WasmFs;
33- const $RubyVM = window["ruby-wasm-wasi"].RubyVM;
62+ CRubyWASI . inject_scripts . await
3463
35- const wasmFs = new $WasmFs();
36- const originalWriteSync = wasmFs.fs.writeSync.bind(wasmFs.fs);
37- const textDecoder = new TextDecoder("utf-8");
38- wasmFs.fs.writeSync = (fd, buffer, offset, length, position) => {
39- const text = textDecoder.decode(buffer);
40- if (fd == 1 || fd == 2) {
41- #{ writer . print_to_output ( `text` , "" ) } ;
42- }
43- return originalWriteSync(fd, buffer, offset, length, position);
44- };
64+ %x{
65+ const $WASI = window["WASI"].WASI;
66+ const $WasmFs = window["WasmFs"].WasmFs;
67+ const $RubyVM = window["ruby-wasm-wasi"].RubyVM;
4568
46- const vm = new $RubyVM();
47- const wasi = new $WASI({
48- bindings: { ...$WASI.defaultBindings, fs: wasmFs.fs },
49- });
50- const imports = { wasi_snapshot_preview1: wasi.wasiImport };
51- vm.addToImports(imports);
52- const wasmInstance = await WebAssembly.instantiate(await #{ wasm_module } , imports);
53- await vm.setInstance(wasmInstance);
54- wasi.setMemory(wasmInstance.exports.memory);
55- vm.initialize();
56- return vm;
57- }
69+ const wasmFs = new $WasmFs();
70+ const originalWriteSync = wasmFs.fs.writeSync.bind(wasmFs.fs);
71+ const textDecoder = new TextDecoder("utf-8");
72+ wasmFs.fs.writeSync = (fd, buffer, offset, length, position) => {
73+ const text = textDecoder.decode(buffer);
74+ if (fd == 1 || fd == 2) {
75+ #{ writer . print_to_output ( `text` , "" ) } ;
76+ }
77+ return originalWriteSync(fd, buffer, offset, length, position);
78+ };
5879
59- instantiateVM()
60- .then((vm) => { #{ yield `vm.eval(source).toString()` } })
61- .catch((err) => { #{ writer . log_error ( `err` ) } })
80+ const vm = new $RubyVM();
81+ const wasi = new $WASI({
82+ bindings: { ...$WASI.defaultBindings, fs: wasmFs.fs },
83+ });
84+ const imports = { wasi_snapshot_preview1: wasi.wasiImport };
85+ vm.addToImports(imports);
86+ const wasmInstance = await WebAssembly.instantiate(#{ wasm_module . await } , imports);
87+ await vm.setInstance(wasmInstance);
88+ wasi.setMemory(wasmInstance.exports.memory);
89+ vm.initialize();
6290 }
91+
92+ yield `vm.eval(source).toString()`
93+ rescue JS ::Error => err
94+ writer . log_error ( err )
6395 end
6496 end
6597end
0 commit comments