as-bind
as-bind copied to clipboard
as-bind seems to not be able to handle proxies?
Iβm not 100% sure I dug out the very core issue here, but I put a sufficiently minimal repro in a gist, which will hopefully help analyze the bug.
I import a function which takes a string
as a parameter, which is working fine with as-bind
. However, some of my functions rely on this
being the object the imported function is defined on. So I thought Iβd bind()
all functions before importing. as-bind
handles that, too. Then I thought I should do the binding lazily, so I added a Proxy
that does the binding on GET
and caches it in a Map
. Now, as-bind
is failing to do its job and I just get a pointer.
import { AsBind } from "as-bind";
// Bundler magic compiles my ASC for me
import wasmUrl from "asc:./main.ts";
// Manually binds all methods found on `obj` to `obj.
function manualbind(obj) {
const returnobj = {};
for (const key of Object.keys(obj)) {
if (typeof obj[key] === "function") {
returnobj[key] = obj[key].bind(obj);
}
returnobj[key] = obj[key];
}
return returnobj;
}
// *Lazily* binds all methods found on `obj` to `obj.
function proxybind(obj) {
const bindCache = new Map();
return new Proxy(obj, {
get(target, p) {
if (bindCache.has(p)) {
return bindCache.get(p);
}
if (typeof target?.[p] === "function") {
const bound = target[p].bind(target);
bindCache.set(p, bound);
return bound;
}
return target[p];
},
});
}
function myalert(s) {
alert(`message: ${JSON.stringify(s)}, has a this: ${this !== null}`);
}
async function main() {
// Works fine!
const instance = await AsBind.instantiate(fetch(wasmUrl), {
main: { myalert },
});
instance.exports.run("vanilla");
// Works fine!
const instance2 = await AsBind.instantiate(fetch(wasmUrl), {
main: manualbind({ myalert }),
});
instance2.exports.run("manualbind");
// Breaks. I only get a pointer value and not the string.
const instance3 = await AsBind.instantiate(fetch(wasmUrl), {
main: proxybind({ myalert }),
});
instance3.exports.run("proxybind");
}
main();
Can you take a look and let me know if itβs something that I am doing wrong or something we can fix in as-bind
?
@surma Thank you for the issue! So I took a look at this by:
- Downloading your source
- Importing as-bind from
lib/lib.js
directly - Added some logging in as-bind
And I was able to figure out, it seems like the proxy skips or overrides the bindImportFunction
that AsBind does (I know this since the "functionThis" logs I added are never called): https://github.com/torch2424/as-bind/blob/master/lib/asbind-instance/bind-function.js#L7
So, I'll be honest, I'm not super strong at using Proxies. So I'm not quite sure where to start fixing this :hushed: But! Perhaps it's because we aren't using arrow functions to bind our stuff? But, we need that so we can set function properties :thinking:
Let me know if this helps, or if you need me to poke around a bit more :hushed: I can buckle down and try to figure out how Proxies work haha! :joy: