diff options
-rw-r--r-- | lbaselib.c | 81 | ||||
-rw-r--r-- | lcode.c | 3 | ||||
-rw-r--r-- | ldebug.c | 15 | ||||
-rw-r--r-- | ldo.c | 126 | ||||
-rw-r--r-- | lopcodes.h | 19 | ||||
-rw-r--r-- | lparser.c | 10 | ||||
-rw-r--r-- | lstate.c | 1 | ||||
-rw-r--r-- | lstate.h | 6 | ||||
-rw-r--r-- | lua.h | 17 | ||||
-rw-r--r-- | lvm.c | 86 | ||||
-rw-r--r-- | lvm.h | 2 |
11 files changed, 229 insertions, 137 deletions
@@ -148,30 +148,6 @@ static int luaB_eventtable (lua_State *L) { | |||
148 | } | 148 | } |
149 | 149 | ||
150 | 150 | ||
151 | static int luaB_weakmode (lua_State *L) { | ||
152 | const char *mode = luaL_check_string(L, 2); | ||
153 | luaL_check_type(L, 1, LUA_TTABLE); | ||
154 | if (*mode == '?') { | ||
155 | char buff[3]; | ||
156 | char *s = buff; | ||
157 | int imode = lua_getweakmode(L, 1); | ||
158 | if (imode & LUA_WEAK_KEY) *s++ = 'k'; | ||
159 | if (imode & LUA_WEAK_VALUE) *s++ = 'v'; | ||
160 | *s = '\0'; | ||
161 | lua_pushstring(L, buff); | ||
162 | return 1; | ||
163 | } | ||
164 | else { | ||
165 | int imode = 0; | ||
166 | if (strchr(mode, 'k')) imode |= LUA_WEAK_KEY; | ||
167 | if (strchr(mode, 'v')) imode |= LUA_WEAK_VALUE; | ||
168 | lua_pushvalue(L, 1); /* push table */ | ||
169 | lua_setweakmode(L, imode); | ||
170 | return 1; /* return the table */ | ||
171 | } | ||
172 | } | ||
173 | |||
174 | |||
175 | static int luaB_globals (lua_State *L) { | 151 | static int luaB_globals (lua_State *L) { |
176 | lua_getglobals(L); /* value to be returned */ | 152 | lua_getglobals(L); /* value to be returned */ |
177 | if (!lua_isnone(L, 1)) { | 153 | if (!lua_isnone(L, 1)) { |
@@ -287,6 +263,14 @@ static int luaB_loadfile (lua_State *L) { | |||
287 | } | 263 | } |
288 | 264 | ||
289 | 265 | ||
266 | static int luaB_assert (lua_State *L) { | ||
267 | luaL_check_any(L, 1); | ||
268 | if (!lua_istrue(L, 1)) | ||
269 | luaL_verror(L, "assertion failed! %.90s", luaL_opt_string(L, 2, "")); | ||
270 | lua_settop(L, 1); | ||
271 | return 1; | ||
272 | } | ||
273 | |||
290 | 274 | ||
291 | #define LUA_PATH "LUA_PATH" | 275 | #define LUA_PATH "LUA_PATH" |
292 | 276 | ||
@@ -428,6 +412,40 @@ static int luaB_tostring (lua_State *L) { | |||
428 | } | 412 | } |
429 | 413 | ||
430 | 414 | ||
415 | static int luaB_resume (lua_State *L) { | ||
416 | lua_State *co = (lua_State *)lua_touserdata(L, lua_upvalueindex(1)); | ||
417 | lua_resume(L, co); | ||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | |||
422 | static int luaB_coroutine (lua_State *L) { | ||
423 | lua_State *NL; | ||
424 | int ref; | ||
425 | luaL_check_type(L, 1, LUA_TFUNCTION); | ||
426 | NL = lua_newthread(L, 0); | ||
427 | if (NL == NULL) lua_error(L, "unable to create new thread"); | ||
428 | /* move function from L to NL */ | ||
429 | ref = lua_ref(L, 1); | ||
430 | lua_getref(NL, ref); | ||
431 | lua_unref(L, ref); | ||
432 | lua_cobegin(NL, 0); | ||
433 | lua_newuserdatabox(L, NL); | ||
434 | lua_pushcclosure(L, luaB_resume, 1); | ||
435 | return 1; | ||
436 | } | ||
437 | |||
438 | |||
439 | static int luaB_yield (lua_State *L) { | ||
440 | return lua_yield(L, 0); | ||
441 | } | ||
442 | |||
443 | |||
444 | /* | ||
445 | ** {====================================================== | ||
446 | ** Auxiliar table-related functions | ||
447 | */ | ||
448 | |||
431 | static int luaB_foreachi (lua_State *L) { | 449 | static int luaB_foreachi (lua_State *L) { |
432 | int n, i; | 450 | int n, i; |
433 | luaL_check_type(L, 1, LUA_TTABLE); | 451 | luaL_check_type(L, 1, LUA_TTABLE); |
@@ -464,15 +482,6 @@ static int luaB_foreach (lua_State *L) { | |||
464 | } | 482 | } |
465 | 483 | ||
466 | 484 | ||
467 | static int luaB_assert (lua_State *L) { | ||
468 | luaL_check_any(L, 1); | ||
469 | if (!lua_istrue(L, 1)) | ||
470 | luaL_verror(L, "assertion failed! %.90s", luaL_opt_string(L, 2, "")); | ||
471 | lua_settop(L, 1); | ||
472 | return 1; | ||
473 | } | ||
474 | |||
475 | |||
476 | static int luaB_getn (lua_State *L) { | 485 | static int luaB_getn (lua_State *L) { |
477 | luaL_check_type(L, 1, LUA_TTABLE); | 486 | luaL_check_type(L, 1, LUA_TTABLE); |
478 | lua_pushnumber(L, lua_getn(L, 1)); | 487 | lua_pushnumber(L, lua_getn(L, 1)); |
@@ -521,7 +530,6 @@ static int luaB_tremove (lua_State *L) { | |||
521 | 530 | ||
522 | 531 | ||
523 | 532 | ||
524 | |||
525 | /* | 533 | /* |
526 | ** {====================================================== | 534 | ** {====================================================== |
527 | ** Quicksort | 535 | ** Quicksort |
@@ -627,6 +635,8 @@ static int luaB_sort (lua_State *L) { | |||
627 | 635 | ||
628 | /* }====================================================== */ | 636 | /* }====================================================== */ |
629 | 637 | ||
638 | /* }====================================================== */ | ||
639 | |||
630 | 640 | ||
631 | 641 | ||
632 | static const luaL_reg base_funcs[] = { | 642 | static const luaL_reg base_funcs[] = { |
@@ -634,6 +644,7 @@ static const luaL_reg base_funcs[] = { | |||
634 | {LUA_ERRORMESSAGE, luaB__ERRORMESSAGE}, | 644 | {LUA_ERRORMESSAGE, luaB__ERRORMESSAGE}, |
635 | {"call", luaB_call}, | 645 | {"call", luaB_call}, |
636 | {"collectgarbage", luaB_collectgarbage}, | 646 | {"collectgarbage", luaB_collectgarbage}, |
647 | {"coroutine", luaB_coroutine}, | ||
637 | {"dofile", luaB_dofile}, | 648 | {"dofile", luaB_dofile}, |
638 | {"dostring", luaB_dostring}, | 649 | {"dostring", luaB_dostring}, |
639 | {"error", luaB_error}, | 650 | {"error", luaB_error}, |
@@ -659,7 +670,7 @@ static const luaL_reg base_funcs[] = { | |||
659 | {"tinsert", luaB_tinsert}, | 670 | {"tinsert", luaB_tinsert}, |
660 | {"tremove", luaB_tremove}, | 671 | {"tremove", luaB_tremove}, |
661 | {"unpack", luaB_unpack}, | 672 | {"unpack", luaB_unpack}, |
662 | {"weakmode", luaB_weakmode} | 673 | {"yield", luaB_yield} |
663 | }; | 674 | }; |
664 | 675 | ||
665 | 676 | ||
@@ -264,8 +264,7 @@ static int nil_constant (FuncState *fs) { | |||
264 | 264 | ||
265 | void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) { | 265 | void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) { |
266 | if (e->k == VCALL) { /* expression is an open function call? */ | 266 | if (e->k == VCALL) { /* expression is an open function call? */ |
267 | if (nresults == LUA_MULTRET) nresults = NO_REG; | 267 | SETARG_C(getcode(fs, e), nresults+1); |
268 | SETARG_C(getcode(fs, e), nresults); | ||
269 | if (nresults == 1) { /* `regular' expression? */ | 268 | if (nresults == 1) { /* `regular' expression? */ |
270 | e->k = VNONRELOC; | 269 | e->k = VNONRELOC; |
271 | e->u.i.info = GETARG_A(getcode(fs, e)); | 270 | e->u.i.info = GETARG_A(getcode(fs, e)); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ | 2 | ** $Id: ldebug.c,v 1.96 2001/12/18 20:52:30 roberto Exp $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -303,7 +303,7 @@ static int checkopenop (const Proto *pt, int pc) { | |||
303 | switch (GET_OPCODE(i)) { | 303 | switch (GET_OPCODE(i)) { |
304 | case OP_CALL: | 304 | case OP_CALL: |
305 | case OP_RETURN: { | 305 | case OP_RETURN: { |
306 | check(GETARG_B(i) == NO_REG); | 306 | check(GETARG_B(i) == 0); |
307 | return 1; | 307 | return 1; |
308 | } | 308 | } |
309 | case OP_SETLISTO: return 1; | 309 | case OP_SETLISTO: return 1; |
@@ -391,10 +391,11 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
391 | break; | 391 | break; |
392 | } | 392 | } |
393 | case OP_CALL: { | 393 | case OP_CALL: { |
394 | if (b != NO_REG) { | 394 | if (b != 0) { |
395 | checkreg(pt, a+b); | 395 | checkreg(pt, a+b-1); |
396 | } | 396 | } |
397 | if (c == NO_REG) { | 397 | c--; /* c = num. returns */ |
398 | if (c == LUA_MULTRET) { | ||
398 | check(checkopenop(pt, pc)); | 399 | check(checkopenop(pt, pc)); |
399 | } | 400 | } |
400 | else if (c != 0) | 401 | else if (c != 0) |
@@ -403,8 +404,8 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
403 | break; | 404 | break; |
404 | } | 405 | } |
405 | case OP_RETURN: { | 406 | case OP_RETURN: { |
406 | if (b != NO_REG && b != 0) | 407 | b--; /* b = num. returns */ |
407 | checkreg(pt, a+b-1); | 408 | if (b > 0) checkreg(pt, a+b-1); |
408 | break; | 409 | break; |
409 | } | 410 | } |
410 | case OP_FORPREP: | 411 | case OP_FORPREP: |
@@ -18,6 +18,7 @@ | |||
18 | #include "lgc.h" | 18 | #include "lgc.h" |
19 | #include "lmem.h" | 19 | #include "lmem.h" |
20 | #include "lobject.h" | 20 | #include "lobject.h" |
21 | #include "lopcodes.h" | ||
21 | #include "lparser.h" | 22 | #include "lparser.h" |
22 | #include "lstate.h" | 23 | #include "lstate.h" |
23 | #include "lstring.h" | 24 | #include "lstring.h" |
@@ -112,8 +113,6 @@ void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event) { | |||
112 | } | 113 | } |
113 | 114 | ||
114 | 115 | ||
115 | #define newci(L) ((++L->ci == L->end_ci) ? growci(L) : L->ci) | ||
116 | |||
117 | static CallInfo *growci (lua_State *L) { | 116 | static CallInfo *growci (lua_State *L) { |
118 | lua_assert(L->ci == L->end_ci); | 117 | lua_assert(L->ci == L->end_ci); |
119 | luaM_reallocvector(L, L->base_ci, L->size_ci, 2*L->size_ci, CallInfo); | 118 | luaM_reallocvector(L, L->base_ci, L->size_ci, 2*L->size_ci, CallInfo); |
@@ -124,9 +123,32 @@ static CallInfo *growci (lua_State *L) { | |||
124 | } | 123 | } |
125 | 124 | ||
126 | 125 | ||
126 | static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { | ||
127 | int i; | ||
128 | Table *htab; | ||
129 | TObject n, nname; | ||
130 | StkId firstvar = base + nfixargs; /* position of first vararg */ | ||
131 | if (L->top < firstvar) { | ||
132 | luaD_checkstack(L, firstvar - L->top); | ||
133 | while (L->top < firstvar) | ||
134 | setnilvalue(L->top++); | ||
135 | } | ||
136 | htab = luaH_new(L, 0, 0); | ||
137 | for (i=0; firstvar+i<L->top; i++) | ||
138 | luaH_setnum(L, htab, i+1, firstvar+i); | ||
139 | /* store counter in field `n' */ | ||
140 | setnvalue(&n, i); | ||
141 | setsvalue(&nname, luaS_newliteral(L, "n")); | ||
142 | luaH_set(L, htab, &nname, &n); | ||
143 | L->top = firstvar; /* remove elements from the stack */ | ||
144 | sethvalue(L->top, htab); | ||
145 | incr_top; | ||
146 | } | ||
147 | |||
148 | |||
127 | StkId luaD_precall (lua_State *L, StkId func) { | 149 | StkId luaD_precall (lua_State *L, StkId func) { |
128 | CallInfo *ci; | 150 | CallInfo *ci; |
129 | int n; | 151 | LClosure *cl; |
130 | if (ttype(func) != LUA_TFUNCTION) { | 152 | if (ttype(func) != LUA_TFUNCTION) { |
131 | /* `func' is not a function; check the `function' tag method */ | 153 | /* `func' is not a function; check the `function' tag method */ |
132 | const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); | 154 | const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); |
@@ -135,21 +157,39 @@ StkId luaD_precall (lua_State *L, StkId func) { | |||
135 | luaD_openstack(L, func); | 157 | luaD_openstack(L, func); |
136 | setobj(func, tm); /* tag method is the new function to be called */ | 158 | setobj(func, tm); /* tag method is the new function to be called */ |
137 | } | 159 | } |
138 | ci = newci(L); | 160 | ci = ++L->ci; |
161 | if (L->ci == L->end_ci) ci = growci(L); | ||
139 | ci->base = func+1; | 162 | ci->base = func+1; |
140 | ci->savedpc = NULL; | ||
141 | if (L->callhook) | 163 | if (L->callhook) |
142 | luaD_callHook(L, L->callhook, "call"); | 164 | luaD_callHook(L, L->callhook, "call"); |
143 | if (!clvalue(func)->c.isC) return NULL; | 165 | cl = &clvalue(func)->l; |
144 | /* if is a C function, call it */ | 166 | if (!cl->isC) { /* Lua function? prepare its call */ |
145 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 167 | StkId base = func+1; |
146 | lua_unlock(L); | 168 | Proto *p = cl->p; |
169 | ci->linehook = L->linehook; | ||
170 | ci->savedpc = p->code; /* starting point */ | ||
171 | if (p->is_vararg) /* varargs? */ | ||
172 | adjust_varargs(L, base, p->numparams); | ||
173 | if (base > L->stack_last - p->maxstacksize) | ||
174 | luaD_stackerror(L); | ||
175 | ci->top = base + p->maxstacksize; | ||
176 | while (L->top < ci->top) | ||
177 | setnilvalue(L->top++); | ||
178 | L->top = ci->top; | ||
179 | return NULL; | ||
180 | } | ||
181 | else { /* if is a C function, call it */ | ||
182 | int n; | ||
183 | ci->savedpc = NULL; | ||
184 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | ||
185 | lua_unlock(L); | ||
147 | #if LUA_COMPATUPVALUES | 186 | #if LUA_COMPATUPVALUES |
148 | lua_pushupvalues(L); | 187 | lua_pushupvalues(L); |
149 | #endif | 188 | #endif |
150 | n = (*clvalue(func)->c.f)(L); /* do the actual call */ | 189 | n = (*clvalue(func)->c.f)(L); /* do the actual call */ |
151 | lua_lock(L); | 190 | lua_lock(L); |
152 | return L->top - n; | 191 | return L->top - n; |
192 | } | ||
153 | } | 193 | } |
154 | 194 | ||
155 | 195 | ||
@@ -179,12 +219,60 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { | |||
179 | */ | 219 | */ |
180 | void luaD_call (lua_State *L, StkId func, int nResults) { | 220 | void luaD_call (lua_State *L, StkId func, int nResults) { |
181 | StkId firstResult = luaD_precall(L, func); | 221 | StkId firstResult = luaD_precall(L, func); |
182 | if (firstResult == NULL) /* is a Lua function? */ | 222 | if (firstResult == NULL) { /* is a Lua function? */ |
183 | firstResult = luaV_execute(L, &clvalue(func)->l, func+1); /* call it */ | 223 | firstResult = luaV_execute(L); /* call it */ |
224 | if (firstResult == NULL) { | ||
225 | luaD_poscall(L, 0, L->top); | ||
226 | luaD_error(L, "attempt to `yield' across tag-method/C-call boundary"); | ||
227 | } | ||
228 | } | ||
184 | luaD_poscall(L, nResults, firstResult); | 229 | luaD_poscall(L, nResults, firstResult); |
185 | } | 230 | } |
186 | 231 | ||
187 | 232 | ||
233 | LUA_API void lua_cobegin (lua_State *L, int nargs) { | ||
234 | StkId func; | ||
235 | lua_lock(L); | ||
236 | func = L->top - (nargs+1); /* coroutine main function */ | ||
237 | if (luaD_precall(L, func) != NULL) | ||
238 | luaD_error(L, "coroutine started with a C function"); | ||
239 | lua_unlock(L); | ||
240 | } | ||
241 | |||
242 | |||
243 | LUA_API void lua_resume (lua_State *L, lua_State *co) { | ||
244 | StkId firstResult; | ||
245 | lua_lock(L); | ||
246 | if (co->ci->savedpc == NULL) /* no activation record? */ | ||
247 | luaD_error(L, "thread is dead - cannot be resumed"); | ||
248 | lua_assert(co->errorJmp == NULL); | ||
249 | co->errorJmp = L->errorJmp; | ||
250 | firstResult = luaV_execute(co); | ||
251 | if (firstResult != NULL) /* `return'? */ | ||
252 | luaD_poscall(co, LUA_MULTRET, firstResult); /* ends this coroutine */ | ||
253 | else { /* `yield' */ | ||
254 | int nresults = GETARG_C(*((co->ci-1)->savedpc - 1)) - 1; | ||
255 | luaD_poscall(co, nresults, co->top); /* complete it */ | ||
256 | if (nresults >= 0) co->top = co->ci->top; | ||
257 | } | ||
258 | co->errorJmp = NULL; | ||
259 | lua_unlock(L); | ||
260 | } | ||
261 | |||
262 | |||
263 | LUA_API int lua_yield (lua_State *L, int nresults) { | ||
264 | CallInfo *ci; | ||
265 | int ibase; | ||
266 | lua_lock(L); | ||
267 | ci = L->ci - 1; /* call info of calling function */ | ||
268 | if (ci->pc == NULL) | ||
269 | luaD_error(L, "cannot `yield' a C function"); | ||
270 | ibase = L->top - ci->base; | ||
271 | lua_unlock(L); | ||
272 | return ibase; | ||
273 | } | ||
274 | |||
275 | |||
188 | /* | 276 | /* |
189 | ** Execute a protected call. | 277 | ** Execute a protected call. |
190 | */ | 278 | */ |
@@ -330,7 +418,13 @@ static void message (lua_State *L, const char *s) { | |||
330 | ** Reports an error, and jumps up to the available recovery label | 418 | ** Reports an error, and jumps up to the available recovery label |
331 | */ | 419 | */ |
332 | void luaD_error (lua_State *L, const char *s) { | 420 | void luaD_error (lua_State *L, const char *s) { |
333 | if (s) message(L, s); | 421 | if (s) { |
422 | if (L->ci->savedpc) { /* error in Lua function preamble? */ | ||
423 | L->ci->savedpc = NULL; /* pretend function was already running */ | ||
424 | L->ci->pc = NULL; | ||
425 | } | ||
426 | message(L, s); | ||
427 | } | ||
334 | luaD_breakrun(L, LUA_ERRRUN); | 428 | luaD_breakrun(L, LUA_ERRRUN); |
335 | } | 429 | } |
336 | 430 | ||
@@ -168,8 +168,8 @@ OP_TESTGE,/* A C test := (R(A) >= R/K(C)) */ | |||
168 | OP_TESTT,/* A B test := R(B); if (test) R(A) := R(B) */ | 168 | OP_TESTT,/* A B test := R(B); if (test) R(A) := R(B) */ |
169 | OP_TESTF,/* A B test := not R(B); if (test) R(A) := R(B) */ | 169 | OP_TESTF,/* A B test := not R(B); if (test) R(A) := R(B) */ |
170 | 170 | ||
171 | OP_CALL,/* A B C R(A), ... ,R(A+C-1) := R(A)(R(A+1), ... ,R(A+B))*/ | 171 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))*/ |
172 | OP_RETURN,/* A B return R(A), ... ,R(A+B-1) (see (3)) */ | 172 | OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see (3)) */ |
173 | 173 | ||
174 | OP_FORPREP,/* A sBc */ | 174 | OP_FORPREP,/* A sBc */ |
175 | OP_FORLOOP,/* A sBc */ | 175 | OP_FORLOOP,/* A sBc */ |
@@ -182,6 +182,9 @@ OP_SETLISTO,/* A Bc */ | |||
182 | 182 | ||
183 | OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ | 183 | OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ |
184 | OP_CLOSURE /* A Bc R(A) := closure(KPROTO[Bc], R(A), ... ,R(A+n)) */ | 184 | OP_CLOSURE /* A Bc R(A) := closure(KPROTO[Bc], R(A), ... ,R(A+n)) */ |
185 | /*---------------------------------------------------------------------- | ||
186 | pseudo-instructions (interruptions): cannot occur in regular code | ||
187 | ------------------------------------------------------------------------*/ | ||
185 | } OpCode; | 188 | } OpCode; |
186 | 189 | ||
187 | 190 | ||
@@ -194,11 +197,11 @@ OP_CLOSURE /* A Bc R(A) := closure(KPROTO[Bc], R(A), ... ,R(A+n)) */ | |||
194 | (1) In the current implementation there is no `test' variable; | 197 | (1) In the current implementation there is no `test' variable; |
195 | instructions OP_TEST* and OP_CJMP must always occur together. | 198 | instructions OP_TEST* and OP_CJMP must always occur together. |
196 | 199 | ||
197 | (2) In OP_CALL, if (B == NO_REG) then B = top. C is the number of returns, | 200 | (2) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, |
198 | and can be NO_REG. OP_CALL can set `top' to last_result+1, so | 201 | and can be 0: OP_CALL then sets `top' to last_result+1, so |
199 | next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. | 202 | next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. |
200 | 203 | ||
201 | (3) In OP_RETURN, if (B == NO_REG) then return up to `top' | 204 | (3) In OP_RETURN, if (B == 0) then return up to `top' |
202 | ===========================================================================*/ | 205 | ===========================================================================*/ |
203 | 206 | ||
204 | 207 | ||
@@ -221,6 +224,12 @@ extern const lu_byte luaP_opmodes[NUM_OPCODES]; | |||
221 | 224 | ||
222 | 225 | ||
223 | /* | 226 | /* |
227 | ** constant instructions | ||
228 | */ | ||
229 | |||
230 | extern const Instruction luaP_yieldop; | ||
231 | |||
232 | /* | ||
224 | ** opcode names (only included when compiled with LUA_OPNAMES) | 233 | ** opcode names (only included when compiled with LUA_OPNAMES) |
225 | */ | 234 | */ |
226 | extern const char *const luaP_opnames[]; | 235 | extern const char *const luaP_opnames[]; |
@@ -335,7 +335,7 @@ static void close_func (LexState *ls) { | |||
335 | FuncState *fs = ls->fs; | 335 | FuncState *fs = ls->fs; |
336 | Proto *f = fs->f; | 336 | Proto *f = fs->f; |
337 | removelocalvars(ls, fs->nactloc, 0); | 337 | removelocalvars(ls, fs->nactloc, 0); |
338 | luaK_codeABC(fs, OP_RETURN, 0, 0, 0); /* final return */ | 338 | luaK_codeABC(fs, OP_RETURN, 0, 1, 0); /* final return */ |
339 | luaK_getlabel(fs); /* close eventual list of pending jumps */ | 339 | luaK_getlabel(fs); /* close eventual list of pending jumps */ |
340 | lua_assert(G(L)->roottable == fs->h); | 340 | lua_assert(G(L)->roottable == fs->h); |
341 | G(L)->roottable = fs->h->next; | 341 | G(L)->roottable = fs->h->next; |
@@ -449,13 +449,13 @@ static void funcargs (LexState *ls, expdesc *f) { | |||
449 | lua_assert(f->k == VNONRELOC); | 449 | lua_assert(f->k == VNONRELOC); |
450 | base = f->u.i.info; /* base register for call */ | 450 | base = f->u.i.info; /* base register for call */ |
451 | if (args.k == VCALL) | 451 | if (args.k == VCALL) |
452 | nparams = NO_REG; /* open call */ | 452 | nparams = LUA_MULTRET; /* open call */ |
453 | else { | 453 | else { |
454 | if (args.k != VVOID) | 454 | if (args.k != VVOID) |
455 | luaK_exp2nextreg(fs, &args); /* close last argument */ | 455 | luaK_exp2nextreg(fs, &args); /* close last argument */ |
456 | nparams = fs->freereg - (base+1); | 456 | nparams = fs->freereg - (base+1); |
457 | } | 457 | } |
458 | init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams, 1)); | 458 | init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); |
459 | fs->freereg = base+1; /* call remove function and arguments and leaves | 459 | fs->freereg = base+1; /* call remove function and arguments and leaves |
460 | (unless changed) one result */ | 460 | (unless changed) one result */ |
461 | } | 461 | } |
@@ -1136,7 +1136,7 @@ static void retstat (LexState *ls) { | |||
1136 | if (e.k == VCALL) { | 1136 | if (e.k == VCALL) { |
1137 | luaK_setcallreturns(fs, &e, LUA_MULTRET); | 1137 | luaK_setcallreturns(fs, &e, LUA_MULTRET); |
1138 | first = fs->nactloc; | 1138 | first = fs->nactloc; |
1139 | nret = NO_REG; /* return all values */ | 1139 | nret = LUA_MULTRET; /* return all values */ |
1140 | } | 1140 | } |
1141 | else { | 1141 | else { |
1142 | luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ | 1142 | luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ |
@@ -1144,7 +1144,7 @@ static void retstat (LexState *ls) { | |||
1144 | nret = fs->freereg - first; /* return all `active' values */ | 1144 | nret = fs->freereg - first; /* return all `active' values */ |
1145 | } | 1145 | } |
1146 | } | 1146 | } |
1147 | luaK_codeABC(fs, OP_RETURN, first, nret, 0); | 1147 | luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); |
1148 | fs->freereg = fs->nactloc; /* removes all temp values */ | 1148 | fs->freereg = fs->nactloc; /* removes all temp values */ |
1149 | } | 1149 | } |
1150 | 1150 | ||
@@ -104,6 +104,7 @@ LUA_API lua_State *lua_newthread (lua_State *OL, int stacksize) { | |||
104 | } | 104 | } |
105 | } | 105 | } |
106 | if (OL) lua_unlock(OL); | 106 | if (OL) lua_unlock(OL); |
107 | lua_userstateopen(L); | ||
107 | return L; | 108 | return L; |
108 | } | 109 | } |
109 | 110 | ||
@@ -39,6 +39,10 @@ | |||
39 | #define LUA_USERSTATE | 39 | #define LUA_USERSTATE |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #ifndef lua_userstateopen | ||
43 | #define lua_userstateopen(l) | ||
44 | #endif | ||
45 | |||
42 | 46 | ||
43 | 47 | ||
44 | struct lua_longjmp; /* defined in ldo.c */ | 48 | struct lua_longjmp; /* defined in ldo.c */ |
@@ -77,8 +81,8 @@ typedef struct CallInfo { | |||
77 | const Instruction *savedpc; | 81 | const Instruction *savedpc; |
78 | lua_Hook linehook; | 82 | lua_Hook linehook; |
79 | StkId top; /* top for this function (when it's a Lua function) */ | 83 | StkId top; /* top for this function (when it's a Lua function) */ |
80 | /* extra information for debugging */ | ||
81 | const Instruction **pc; | 84 | const Instruction **pc; |
85 | /* extra information for line tracing */ | ||
82 | int lastpc; /* last pc traced */ | 86 | int lastpc; /* last pc traced */ |
83 | int line; /* current line */ | 87 | int line; /* current line */ |
84 | int refi; /* current index in `lineinfo' */ | 88 | int refi; /* current index in `lineinfo' */ |
@@ -45,10 +45,6 @@ | |||
45 | #define LUA_ERRMEM 4 | 45 | #define LUA_ERRMEM 4 |
46 | #define LUA_ERRERR 5 | 46 | #define LUA_ERRERR 5 |
47 | 47 | ||
48 | /* weak-table modes */ | ||
49 | #define LUA_WEAK_KEY 1 | ||
50 | #define LUA_WEAK_VALUE 2 | ||
51 | |||
52 | 48 | ||
53 | typedef struct lua_State lua_State; | 49 | typedef struct lua_State lua_State; |
54 | 50 | ||
@@ -182,6 +178,14 @@ LUA_API int lua_loadbuffer (lua_State *L, const char *buff, size_t size, | |||
182 | LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, | 178 | LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, |
183 | const char *name); | 179 | const char *name); |
184 | 180 | ||
181 | |||
182 | /* | ||
183 | ** coroutine functions | ||
184 | */ | ||
185 | LUA_API void lua_cobegin (lua_State *L, int nargs); | ||
186 | LUA_API int lua_yield (lua_State *L, int nresults); | ||
187 | LUA_API void lua_resume (lua_State *L, lua_State *co); | ||
188 | |||
185 | /* | 189 | /* |
186 | ** Garbage-collection functions | 190 | ** Garbage-collection functions |
187 | */ | 191 | */ |
@@ -203,9 +207,6 @@ LUA_API void lua_concat (lua_State *L, int n); | |||
203 | LUA_API void *lua_newuserdata (lua_State *L, size_t size); | 207 | LUA_API void *lua_newuserdata (lua_State *L, size_t size); |
204 | LUA_API void lua_newuserdatabox (lua_State *L, void *u); | 208 | LUA_API void lua_newuserdatabox (lua_State *L, void *u); |
205 | 209 | ||
206 | LUA_API void lua_setweakmode (lua_State *L, int mode); | ||
207 | LUA_API int lua_getweakmode (lua_State *L, int index); | ||
208 | |||
209 | 210 | ||
210 | 211 | ||
211 | /* | 212 | /* |
@@ -242,7 +243,7 @@ LUA_API int lua_getweakmode (lua_State *L, int index); | |||
242 | ** compatibility macros and functions | 243 | ** compatibility macros and functions |
243 | */ | 244 | */ |
244 | 245 | ||
245 | LUA_API void lua_pushupvalues (lua_State *L); | 246 | LUA_API int lua_pushupvalues (lua_State *L); |
246 | 247 | ||
247 | #define lua_isnull lua_isnone | 248 | #define lua_isnull lua_isnone |
248 | 249 | ||
@@ -254,29 +254,6 @@ void luaV_strconc (lua_State *L, int total, StkId top) { | |||
254 | } | 254 | } |
255 | 255 | ||
256 | 256 | ||
257 | static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { | ||
258 | int i; | ||
259 | Table *htab; | ||
260 | TObject n, nname; | ||
261 | StkId firstvar = base + nfixargs; /* position of first vararg */ | ||
262 | if (L->top < firstvar) { | ||
263 | luaD_checkstack(L, firstvar - L->top); | ||
264 | while (L->top < firstvar) | ||
265 | setnilvalue(L->top++); | ||
266 | } | ||
267 | htab = luaH_new(L, 0, 0); | ||
268 | for (i=0; firstvar+i<L->top; i++) | ||
269 | luaH_setnum(L, htab, i+1, firstvar+i); | ||
270 | /* store counter in field `n' */ | ||
271 | setnvalue(&n, i); | ||
272 | setsvalue(&nname, luaS_newliteral(L, "n")); | ||
273 | luaH_set(L, htab, &nname, &n); | ||
274 | L->top = firstvar; /* remove elements from the stack */ | ||
275 | sethvalue(L->top, htab); | ||
276 | incr_top; | ||
277 | } | ||
278 | |||
279 | |||
280 | static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { | 257 | static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { |
281 | const TObject *b = rb; | 258 | const TObject *b = rb; |
282 | const TObject *c = rc; | 259 | const TObject *c = rc; |
@@ -307,8 +284,8 @@ static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { | |||
307 | #define RC(i) (base+GETARG_C(i)) | 284 | #define RC(i) (base+GETARG_C(i)) |
308 | #define RKC(i) ((GETARG_C(i) < MAXSTACK) ? \ | 285 | #define RKC(i) ((GETARG_C(i) < MAXSTACK) ? \ |
309 | base+GETARG_C(i) : \ | 286 | base+GETARG_C(i) : \ |
310 | cl->p->k+GETARG_C(i)-MAXSTACK) | 287 | k+GETARG_C(i)-MAXSTACK) |
311 | #define KBc(i) (cl->p->k+GETARG_Bc(i)) | 288 | #define KBc(i) (k+GETARG_Bc(i)) |
312 | 289 | ||
313 | #define Arith(op, optm) { \ | 290 | #define Arith(op, optm) { \ |
314 | const TObject *b = RB(i); const TObject *c = RKC(i); \ | 291 | const TObject *b = RB(i); const TObject *c = RKC(i); \ |
@@ -321,38 +298,26 @@ static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { | |||
321 | } | 298 | } |
322 | 299 | ||
323 | 300 | ||
324 | #define luaV_poscall(L,c,f,ci) \ | ||
325 | if (c != NO_REG) { \ | ||
326 | luaD_poscall(L, c, f); \ | ||
327 | L->top = ci->top; \ | ||
328 | } \ | ||
329 | else { \ | ||
330 | luaD_poscall(L, LUA_MULTRET, f); \ | ||
331 | } | ||
332 | |||
333 | |||
334 | #define dojump(pc, i) ((pc) += GETARG_sBc(i)) | 301 | #define dojump(pc, i) ((pc) += GETARG_sBc(i)) |
335 | 302 | ||
336 | /* | 303 | /* |
337 | ** Executes the given Lua function. Parameters are between [base,top). | 304 | ** Executes current Lua function. Parameters are between [base,top). |
338 | ** Returns n such that the results are between [n,top). | 305 | ** Returns n such that the results are between [n,top). |
339 | */ | 306 | */ |
340 | StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { | 307 | StkId luaV_execute (lua_State *L) { |
308 | StkId base; | ||
309 | LClosure *cl; | ||
310 | TObject *k; | ||
341 | const Instruction *pc; | 311 | const Instruction *pc; |
342 | lua_Hook linehook; | 312 | lua_Hook linehook; |
343 | reinit: | 313 | reinit: |
344 | lua_assert(L->ci->savedpc == NULL); | 314 | base = L->ci->base; |
315 | cl = &clvalue(base - 1)->l; | ||
316 | k = cl->p->k; | ||
317 | linehook = L->ci->linehook; | ||
345 | L->ci->pc = &pc; | 318 | L->ci->pc = &pc; |
346 | L->ci->top = base + cl->p->maxstacksize; | 319 | pc = L->ci->savedpc; |
347 | if (cl->p->is_vararg) /* varargs? */ | 320 | L->ci->savedpc = NULL; |
348 | adjust_varargs(L, base, cl->p->numparams); | ||
349 | if (base > L->stack_last - cl->p->maxstacksize) | ||
350 | luaD_stackerror(L); | ||
351 | while (L->top < L->ci->top) | ||
352 | setnilvalue(L->top++); | ||
353 | L->top = L->ci->top; | ||
354 | linehook = L->ci->linehook = L->linehook; | ||
355 | pc = cl->p->code; | ||
356 | /* main loop of interpreter */ | 321 | /* main loop of interpreter */ |
357 | for (;;) { | 322 | for (;;) { |
358 | const Instruction i = *pc++; | 323 | const Instruction i = *pc++; |
@@ -535,18 +500,21 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { | |||
535 | case OP_CALL: { | 500 | case OP_CALL: { |
536 | StkId firstResult; | 501 | StkId firstResult; |
537 | int b = GETARG_B(i); | 502 | int b = GETARG_B(i); |
538 | if (b != NO_REG) L->top = ra+b+1; | 503 | int nresults; |
539 | /* else previous instruction set top */ | 504 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
505 | nresults = GETARG_C(i) - 1; | ||
540 | firstResult = luaD_precall(L, ra); | 506 | firstResult = luaD_precall(L, ra); |
541 | if (firstResult) { | 507 | if (firstResult) { |
508 | if (firstResult == base) { /* yield?? */ | ||
509 | (L->ci-1)->savedpc = pc; | ||
510 | return NULL; | ||
511 | } | ||
542 | /* it was a C function (`precall' called it); adjust results */ | 512 | /* it was a C function (`precall' called it); adjust results */ |
543 | luaV_poscall(L, GETARG_C(i), firstResult, L->ci); | 513 | luaD_poscall(L, nresults, firstResult); |
514 | if (nresults >= 0) L->top = L->ci->top; | ||
544 | } | 515 | } |
545 | else { /* it is a Lua function: `call' it */ | 516 | else { /* it is a Lua function: `call' it */ |
546 | CallInfo *ci = L->ci; | 517 | (L->ci-1)->savedpc = pc; |
547 | (ci-1)->savedpc = pc; | ||
548 | base = ci->base; | ||
549 | cl = &clvalue(base - 1)->l; | ||
550 | goto reinit; | 518 | goto reinit; |
551 | } | 519 | } |
552 | break; | 520 | break; |
@@ -556,19 +524,23 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { | |||
556 | int b; | 524 | int b; |
557 | if (L->openupval) luaF_close(L, base); | 525 | if (L->openupval) luaF_close(L, base); |
558 | b = GETARG_B(i); | 526 | b = GETARG_B(i); |
559 | if (b != NO_REG) L->top = ra+b; | 527 | if (b != 0) L->top = ra+b-1; |
560 | ci = L->ci - 1; | 528 | ci = L->ci - 1; |
561 | if (ci->savedpc == NULL) | 529 | if (ci->savedpc == NULL) |
562 | return ra; | 530 | return ra; |
563 | else { /* previous function is Lua: continue its execution */ | 531 | else { /* previous function is Lua: continue its execution */ |
532 | int nresults; | ||
564 | lua_assert(ttype(ci->base-1) == LUA_TFUNCTION); | 533 | lua_assert(ttype(ci->base-1) == LUA_TFUNCTION); |
565 | base = ci->base; /* restore previous values */ | 534 | base = ci->base; /* restore previous values */ |
566 | linehook = ci->linehook; | 535 | linehook = ci->linehook; |
567 | cl = &clvalue(base - 1)->l; | 536 | cl = &clvalue(base - 1)->l; |
537 | k = cl->p->k; | ||
568 | pc = ci->savedpc; | 538 | pc = ci->savedpc; |
569 | ci->savedpc = NULL; | 539 | ci->savedpc = NULL; |
570 | lua_assert(GET_OPCODE(*(pc-1)) == OP_CALL); | 540 | lua_assert(GET_OPCODE(*(pc-1)) == OP_CALL); |
571 | luaV_poscall(L, GETARG_C(*(pc-1)), ra, ci); | 541 | nresults = GETARG_C(*(pc-1)) - 1; |
542 | luaD_poscall(L, nresults, ra); | ||
543 | if (nresults >= 0) L->top = L->ci->top; | ||
572 | } | 544 | } |
573 | break; | 545 | break; |
574 | } | 546 | } |
@@ -20,7 +20,7 @@ const TObject *luaV_tonumber (const TObject *obj, TObject *n); | |||
20 | int luaV_tostring (lua_State *L, TObject *obj); | 20 | int luaV_tostring (lua_State *L, TObject *obj); |
21 | void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res); | 21 | void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res); |
22 | void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val); | 22 | void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val); |
23 | StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base); | 23 | StkId luaV_execute (lua_State *L); |
24 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); | 24 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); |
25 | void luaV_strconc (lua_State *L, int total, StkId top); | 25 | void luaV_strconc (lua_State *L, int total, StkId top); |
26 | 26 | ||