fixed SP restoration.
[bugg-scheme-compiler.git] / src / c / rtemgr.c~
blob7e0b28d343c95cdb3f93b4098921b340480359de
1 #include "rtemgr.h"
2 #include "scheme.h"
3 #include "arch.h"
4 #include "assertions.h"
5 #include "strings.h"
7 /* Copies the enviroment vector currenv to a new vector of size
8    (currenv_size+1) starting from element #1.
9    Copies the arguments from the stack to element #0 of the new vector.
10    Returns the new env. vector.
12    @param currenv: points to the current enviroment vector
13    @param currenv_size: size of the current enviroment vector
15 int** extendEnviroment(int** currenv, int currenv_size)
17     int** newenv;   /* newenv: points to the new envoriment vector */
18     int ndx;        /* ndx: loop index */
20     ASSERT_ALWAYS(currenv_size>=0,"");
22     /* allocate new enviroment vector */
23     newenv = autoMalloc( sizeof(int) * (currenv_size + 1) );
25     /* copy current enviroment to new enviroment */
26     ndx = currenv_size;
27 Lfor1:
28     if (ndx<=0) goto LendFor1;
29     newenv[ndx] = currenv[ndx-1];
30     --ndx;
31     goto Lfor1;
32 LendFor1:
33     /* copy arguments from stack to new enviroment vector (extend env.) */
34     if (currenv_size<=0) goto LendExtend1; /* no activation frame at all */
35     if (ST_ARG_COUNT()<=0) goto LendExtend1; /* no args in act. frame */
36     newenv[0] = autoMalloc( sizeof(int) * ST_ARG_COUNT() );
37     ndx = 0;
38 Lfor2:
39     if (ndx>=ST_ARG_COUNT()) goto LendFor2;
40     newenv[0][ndx] = ST_ARG(ndx);
41     ++ndx;
42     goto Lfor2;
43 LendFor2:
44 LendExtend1:
46     return newenv;
49 /* Prepares the stack for a tail-call.
50    Overrides the last activation frame with the current one,
51    fixes sp,fp
53 void shiftActFrmDown()
55     int low;       /* lowest address of the activation frame (included) */
56     int high;      /* highest address of the activation frame (included) */
57     int dest_low;  /* lowest address where to put the activation frame */
59     int old_fp = ST_OLDFP();
61     /* Shift activation frame down the stack */
62     low = fp;
63     high = sp-1;
64     dest_low = old_fp;
66     while (low <= high) {
67         stack[dest_low] = stack[low];
68         ++dest_low;
69         ++low;
70     }
72     /* Fix sp,fp */
73     fp = old_fp;
74     sp = dest_low;
77 /* Shifts the elements in the stack upwards.
79    @param pos: index of the first element to shift
80    @param amount: the number of elements to shift up each element by
82    Shifts up each element between `pos` and sp (inclusive) by `amount`.
84 void shiftStackUp(int pos, unsigned int amount)
86     int i;
88     /* shift elements upwards */
89     for (i=sp-1; i>=pos; --i) {
90         stack[i+amount] = stack[i];
91     }
93     /* fix sp,fp */
94     sp = sp + amount;
95     fp = fp + amount;
98 /* Shifts the elements in the stack downwards.
100    @param pos: index of the first element to shift
101    @param amount: the number of elements to shift down each element by
103    Shifts down each element between `pos` and sp (inclusive) by `amount`.
105 void shiftStackDown(int pos, unsigned int amount)
107     int i;
109     /* shift elements downwards */
110     for (i=pos; i<=sp-1; ++i) {
111         stack[i-amount] = stack[i];
112     }
114     /* fix sp,fp */
115     sp = sp - amount;
116     fp = fp - amount;
119 /* Prepares the stack for an application of lambda-optional.
121    @param formalParams: the number of formal parameters the lambda
122           expects, including the optional one.
124    Moves the optional parameters to a list in the heap.
126 void prepareStackForAbsOpt(int formalParams)
128     int actualParams = ST_ARG_COUNT();
129     int optionalsUsed = actualParams-(formalParams-1);
131     ASSERT_ALWAYS( optionalsUsed>=0, "" );
133     if (optionalsUsed==0) {
134         /* if the optional parameter was not used, initialize it to an
135            empty list: */
137         shiftStackUp( ST_OLDFP(), 1 ); /* make room for the optional param */
138         stack[ ST_OLDFP() ] = (int)makeSchemeNil(); /* set it to () */
139     }
140     else {
141         /* if the optional parameters were used, move them to a list
142            on the heap: */
144         SchemeObject* opt;  /* the list of optional params */
145         int lastOptional;   /* last opt. param. (lowest index) */
146         int firstOptional;  /* first opt. param. (highest index) */
147         int i;
149         /* copy optional params to a list on the heap */
150         opt = makeSchemeNil();
151         lastOptional = ST_OLDFP();
152         firstOptional = lastOptional + (optionalsUsed-1);
154         for (i=lastOptional; i<=firstOptional; ++i) {
155             opt = makeSchemePair( (SchemeObject*)(stack[i]), opt );
156         }
158         /* override all but one optional */
159         shiftStackDown( firstOptional, optionalsUsed-1 );
161         /* the last parameter is a pointer to the new list */
162         stack[ ST_OLDFP() ] = (int)opt;
163     }
165     /* fix actual arguments number */
166     ST_ARG_COUNT() = formalParams;