programming tools for Windows applications development
  Home  |   SwiftForth Archive  |   SwiftX Archive  |

Re: Run-time stack balance verification

From: Rick VanNorman <rvn_at_forth.com>
Date: Fri, 17 Dec 1999 08:23:55 -0800

Charles,

The following code will implement a simple version of your requirements.
You might need to pretty it up a bit, add a few features.

Hope it helps,

Rick

*********** REPLY SEPARATOR ***********

>From: "Charles Melice" <mail_at_forthcad.com>
>
>Is Anybody can propose here ideas ( or a solution ) to have a reliable
>system to check the stack balance, optionally and at run-time ?
>

*********** CODE SEPARATOR ***********

OPTIONAL BALANCECHECK Run-time stack balance checking.

{ ====================================================================
(C) Copyright 1999 FORTH, Inc. www.forth.com Rick VanNorman

Run time stack checking. SwiftForth specific, requires intimate
carnal knowledge of the compiler!

This code implements a run-time stack balance checker on a per-word
basis. It adds overhead to program execution. There are very strict
requirements for the stack format:
1. each parameter must be delimited by spaces
2. the separator between input and output parameters must be
   exactly two dashes
3. variable numbers of inputs and outputs are _NOT_ supported.
==================================================================== }

THROW#
   S" Local stack underflow" >THROW ENUM IOR_LOCALUNDER
   S" Local stack overflow" >THROW ENUM IOR_LOCALOVER
TO THROW#

LABEL CONTINUE \ this returns to my caller with a
   EAX JMP \ frame saved on the return stack
   END-CODE \

CODE CHECKER ( cells -- )
   EAX POP \ true return address
   EBX PUSH \ save on return stack
   POP(EBX) \
   EBP 0 [ESP] ADD \ calculate stack final balance
   CONTINUE CALL \ return to my caller. on his exit we come back
   EAX POP \ <-- here and check the stack balance
   EBP EAX CMP 0= IF \ they match
      RET THEN \ so we exit and are done
   < IF \ if ebp was less than expected
      IOR_LOCALUNDER # EBX MOV
   ELSE
      IOR_LOCALOVER # EBX MOV
   THEN
   ] THROW [
   RET END-CODE

: BALANCE ( -- n ) 4 0 \ i b \ increment balance
   [CHAR] ) PARSE ( addr len) \ i b a n \ and string
   2DUP ARGC 0 ?DO \ i b a n
      2DUP I ARGV 2SWAP 2>R \ i b a n \ nth parameter
      S" --" COMPARE IF \ i b \ parameter not "--"
         OVER + \ i b \ increment balance
      ELSE \ i b \ found "--"
         SWAP NEGATE SWAP \ i b \ change increment
      THEN 2R> \ i b a n \ restore string
   LOOP \ i b a n
   2DROP NIP ; \ b \ return only balance

: FIRST? ( -- flag ) \ true if no code has yet been compiled
   HERE LAST 2 CELLS + @ = ;

: (
   STATE @ IF FIRST? IF \ compiling, and first token after colon
         BALANCE POSTPONE LITERAL \ push balance as a literal
         POSTPONE CHECKER EXIT \ then compile the checker
   THEN THEN POSTPONE ( ; IMMEDIATE \ else, do old paren

: G1 ( a b -- c ) + ;
: G2 ( a -- a a ) DUP ;
: G3 ( a b -- a b ) + DUP ;
: G4 ( -- ) 5 4 * DROP ;

: B1 ( a b -- c ) ; \ too much
: B2 ( a b -- c ) 2DROP ; \ too little
: B3 ( a b -- c ) DUP ; \ too much

.
Received on Fri Dec 17 1999 - 08:23:55 PST

This archive was generated by hypermail 2.2.0 : Thu Nov 20 2008 - 03:04:26 PST