On Tue, Apr 12, 2016 at 10:07 PM, Alex <[email protected]> wrote:

> I set up a small example for passing a string from C++ to JS. The string
> is correctly received in JS when no optimizations are used but it becomes
> an empty string when -O is -O2, -Os or -O3 and I can't figure out how to
> make it work. If someone can point me in the right direction I'd be truly
> thankful.
>
[snip]

>         <script type="text/javascript" src="sample.js"></script>
>         <script type="text/javascript">
> function ShowAlert(string_ptr) {
>     alert(Module.Pointer_stringify(string_ptr));
> }
> Test = Module.cwrap('Test', null, []);
> Test();
>         </script>
>

At -O2 and above things like string literals are stored in a separate
memory initialization file, 'sample.js.mem'. This has to be loaded
asynchronously via an XMLHTTPRequest, and won't have been loaded yet by the
time you run Test().

You can trigger your code after initialization is complete by setting a
callback on the onRuntimeInitialized property on the Module object:

        <script type="text/javascript">
        function ShowAlert(string_ptr) {
            alert(Module.Pointer_stringify(string_ptr));
        }
        Module = {
          onRuntimeInitialized: function() {
            Test = Module.cwrap('Test', null, []);
            Test();
          }
        };
        </script>
        <script type="text/javascript" src="sample.js"></script>

This works reliably in Firefox for me with the build settings you gave.

Alternately, you can disable generation of the memory initialization file
which should get the runtime data initialized immediately by embedding a
big array in the .js output, as happens at -O0:

"--memory-init-file <on>"
   Specifies whether to emit a separate memory initialization file.
   Possible "on" values are:

      * "0": Do not emit a separate memory initialization file.
        Instead keep the static initialization inside the generated
        JavaScript as text. This is the default setting if compiling
        with -O0 or -O1 link-time optimization flags.

      * "1": Emit a separate memory initialization file in binary
        format. This is more efficient than storing it as text inside
        JavaScript, but does mean you have another file to publish.
        The binary file will also be loaded asynchronously, which
        means "main()" will not be called until the file is downloaded
        and applied; you cannot call any C functions until it arrives.
        This is the default setting when compiling with -O2 or higher.

           Note: The safest way to ensure that it is safe to call C
             functions (the initialisation file has loaded) is to call
             a notifier function from "main()".

           Note: If you assign a network request to
             "Module.memoryInitializerRequest" (before the script
             runs), then it will use that request instead of
             automatically starting a download for you. This is
             beneficial in that you can, in your HTML, fire off a
             request for the memory init file before the script
             actually arrives. For this to work, the network request
             should be an XMLHttpRequest with responseType set to
             "'arraybuffer'". (You can also put any other object here,
             all it must provide is a ".response" property containing
             an ArrayBuffer.)


-- brion

-- 
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to