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
|
class StdinBuffer {
constructor() {
this.sab = new SharedArrayBuffer(128 * Int32Array.BYTES_PER_ELEMENT)
this.buffer = new Int32Array(this.sab)
this.readIndex = 1;
this.numberOfCharacters = 0;
this.sentNull = true
}
prompt() {
this.readIndex = 1
Atomics.store(this.buffer, 0, -1)
postMessage({
type: 'stdin',
buffer: this.sab
})
Atomics.wait(this.buffer, 0, -1)
this.numberOfCharacters = this.buffer[0]
}
stdin = () => {
if (this.numberOfCharacters + 1 === this.readIndex) {
if (!this.sentNull) {
// Must return null once to indicate we're done for now.
this.sentNull = true
return null
}
this.sentNull = false
this.prompt()
}
const char = this.buffer[this.readIndex]
this.readIndex += 1
// How do I send an EOF??
return char
}
}
const stdout = (charCode) => {
if (charCode) {
postMessage({
type: 'stdout',
stdout: charCode,
})
} else {
console.log(typeof charCode, charCode)
}
}
const stderr = (charCode) => {
if (charCode) {
postMessage({
type: 'stderr',
stderr: charCode,
})
} else {
console.log(typeof charCode, charCode)
}
}
const stdinBuffer = new StdinBuffer()
var Module = {
noInitialRun: true,
stdin: stdinBuffer.stdin,
stdout: stdout,
stderr: stderr,
onRuntimeInitialized: () => {
postMessage({type: 'ready', stdinBuffer: stdinBuffer.sab})
}
}
onmessage = (event) => {
if (event.data.type === 'run') {
// TODO: Set up files from event.data.files
const ret = callMain(event.data.args)
postMessage({
type: 'finished',
returnCode: ret
})
}
}
importScripts('python.js')
|