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 while (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 // Prompt will reset this.readIndex to 1 30 this.prompt() 31 } 32 const char = this.buffer[this.readIndex] 33 this.readIndex += 1 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 if (event.data.files) { 75 for (const [filename, contents] of Object.entries(event.data.files)) { 76 Module.FS.writeFile(filename, contents) 77 } 78 } 79 const ret = callMain(event.data.args) 80 postMessage({ 81 type: 'finished', 82 returnCode: ret 83 }) 84 } 85} 86 87importScripts('python.js') 88