assemblyscript
assemblyscript copied to clipboard
[FR] Passing any JavaScript object/class to AssemblyScript
It would be nice if AssemblyScript adds support for passing any JavaScript object/class to WASM using variants. This is similar to how node-addon-api supports passing any JavaScript object as Napi::Object. The calls to the methods and getter/setters will happen on the JS side.
The goal is to make it easier to pass random objects to AssemblyScript without the need for writing the types for it (the efficiency is not a priority).
The proposed syntax
function asFunc(obj: JS.Object) {
// getting values
const x = obj.get(1) as string
// setting values
obj.set(2, 1)
}
As a bonus, optional typing might be provided for a subset of the object that is needed:
// a subset of the object which is typed
interface MyObject {
desiredMethod(a: i32): i32
}
function asFunc(obj: JS.Object) {
const x = obj as MyObject
x.desiredMethod()
}
This is different from the reference-type proposal, which is not supported in many environments, and waiting for it may take a long time. The same syntax might be used later with a more efficient backend implementation using reference types.
The possible implementation will look like this: https://github.com/nearprotocol/assemblyscript-json/blob/master/assembly/JSON.ts#L103 https://github.com/nearprotocol/assemblyscript-json/blob/master/assembly/JSON.ts#L202
P.S: I already discussed this with @MaxGraey in the discord chat.
How would the object be referenced from within Wasm, if not with a reference type? And how would the compiler determine the intention of the programmer, to generate the necessary typed imports to interface with the object, if there are no types?
Emscripten already does it: https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#using-val-to-transliterate-javascript-to-c
I already suggested this in Discord and duplicating here. With reference types it will be much more powerful and simpler. Something like:
@external("webapi", "DOMNode")
interface DOMNodeExternal {
replaceChild(oldNode: DOMNodeExternal, newNode: DOMNodeExternal): DOMNodeExternal;
...
}
type DOMNode = Externref<DOMNodeExternal>
export function replaceChild(old: DOMNode, new_: DOMNode): DOMNode {
return old.replaceChild(old, new_);
}
And you don't need expensive Variant accessor. But reftypes (externref) still very experimental and required more adoption from compiler for that. Externref<T> here is builtin proxy object which support and handled by compiler which automatically wrap every field with some Reflect's method.
But reftypes (externref) still very experimental and required more adoption from compiler for that
Can we have something less efficient for now, so we can start thinking about using WASM? Without this, it is impossible for me to port some of my apps to WASM.
If we choose a good syntax, the same thing can be used for reference types which makes the later transition to actual reference types as easy as upgrading the AssemblyScript.
Can we have something less efficient for now, so we can start thinking about using WASM?
Of course it's possible, but someone has to spend time on it. That's the main problem. But I agree, it would provide a way to start writing code now that would get a performance boost from reference types later, without existing user code changing much (if at all).
Can it be done as a library for AS (not in core)?
Whatever the solution will be, I hope we can keep it valid TypeScript syntax. In the previous example,
@external("webapi", "DOMNode")
interface DOMNodeExternal {
replaceChild(oldNode: DOMNodeExternal, newNode: DOMNodeExternal): DOMNodeExternal;
...
}
decorators are not allowed there in TypeScript.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in one week if no further activity occurs. Thank you for your contributions!
Unstale
I have a related requirement; https://stackoverflow.com/questions/74554478/passing-javascript-references-to-assemblyscript