Using emscripten::val with EM_ASM_ ?

177 views
Skip to first unread message

Reuben Scratton

unread,
Jun 20, 2016, 12:06:42 PM6/20/16
to emscripten-discuss
Hi,

I'd like to pass a reference to a javascript object into an EM_ASM_ block, i.e :

{
    val jsObj = ... whatever ...;

    EM_ASM_ ({
        var obj = $0;
        ...
    }, jsObj);

}

But the compiler won't let me do this... it seems only trivial values (ints and doubles and strings) are allowed to go in and out of the js block.

What are my options here? The js object in question can actually be created inside the block but I do need to hold a long-lived reference to it from the C++ world. It'd be helpful if there was an EM_ASM_OBJ macro so I could simply return it to the C++ side...

Many thanks,


Reuben

juj j

unread,
Jun 21, 2016, 7:59:51 AM6/21/16
to emscripte...@googlegroups.com
I think we don't currently have anything built-in for that, but you should marshall the object manually, e.g. by managing a table or other location where the object exists, and referencing that object via an int.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reuben Scratton

unread,
Jul 1, 2016, 7:44:51 AM7/1/16
to emscripten-discuss
Thanks for the reply juj, any chance you could point me to an example of how to do this? Am afraid I just can't work it out.

I am also wanting to pass JS objects as parameters to Runtime.dynCall() and store them in vals on the C++ side... presumably once I understand manual marshalling this will be easy.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-discuss+unsub...@googlegroups.com.

Charles Vaughn

unread,
Jul 5, 2016, 2:43:24 PM7/5/16
to emscripten-discuss
You can do it with something like this

uint32_t objID = ++globalID;
val someJSObject;
val::global("MyObjectTracker")[objID] = someJSObject;
EM_ASM_INT({ 
  var objToUse = MyObjectTracker[$0];
}, objID);

Reuben Scratton

unread,
Jul 6, 2016, 11:14:15 AM7/6/16
to emscripten-discuss
Hey, many thanks, using a global object's properties to hold temporary references to passed objects seems inspired! However I get a runtime error when trying to put the passed object into the global's property :

   uint32_t objID = 123;

   val img = val::global("Image").new_();

   val::global("MyObjectTracker")[objID] = img; <-- boom!


The error is:


Exception: TypeError: undefined is not an object (evaluating '__emval_register') error:undefined


I have definitely declared a global Object named MyObjectTracker in my javascript (in the shell file).

Charles Vaughn

unread,
Jul 6, 2016, 1:55:07 PM7/6/16
to emscripten-discuss
Is MyObjectTracker defined at this point?

Reuben Scratton

unread,
Jul 8, 2016, 4:39:46 PM7/8/16
to emscripten-discuss
It was indeed defined in code, but a silly makefile issue meant it effectively wasn't. Oops!

::embarrassed::

Thanks again for your help.
Reply all
Reply to author
Forward
0 new messages