2424 #define USE_X86_CDECL // cdecl on x86 puts FP args elsewhere!
2525#endif
2626
27+ #if defined(__WORDSIZE ) && __WORDSIZE == 64
28+ #define USE_64BIT
29+ #else // 32 bit
30+ #if defined(__gnu_linux__ ) && !defined(USE_X86_CDECL )
31+ /* This is nuts. On rasbperry pi Linux:
32+ *
33+ * `uint32_t a, uint32_t b, uint64_t c` -> a,b,c - awesome
34+ * `uint64_t a, uint32_t b, uint32_t c` -> a,b,c - awesome
35+ * `uint32_t a, uint64_t b, uint32_t c` -> a,c,b - NOT awesome
36+ *
37+ * 64 bits are aligned, but 32 bits fill in the gaps inbetween!
38+ */
39+ #define USE_ARG_REORDERING
40+ #endif
41+ #endif
42+
2743/** Call a function with the given argument specifiers */
2844JsVar * jsnCallFunction (void * function , JsnArgumentType argumentSpecifier , JsVar * thisParam , JsVar * * paramData , int paramCount ) {
2945 JsnArgumentType returnType = (JsnArgumentType )(argumentSpecifier & JSWAT_MASK );
@@ -41,6 +57,10 @@ JsVar *jsnCallFunction(void *function, JsnArgumentType argumentSpecifier, JsVar
4157 argData [argCount ++ ] = (size_t )thisParam ;
4258 argumentSpecifier = (argumentSpecifier & JSWAT_ARGUMENTS_MASK ) >> JSWAT_BITS ;
4359
60+ #ifdef USE_ARG_REORDERING
61+ size_t alignedLongsAfter = 0 ;
62+ #endif
63+
4464
4565 // run through all arguments
4666 while (argumentSpecifier & JSWAT_MASK ) {
@@ -50,17 +70,18 @@ JsVar *jsnCallFunction(void *function, JsnArgumentType argumentSpecifier, JsVar
5070 // try and pack it:
5171 JsnArgumentType argType = (JsnArgumentType )(argumentSpecifier & JSWAT_MASK );
5272
53- #ifndef USE_X86_CDECL
54- if (JSWAT_IS_64BIT (argType ))
55- argCount = (argCount + 1 )& ~1 ;
73+ #ifdef USE_ARG_REORDERING
74+ if (!JSWAT_IS_64BIT (argType ) && !(argCount & 1 )) {
75+ argCount += alignedLongsAfter * 2 ;
76+ alignedLongsAfter = 0 ;
77+ }
5678#endif
5779
5880 if (argCount > MAX_ARGS - (JSWAT_IS_64BIT (argType )?2 :1 )) {
81+ // TODO: can we ever hit this because of JsnArgumentType's restrictions?
5982 jsError ("INTERNAL: too many arguments for jsnCallFunction" );
6083 }
6184
62-
63-
6485 switch (argType ) {
6586 case JSWAT_JSVAR : { // standard variable
6687 argData [argCount ++ ] = (size_t )param ;
@@ -95,11 +116,24 @@ JsVar *jsnCallFunction(void *function, JsnArgumentType argumentSpecifier, JsVar
95116 doubleData [doubleCount ++ ] = f ;
96117#else
97118 uint64_t i = * (uint64_t * )& f ;
98- #if defined( __WORDSIZE ) && __WORDSIZE == 64
119+ #if USE_64BIT
99120 argData [argCount ++ ] = (size_t )i ;
100- #else
121+ #else // 32 bit...
122+ #ifdef USE_ARG_REORDERING
123+ if (argCount & 1 ) {
124+ size_t argC = argCount + 1 ;
125+ argData [argC ++ ] = (size_t )((i ) & 0xFFFFFFFF );
126+ argData [argC ++ ] = (size_t )((i >>32 ) & 0xFFFFFFFF );
127+ alignedLongsAfter ++ ;
128+ } else {
129+ argData [argCount ++ ] = (size_t )((i ) & 0xFFFFFFFF );
130+ argData [argCount ++ ] = (size_t )((i >>32 ) & 0xFFFFFFFF );
131+ }
132+ #else // no reordering
133+ if (argCount & 1 ) argCount ++ ;
101134 argData [argCount ++ ] = (size_t )((i ) & 0xFFFFFFFF );
102135 argData [argCount ++ ] = (size_t )((i >>32 ) & 0xFFFFFFFF );
136+ #endif
103137#endif
104138#endif
105139 break ;
0 commit comments