Skip to content

Commit 9f80957

Browse files
committed
Add handling for uint32_t,uint64_t,uint32_t case for Raspberry Pi
1 parent 65876f4 commit 9f80957

2 files changed

Lines changed: 42 additions & 7 deletions

File tree

ChangeLog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
Store `function(){return ...}` without the return (fix #700)
2121
Increased simple string usage from 4 chars up to 8
2222
Swap order of JsVar internals, string usage up to 10 chars
23+
Add handling for uint32_t,uint64_t,uint32_t case for Raspberry Pi
2324

2425
1v81 : Fix regression on UART4/5 (bug #559)
2526
Fix Serial3 on C10/C11 for F103 boards (fix #409)

src/jsnative.c

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,22 @@
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 */
2844
JsVar *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

Comments
 (0)