summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lbaselib.c81
-rw-r--r--lcode.c3
-rw-r--r--ldebug.c15
-rw-r--r--ldo.c126
-rw-r--r--lopcodes.h19
-rw-r--r--lparser.c10
-rw-r--r--lstate.c1
-rw-r--r--lstate.h6
-rw-r--r--lua.h17
-rw-r--r--lvm.c86
-rw-r--r--lvm.h2
11 files changed, 229 insertions, 137 deletions
diff --git a/lbaselib.c b/lbaselib.c
index cb914f18..6cd97d95 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -148,30 +148,6 @@ static int luaB_eventtable (lua_State *L) {
148} 148}
149 149
150 150
151static 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
175static int luaB_globals (lua_State *L) { 151static 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
266static 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
415static 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
422static 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
439static int luaB_yield (lua_State *L) {
440 return lua_yield(L, 0);
441}
442
443
444/*
445** {======================================================
446** Auxiliar table-related functions
447*/
448
431static int luaB_foreachi (lua_State *L) { 449static 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
467static 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
476static int luaB_getn (lua_State *L) { 485static 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
632static const luaL_reg base_funcs[] = { 642static 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
diff --git a/lcode.c b/lcode.c
index 4e8d23c1..a93b52b9 100644
--- a/lcode.c
+++ b/lcode.c
@@ -264,8 +264,7 @@ static int nil_constant (FuncState *fs) {
264 264
265void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) { 265void 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));
diff --git a/ldebug.c b/ldebug.c
index 16a3c5c5..17a0f11a 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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:
diff --git a/ldo.c b/ldo.c
index fedc0e35..c161cfe8 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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
117static CallInfo *growci (lua_State *L) { 116static 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
126static 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
127StkId luaD_precall (lua_State *L, StkId func) { 149StkId 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*/
180void luaD_call (lua_State *L, StkId func, int nResults) { 220void 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
233LUA_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
243LUA_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
263LUA_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*/
332void luaD_error (lua_State *L, const char *s) { 420void 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
diff --git a/lopcodes.h b/lopcodes.h
index b9539a9a..722e3d6a 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -168,8 +168,8 @@ OP_TESTGE,/* A C test := (R(A) >= R/K(C)) */
168OP_TESTT,/* A B test := R(B); if (test) R(A) := R(B) */ 168OP_TESTT,/* A B test := R(B); if (test) R(A) := R(B) */
169OP_TESTF,/* A B test := not R(B); if (test) R(A) := R(B) */ 169OP_TESTF,/* A B test := not R(B); if (test) R(A) := R(B) */
170 170
171OP_CALL,/* A B C R(A), ... ,R(A+C-1) := R(A)(R(A+1), ... ,R(A+B))*/ 171OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1))*/
172OP_RETURN,/* A B return R(A), ... ,R(A+B-1) (see (3)) */ 172OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see (3)) */
173 173
174OP_FORPREP,/* A sBc */ 174OP_FORPREP,/* A sBc */
175OP_FORLOOP,/* A sBc */ 175OP_FORLOOP,/* A sBc */
@@ -182,6 +182,9 @@ OP_SETLISTO,/* A Bc */
182 182
183OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ 183OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
184OP_CLOSURE /* A Bc R(A) := closure(KPROTO[Bc], R(A), ... ,R(A+n)) */ 184OP_CLOSURE /* A Bc R(A) := closure(KPROTO[Bc], R(A), ... ,R(A+n)) */
185/*----------------------------------------------------------------------
186pseudo-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
230extern 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*/
226extern const char *const luaP_opnames[]; 235extern const char *const luaP_opnames[];
diff --git a/lparser.c b/lparser.c
index 2a11fef6..0e43b2ba 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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
diff --git a/lstate.c b/lstate.c
index 504313d6..bf669bec 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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
diff --git a/lstate.h b/lstate.h
index db7c7b86..b7d69af6 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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
44struct lua_longjmp; /* defined in ldo.c */ 48struct 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' */
diff --git a/lua.h b/lua.h
index ed779771..0a2f5b10 100644
--- a/lua.h
+++ b/lua.h
@@ -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
53typedef struct lua_State lua_State; 49typedef 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,
182LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, 178LUA_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*/
185LUA_API void lua_cobegin (lua_State *L, int nargs);
186LUA_API int lua_yield (lua_State *L, int nresults);
187LUA_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);
203LUA_API void *lua_newuserdata (lua_State *L, size_t size); 207LUA_API void *lua_newuserdata (lua_State *L, size_t size);
204LUA_API void lua_newuserdatabox (lua_State *L, void *u); 208LUA_API void lua_newuserdatabox (lua_State *L, void *u);
205 209
206LUA_API void lua_setweakmode (lua_State *L, int mode);
207LUA_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
245LUA_API void lua_pushupvalues (lua_State *L); 246LUA_API int lua_pushupvalues (lua_State *L);
246 247
247#define lua_isnull lua_isnone 248#define lua_isnull lua_isnone
248 249
diff --git a/lvm.c b/lvm.c
index a073d39d..bec488f1 100644
--- a/lvm.c
+++ b/lvm.c
@@ -254,29 +254,6 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
254} 254}
255 255
256 256
257static 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
280static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { 257static 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*/
340StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { 307StkId 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 }
diff --git a/lvm.h b/lvm.h
index 1e0369fc..ebe15e65 100644
--- a/lvm.h
+++ b/lvm.h
@@ -20,7 +20,7 @@ const TObject *luaV_tonumber (const TObject *obj, TObject *n);
20int luaV_tostring (lua_State *L, TObject *obj); 20int luaV_tostring (lua_State *L, TObject *obj);
21void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res); 21void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res);
22void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val); 22void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val);
23StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base); 23StkId luaV_execute (lua_State *L);
24int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); 24int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
25void luaV_strconc (lua_State *L, int total, StkId top); 25void luaV_strconc (lua_State *L, int total, StkId top);
26 26