aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c170
1 files changed, 81 insertions, 89 deletions
diff --git a/ldo.c b/ldo.c
index f869f82a..94c2bf3a 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.7 1997/11/04 15:27:53 roberto Exp roberto $ 2** $Id: ldo.c,v 1.8 1997/11/07 15:09:49 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -16,6 +16,7 @@
16#include "lmem.h" 16#include "lmem.h"
17#include "lobject.h" 17#include "lobject.h"
18#include "lparser.h" 18#include "lparser.h"
19#include "lstate.h"
19#include "ltm.h" 20#include "ltm.h"
20#include "lua.h" 21#include "lua.h"
21#include "luadebug.h" 22#include "luadebug.h"
@@ -30,14 +31,6 @@
30#endif 31#endif
31 32
32 33
33struct Stack luaD_stack;
34
35
36struct C_Lua_Stack luaD_Cstack = {0, 0, 0};
37
38static jmp_buf *errorJmp = NULL; /* current error recover point */
39
40
41 34
42/* 35/*
43** Error messages 36** Error messages
@@ -50,8 +43,6 @@ static void stderrorim (void)
50 fprintf(stderr, "lua error: %s\n", lua_getstring(s)); 43 fprintf(stderr, "lua error: %s\n", lua_getstring(s));
51} 44}
52 45
53TObject luaD_errorim;
54
55 46
56static void initCfunc (TObject *o, lua_CFunction f) 47static void initCfunc (TObject *o, lua_CFunction f)
57{ 48{
@@ -67,24 +58,25 @@ static void initCfunc (TObject *o, lua_CFunction f)
67 58
68void luaD_init (void) 59void luaD_init (void)
69{ 60{
70 luaD_stack.stack = luaM_newvector(INIT_STACK_SIZE, TObject); 61 L->stacklimit = STACK_LIMIT;
71 luaD_stack.top = luaD_stack.stack; 62 L->stack.stack = luaM_newvector(INIT_STACK_SIZE, TObject);
72 luaD_stack.last = luaD_stack.stack+(INIT_STACK_SIZE-1); 63 L->stack.top = L->stack.stack;
73 initCfunc(&luaD_errorim, stderrorim); 64 L->stack.last = L->stack.stack+(INIT_STACK_SIZE-1);
65 initCfunc(&L->errorim, stderrorim);
74} 66}
75 67
76 68
77void luaD_checkstack (int n) 69void luaD_checkstack (int n)
78{ 70{
79 if (luaD_stack.last-luaD_stack.top <= n) { 71 if (L->stack.last-L->stack.top <= n) {
80 static int limit = STACK_LIMIT; 72 StkId top = L->stack.top-L->stack.stack;
81 StkId top = luaD_stack.top-luaD_stack.stack; 73 int stacksize = (L->stack.last-L->stack.stack)+1+STACK_EXTRA+n;
82 int stacksize = (luaD_stack.last-luaD_stack.stack)+1+STACK_EXTRA+n; 74 L->stack.stack = luaM_reallocvector(L->stack.stack, stacksize,TObject);
83 luaD_stack.stack = luaM_reallocvector(luaD_stack.stack, stacksize,TObject); 75 L->stack.last = L->stack.stack+(stacksize-1);
84 luaD_stack.last = luaD_stack.stack+(stacksize-1); 76 L->stack.top = L->stack.stack + top;
85 luaD_stack.top = luaD_stack.stack + top; 77 if (stacksize >= L->stacklimit) {
86 if (stacksize >= limit) { 78 /* extra space to run error handler */
87 limit = stacksize+STACK_EXTRA; /* extra space to run error handler */ 79 L->stacklimit = stacksize+STACK_EXTRA;
88 if (lua_stackedfunction(100) == LUA_NOOBJECT) { 80 if (lua_stackedfunction(100) == LUA_NOOBJECT) {
89 /* less than 100 functions on the stack: cannot be recursive loop */ 81 /* less than 100 functions on the stack: cannot be recursive loop */
90 lua_error("Lua2C - C2Lua overflow"); 82 lua_error("Lua2C - C2Lua overflow");
@@ -101,80 +93,80 @@ void luaD_checkstack (int n)
101*/ 93*/
102void luaD_adjusttop (StkId newtop) 94void luaD_adjusttop (StkId newtop)
103{ 95{
104 int diff = newtop-(luaD_stack.top-luaD_stack.stack); 96 int diff = newtop-(L->stack.top-L->stack.stack);
105 if (diff <= 0) 97 if (diff <= 0)
106 luaD_stack.top += diff; 98 L->stack.top += diff;
107 else { 99 else {
108 luaD_checkstack(diff); 100 luaD_checkstack(diff);
109 while (diff--) 101 while (diff--)
110 ttype(luaD_stack.top++) = LUA_T_NIL; 102 ttype(L->stack.top++) = LUA_T_NIL;
111 } 103 }
112} 104}
113 105
114 106
115/* 107/*
116** Open a hole below "nelems" from the luaD_stack.top. 108** Open a hole below "nelems" from the L->stack.top.
117*/ 109*/
118void luaD_openstack (int nelems) 110void luaD_openstack (int nelems)
119{ 111{
120 int i; 112 int i;
121 for (i=0; i<nelems; i++) 113 for (i=0; i<nelems; i++)
122 *(luaD_stack.top-i) = *(luaD_stack.top-i-1); 114 *(L->stack.top-i) = *(L->stack.top-i-1);
123 incr_top; 115 incr_top;
124} 116}
125 117
126 118
127void luaD_lineHook (int line) 119void luaD_lineHook (int line)
128{ 120{
129 struct C_Lua_Stack oldCLS = luaD_Cstack; 121 struct C_Lua_Stack oldCLS = L->Cstack;
130 StkId old_top = luaD_Cstack.lua2C = luaD_Cstack.base = luaD_stack.top-luaD_stack.stack; 122 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
131 luaD_Cstack.num = 0; 123 L->Cstack.num = 0;
132 (*lua_linehook)(line); 124 (*lua_linehook)(line);
133 luaD_stack.top = luaD_stack.stack+old_top; 125 L->stack.top = L->stack.stack+old_top;
134 luaD_Cstack = oldCLS; 126 L->Cstack = oldCLS;
135} 127}
136 128
137 129
138void luaD_callHook (StkId base, lua_Type type, int isreturn) 130void luaD_callHook (StkId base, lua_Type type, int isreturn)
139{ 131{
140 struct C_Lua_Stack oldCLS = luaD_Cstack; 132 struct C_Lua_Stack oldCLS = L->Cstack;
141 StkId old_top = luaD_Cstack.lua2C = luaD_Cstack.base = luaD_stack.top-luaD_stack.stack; 133 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
142 luaD_Cstack.num = 0; 134 L->Cstack.num = 0;
143 if (isreturn) 135 if (isreturn)
144 (*lua_callhook)(LUA_NOOBJECT, "(return)", 0); 136 (*lua_callhook)(LUA_NOOBJECT, "(return)", 0);
145 else { 137 else {
146 TObject *f = luaD_stack.stack+base-1; 138 TObject *f = L->stack.stack+base-1;
147 if (type == LUA_T_PROTO) 139 if (type == LUA_T_PROTO)
148 (*lua_callhook)(Ref(f), tfvalue(protovalue(f))->fileName->str, 140 (*lua_callhook)(Ref(f), tfvalue(protovalue(f))->fileName->str,
149 tfvalue(protovalue(f))->lineDefined); 141 tfvalue(protovalue(f))->lineDefined);
150 else 142 else
151 (*lua_callhook)(Ref(f), "(C)", -1); 143 (*lua_callhook)(Ref(f), "(C)", -1);
152 } 144 }
153 luaD_stack.top = luaD_stack.stack+old_top; 145 L->stack.top = L->stack.stack+old_top;
154 luaD_Cstack = oldCLS; 146 L->Cstack = oldCLS;
155} 147}
156 148
157 149
158/* 150/*
159** Call a C function. luaD_Cstack.base will point to the top of the stack, 151** Call a C function. L->Cstack.base will point to the top of the stack,
160** and luaD_Cstack.num is the number of parameters. Returns an index 152** and L->Cstack.num is the number of parameters. Returns an index
161** to the first result from C. 153** to the first result from C.
162*/ 154*/
163static StkId callC (lua_CFunction func, StkId base) 155static StkId callC (lua_CFunction func, StkId base)
164{ 156{
165 struct C_Lua_Stack oldCLS = luaD_Cstack; 157 struct C_Lua_Stack oldCLS = L->Cstack;
166 StkId firstResult; 158 StkId firstResult;
167 luaD_Cstack.num = (luaD_stack.top-luaD_stack.stack) - base; 159 L->Cstack.num = (L->stack.top-L->stack.stack) - base;
168 /* incorporate parameters on the luaD_stack.stack */ 160 /* incorporate parameters on the L->stack.stack */
169 luaD_Cstack.lua2C = base; 161 L->Cstack.lua2C = base;
170 luaD_Cstack.base = base+luaD_Cstack.num; /* == top-stack */ 162 L->Cstack.base = base+L->Cstack.num; /* == top-stack */
171 if (lua_callhook) 163 if (lua_callhook)
172 luaD_callHook(base, LUA_T_CPROTO, 0); 164 luaD_callHook(base, LUA_T_CPROTO, 0);
173 (*func)(); 165 (*func)();
174 if (lua_callhook) /* func may have changed lua_callhook */ 166 if (lua_callhook) /* func may have changed lua_callhook */
175 luaD_callHook(base, LUA_T_CPROTO, 1); 167 luaD_callHook(base, LUA_T_CPROTO, 1);
176 firstResult = luaD_Cstack.base; 168 firstResult = L->Cstack.base;
177 luaD_Cstack = oldCLS; 169 L->Cstack = oldCLS;
178 return firstResult; 170 return firstResult;
179} 171}
180 172
@@ -182,21 +174,21 @@ static StkId callC (lua_CFunction func, StkId base)
182void luaD_callTM (TObject *f, int nParams, int nResults) 174void luaD_callTM (TObject *f, int nParams, int nResults)
183{ 175{
184 luaD_openstack(nParams); 176 luaD_openstack(nParams);
185 *(luaD_stack.top-nParams-1) = *f; 177 *(L->stack.top-nParams-1) = *f;
186 luaD_call((luaD_stack.top-luaD_stack.stack)-nParams, nResults); 178 luaD_call((L->stack.top-L->stack.stack)-nParams, nResults);
187} 179}
188 180
189 181
190/* 182/*
191** Call a function (C or Lua). The parameters must be on the luaD_stack.stack, 183** Call a function (C or Lua). The parameters must be on the L->stack.stack,
192** between [luaD_stack.stack+base,luaD_stack.top). The function to be called is at luaD_stack.stack+base-1. 184** between [L->stack.stack+base,L->stack.top). The function to be called is at L->stack.stack+base-1.
193** When returns, the results are on the luaD_stack.stack, between [luaD_stack.stack+base-1,luaD_stack.top). 185** When returns, the results are on the L->stack.stack, between [L->stack.stack+base-1,L->stack.top).
194** The number of results is nResults, unless nResults=MULT_RET. 186** The number of results is nResults, unless nResults=MULT_RET.
195*/ 187*/
196void luaD_call (StkId base, int nResults) 188void luaD_call (StkId base, int nResults)
197{ 189{
198 StkId firstResult; 190 StkId firstResult;
199 TObject *func = luaD_stack.stack+base-1; 191 TObject *func = L->stack.stack+base-1;
200 int i; 192 int i;
201 if (ttype(func) == LUA_T_FUNCTION) { 193 if (ttype(func) == LUA_T_FUNCTION) {
202 TObject *proto = protovalue(func); 194 TObject *proto = protovalue(func);
@@ -209,7 +201,7 @@ void luaD_call (StkId base, int nResults)
209 TObject *im = luaT_getimbyObj(func, IM_FUNCTION); 201 TObject *im = luaT_getimbyObj(func, IM_FUNCTION);
210 if (ttype(im) == LUA_T_NIL) 202 if (ttype(im) == LUA_T_NIL)
211 lua_error("call expression not a function"); 203 lua_error("call expression not a function");
212 luaD_callTM(im, (luaD_stack.top-luaD_stack.stack)-(base-1), nResults); 204 luaD_callTM(im, (L->stack.top-L->stack.stack)-(base-1), nResults);
213 return; 205 return;
214 } 206 }
215 /* adjust the number of results */ 207 /* adjust the number of results */
@@ -217,29 +209,29 @@ void luaD_call (StkId base, int nResults)
217 luaD_adjusttop(firstResult+nResults); 209 luaD_adjusttop(firstResult+nResults);
218 /* move results to base-1 (to erase parameters and function) */ 210 /* move results to base-1 (to erase parameters and function) */
219 base--; 211 base--;
220 nResults = luaD_stack.top - (luaD_stack.stack+firstResult); /* actual number of results */ 212 nResults = L->stack.top - (L->stack.stack+firstResult); /* actual number of results */
221 for (i=0; i<nResults; i++) 213 for (i=0; i<nResults; i++)
222 *(luaD_stack.stack+base+i) = *(luaD_stack.stack+firstResult+i); 214 *(L->stack.stack+base+i) = *(L->stack.stack+firstResult+i);
223 luaD_stack.top -= firstResult-base; 215 L->stack.top -= firstResult-base;
224} 216}
225 217
226 218
227 219
228/* 220/*
229** Traverse all objects on luaD_stack.stack 221** Traverse all objects on L->stack.stack
230*/ 222*/
231void luaD_travstack (int (*fn)(TObject *)) 223void luaD_travstack (int (*fn)(TObject *))
232{ 224{
233 StkId i; 225 StkId i;
234 for (i = (luaD_stack.top-1)-luaD_stack.stack; i>=0; i--) 226 for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--)
235 fn (luaD_stack.stack+i); 227 fn (L->stack.stack+i);
236} 228}
237 229
238 230
239 231
240static void message (char *s) 232static void message (char *s)
241{ 233{
242 TObject im = luaD_errorim; 234 TObject im = L->errorim;
243 if (ttype(&im) != LUA_T_NIL) { 235 if (ttype(&im) != LUA_T_NIL) {
244 lua_pushstring(s); 236 lua_pushstring(s);
245 luaD_callTM(&im, 1, 0); 237 luaD_callTM(&im, 1, 0);
@@ -252,8 +244,8 @@ static void message (char *s)
252void lua_error (char *s) 244void lua_error (char *s)
253{ 245{
254 if (s) message(s); 246 if (s) message(s);
255 if (errorJmp) 247 if (L->errorJmp)
256 longjmp(*errorJmp, 1); 248 longjmp(*((jmp_buf *)L->errorJmp), 1);
257 else { 249 else {
258 fprintf (stderr, "lua: exit(1). Unable to recover\n"); 250 fprintf (stderr, "lua: exit(1). Unable to recover\n");
259 exit(1); 251 exit(1);
@@ -261,40 +253,40 @@ void lua_error (char *s)
261} 253}
262 254
263/* 255/*
264** Call the function at luaD_Cstack.base, and incorporate results on 256** Call the function at L->Cstack.base, and incorporate results on
265** the Lua2C structure. 257** the Lua2C structure.
266*/ 258*/
267static void do_callinc (int nResults) 259static void do_callinc (int nResults)
268{ 260{
269 StkId base = luaD_Cstack.base; 261 StkId base = L->Cstack.base;
270 luaD_call(base+1, nResults); 262 luaD_call(base+1, nResults);
271 luaD_Cstack.lua2C = base; /* position of the luaM_new results */ 263 L->Cstack.lua2C = base; /* position of the luaM_new results */
272 luaD_Cstack.num = (luaD_stack.top-luaD_stack.stack) - base; /* number of results */ 264 L->Cstack.num = (L->stack.top-L->stack.stack) - base; /* number of results */
273 luaD_Cstack.base = base + luaD_Cstack.num; /* incorporate results on luaD_stack.stack */ 265 L->Cstack.base = base + L->Cstack.num; /* incorporate results on L->stack.stack */
274} 266}
275 267
276 268
277/* 269/*
278** Execute a protected call. Assumes that function is at luaD_Cstack.base and 270** Execute a protected call. Assumes that function is at L->Cstack.base and
279** parameters are on top of it. Leave nResults on the stack. 271** parameters are on top of it. Leave nResults on the stack.
280*/ 272*/
281int luaD_protectedrun (int nResults) 273int luaD_protectedrun (int nResults)
282{ 274{
283 jmp_buf myErrorJmp; 275 jmp_buf myErrorJmp;
284 int status; 276 int status;
285 struct C_Lua_Stack oldCLS = luaD_Cstack; 277 struct C_Lua_Stack oldCLS = L->Cstack;
286 jmp_buf *oldErr = errorJmp; 278 jmp_buf *oldErr = L->errorJmp;
287 errorJmp = &myErrorJmp; 279 L->errorJmp = &myErrorJmp;
288 if (setjmp(myErrorJmp) == 0) { 280 if (setjmp(myErrorJmp) == 0) {
289 do_callinc(nResults); 281 do_callinc(nResults);
290 status = 0; 282 status = 0;
291 } 283 }
292 else { /* an error occurred: restore luaD_Cstack and luaD_stack.top */ 284 else { /* an error occurred: restore L->Cstack and L->stack.top */
293 luaD_Cstack = oldCLS; 285 L->Cstack = oldCLS;
294 luaD_stack.top = luaD_stack.stack+luaD_Cstack.base; 286 L->stack.top = L->stack.stack+L->Cstack.base;
295 status = 1; 287 status = 1;
296 } 288 }
297 errorJmp = oldErr; 289 L->errorJmp = oldErr;
298 return status; 290 return status;
299} 291}
300 292
@@ -307,8 +299,8 @@ static int protectedparser (ZIO *z, char *chunkname, int bin)
307 int status; 299 int status;
308 TProtoFunc *tf; 300 TProtoFunc *tf;
309 jmp_buf myErrorJmp; 301 jmp_buf myErrorJmp;
310 jmp_buf *oldErr = errorJmp; 302 jmp_buf *oldErr = L->errorJmp;
311 errorJmp = &myErrorJmp; 303 L->errorJmp = &myErrorJmp;
312 if (setjmp(myErrorJmp) == 0) { 304 if (setjmp(myErrorJmp) == 0) {
313 tf = bin ? luaU_undump1(z, chunkname) : luaY_parser(z, chunkname); 305 tf = bin ? luaU_undump1(z, chunkname) : luaY_parser(z, chunkname);
314 status = 0; 306 status = 0;
@@ -317,12 +309,12 @@ static int protectedparser (ZIO *z, char *chunkname, int bin)
317 tf = NULL; 309 tf = NULL;
318 status = 1; 310 status = 1;
319 } 311 }
320 errorJmp = oldErr; 312 L->errorJmp = oldErr;
321 if (status) return 1; /* error code */ 313 if (status) return 1; /* error code */
322 if (tf == NULL) return 2; /* 'natural' end */ 314 if (tf == NULL) return 2; /* 'natural' end */
323 luaD_adjusttop(luaD_Cstack.base+1); /* one slot for the pseudo-function */ 315 luaD_adjusttop(L->Cstack.base+1); /* one slot for the pseudo-function */
324 luaD_stack.stack[luaD_Cstack.base].ttype = LUA_T_PROTO; 316 L->stack.stack[L->Cstack.base].ttype = LUA_T_PROTO;
325 luaD_stack.stack[luaD_Cstack.base].value.tf = tf; 317 L->stack.stack[L->Cstack.base].value.tf = tf;
326 luaV_closure(0); 318 luaV_closure(0);
327 return 0; 319 return 0;
328} 320}
@@ -332,15 +324,15 @@ static int do_main (ZIO *z, char *chunkname, int bin)
332{ 324{
333 int status; 325 int status;
334 do { 326 do {
335 long old_blocks = (luaC_checkGC(), luaO_nblocks); 327 long old_blocks = (luaC_checkGC(), L->nblocks);
336 status = protectedparser(z, chunkname, bin); 328 status = protectedparser(z, chunkname, bin);
337 if (status == 1) return 1; /* error */ 329 if (status == 1) return 1; /* error */
338 else if (status == 2) return 0; /* 'natural' end */ 330 else if (status == 2) return 0; /* 'natural' end */
339 else { 331 else {
340 unsigned long newelems2 = 2*(luaO_nblocks-old_blocks); 332 unsigned long newelems2 = 2*(L->nblocks-old_blocks);
341 luaC_threshold += newelems2; 333 L->GCthreshold += newelems2;
342 status = luaD_protectedrun(MULT_RET); 334 status = luaD_protectedrun(MULT_RET);
343 luaC_threshold -= newelems2; 335 L->GCthreshold -= newelems2;
344 } 336 }
345 } while (bin && status == 0); 337 } while (bin && status == 0);
346 return status; 338 return status;
@@ -351,7 +343,7 @@ void luaD_gcIM (TObject *o)
351{ 343{
352 TObject *im = luaT_getimbyObj(o, IM_GC); 344 TObject *im = luaT_getimbyObj(o, IM_GC);
353 if (ttype(im) != LUA_T_NIL) { 345 if (ttype(im) != LUA_T_NIL) {
354 *luaD_stack.top = *o; 346 *L->stack.top = *o;
355 incr_top; 347 incr_top;
356 luaD_callTM(im, 1, 0); 348 luaD_callTM(im, 1, 0);
357 } 349 }