'#pragma reserve' statement to reserve backend keywords

Forum for discussion about the documentation project.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

'#pragma reserve' statement to reserve backend keywords

Post by coderJeff »

Working on an update to add #pragma reserve (asm, shared) symbol statement to reserve words in the global shared namespace and ASM statements.

- #pragma reserve (asm) symbol - reserve symbol as ASM keyword
- #pragma reserve (shared) symbol - reserve symbol in the global shared namespace
- #pragma reserve (asm, shared) symbol - reserve symbol as both ASM keyword and in the global shared namespace
- #pragma reserve symbol - reserve symbol in current scope / namespace (not very well tested and is a side-effect of the above).

PR #345 on github on provides a partial solution for backend compilation errors reported:
- sourceforge.net #515 Reserved variable names (0.21.1)
- freebasic.net fbc 0.21.1: Bug or feature, that's the question
- freebasic.net Strange behaviour. Maybe a bug?
- freebasic.net Re: Wiki improvements
- freebasic.net 'dword ptr [K2]' is not a valid base/index expression

Short version of the problem: some symbol names in fbc are emitted as-is to the backend compilers (gcc, as, etc) where the symbol name is a reserved keyword by the backend compiler. There are typically two outcomes:
- compilation error in the backend
- bad code generation in the backend - successful compile and unexpected run time crashes

#pragma reserve allows user some access to the internal symbol tables.

Before updating the compiler to automatically add reserved words (and potentially breaking user code), this seemed like a good approach for testing the internals. And in future, users can add reserved words in the event that new reserved words in the backend are discovered.

Currently, no new reserved words are added automatically.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: '#pragma reserve' statement to reserve backend keywords

Post by coderJeff »

These examples are based on current fbc version. If reserved backend keywords are automatically added in a future update, these examples may become irrelevant.

Already defined ASM keywords since several versions of fbc: parser-inlineasm.bas

Not sure if the intent should be to only add keywords when using intel syntax.

Example 1

Code: Select all

#if ( __FB_ASM__ = "intel" )
	'' 'ax' is already a reserved asm keyword
	'' but should also not allow it for procedures
	#pragma reserve (shared) ax
#endif

'' ax.bas(8) error 4: Duplicated definition in 'sub ax()' 
sub ax()
end sub
Example 2
Show the difference between a reserved and non-reserved asm keyword. This example uses '-gen gas64' and will have comparable results for '-gen gcc'. Currently 'CQO' 64-bit instruction is not reserved by fbc.

'CQO' instruction is not reserved:

Code: Select all

#cmdline "-gen gas64 -r"

dim shared cqo as integer

sub proc naked()
	asm
		cqo
		ret
	end asm
end sub 

/' OUTPUT in cqo-1.asm:
   .text
   .globl PROC
PROC:
   .L_0004:
   CQO$
   ret
   .L_0005:
   ret
'/
'CQO' instruction is reserved:

Code: Select all

#cmdline "-gen gas64 -r"
#pragma reserve(asm) cqo

dim shared cqo as integer

sub proc naked()
	asm
		cqo
		ret
	end asm
end sub 

/' OUTPUT in cqo-2.asm:

   .text
   .globl PROC
PROC:
   .L_0004:
   cqo
   ret
   .L_0005:
   ret

'/
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: '#pragma reserve' statement to reserve backend keywords

Post by coderJeff »

Based on the discussions in the other threads, the following include file is what I think needs to be added to fbc. Does not include new 64-bit instructions or instructions for other processor extensions.

Code: Select all

#pragma once

#if ( __FB_ASM__ = "intel" )

	#pragma reserve (shared)     ax
	#pragma reserve (shared)     bx
	#pragma reserve (shared)     bp
	#pragma reserve (shared)     cx
	#pragma reserve (shared)     di
	#pragma reserve (shared)     dx
	#pragma reserve (shared)     dword
	#pragma reserve (asm,shared) fword
	#pragma reserve (asm,shared) mmword
	#pragma reserve (asm,shared) oword
	#pragma reserve (shared)     qword
	#pragma reserve (asm,shared) r8
	#pragma reserve (asm,shared) r9
	#pragma reserve (asm,shared) r10
	#pragma reserve (asm,shared) r11
	#pragma reserve (asm,shared) r12
	#pragma reserve (asm,shared) r13
	#pragma reserve (asm,shared) r14
	#pragma reserve (asm,shared) r15
	#pragma reserve (asm,shared) r8w
	#pragma reserve (asm,shared) r9w
	#pragma reserve (asm,shared) r10w
	#pragma reserve (asm,shared) r11w
	#pragma reserve (asm,shared) r12w
	#pragma reserve (asm,shared) r13w
	#pragma reserve (asm,shared) r14w
	#pragma reserve (asm,shared) r15w
	#pragma reserve (asm,shared) rax
	#pragma reserve (asm,shared) rbp
	#pragma reserve (asm,shared) rbx
	#pragma reserve (asm,shared) rcx
	#pragma reserve (asm,shared) rdi
	#pragma reserve (asm,shared) rdx
	#pragma reserve (asm,shared) rsi
	#pragma reserve (asm,shared) rsp
	#pragma reserve (shared)     si
	#pragma reserve (shared)     sp
	#pragma reserve (asm,shared) tbyte
	#pragma reserve (shared)     word
	#pragma reserve (asm,shared) xmmword
	#pragma reserve (asm,shared) ymmword
	#pragma reserve (asm,shared) zmmword

	#pragma reserve (asm,shared) ah
	#pragma reserve (shared)     al
	#pragma reserve (asm,shared) axl

	#pragma reserve (asm,shared) bh
	#pragma reserve (shared)     bl
	#pragma reserve (asm,shared) bpl
	#pragma reserve (asm,shared) bxl

	#pragma reserve (asm,shared) ch
	#pragma reserve (shared)     cl
	#pragma reserve (shared)     cs
	#pragma reserve (asm,shared) cxl

	#pragma reserve (asm,shared) dh
	#pragma reserve (asm,shared) dil
	#pragma reserve (shared)     dl
	#pragma reserve (asm,shared) dr0
	#pragma reserve (asm,shared) dr1
	#pragma reserve (asm,shared) dr2
	#pragma reserve (asm,shared) dr3
	#pragma reserve (asm,shared) dr4
	#pragma reserve (asm,shared) dr5
	#pragma reserve (asm,shared) dr6
	#pragma reserve (asm,shared) dr7
	#pragma reserve (shared)     ds
	#pragma reserve (asm,shared) dxl

	#pragma reserve (shared)     eax
	#pragma reserve (shared)     ebp
	#pragma reserve (shared)     ebx
	#pragma reserve (shared)     ecx
	#pragma reserve (shared)     edi
	#pragma reserve (shared)     edx
	#pragma reserve (asm,shared) eip
	#pragma reserve (asm,shared) eq
	#pragma reserve (shared)     es
	#pragma reserve (shared)     esi
	#pragma reserve (shared)     esp

	#pragma reserve (shared)     fs

	#pragma reserve (asm,shared) ge

	#pragma reserve (shared)     gs
	#pragma reserve (asm,shared) gt

	#pragma reserve (asm,shared) le
	#pragma reserve (asm,shared) lt

	#pragma reserve (shared)     mm0
	#pragma reserve (shared)     mm1
	#pragma reserve (shared)     mm2
	#pragma reserve (shared)     mm3
	#pragma reserve (shared)     mm4
	#pragma reserve (shared)     mm5
	#pragma reserve (shared)     mm6
	#pragma reserve (shared)     mm7

	#pragma reserve (asm,shared) ne

	#pragma reserve (asm,shared) r8b
	#pragma reserve (asm,shared) r9b
	#pragma reserve (asm,shared) r10b
	#pragma reserve (asm,shared) r11b
	#pragma reserve (asm,shared) r12b
	#pragma reserve (asm,shared) r13b
	#pragma reserve (asm,shared) r14b
	#pragma reserve (asm,shared) r15b
	#pragma reserve (asm,shared) r8d
	#pragma reserve (asm,shared) r9d
	#pragma reserve (asm,shared) r10d
	#pragma reserve (asm,shared) r11d
	#pragma reserve (asm,shared) r12d
	#pragma reserve (asm,shared) r13d
	#pragma reserve (asm,shared) r14d
	#pragma reserve (asm,shared) r15d
	#pragma reserve (asm,shared) rip

	#pragma reserve (asm,shared) sil
	#pragma reserve (asm,shared) spl
	#pragma reserve (shared)     ss
	#pragma reserve (shared)     st

	#pragma reserve (shared)     xmm0
	#pragma reserve (shared)     xmm1
	#pragma reserve (shared)     xmm2
	#pragma reserve (shared)     xmm3
	#pragma reserve (shared)     xmm4
	#pragma reserve (shared)     xmm5
	#pragma reserve (shared)     xmm6
	#pragma reserve (shared)     xmm7
	#pragma reserve (shared)     xmm8
	#pragma reserve (shared)     xmm9
	#pragma reserve (shared)     xmm10
	#pragma reserve (shared)     xmm11
	#pragma reserve (shared)     xmm12
	#pragma reserve (shared)     xmm13
	#pragma reserve (shared)     xmm14
	#pragma reserve (shared)     xmm15

	#pragma reserve (asm,shared) ymm0
	#pragma reserve (asm,shared) ymm1
	#pragma reserve (asm,shared) ymm2
	#pragma reserve (asm,shared) ymm3
	#pragma reserve (asm,shared) ymm4
	#pragma reserve (asm,shared) ymm5
	#pragma reserve (asm,shared) ymm6
	#pragma reserve (asm,shared) ymm7
	#pragma reserve (asm,shared) ymm8
	#pragma reserve (asm,shared) ymm9
	#pragma reserve (asm,shared) ymm10
	#pragma reserve (asm,shared) ymm11
	#pragma reserve (asm,shared) ymm12
	#pragma reserve (asm,shared) ymm13
	#pragma reserve (asm,shared) ymm14
	#pragma reserve (asm,shared) ymm15

	#pragma reserve (asm,shared) zmm0
	#pragma reserve (asm,shared) zmm1
	#pragma reserve (asm,shared) zmm2
	#pragma reserve (asm,shared) zmm3
	#pragma reserve (asm,shared) zmm4
	#pragma reserve (asm,shared) zmm5
	#pragma reserve (asm,shared) zmm6
	#pragma reserve (asm,shared) zmm7
	#pragma reserve (asm,shared) zmm8
	#pragma reserve (asm,shared) zmm9
	#pragma reserve (asm,shared) zmm10
	#pragma reserve (asm,shared) zmm11
	#pragma reserve (asm,shared) zmm12
	#pragma reserve (asm,shared) zmm13
	#pragma reserve (asm,shared) zmm14
	#pragma reserve (asm,shared) zmm15
	#pragma reserve (asm,shared) zmm16
	#pragma reserve (asm,shared) zmm17
	#pragma reserve (asm,shared) zmm18
	#pragma reserve (asm,shared) zmm19
	#pragma reserve (asm,shared) zmm20
	#pragma reserve (asm,shared) zmm21
	#pragma reserve (asm,shared) zmm22
	#pragma reserve (asm,shared) zmm23
	#pragma reserve (asm,shared) zmm24
	#pragma reserve (asm,shared) zmm25
	#pragma reserve (asm,shared) zmm26
	#pragma reserve (asm,shared) zmm27
	#pragma reserve (asm,shared) zmm28
	#pragma reserve (asm,shared) zmm29
	#pragma reserve (asm,shared) zmm30
	#pragma reserve (asm,shared) zmm31

#endif
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: '#pragma reserve' statement to reserve backend keywords

Post by fxm »

Future new documentation page ?
or
Future complement (fourth syntax a little twisted) to the already existing '#pragma' documentation page ?
Syntax
  • #pragma option [ = value ]
    Or
    #pragma push ( option [, value ] )
    Or
    #pragma pop ( option )
    Or
    #pragma reserve [ (asm) | (shared) | (asm, shared) ] symbol
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: '#pragma reserve' statement to reserve backend keywords

Post by coderJeff »

fxm wrote:Future new documentation page ?
or
Future complement (fourth syntax a little twisted) to the already existing '#pragma' documentation page ?
I'm OK with either. For a new page maybe choose: "KeyPgPragmaReserve". This would work well if we add other #pragma's in future and could have their own links in the full and functional indexes and category pages.

For syntax, maybe:
#pragma reserve [ ( attributes... ) ] symbol

All of the following syntax are valid:

Code: Select all

#pragma reserve              symbol 
#pragma reserve ()           symbol
#pragma reserve (,,,,)       symbol
#pragma reserve (asm,shared) symbol
#pragma reserve (shared asm) symbol
Attribute list is optional.
Attributes must be enclosed by parentheses.
Attributes must be separated by comma or white space. (I will probably regret allowing white space some day...)
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: '#pragma reserve' statement to reserve backend keywords

Post by fxm »

OK for a new '#PRAGMA RESERVE' page.
It's easier to add (and so on for eventual future others '#PRAGMA ...').
coderJeff wrote: Attributes must be separated by comma or white space. (I will probably regret allowing white space some day...)
As the keyword documentation pages act as requirements for implementing their syntax and usage, I will not mention the white space as other possible delimiter for the 'asm' and 'shared' attributes.
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: '#pragma reserve' statement to reserve backend keywords

Post by fxm »

From the last fbc build of this night

Extract from changelog.txt (all new addings):
[added]
- fbc: '#pragma reserve (shared) symbol' statement will reserve a symbol name in the current scope / namespace
- fbc: '#pragma reserve (asm) symbol' statement will reserve an ASM symbol name in for all ASM statements and blocks
This suggests that only these two syntaxes are supported among the 4 described in all previous posts.
In addition, the first description is not coherent with the one of the posts above.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: '#pragma reserve' statement to reserve backend keywords

Post by coderJeff »

I well like that the documentation can develop in parallel with the compiler. The posts in this topic should be the most up to date and correct. And eventually the documentation will be the authority on what should be expected.

The primary objective is to create a mechanism using '#pragma reserve' to help deal with some symbols causing compile errors and run-time crashes. Once that is working, adding a list of symbols to fbc automatically will be trivial.

Closely related secondary objective are ASM words used in ASM blocks and statements.

Under the hood there are 2 symbol lists:
- '#pragma resereve (asm) symbol' is for adding symbols to the ASM keywords list. Any name on the ASM keywords list is emitted as-is to the backend when used in ASM blocks or ASM statements. Only some of the ASM keywords are documented on ASM wiki page.
- '#pragma reserve (shared) symbol' adds a symbol name to fbc's symbol table like other shared symbols but has no symbol class associated with it. Internally it has the 'reserved' symbol class which can not be used by user in any way except in 'defined(symbol)' expressions and can be removed from the symbol table with '#undef' statement. The main purpose is to reserve the name in the symbol table so no other conflicting symbol with the same name can be used.

Example as already given earlier of primary objective:

Code: Select all

#pragma reserve (shared) AX

'' duplicate definition
sub ax()
end sub
We should also expect non-conflicting names to be allowed:

Code: Select all

#pragma reserve (shared) AX

'' this is OK
type AX
	__ as integer
end type

dim x as AX
However, currently the check is not symmetric. Under the hood there are about 35 places in fbc code where duplicate definition checks are made and I have not visited them all.

Code: Select all

type AX
	__ as integer
end type

'' duplicate definition - but should probably be allowed.
#pragma reserve (shared) AX
The form of '#pragma reserve symbol' is currently a side effect of allowing the above. To be honest, I'm not sure of the usefulness of it.
The reserved symbol respects scopes:

Code: Select all

scope
	#pragma reserve symbol
	#if defined( symbol)
		#print "symbol is defined"
	#endif
end scope

#if not defined( symbol)
	#print "symbol is not defined"
#endif
And namespaces - but can cause compiler crashes ( which is probably related to some other namespace lookup bugs I found ):

Code: Select all

namespace ns
	#pragma reserve symbol
end namespace

#if defined( ns.symbol )
	#print "ns.symbol defined"
#endif

#if not defined( symbol )
	#print "symbol not defined"
#endif

'' import 'ns' in to the current namespace, including reserved symbols
using ns

#if defined( symbol )
	#print "symbol defined"
#endif

'' compiler crash
print ns.symbol
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: '#pragma reserve' statement to reserve backend keywords

Post by fxm »

My second remark is about the description of the first syntax in changelog.txt:
- fbc: '#pragma reserve (shared) symbol' statement will reserve a symbol name in the current scope / namespace
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: '#pragma reserve' statement to reserve backend keywords

Post by coderJeff »

Ah, I see. I will update changelog.txt next time I push changes.

- fbc: '#pragma reserve symbol' statement will reserve a symbol name in the current scope / namespace
- fbc: '#pragma reserve (shared) symbol' statement will reserve a symbol name in the shared scope (module or namespace)
- fbc: '#pragma reserve (asm) symbol' statement will reserve an ASM symbol name in all ASM statements and blocks

I have not tested '#pragma reserved (shared)' in a namespace where the symbol gets the 'shared' attribute.
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: '#pragma reserve' statement to reserve backend keywords

Post by fxm »

In any case, the same result than that fourth syntax a little weird '#pragma reserve (shared, asm) symbol' could still be obtained by chaining the 2 lines '#pragma reserve (shared) symbol' and '#pragma reserve (asm) symbol'.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: '#pragma reserve' statement to reserve backend keywords

Post by coderJeff »

fxm wrote:In any case, the same result than that fourth syntax a little weird '#pragma reserve (shared, asm) symbol' could still be obtained by chaining the 2 lines '#pragma reserve (shared) symbol' and '#pragma reserve (asm) symbol'.
True. I had it like this at one time in the development expecting the user to write the statements separately. But also I wanted to build in some flexibility for some unknown future problem to solve - #pragma reserve (public,extern,common,shared) symbol, or whatever.

I suppose I could make it so that '(asm)' must be on it's own since it is a separate symbol list within the compiler.
speedfixer
Posts: 606
Joined: Nov 28, 2012 1:27
Location: CA, USA moving to WA, USA
Contact:

Re: '#pragma reserve' statement to reserve backend keywords

Post by speedfixer »

Perhaps an 'errata' note list somewhere can capture this decision - at the present time <date> - that some syntax allowed but not described in the docs.

Then these allowances can be preserved for future reference and pointed to as explanations when someone stumbles over the allowed exception instead of crying "BUG!" or 'undocumented feature.'

david
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: '#pragma reserve' statement to reserve backend keywords

Post by fxm »

I think a short note at the end of the 'Description' paragraph is sufficient to simply cite the other syntaxes currently allowed by the compiler but not yet finalized as requirements (therefore to be used at own risk).
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: '#pragma reserve' statement to reserve backend keywords

Post by fxm »

All other preprocessor directives than '#pragma' are referenced by 'KeyPgPp...' (example 'KeyPgPpif' for '#if').
Only '#pragma' is referenced by 'KeyPg...' ('KeyPgPragma').
I do not know why !
What to do for '#pragma reserve' ?
Post Reply