What happened to the Emscripten branch?
Re: What happened to the Emscripten branch?
At this point, I suspect the bug is in Emscripten, not in FreeBasic
Re: What happened to the Emscripten branch?
In your minimum code, arr is one element short. It should be:
Otherwise you're running off the end of the array, just as adeyblue says.
Does that change the outcome?
Code: Select all
int arr[14];
Does that change the outcome?
Re: What happened to the Emscripten branch?
No, it doesn't.
This code works:
This code fails:
This code works:
Code: Select all
int main(){
int arr[14];
for (int i=0;i<=5;i++){
*(int*)(((int)(int*)arr + (-i << (2 & 31))) + 52) = i;
}
}
Code: Select all
int arr[14];
int main(){
for (int i=0;i<=5;i++){
*(int*)(((int)(int*)arr + (-i << (2 & 31))) + 52) = i;
}
}
Re: What happened to the Emscripten branch?
On the other hand, this seems to work:
In case, maybe I figured where the issue might be: pointers, in Emscripten version of FreeBasic, were cast as 32 bit integers, since this was the standard for Emscripten. Perhaps they started using 64 bit pointers
Code: Select all
int arr[14];
int main(){
for (int i=0;i<=5;i++){
*(int*)(((long long int)(int*)arr + (-i << (2 & 31))) + 52) = i;
}
}
Re: What happened to the Emscripten branch?
Perhaps a simple C program that prints out the sizeof(int*) would tell you. I can't get any definitive answer out of google.
ChatGPT says:
"The bit size of a pointer in emscripten depends on the target architecture. By default, emscripten uses a 32-bit architecture. However, there is a MEMORY64 mode that allows for 64-bit function pointers."
ChatGPT says:
"The bit size of a pointer in emscripten depends on the target architecture. By default, emscripten uses a 32-bit architecture. However, there is a MEMORY64 mode that allows for 64-bit function pointers."
Re: What happened to the Emscripten branch?
Now I do not remember... is there a flag to force FreeBasic to compile in 32 or in 64 bit mode (emitting different .c code) without changing the platform?
Re: What happened to the Emscripten branch?
Ok, I found a possible workaround:
Add the option -Wl "-s WASM=0" to the command line
So:
Code: Select all
fbc -target js-asmjs mancala.bas -Wl "-s ASYNCIFY=1" -Wl "-s WASM=0" -Wl --preload-file,res
Re: What happened to the Emscripten branch?
Yes, this solves this local problem, but there is another one. A recursion exception occurs. Browser Console Message (Developer Tools):angros47 wrote: ↑Sep 24, 2023 22:38
Ok, I found a possible workaround:
Add the option -Wl "-s WASM=0" to the command line
So:It won't produce WASM code, but only JavaScript code. It seems to work fine, in that way. At this point, I would say it is an Emscripten bugCode: Select all
fbc -target js-asmjs mancala.bas -Wl "-s ASYNCIFY=1" -Wl "-s WASM=0" -Wl --preload-file,res
This did not happen before and everything worked correctly. Here I compiled in 2020: https://users.freebasic-portal.de/freeb ... ncala.html.Uncaught InternalError: too much recursion
It's a pity that that compiler has not been preserved.
Re: What happened to the Emscripten branch?
It turns out that I saved the previous compiler (1.08) in my archives. And there are no problems with him. Here is the difference in code generation:
1.09:
1.08:
So the problem is in the FB compiler.
1.09:
Code: Select all
fb_IntToStr( (int32)*(int8*)(((int64)(struct $8TMANCALA*)BDIMMANCALA$ + (-(int64)I$2 * 49ll)) + 637ll) );
Code: Select all
fb_IntToStr( (int32)*(int8*)(((uint8*)BDIMMANCALA$ + (-I$2 * 49)) + 637) );
Re: What happened to the Emscripten branch?
For this source file:
Generated code 1.08:
The difference is only in one line:
1.09:
1.08:
Code: Select all
Dim shared As long bDimMancala(13)
Sub DrawNumbers()
For i As Long = 0 To 5
bDimMancala(13 - i) = i
next
End Sub
DrawNumbers()
Code: Select all
typedef signed char int8;
typedef unsigned char uint8;
typedef signed short int16;
typedef unsigned short uint16;
typedef signed int int32;
typedef unsigned int uint32;
typedef signed long long int64;
typedef unsigned long long uint64;
typedef struct { char *data; int32 len; int32 size; } FBSTRING;
typedef int8 boolean;
void fb_Init( int32, uint8**, int32 );
void fb_End( int32 );
void DRAWNUMBERS( void );
static int32 BDIMMANCALA$[14];
void DRAWNUMBERS( void )
{
label$2:;
{
int32 I$2;
I$2 = 0;
label$7:;
{
*(int32*)(((uint8*)BDIMMANCALA$ + (-I$2 << (2 & 31))) + 52) = I$2;
}
label$5:;
I$2 = I$2 + 1;
label$4:;
if( I$2 <= 5 ) goto label$7;
label$6:;
}
label$3:;
}
int32 main( int32 __FB_ARGC__$0, char** __FB_ARGV__$0 )
{
int32 fb$result$0;
__builtin_memset( &fb$result$0, 0, 4 );
fb_Init( __FB_ARGC__$0, (uint8**)__FB_ARGV__$0, 0 );
label$0:;
DRAWNUMBERS( );
label$1:;
fb_End( 0 );
return fb$result$0;
}
1.09:
Code: Select all
*(int32*)(((int32)(int32*)BDIMMANCALA$ + (-I$2 << (2 & 31))) + 52) = I$2;
Code: Select all
*(int32*)(((uint8*)BDIMMANCALA$ + (-I$2 << (2 & 31))) + 52) = I$2;
Re: What happened to the Emscripten branch?
Interesting... it might be related with another bug of the last version, that produces warning with some C functions like printf
Re: What happened to the Emscripten branch?
Actually, both codes should be valid: in one, the pointer is cast to a byte pointer (so, pointer math will be at one byte level: a longer pointer will increase/decrease by as many bytes as a single element is long), in the newer code it's cast to an integer, that, not being subject to pointer math rules, will act like a byte pointerVANYA wrote: ↑Sep 25, 2023 3:07 The difference is only in one line:
1.09:1.08:Code: Select all
*(int32*)(((int32)(int32*)BDIMMANCALA$ + (-I$2 << (2 & 31))) + 52) = I$2;
Code: Select all
*(int32*)(((uint8*)BDIMMANCALA$ + (-I$2 << (2 & 31))) + 52) = I$2;
BTW, the fact that it works by disabling the WASM emitter proves that the code itself is valid, the Emscripten emitter is the cause of the issue.
Re: What happened to the Emscripten branch?
With this version of the compiler everything goes without problems:
https://disk.yandex.ru/d/Y8T52dgOt-vybw
P.S. I used Linux x86-64
https://disk.yandex.ru/d/Y8T52dgOt-vybw
P.S. I used Linux x86-64