-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.js
126 lines (98 loc) · 2.88 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import './dist/output.css'
import { init, WASI } from "@wasmer/wasi"
import { WasmFs } from '@wasmer/wasmfs'
import { RubyVM } from "ruby-head-wasm-wasi"
import {} from "geteventlisteners"
const consolePrinter = () => {
let memory = undefined;
let view = undefined;
const decoder = new TextDecoder();
return {
addToImports(imports) {
const original = imports.wasi_snapshot_preview1.fd_write;
imports.wasi_snapshot_preview1.fd_write = (fd, iovs, iovsLen, nwritten) => {
if (fd !== 1 && fd !== 2) {
return original(fd, iovs, iovsLen, nwritten);
}
if (typeof memory === 'undefined' || typeof view === 'undefined') {
throw new Error('Memory is not set');
}
if (view.buffer.byteLength === 0) {
view = new DataView(memory.buffer);
}
const buffers = Array.from({ length: iovsLen }, (_, i) => {
const ptr = iovs + i * 8;
const buf = view.getUint32(ptr, true);
const bufLen = view.getUint32(ptr + 4, true);
return new Uint8Array(memory.buffer, buf, bufLen);
});
let written = 0;
let str = '';
for (const buffer of buffers) {
str += decoder.decode(buffer);
written += buffer.byteLength;
}
view.setUint32(nwritten, written, true);
const log = fd === 1 ? console.log : console.warn;
log(str);
return 0;
};
},
setMemory(m) {
memory = m;
view = new DataView(m.buffer);
}
}
};
export class RubyFront {
async init(rubyModule) {
await init()
const wasmFs = new WasmFs()
const wasi = new WASI({
env: {
"RUBY_FIBER_MACHINE_STACK_SIZE": String(1024 * 1024 * 20),
},
bindings: {fs: wasmFs.fs}
})
const vm = new RubyVM()
const imports = wasi.getImports(rubyModule)
vm.addToImports(imports)
const printer = consolePrinter()
printer?.addToImports(imports)
const instance = await WebAssembly.instantiate(rubyModule, imports)
wasi.instantiate(instance)
await vm.setInstance(instance)
printer?.setMemory(instance.exports.memory)
instance.exports._initialize()
vm.initialize()
return {vm, wasi, instance}
}
}
const main = async() => {
const response = await fetch(`ruby+stdlib.wasm`)
const buffer = await response.arrayBuffer()
const module = await WebAssembly.compile(buffer)
const { vm } = await new RubyFront().init(module)
vm.printVersion();
globalThis.rubyVM = vm
const script = await fetch(`./src/main.rb`)
vm.evalAsync(await script.text())
}
class PromiseFunctions {
constructor(ok, fail) {
this.okCb = ok
this.failCb = fail
}
ok(value) {
this.okCb(value)
}
fail(value) {
this.failCb(value)
}
}
window.NewPromise = (callback) => {
return new Promise((ok, fail) => {
callback(new PromiseFunctions(ok, fail))
})
}
await main()