-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add support for exported classes #102
Labels
enhancement
New feature or request
Comments
Or instead of wrapping useing a proxy. |
Got a small working prototype (all manual but can be automated): Assemblyscript export class Foo {
constructor(public str: string) {}
getString(): string {
return this.str
}
} Host: import * as AsBind from "/node_modules/as-bind/dist/as-bind.esm.js";
const asyncTask = async () => {
const wasm = await fetch("/build/optimized.wasm").then(v => v.arrayBuffer());
const asBindInstance = await AsBind.instantiate(wasm);
let e = asBindInstance.exports
// When not supported noop
const pointerRegistry = FinalizationRegistry ? new FinalizationRegistry(ptr => {
e.__unpin(ptr)
}) : {register(){}};
function createProxyClass(klass, definition) {
const newConstructor = new Proxy(klass, {
construct(target, args) {
// TODO: wrap args - get from definition
const ptr = new target(...args)
return newConstructor.wrap(ptr)
},
get(_, prop) {
if (prop === 'wrap') {
return (ptr) => {
e.__pin(ptr)
const instance = klass.wrap(ptr)
const a = new Proxy({}, {
ownKeys() {
return Reflect.ownKeys(instance);
},
defineProperty() {
throw new Error("Not allowed!")
},
deleteProperty() {
throw new Error("Not allowed!")
},
get(_, ...args) {
if (prop === '__collect') {
return () => e.__unpin(ptr)
}
const value = Reflect.get(instance, ...args)
// TODO: wrap function - or wrap value
return value
},
set(_, ...args) {
// TODO: check if is settable; wrap value if needed
return Reflect.set(instance, ...args)
},
setPrototypeOf() {
throw new Error("Not allowed!")
},
preventExtensions() {
throw new Error("Not allowed!")
},
isExtensible() {
return false;
},
has(_, p) {
return Reflect.has(instance, p)
},
getPrototypeOf() {
throw new Error("Not allowed!")
}
})
// handle GC
pointerRegistry.register(a, ptr)
return a
}
}
return undefined
},
set() {
throw new Error("Not allowed!")
}
})
return newConstructor
}
window.e = e
window.Foo = createProxyClass(e.Foo, {
constructor: {
memberType: "constructor",
parameterTypes: ["~lib/string/String"],
returnType: null
},
str: {
memberType: "field",
set: true,
get: true,
type: "~lib/string/String"
},
getString: {
memberType: "function",
parameterTypes: [],
returnType: "~lib/string/String"
}
})
// example usage
const sptr = e.__newString("test")
const f = new Foo(sptr)
console.log(e.__getString(f.getString())) // "test"
const sptr2 = e.__newString("test 42")
f.str = sptr2
console.log(e.__getString(f.getString())) // "test 42"
};
asyncTask(); |
@torch2424 If this looks good to you I will integrate it. :D |
@mathe42 Thank you very much for drafting up this implementation! 😄 Yeah! I like this approach and it makes sense to me, so let's go for it! 😄 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I currently look at how we can support classes.
Example:
Assemblyscript
In JS:
This in combination with #64 would allow some cool things!
To do that I would wrap the full class in a JS-Class that calls the correspondig function by runtime and loader.
FinalizationRegistry
I want to do the following to get full garbage collection (in a wrapper function for the classes):
This would allow full GarbageCollection for Browsers that support
FinalizationRegistry
(see https://caniuse.com/mdn-javascript_builtins_finalizationregistry). WithoutFinalizationRegistry
I see no way to add this wrapping without memory leaks (any ideas?).But in that case the developer can allways call
__unpin
so I think there is nothing to worry about.The text was updated successfully, but these errors were encountered: