lapi.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. /*
  2. ** $Id: lapi.c,v 1.61 1999/12/01 19:50:08 roberto Exp roberto $
  3. ** Lua API
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <string.h>
  7. #define LUA_REENTRANT
  8. #include "lapi.h"
  9. #include "lauxlib.h"
  10. #include "ldo.h"
  11. #include "lfunc.h"
  12. #include "lgc.h"
  13. #include "lmem.h"
  14. #include "lobject.h"
  15. #include "lref.h"
  16. #include "lstate.h"
  17. #include "lstring.h"
  18. #include "ltable.h"
  19. #include "ltm.h"
  20. #include "lua.h"
  21. #include "luadebug.h"
  22. #include "lvm.h"
  23. const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
  24. "$Authors: " LUA_AUTHORS " $";
  25. static lua_Type normalized_type (const TObject *o) {
  26. int t = ttype(o);
  27. switch (t) {
  28. case LUA_T_PMARK:
  29. return LUA_T_PROTO;
  30. case LUA_T_CMARK:
  31. return LUA_T_CPROTO;
  32. case LUA_T_CLMARK:
  33. return LUA_T_CLOSURE;
  34. default:
  35. return t;
  36. }
  37. }
  38. static void set_normalized (TObject *d, const TObject *s) {
  39. d->value = s->value;
  40. d->ttype = normalized_type(s);
  41. }
  42. static const TObject *luaA_protovalue (const TObject *o) {
  43. return (normalized_type(o) == LUA_T_CLOSURE) ? protovalue(o) : o;
  44. }
  45. static void checkCparams (lua_State *L, int nParams) {
  46. if (nParams > L->top-L->Cstack.base)
  47. lua_error(L, "API error - wrong number of arguments in C2lua stack");
  48. }
  49. static lua_Object put_luaObject (lua_State *L, const TObject *o) {
  50. luaD_openstack(L, L->Cstack.base);
  51. *L->Cstack.base++ = *o;
  52. return L->Cstack.base-1;
  53. }
  54. lua_Object luaA_putObjectOnTop (lua_State *L) {
  55. luaD_openstack(L, L->Cstack.base);
  56. *L->Cstack.base++ = *(--L->top);
  57. return L->Cstack.base-1;
  58. }
  59. static void top2LC (lua_State *L, int n) {
  60. /* Put the 'n' elements on the top as the Lua2C contents */
  61. L->Cstack.base = L->top; /* new base */
  62. L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */
  63. L->Cstack.num = n; /* number of results */
  64. }
  65. lua_Object lua_pop (lua_State *L) {
  66. checkCparams(L, 1);
  67. return luaA_putObjectOnTop(L);
  68. }
  69. /*
  70. ** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
  71. ** `number' must be 1 to get the first parameter.
  72. */
  73. lua_Object lua_lua2C (lua_State *L, int number) {
  74. if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT;
  75. return L->Cstack.lua2C+number-1;
  76. }
  77. int lua_callfunction (lua_State *L, lua_Object function) {
  78. if (function == LUA_NOOBJECT)
  79. return 1;
  80. else {
  81. luaD_openstack(L, L->Cstack.base);
  82. set_normalized(L->Cstack.base, function);
  83. return luaD_protectedrun(L);
  84. }
  85. }
  86. lua_Object lua_gettagmethod (lua_State *L, int tag, const char *event) {
  87. return put_luaObject(L, luaT_gettagmethod(L, tag, event));
  88. }
  89. lua_Object lua_settagmethod (lua_State *L, int tag, const char *event) {
  90. checkCparams(L, 1);
  91. luaT_settagmethod(L, tag, event, L->top-1);
  92. return luaA_putObjectOnTop(L);
  93. }
  94. lua_Object lua_seterrormethod (lua_State *L) {
  95. lua_Object temp;
  96. checkCparams(L, 1);
  97. temp = lua_getglobal(L, "_ERRORMESSAGE");
  98. lua_setglobal(L, "_ERRORMESSAGE");
  99. return temp;
  100. }
  101. lua_Object lua_gettable (lua_State *L) {
  102. checkCparams(L, 2);
  103. luaV_gettable(L);
  104. return luaA_putObjectOnTop(L);
  105. }
  106. lua_Object lua_rawgettable (lua_State *L) {
  107. checkCparams(L, 2);
  108. if (ttype(L->top-2) != LUA_T_ARRAY)
  109. lua_error(L, "indexed expression not a table in rawgettable");
  110. *(L->top-2) = *luaH_get(L, avalue(L->top-2), L->top-1);
  111. --L->top;
  112. return luaA_putObjectOnTop(L);
  113. }
  114. void lua_settable (lua_State *L) {
  115. checkCparams(L, 3);
  116. luaV_settable(L, L->top-3);
  117. L->top -= 2; /* pop table and index */
  118. }
  119. void lua_rawsettable (lua_State *L) {
  120. checkCparams(L, 3);
  121. luaV_rawsettable(L, L->top-3);
  122. }
  123. lua_Object lua_createtable (lua_State *L) {
  124. TObject o;
  125. luaC_checkGC(L);
  126. avalue(&o) = luaH_new(L, 0);
  127. ttype(&o) = LUA_T_ARRAY;
  128. return put_luaObject(L, &o);
  129. }
  130. lua_Object lua_getglobal (lua_State *L, const char *name) {
  131. luaD_checkstack(L, 2); /* may need that to call T.M. */
  132. luaV_getglobal(L, luaS_assertglobalbyname(L, name));
  133. return luaA_putObjectOnTop(L);
  134. }
  135. lua_Object lua_rawgetglobal (lua_State *L, const char *name) {
  136. GlobalVar *gv = luaS_assertglobalbyname(L, name);
  137. return put_luaObject(L, &gv->value);
  138. }
  139. void lua_setglobal (lua_State *L, const char *name) {
  140. checkCparams(L, 1);
  141. luaD_checkstack(L, 2); /* may need that to call T.M. */
  142. luaV_setglobal(L, luaS_assertglobalbyname(L, name));
  143. }
  144. void lua_rawsetglobal (lua_State *L, const char *name) {
  145. GlobalVar *gv = luaS_assertglobalbyname(L, name);
  146. checkCparams(L, 1);
  147. gv->value = *(--L->top);
  148. }
  149. const char *lua_type (lua_State *L, lua_Object o) {
  150. UNUSED(L);
  151. return (o == LUA_NOOBJECT) ? "NOOBJECT" : luaO_typename(L, o);
  152. }
  153. int lua_isnil (lua_State *L, lua_Object o) {
  154. UNUSED(L);
  155. return (o != LUA_NOOBJECT) && (ttype(o) == LUA_T_NIL);
  156. }
  157. int lua_istable (lua_State *L, lua_Object o) {
  158. UNUSED(L);
  159. return (o != LUA_NOOBJECT) && (ttype(o) == LUA_T_ARRAY);
  160. }
  161. int lua_isuserdata (lua_State *L, lua_Object o) {
  162. UNUSED(L);
  163. return (o != LUA_NOOBJECT) && (ttype(o) == LUA_T_USERDATA);
  164. }
  165. int lua_iscfunction (lua_State *L, lua_Object o) {
  166. UNUSED(L);
  167. return (lua_tag(L, o) == LUA_T_CPROTO);
  168. }
  169. int lua_isnumber (lua_State *L, lua_Object o) {
  170. UNUSED(L);
  171. return (o != LUA_NOOBJECT) && (tonumber(o) == 0);
  172. }
  173. int lua_isstring (lua_State *L, lua_Object o) {
  174. int t = lua_tag(L, o);
  175. return (t == LUA_T_STRING) || (t == LUA_T_NUMBER);
  176. }
  177. int lua_isfunction (lua_State *L, lua_Object o) {
  178. int t = lua_tag(L, o);
  179. return (t == LUA_T_PROTO) || (t == LUA_T_CPROTO);
  180. }
  181. int lua_equal(lua_State *L, lua_Object o1, lua_Object o2) {
  182. UNUSED(L);
  183. if (o1 == LUA_NOOBJECT || o2 == LUA_NOOBJECT) return (o1 == o2);
  184. else return luaO_equalObj(o1, o2);
  185. }
  186. double lua_getnumber (lua_State *L, lua_Object obj) {
  187. UNUSED(L);
  188. if (obj == LUA_NOOBJECT) return 0.0;
  189. if (tonumber(obj)) return 0.0;
  190. else return (nvalue(obj));
  191. }
  192. const char *lua_getstring (lua_State *L, lua_Object obj) {
  193. luaC_checkGC(L); /* `tostring' may create a new string */
  194. if (obj == LUA_NOOBJECT || tostring(L, obj))
  195. return NULL;
  196. else return (svalue(obj));
  197. }
  198. long lua_strlen (lua_State *L, lua_Object obj) {
  199. UNUSED(L);
  200. if (obj == LUA_NOOBJECT || tostring(L, obj))
  201. return 0L;
  202. else return (tsvalue(obj)->u.s.len);
  203. }
  204. void *lua_getuserdata (lua_State *L, lua_Object obj) {
  205. UNUSED(L);
  206. if (obj == LUA_NOOBJECT || ttype(obj) != LUA_T_USERDATA)
  207. return NULL;
  208. else return tsvalue(obj)->u.d.value;
  209. }
  210. lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj) {
  211. if (!lua_iscfunction(L, obj))
  212. return NULL;
  213. else return fvalue(luaA_protovalue(obj));
  214. }
  215. void lua_pushnil (lua_State *L) {
  216. ttype(L->top) = LUA_T_NIL;
  217. incr_top;
  218. }
  219. void lua_pushnumber (lua_State *L, double n) {
  220. ttype(L->top) = LUA_T_NUMBER;
  221. nvalue(L->top) = n;
  222. incr_top;
  223. }
  224. void lua_pushlstring (lua_State *L, const char *s, long len) {
  225. tsvalue(L->top) = luaS_newlstr(L, s, len);
  226. ttype(L->top) = LUA_T_STRING;
  227. incr_top;
  228. luaC_checkGC(L);
  229. }
  230. void lua_pushstring (lua_State *L, const char *s) {
  231. if (s == NULL)
  232. lua_pushnil(L);
  233. else
  234. lua_pushlstring(L, s, strlen(s));
  235. }
  236. void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
  237. if (fn == NULL)
  238. lua_error(L, "API error - attempt to push a NULL Cfunction");
  239. checkCparams(L, n);
  240. ttype(L->top) = LUA_T_CPROTO;
  241. fvalue(L->top) = fn;
  242. incr_top;
  243. luaV_closure(L, n);
  244. luaC_checkGC(L);
  245. }
  246. void lua_pushusertag (lua_State *L, void *u, int tag) {
  247. if (tag < 0 && tag != LUA_ANYTAG)
  248. luaT_realtag(L, tag); /* error if tag is not valid */
  249. tsvalue(L->top) = luaS_createudata(L, u, tag);
  250. ttype(L->top) = LUA_T_USERDATA;
  251. incr_top;
  252. luaC_checkGC(L);
  253. }
  254. void luaA_pushobject (lua_State *L, const TObject *o) {
  255. *L->top = *o;
  256. incr_top;
  257. }
  258. void lua_pushobject (lua_State *L, lua_Object o) {
  259. if (o == LUA_NOOBJECT)
  260. lua_error(L, "API error - attempt to push a NOOBJECT");
  261. set_normalized(L->top, o);
  262. incr_top;
  263. }
  264. int lua_tag (lua_State *L, lua_Object o) {
  265. UNUSED(L);
  266. if (o == LUA_NOOBJECT)
  267. return LUA_T_NIL;
  268. else {
  269. int t;
  270. switch (t = ttype(o)) {
  271. case LUA_T_USERDATA:
  272. return o->value.ts->u.d.tag;
  273. case LUA_T_ARRAY:
  274. return o->value.a->htag;
  275. case LUA_T_PMARK:
  276. return LUA_T_PROTO;
  277. case LUA_T_CMARK:
  278. return LUA_T_CPROTO;
  279. case LUA_T_CLOSURE: case LUA_T_CLMARK:
  280. return o->value.cl->consts[0].ttype;
  281. #ifdef DEBUG
  282. case LUA_T_LINE:
  283. LUA_INTERNALERROR(L, "invalid type");
  284. #endif
  285. default:
  286. return t;
  287. }
  288. }
  289. }
  290. void lua_settag (lua_State *L, int tag) {
  291. checkCparams(L, 1);
  292. luaT_realtag(L, tag);
  293. switch (ttype(L->top-1)) {
  294. case LUA_T_ARRAY:
  295. (L->top-1)->value.a->htag = tag;
  296. break;
  297. case LUA_T_USERDATA:
  298. (L->top-1)->value.ts->u.d.tag = tag;
  299. break;
  300. default:
  301. luaL_verror(L, "cannot change the tag of a %.20s",
  302. luaO_typename(L, L->top-1));
  303. }
  304. L->top--;
  305. }
  306. GlobalVar *luaA_nextvar (lua_State *L, TaggedString *ts) {
  307. GlobalVar *gv;
  308. if (ts == NULL)
  309. gv = L->rootglobal; /* first variable */
  310. else {
  311. /* check whether name is in global var list */
  312. luaL_arg_check(L, ts->u.s.gv, 1, "variable name expected");
  313. gv = ts->u.s.gv->next; /* get next */
  314. }
  315. while (gv && gv->value.ttype == LUA_T_NIL) /* skip globals with nil */
  316. gv = gv->next;
  317. if (gv) {
  318. ttype(L->top) = LUA_T_STRING; tsvalue(L->top) = gv->name;
  319. incr_top;
  320. luaA_pushobject(L, &gv->value);
  321. }
  322. return gv;
  323. }
  324. const char *lua_nextvar (lua_State *L, const char *varname) {
  325. TaggedString *ts = (varname == NULL) ? NULL : luaS_new(L, varname);
  326. GlobalVar *gv = luaA_nextvar(L, ts);
  327. if (gv) {
  328. top2LC(L, 2);
  329. return gv->name->str;
  330. }
  331. else {
  332. top2LC(L, 0);
  333. return NULL;
  334. }
  335. }
  336. int luaA_next (lua_State *L, const Hash *t, int i) {
  337. int tsize = t->size;
  338. for (; i<tsize; i++) {
  339. Node *n = node(t, i);
  340. if (ttype(val(n)) != LUA_T_NIL) {
  341. luaA_pushobject(L, key(n));
  342. luaA_pushobject(L, val(n));
  343. return i+1; /* index to be used next time */
  344. }
  345. }
  346. return 0; /* no more elements */
  347. }
  348. int lua_next (lua_State *L, lua_Object t, int i) {
  349. if (ttype(t) != LUA_T_ARRAY)
  350. lua_error(L, "API error - object is not a table in `lua_next'");
  351. i = luaA_next(L, avalue(t), i);
  352. top2LC(L, (i==0) ? 0 : 2);
  353. return i;
  354. }
  355. /*
  356. ** {======================================================
  357. ** To manipulate some state information
  358. ** =======================================================
  359. */
  360. lua_LHFunction lua_setlinehook (lua_State *L, lua_LHFunction func) {
  361. lua_LHFunction old = L->linehook;
  362. L->linehook = func;
  363. return old;
  364. }
  365. lua_CHFunction lua_setcallhook (lua_State *L, lua_CHFunction func) {
  366. lua_CHFunction old = L->callhook;
  367. L->callhook = func;
  368. return old;
  369. }
  370. int lua_setdebug (lua_State *L, int debug) {
  371. int old = L->debug;
  372. L->debug = debug;
  373. return old;
  374. }
  375. /* }====================================================== */
  376. /*
  377. ** {======================================================
  378. ** Debug interface
  379. ** =======================================================
  380. */
  381. lua_Function lua_stackedfunction (lua_State *L, int level) {
  382. int i;
  383. for (i = (L->top-1)-L->stack; i>=0; i--) {
  384. int t = L->stack[i].ttype;
  385. if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK)
  386. if (level-- == 0)
  387. return L->stack+i;
  388. }
  389. return LUA_NOOBJECT;
  390. }
  391. int lua_nups (lua_State *L, lua_Function f) {
  392. UNUSED(L);
  393. return (!f || normalized_type(f) != LUA_T_CLOSURE) ? 0 : f->value.cl->nelems;
  394. }
  395. int lua_currentline (lua_State *L, lua_Function f) {
  396. return (f+1 < L->top && (f+1)->ttype == LUA_T_LINE) ? (f+1)->value.i : -1;
  397. }
  398. lua_Object lua_getlocal (lua_State *L, lua_Function f, int local_number,
  399. const char **name) {
  400. /* check whether `f' is a Lua function */
  401. if (lua_tag(L, f) != LUA_T_PROTO)
  402. return LUA_NOOBJECT;
  403. else {
  404. TProtoFunc *fp = luaA_protovalue(f)->value.tf;
  405. *name = luaF_getlocalname(fp, local_number, lua_currentline(L, f));
  406. if (*name) {
  407. /* if "*name", there must be a LUA_T_LINE */
  408. /* therefore, f+2 points to function base */
  409. return put_luaObject(L, (f+2)+(local_number-1));
  410. }
  411. else
  412. return LUA_NOOBJECT;
  413. }
  414. }
  415. int lua_setlocal (lua_State *L, lua_Function f, int local_number) {
  416. /* check whether `f' is a Lua function */
  417. if (lua_tag(L, f) != LUA_T_PROTO)
  418. return 0;
  419. else {
  420. TProtoFunc *fp = luaA_protovalue(f)->value.tf;
  421. const char *name = luaF_getlocalname(fp, local_number,
  422. lua_currentline(L, f));
  423. checkCparams(L, 1);
  424. --L->top;
  425. if (name) {
  426. /* if "name", there must be a LUA_T_LINE */
  427. /* therefore, f+2 points to function base */
  428. *((f+2)+(local_number-1)) = *L->top;
  429. return 1;
  430. }
  431. else
  432. return 0;
  433. }
  434. }
  435. void lua_funcinfo (lua_State *L, lua_Object func,
  436. const char **source, int *linedefined) {
  437. if (!lua_isfunction(L, func))
  438. lua_error(L, "API error - `funcinfo' called with a non-function value");
  439. else {
  440. const TObject *f = luaA_protovalue(func);
  441. if (normalized_type(f) == LUA_T_PROTO) {
  442. *source = tfvalue(f)->source->str;
  443. *linedefined = tfvalue(f)->lineDefined;
  444. }
  445. else {
  446. *source = "(C)";
  447. *linedefined = -1;
  448. }
  449. }
  450. }
  451. static int checkfunc (lua_State *L, TObject *o) {
  452. return luaO_equalObj(o, L->top);
  453. }
  454. const char *lua_getobjname (lua_State *L, lua_Object o, const char **name) {
  455. /* try to find a name for given function */
  456. GlobalVar *g;
  457. set_normalized(L->top, o); /* to be used by `checkfunc' */
  458. for (g=L->rootglobal; g; g=g->next) {
  459. if (checkfunc(L, &g->value)) {
  460. *name = g->name->str;
  461. return "global";
  462. }
  463. }
  464. /* not found: try tag methods */
  465. if ((*name = luaT_travtagmethods(L, checkfunc)) != NULL)
  466. return "tag-method";
  467. else return ""; /* not found at all */
  468. }
  469. /* }====================================================== */
  470. /*
  471. ** {======================================================
  472. ** BLOCK mechanism
  473. ** =======================================================
  474. */
  475. #ifndef MAX_C_BLOCKS
  476. #define MAX_C_BLOCKS 1000 /* arbitrary limit */
  477. #endif
  478. void lua_beginblock (lua_State *L) {
  479. luaM_growvector(L, L->Cblocks, L->numCblocks, 1, struct C_Lua_Stack,
  480. "too many nested blocks", MAX_C_BLOCKS);
  481. L->Cblocks[L->numCblocks] = L->Cstack;
  482. L->numCblocks++;
  483. }
  484. void lua_endblock (lua_State *L) {
  485. --L->numCblocks;
  486. L->Cstack = L->Cblocks[L->numCblocks];
  487. L->top = L->Cstack.base;
  488. }
  489. int lua_ref (lua_State *L, int lock) {
  490. int ref;
  491. checkCparams(L, 1);
  492. ref = luaR_ref(L, L->top-1, lock);
  493. L->top--;
  494. return ref;
  495. }
  496. lua_Object lua_getref (lua_State *L, int ref) {
  497. const TObject *o = luaR_getref(L, ref);
  498. return (o ? put_luaObject(L, o) : LUA_NOOBJECT);
  499. }
  500. /* }====================================================== */