aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-11-22 11:12:07 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-11-22 11:12:07 -0200
commit29ede6aa13144ff7b69c57a87be1ee93f57ae896 (patch)
treeadcfb5dcff7db55481cd675349e23dec0e63c939 /ldo.c
parent951897c09319ae5474a4b86bb7d615136577caa0 (diff)
downloadlua-29ede6aa13144ff7b69c57a87be1ee93f57ae896.tar.gz
lua-29ede6aa13144ff7b69c57a87be1ee93f57ae896.tar.bz2
lua-29ede6aa13144ff7b69c57a87be1ee93f57ae896.zip
first implementation of multiple states (reentrant code).
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c127
1 files changed, 64 insertions, 63 deletions
diff --git a/ldo.c b/ldo.c
index c8797a7c..8a534041 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.50 1999/10/14 19:46:57 roberto Exp roberto $ 2** $Id: ldo.c,v 1.51 1999/11/04 17:22:26 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*/
@@ -9,6 +9,8 @@
9#include <stdlib.h> 9#include <stdlib.h>
10#include <string.h> 10#include <string.h>
11 11
12#define LUA_REENTRANT
13
12#include "lauxlib.h" 14#include "lauxlib.h"
13#include "ldo.h" 15#include "ldo.h"
14#include "lgc.h" 16#include "lgc.h"
@@ -41,26 +43,26 @@
41#endif 43#endif
42 44
43 45
44void luaD_init (void) { 46void luaD_init (lua_State *L) {
45 L->stack.stack = luaM_newvector(STACK_UNIT, TObject); 47 L->stack.stack = luaM_newvector(L, STACK_UNIT, TObject);
46 L->stack.top = L->stack.stack; 48 L->stack.top = L->stack.stack;
47 L->stack.last = L->stack.stack+(STACK_UNIT-1); 49 L->stack.last = L->stack.stack+(STACK_UNIT-1);
48} 50}
49 51
50 52
51void luaD_checkstack (int n) { 53void luaD_checkstack (lua_State *L, int n) {
52 struct Stack *S = &L->stack; 54 struct Stack *S = &L->stack;
53 if (S->last-S->top <= n) { 55 if (S->last-S->top <= n) {
54 StkId top = S->top-S->stack; 56 StkId top = S->top-S->stack;
55 int stacksize = (S->last-S->stack)+STACK_UNIT+n; 57 int stacksize = (S->last-S->stack)+STACK_UNIT+n;
56 luaM_reallocvector(S->stack, stacksize, TObject); 58 luaM_reallocvector(L, S->stack, stacksize, TObject);
57 S->last = S->stack+(stacksize-1); 59 S->last = S->stack+(stacksize-1);
58 S->top = S->stack + top; 60 S->top = S->stack + top;
59 if (stacksize >= STACK_LIMIT) { /* stack overflow? */ 61 if (stacksize >= STACK_LIMIT) { /* stack overflow? */
60 if (lua_stackedfunction(100) == LUA_NOOBJECT) /* 100 funcs on stack? */ 62 if (lua_stackedfunction(L, 100) == LUA_NOOBJECT) /* 100 funcs on stack? */
61 lua_error("Lua2C - C2Lua overflow"); /* doesn't look like a rec. loop */ 63 lua_error(L, "Lua2C - C2Lua overflow"); /* doesn't look like a rec. loop */
62 else 64 else
63 lua_error("stack size overflow"); 65 lua_error(L, "stack size overflow");
64 } 66 }
65 } 67 }
66} 68}
@@ -69,12 +71,12 @@ void luaD_checkstack (int n) {
69/* 71/*
70** Adjust stack. Set top to the given value, pushing NILs if needed. 72** Adjust stack. Set top to the given value, pushing NILs if needed.
71*/ 73*/
72void luaD_adjusttop (StkId newtop) { 74void luaD_adjusttop (lua_State *L, StkId newtop) {
73 int diff = newtop-(L->stack.top-L->stack.stack); 75 int diff = newtop-(L->stack.top-L->stack.stack);
74 if (diff <= 0) 76 if (diff <= 0)
75 L->stack.top += diff; 77 L->stack.top += diff;
76 else { 78 else {
77 luaD_checkstack(diff); 79 luaD_checkstack(L, diff);
78 while (diff--) 80 while (diff--)
79 ttype(L->stack.top++) = LUA_T_NIL; 81 ttype(L->stack.top++) = LUA_T_NIL;
80 } 82 }
@@ -84,35 +86,34 @@ void luaD_adjusttop (StkId newtop) {
84/* 86/*
85** Open a hole below "nelems" from the L->stack.top. 87** Open a hole below "nelems" from the L->stack.top.
86*/ 88*/
87void luaD_openstack (int nelems) { 89void luaD_openstack (lua_State *L, int nelems) {
88 luaO_memup(L->stack.top-nelems+1, L->stack.top-nelems, 90 luaO_memup(L->stack.top-nelems+1, L->stack.top-nelems,
89 nelems*sizeof(TObject)); 91 nelems*sizeof(TObject));
90 incr_top; 92 incr_top;
91} 93}
92 94
93 95
94void luaD_lineHook (int line) { 96void luaD_lineHook (lua_State *L, int line) {
95 struct C_Lua_Stack oldCLS = L->Cstack; 97 struct C_Lua_Stack oldCLS = L->Cstack;
96 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; 98 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
97 L->Cstack.num = 0; 99 L->Cstack.num = 0;
98 (*L->linehook)(line); 100 (*L->linehook)(L, line);
99 L->stack.top = L->stack.stack+old_top; 101 L->stack.top = L->stack.stack+old_top;
100 L->Cstack = oldCLS; 102 L->Cstack = oldCLS;
101} 103}
102 104
103 105
104void luaD_callHook (StkId base, const TProtoFunc *tf, int isreturn) { 106void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn) {
105 struct C_Lua_Stack oldCLS = L->Cstack; 107 struct C_Lua_Stack oldCLS = L->Cstack;
106 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; 108 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack;
107 L->Cstack.num = 0; 109 L->Cstack.num = 0;
108 if (isreturn) 110 if (isreturn)
109 (*L->callhook)(LUA_NOOBJECT, "(return)", 0); 111 (*L->callhook)(L, LUA_NOOBJECT, "(return)", 0);
110 else { 112 else {
111 TObject *f = L->stack.stack+base-1; 113 TObject *f = L->stack.stack+base-1;
112 if (tf) 114 if (tf)
113 (*L->callhook)(Ref(f), tf->source->str, tf->lineDefined); 115 (*L->callhook)(L, Ref(L, f), tf->source->str, tf->lineDefined);
114 else 116 else (*L->callhook)(L, Ref(L, f), "(C)", -1);
115 (*L->callhook)(Ref(f), "(C)", -1);
116 } 117 }
117 L->stack.top = L->stack.stack+old_top; 118 L->stack.top = L->stack.stack+old_top;
118 L->Cstack = oldCLS; 119 L->Cstack = oldCLS;
@@ -124,7 +125,7 @@ void luaD_callHook (StkId base, const TProtoFunc *tf, int isreturn) {
124** Cstack.num is the number of arguments; Cstack.lua2C points to the 125** Cstack.num is the number of arguments; Cstack.lua2C points to the
125** first argument. Returns an index to the first result from C. 126** first argument. Returns an index to the first result from C.
126*/ 127*/
127static StkId callC (lua_CFunction f, StkId base) { 128static StkId callC (lua_State *L, lua_CFunction f, StkId base) {
128 struct C_Lua_Stack *cls = &L->Cstack; 129 struct C_Lua_Stack *cls = &L->Cstack;
129 struct C_Lua_Stack oldCLS = *cls; 130 struct C_Lua_Stack oldCLS = *cls;
130 StkId firstResult; 131 StkId firstResult;
@@ -133,35 +134,35 @@ static StkId callC (lua_CFunction f, StkId base) {
133 cls->lua2C = base; 134 cls->lua2C = base;
134 cls->base = base+numarg; /* == top-stack */ 135 cls->base = base+numarg; /* == top-stack */
135 if (L->callhook) 136 if (L->callhook)
136 luaD_callHook(base, NULL, 0); 137 luaD_callHook(L, base, NULL, 0);
137 (*f)(); /* do the actual call */ 138 (*f)(L); /* do the actual call */
138 if (L->callhook) /* func may have changed callhook */ 139 if (L->callhook) /* func may have changed callhook */
139 luaD_callHook(base, NULL, 1); 140 luaD_callHook(L, base, NULL, 1);
140 firstResult = cls->base; 141 firstResult = cls->base;
141 *cls = oldCLS; 142 *cls = oldCLS;
142 return firstResult; 143 return firstResult;
143} 144}
144 145
145 146
146static StkId callCclosure (const struct Closure *cl, 147static StkId callCclosure (lua_State *L, const struct Closure *cl,
147 lua_CFunction f, StkId base) { 148 lua_CFunction f, StkId base) {
148 TObject *pbase; 149 TObject *pbase;
149 int nup = cl->nelems; /* number of upvalues */ 150 int nup = cl->nelems; /* number of upvalues */
150 luaD_checkstack(nup); 151 luaD_checkstack(L, nup);
151 pbase = L->stack.stack+base; /* care: previous call may change this */ 152 pbase = L->stack.stack+base; /* care: previous call may change this */
152 /* open space for upvalues as extra arguments */ 153 /* open space for upvalues as extra arguments */
153 luaO_memup(pbase+nup, pbase, (L->stack.top-pbase)*sizeof(TObject)); 154 luaO_memup(pbase+nup, pbase, (L->stack.top-pbase)*sizeof(TObject));
154 /* copy upvalues into stack */ 155 /* copy upvalues into stack */
155 memcpy(pbase, cl->consts+1, nup*sizeof(TObject)); 156 memcpy(pbase, cl->consts+1, nup*sizeof(TObject));
156 L->stack.top += nup; 157 L->stack.top += nup;
157 return callC(f, base); 158 return callC(L, f, base);
158} 159}
159 160
160 161
161void luaD_callTM (const TObject *f, int nParams, int nResults) { 162void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) {
162 luaD_openstack(nParams); 163 luaD_openstack(L, nParams);
163 *(L->stack.top-nParams-1) = *f; 164 *(L->stack.top-nParams-1) = *f;
164 luaD_calln(nParams, nResults); 165 luaD_calln(L, nParams, nResults);
165} 166}
166 167
167 168
@@ -172,7 +173,7 @@ void luaD_callTM (const TObject *f, int nParams, int nResults) {
172** When returns, the results are on the stack, between [top-nArgs-1,top). 173** When returns, the results are on the stack, between [top-nArgs-1,top).
173** The number of results is nResults, unless nResults=MULT_RET. 174** The number of results is nResults, unless nResults=MULT_RET.
174*/ 175*/
175void luaD_calln (int nArgs, int nResults) { 176void luaD_calln (lua_State *L, int nArgs, int nResults) {
176 struct Stack *S = &L->stack; /* to optimize */ 177 struct Stack *S = &L->stack; /* to optimize */
177 StkId base = (S->top-S->stack)-nArgs; 178 StkId base = (S->top-S->stack)-nArgs;
178 TObject *func = S->stack+base-1; 179 TObject *func = S->stack+base-1;
@@ -181,27 +182,27 @@ void luaD_calln (int nArgs, int nResults) {
181 switch (ttype(func)) { 182 switch (ttype(func)) {
182 case LUA_T_CPROTO: 183 case LUA_T_CPROTO:
183 ttype(func) = LUA_T_CMARK; 184 ttype(func) = LUA_T_CMARK;
184 firstResult = callC(fvalue(func), base); 185 firstResult = callC(L, fvalue(func), base);
185 break; 186 break;
186 case LUA_T_PROTO: 187 case LUA_T_PROTO:
187 ttype(func) = LUA_T_PMARK; 188 ttype(func) = LUA_T_PMARK;
188 firstResult = luaV_execute(NULL, tfvalue(func), base); 189 firstResult = luaV_execute(L, NULL, tfvalue(func), base);
189 break; 190 break;
190 case LUA_T_CLOSURE: { 191 case LUA_T_CLOSURE: {
191 Closure *c = clvalue(func); 192 Closure *c = clvalue(func);
192 TObject *proto = c->consts; 193 TObject *proto = c->consts;
193 ttype(func) = LUA_T_CLMARK; 194 ttype(func) = LUA_T_CLMARK;
194 firstResult = (ttype(proto) == LUA_T_CPROTO) ? 195 firstResult = (ttype(proto) == LUA_T_CPROTO) ?
195 callCclosure(c, fvalue(proto), base) : 196 callCclosure(L, c, fvalue(proto), base) :
196 luaV_execute(c, tfvalue(proto), base); 197 luaV_execute(L, c, tfvalue(proto), base);
197 break; 198 break;
198 } 199 }
199 default: { /* func is not a function */ 200 default: { /* func is not a function */
200 /* Check the tag method for invalid functions */ 201 /* Check the tag method for invalid functions */
201 const TObject *im = luaT_getimbyObj(func, IM_FUNCTION); 202 const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION);
202 if (ttype(im) == LUA_T_NIL) 203 if (ttype(im) == LUA_T_NIL)
203 lua_error("call expression not a function"); 204 lua_error(L, "call expression not a function");
204 luaD_callTM(im, (S->top-S->stack)-(base-1), nResults); 205 luaD_callTM(L, im, (S->top-S->stack)-(base-1), nResults);
205 return; 206 return;
206 } 207 }
207 } 208 }
@@ -209,7 +210,7 @@ void luaD_calln (int nArgs, int nResults) {
209 if (nResults == MULT_RET) 210 if (nResults == MULT_RET)
210 nResults = (S->top-S->stack)-firstResult; 211 nResults = (S->top-S->stack)-firstResult;
211 else 212 else
212 luaD_adjusttop(firstResult+nResults); 213 luaD_adjusttop(L, firstResult+nResults);
213 /* move results to base-1 (to erase parameters and function) */ 214 /* move results to base-1 (to erase parameters and function) */
214 base--; 215 base--;
215 for (i=0; i<nResults; i++) 216 for (i=0; i<nResults; i++)
@@ -218,26 +219,26 @@ void luaD_calln (int nArgs, int nResults) {
218} 219}
219 220
220 221
221static void message (const char *s) { 222static void message (lua_State *L, const char *s) {
222 const TObject *em = &(luaS_assertglobalbyname("_ERRORMESSAGE")->value); 223 const TObject *em = &(luaS_assertglobalbyname(L, "_ERRORMESSAGE")->value);
223 if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO || 224 if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
224 ttype(em) == LUA_T_CLOSURE) { 225 ttype(em) == LUA_T_CLOSURE) {
225 *L->stack.top = *em; 226 *L->stack.top = *em;
226 incr_top; 227 incr_top;
227 lua_pushstring(s); 228 lua_pushstring(L, s);
228 luaD_calln(1, 0); 229 luaD_calln(L, 1, 0);
229 } 230 }
230} 231}
231 232
232/* 233/*
233** Reports an error, and jumps up to the available recover label 234** Reports an error, and jumps up to the available recover label
234*/ 235*/
235void lua_error (const char *s) { 236void lua_error (lua_State *L, const char *s) {
236 if (s) message(s); 237 if (s) message(L, s);
237 if (L->errorJmp) 238 if (L->errorJmp)
238 longjmp(L->errorJmp->b, 1); 239 longjmp(L->errorJmp->b, 1);
239 else { 240 else {
240 message("exit(1). Unable to recover.\n"); 241 message(L, "exit(1). Unable to recover.\n");
241 exit(1); 242 exit(1);
242 } 243 }
243} 244}
@@ -247,7 +248,7 @@ void lua_error (const char *s) {
247** Execute a protected call. Assumes that function is at L->Cstack.base and 248** Execute a protected call. Assumes that function is at L->Cstack.base and
248** parameters are on top of it. Leave nResults on the stack. 249** parameters are on top of it. Leave nResults on the stack.
249*/ 250*/
250int luaD_protectedrun (void) { 251int luaD_protectedrun (lua_State *L) {
251 volatile struct C_Lua_Stack oldCLS = L->Cstack; 252 volatile struct C_Lua_Stack oldCLS = L->Cstack;
252 struct lua_longjmp myErrorJmp; 253 struct lua_longjmp myErrorJmp;
253 volatile int status; 254 volatile int status;
@@ -255,7 +256,7 @@ int luaD_protectedrun (void) {
255 L->errorJmp = &myErrorJmp; 256 L->errorJmp = &myErrorJmp;
256 if (setjmp(myErrorJmp.b) == 0) { 257 if (setjmp(myErrorJmp.b) == 0) {
257 StkId base = L->Cstack.base; 258 StkId base = L->Cstack.base;
258 luaD_calln((L->stack.top-L->stack.stack)-base-1, MULT_RET); 259 luaD_calln(L, (L->stack.top-L->stack.stack)-base-1, MULT_RET);
259 L->Cstack.lua2C = base; /* position of the new results */ 260 L->Cstack.lua2C = base; /* position of the new results */
260 L->Cstack.num = (L->stack.top-L->stack.stack) - base; 261 L->Cstack.num = (L->stack.top-L->stack.stack) - base;
261 L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */ 262 L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */
@@ -274,7 +275,7 @@ int luaD_protectedrun (void) {
274/* 275/*
275** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load 276** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load
276*/ 277*/
277static int protectedparser (ZIO *z, int bin) { 278static int protectedparser (lua_State *L, ZIO *z, int bin) {
278 volatile struct C_Lua_Stack oldCLS = L->Cstack; 279 volatile struct C_Lua_Stack oldCLS = L->Cstack;
279 struct lua_longjmp myErrorJmp; 280 struct lua_longjmp myErrorJmp;
280 volatile int status; 281 volatile int status;
@@ -282,7 +283,7 @@ static int protectedparser (ZIO *z, int bin) {
282 struct lua_longjmp *volatile oldErr = L->errorJmp; 283 struct lua_longjmp *volatile oldErr = L->errorJmp;
283 L->errorJmp = &myErrorJmp; 284 L->errorJmp = &myErrorJmp;
284 if (setjmp(myErrorJmp.b) == 0) { 285 if (setjmp(myErrorJmp.b) == 0) {
285 tf = bin ? luaU_undump1(z) : luaY_parser(z); 286 tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
286 status = 0; 287 status = 0;
287 } 288 }
288 else { /* an error occurred: restore L->Cstack and L->stack.top */ 289 else { /* an error occurred: restore L->Cstack and L->stack.top */
@@ -294,26 +295,26 @@ static int protectedparser (ZIO *z, int bin) {
294 L->errorJmp = oldErr; 295 L->errorJmp = oldErr;
295 if (status) return 1; /* error code */ 296 if (status) return 1; /* error code */
296 if (tf == NULL) return 2; /* 'natural' end */ 297 if (tf == NULL) return 2; /* 'natural' end */
297 luaD_adjusttop(L->Cstack.base+1); /* one slot for the pseudo-function */ 298 luaD_adjusttop(L, L->Cstack.base+1); /* one slot for the pseudo-function */
298 L->stack.stack[L->Cstack.base].ttype = LUA_T_PROTO; 299 L->stack.stack[L->Cstack.base].ttype = LUA_T_PROTO;
299 L->stack.stack[L->Cstack.base].value.tf = tf; 300 L->stack.stack[L->Cstack.base].value.tf = tf;
300 luaV_closure(0); 301 luaV_closure(L, 0);
301 return 0; 302 return 0;
302} 303}
303 304
304 305
305static int do_main (ZIO *z, int bin) { 306static int do_main (lua_State *L, ZIO *z, int bin) {
306 int status; 307 int status;
307 int debug = L->debug; /* save debug status */ 308 int debug = L->debug; /* save debug status */
308 do { 309 do {
309 long old_blocks = (luaC_checkGC(), L->nblocks); 310 long old_blocks = (luaC_checkGC(L), L->nblocks);
310 status = protectedparser(z, bin); 311 status = protectedparser(L, z, bin);
311 if (status == 1) return 1; /* error */ 312 if (status == 1) return 1; /* error */
312 else if (status == 2) return 0; /* 'natural' end */ 313 else if (status == 2) return 0; /* 'natural' end */
313 else { 314 else {
314 unsigned long newelems2 = 2*(L->nblocks-old_blocks); 315 unsigned long newelems2 = 2*(L->nblocks-old_blocks);
315 L->GCthreshold += newelems2; 316 L->GCthreshold += newelems2;
316 status = luaD_protectedrun(); 317 status = luaD_protectedrun(L);
317 L->GCthreshold -= newelems2; 318 L->GCthreshold -= newelems2;
318 } 319 }
319 } while (bin && status == 0); 320 } while (bin && status == 0);
@@ -322,19 +323,19 @@ static int do_main (ZIO *z, int bin) {
322} 323}
323 324
324 325
325void luaD_gcIM (const TObject *o) { 326void luaD_gcIM (lua_State *L, const TObject *o) {
326 const TObject *im = luaT_getimbyObj(o, IM_GC); 327 const TObject *im = luaT_getimbyObj(L, o, IM_GC);
327 if (ttype(im) != LUA_T_NIL) { 328 if (ttype(im) != LUA_T_NIL) {
328 *L->stack.top = *o; 329 *L->stack.top = *o;
329 incr_top; 330 incr_top;
330 luaD_callTM(im, 1, 0); 331 luaD_callTM(L, im, 1, 0);
331 } 332 }
332} 333}
333 334
334 335
335#define MAXFILENAME 260 /* maximum part of a file name kept */ 336#define MAXFILENAME 260 /* maximum part of a file name kept */
336 337
337int lua_dofile (const char *filename) { 338int lua_dofile (lua_State *L, const char *filename) {
338 ZIO z; 339 ZIO z;
339 int status; 340 int status;
340 int c; 341 int c;
@@ -350,22 +351,22 @@ int lua_dofile (const char *filename) {
350 f = freopen(filename, "rb", f); /* set binary mode */ 351 f = freopen(filename, "rb", f); /* set binary mode */
351 luaL_filesource(source, filename, sizeof(source)); 352 luaL_filesource(source, filename, sizeof(source));
352 luaZ_Fopen(&z, f, source); 353 luaZ_Fopen(&z, f, source);
353 status = do_main(&z, bin); 354 status = do_main(L, &z, bin);
354 if (f != stdin) 355 if (f != stdin)
355 fclose(f); 356 fclose(f);
356 return status; 357 return status;
357} 358}
358 359
359 360
360int lua_dostring (const char *str) { 361int lua_dostring (lua_State *L, const char *str) {
361 return lua_dobuffer(str, strlen(str), str); 362 return lua_dobuffer(L, str, strlen(str), str);
362} 363}
363 364
364 365
365int lua_dobuffer (const char *buff, int size, const char *name) { 366int lua_dobuffer (lua_State *L, const char *buff, int size, const char *name) {
366 ZIO z; 367 ZIO z;
367 if (!name) name = "?"; 368 if (!name) name = "?";
368 luaZ_mopen(&z, buff, size, name); 369 luaZ_mopen(&z, buff, size, name);
369 return do_main(&z, buff[0]==ID_CHUNK); 370 return do_main(L, &z, buff[0]==ID_CHUNK);
370} 371}
371 372