Update to bleeding edge Hoot.

This commit is contained in:
David Thompson 2024-12-19 13:09:47 -05:00
parent 5e4d6cce1c
commit bd5036a160
3 changed files with 55 additions and 127 deletions

View file

@ -5,4 +5,21 @@
(gnu packages guile)
(gnu packages guile-xyz))
(packages->manifest (list guile-next guile-hoot gnu-make zip))
(define guile-hoot*
(let ((commit "61c072433020d7669c7edaf18803d790bf984a03"))
(package
(inherit guile-hoot)
(version (string-append (package-version guile-hoot)
"-1." (string-take commit 7)))
(source (origin
(method git-fetch)
(uri (git-reference
(url "https://gitlab.com/spritely/guile-hoot.git")
(commit commit)))
(sha256
(base32
"0isx20rk92xlhcc5spbbxzs2dgmqcsjzsm82iri195894ir59f4f"))))
(arguments
'(#:tests? #f)))))
(packages->manifest (list guile-next guile-hoot* gnu-make zip))

View file

@ -5,6 +5,8 @@ class Char {
}
toString() {
let ch = String.fromCodePoint(this.codepoint);
if (ch == '\n') return '#\\newline';
if (ch == '\r') return '#\\return';
if (ch.match(/[a-zA-Z0-9$[\]().]/)) return `#\\${ch}`;
return `#\\x${this.codepoint.toString(16)}`;
}
@ -137,6 +139,7 @@ class WeakTable extends HeapObject { toString() { return "#<weak-table>"; } }
class Fluid extends HeapObject { toString() { return "#<fluid>"; } }
class DynamicState extends HeapObject { toString() { return "#<dynamic-state>"; } }
class Syntax extends HeapObject { toString() { return "#<syntax>"; } }
class SyntaxTransformer extends HeapObject { toString() { return "#<syntax-transformer>"; } }
class Port extends HeapObject { toString() { return "#<port>"; } }
class Struct extends HeapObject { toString() { return "#<struct>"; } }
@ -200,123 +203,6 @@ class IterableWeakSet {
}
}
// See:
// https://github.com/tc39/proposal-weakrefs?tab=readme-ov-file#iterable-weakmaps
class IterableWeakMap {
#weakMap = new WeakMap();
#refSet = new Set();
#finalizationGroup = new FinalizationRegistry(IterableWeakMap.#cleanup);
static #cleanup({ set, ref }) {
set.delete(ref);
}
constructor(iterable) {
for (const [key, value] of iterable) {
this.set(key, value);
}
}
set(key, value) {
const ref = new WeakRef(key);
this.#weakMap.set(key, { value, ref });
this.#refSet.add(ref);
this.#finalizationGroup.register(key, {
set: this.#refSet,
ref
}, ref);
}
get(key) {
const entry = this.#weakMap.get(key);
return entry && entry.value;
}
delete(key) {
const entry = this.#weakMap.get(key);
if (!entry) {
return false;
}
this.#weakMap.delete(key);
this.#refSet.delete(entry.ref);
this.#finalizationGroup.unregister(entry.ref);
return true;
}
*[Symbol.iterator]() {
for (const ref of this.#refSet) {
const key = ref.deref();
if (!key) continue;
const { value } = this.#weakMap.get(key);
yield [key, value];
}
}
entries() {
return this[Symbol.iterator]();
}
*keys() {
for (const [key, value] of this) {
yield key;
}
}
*values() {
for (const [key, value] of this) {
yield value;
}
}
}
// class IterableWeakMap {
// #array;
// #map;
// constructor() { this.#array = []; this.#map = new WeakMap; }
// #kill(i) {
// let tail = this.#array.pop();
// if (i < this.#array.length)
// this.#array[i] = tail;
// }
// #geti(i) {
// // If a dead weak ref is at i then kill it and try again with
// // the next weak ref.
// while (true) {
// if (i >= this.#array.length)
// return null;
// let obj = this.#array[i].deref();
// if (obj)
// return obj;
// this.#kill(i);
// }
// }
// #cleanup() {
// let i = 0;
// while (this.#get(i)) i++;
// }
// has(k) { return this.#map.has(k); }
// get(k) { return this.#map.get(k); }
// set(k, v) {
// if (this.#array.length % 32 == 0)
// this.#cleanup();
// this.#map.set(k, v);
// this.#array.push(new WeakRef(k));
// }
// delete(k) {
// if (!this.has(k))
// return;
// this.#map.delete(k);
// let i = 0;
// while (this.#geti(i) != k) i++;
// this.#kill(i);
// }
// *[Symbol.iterator]() {
// for (let i = 0, k; k = this.#geti(i); i++)
// yield [k, this.get(k)];
// }
// }
class Scheme {
#instance;
#abi;
@ -362,6 +248,22 @@ class Scheme {
};
}
});
mod.set_finalization_handler({
make_finalization_registry: (f) => new FinalizationRegistry(f),
finalization_registry_register: (registry, target, heldValue) => {
// heldValue is a Wasm struct and needs to be wrapped
// so that when it goes back to Scheme via the
// finalizer callback it is seen as a Scheme value and
// not an external one.
registry.register(target, this.#to_js(heldValue));
},
finalization_registry_register_with_token: (registry, target, heldValue, unregisterToken) => {
registry.register(target, this.#to_js(heldValue), unregisterToken);
},
finalization_registry_unregister: (registry, unregisterToken) => {
return registry.unregister(unregisterToken);
}
});
let proc = new Procedure(this, mod.get_export('$load').value);
return proc.call();
}
@ -447,6 +349,7 @@ class Scheme {
fluid: () => new Fluid(this, scm),
'dynamic-state': () => new DynamicState(this, scm),
syntax: () => new Syntax(this, scm),
'syntax-transformer': () => new SyntaxTransformer(this, scm),
port: () => new Port(this, scm),
struct: () => new Struct(this, scm),
'extern-ref': () => api.extern_value(scm)
@ -601,6 +504,7 @@ class SchemeModule {
#io_handler;
#debug_handler;
#ffi_handler;
#finalization_handler;
static #rt = {
bignum_from_string(str) { return BigInt(str); },
bignum_from_i32(n) { return BigInt(n); },
@ -676,14 +580,6 @@ class SchemeModule {
weak_map_set(map, k, v) { return map.set(k, v); },
weak_map_delete(map, k) { return map.delete(k); },
make_finalization_registry(f) { return new FinalizationRegistry(f); },
finalization_registry_register(registry, target, heldValue, unregisterToken) {
registry.register(target, heldValue, unregisterToken);
},
finalization_registry_unregister(registry, unregisterToken) {
registry.unregister(unregisterToken);
},
fsqrt: Math.sqrt,
fsin: Math.sin,
fcos: Math.cos,
@ -979,9 +875,23 @@ class SchemeModule {
return mod.#ffi_handler.procedure_to_extern(proc);
}
};
let finalization = {
make_finalization_registry(f) {
return mod.#finalization_handler.make_finalization_registry(f);
},
finalization_registry_register(registry, target, heldValue) {
mod.#finalization_handler.finalization_registry_register(registry, target, heldValue);
},
finalization_registry_register_with_token(registry, target, heldValue, unregisterToken) {
mod.#finalization_handler.finalization_registry_register_with_token(registry, target, heldValue, unregisterToken);
},
finalization_registry_unregister(registry, unregisterToken) {
return mod.#finalization_handler.finalization_registry_unregister(registry, unregisterToken);
}
};
let imports = {
rt: SchemeModule.#rt,
abi, debug, io, ffi, ...user_imports
abi, debug, io, ffi, finalization, ...user_imports
};
let { module, instance } = await instantiate_streaming(path, imports);
let mod = new SchemeModule(instance);
@ -990,6 +900,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; }
set_finalization_handler(h) { this.#finalization_handler = h; }
all_exports() { return this.#instance.exports; }
exported_abi() {
let abi = {}

Binary file not shown.