Segfault when using JS::Value with static function template ins VS2010

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Segfault when using JS::Value with static function template ins VS2010

Yves
Hi

I thought I was nearly ready with the SpiderMonkey upgrade and now I'm
stuck with a very weird issue which looks like a compiler bug in in
conjunction with some very special behaviour of the JS::Value type.

I have a quite simple static template function like this (for
demonstration):
template<> jsval ScriptInterface::myToJSValStaticTemplate<int>(const int&
val){
        int x = val;
        printf("value: %d", x);
        return JS::Int32Value(x);
}

When I call this from another translation unit (which cannot know the
details of that integer-argument specialization because it only sees the
generic function template in the header), it causes a segmentation fault
on the line "int x = val".
Not using templates, using non-static template functions or using another
return value type work correctly. Also there's no issue with the GCC
compiler on my Linux system.
Adding this to main.cpp of my example program (informing it about that
specific specialization of the function template) works around the issue:

template jsval ScriptInterface::myToJSValStaticTemplate<int>(const int&
val);


In my example program the segfault does only happen in debug mode, but in
the real program (0 A.D.) it happens in release mode too. I have not yet
figure out where this difference comes from.
Philip, the guy who did the upgrade to v1.8.5 years ago, had similar
issues with VS2008 in Debug mode and had to define
JS_NO_JSVAL_JSID_STRUCT_TYPES to work around the problem. Unfortunately
this does not solve the problem for v24 anymore.

I digged deeper and tried to analyze the problem with my very limited
assembler knowledge (I actually red my first assembler tutorials
yesterday).
I noticed that the code for calling the function is different in the
version with the workaround (adding the declaration of the int-
specialization to main.cpp) and the version causing the segfault.
I would expect that since it takes the compiled function from an object
file, it must be binary identical and therefore must be called with
exactly the same conventions.


  Working
 
  004117E9: 8D 45 A0           lea         eax,[ebp-60h]       ; storing
a reference to the memory location of the integer argument in eax
  004117EC: 50                 push        eax                 ; pushing
the content of eax on the stack
  004117ED: 8D 8D D0 FE FF FF  lea         ecx,[ebp-130h]      ; storing
a reference to the memory location of the JS::Value in ecx
  004117F3: 51                 push        ecx                 ; pushing
the content of ecx on the stack
  004117F4: E8 7A F8 FF FF     call        @ILT+110(??
$myToJSValStaticTemplate@H@ScriptInterface@@SA?AVValue@JS@@ABH@Z) ; call
the function
  004117F9: 83 C4 08           add         esp,8               ; clean up
the space required for the arguments (the int ptr and the JS::Value
pointer)
  004117FC: 8B 10              mov         edx,dword ptr [eax]        ;
expect the pointer to the JS::Value data in eax. Copy the first four
Bytes to edx
  004117FE: 8B 40 04           mov         eax,dword ptr [eax+4]      ;
expect the pointer to the JS::Value data in each. Copy the second four
Bytes to eax
  00411801: 89 55 AC           mov         dword ptr [ebp-54h],edx    ;
copy the first part of the value from the register to the memory location
of the JS::Value
  00411804: 89 45 B0           mov         dword ptr [ebp-50h],eax    ;
copy the second part of the value from the register to the memory
location of the JS::Value
  00411807: C7 45 FC FF FF FF  mov         dword ptr [ebp-4],0FFFFFFFFh


Segfault

  004117E9: 8D 45 A0           lea         eax,[ebp-60h]            ;
storing a reference to the memory location of the integer argument in eax
  004117EC: 50                 push        eax                      ;
pushing the content of eax on the stack
  004117ED: E8 81 F8 FF FF     call        @ILT+110(??
$myToJSValStaticTemplate@H@ScriptInterface@@SA?AVValue@JS@@ABH@Z)  ; Call
the function
  004117F2: 83 C4 04           add         esp,4                      ;
clean up the space required for the argument (the int ptr in eax)
  004117F5: 89 85 D0 FE FF FF  mov         dword ptr [ebp-130h],eax   ;
JS::Value structure is 8 Bytes. Expect to find the first four bytes of
the JS::Value data in eax and copy it to memory (12Ch is 4 bytes before/
after 130h)
  004117FB: 89 95 D4 FE FF FF  mov         dword ptr [ebp-12Ch],edx   ;
expect the second four bytes of JS::Value data in edx and copy it to
memory (12Ch is 4 bytes before/after 130h)
  00411801: 8B 8D D0 FE FF FF  mov         ecx,dword ptr [ebp-130h]
  00411807: 89 4D AC           mov         dword ptr [ebp-54h],ecx
  0041180A: 8B 95 D4 FE FF FF  mov         edx,dword ptr [ebp-12Ch]
  00411810: 89 55 B0           mov         dword ptr [ebp-50h],edx
  00411813: C7 45 FC FF FF FF  mov         dword ptr [ebp-4],0FFFFFFFFh


Also check the discussion in our forums for the full code of the example
program and some additional information:
http://www.wildfiregames.com/forum/index.php?showtopic=17289&p=285921

Any ideas what could cause this issue exactly and how to work around it?
Is it a compiler bug, a JSAPI bug or a problem with how I'm using it?


Thanks in advance!

Regards,
Yves
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: Segfault when using JS::Value with static function template ins VS2010

Yves
It looks like a bug in VisualStudio, but passing the JS::Value as
reference instead of using a return value works around the problem.

_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine