cpython/Tools/wasm/python.worker.js
Trey Hunner a8e333d79a
gh-84461: Improve WebAssembly in-browser demo (#91879)
* Buffer standard input line-by-line

* Add non-root .editorconfig for JS & HTML indent

* Add support for clearing REPL with CTRL+L

* Support unicode in stdout and stderr

* Remove \r\n normalization

* Note that local .editorconfig file extends root

* Only normalize lone \r characters (convert to \n)

* Skip non-printable characters in buffered input

* Fix Safari bug (regex lookbehind not supported)

Co-authored-by: Christian Heimes <christian@python.org>
2022-07-01 11:52:58 +02:00

84 lines
1.9 KiB
JavaScript

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