lvm.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. /*
  2. ** $Id: lvm.c,v 1.67 1999/11/25 18:59:43 roberto Exp roberto $
  3. ** Lua virtual machine
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #define LUA_REENTRANT
  10. #include "lauxlib.h"
  11. #include "ldo.h"
  12. #include "lfunc.h"
  13. #include "lgc.h"
  14. #include "lobject.h"
  15. #include "lopcodes.h"
  16. #include "lstate.h"
  17. #include "lstring.h"
  18. #include "ltable.h"
  19. #include "ltm.h"
  20. #include "lvm.h"
  21. #ifdef OLD_ANSI
  22. #define strcoll(a,b) strcmp(a,b)
  23. #endif
  24. #define highbyte(L, x) ((x)<<8)
  25. /* Extra stack size to run a function: LUA_T_LINE(1), TM calls(2), ... */
  26. #define EXTRA_STACK 5
  27. static TaggedString *strconc (lua_State *L, const TaggedString *l,
  28. const TaggedString *r) {
  29. long nl = l->u.s.len;
  30. long nr = r->u.s.len;
  31. char *buffer = luaL_openspace(L, nl+nr);
  32. memcpy(buffer, l->str, nl);
  33. memcpy(buffer+nl, r->str, nr);
  34. return luaS_newlstr(L, buffer, nl+nr);
  35. }
  36. int luaV_tonumber (TObject *obj) { /* LUA_NUMBER */
  37. if (ttype(obj) != LUA_T_STRING)
  38. return 1;
  39. else {
  40. if (!luaO_str2d(svalue(obj), &nvalue(obj)))
  41. return 2;
  42. ttype(obj) = LUA_T_NUMBER;
  43. return 0;
  44. }
  45. }
  46. int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */
  47. if (ttype(obj) != LUA_T_NUMBER)
  48. return 1;
  49. else {
  50. char s[32]; /* 16 digits, signal, point and \0 (+ some extra...) */
  51. sprintf(s, "%.16g", (double)nvalue(obj));
  52. tsvalue(obj) = luaS_new(L, s);
  53. ttype(obj) = LUA_T_STRING;
  54. return 0;
  55. }
  56. }
  57. void luaV_setn (lua_State *L, Hash *t, int val) {
  58. TObject index, value;
  59. ttype(&index) = LUA_T_STRING; tsvalue(&index) = luaS_new(L, "n");
  60. ttype(&value) = LUA_T_NUMBER; nvalue(&value) = val;
  61. luaH_set(L, t, &index, &value);
  62. }
  63. void luaV_closure (lua_State *L, int nelems) {
  64. if (nelems > 0) {
  65. struct Stack *S = &L->stack;
  66. Closure *c = luaF_newclosure(L, nelems);
  67. c->consts[0] = *(S->top-1);
  68. memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject));
  69. S->top -= nelems;
  70. ttype(S->top-1) = LUA_T_CLOSURE;
  71. (S->top-1)->value.cl = c;
  72. }
  73. }
  74. /*
  75. ** Function to index a table.
  76. ** Receives the table at top-2 and the index at top-1.
  77. */
  78. void luaV_gettable (lua_State *L) {
  79. TObject *table = L->stack.top-2;
  80. const TObject *im;
  81. if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */
  82. im = luaT_getimbyObj(L, table, IM_GETTABLE);
  83. if (ttype(im) == LUA_T_NIL)
  84. lua_error(L, "indexed expression not a table");
  85. }
  86. else { /* object is a table... */
  87. int tg = table->value.a->htag;
  88. im = luaT_getim(L, tg, IM_GETTABLE);
  89. if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */
  90. const TObject *h = luaH_get(L, avalue(table), table+1);
  91. if (ttype(h) == LUA_T_NIL &&
  92. (ttype(im=luaT_getim(L, tg, IM_INDEX)) != LUA_T_NIL)) {
  93. /* result is nil and there is an "index" tag method */
  94. luaD_callTM(L, im, 2, 1); /* calls it */
  95. }
  96. else {
  97. L->stack.top--;
  98. *table = *h; /* "push" result into table position */
  99. }
  100. return;
  101. }
  102. /* else it has a "gettable" method, go through to next command */
  103. }
  104. /* object is not a table, or it has a "gettable" method */
  105. luaD_callTM(L, im, 2, 1);
  106. }
  107. /*
  108. ** Receives table at *t, index at *(t+1) and value at top.
  109. */
  110. void luaV_settable (lua_State *L, const TObject *t) {
  111. struct Stack *S = &L->stack;
  112. const TObject *im;
  113. if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */
  114. im = luaT_getimbyObj(L, t, IM_SETTABLE);
  115. if (ttype(im) == LUA_T_NIL)
  116. lua_error(L, "indexed expression not a table");
  117. }
  118. else { /* object is a table... */
  119. im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE);
  120. if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */
  121. luaH_set(L, avalue(t), t+1, S->top-1);
  122. S->top--; /* pop value */
  123. return;
  124. }
  125. /* else it has a "settable" method, go through to next command */
  126. }
  127. /* object is not a table, or it has a "settable" method */
  128. /* prepare arguments and call the tag method */
  129. *(S->top+1) = *(L->stack.top-1);
  130. *(S->top) = *(t+1);
  131. *(S->top-1) = *t;
  132. S->top += 2; /* WARNING: caller must assure stack space */
  133. luaD_callTM(L, im, 3, 0);
  134. }
  135. void luaV_rawsettable (lua_State *L, const TObject *t) {
  136. if (ttype(t) != LUA_T_ARRAY)
  137. lua_error(L, "indexed expression not a table");
  138. else {
  139. struct Stack *S = &L->stack;
  140. luaH_set(L, avalue(t), t+1, S->top-1);
  141. S->top -= 3;
  142. }
  143. }
  144. void luaV_getglobal (lua_State *L, GlobalVar *gv) {
  145. /* WARNING: caller must assure stack space */
  146. const TObject *value = &gv->value;
  147. switch (ttype(value)) {
  148. /* only userdata, tables and nil can have getglobal tag methods */
  149. case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: {
  150. TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL);
  151. if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */
  152. struct Stack *S = &L->stack;
  153. ttype(S->top) = LUA_T_STRING;
  154. tsvalue(S->top) = gv->name; /* global name */
  155. S->top++;
  156. *S->top++ = *value;
  157. luaD_callTM(L, im, 2, 1);
  158. return;
  159. }
  160. /* else no tag method: go through to default behavior */
  161. }
  162. default: *L->stack.top++ = *value; /* default behavior */
  163. }
  164. }
  165. void luaV_setglobal (lua_State *L, GlobalVar *gv) {
  166. const TObject *oldvalue = &gv->value;
  167. const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL);
  168. if (ttype(im) == LUA_T_NIL) /* is there a tag method? */
  169. gv->value = *(--L->stack.top);
  170. else {
  171. /* WARNING: caller must assure stack space */
  172. struct Stack *S = &L->stack;
  173. TObject newvalue;
  174. newvalue = *(S->top-1);
  175. ttype(S->top-1) = LUA_T_STRING;
  176. tsvalue(S->top-1) = gv->name;
  177. *S->top++ = *oldvalue;
  178. *S->top++ = newvalue;
  179. luaD_callTM(L, im, 3, 0);
  180. }
  181. }
  182. static void call_binTM (lua_State *L, IMS event, const char *msg) {
  183. /* try first operand */
  184. const TObject *im = luaT_getimbyObj(L, L->stack.top-2, event);
  185. if (ttype(im) == LUA_T_NIL) {
  186. im = luaT_getimbyObj(L, L->stack.top-1, event); /* try second operand */
  187. if (ttype(im) == LUA_T_NIL) {
  188. im = luaT_getim(L, 0, event); /* try a 'global' i.m. */
  189. if (ttype(im) == LUA_T_NIL)
  190. lua_error(L, msg);
  191. }
  192. }
  193. lua_pushstring(L, luaT_eventname[event]);
  194. luaD_callTM(L, im, 3, 1);
  195. }
  196. static void call_arith (lua_State *L, IMS event) {
  197. call_binTM(L, event, "unexpected type in arithmetic operation");
  198. }
  199. static int luaV_strcomp (const char *l, long ll, const char *r, long lr) {
  200. for (;;) {
  201. long temp = strcoll(l, r);
  202. if (temp != 0) return temp;
  203. /* strings are equal up to a '\0' */
  204. temp = strlen(l); /* index of first '\0' in both strings */
  205. if (temp == ll) /* l is finished? */
  206. return (temp == lr) ? 0 : -1; /* l is equal or smaller than r */
  207. else if (temp == lr) /* r is finished? */
  208. return 1; /* l is greater than r (because l is not finished) */
  209. /* both strings longer than temp; go on comparing (after the '\0') */
  210. temp++;
  211. l += temp; ll -= temp; r += temp; lr -= temp;
  212. }
  213. }
  214. void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal,
  215. lua_Type ttype_great, IMS op) {
  216. struct Stack *S = &L->stack;
  217. const TObject *l = S->top-2;
  218. const TObject *r = S->top-1;
  219. real result;
  220. if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
  221. result = nvalue(l)-nvalue(r);
  222. else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
  223. result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len,
  224. svalue(r), tsvalue(r)->u.s.len);
  225. else {
  226. call_binTM(L, op, "unexpected type in comparison");
  227. return;
  228. }
  229. S->top--;
  230. nvalue(S->top-1) = 1;
  231. ttype(S->top-1) = (result < 0) ? ttype_less :
  232. (result == 0) ? ttype_equal : ttype_great;
  233. }
  234. void luaV_pack (lua_State *L, StkId firstel, int nvararg, TObject *tab) {
  235. TObject *firstelem = L->stack.stack+firstel;
  236. int i;
  237. Hash *htab;
  238. if (nvararg < 0) nvararg = 0;
  239. htab = avalue(tab) = luaH_new(L, nvararg+1); /* +1 for field 'n' */
  240. ttype(tab) = LUA_T_ARRAY;
  241. for (i=0; i<nvararg; i++)
  242. luaH_setint(L, htab, i+1, firstelem+i);
  243. luaV_setn(L, htab, nvararg); /* store counter in field "n" */
  244. }
  245. static void adjust_varargs (lua_State *L, StkId first_extra_arg) {
  246. TObject arg;
  247. luaV_pack(L, first_extra_arg,
  248. (L->stack.top-L->stack.stack)-first_extra_arg, &arg);
  249. luaD_adjusttop(L, first_extra_arg);
  250. *L->stack.top++ = arg;
  251. }
  252. /*
  253. ** Execute the given opcode, until a RET. Parameters are between
  254. ** [stack+base,top). Returns n such that the the results are between
  255. ** [stack+n,top).
  256. */
  257. StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
  258. StkId base) {
  259. struct Stack *S = &L->stack; /* to optimize */
  260. register const Byte *pc = tf->code;
  261. const TObject *consts = tf->consts;
  262. if (L->callhook)
  263. luaD_callHook(L, base, tf, 0);
  264. luaD_checkstack(L, (*pc++)+EXTRA_STACK);
  265. if (*pc < ZEROVARARG)
  266. luaD_adjusttop(L, base+*(pc++));
  267. else { /* varargs */
  268. luaC_checkGC(L);
  269. adjust_varargs(L, base+(*pc++)-ZEROVARARG);
  270. }
  271. for (;;) {
  272. register int aux = 0;
  273. switchentry:
  274. switch ((OpCode)*pc++) {
  275. case ENDCODE:
  276. S->top = S->stack + base;
  277. goto ret;
  278. case RETCODE:
  279. base += *pc++;
  280. goto ret;
  281. case CALL: aux = *pc++;
  282. luaD_call(L, (S->stack+base) + *pc++, aux);
  283. break;
  284. case TAILCALL: aux = *pc++;
  285. luaD_call(L, (S->stack+base) + *pc++, MULT_RET);
  286. base += aux;
  287. goto ret;
  288. case PUSHNIL: aux = *pc++;
  289. do {
  290. ttype(S->top++) = LUA_T_NIL;
  291. } while (aux--);
  292. break;
  293. case POP: aux = *pc++;
  294. S->top -= aux;
  295. break;
  296. case PUSHNUMBERW: aux += highbyte(L, *pc++);
  297. case PUSHNUMBER: aux += *pc++;
  298. ttype(S->top) = LUA_T_NUMBER;
  299. nvalue(S->top) = aux;
  300. S->top++;
  301. break;
  302. case PUSHNUMBERNEGW: aux += highbyte(L, *pc++);
  303. case PUSHNUMBERNEG: aux += *pc++;
  304. ttype(S->top) = LUA_T_NUMBER;
  305. nvalue(S->top) = -aux;
  306. S->top++;
  307. break;
  308. case PUSHCONSTANTW: aux += highbyte(L, *pc++);
  309. case PUSHCONSTANT: aux += *pc++;
  310. *S->top++ = consts[aux];
  311. break;
  312. case PUSHUPVALUE: aux = *pc++;
  313. *S->top++ = cl->consts[aux+1];
  314. break;
  315. case PUSHLOCAL: aux = *pc++;
  316. *S->top++ = *((S->stack+base) + aux);
  317. break;
  318. case GETGLOBALW: aux += highbyte(L, *pc++);
  319. case GETGLOBAL: aux += *pc++;
  320. luaV_getglobal(L, tsvalue(&consts[aux])->u.s.gv);
  321. break;
  322. case GETTABLE:
  323. luaV_gettable(L);
  324. break;
  325. case GETDOTTEDW: aux += highbyte(L, *pc++);
  326. case GETDOTTED: aux += *pc++;
  327. *S->top++ = consts[aux];
  328. luaV_gettable(L);
  329. break;
  330. case PUSHSELFW: aux += highbyte(L, *pc++);
  331. case PUSHSELF: aux += *pc++; {
  332. TObject receiver;
  333. receiver = *(S->top-1);
  334. *S->top++ = consts[aux];
  335. luaV_gettable(L);
  336. *S->top++ = receiver;
  337. break;
  338. }
  339. case CREATEARRAYW: aux += highbyte(L, *pc++);
  340. case CREATEARRAY: aux += *pc++;
  341. luaC_checkGC(L);
  342. avalue(S->top) = luaH_new(L, aux);
  343. ttype(S->top) = LUA_T_ARRAY;
  344. S->top++;
  345. break;
  346. case SETLOCAL: aux = *pc++;
  347. *((S->stack+base) + aux) = *(--S->top);
  348. break;
  349. case SETGLOBALW: aux += highbyte(L, *pc++);
  350. case SETGLOBAL: aux += *pc++;
  351. luaV_setglobal(L, tsvalue(&consts[aux])->u.s.gv);
  352. break;
  353. case SETTABLEPOP:
  354. luaV_settable(L, S->top-3);
  355. S->top -= 2; /* pop table and index */
  356. break;
  357. case SETTABLE:
  358. luaV_settable(L, S->top-3-(*pc++));
  359. break;
  360. case SETLISTW: aux += highbyte(L, *pc++);
  361. case SETLIST: aux += *pc++; {
  362. int n = *(pc++);
  363. Hash *arr = avalue(S->top-n-1);
  364. aux *= LFIELDS_PER_FLUSH;
  365. for (; n; n--)
  366. luaH_setint(L, arr, n+aux, --S->top);
  367. break;
  368. }
  369. case SETMAP: aux = *pc++; {
  370. Hash *arr = avalue(S->top-(2*aux)-3);
  371. do {
  372. luaH_set(L, arr, S->top-2, S->top-1);
  373. S->top-=2;
  374. } while (aux--);
  375. break;
  376. }
  377. case NEQOP: aux = 1;
  378. case EQOP: {
  379. int res = luaO_equalObj(S->top-2, S->top-1);
  380. if (aux) res = !res;
  381. S->top--;
  382. ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
  383. nvalue(S->top-1) = 1;
  384. break;
  385. }
  386. case LTOP:
  387. luaV_comparison(L, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
  388. break;
  389. case LEOP:
  390. luaV_comparison(L, LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
  391. break;
  392. case GTOP:
  393. luaV_comparison(L, LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
  394. break;
  395. case GEOP:
  396. luaV_comparison(L, LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
  397. break;
  398. case ADDOP: {
  399. TObject *l = S->top-2;
  400. TObject *r = S->top-1;
  401. if (tonumber(r) || tonumber(l))
  402. call_arith(L, IM_ADD);
  403. else {
  404. nvalue(l) += nvalue(r);
  405. --S->top;
  406. }
  407. break;
  408. }
  409. case SUBOP: {
  410. TObject *l = S->top-2;
  411. TObject *r = S->top-1;
  412. if (tonumber(r) || tonumber(l))
  413. call_arith(L, IM_SUB);
  414. else {
  415. nvalue(l) -= nvalue(r);
  416. --S->top;
  417. }
  418. break;
  419. }
  420. case MULTOP: {
  421. TObject *l = S->top-2;
  422. TObject *r = S->top-1;
  423. if (tonumber(r) || tonumber(l))
  424. call_arith(L, IM_MUL);
  425. else {
  426. nvalue(l) *= nvalue(r);
  427. --S->top;
  428. }
  429. break;
  430. }
  431. case DIVOP: {
  432. TObject *l = S->top-2;
  433. TObject *r = S->top-1;
  434. if (tonumber(r) || tonumber(l))
  435. call_arith(L, IM_DIV);
  436. else {
  437. nvalue(l) /= nvalue(r);
  438. --S->top;
  439. }
  440. break;
  441. }
  442. case POWOP:
  443. call_binTM(L, IM_POW, "undefined operation");
  444. break;
  445. case CONCOP: {
  446. TObject *l = S->top-2;
  447. TObject *r = S->top-1;
  448. if (tostring(L, l) || tostring(L, r))
  449. call_binTM(L, IM_CONCAT, "unexpected type for concatenation");
  450. else {
  451. tsvalue(l) = strconc(L, tsvalue(l), tsvalue(r));
  452. --S->top;
  453. }
  454. luaC_checkGC(L);
  455. break;
  456. }
  457. case MINUSOP:
  458. if (tonumber(S->top-1)) {
  459. ttype(S->top) = LUA_T_NIL;
  460. S->top++;
  461. call_arith(L, IM_UNM);
  462. }
  463. else
  464. nvalue(S->top-1) = - nvalue(S->top-1);
  465. break;
  466. case NOTOP:
  467. ttype(S->top-1) =
  468. (ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
  469. nvalue(S->top-1) = 1;
  470. break;
  471. case ONTJMPW: aux += highbyte(L, *pc++);
  472. case ONTJMP: aux += *pc++;
  473. if (ttype(S->top-1) != LUA_T_NIL) pc += aux;
  474. else S->top--;
  475. break;
  476. case ONFJMPW: aux += highbyte(L, *pc++);
  477. case ONFJMP: aux += *pc++;
  478. if (ttype(S->top-1) == LUA_T_NIL) pc += aux;
  479. else S->top--;
  480. break;
  481. case JMPW: aux += highbyte(L, *pc++);
  482. case JMP: aux += *pc++;
  483. pc += aux;
  484. break;
  485. case IFFJMPW: aux += highbyte(L, *pc++);
  486. case IFFJMP: aux += *pc++;
  487. if (ttype(--S->top) == LUA_T_NIL) pc += aux;
  488. break;
  489. case IFTUPJMPW: aux += highbyte(L, *pc++);
  490. case IFTUPJMP: aux += *pc++;
  491. if (ttype(--S->top) != LUA_T_NIL) pc -= aux;
  492. break;
  493. case IFFUPJMPW: aux += highbyte(L, *pc++);
  494. case IFFUPJMP: aux += *pc++;
  495. if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
  496. break;
  497. case CLOSUREW: aux += highbyte(L, *pc++);
  498. case CLOSURE: aux += *pc++;
  499. *S->top++ = consts[aux];
  500. luaV_closure(L, *pc++);
  501. luaC_checkGC(L);
  502. break;
  503. case SETLINEW: aux += highbyte(L, *pc++);
  504. case SETLINE: aux += *pc++;
  505. if ((S->stack+base-1)->ttype != LUA_T_LINE) {
  506. /* open space for LINE value */
  507. luaD_openstack(L, (S->top-S->stack)-base);
  508. base++;
  509. (S->stack+base-1)->ttype = LUA_T_LINE;
  510. }
  511. (S->stack+base-1)->value.i = aux;
  512. if (L->linehook)
  513. luaD_lineHook(L, aux);
  514. break;
  515. case LONGARGW: aux += highbyte(L, *pc++);
  516. case LONGARG: aux += *pc++;
  517. aux = highbyte(L, highbyte(L, aux));
  518. goto switchentry; /* do not reset "aux" */
  519. }
  520. } ret:
  521. if (L->callhook)
  522. luaD_callHook(L, 0, NULL, 1);
  523. return base;
  524. }