Cannot compile helloworld.cs example with emscripten

Aug 4, 2015 at 1:21 PM
Edited Aug 5, 2015 at 7:13 AM
Hi,

I am trying to generate asm.js code for a large project, but i am struggling a bit with compiling the helloworld example.

I am running the same steps as described for native except also specifying /emscripten for all calls to il2c.exe ( it seemed like a good idea ).

When i run emcc .\helloworld.cpp .\CoreLib.cpp i get the following error:

.\helloworld.cpp:2398:7: error: second parameter of 'main' (argument array) must be of type 'char '
Int32 main(Int32 count, SByte
parameters) {

Is it an issue with the version of Emscripten ( emscripten-1.34.1) i am using?

Any help is greatly appreciated, i think the ability to target asm.js from C# is extremely useful, so i am really looking forward to getting the basics working.

Update: Just to be clear, i get this error also with em++
Coordinator
Aug 5, 2015 at 11:17 AM
you need to stop treating warnings as errors or you can fix it manually
Aug 5, 2015 at 12:02 PM
Thank you for the quick reply.

Is treat warnings as errors enabled by default, because i am getting a mix of warnings and errors. If i run the previously mentioned cmd line, the full output is:
In file included from .\helloworld.cpp:1:
In file included from ./helloworld.h:3:
./CoreLib.h:108:2: warning: expression result unused [-Wunused-value]
        _object;
        ^~~~~~~
.\helloworld.cpp:2398:7: error: second parameter of 'main' (argument array) must be of type 'char **'
Int32 main(Int32 count, SByte** parameters) {
      ^
.\helloworld.cpp:2439:9: warning: expression result unused [-Wunused-value]
        _phi91;
        ^~~~~~
2 warnings and 1 error generated.
If treat warnings as errors was enabled i would have expected 3 errors instead? If i *enable * warnings as errors i do get 3 errors, and the two that derive from a warning list their matching -W flag (ie. -Wunused-value).

Could you provide a hint to what the appropriate cmd line is? Or perhaps you can point me to where in the code base the main method is generated, so that i can fix it completely?
Coordinator
Aug 5, 2015 at 8:34 PM
FOA try to replace Int32 main(Int32 count, SByte** parameters) with Int32 main(Int32 count, char** parameters)

then you can try to fix the procedure WriteMainFunction in file CWriter,cs but I would not do it as the code is not clean yet.
Aug 6, 2015 at 9:38 AM
If I do that it fails a bit later in
parameters = (SByte**) (((Byte*) (_dup24) + sizeof(SByte*)));
Seems better to just fix it in WriteMainFunction?

If I fix it manually and a few other places in helloworld.cpp, then I get this from CoreLib.cpp:
.\CoreLib.cpp:22:16: error: use of undeclared identifier 'realpath'
        return (Byte*)realpath(partial, full);
                      ^
.\CoreLib.cpp:311216:80: error: cannot initialize a parameter of type 'Int32' (aka 'int') with an lvalue of type 'Boolean *' (aka 'bool *')
    *((Int32*) location1) = compare_and_swap_bool((Int32*) (comparand), value, succeeded);
Which version and/or settings are you using with Emscripten (or is that unsupported currently) I just thought it was supported given the /emscripten flag.
Coordinator
Aug 6, 2015 at 10:54 AM
Yes, I have not tested for emscripten for a while. Seems they do not have realpath

you can replace __return (Byte*)realpath(partial, full);__ with return partial; I am not sure if you depends on this function.
Coordinator
Aug 6, 2015 at 10:57 AM
I just thought it was supported given the /emscripten flag.
yes, it was supported a while back but I have written tons of code since and have not tested it for emscripten.
Aug 6, 2015 at 7:58 PM
Fair enough. My goal isn´t really to compile a program with a main() method at all, but rather some API's, so perhaps ill just go for compiling as an emscripten module and call it from js. But ill probably take a look if its easy to change. I am very interested in getting from MSIL to asm.js (though to native would also be interesting).
Aug 7, 2015 at 7:29 PM
I changed my example to a simple class with a function. I had to do the following to get it to compile. I would appreciate verfication that i didn´t screw up :)
  1. I had to set my region settings to use '.' as decimal separator (i created an issue for this), it was creating float constants like 0,72f.
  2. I replaced
return (Byte*)realpath(partial, full);
with
return partial;
Not really sure what impact that has, but at least in my example i don´t work with paths.
  1. You have the following setup in CoreLib.h (at least as it generated for me):
#define compare_and_swap __sync_val_compare_and_swap 
#define compare_and_swap_bool __sync_bool_compare_and_swap 
And in CoreLib.cpp you define the following:
Int32 Int32_System_Threading_Interlocked_CompareExchangeFRef_Int32R__Int32__Int32__Ref_BooleanRN(Int32* location1, Int32 value, Int32 comparand, Boolean* succeeded) {
    Int32 local0;
    local0 = (*((Int32*)location1));
    *((Int32*) location1) = compare_and_swap_bool((Int32*) (comparand), value, succeeded);
    return local0;
}
However, according to https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html the signature for __sync_bool_compare_and_swap (which compare_and_swap_bool maps to) is:
bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
Since you are looking to return the original value it seems more appropriate to use compare_and_swap (mapped to __sync_val_compare_and_swap). So, i changed it to the following:
Int32 Int32_System_Threading_Interlocked_CompareExchangeFRef_Int32R__Int32__Int32__Ref_BooleanRN(Int32* location1, Int32 value, Int32 comparand, Boolean* succeeded) {
    return compare_and_swap(location1, comparand, value);
}
I assume that is correct?

After this, it seemed to compile okay. I would be happy to assist in changing the code generation to fix these issue, if you can point me in the right direction.
Coordinator
Aug 10, 2015 at 9:14 AM
Edited Aug 10, 2015 at 9:26 AM
Thank you for your investigation, I probably did a typo using compare_and_swap_bool instead of compare_and_swap.

I will double check. I remember there should be one overload of function which should use compare_and_swap_bool not compare_and_swap

Ok, fixed it,

FIX:
1) Find file CompareExchangeGen.cs
2) Locate function GetCompareExchangeForTypeWithBool
3) Replace
            ilCodeBuilder.LoadArgument(0);
            ilCodeBuilder.LoadArgument(2);
            ilCodeBuilder.LoadArgument(1);
            ilCodeBuilder.LoadArgument(3);
with
            ilCodeBuilder.LoadArgument(3);
            ilCodeBuilder.LoadArgument(0);
            ilCodeBuilder.LoadArgument(2);
            ilCodeBuilder.LoadArgument(1);
Coordinator
Aug 10, 2015 at 6:47 PM
or you can grab the latest update from git
Aug 11, 2015 at 7:54 AM
Ah okay, thanks, so i don´t need the change i made any more?