Archive: Stack metafunctions


Stack metafunctions
  I've now written several dozen functions, and still, I haven't got the hand of the stack manipulation...

I was wondering, does anyone have any general "recipe" to start and finish a function and ensure that the state of the stack and $0-$R9 variables are unchanged at the end of the function (with the exception of the results that should end up on top of the stack).

So, if you know that
- The function takes x parameters/arguments
- The function will (internally) require y variables
- The function returns z results
what would be the general recipe?

So far, I've managed to get the first two constraints, but am failing to get the 3rd one working. I'd like to end up with results z_1,z_2,...,z_n in that order on the stack...
What I've got at the moment is z_1,z_n,z_n-1,...,z_2

Here is my code:




Name "Stack Test"

>OutFile "StackTest.exe"

>LoadLanguageFile "${NSISDIR}\Contrib\Language files\English.nlf"


>!macro OpenStack _Arg1 _Arg2 _Arg3 _Res1 _Res2 _Res3 _Res4 _Res5
Push${_Arg1}
Push ${_Arg2}
Push ${_Arg3}
Call OpenStackFunction
Pop${_Res1}
Pop ${_Res2}
Pop ${_Res3}
Pop ${_Res4}
Pop ${_Res5}
!macroend


>Function OpenStackFunction

; get parameters (3),
;so that they get into $0, $1, $2
Exch 2
Exch$0
Exch 2
Exch 1
Exch$1
Exch 1
Exch$2

; prepare rest of the internal variables (4 for 7 in total)
Push $3
StrCpy$3 ""
Push $4
StrCpy$4 ""
Push $5
StrCpy$5 ""
Push $6
StrCpy$6 ""

; Core of the function
; ... Dosomething ...

;Copy results (5) to $0 to $n
StrCpy$0 "result-line1"
StrCpy $1 "result-line2"
StrCpy $2 "result-line3"
StrCpy $3 "result-line4"
StrCpy $4 "result-line5"

; Restore registers that dont hold results
Pop$6
Pop$5

; Push results on stack in right order
; and recover registers to initial state

Exch$4
Exch 1
Exch$3
Exch 2
Exch$2
Exch 3
Exch$1
Exch 4
Exch$0

FunctionEnd

Section ""
>SectionEnd

>Function .onInit

; create a state for testing
Push "stack3"
Push "stack2"
Push "stack1"
StrCpy $0 "ex-r0"
StrCpy $1 "ex-r1"
StrCpy $2 "ex-r2"
StrCpy $3 "ex-r3"
StrCpy $4 "ex-r4"
StrCpy $5 "ex-r5"
StrCpy $6 "ex-r6"
!insertmacro OpenStack "arg1" "arg2" "arg3" $R1 $R2 $R3 $R4 $R5
; display results
MessageBox MB_OK "R1=$R1 - R2=$R2 - R3=$R3 - R4=$R4 - R5=$R5"

>FunctionEnd
>

I am currently working on a header file, which will care about passing and getting parameters before and after the function call.

The header will have a macro called InstallFunction which will generate the call interface dynamically.

Can you wait until monday ?


Will it be able to cope with functions that have to return more than one value to the stack?


To put it clear: InstallFunction will only do the stuff before and after call of the function for up to ten parameters.

Maybe I misunderstood you, or do you need a solution which does the prologue and epilogue INSIDE the function body ?


StrReplace pushes 3 items but only returns 1. To prevent the contents of the other 2 variables being removed, it Pushes them onto the stack before calling the function...

http://nsis.sourceforge.net/StrReplace_v4

-Stu


try nfUtils.nsh !
  Have a look at this thread:

http://forums.winamp.com/showthread.php?threadid=249699

${nfu.Function} and ${nfu.FunctionEnd} are designed to handle the passing of parameters inside the functionbody.

${nfu.!InstallFunction} will generate macros, which call a function and pass parameters before and after the call.