1 /*
2 ** $Id: lvm.cpp 940 2008-07-26 19:30:44Z aquadran $
3 ** Lua virtual machine
4 ** See Copyright Notice in lua.h
5 */
6
7
8 #include "lauxlib.h"
9 #include "ldo.h"
10 #include "lfunc.h"
11 #include "lgc.h"
12 #include "lmem.h"
13 #include "lopcodes.h"
14 #include "lstate.h"
15 #include "lstring.h"
16 #include "ltable.h"
17 #include "ltm.h"
18 #include "luadebug.h"
19 #include "lvm.h"
20
21
22 #define skip_word(pc) (pc+=2)
23
24 #define get_word(pc) ((*((pc)+1)<<8)|(*(pc)))
25
26 #define next_word(pc) (pc+=2, get_word(pc-2))
27
28
strconc(TaggedString * l,TaggedString * r)29 static TaggedString *strconc (TaggedString *l, TaggedString *r)
30 {
31 size_t nl = l->u.s.len;
32 size_t nr = r->u.s.len;
33 char *buffer = luaL_openspace(nl+nr+1);
34 memcpy(buffer, l->str, nl);
35 memcpy(buffer+nl, r->str, nr);
36 return luaS_newlstr(buffer, nl+nr);
37 }
38
39
luaV_tonumber(TObject * obj)40 int32 luaV_tonumber (TObject *obj)
41 { /* LUA_NUMBER */
42 double t;
43 char c;
44 if (ttype(obj) != LUA_T_STRING)
45 return 1;
46 else if (sscanf(svalue(obj), "%lf %c",&t, &c) == 1) {
47 nvalue(obj) = (real)t;
48 ttype(obj) = LUA_T_NUMBER;
49 return 0;
50 }
51 else
52 return 2;
53 }
54
55
luaV_tostring(TObject * obj)56 int32 luaV_tostring (TObject *obj)
57 { /* LUA_NUMBER */
58 /* The Lua scripts for Grim Fandango sometimes end up executing
59 str..nil. The nil shows up in the original engine as "(nil)"... */
60 if (ttype(obj) == LUA_T_NIL) {
61 tsvalue(obj) = luaS_new("(nil)");
62 ttype(obj) = LUA_T_STRING;
63 return 0;
64 }
65 else if (ttype(obj) != LUA_T_NUMBER)
66 return 1;
67 else {
68 char s[60];
69 real f = nvalue(obj);
70 int32 i;
71 if ((real)(-MAX_INT) <= f && f <= (real)MAX_INT && (real)(i=(int32)f) == f)
72 sprintf (s, "%d", (int)i);
73 else
74 sprintf (s, NUMBER_FMT, nvalue(obj));
75 tsvalue(obj) = luaS_new(s);
76 ttype(obj) = LUA_T_STRING;
77 return 0;
78 }
79 }
80
81
luaV_closure(int32 nelems)82 void luaV_closure (int32 nelems)
83 {
84 if (nelems > 0) {
85 struct Stack *S = &L->stack;
86 Closure *c = luaF_newclosure(nelems);
87 c->consts[0] = *(S->top-1);
88 memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject));
89 S->top -= nelems;
90 ttype(S->top-1) = LUA_T_CLOSURE;
91 (S->top-1)->value.cl = c;
92 }
93 }
94
95
96 /*
97 ** Function to index a table.
98 ** Receives the table at top-2 and the index at top-1.
99 */
luaV_gettable(void)100 void luaV_gettable (void)
101 {
102 struct Stack *S = &L->stack;
103 TObject *im;
104 if (ttype(S->top-2) != LUA_T_ARRAY) /* not a table, get "gettable" method */
105 im = luaT_getimbyObj(S->top-2, IM_GETTABLE);
106 else { /* object is a table... */
107 int32 tg = (S->top-2)->value.a->htag;
108 im = luaT_getim(tg, IM_GETTABLE);
109 if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */
110 TObject *h = luaH_get(avalue(S->top-2), S->top-1);
111 if (h != NULL && ttype(h) != LUA_T_NIL) {
112 --S->top;
113 *(S->top-1) = *h;
114 }
115 else if (ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL)
116 luaD_callTM(im, 2, 1);
117 else {
118 --S->top;
119 ttype(S->top-1) = LUA_T_NIL;
120 }
121 return;
122 }
123 /* else it has a "gettable" method, go through to next command */
124 }
125 /* object is not a table, or it has a "gettable" method */
126 if (ttype(im) != LUA_T_NIL)
127 luaD_callTM(im, 2, 1);
128 else
129 lua_error("indexed expression not a table");
130 }
131
132
133 /*
134 ** Function to store indexed based on values at the stack.top
135 ** mode = 0: raw store (without tag methods)
136 ** mode = 1: normal store (with tag methods)
137 ** mode = 2: "deep L->stack.stack" store (with tag methods)
138 */
luaV_settable(TObject * t,int32 mode)139 void luaV_settable (TObject *t, int32 mode)
140 {
141 struct Stack *S = &L->stack;
142 TObject *im = (mode == 0) ? NULL : luaT_getimbyObj(t, IM_SETTABLE);
143 if (ttype(t) == LUA_T_ARRAY && (im == NULL || ttype(im) == LUA_T_NIL)) {
144 TObject *h = luaH_set(avalue(t), t+1);
145 *h = *(S->top-1);
146 S->top -= (mode == 2) ? 1 : 3;
147 }
148 else { /* object is not a table, and/or has a specific "settable" method */
149 if (im && ttype(im) != LUA_T_NIL) {
150 if (mode == 2) {
151 *(S->top+1) = *(L->stack.top-1);
152 *(S->top) = *(t+1);
153 *(S->top-1) = *t;
154 S->top += 2; /* WARNING: caller must assure stack space */
155 }
156 luaD_callTM(im, 3, 0);
157 }
158 else
159 lua_error("indexed expression not a table");
160 }
161 }
162
163
luaV_getglobal(TaggedString * ts)164 void luaV_getglobal (TaggedString *ts)
165 {
166 /* WARNING: caller must assure stack space */
167 TObject *value = &ts->u.s.globalval;
168 TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
169 if (ttype(im) == LUA_T_NIL) { /* default behavior */
170 *L->stack.top++ = *value;
171 }
172 else {
173 struct Stack *S = &L->stack;
174 ttype(S->top) = LUA_T_STRING;
175 tsvalue(S->top) = ts;
176 S->top++;
177 *S->top++ = *value;
178 luaD_callTM(im, 2, 1);
179 }
180 }
181
182
luaV_setglobal(TaggedString * ts)183 void luaV_setglobal (TaggedString *ts)
184 {
185 TObject *oldvalue = &ts->u.s.globalval;
186 TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
187 if (ttype(im) == LUA_T_NIL) /* default behavior */
188 luaS_rawsetglobal(ts, --L->stack.top);
189 else {
190 /* WARNING: caller must assure stack space */
191 struct Stack *S = &L->stack;
192 TObject newvalue = *(S->top-1);
193 ttype(S->top-1) = LUA_T_STRING;
194 tsvalue(S->top-1) = ts;
195 *S->top++ = *oldvalue;
196 *S->top++ = newvalue;
197 luaD_callTM(im, 3, 0);
198 }
199 }
200
201
call_binTM(IMS event,const char * msg)202 static void call_binTM (IMS event, const char *msg)
203 {
204 TObject *im = luaT_getimbyObj(L->stack.top-2, event);/* try first operand */
205 if (ttype(im) == LUA_T_NIL) {
206 im = luaT_getimbyObj(L->stack.top-1, event); /* try second operand */
207 if (ttype(im) == LUA_T_NIL) {
208 im = luaT_getim(0, event); /* try a 'global' i.m. */
209 if (ttype(im) == LUA_T_NIL)
210 lua_error(msg);
211 }
212 }
213 lua_pushstring(luaT_eventname[event]);
214 luaD_callTM(im, 3, 1);
215 }
216
217
call_arith(IMS event)218 static void call_arith (IMS event)
219 {
220 call_binTM(event, "unexpected type in arithmetic operation");
221 }
222
223
strcomp(char * l,int32 ll,char * r,int32 lr)224 static int32 strcomp (char *l, int32 ll, char *r, int32 lr)
225 {
226 for (;;) {
227 int32 temp = (int32)strcoll(l, r);
228 if (temp != 0) return temp;
229 /* strings are equal up to a '\0' */
230 temp = strlen(l); /* index of first '\0' in both strings */
231 if (temp == ll) /* l is finished? */
232 return (temp == lr) ? 0 : -1; /* l is equal or smaller than r */
233 else if (temp == lr) /* r is finished? */
234 return 1; /* l is greater than r (because l is not finished) */
235 /* both strings longer than temp; go on comparing (after the '\0') */
236 temp++;
237 l += temp; ll -= temp; r += temp; lr -= temp;
238 }
239 }
240
comparison(lua_Type ttype_less,lua_Type ttype_equal,lua_Type ttype_great,IMS op)241 static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
242 lua_Type ttype_great, IMS op)
243 {
244 struct Stack *S = &L->stack;
245 TObject *l = S->top-2;
246 TObject *r = S->top-1;
247 int32 result;
248 if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
249 result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1;
250 else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
251 result = (int32)strcomp(svalue(l), tsvalue(l)->u.s.len,
252 svalue(r), tsvalue(r)->u.s.len);
253 else {
254 call_binTM(op, "unexpected type in comparison");
255 return;
256 }
257 S->top--;
258 nvalue(S->top-1) = 1;
259 ttype(S->top-1) = (result < 0) ? ttype_less :
260 (result == 0) ? ttype_equal : ttype_great;
261 }
262
263
luaV_pack(StkId firstel,int32 nvararg,TObject * tab)264 void luaV_pack (StkId firstel, int32 nvararg, TObject *tab)
265 {
266 TObject *firstelem = L->stack.stack+firstel;
267 int32 i;
268 if (nvararg < 0) nvararg = 0;
269 avalue(tab) = luaH_new(nvararg+1); /* +1 for field 'n' */
270 ttype(tab) = LUA_T_ARRAY;
271 for (i=0; i<nvararg; i++) {
272 TObject index;
273 ttype(&index) = LUA_T_NUMBER;
274 nvalue(&index) = (real)i+1;
275 *(luaH_set(avalue(tab), &index)) = *(firstelem+i);
276 }
277 /* store counter in field "n" */ {
278 TObject index, extra;
279 ttype(&index) = LUA_T_STRING;
280 tsvalue(&index) = luaS_new("n");
281 ttype(&extra) = LUA_T_NUMBER;
282 nvalue(&extra) = (real)nvararg;
283 *(luaH_set(avalue(tab), &index)) = extra;
284 }
285 }
286
287
288 /*
289 ** Execute the given opcode, until a RET. Parameters are between
290 ** [stack+base,top). Returns n such that the the results are between
291 ** [stack+n,top).
292 */
luaV_execute(struct CallInfo * ci)293 StkId luaV_execute (struct CallInfo *ci)
294 {
295 /* Save index in case CallInfo array is realloc'd */
296 int32 ci_index = ci - L->base_ci;
297 struct Stack *S = &L->stack; /* to optimize */
298 Closure *cl;
299 TProtoFunc *tf;
300 StkId base;
301 Byte *pc;
302 TObject *consts;
303 newfunc:
304 cl = L->ci->c;
305 tf = L->ci->tf;
306 base = L->ci->base;
307 if (S->top-S->stack > base && ttype(S->stack+base) == LUA_T_LINE)
308 base++;
309 pc = L->ci->pc;
310 consts = tf->consts;
311 while (1) {
312 int32 aux;
313 switch ((OpCode)(aux = *pc++)) {
314
315 case PUSHNIL0:
316 ttype(S->top++) = LUA_T_NIL;
317 break;
318
319 case PUSHNIL:
320 aux = *pc++;
321 do {
322 ttype(S->top++) = LUA_T_NIL;
323 } while (aux--);
324 break;
325
326 case PUSHNUMBER:
327 aux = *pc++; goto pushnumber;
328
329 case PUSHNUMBERW:
330 aux = next_word(pc); goto pushnumber;
331
332 case PUSHNUMBER0: case PUSHNUMBER1: case PUSHNUMBER2:
333 aux -= PUSHNUMBER0;
334 pushnumber:
335 ttype(S->top) = LUA_T_NUMBER;
336 nvalue(S->top) = (real)aux;
337 S->top++;
338 break;
339
340 case PUSHLOCAL:
341 aux = *pc++; goto pushlocal;
342
343 case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3:
344 case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7:
345 aux -= PUSHLOCAL0;
346 pushlocal:
347 *S->top++ = *((S->stack+base) + aux);
348 break;
349
350 case GETGLOBALW:
351 aux = next_word(pc); goto getglobal;
352
353 case GETGLOBAL:
354 aux = *pc++; goto getglobal;
355
356 case GETGLOBAL0: case GETGLOBAL1: case GETGLOBAL2: case GETGLOBAL3:
357 case GETGLOBAL4: case GETGLOBAL5: case GETGLOBAL6: case GETGLOBAL7:
358 aux -= GETGLOBAL0;
359 getglobal:
360 luaV_getglobal(tsvalue(&consts[aux]));
361 break;
362
363 case GETTABLE:
364 luaV_gettable();
365 break;
366
367 case GETDOTTEDW:
368 aux = next_word(pc); goto getdotted;
369
370 case GETDOTTED:
371 aux = *pc++; goto getdotted;
372
373 case GETDOTTED0: case GETDOTTED1: case GETDOTTED2: case GETDOTTED3:
374 case GETDOTTED4: case GETDOTTED5: case GETDOTTED6: case GETDOTTED7:
375 aux -= GETDOTTED0;
376 getdotted:
377 *S->top++ = consts[aux];
378 luaV_gettable();
379 break;
380
381 case PUSHSELFW:
382 aux = next_word(pc); goto pushself;
383
384 case PUSHSELF:
385 aux = *pc++; goto pushself;
386
387 case PUSHSELF0: case PUSHSELF1: case PUSHSELF2: case PUSHSELF3:
388 case PUSHSELF4: case PUSHSELF5: case PUSHSELF6: case PUSHSELF7:
389 aux -= PUSHSELF0;
390 pushself: {
391 TObject receiver = *(S->top-1);
392 *S->top++ = consts[aux];
393 luaV_gettable();
394 *S->top++ = receiver;
395 break;
396 }
397
398 case PUSHCONSTANTW:
399 aux = next_word(pc); goto pushconstant;
400
401 case PUSHCONSTANT:
402 aux = *pc++; goto pushconstant;
403
404 case PUSHCONSTANT0: case PUSHCONSTANT1: case PUSHCONSTANT2:
405 case PUSHCONSTANT3: case PUSHCONSTANT4: case PUSHCONSTANT5:
406 case PUSHCONSTANT6: case PUSHCONSTANT7:
407 aux -= PUSHCONSTANT0;
408 pushconstant:
409 *S->top++ = consts[aux];
410 break;
411
412 case PUSHUPVALUE:
413 aux = *pc++; goto pushupvalue;
414
415 case PUSHUPVALUE0: case PUSHUPVALUE1:
416 aux -= PUSHUPVALUE0;
417 pushupvalue:
418 *S->top++ = cl->consts[aux+1];
419 break;
420
421 case SETLOCAL:
422 aux = *pc++; goto setlocal;
423
424 case SETLOCAL0: case SETLOCAL1: case SETLOCAL2: case SETLOCAL3:
425 case SETLOCAL4: case SETLOCAL5: case SETLOCAL6: case SETLOCAL7:
426 aux -= SETLOCAL0;
427 setlocal:
428 *((S->stack+base) + aux) = *(--S->top);
429 break;
430
431 case SETGLOBALW:
432 aux = next_word(pc); goto setglobal;
433
434 case SETGLOBAL:
435 aux = *pc++; goto setglobal;
436
437 case SETGLOBAL0: case SETGLOBAL1: case SETGLOBAL2: case SETGLOBAL3:
438 case SETGLOBAL4: case SETGLOBAL5: case SETGLOBAL6: case SETGLOBAL7:
439 aux -= SETGLOBAL0;
440 setglobal:
441 luaV_setglobal(tsvalue(&consts[aux]));
442 break;
443
444 case SETTABLE0:
445 luaV_settable(S->top-3, 1);
446 break;
447
448 case SETTABLE:
449 luaV_settable(S->top-3-(*pc++), 2);
450 break;
451
452 case SETLISTW:
453 aux = next_word(pc); aux *= LFIELDS_PER_FLUSH; goto setlist;
454
455 case SETLIST:
456 aux = *(pc++) * LFIELDS_PER_FLUSH; goto setlist;
457
458 case SETLIST0:
459 aux = 0;
460 setlist: {
461 int32 n = *(pc++);
462 TObject *arr = S->top-n-1;
463 for (; n; n--) {
464 ttype(S->top) = LUA_T_NUMBER;
465 nvalue(S->top) = (real)(n+aux);
466 *(luaH_set(avalue(arr), S->top)) = *(S->top-1);
467 S->top--;
468 }
469 break;
470 }
471
472 case SETMAP0:
473 aux = 0; goto setmap;
474
475 case SETMAP:
476 aux = *pc++;
477 setmap: {
478 TObject *arr = S->top-(2*aux)-3;
479 do {
480 *(luaH_set(avalue(arr), S->top-2)) = *(S->top-1);
481 S->top-=2;
482 } while (aux--);
483 break;
484 }
485
486 case POP:
487 aux = *pc++; goto pop;
488
489 case POP0: case POP1:
490 aux -= POP0;
491 pop:
492 S->top -= (aux+1);
493 break;
494
495 case CREATEARRAYW:
496 aux = next_word(pc); goto createarray;
497
498 case CREATEARRAY0: case CREATEARRAY1:
499 aux -= CREATEARRAY0; goto createarray;
500
501 case CREATEARRAY:
502 aux = *pc++;
503 createarray:
504 luaC_checkGC();
505 avalue(S->top) = luaH_new(aux);
506 ttype(S->top) = LUA_T_ARRAY;
507 S->top++;
508 break;
509
510 case EQOP: case NEQOP: {
511 int32 res = luaO_equalObj(S->top-2, S->top-1);
512 S->top--;
513 if (aux == NEQOP) res = !res;
514 ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
515 nvalue(S->top-1) = 1;
516 break;
517 }
518
519 case LTOP:
520 comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
521 break;
522
523 case LEOP:
524 comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
525 break;
526
527 case GTOP:
528 comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
529 break;
530
531 case GEOP:
532 comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
533 break;
534
535 case ADDOP: {
536 TObject *l = S->top-2;
537 TObject *r = S->top-1;
538 if (tonumber(r) || tonumber(l))
539 call_arith(IM_ADD);
540 else {
541 nvalue(l) += nvalue(r);
542 --S->top;
543 }
544 break;
545 }
546
547 case SUBOP: {
548 TObject *l = S->top-2;
549 TObject *r = S->top-1;
550 if (tonumber(r) || tonumber(l))
551 call_arith(IM_SUB);
552 else {
553 nvalue(l) -= nvalue(r);
554 --S->top;
555 }
556 break;
557 }
558
559 case MULTOP: {
560 TObject *l = S->top-2;
561 TObject *r = S->top-1;
562 if (tonumber(r) || tonumber(l))
563 call_arith(IM_MUL);
564 else {
565 nvalue(l) *= nvalue(r);
566 --S->top;
567 }
568 break;
569 }
570
571 case DIVOP: {
572 TObject *l = S->top-2;
573 TObject *r = S->top-1;
574 if (tonumber(r) || tonumber(l))
575 call_arith(IM_DIV);
576 else {
577 nvalue(l) /= nvalue(r);
578 --S->top;
579 }
580 break;
581 }
582
583 case POWOP:
584 call_binTM(IM_POW, "undefined operation");
585 break;
586
587 case CONCOP: {
588 TObject *l = S->top-2;
589 TObject *r = S->top-1;
590 if (tostring(l) || tostring(r))
591 call_binTM(IM_CONCAT, "unexpected type for concatenation");
592 else {
593 tsvalue(l) = strconc(tsvalue(l), tsvalue(r));
594 --S->top;
595 }
596 luaC_checkGC();
597 break;
598 }
599
600 case MINUSOP:
601 if (tonumber(S->top-1)) {
602 ttype(S->top) = LUA_T_NIL;
603 S->top++;
604 call_arith(IM_UNM);
605 }
606 else
607 nvalue(S->top-1) = - nvalue(S->top-1);
608 break;
609
610 case NOTOP:
611 ttype(S->top-1) =
612 (ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
613 nvalue(S->top-1) = 1;
614 break;
615
616 case ONTJMPW:
617 aux = next_word(pc); goto ontjmp;
618
619 case ONTJMP:
620 aux = *pc++;
621 ontjmp:
622 if (ttype(S->top-1) != LUA_T_NIL) pc += aux;
623 else S->top--;
624 break;
625
626 case ONFJMPW:
627 aux = next_word(pc); goto onfjmp;
628
629 case ONFJMP:
630 aux = *pc++;
631 onfjmp:
632 if (ttype(S->top-1) == LUA_T_NIL) pc += aux;
633 else S->top--;
634 break;
635
636 case JMPW:
637 aux = next_word(pc); goto jmp;
638
639 case JMP:
640 aux = *pc++;
641 jmp:
642 pc += aux;
643 break;
644
645 case IFFJMPW:
646 aux = next_word(pc); goto iffjmp;
647
648 case IFFJMP:
649 aux = *pc++;
650 iffjmp:
651 if (ttype(--S->top) == LUA_T_NIL) pc += aux;
652 break;
653
654 case IFTUPJMPW:
655 aux = next_word(pc); goto iftupjmp;
656
657 case IFTUPJMP:
658 aux = *pc++;
659 iftupjmp:
660 if (ttype(--S->top) != LUA_T_NIL) pc -= aux;
661 break;
662
663 case IFFUPJMPW:
664 aux = next_word(pc); goto iffupjmp;
665
666 case IFFUPJMP:
667 aux = *pc++;
668 iffupjmp:
669 if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
670 break;
671
672 case CLOSURE:
673 aux = *pc++;
674 goto closure;
675
676 case CLOSURE0:
677 aux = 0;
678 goto closure;
679
680 case CLOSURE1:
681 aux = 1;
682 closure:
683 luaV_closure(aux);
684 luaC_checkGC();
685 break;
686
687 case CALLFUNC:
688 aux = *pc++; goto callfunc;
689
690 case CALLFUNC0: case CALLFUNC1:
691 aux -= CALLFUNC0;
692 callfunc: {
693 StkId newBase = (S->top-S->stack)-(*pc++);
694 TObject *func = S->stack+newBase-1;
695 L->ci->pc = pc;
696 if (ttype(func) == LUA_T_PROTO ||
697 (ttype(func) == LUA_T_CLOSURE &&
698 ttype(&clvalue(func)->consts[0]) == LUA_T_PROTO)) {
699
700 /* Calling another Lua function */
701 luaD_precall(func, newBase, aux);
702 ttype(func) = (ttype(func) == LUA_T_PROTO) ?
703 LUA_T_PMARK : LUA_T_CLMARK;
704 goto newfunc;
705 }
706 luaD_call(newBase, aux);
707
708 if (L->Tstate != RUN) {
709 if (ci_index > 1) /* C functions detected by break_here */
710 lua_error("Cannot yield through method call");
711 return -1;
712 }
713 break;
714 }
715
716 case ENDCODE:
717 S->top = S->stack + base;
718 /* goes through */
719 case RETCODE: {
720 StkId firstResult = (base + ((aux==RETCODE) ? *pc : 0));
721 if (lua_callhook)
722 luaD_callHook(base, NULL, 1);
723 /* If returning from the original stack frame, terminate */
724 if (L->ci == L->base_ci + ci_index)
725 return firstResult;
726 luaD_postret(firstResult);
727 goto newfunc;
728 }
729
730 case SETLINEW:
731 aux = next_word(pc); goto setline;
732
733 case SETLINE:
734 aux = *pc++;
735 setline:
736 if ((S->stack+base-1)->ttype != LUA_T_LINE) {
737 /* open space for LINE value */
738 luaD_openstack((S->top-S->stack)-base);
739 base++;
740 (S->stack+base-1)->ttype = LUA_T_LINE;
741 }
742 (S->stack+base-1)->value.i = aux;
743 if (lua_linehook)
744 luaD_lineHook(aux);
745 break;
746
747 #ifdef DEBUG
748 default:
749 LUA_INTERNALERROR("opcode doesn't match");
750 #endif
751 }
752 }
753 }
754
755