BP.LET / SB.PUTP

Anything QL Software or Programming Related.
Post Reply
Silvester
Gold Card
Posts: 436
Joined: Thu Dec 12, 2013 10:14 am
Location: UK

BP.LET / SB.PUTP

Post by Silvester »

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.


David
User avatar
pjw
QL Wafer Drive
Posts: 1608
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: BP.LET / SB.PUTP

Post by pjw »

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
..
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..

Per


Per
I love long walks, especially when they are taken by people who annoy me.
- Fred Allen
Silvester
Gold Card
Posts: 436
Joined: Thu Dec 12, 2013 10:14 am
Location: UK

Re: BP.LET / SB.PUTP

Post by Silvester »

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:

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.
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.
Attachments
nt.zip
(1.72 KiB) Downloaded 113 times


David
Post Reply