From 7d728559d070f63baacbd1975057eea5883c0cb8 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Fri, 17 May 2024 15:39:29 -0400 Subject: [PATCH] Use latest hoot. --- index.html | 2 +- manifest.scm | 27 ++++++++- js-runtime/reflect.js => reflect.js | 72 ++++++++++++++++-------- js-runtime/reflect.wasm => reflect.wasm | Bin js-runtime/wtf8.wasm => wtf8.wasm | Bin 5 files changed, 74 insertions(+), 27 deletions(-) rename js-runtime/reflect.js => reflect.js (92%) rename js-runtime/reflect.wasm => reflect.wasm (100%) rename js-runtime/wtf8.wasm => wtf8.wasm (100%) diff --git a/index.html b/index.html index 1c4ea28..e9166d0 100644 --- a/index.html +++ b/index.html @@ -1,7 +1,7 @@ - + diff --git a/manifest.scm b/manifest.scm index 198ee07..fdb6a52 100644 --- a/manifest.scm +++ b/manifest.scm @@ -1,7 +1,28 @@ -(use-modules (guix packages) +(use-modules (guix git-download) + (guix packages) + (gnu packages autotools) (gnu packages base) (gnu packages compression) (gnu packages guile) - (gnu packages guile-xyz)) + (gnu packages guile-xyz) + (gnu packages pkg-config) + (gnu packages texinfo)) -(packages->manifest (list guile-next guile-hoot gnu-make zip)) +(define guile-hoot-next + (let ((commit "bdc355d97a88b1337c14d3155ce83fe699b405ac") + (revision "1")) + (package + (inherit guile-hoot) + (version (git-version "0.4.1" revision commit)) + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://gitlab.com/spritely/guile-hoot.git") + (commit commit))) + (file-name (git-file-name "guile-hoot" version)) + (sha256 + (base32 "0p18zy505flacvqi4r2xp42gljnpq86fydvw2k154aw89chhkc32")))) + (native-inputs + (list autoconf automake pkg-config texinfo))))) + +(packages->manifest (list guile-next guile-hoot-next gnu-make zip)) diff --git a/js-runtime/reflect.js b/reflect.js similarity index 92% rename from js-runtime/reflect.js rename to reflect.js index 1e66c50..b38867f 100644 --- a/js-runtime/reflect.js +++ b/reflect.js @@ -115,6 +115,9 @@ class Procedure extends HeapObject { call(...arg) { return this.reflector.call(this, ...arg); } + async call_async(...arg) { + return await this.reflector.call_async(this, ...arg); + } } class Sym extends HeapObject { @@ -160,7 +163,7 @@ class Scheme { this.#abi = abi; } - static async reflect(abi) { + static async reflect(abi, {reflect_wasm_dir = '.'}) { let debug = { debug_str(x) { console.log(`reflect debug: ${x}`); }, debug_str_i32(x, y) { console.log(`reflect debug: ${x}: ${y}`); }, @@ -168,16 +171,14 @@ class Scheme { console.log(`reflect debug: ${x}: #`); }, }; + let reflect_wasm = reflect_wasm_dir + '/reflect.wasm'; + let rt = { + die(tag, data) { throw new SchemeTrapError(tag, data); }, + wtf8_to_string(wtf8) { return wtf8_to_string(wtf8); }, + string_to_wtf8(str) { return string_to_wtf8(str); }, + }; let { module, instance } = - await instantiate_streaming('js-runtime/reflect.wasm', { - abi, - debug, - rt: { - die(tag, data) { throw new SchemeTrapError(tag, data); }, - wtf8_to_string(wtf8) { return wtf8_to_string(wtf8); }, - string_to_wtf8(str) { return string_to_wtf8(str); }, - } - }); + await instantiate_streaming(reflect_wasm, { abi, debug, rt }); return new Scheme(instance, abi); } @@ -200,13 +201,14 @@ class Scheme { let proc = new Procedure(this, mod.get_export('$load').value); return proc.call(); } - static async load_main(path, abi, user_imports = {}) { - let mod = await SchemeModule.fetch_and_instantiate(path, abi, user_imports); - let reflect = await mod.reflect(); + static async load_main(path, opts = {}) { + let mod = await SchemeModule.fetch_and_instantiate(path, opts); + let reflect = await mod.reflect(opts); return reflect.#init_module(mod); } - async load_extension(path, user_imports = {}) { - let mod = await SchemeModule.fetch_and_instantiate(path, this.#abi, user_imports); + async load_extension(path, opts = {}) { + opts = Object.assign({ abi: this.#abi }, opts); + let mod = await SchemeModule.fetch_and_instantiate(path, opts); return this.#init_module(mod); } @@ -236,6 +238,8 @@ class Scheme { if (js instanceof Complex) return api.scm_from_complex(js.real, js.imag); return api.scm_from_extern(js); + } else if (typeof(js) == 'function') { + return api.scm_from_extern(js); } else { throw new Error(`unexpected; ${typeof(js)}`); } @@ -301,6 +305,15 @@ class Scheme { return results; } + call_async(func, ...args) { + return new Promise((resolve, reject) => { + this.call(func, + val => resolve(this.#to_js(val)), + err => reject(this.#to_js(err)), + ...args); + }) + } + car(x) { return this.#to_js(this.#instance.exports.car(x.obj)); } cdr(x) { return this.#to_js(this.#instance.exports.cdr(x.obj)); } @@ -353,6 +366,13 @@ function flonum_to_string(f64) { } } +let async_invoke = typeof queueMicrotask !== 'undefined' + ? queueMicrotask + : thunk => setTimeout(thunk, 0); +function async_invoke_later(thunk, jiffies) { + setTimeout(thunk, jiffies / 1000); +} + let wtf8_helper; function wtf8_to_string(wtf8) { @@ -388,9 +408,10 @@ function string_to_wtf8(str) { return finish_builder(builder); } -async function load_wtf8_helper_module() { +async function load_wtf8_helper_module(reflect_wasm_dir = '') { if (wtf8_helper) return; - let { module, instance } = await instantiate_streaming("js-runtime/wtf8.wasm"); + let wtf8_wasm = reflect_wasm_dir + "/wtf8.wasm"; + let { module, instance } = await instantiate_streaming(wtf8_wasm); wtf8_helper = instance; } @@ -487,6 +508,11 @@ class SchemeModule { current_jiffy() { return performance.now() * 1000; }, current_second() { return Date.now() / 1000; }, + async_invoke, + async_invoke_later, + promise_on_completed(p, kt, kf) { p.then(kt, kf); }, + promise_complete(callback, val) { callback(val); }, + // Wrap in functions to allow for lazy loading of the wtf8 // module. wtf8_to_string(wtf8) { return wtf8_to_string(wtf8); }, @@ -629,8 +655,9 @@ class SchemeModule { debug_str_scm(x, y) { console.log(`debug: ${x}: #`); }, }; } - static async fetch_and_instantiate(path, imported_abi, user_imports = {}) { - await load_wtf8_helper_module(); + static async fetch_and_instantiate(path, { abi, reflect_wasm_dir = '.', + user_imports = {} }) { + await load_wtf8_helper_module(reflect_wasm_dir); let io = { write_stdout(str) { mod.#io_handler.write_stdout(str); }, write_stderr(str) { mod.#io_handler.write_stderr(str); }, @@ -660,8 +687,7 @@ class SchemeModule { }; let imports = { rt: SchemeModule.#rt, - abi: imported_abi, - debug, io, ffi, ...user_imports + abi, debug, io, ffi, ...user_imports }; let { module, instance } = await instantiate_streaming(path, imports); let mod = new SchemeModule(instance); @@ -692,8 +718,8 @@ class SchemeModule { return this.all_exports()[name]; throw new Error(`unknown export: ${name}`) } - async reflect() { - return await Scheme.reflect(this.exported_abi()); + async reflect(opts = {}) { + return await Scheme.reflect(this.exported_abi(), opts); } } diff --git a/js-runtime/reflect.wasm b/reflect.wasm similarity index 100% rename from js-runtime/reflect.wasm rename to reflect.wasm diff --git a/js-runtime/wtf8.wasm b/wtf8.wasm similarity index 100% rename from js-runtime/wtf8.wasm rename to wtf8.wasm