The goal is to make the routines reentrant and to fill in any structures at run time and not compile time. I have chosen to fix this in a way similar to how MASM (the Microsoft Macro Assembler), and most other assemblers and compilers for that matter, handles it. MASM has a directive called LOCAL which creates a "stack frame" for handling procedures. A "stack frame" is a block of locations on the stack that can be addressed like a structure in memory. The advantage, of course, is that it is reentrant and doesn't require a fixed memory address that could change.
The basic idea for my implementation is that the Win32Forth words
SP@ and SP! can be used to return addresses on the stack
and to restore the stack after a stack frame structure is no longer needed.
For example, suppose we want to get the rectangle for a window. We do this
with a call to GetWindowRect. This function requires an address of a RECT
structure and the handle of a window. The following code will do this:
\ Using a structure in memory (assume hWnd returns the window handle) CREATE 'RECT 0 , \ left 0 , \ top 0 , \ right 0 , \ bottom 'RECT REL>ABS hWnd Call GetWindowRect DROP
\ Using a structure on the stack (assume hWnd returns the window handle)
0 0 0 0 \ create room for RECT results on the stack
SP@ REL>ABS \ returns absolute address of the
\ 4 cells we just initialized
hWnd Call GetWindowRect DROP \ this fills the stack frame
\ which now contains ( bottom right top left)
In the updated class libraries I have defined a word called sFrame
which takes as an argument the number of cells you want to reserve on the
stack and returns the address of the start of this structure. In order to
keep the stack properly aligned, only cell counts should be added. This
shouldn't be a limit in practice since the Win32 structures also need to be
aligned on cell boundries. The above example would now look like:
\ Using sFrame (assume hWnd returns the window handle)
4 sFrame \ create room for RECT results on the stack
REL>ABS \ returns absolute address of the
\ 4 cells we just initialized
hWnd Call GetWindowRect DROP \ this fills the stack frame
\ which now contains ( bottom right top left)
I have updated the class libraries and put them on a new
page while I debug things. Everything seems to be
working, but ya' never know. For now I'll keep the
original versions around.