FreeBASIC 1.10.1 Release Discussion

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

coderJeff wrote: Apr 26, 2023 22:16 - should we change PROCPTR( ..., virtual ) to return index instead of byte offset? probably ...
Of course I agree...

coderJeff wrote: Apr 26, 2023 22:16 - is -2147483648 good check value? Due to the way fbc parses constants const c = -2147483648L is a positive on 64-bit. Even if this is an unrelated quirk (or bug), I struggled for a while with tests passing on 32-bit but failing on 64-bit due to this incorrect constant. const c = -2147483648U is ok for 32 & 64 bit.
Moreover, by using an index instead of an offset (which depends on the processor), we could then simply choose the value '-1' as the error value.
(it does not matter if this index value for a vtable exists and provides a pointer to the RTTI info)
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

@Jeff,

About : 'Procptr ( identifier, virtual [ any|user_proctype ] )'

Do you think it is better to:
- create: a very short new 'Virtual (Qualifier)' documentation page,
- or more simply to only insert a very short adding (syntax + description) in the already existing 'Virtual' (member) documentation page,
- or else the definition of 'Virtual (Qualifier)' remains internal to the 'Procptr' documentation page ?
(I predisposed the second solution, but the 3 are all easy to integrate)
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.10.0 Development

Post by coderJeff »

fxm wrote: Apr 27, 2023 9:11 Moreover, by using an index instead of an offset (which depends on the processor), we could then simply choose the value '-1' as the error value.
Next commit I will change so index is returned and -1 is the error value.
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.10.0 Development

Post by coderJeff »

fxm wrote: Apr 28, 2023 18:51 About : 'Procptr ( identifier, virtual [ any|user_proctype ] )'
my opinion, I think VIRTUAL for this context should only be described on PROCPTR page and only a brief mention on VIRTUAL page.
VIRTUAL when used with PROCPTR changes the purpose of PROCPTR, which I suppose is bad design on my part, but avoids having to add any *new* global functions / operators / keywords. And if fbc did something better, VIRTUAL in this context probably wouldn't be needed.

In the meantime, procptr(...,virtual) can be used to help with work-arounds or prototyping something better in user code.

----
Fun fact, PROCPTR( proc, virtual) is a compile time constant. If used in expressions or assigned to constants, will get optimized and constant folded at compile time.

Or can make decisions in the pre-processor for conditional compilation:

Code: Select all

#if procptr(proc, virtual) >= 0
  '' do virtual call stuff
#else
  '' do normal call stuff
#endif
...
---
An approximation of adeyblue's idea using a stub procedure for the virtual call thunk...

Code: Select all

'' make a unique-ish name
#macro mkVirtualThunkProcName( typeName, procName, signature... )
	__FB_JOIN__( VirtualThunk##typeName, __FB_EVAL__( procptr( typeName.procName, virtual signature ) ) ) 
#endmacro

'' define a stub to call handle the virtual call
#macro mkVirtualThunk( typeName, procName, signature... )
	'' only define a thunk if it is virtual ....
	#if( procptr( typeName.procName, virtual signature ) >= 0 )
		private sub mkVirtualThunkProcName( typeName, procName, signature ) naked ()
			const index = procptr( typeName.procName, virtual signature )
			'' assuming we can use EAX/RAX on any x86/x86_64
			asm
				#if defined(__FB_64BIT__)
					#if defined(__FB_WIN32__)
						mov rax, rcx    '' rax = address of instance 
					#else
						mov rax, rdi    '' rax = address of instance
					#endif 
					mov rax, [rax]      ''  rax  = address of virtual table
					jmp [rax+8*index]   '' [rax+8*index] = address of virtual procedure        
				#else
					mov eax, [esp+4]    ''  eax  = address of instance
					mov eax, [eax]      ''  eax  = address of virtual table
					jmp [eax+4*index]   '' [eax+4*index] = address of virtual procedure        
				#endif
			end asm 
		end sub 
	#endif 
#endmacro

'' get an address to the thunk if it is virtual, otherwise just the address
#macro VirtualProcPtr( typeName, procName, signature... )
	__FB_IIF__( procptr( typeName.procName, virtual signature ) >= 0, _
		cast( typeof( procptr( typeName.procName, signature )), _
			procptr( mkVirtualThunkProcName( typeName, procName, signature ) ) ), _
		procptr( typeName.procName, signature ) ) 
#endmacro

'' ------------------------------------

type B extends object
	declare abstract sub proc1()
	declare abstract sub proc2()
end type

type D extends B
	declare virtual sub proc1()
	declare virtual sub proc2()
end type

sub D.proc1() : print "D.proc1" : end sub
sub D.proc2() : print "D.proc2" : end sub

mkVirtualThunk( B, proc1 )
mkVirtualThunk( B, proc2 )

dim x as B ptr = new D

'' call virtual members of derivied instance through base pointer
var fp1 = VirtualProcPtr( B, proc1 )
var fp2 = VirtualProcPtr( B, proc2 )

fp1( *x )
fp2( *x )

delete x

sleep
However, the NAKED procedure doesn't seem to be seen by gcc since it is defined in ASM ... gcc issues a warning that it is used but not defined.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

coderJeff wrote: Apr 29, 2023 13:54
fxm wrote: Apr 27, 2023 9:11 Moreover, by using an index instead of an offset (which depends on the processor), we could then simply choose the value '-1' as the error value.
Next commit I will change so index is returned and -1 is the error value.
coderJeff wrote: Apr 29, 2023 14:17
fxm wrote: Apr 28, 2023 18:51 About : 'Procptr ( identifier, virtual [ any|user_proctype ] )'
my opinion, I think VIRTUAL for this context should only be described on PROCPTR page and only a brief mention on VIRTUAL page.

Documentation updated accordingly.
adeyblue
Posts: 300
Joined: Nov 07, 2019 20:08

Re: FreeBASIC 1.10.0 Development

Post by adeyblue »

Why not extend procptr even further to take an object and the index and return the address? Like turn
cptr( typeof(delegate.proc), (*cast( any ptr ptr ptr, delegate.inst ))[delegate.ofst\sizeof(any ptr)] )
into a nice
procptr(delegate.inst, delegate.ofst)

Whatever form it takes, you really need to hide that sort of thing behind a nicety. Everybody has to do it and it doesn't change so making everybody type it out in full every time (or having to dig out the place to copy and paste it from) is an act of utter barbarity.
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.10.0 Development

Post by coderJeff »

adeyblue wrote: Apr 30, 2023 2:30 Why not extend procptr even further to take an object and the index and return the address?
I tried extending PROCPTR to handle expressions too (the instance) and it gave me a lot of grief sorting out the ambiguity.
I can give it another try, maybe with:
procptr( ( expression ) ) - like with @(expression) using parens to sort out ambiguity.

For interest, what we are starting with:
procptr( symbol ) - symbol is expected to be name of a procedure
varptr( expression) - expression is expected to be data that we can take address of
@symbol-or-expression - maybe name of procedure (checked first) or maybe expression (checked second)
@(expression) - always expression due the parens

Internally, @symbol-or-expression uses same handling as either PROCPTR or VARPTR except that preference is given to returning a procedure pointer instead of the address of the value returned by the procedure if symbol-or-expression could be seen as either.

Current parsing on fbc 1.10 (and same on fbc 1.09) for example:

Code: Select all

type D extends object
end type

type T extends object
	declare static function getD() byref as D
end type

function T.getD() byref as D
	static ret as D
	print "T.getD(), static ret  = " & cint( @ret )
	return ret
end function

var f0 = @T.getD             '' address of function T.getD
print "@T.getD               = " & cint(f0)

var f1 = @T.getD()           '' address of function T.getD
print "@T.getD()             = " & cint(f1)

var f2 = procptr( T.getD )   '' address of function T.getD
print "procptr( T.getD )     = " & cint(f2)

var f3 = procptr( T.getD() ) '' address of function T.getD
print "procptr( T.getD() )   = " & cint(f3)

var v0 = @(T.getD)           '' address of returned D (ret)
print "@(T.getD)             = " & cint(v0)

var v1 = @(T.getD())         '' address of returned D (ret)
print "@(T.getD())           = " & cint(v1)

var v2 = varptr( T.getD )    '' address of returned D (ret)
print "varptr( T.getD )      = " & cint(v2)

var v3 = varptr( T.getD() )  '' address of returned D (ret)
print "varptr( T.getD() )    = " & cint(v3)

dim x as T
var v4 = varptr( x.getD )    '' address of returned D (ret)
print "varptr( x.getD )      = " & cint(v4)

var v5 = varptr( x.getD() )  '' address of returned D (ret)
print "varptr( x.getD() )    = " & cint(v5)

sleep
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.10.0 Development

Post by coderJeff »

adeyblue wrote: Apr 30, 2023 2:30 cptr( typeof(delegate.proc), (*cast( any ptr ptr ptr, delegate.inst ))[delegate.ofst\sizeof(any ptr)] )
into a nice
procptr(delegate.inst, delegate.ofst)
In latest update '\sizeof(any ptr)' is not needed

Just remembered if 'delegate.ofst' is only known at runtime, then 'procptr(delegate.inst, delegate.ofst)' can't have a known function pointer type at compile time unless we work in the expected 'typeof(delegate.proc)' signature somewhere. Which leads back to maybe disambiguating 'delegate.inst.member' - (is the next token to parse the member? or just more expression?). I had previously tried 'expression->(member, signature)' to get the procedure type, but this is a new kind of AST so will need to develop all the associated AST and handling .. maybe.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

coderJeff wrote: Apr 24, 2023 22:49 4) 'PROCPTR( proc )' is existing syntax and we don't want to break that. But we might want to do something in future.

Code: Select all

'' maybe in future ...  a '-w pedantic' warning?
sub OVL overload( byval arg as short ) : end sub
sub OVL overload( byval arg as byte )  : end sub

var fp1 = procptr( OVL )      '' warning: signature not specified for overloaded procedure
var fp2 = procptr( OVL, any ) '' no warning
I really like this possible improvement for the use of ANY !
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.10.0 Development

Post by coderJeff »

fxm, sounds good, let's come back to it.

For now I just want to push ahead and get a release done before we start working on whatever the next thing is. Because of course there's lots of things we could keep working on: bug fixes, testing out the new features, investigating reports from the forum (pmap, array bounds, utf8 strings, fbdoc formatting), user contributions I was too slow to deal with, the list goes on and on.

Anyway fbc 1.10.0 release will be based on this commit: FreeBASIC 1.10.0 Release

With a little luck I will be done with the builds and uploads today.
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.10.0 Release Discussion

Post by coderJeff »

... reticulating splines...
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: FreeBASIC 1.10.0 Release Discussion

Post by srvaldez »

hello coderJeff :)
... reticulating splines... , has me puzzled, not clear to me what you meant
"Reticulating splines" is a phrase that was popularized by the computer game "SimCity" in the 1990s. In the game, the phrase was displayed on the loading screen as the game loaded its graphics and simulated the city's infrastructure.

However, the phrase itself doesn't have a specific meaning outside of the context of the game. "Reticulating" means to form a network or mesh, while "spline" refers to a curve that is defined by a set of points and mathematical formulas. So, in the context of the game, it was likely intended to give the impression that the game was creating a complex network of connections between different parts of the simulated city.

In more general use, the phrase "reticulating splines" has become a humorous way to refer to any situation where a computer or other technology is working on a complex task that is not immediately obvious to the user.
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.10.0 Release Discussion

Post by coderJeff »

srvaldez wrote: May 15, 2023 0:43 hello coderJeff :)
... reticulating splines... , has me puzzled, not clear to me what you meant
Perfect. I could not have hoped for a better response.

Release is uploaded and now just need to do the announcements -- but pages and posts need to link to all the files and to each other, so I thought the expression was fitting, and since it is past my bedtime, I'm slowing down and need a little extra time to get this done :)

EDIT:
OK i'm done. No doubt I've forgotten something and too weary to see it.

Please let us know if there is anything amiss with the release. Cheers!
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: FreeBASIC 1.10.0 Release Discussion

Post by srvaldez »

thank you coderJeff for the release :D
VANYA
Posts: 1834
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: FreeBASIC 1.10.0 Release Discussion

Post by VANYA »

Thank you for the continued work on the compiler! This is very hard work, I appreciate it and I think others too.
Post Reply