Skip to content

Add support for Cocoa OpenGL screen in gfxlib2 and other compiler error fixes for macOS #448

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

Markos-Th09
Copy link

@Markos-Th09 Markos-Th09 commented Mar 31, 2025

This PR includes several changes to improve support for the macOS platform in fbc and its libraries. It also aims to add support for OpenGL screens using Cocoa instead of requiring XQuartz for X11 support, although at the time of writing this I haven't tested the implementation very thoroughly yet.

Currently some mechanism similar to #inclib but for macOS frameworks is missing. Since a lot of important system libraries contained within frameworks such as OpenGL, this would be useful for headers such as gl.bi and glut.bi but also in general. How should this feature be implemented in FreeBASIC?

@rversteegen
Copy link
Member

Wow, nice!

I'm not sure about frameworks, but I think it should be up to the user whether they want to link to a framework or to a dylib. For example you can either install SDL via homebrew or compile/download a framework. For system frameworks there's no need for a choice, Maybe a new directive to add a framework, with some way to disable it (do I remember that there's now a way to disable/remove libraries added by #inclib?)

I'll want to look into the computed goto removal. clang does support computed gotos. Casting a label address to a function pointer and calling it seems very unsafe (or rather, x86-specific).

@Markos-Th09
Copy link
Author

Markos-Th09 commented Mar 31, 2025

On mac os specifically I couldn't get the computed goto version to compile and function pointers haven't caused any issues so far. I'm still on x86_64, so I haven't tested arm. I don't thing calling function pointers has any specific semantics other than the memory being executable, so it should be fine, although it probably generates a call-type instruction instead just a jmp-type instruction. The only mildly concerning thing is pushing the return address (or possibly the link register on arm) to the stack, but the labels don't seem to ever return.

It seems the specific usage of computed gotos by fbc is causing this issue as I can get other code compiling with computed gotos. I know it's not ideal but I couldn't find another easy solution. In fact, my current bootstrap source contains this patch and has allowed me to use fbc without any issues.

This has been mentioned before in issue #409, but it wasn't really resolved there completely either. Since the llvm backend seems to be completely broken and the gas backend also isn't compatible with apple's assembler in its current form it's the best I could do. I am open to any suggestions about resolving this.

Edit: I have traced it to a real llvm bug and I found a workaround for the error error: indirect goto in function with no address-of-label expressions. You basically need to add a useless label in the the function, if there no other variables taking the address of a label

_useless:;  void* _useless_label = &&_useless;

Optionally the variable can be marked as __attribute__((unused)) to ensure the optimizer strips it away. All versions of clang I have tried seem to affected by this. Specifically it seems to happen whenever some error is thrown using fb_ErrorThrow*. Here is an example in the output for list.bas for the fatalOutOfMemory function

static void FATALOUTOFMEMORY( void )
{
	label$2:;
	label$4:;
	void* vr$0 = fb_ErrorThrowEx( 4, 10, (char*)"src/compiler/list.bas", (void*)0ull, (void*)0ull );
	goto *vr$0;
	label$5:;
	label$3:;
}

However, this use of computed goto is undefined behavior per GCC, as this only meant to be used with the addresses of label in this same function taken with &&, when this is clearly pointing to a function pointer. Therefore the code fbc is outputting is already unsafe and should be adjusted.

You may not use this mechanism to jump to code in a different function. If you do that, totally unpredictable things happen. The best way to avoid this is to store the label address only in automatic variables and never pass it as an argument.

@Markos-Th09
Copy link
Author

Also I forgot to mention that the profiler section name is a problem for mach-o binaries so I have disabled it for now, as I don't what is the best solution.

@Markos-Th09
Copy link
Author

Markos-Th09 commented Apr 1, 2025

@rversteegen Just to be sure when using gfxlib functions like Line or Circle am I supposed to see nothing in an OpenGL Screen? It seems to also be the case on X11. What tests do I need to perform to make sure the implementation is fully correct?

@Markos-Th09
Copy link
Author

Markos-Th09 commented Apr 15, 2025

I'll want to look into the computed goto removal. clang does support computed gotos. Casting a label address to a function pointer and calling it seems very unsafe (or rather, x86-specific).

@rversteegen given what I have found about computed gotos, how do you believe it would be best addressed?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants