1class StdinBuffer {
2    constructor() {
3        this.sab = new SharedArrayBuffer(128 * Int32Array.BYTES_PER_ELEMENT)
4        this.buffer = new Int32Array(this.sab)
5        this.readIndex = 1;
6        this.numberOfCharacters = 0;
7        this.sentNull = true
8    }
9
10    prompt() {
11        this.readIndex = 1
12        Atomics.store(this.buffer, 0, -1)
13        postMessage({
14            type: 'stdin',
15            buffer: this.sab
16        })
17        Atomics.wait(this.buffer, 0, -1)
18        this.numberOfCharacters = this.buffer[0]
19    }
20
21    stdin = () => {
22        if (this.numberOfCharacters + 1 === this.readIndex) {
23            if (!this.sentNull) {
24                // Must return null once to indicate we're done for now.
25                this.sentNull = true
26                return null
27            }
28            this.sentNull = false
29            this.prompt()
30        }
31        const char = this.buffer[this.readIndex]
32        this.readIndex += 1
33        // How do I send an EOF??
34        return char
35    }
36}
37
38const stdout = (charCode) => {
39    if (charCode) {
40        postMessage({
41            type: 'stdout',
42            stdout: charCode,
43        })
44    } else {
45        console.log(typeof charCode, charCode)
46    }
47}
48
49const stderr = (charCode) => {
50    if (charCode) {
51        postMessage({
52            type: 'stderr',
53            stderr: charCode,
54        })
55    } else {
56        console.log(typeof charCode, charCode)
57    }
58}
59
60const stdinBuffer = new StdinBuffer()
61
62var Module = {
63    noInitialRun: true,
64    stdin: stdinBuffer.stdin,
65    stdout: stdout,
66    stderr: stderr,
67    onRuntimeInitialized: () => {
68        postMessage({type: 'ready', stdinBuffer: stdinBuffer.sab})
69    }
70}
71
72onmessage = (event) => {
73    if (event.data.type === 'run') {
74        // TODO: Set up files from event.data.files
75        const ret = callMain(event.data.args)
76        postMessage({
77            type: 'finished',
78            returnCode: ret
79        })
80    }
81}
82
83importScripts('python.js')
84