Odd thing found when implementing function which returns changed parameters.
I soon discovered if you don't check name table that passed parameter is of correct type you can cause crash sometime:
MYFUNC(X%) : REMark is OK, but
MYFUNC(3) : REMark is not
Although both pass CA.GTINT as valid parameter, BP.LET with new value appears OK (no err_bp) but SuperBASIC causes memory corruption (eventually, if not immediately). I assumed the temporary name table entry for passed parameter (literal) would be discarded.
Solution of course, is to check name table that parameter passed is strictly an integer variable ($02x3) on entry (else reject) and then BP.LET is OK for system. So even
MYFUNC(X%) : REMark is rejected if X% unset, or
MYFUNC(X%+1) : REMark is rejected (integer expression)
But oddly, this is not rejected
MYFUNC(X%+Z%) : REMark where X% and Z% are set variables
It doesn't appear to cause same problem, even though strictly it is an integer expression (type $01x3). X% or Z% are not changed on return. The name table entry for X%+Z% is given as $02x3 !
BTW recently found nasty long time bug in SMSQ:
DIM a$(32767) : REMark is accepted (QDOS/Minerva only accepts <=32766)
a$='hello' : REMark bad, bad, bad!
Causes instant memory corruption.
BP.LET / SB.PUTP
Re: BP.LET / SB.PUTP
Could you show what youre doing in your function here? I have written a number of keywords using sb.putp, so I suspect I know whats going on, but to be sure Id prefer some more detail..Silvester wrote:Odd thing found when implementing function which returns changed parameters.
I soon discovered if you don't check name table that passed parameter is of correct type you can cause crash sometime:
MYFUNC(X%) : REMark is OK, but
MYFUNC(3) : REMark is not
..
Per
Per
I love long walks, especially when they are taken by people who annoy me.
- Fred Allen
I love long walks, especially when they are taken by people who annoy me.
- Fred Allen
Re: BP.LET / SB.PUTP
I had a closer look and the memory corruption was due to bad RI stack pointer (too little stacked, too much removed).
ie. MYFUNC(3)
SMSQ passes the 3 as a floating point number. CA.GTINT is quite happy to accept float as integer, but BP.LET is not (it expected a 6 byte float on RI stack, not the 2 byte integer given). But as mentioned this was easily solved by doing a check on parameter type beforehand and rejecting float.
I did a little test on SMSQ, Minerva and QDOS parameter types:
None pass expression type (01x?), so there appears to be no easy way to reject expressions like X%+Z%.
BTW both QDOS and Minerva calls to CA.GTINT etc, alter top byte of name table entry (from 02xx to 01xx). SMSQ leaves them unchanged. So any type check might need to be done before calling CA.GTxxx
The need to be pedantic on parameters was because I've done a PIC scaling function which I wanted to be able to pass window X% & Y% parameters. To maintain image aspect ratio I could then return appropriate changes to either X% or Y% as required to fit. Thus I wanted to reject (1024,768) etc as parameters.
Attached function I used which simply returns name table entry for parameter type.
ie. MYFUNC(3)
SMSQ passes the 3 as a floating point number. CA.GTINT is quite happy to accept float as integer, but BP.LET is not (it expected a 6 byte float on RI stack, not the 2 byte integer given). But as mentioned this was easily solved by doing a check on parameter type beforehand and rejecting float.
I did a little test on SMSQ, Minerva and QDOS parameter types:
Code: Select all
Parameter passed SMSQ QDOS Minerva
-----------------------+-------+-------+-------
2 02x2 02x2 02x3
2+3 02x2 02x2 02x3
X% (X% unset) 00x3 err_xp err_xp
X%+2 (X% unset) 02x2 err_xp err_xp
X% (X% set) 02x3 02x3 02x3 <<< target
X%+3 02x2 02x2 02x3
X%+Z% (Z% unset) 02x3 err_xp err_xp
X%+Z% (Z% set) 02x3 02x2 02x3
X%+INT(5) 02x3 02x2 02x2(!)
X%+5 02x2 02x2 02x3
where: 00x3 undefined integer
02x2 float variable
02x3 integer variable
(x specifies parameter separator)
err_xp means SuperBASIC rejected parameter with
'error in expression' before calling function.
BTW both QDOS and Minerva calls to CA.GTINT etc, alter top byte of name table entry (from 02xx to 01xx). SMSQ leaves them unchanged. So any type check might need to be done before calling CA.GTxxx
The need to be pedantic on parameters was because I've done a PIC scaling function which I wanted to be able to pass window X% & Y% parameters. To maintain image aspect ratio I could then return appropriate changes to either X% or Y% as required to fit. Thus I wanted to reject (1024,768) etc as parameters.
Attached function I used which simply returns name table entry for parameter type.
- Attachments
-
- nt.zip
- (1.72 KiB) Downloaded 113 times
David