-
Notifications
You must be signed in to change notification settings - Fork 0
/
ruby.js
56 lines (52 loc) · 1.63 KB
/
ruby.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
/**
* @file OnBrowserJudge - for Ruby
* @author nodai2hITC
* @license MIT License
* @version v1.0.0
*/
"use strict"
const script = "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.6.2/dist/browser.umd.js"
const wasm = "https://cdn.jsdelivr.net/npm/@ruby/3.3-wasm-wasi@2.6.2/dist/ruby+stdlib.wasm"
importScripts(script)
let RubyModule
const { DefaultRubyVM } = this["ruby-wasm-wasi"]
const main = async () => {
const response = await fetch(wasm)
RubyModule = await WebAssembly.compileStreaming(response)
self.postMessage(["init"])
}
main()
self.addEventListener("message", async function(e) {
switch (e.data[0]) {
case "init":
this.self.postMessage(["ready"])
break
case "execute":
const data = e.data[1]
const testCase = data.testCase
const program = data.program
const input = data.input
const { vm } = await DefaultRubyVM(RubyModule)
vm.eval(`
require 'stringio'
$stdin = StringIO.new('${input.replaceAll("\\", "\\\\").replaceAll("'", "\\'")}', 'r')
$stdout = $stderr = StringIO.new(+'', 'w')
`)
let output = ""
let error = 0
const startTime = performance.now()
try {
vm.eval(program)
output = vm.eval("$stdout.string").toString()
} catch(err) {
if (err.toString().indexOf("SystemExit") != -1) {
output = vm.eval("$stdout.string").toString();
} else {
output = err.toString()
error = 2
}
}
const execTime = performance.now() - startTime
self.postMessage(["executed", { testCase, output, error, execTime }])
}
})