summaryrefslogtreecommitdiff
path: root/js-runtime/reflect.js
diff options
context:
space:
mode:
Diffstat (limited to 'js-runtime/reflect.js')
-rw-r--r--js-runtime/reflect.js48
1 files changed, 32 insertions, 16 deletions
diff --git a/js-runtime/reflect.js b/js-runtime/reflect.js
index 7ba19b7..a930547 100644
--- a/js-runtime/reflect.js
+++ b/js-runtime/reflect.js
@@ -1,3 +1,4 @@
+// -*- js2-basic-offset: 4 -*-
class Char {
constructor(codepoint) {
this.codepoint = codepoint;
@@ -170,25 +171,33 @@ class Scheme {
return new Scheme(instance, abi);
}
- init_module(mod) {
+ #init_module(mod) {
mod.set_debug_handler({
debug_str(x) { console.log(`debug: ${x}`); },
debug_str_i32(x, y) { console.log(`debug: ${x}: ${y}`); },
debug_str_scm: (x, y) => {
- console.log(`debug: ${x}: ${repr(this.to_js(y))}`);
+ console.log(`debug: ${x}: ${repr(this.#to_js(y))}`);
},
});
- let proc = new Procedure(this, mod.get_export('$load').value)
+ mod.set_ffi_handler({
+ procedure_to_extern: (obj) => {
+ const proc = this.#to_js(obj);
+ return (...args) => {
+ return proc.call(...args);
+ };
+ }
+ });
+ 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();
- return reflect.init_module(mod);
+ return reflect.#init_module(mod);
}
- async load_extension(path) {
- let mod = await SchemeModule.fetch_and_instantiate(path, this.#abi);
- return this.init_module(mod);
+ async load_extension(path, user_imports = {}) {
+ let mod = await SchemeModule.fetch_and_instantiate(path, this.#abi, user_imports);
+ return this.#init_module(mod);
}
#to_scm(js) {
@@ -222,7 +231,7 @@ class Scheme {
}
}
- to_js(scm) {
+ #to_js(scm) {
let api = this.#instance.exports;
let descr = api.describe(scm);
let handlers = {
@@ -238,8 +247,8 @@ class Scheme {
bignum: () => api.bignum_value(scm),
complex: () => new Complex(api.complex_real(scm),
api.complex_imag(scm)),
- fraction: () => new Fraction(this.to_js(api.fraction_num(scm)),
- this.to_js(api.fraction_denom(scm))),
+ fraction: () => new Fraction(this.#to_js(api.fraction_num(scm)),
+ this.#to_js(api.fraction_denom(scm))),
pair: () => new Pair(this, scm),
'mutable-pair': () => new MutablePair(this, scm),
vector: () => new Vector(this, scm),
@@ -278,16 +287,16 @@ class Scheme {
argv = api.call(func, argv);
let results = [];
for (let idx = 0; idx < api.vector_length(argv); idx++)
- results.push(this.to_js(api.vector_ref(argv, idx)))
+ results.push(this.#to_js(api.vector_ref(argv, idx)))
return results;
}
- car(x) { return this.to_js(this.#instance.exports.car(x.obj)); }
- cdr(x) { return this.to_js(this.#instance.exports.cdr(x.obj)); }
+ car(x) { return this.#to_js(this.#instance.exports.car(x.obj)); }
+ cdr(x) { return this.#to_js(this.#instance.exports.cdr(x.obj)); }
vector_length(x) { return this.#instance.exports.vector_length(x.obj); }
vector_ref(x, i) {
- return this.to_js(this.#instance.exports.vector_ref(x.obj, i));
+ return this.#to_js(this.#instance.exports.vector_ref(x.obj, i));
}
bytevector_length(x) {
@@ -359,6 +368,7 @@ class SchemeModule {
#instance;
#io_handler;
#debug_handler;
+ #ffi_handler;
static #rt = {
bignum_from_string(str) { return BigInt(str); },
bignum_from_i32(n) { return BigInt(n); },
@@ -492,10 +502,15 @@ class SchemeModule {
debug_str_i32(x, y) { mod.#debug_handler.debug_str_i32(x, y); },
debug_str_scm(x, y) { mod.#debug_handler.debug_str_scm(x, y); },
}
+ let ffi = {
+ procedure_to_extern(proc) {
+ return mod.#ffi_handler.procedure_to_extern(proc);
+ }
+ };
let imports = {
rt: SchemeModule.#rt,
abi: imported_abi,
- debug, io, ...user_imports
+ debug, io, ffi, ...user_imports
};
let { module, instance } = await instantiate_streaming(path, imports);
let mod = new SchemeModule(instance);
@@ -503,6 +518,7 @@ class SchemeModule {
}
set_io_handler(h) { this.#io_handler = h; }
set_debug_handler(h) { this.#debug_handler = h; }
+ set_ffi_handler(h) { this.#ffi_handler = h; }
all_exports() { return this.#instance.exports; }
exported_abi() {
let abi = {}
@@ -539,6 +555,6 @@ function repr(obj) {
return flonum_to_string(obj);
if (typeof obj === 'string')
// FIXME: Improve to match Scheme.
- return '"' + obj.replace(/(["\\])/g, '\\$1') + '"';
+ return '"' + obj.replace(/(["\\])/g, '\\$1').replace(/\n/g, '\\n') + '"';
return obj + '';
}