Trying to do reflection in Wasm/JS via JS - i.e., ...
# webassembly
l
Trying to do reflection in Wasm/JS via JS - i.e., given a function's name and signature, return a lambda of that same signature. When creating a Kotlin function that calls JS code, i.e.:
Copy code
fun foo() = js("console.log('foo')")
Kotlin generates:
Copy code
(func $js_code.foo (;3873;) (import "js_code" "foo"))
And (in an object containing all functions exported to Wasm):
Copy code
'foo' : () => console.log('foo')
Is it possible to provide the
foo
JS function the
WebAssembly.Instance
? That way, one can call the function named `bar`:
Copy code
'foo': (instance) => instance.exports.bar
a
As far as I know, it's impossible to do it safely. There is one unsafe way, but it's based on the implementation details we could break in the future. We generate some glue code, and the wasm instance is stored in the variable with
wasmInstance
name. You could try to refer to it inside the function body like this:
Copy code
fun foo() = js("wasmInstance.exports.bar")
But again, I don't recommend you to go this way. It's not something we support, and we can change it anytime in the future.
l
Ic. Thanks for the reply. Question: is this something that is likely to change frequently? Just trying to figure out the risk here. The specific thing I'm trying to do is to fetch instances of `object`s based on dependencies' resources (imagine, idk, a Json file), and this is the best I can have without proper reflection support. This Wasm/JS code is fetched from a Kotlin/JVM server, though - I guess I could try modifying the bytecode server-side? I have no idea how to even start, though, considering I don't have sophisticated tools for that like I have for modifying JVM bytecode.
I.e. I'll try to find an ASM library but for Wasm.
a
As I see, the name of the variable has not been changed since it was introduced 😄 I just warn you that it's not something officially supported to understand the risk of using such a hack.
l
Yeah, I understand. Thanks! Will use the hack for now, codegen stuff later down the line.
🫡 1
@Artem Kobzar note, the approach you've gave me won't work for getting instances of objects, as they're globals (named
com.example.Object_instance
), not functions - and getting Wasm globals' values from JS isn't supported - unless I'm wrong?
a
I'm not quite sure that I understand the case you are trying to describe. Could you please provide some code snippet with the case?
l
Copy code
fun instanceOf(objectQualifiedName: String) = js("wasmInstance.exports[objectQualifiedName + 'instance']")
This won't work, because
exports
only allows access to functions
And object instances are globals in Kotlin/Wasm.
a
Yeap, it's true