lapi.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. /*
  2. ** $Id: lapi.c,v 1.2 1997/09/26 15:02:26 roberto Exp roberto $
  3. ** Lua API
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <stdlib.h>
  7. #include <string.h>
  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 "lstring.h"
  16. #include "ltable.h"
  17. #include "ltm.h"
  18. #include "lua.h"
  19. #include "luadebug.h"
  20. #include "lvm.h"
  21. char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
  22. "$Autores: " LUA_AUTHORS " $";
  23. TObject *luaA_Address (lua_Object o)
  24. {
  25. return Address(o);
  26. }
  27. void luaA_packresults (void)
  28. {
  29. luaV_pack(luaD_Cstack.lua2C, luaD_Cstack.num, luaD_stack.top);
  30. incr_top;
  31. }
  32. int luaA_passresults (void)
  33. {
  34. luaD_checkstack(luaD_Cstack.num);
  35. memcpy(luaD_stack.top, luaD_Cstack.lua2C+luaD_stack.stack,
  36. luaD_Cstack.num*sizeof(TObject));
  37. luaD_stack.top += luaD_Cstack.num;
  38. return luaD_Cstack.num;
  39. }
  40. static void checkCparams (int nParams)
  41. {
  42. if (luaD_stack.top-luaD_stack.stack < luaD_Cstack.base+nParams)
  43. lua_error("API error - wrong number of arguments in C2lua stack");
  44. }
  45. static lua_Object put_luaObject (TObject *o)
  46. {
  47. luaD_openstack((luaD_stack.top-luaD_stack.stack)-luaD_Cstack.base);
  48. luaD_stack.stack[luaD_Cstack.base++] = *o;
  49. return luaD_Cstack.base; /* this is +1 real position (see Ref) */
  50. }
  51. static lua_Object put_luaObjectonTop (void)
  52. {
  53. luaD_openstack((luaD_stack.top-luaD_stack.stack)-luaD_Cstack.base);
  54. luaD_stack.stack[luaD_Cstack.base++] = *(--luaD_stack.top);
  55. return luaD_Cstack.base; /* this is +1 real position (see Ref) */
  56. }
  57. lua_Object lua_pop (void)
  58. {
  59. checkCparams(1);
  60. return put_luaObjectonTop();
  61. }
  62. /*
  63. ** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
  64. ** 'number' must be 1 to get the first parameter.
  65. */
  66. lua_Object lua_lua2C (int number)
  67. {
  68. if (number <= 0 || number > luaD_Cstack.num) return LUA_NOOBJECT;
  69. /* Ref(luaD_stack.stack+(luaD_Cstack.lua2C+number-1)) ==
  70. luaD_stack.stack+(luaD_Cstack.lua2C+number-1)-luaD_stack.stack+1 == */
  71. return luaD_Cstack.lua2C+number;
  72. }
  73. lua_Object lua_upvalue (int n)
  74. {
  75. TObject *f = luaD_stack.stack+luaD_Cstack.lua2C-1;
  76. if (ttype(f) != LUA_T_MARK || n <= 0 || n > clvalue(f)->nelems)
  77. return LUA_NOOBJECT;
  78. if (ttype(protovalue(f)) != LUA_T_CPROTO) lua_error("BAD!!");
  79. *luaD_stack.top = clvalue(f)->consts[n];
  80. incr_top;
  81. return put_luaObjectonTop();
  82. }
  83. int lua_callfunction (lua_Object function)
  84. {
  85. if (function == LUA_NOOBJECT)
  86. return 1;
  87. else {
  88. luaD_openstack((luaD_stack.top-luaD_stack.stack)-luaD_Cstack.base);
  89. luaD_stack.stack[luaD_Cstack.base] = *Address(function);
  90. return luaD_protectedrun(MULT_RET);
  91. }
  92. }
  93. lua_Object lua_gettagmethod (int tag, char *event)
  94. {
  95. return put_luaObject(luaT_gettagmethod(tag, event));
  96. }
  97. lua_Object lua_settagmethod (int tag, char *event)
  98. {
  99. checkCparams(1);
  100. luaT_settagmethod(tag, event, luaD_stack.top-1);
  101. return put_luaObjectonTop();
  102. }
  103. lua_Object lua_seterrormethod (void)
  104. {
  105. TObject temp = luaD_errorim;
  106. checkCparams(1);
  107. luaD_errorim = *(--luaD_stack.top);
  108. return put_luaObject(&temp);
  109. }
  110. lua_Object lua_gettable (void)
  111. {
  112. checkCparams(2);
  113. luaV_gettable();
  114. return put_luaObjectonTop();
  115. }
  116. lua_Object lua_rawgettable (void)
  117. {
  118. checkCparams(2);
  119. if (ttype(luaD_stack.top-2) != LUA_T_ARRAY)
  120. lua_error("indexed expression not a table in raw gettable");
  121. else {
  122. TObject *h = luaH_get(avalue(luaD_stack.top-2), luaD_stack.top-1);
  123. --luaD_stack.top;
  124. if (h != NULL)
  125. *(luaD_stack.top-1) = *h;
  126. else
  127. ttype(luaD_stack.top-1) = LUA_T_NIL;
  128. }
  129. return put_luaObjectonTop();
  130. }
  131. void lua_settable (void)
  132. {
  133. checkCparams(3);
  134. luaV_settable(luaD_stack.top-3, 1);
  135. }
  136. void lua_rawsettable (void)
  137. {
  138. checkCparams(3);
  139. luaV_settable(luaD_stack.top-3, 0);
  140. }
  141. lua_Object lua_createtable (void)
  142. {
  143. TObject o;
  144. luaC_checkGC();
  145. avalue(&o) = luaH_new(0);
  146. ttype(&o) = LUA_T_ARRAY;
  147. return put_luaObject(&o);
  148. }
  149. lua_Object lua_getglobal (char *name)
  150. {
  151. luaD_checkstack(2); /* may need that to call T.M. */
  152. luaV_getglobal(luaS_new(name));
  153. return put_luaObjectonTop();
  154. }
  155. lua_Object lua_rawgetglobal (char *name)
  156. {
  157. TaggedString *ts = luaS_new(name);
  158. return put_luaObject(&ts->u.globalval);
  159. }
  160. void lua_setglobal (char *name)
  161. {
  162. checkCparams(1);
  163. luaD_checkstack(2); /* may need that to call T.M. */
  164. luaV_setglobal(luaS_new(name));
  165. }
  166. void lua_rawsetglobal (char *name)
  167. {
  168. TaggedString *ts = luaS_new(name);
  169. checkCparams(1);
  170. luaS_rawsetglobal(ts, --luaD_stack.top);
  171. }
  172. int lua_isnil (lua_Object o)
  173. {
  174. return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_NIL);
  175. }
  176. int lua_istable (lua_Object o)
  177. {
  178. return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_ARRAY);
  179. }
  180. int lua_isuserdata (lua_Object o)
  181. {
  182. return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_USERDATA);
  183. }
  184. int lua_iscfunction (lua_Object o)
  185. {
  186. return (o != LUA_NOOBJECT) && (lua_tag(o) == LUA_T_CPROTO);
  187. }
  188. int lua_isnumber (lua_Object o)
  189. {
  190. return (o!= LUA_NOOBJECT) && (tonumber(Address(o)) == 0);
  191. }
  192. int lua_isstring (lua_Object o)
  193. {
  194. int t = lua_tag(o);
  195. return (t == LUA_T_STRING) || (t == LUA_T_NUMBER);
  196. }
  197. int lua_isfunction (lua_Object o)
  198. {
  199. return (o != LUA_NOOBJECT) && ((ttype(Address(o)) == LUA_T_FUNCTION) ||
  200. (ttype(Address(o)) == LUA_T_MARK));
  201. }
  202. real lua_getnumber (lua_Object object)
  203. {
  204. if (object == LUA_NOOBJECT) return 0.0;
  205. if (tonumber (Address(object))) return 0.0;
  206. else return (nvalue(Address(object)));
  207. }
  208. char *lua_getstring (lua_Object object)
  209. {
  210. if (object == LUA_NOOBJECT || tostring(Address(object)))
  211. return NULL;
  212. else return (svalue(Address(object)));
  213. }
  214. void *lua_getuserdata (lua_Object object)
  215. {
  216. if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA)
  217. return NULL;
  218. else return tsvalue(Address(object))->u.d.v;
  219. }
  220. lua_CFunction lua_getcfunction (lua_Object object)
  221. {
  222. if (!lua_iscfunction(object))
  223. return NULL;
  224. else return fvalue(protovalue(Address(object)));
  225. }
  226. void lua_pushnil (void)
  227. {
  228. ttype(luaD_stack.top) = LUA_T_NIL;
  229. incr_top;
  230. }
  231. void lua_pushnumber (real n)
  232. {
  233. ttype(luaD_stack.top) = LUA_T_NUMBER;
  234. nvalue(luaD_stack.top) = n;
  235. incr_top;
  236. }
  237. void lua_pushstring (char *s)
  238. {
  239. if (s == NULL)
  240. ttype(luaD_stack.top) = LUA_T_NIL;
  241. else {
  242. tsvalue(luaD_stack.top) = luaS_new(s);
  243. ttype(luaD_stack.top) = LUA_T_STRING;
  244. }
  245. incr_top;
  246. luaC_checkGC();
  247. }
  248. void lua_pushCclosure (lua_CFunction fn, int n)
  249. {
  250. if (fn == NULL) {
  251. ttype(luaD_stack.top) = LUA_T_NIL;
  252. incr_top;
  253. }
  254. else {
  255. checkCparams(n);
  256. ttype(luaD_stack.top) = LUA_T_CPROTO;
  257. fvalue(luaD_stack.top) = fn;
  258. incr_top;
  259. luaV_closure(n);
  260. }
  261. }
  262. void lua_pushusertag (void *u, int tag)
  263. {
  264. if (tag < 0 && tag != LUA_ANYTAG)
  265. luaT_realtag(tag); /* error if tag is not valid */
  266. tsvalue(luaD_stack.top) = luaS_createudata(u, tag);
  267. ttype(luaD_stack.top) = LUA_T_USERDATA;
  268. incr_top;
  269. luaC_checkGC();
  270. }
  271. void luaA_pushobject (TObject *o)
  272. {
  273. *luaD_stack.top = *o;
  274. incr_top;
  275. }
  276. void lua_pushobject (lua_Object o)
  277. {
  278. if (o == LUA_NOOBJECT)
  279. lua_error("API error - attempt to push a NOOBJECT");
  280. *luaD_stack.top = *Address(o);
  281. if (ttype(luaD_stack.top) == LUA_T_MARK)
  282. ttype(luaD_stack.top) = LUA_T_FUNCTION;
  283. incr_top;
  284. }
  285. int lua_tag (lua_Object lo)
  286. {
  287. if (lo == LUA_NOOBJECT) return LUA_T_NIL;
  288. else {
  289. TObject *o = Address(lo);
  290. int t = luaT_efectivetag(o);
  291. if (t == LUA_T_USERDATA)
  292. return o->value.ts->u.d.tag;
  293. else
  294. return t;
  295. }
  296. }
  297. void lua_settag (int tag)
  298. {
  299. checkCparams(1);
  300. luaT_realtag(tag);
  301. switch (ttype(luaD_stack.top-1)) {
  302. case LUA_T_ARRAY:
  303. (luaD_stack.top-1)->value.a->htag = tag;
  304. break;
  305. case LUA_T_USERDATA:
  306. (luaD_stack.top-1)->value.ts->u.d.tag = tag;
  307. break;
  308. default:
  309. luaL_verror("cannot change the tag of a %s",
  310. luaO_typenames[-ttype((luaD_stack.top-1))]);
  311. }
  312. luaD_stack.top--;
  313. }
  314. /*
  315. ** =======================================================
  316. ** Debug interface
  317. ** =======================================================
  318. */
  319. /* Hooks */
  320. lua_CHFunction lua_callhook = NULL;
  321. lua_LHFunction lua_linehook = NULL;
  322. lua_Function lua_stackedfunction (int level)
  323. {
  324. StkId i;
  325. for (i = (luaD_stack.top-1)-luaD_stack.stack; i>=0; i--)
  326. if (luaD_stack.stack[i].ttype == LUA_T_MARK)
  327. if (level-- == 0)
  328. return Ref(luaD_stack.stack+i);
  329. return LUA_NOOBJECT;
  330. }
  331. int lua_currentline (lua_Function func)
  332. {
  333. TObject *f = Address(func);
  334. return (f+1 < luaD_stack.top && (f+1)->ttype == LUA_T_LINE) ? (f+1)->value.i : -1;
  335. }
  336. lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
  337. {
  338. TObject *f = luaA_Address(func);
  339. /* check whether func is a Lua function */
  340. if (!(f->ttype == LUA_T_MARK || f->ttype == LUA_T_FUNCTION))
  341. return LUA_NOOBJECT;
  342. else {
  343. TProtoFunc *fp = protovalue(f)->value.tf;
  344. *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
  345. if (*name) {
  346. /* if "*name", there must be a LUA_T_LINE */
  347. /* therefore, f+2 points to function base */
  348. return Ref((f+2)+(local_number-1));
  349. }
  350. else
  351. return LUA_NOOBJECT;
  352. }
  353. }
  354. int lua_setlocal (lua_Function func, int local_number)
  355. {
  356. TObject *f = Address(func);
  357. TProtoFunc *fp = protovalue(f)->value.tf;
  358. char *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
  359. checkCparams(1);
  360. --luaD_stack.top;
  361. if (name) {
  362. /* if "name", there must be a LUA_T_LINE */
  363. /* therefore, f+2 points to function base */
  364. *((f+2)+(local_number-1)) = *luaD_stack.top;
  365. return 1;
  366. }
  367. else
  368. return 0;
  369. }
  370. void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
  371. {
  372. TObject *f = Address(func);
  373. if (!(ttype(f) == LUA_T_MARK || ttype(f) == LUA_T_FUNCTION))
  374. lua_error("API - `funcinfo' called with a non-function value");
  375. else {
  376. f = protovalue(f);
  377. if (ttype(f) == LUA_T_PROTO) {
  378. *filename = tfvalue(f)->fileName->str;
  379. *linedefined = tfvalue(f)->lineDefined;
  380. }
  381. else {
  382. *filename = "(C)";
  383. *linedefined = -1;
  384. }
  385. }
  386. }
  387. static TObject *functofind;
  388. static int checkfunc (TObject *o)
  389. {
  390. return (o->ttype == LUA_T_FUNCTION) &&
  391. ((functofind->ttype == LUA_T_FUNCTION) ||
  392. (functofind->ttype == LUA_T_MARK)) &&
  393. (functofind->value.cl == o->value.cl);
  394. }
  395. char *lua_getobjname (lua_Object o, char **name)
  396. { /* try to find a name for given function */
  397. functofind = Address(o);
  398. if ((*name = luaT_travtagmethods(checkfunc)) != NULL)
  399. return "tag-method";
  400. else if ((*name = luaS_travsymbol(checkfunc)) != NULL)
  401. return "global";
  402. else return "";
  403. }
  404. /*
  405. ** =======================================================
  406. ** BLOCK mechanism
  407. ** =======================================================
  408. */
  409. #define MAX_C_BLOCKS 10
  410. static int numCblocks = 0;
  411. static struct C_Lua_Stack Cblocks[MAX_C_BLOCKS];
  412. void lua_beginblock (void)
  413. {
  414. if (numCblocks >= MAX_C_BLOCKS)
  415. lua_error("`lua_beginblock': too many nested blocks");
  416. Cblocks[numCblocks] = luaD_Cstack;
  417. numCblocks++;
  418. }
  419. void lua_endblock (void)
  420. {
  421. --numCblocks;
  422. luaD_Cstack = Cblocks[numCblocks];
  423. luaD_adjusttop(luaD_Cstack.base);
  424. }
  425. int lua_ref (int lock)
  426. {
  427. int ref;
  428. checkCparams(1);
  429. ref = luaC_ref(luaD_stack.top-1, lock);
  430. luaD_stack.top--;
  431. return ref;
  432. }
  433. lua_Object lua_getref (int ref)
  434. {
  435. TObject *o = luaC_getref(ref);
  436. return (o ? put_luaObject(o) : LUA_NOOBJECT);
  437. }
  438. #if LUA_COMPAT2_5
  439. /*
  440. ** API: set a function as a fallback
  441. */
  442. static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults)
  443. {
  444. StkId base = (luaD_stack.top-luaD_stack.stack)-nParams;
  445. luaD_openstack(nParams);
  446. luaD_stack.stack[base].ttype = LUA_T_CPROTO;
  447. luaD_stack.stack[base].value.f = f;
  448. luaF_simpleclosure(luaD_stack.stack+base);
  449. luaD_call(base+1, nResults);
  450. }
  451. lua_Object lua_setfallback (char *name, lua_CFunction fallback)
  452. {
  453. lua_pushstring(name);
  454. lua_pushcfunction(fallback);
  455. do_unprotectedrun(luaT_setfallback, 2, 1);
  456. return put_luaObjectonTop();
  457. }
  458. #endif