kopia lustrzana https://github.com/micropython/micropython
147 wiersze
5.1 KiB
JavaScript
147 wiersze
5.1 KiB
JavaScript
/*
|
|
* This file is part of the MicroPython project, http://micropython.org/
|
|
*
|
|
* The MIT License (MIT)
|
|
*
|
|
* Copyright (c) 2023-2024 Damien P. George
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
*/
|
|
|
|
// Options:
|
|
// - heapsize: size in bytes of the MicroPython GC heap.
|
|
// - url: location to load `micropython.mjs`.
|
|
// - stdin: function to return input characters.
|
|
// - stdout: function that takes one argument, and is passed lines of stdout
|
|
// output as they are produced. By default this is handled by Emscripten
|
|
// and in a browser goes to console, in node goes to process.stdout.write.
|
|
// - stderr: same behaviour as stdout but for error output.
|
|
// - linebuffer: whether to buffer line-by-line to stdout/stderr.
|
|
export async function loadMicroPython(options) {
|
|
const { heapsize, url, stdin, stdout, stderr, linebuffer } = Object.assign(
|
|
{ heapsize: 1024 * 1024, linebuffer: true },
|
|
options,
|
|
);
|
|
const Module = {};
|
|
Module.locateFile = (path, scriptDirectory) =>
|
|
url || scriptDirectory + path;
|
|
Module._textDecoder = new TextDecoder();
|
|
if (stdin !== undefined) {
|
|
Module.stdin = stdin;
|
|
}
|
|
if (stdout !== undefined) {
|
|
if (linebuffer) {
|
|
Module._stdoutBuffer = [];
|
|
Module.stdout = (c) => {
|
|
if (c === 10) {
|
|
stdout(
|
|
Module._textDecoder.decode(
|
|
new Uint8Array(Module._stdoutBuffer),
|
|
),
|
|
);
|
|
Module._stdoutBuffer = [];
|
|
} else {
|
|
Module._stdoutBuffer.push(c);
|
|
}
|
|
};
|
|
} else {
|
|
Module.stdout = (c) => stdout(new Uint8Array([c]));
|
|
}
|
|
}
|
|
if (stderr !== undefined) {
|
|
if (linebuffer) {
|
|
Module._stderrBuffer = [];
|
|
Module.stderr = (c) => {
|
|
if (c === 10) {
|
|
stderr(
|
|
Module._textDecoder.decode(
|
|
new Uint8Array(Module._stderrBuffer),
|
|
),
|
|
);
|
|
Module._stderrBuffer = [];
|
|
} else {
|
|
Module._stderrBuffer.push(c);
|
|
}
|
|
};
|
|
} else {
|
|
Module.stderr = (c) => stderr(new Uint8Array([c]));
|
|
}
|
|
}
|
|
const moduleLoaded = new Promise((r) => {
|
|
Module.postRun = r;
|
|
});
|
|
_createMicroPythonModule(Module);
|
|
await moduleLoaded;
|
|
globalThis.Module = Module;
|
|
proxy_js_init();
|
|
const pyimport = (name) => {
|
|
const value = Module._malloc(3 * 4);
|
|
Module.ccall(
|
|
"mp_js_do_import",
|
|
"null",
|
|
["string", "pointer"],
|
|
[name, value],
|
|
);
|
|
return proxy_convert_mp_to_js_obj_jsside_with_free(value);
|
|
};
|
|
Module.ccall("mp_js_init", "null", ["number"], [heapsize]);
|
|
Module.ccall("proxy_c_init", "null", [], []);
|
|
return {
|
|
_module: Module,
|
|
PyProxy: PyProxy,
|
|
FS: Module.FS,
|
|
globals: {
|
|
__dict__: pyimport("__main__").__dict__,
|
|
get(key) {
|
|
return this.__dict__[key];
|
|
},
|
|
set(key, value) {
|
|
this.__dict__[key] = value;
|
|
},
|
|
delete(key) {
|
|
delete this.__dict__[key];
|
|
},
|
|
},
|
|
registerJsModule(name, module) {
|
|
const value = Module._malloc(3 * 4);
|
|
proxy_convert_js_to_mp_obj_jsside(module, value);
|
|
Module.ccall(
|
|
"mp_js_register_js_module",
|
|
"null",
|
|
["string", "pointer"],
|
|
[name, value],
|
|
);
|
|
Module._free(value);
|
|
},
|
|
pyimport: pyimport,
|
|
runPython(code) {
|
|
const value = Module._malloc(3 * 4);
|
|
Module.ccall(
|
|
"mp_js_do_exec",
|
|
"number",
|
|
["string", "pointer"],
|
|
[code, value],
|
|
);
|
|
return proxy_convert_mp_to_js_obj_jsside_with_free(value);
|
|
},
|
|
};
|
|
}
|
|
|
|
globalThis.loadMicroPython = loadMicroPython;
|