| 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') |