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