2 ** $Id: ldo.c,v 1.45 1999/06/22 20:37:23 roberto Exp $
3 ** Stack and Call structure of Lua
4 ** See Copyright Notice in lua.h
32 #define STACK_LIMIT 6000 /* arbitrary limit */
37 #define STACK_UNIT 128
46 void luaD_init (void) {
47 L
->stack
.stack
= luaM_newvector(STACK_UNIT
, TObject
);
48 L
->stack
.top
= L
->stack
.stack
;
49 L
->stack
.last
= L
->stack
.stack
+(STACK_UNIT
-1);
53 void luaD_checkstack (int n
) {
54 struct Stack
*S
= &L
->stack
;
55 if (S
->last
-S
->top
<= n
) {
56 StkId top
= S
->top
-S
->stack
;
57 int stacksize
= (S
->last
-S
->stack
)+STACK_UNIT
+n
;
58 luaM_reallocvector(S
->stack
, stacksize
, TObject
);
59 S
->last
= S
->stack
+(stacksize
-1);
60 S
->top
= S
->stack
+ top
;
61 if (stacksize
>= STACK_LIMIT
) { /* stack overflow? */
62 if (lua_stackedfunction(100) == LUA_NOOBJECT
) /* 100 funcs on stack? */
63 lua_error("Lua2C - C2Lua overflow"); /* doesn't look like a rec. loop */
65 lua_error("stack size overflow");
72 ** Adjust stack. Set top to the given value, pushing NILs if needed.
74 void luaD_adjusttop (StkId newtop
) {
75 int diff
= newtop
-(L
->stack
.top
-L
->stack
.stack
);
79 luaD_checkstack(diff
);
81 ttype(L
->stack
.top
++) = LUA_T_NIL
;
87 ** Open a hole below "nelems" from the L->stack.top.
89 void luaD_openstack (int nelems
) {
90 luaO_memup(L
->stack
.top
-nelems
+1, L
->stack
.top
-nelems
,
91 nelems
*sizeof(TObject
));
96 void luaD_lineHook (int line
) {
97 struct C_Lua_Stack oldCLS
= L
->Cstack
;
98 StkId old_top
= L
->Cstack
.lua2C
= L
->Cstack
.base
= L
->stack
.top
-L
->stack
.stack
;
100 (*L
->linehook
)(line
);
101 L
->stack
.top
= L
->stack
.stack
+old_top
;
106 void luaD_callHook (StkId base
, TProtoFunc
*tf
, int isreturn
) {
107 struct C_Lua_Stack oldCLS
= L
->Cstack
;
108 StkId old_top
= L
->Cstack
.lua2C
= L
->Cstack
.base
= L
->stack
.top
-L
->stack
.stack
;
111 (*L
->callhook
)(LUA_NOOBJECT
, "(return)", 0);
113 TObject
*f
= L
->stack
.stack
+base
-1;
115 (*L
->callhook
)(Ref(f
), tf
->source
->str
, tf
->lineDefined
);
117 (*L
->callhook
)(Ref(f
), "(C)", -1);
119 L
->stack
.top
= L
->stack
.stack
+old_top
;
125 ** Call a C function.
126 ** Cstack.num is the number of arguments; Cstack.lua2C points to the
127 ** first argument. Returns an index to the first result from C.
129 static StkId
callC (lua_CFunction f
, StkId base
) {
130 struct C_Lua_Stack
*cls
= &L
->Cstack
;
131 struct C_Lua_Stack oldCLS
= *cls
;
133 int numarg
= (L
->stack
.top
-L
->stack
.stack
) - base
;
136 cls
->base
= base
+numarg
; /* == top-stack */
138 luaD_callHook(base
, NULL
, 0);
139 (*f
)(); /* do the actual call */
140 if (L
->callhook
) /* func may have changed callhook */
141 luaD_callHook(base
, NULL
, 1);
142 firstResult
= cls
->base
;
148 static StkId
callCclosure (struct Closure
*cl
, lua_CFunction f
, StkId base
) {
150 int nup
= cl
->nelems
; /* number of upvalues */
151 luaD_checkstack(nup
);
152 pbase
= L
->stack
.stack
+base
; /* care: previous call may change this */
153 /* open space for upvalues as extra arguments */
154 luaO_memup(pbase
+nup
, pbase
, (L
->stack
.top
-pbase
)*sizeof(TObject
));
155 /* copy upvalues into stack */
156 memcpy(pbase
, cl
->consts
+1, nup
*sizeof(TObject
));
158 return callC(f
, base
);
162 void luaD_callTM (TObject
*f
, int nParams
, int nResults
) {
163 luaD_openstack(nParams
);
164 *(L
->stack
.top
-nParams
-1) = *f
;
165 luaD_calln(nParams
, nResults
);
170 ** Call a function (C or Lua). The parameters must be on the stack,
171 ** between [top-nArgs,top). The function to be called is right below the
173 ** When returns, the results are on the stack, between [top-nArgs-1,top).
174 ** The number of results is nResults, unless nResults=MULT_RET.
176 void luaD_calln (int nArgs
, int nResults
) {
177 struct Stack
*S
= &L
->stack
; /* to optimize */
178 StkId base
= (S
->top
-S
->stack
)-nArgs
;
179 TObject
*func
= S
->stack
+base
-1;
182 switch (ttype(func
)) {
184 ttype(func
) = LUA_T_CMARK
;
185 firstResult
= callC(fvalue(func
), base
);
188 ttype(func
) = LUA_T_PMARK
;
189 firstResult
= luaV_execute(NULL
, tfvalue(func
), base
);
191 case LUA_T_CLOSURE
: {
192 Closure
*c
= clvalue(func
);
193 TObject
*proto
= &(c
->consts
[0]);
194 ttype(func
) = LUA_T_CLMARK
;
195 firstResult
= (ttype(proto
) == LUA_T_CPROTO
) ?
196 callCclosure(c
, fvalue(proto
), base
) :
197 luaV_execute(c
, tfvalue(proto
), base
);
200 default: { /* func is not a function */
201 /* Check the tag method for invalid functions */
202 TObject
*im
= luaT_getimbyObj(func
, IM_FUNCTION
);
203 if (ttype(im
) == LUA_T_NIL
)
204 lua_error("call expression not a function");
205 luaD_callTM(im
, (S
->top
-S
->stack
)-(base
-1), nResults
);
209 /* adjust the number of results */
210 if (nResults
== MULT_RET
)
211 nResults
= (S
->top
-S
->stack
)-firstResult
;
213 luaD_adjusttop(firstResult
+nResults
);
214 /* move results to base-1 (to erase parameters and function) */
216 for (i
=0; i
<nResults
; i
++)
217 *(S
->stack
+base
+i
) = *(S
->stack
+firstResult
+i
);
218 S
->top
-= firstResult
-base
;
223 ** Traverse all objects on L->stack.stack
225 void luaD_travstack (int (*fn
)(TObject
*))
228 for (i
= (L
->stack
.top
-1)-L
->stack
.stack
; i
>=0; i
--)
229 fn(L
->stack
.stack
+i
);
234 static void message (char *s
) {
235 TObject
*em
= &(luaS_new("_ERRORMESSAGE")->u
.s
.globalval
);
236 if (ttype(em
) == LUA_T_PROTO
|| ttype(em
) == LUA_T_CPROTO
||
237 ttype(em
) == LUA_T_CLOSURE
) {
246 ** Reports an error, and jumps up to the available recover label
248 void lua_error (char *s
) {
251 longjmp(L
->errorJmp
->b
, 1);
253 message("exit(1). Unable to recover.\n");
260 ** Execute a protected call. Assumes that function is at L->Cstack.base and
261 ** parameters are on top of it. Leave nResults on the stack.
263 int luaD_protectedrun (void) {
264 volatile struct C_Lua_Stack oldCLS
= L
->Cstack
;
265 struct lua_longjmp myErrorJmp
;
267 struct lua_longjmp
*volatile oldErr
= L
->errorJmp
;
268 L
->errorJmp
= &myErrorJmp
;
269 if (setjmp(myErrorJmp
.b
) == 0) {
270 StkId base
= L
->Cstack
.base
;
271 luaD_calln((L
->stack
.top
-L
->stack
.stack
)-base
-1, MULT_RET
);
272 L
->Cstack
.lua2C
= base
; /* position of the new results */
273 L
->Cstack
.num
= (L
->stack
.top
-L
->stack
.stack
) - base
;
274 L
->Cstack
.base
= base
+ L
->Cstack
.num
; /* incorporate results on stack */
277 else { /* an error occurred: restore L->Cstack and L->stack.top */
279 L
->stack
.top
= L
->stack
.stack
+L
->Cstack
.base
;
282 L
->errorJmp
= oldErr
;
288 ** returns 0 = chunk loaded; 1 = error; 2 = no more chunks to load
290 static int protectedparser (ZIO
*z
, int bin
) {
291 volatile struct C_Lua_Stack oldCLS
= L
->Cstack
;
292 struct lua_longjmp myErrorJmp
;
294 TProtoFunc
*volatile tf
;
295 struct lua_longjmp
*volatile oldErr
= L
->errorJmp
;
296 L
->errorJmp
= &myErrorJmp
;
297 if (setjmp(myErrorJmp
.b
) == 0) {
298 tf
= bin
? luaU_undump1(z
) : luaY_parser(z
);
301 else { /* an error occurred: restore L->Cstack and L->stack.top */
303 L
->stack
.top
= L
->stack
.stack
+L
->Cstack
.base
;
307 L
->errorJmp
= oldErr
;
308 if (status
) return 1; /* error code */
309 if (tf
== NULL
) return 2; /* 'natural' end */
310 luaD_adjusttop(L
->Cstack
.base
+1); /* one slot for the pseudo-function */
311 L
->stack
.stack
[L
->Cstack
.base
].ttype
= LUA_T_PROTO
;
312 L
->stack
.stack
[L
->Cstack
.base
].value
.tf
= tf
;
318 static int do_main (ZIO
*z
, int bin
) {
320 int debug
= L
->debug
; /* save debug status */
322 long old_blocks
= (luaC_checkGC(), L
->nblocks
);
323 status
= protectedparser(z
, bin
);
324 if (status
== 1) return 1; /* error */
325 else if (status
== 2) return 0; /* 'natural' end */
327 unsigned long newelems2
= 2*(L
->nblocks
-old_blocks
);
328 L
->GCthreshold
+= newelems2
;
329 status
= luaD_protectedrun();
330 L
->GCthreshold
-= newelems2
;
332 } while (bin
&& status
== 0);
333 L
->debug
= debug
; /* restore debug status */
338 void luaD_gcIM (TObject
*o
)
340 TObject
*im
= luaT_getimbyObj(o
, IM_GC
);
341 if (ttype(im
) != LUA_T_NIL
) {
344 luaD_callTM(im
, 1, 0);
349 #define MAXFILENAME 260 /* maximum part of a file name kept */
351 int lua_dofile (char *filename
) {
356 char source
[MAXFILENAME
];
357 FILE *f
= (filename
== NULL
) ? stdin
: fopen(filename
, "r");
362 bin
= (c
== ID_CHUNK
);
364 f
= freopen(filename
, "rb", f
); /* set binary mode */
365 luaL_filesource(source
, filename
, sizeof(source
));
366 luaZ_Fopen(&z
, f
, source
);
367 status
= do_main(&z
, bin
);
374 int lua_dostring (char *str
) {
375 return lua_dobuffer(str
, strlen(str
), str
);
379 int lua_dobuffer (char *buff
, int size
, char *name
) {
381 if (!name
) name
= "?";
382 luaZ_mopen(&z
, buff
, size
, name
);
383 return do_main(&z
, buff
[0]==ID_CHUNK
);