diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-04-14 12:13:48 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-04-14 12:13:48 -0300 |
commit | 7dfa4cd655118faf164427356609fec31906dac2 (patch) | |
tree | d39fac9afba1dc0ab01dd5d174824120650c9eab | |
parent | fc6203ee4308173283f9ad9de6694d47f0908c4d (diff) | |
download | lua-7dfa4cd655118faf164427356609fec31906dac2.tar.gz lua-7dfa4cd655118faf164427356609fec31906dac2.tar.bz2 lua-7dfa4cd655118faf164427356609fec31906dac2.zip |
first implementation of light C functions
-rw-r--r-- | lapi.c | 68 | ||||
-rw-r--r-- | ldebug.c | 32 | ||||
-rw-r--r-- | ldo.c | 54 | ||||
-rw-r--r-- | lobject.c | 4 | ||||
-rw-r--r-- | lobject.h | 39 | ||||
-rw-r--r-- | lstate.h | 3 | ||||
-rw-r--r-- | ltable.c | 4 | ||||
-rw-r--r-- | ltests.c | 9 | ||||
-rw-r--r-- | ltm.c | 4 | ||||
-rw-r--r-- | ltm.h | 5 | ||||
-rw-r--r-- | lvm.c | 7 |
11 files changed, 141 insertions, 88 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 2.119 2010/04/02 15:19:19 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.120 2010/04/05 14:21:38 roberto Exp roberto $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -54,12 +54,16 @@ static TValue *index2addr (lua_State *L, int idx) { | |||
54 | else if (idx == LUA_REGISTRYINDEX) | 54 | else if (idx == LUA_REGISTRYINDEX) |
55 | return &G(L)->l_registry; | 55 | return &G(L)->l_registry; |
56 | else { /* upvalues */ | 56 | else { /* upvalues */ |
57 | Closure *func = curr_func(L); | ||
58 | idx = LUA_REGISTRYINDEX - idx; | 57 | idx = LUA_REGISTRYINDEX - idx; |
59 | api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large"); | 58 | api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large"); |
60 | return (idx <= func->c.nupvalues) | 59 | if (ttiscfp(ci->func)) /* C-function pointer? */ |
61 | ? &func->c.upvalue[idx-1] | 60 | return cast(TValue *, luaO_nilobject); /* it has no upvalues */ |
62 | : cast(TValue *, luaO_nilobject); | 61 | else { |
62 | Closure *func = clvalue(ci->func); | ||
63 | return (idx <= func->c.nupvalues) | ||
64 | ? &func->c.upvalue[idx-1] | ||
65 | : cast(TValue *, luaO_nilobject); | ||
66 | } | ||
63 | } | 67 | } |
64 | } | 68 | } |
65 | 69 | ||
@@ -181,8 +185,10 @@ static void moveto (lua_State *L, TValue *fr, int idx) { | |||
181 | TValue *to = index2addr(L, idx); | 185 | TValue *to = index2addr(L, idx); |
182 | api_checkvalidindex(L, to); | 186 | api_checkvalidindex(L, to); |
183 | setobj(L, to, fr); | 187 | setobj(L, to, fr); |
184 | if (idx < LUA_REGISTRYINDEX) /* function upvalue? */ | 188 | if (idx < LUA_REGISTRYINDEX) { /* function upvalue? */ |
185 | luaC_barrier(L, curr_func(L), fr); | 189 | lua_assert(ttisclosure(L->ci->func)); |
190 | luaC_barrier(L, clvalue(L->ci->func), fr); | ||
191 | } | ||
186 | /* LUA_REGISTRYINDEX does not need gc barrier | 192 | /* LUA_REGISTRYINDEX does not need gc barrier |
187 | (collector revisits it before finishing collection) */ | 193 | (collector revisits it before finishing collection) */ |
188 | } | 194 | } |
@@ -223,19 +229,19 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) { | |||
223 | 229 | ||
224 | LUA_API int lua_type (lua_State *L, int idx) { | 230 | LUA_API int lua_type (lua_State *L, int idx) { |
225 | StkId o = index2addr(L, idx); | 231 | StkId o = index2addr(L, idx); |
226 | return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); | 232 | return (o == luaO_nilobject) ? LUA_TNONE : ttypenv(o); |
227 | } | 233 | } |
228 | 234 | ||
229 | 235 | ||
230 | LUA_API const char *lua_typename (lua_State *L, int t) { | 236 | LUA_API const char *lua_typename (lua_State *L, int t) { |
231 | UNUSED(L); | 237 | UNUSED(L); |
232 | return typename(t); | 238 | return ttypename(t); |
233 | } | 239 | } |
234 | 240 | ||
235 | 241 | ||
236 | LUA_API int lua_iscfunction (lua_State *L, int idx) { | 242 | LUA_API int lua_iscfunction (lua_State *L, int idx) { |
237 | StkId o = index2addr(L, idx); | 243 | StkId o = index2addr(L, idx); |
238 | return iscfunction(o); | 244 | return (ttiscfp(o) || (ttisclosure(o) && clvalue(o)->c.isC)); |
239 | } | 245 | } |
240 | 246 | ||
241 | 247 | ||
@@ -361,7 +367,10 @@ LUA_API size_t lua_rawlen (lua_State *L, int idx) { | |||
361 | 367 | ||
362 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { | 368 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { |
363 | StkId o = index2addr(L, idx); | 369 | StkId o = index2addr(L, idx); |
364 | return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; | 370 | if (ttiscfp(o)) return fvalue(o); |
371 | else if (ttisclosure(o) && clvalue(o)->c.isC) | ||
372 | return clvalue(o)->c.f; | ||
373 | else return NULL; /* not a C function */ | ||
365 | } | 374 | } |
366 | 375 | ||
367 | 376 | ||
@@ -386,6 +395,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) { | |||
386 | switch (ttype(o)) { | 395 | switch (ttype(o)) { |
387 | case LUA_TTABLE: return hvalue(o); | 396 | case LUA_TTABLE: return hvalue(o); |
388 | case LUA_TFUNCTION: return clvalue(o); | 397 | case LUA_TFUNCTION: return clvalue(o); |
398 | case LUA_TCFP: return cast(void *, cast(size_t, fvalue(o))); | ||
389 | case LUA_TTHREAD: return thvalue(o); | 399 | case LUA_TTHREAD: return thvalue(o); |
390 | case LUA_TUSERDATA: | 400 | case LUA_TUSERDATA: |
391 | case LUA_TLIGHTUSERDATA: | 401 | case LUA_TLIGHTUSERDATA: |
@@ -480,18 +490,22 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { | |||
480 | 490 | ||
481 | 491 | ||
482 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | 492 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { |
483 | Closure *cl; | ||
484 | lua_lock(L); | 493 | lua_lock(L); |
485 | api_checknelems(L, n); | 494 | if (n == 0) { |
486 | api_check(L, n <= UCHAR_MAX, "upvalue index too large"); | 495 | setfvalue(L->top, fn); |
487 | luaC_checkGC(L); | 496 | } |
488 | cl = luaF_newCclosure(L, n); | 497 | else { |
489 | cl->c.f = fn; | 498 | Closure *cl; |
490 | L->top -= n; | 499 | api_checknelems(L, n); |
491 | while (n--) | 500 | api_check(L, n <= UCHAR_MAX, "upvalue index too large"); |
492 | setobj2n(L, &cl->c.upvalue[n], L->top+n); | 501 | luaC_checkGC(L); |
493 | setclvalue(L, L->top, cl); | 502 | cl = luaF_newCclosure(L, n); |
494 | lua_assert(iswhite(obj2gco(cl))); | 503 | cl->c.f = fn; |
504 | L->top -= n; | ||
505 | while (n--) | ||
506 | setobj2n(L, &cl->c.upvalue[n], L->top + n); | ||
507 | setclvalue(L, L->top, cl); | ||
508 | } | ||
495 | api_incr_top(L); | 509 | api_incr_top(L); |
496 | lua_unlock(L); | 510 | lua_unlock(L); |
497 | } | 511 | } |
@@ -598,7 +612,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { | |||
598 | mt = uvalue(obj)->metatable; | 612 | mt = uvalue(obj)->metatable; |
599 | break; | 613 | break; |
600 | default: | 614 | default: |
601 | mt = G(L)->mt[ttype(obj)]; | 615 | mt = G(L)->mt[ttypenv(obj)]; |
602 | break; | 616 | break; |
603 | } | 617 | } |
604 | if (mt == NULL) | 618 | if (mt == NULL) |
@@ -713,7 +727,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { | |||
713 | break; | 727 | break; |
714 | } | 728 | } |
715 | default: { | 729 | default: { |
716 | G(L)->mt[ttype(obj)] = mt; | 730 | G(L)->mt[ttypenv(obj)] = mt; |
717 | break; | 731 | break; |
718 | } | 732 | } |
719 | } | 733 | } |
@@ -1063,7 +1077,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { | |||
1063 | 1077 | ||
1064 | static const char *aux_upvalue (StkId fi, int n, TValue **val) { | 1078 | static const char *aux_upvalue (StkId fi, int n, TValue **val) { |
1065 | Closure *f; | 1079 | Closure *f; |
1066 | if (!ttisfunction(fi)) return NULL; | 1080 | if (!ttisclosure(fi)) return NULL; |
1067 | f = clvalue(fi); | 1081 | f = clvalue(fi); |
1068 | if (f->c.isC) { | 1082 | if (f->c.isC) { |
1069 | if (!(1 <= n && n <= f->c.nupvalues)) return NULL; | 1083 | if (!(1 <= n && n <= f->c.nupvalues)) return NULL; |
@@ -1115,7 +1129,7 @@ static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) { | |||
1115 | Closure *f; | 1129 | Closure *f; |
1116 | Proto *p; | 1130 | Proto *p; |
1117 | StkId fi = index2addr(L, fidx); | 1131 | StkId fi = index2addr(L, fidx); |
1118 | api_check(L, ttisfunction(fi), "function expected"); | 1132 | api_check(L, ttisclosure(fi), "Lua function expected"); |
1119 | f = clvalue(fi); | 1133 | f = clvalue(fi); |
1120 | api_check(L, !f->c.isC, "Lua function expected"); | 1134 | api_check(L, !f->c.isC, "Lua function expected"); |
1121 | p = f->l.p; | 1135 | p = f->l.p; |
@@ -1128,7 +1142,7 @@ static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) { | |||
1128 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { | 1142 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { |
1129 | Closure *f; | 1143 | Closure *f; |
1130 | StkId fi = index2addr(L, fidx); | 1144 | StkId fi = index2addr(L, fidx); |
1131 | api_check(L, ttisfunction(fi), "function expected"); | 1145 | api_check(L, ttisclosure(fi), "function expected"); |
1132 | f = clvalue(fi); | 1146 | f = clvalue(fi); |
1133 | if (f->c.isC) { | 1147 | if (f->c.isC) { |
1134 | api_check(L, 1 <= n && n <= f->c.nupvalues, "invalid upvalue index"); | 1148 | api_check(L, 1 <= n && n <= f->c.nupvalues, "invalid upvalue index"); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 2.68 2010/04/05 16:26:37 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.69 2010/04/08 17:06:33 roberto Exp roberto $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -144,7 +144,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
144 | 144 | ||
145 | 145 | ||
146 | static void funcinfo (lua_Debug *ar, Closure *cl) { | 146 | static void funcinfo (lua_Debug *ar, Closure *cl) { |
147 | if (cl->c.isC) { | 147 | if (cl == NULL || cl->c.isC) { |
148 | ar->source = "=[C]"; | 148 | ar->source = "=[C]"; |
149 | ar->linedefined = -1; | 149 | ar->linedefined = -1; |
150 | ar->lastlinedefined = -1; | 150 | ar->lastlinedefined = -1; |
@@ -191,8 +191,8 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
191 | break; | 191 | break; |
192 | } | 192 | } |
193 | case 'u': { | 193 | case 'u': { |
194 | ar->nups = f->c.nupvalues; | 194 | ar->nups = (f == NULL) ? 0 : f->c.nupvalues; |
195 | if (f->c.isC) { | 195 | if (f == NULL || f->c.isC) { |
196 | ar->isvararg = 1; | 196 | ar->isvararg = 1; |
197 | ar->nparams = 0; | 197 | ar->nparams = 0; |
198 | } | 198 | } |
@@ -226,28 +226,30 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
226 | 226 | ||
227 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | 227 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { |
228 | int status; | 228 | int status; |
229 | Closure *f = NULL; | 229 | Closure *cl; |
230 | CallInfo *ci = NULL; | 230 | CallInfo *ci; |
231 | StkId func; | ||
231 | lua_lock(L); | 232 | lua_lock(L); |
232 | if (*what == '>') { | 233 | if (*what == '>') { |
233 | StkId func = L->top - 1; | 234 | ci = NULL; |
235 | func = L->top - 1; | ||
234 | luai_apicheck(L, ttisfunction(func)); | 236 | luai_apicheck(L, ttisfunction(func)); |
235 | what++; /* skip the '>' */ | 237 | what++; /* skip the '>' */ |
236 | f = clvalue(func); | ||
237 | L->top--; /* pop function */ | 238 | L->top--; /* pop function */ |
238 | } | 239 | } |
239 | else { | 240 | else { |
240 | ci = ar->i_ci; | 241 | ci = ar->i_ci; |
242 | func = ci->func; | ||
241 | lua_assert(ttisfunction(ci->func)); | 243 | lua_assert(ttisfunction(ci->func)); |
242 | f = clvalue(ci->func); | ||
243 | } | 244 | } |
244 | status = auxgetinfo(L, what, ar, f, ci); | 245 | cl = ttisclosure(func) ? clvalue(func) : NULL; |
246 | status = auxgetinfo(L, what, ar, cl, ci); | ||
245 | if (strchr(what, 'f')) { | 247 | if (strchr(what, 'f')) { |
246 | setclvalue(L, L->top, f); | 248 | setobjs2s(L, L->top, func); |
247 | incr_top(L); | 249 | incr_top(L); |
248 | } | 250 | } |
249 | if (strchr(what, 'L')) | 251 | if (strchr(what, 'L')) |
250 | collectvalidlines(L, f); | 252 | collectvalidlines(L, cl); |
251 | lua_unlock(L); | 253 | lua_unlock(L); |
252 | return status; | 254 | return status; |
253 | } | 255 | } |
@@ -439,7 +441,7 @@ static const char *getupvalname (CallInfo *ci, const TValue *o, | |||
439 | void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { | 441 | void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { |
440 | CallInfo *ci = L->ci; | 442 | CallInfo *ci = L->ci; |
441 | const char *name = NULL; | 443 | const char *name = NULL; |
442 | const char *t = typename(ttype(o)); | 444 | const char *t = objtypename(o); |
443 | const char *kind = NULL; | 445 | const char *kind = NULL; |
444 | if (isLua(ci)) { | 446 | if (isLua(ci)) { |
445 | kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ | 447 | kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ |
@@ -470,8 +472,8 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { | |||
470 | 472 | ||
471 | 473 | ||
472 | int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { | 474 | int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { |
473 | const char *t1 = typename(ttype(p1)); | 475 | const char *t1 = objtypename(p1); |
474 | const char *t2 = typename(ttype(p2)); | 476 | const char *t2 = objtypename(p2); |
475 | if (t1 == t2) | 477 | if (t1 == t2) |
476 | luaG_runerror(L, "attempt to compare two %s values", t1); | 478 | luaG_runerror(L, "attempt to compare two %s values", t1); |
477 | else | 479 | else |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.82 2010/03/26 20:58:11 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.83 2010/04/08 17:16:46 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -293,18 +293,43 @@ static StkId tryfuncTM (lua_State *L, StkId func) { | |||
293 | ** returns true if function has been executed (C function) | 293 | ** returns true if function has been executed (C function) |
294 | */ | 294 | */ |
295 | int luaD_precall (lua_State *L, StkId func, int nresults) { | 295 | int luaD_precall (lua_State *L, StkId func, int nresults) { |
296 | LClosure *cl; | 296 | Closure *cl; |
297 | lua_CFunction f; | ||
297 | ptrdiff_t funcr; | 298 | ptrdiff_t funcr; |
298 | if (!ttisfunction(func)) /* `func' is not a function? */ | 299 | if (!ttisfunction(func)) /* `func' is not a function? */ |
299 | func = tryfuncTM(L, func); /* check the `function' tag method */ | 300 | func = tryfuncTM(L, func); /* check the `function' tag method */ |
300 | funcr = savestack(L, func); | 301 | funcr = savestack(L, func); |
301 | cl = &clvalue(func)->l; | ||
302 | L->ci->nresults = nresults; | 302 | L->ci->nresults = nresults; |
303 | if (!cl->isC) { /* Lua function? prepare its call */ | 303 | if (ttiscfp(func)) { /* C function pointer? */ |
304 | f = fvalue(func); /* get it */ | ||
305 | goto isCfunc; /* go to call it */ | ||
306 | } | ||
307 | cl = clvalue(func); | ||
308 | if (cl->c.isC) { /* C closure? */ | ||
309 | CallInfo *ci; | ||
310 | int n; | ||
311 | f = cl->c.f; | ||
312 | isCfunc: /* call C function 'f' */ | ||
313 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | ||
314 | ci = next_ci(L); /* now 'enter' new function */ | ||
315 | ci->func = restorestack(L, funcr); | ||
316 | ci->top = L->top + LUA_MINSTACK; | ||
317 | lua_assert(ci->top <= L->stack_last); | ||
318 | ci->callstatus = 0; | ||
319 | if (L->hookmask & LUA_MASKCALL) | ||
320 | luaD_hook(L, LUA_HOOKCALL, -1); | ||
321 | lua_unlock(L); | ||
322 | n = (*f)(L); /* do the actual call */ | ||
323 | lua_lock(L); | ||
324 | api_checknelems(L, n); | ||
325 | luaD_poscall(L, L->top - n); | ||
326 | return 1; | ||
327 | } | ||
328 | else { /* Lua function: prepare its call */ | ||
304 | CallInfo *ci; | 329 | CallInfo *ci; |
305 | int nparams, nargs; | 330 | int nparams, nargs; |
306 | StkId base; | 331 | StkId base; |
307 | Proto *p = cl->p; | 332 | Proto *p = cl->l.p; |
308 | luaD_checkstack(L, p->maxstacksize); | 333 | luaD_checkstack(L, p->maxstacksize); |
309 | func = restorestack(L, funcr); | 334 | func = restorestack(L, funcr); |
310 | nargs = cast_int(L->top - func) - 1; /* number of real arguments */ | 335 | nargs = cast_int(L->top - func) - 1; /* number of real arguments */ |
@@ -327,24 +352,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
327 | callhook(L, ci); | 352 | callhook(L, ci); |
328 | return 0; | 353 | return 0; |
329 | } | 354 | } |
330 | else { /* if is a C function, call it */ | ||
331 | CallInfo *ci; | ||
332 | int n; | ||
333 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | ||
334 | ci = next_ci(L); /* now 'enter' new function */ | ||
335 | ci->func = restorestack(L, funcr); | ||
336 | ci->top = L->top + LUA_MINSTACK; | ||
337 | lua_assert(ci->top <= L->stack_last); | ||
338 | ci->callstatus = 0; | ||
339 | if (L->hookmask & LUA_MASKCALL) | ||
340 | luaD_hook(L, LUA_HOOKCALL, -1); | ||
341 | lua_unlock(L); | ||
342 | n = (*curr_func(L)->c.f)(L); /* do the actual call */ | ||
343 | lua_lock(L); | ||
344 | api_checknelems(L, n); | ||
345 | luaD_poscall(L, L->top - n); | ||
346 | return 1; | ||
347 | } | ||
348 | } | 355 | } |
349 | 356 | ||
350 | 357 | ||
@@ -526,6 +533,7 @@ LUA_API int lua_resume (lua_State *L, int nargs) { | |||
526 | luai_userstateresume(L, nargs); | 533 | luai_userstateresume(L, nargs); |
527 | ++G(L)->nCcalls; /* count resume */ | 534 | ++G(L)->nCcalls; /* count resume */ |
528 | L->nny = 0; /* allow yields */ | 535 | L->nny = 0; /* allow yields */ |
536 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); | ||
529 | status = luaD_rawrunprotected(L, resume, L->top - nargs); | 537 | status = luaD_rawrunprotected(L, resume, L->top - nargs); |
530 | if (status == -1) /* error calling 'lua_resume'? */ | 538 | if (status == -1) /* error calling 'lua_resume'? */ |
531 | status = LUA_ERRRUN; | 539 | status = LUA_ERRRUN; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.c,v 2.36 2010/04/02 15:30:27 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 2.37 2010/04/05 16:26:37 roberto Exp roberto $ |
3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -83,6 +83,8 @@ int luaO_rawequalObj (const TValue *t1, const TValue *t2) { | |||
83 | return pvalue(t1) == pvalue(t2); | 83 | return pvalue(t1) == pvalue(t2); |
84 | case LUA_TSTRING: | 84 | case LUA_TSTRING: |
85 | return rawtsvalue(t1) == rawtsvalue(t2); | 85 | return rawtsvalue(t1) == rawtsvalue(t2); |
86 | case LUA_TCFP: | ||
87 | return fvalue(t1) == fvalue(t2); | ||
86 | default: | 88 | default: |
87 | lua_assert(iscollectable(t1)); | 89 | lua_assert(iscollectable(t1)); |
88 | return gcvalue(t1) == gcvalue(t2); | 90 | return gcvalue(t1) == gcvalue(t2); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.h,v 2.36 2010/03/26 20:58:11 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 2.37 2010/04/12 16:07:06 roberto Exp roberto $ |
3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -25,6 +25,12 @@ | |||
25 | 25 | ||
26 | 26 | ||
27 | /* | 27 | /* |
28 | ** Variant tag for C-function pointers (negative to be considered | ||
29 | ** non collectable by 'iscollectable') | ||
30 | */ | ||
31 | #define LUA_TCFP (~0x0F | LUA_TFUNCTION) | ||
32 | |||
33 | /* | ||
28 | ** Union of all collectable objects | 34 | ** Union of all collectable objects |
29 | */ | 35 | */ |
30 | typedef union GCObject GCObject; | 36 | typedef union GCObject GCObject; |
@@ -54,6 +60,7 @@ typedef union { | |||
54 | void *p; | 60 | void *p; |
55 | lua_Number n; | 61 | lua_Number n; |
56 | int b; | 62 | int b; |
63 | lua_CFunction f; | ||
57 | } Value; | 64 | } Value; |
58 | 65 | ||
59 | 66 | ||
@@ -73,12 +80,26 @@ typedef struct lua_TValue { | |||
73 | #define NILCONSTANT {NULL}, LUA_TNIL | 80 | #define NILCONSTANT {NULL}, LUA_TNIL |
74 | 81 | ||
75 | 82 | ||
83 | /* | ||
84 | ** type tag of a TValue | ||
85 | */ | ||
86 | #define ttype(o) ((o)->tt_) | ||
87 | |||
88 | |||
89 | /* | ||
90 | ** type tag of a TValue with no variants | ||
91 | */ | ||
92 | #define ttypenv(o) (ttype(o) & 0x0F) | ||
93 | |||
94 | |||
76 | /* Macros to test type */ | 95 | /* Macros to test type */ |
77 | #define ttisnil(o) (ttype(o) == LUA_TNIL) | 96 | #define ttisnil(o) (ttype(o) == LUA_TNIL) |
78 | #define ttisnumber(o) (ttype(o) == LUA_TNUMBER) | 97 | #define ttisnumber(o) (ttype(o) == LUA_TNUMBER) |
79 | #define ttisstring(o) (ttype(o) == LUA_TSTRING) | 98 | #define ttisstring(o) (ttype(o) == LUA_TSTRING) |
80 | #define ttistable(o) (ttype(o) == LUA_TTABLE) | 99 | #define ttistable(o) (ttype(o) == LUA_TTABLE) |
81 | #define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) | 100 | #define ttisfunction(o) (ttypenv(o) == LUA_TFUNCTION) |
101 | #define ttisclosure(o) (ttype(o) == LUA_TFUNCTION) | ||
102 | #define ttiscfp(o) (ttype(o) == LUA_TCFP) | ||
82 | #define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) | 103 | #define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) |
83 | #define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) | 104 | #define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) |
84 | #define ttisthread(o) (ttype(o) == LUA_TTHREAD) | 105 | #define ttisthread(o) (ttype(o) == LUA_TTHREAD) |
@@ -86,7 +107,6 @@ typedef struct lua_TValue { | |||
86 | #define ttisdeadkey(o) (ttype(o) == LUA_TDEADKEY) | 107 | #define ttisdeadkey(o) (ttype(o) == LUA_TDEADKEY) |
87 | 108 | ||
88 | /* Macros to access values */ | 109 | /* Macros to access values */ |
89 | #define ttype(o) ((o)->tt_) | ||
90 | #define gcvalue(o) check_exp(iscollectable(o), (o)->value_.gc) | 110 | #define gcvalue(o) check_exp(iscollectable(o), (o)->value_.gc) |
91 | #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value_.p) | 111 | #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value_.p) |
92 | #define nvalue(o) check_exp(ttisnumber(o), (o)->value_.n) | 112 | #define nvalue(o) check_exp(ttisnumber(o), (o)->value_.n) |
@@ -94,16 +114,15 @@ typedef struct lua_TValue { | |||
94 | #define tsvalue(o) (&rawtsvalue(o)->tsv) | 114 | #define tsvalue(o) (&rawtsvalue(o)->tsv) |
95 | #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value_.gc->u) | 115 | #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value_.gc->u) |
96 | #define uvalue(o) (&rawuvalue(o)->uv) | 116 | #define uvalue(o) (&rawuvalue(o)->uv) |
97 | #define clvalue(o) check_exp(ttisfunction(o), &(o)->value_.gc->cl) | 117 | #define clvalue(o) check_exp(ttisclosure(o), &(o)->value_.gc->cl) |
118 | #define fvalue(o) check_exp(ttiscfp(o), (o)->value_.f) | ||
98 | #define hvalue(o) check_exp(ttistable(o), &(o)->value_.gc->h) | 119 | #define hvalue(o) check_exp(ttistable(o), &(o)->value_.gc->h) |
99 | #define bvalue(o) check_exp(ttisboolean(o), (o)->value_.b) | 120 | #define bvalue(o) check_exp(ttisboolean(o), (o)->value_.b) |
100 | #define thvalue(o) check_exp(ttisthread(o), &(o)->value_.gc->th) | 121 | #define thvalue(o) check_exp(ttisthread(o), &(o)->value_.gc->th) |
101 | 122 | ||
102 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) | 123 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) |
103 | 124 | ||
104 | /* | 125 | |
105 | ** for internal debug only | ||
106 | */ | ||
107 | #define iscollectable(o) (ttype(o) >= LUA_TSTRING) | 126 | #define iscollectable(o) (ttype(o) >= LUA_TSTRING) |
108 | 127 | ||
109 | #define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) | 128 | #define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) |
@@ -120,6 +139,9 @@ typedef struct lua_TValue { | |||
120 | #define setnvalue(obj,x) \ | 139 | #define setnvalue(obj,x) \ |
121 | { TValue *i_o=(obj); i_o->value_.n=(x); i_o->tt_=LUA_TNUMBER; } | 140 | { TValue *i_o=(obj); i_o->value_.n=(x); i_o->tt_=LUA_TNUMBER; } |
122 | 141 | ||
142 | #define setfvalue(obj,x) \ | ||
143 | { TValue *i_o=(obj); i_o->value_.f=(x); i_o->tt_=LUA_TCFP; } | ||
144 | |||
123 | #define changenvalue(obj,x) \ | 145 | #define changenvalue(obj,x) \ |
124 | ( lua_assert((obj)->tt_==LUA_TNUMBER), (obj)->value_.n=(x) ) | 146 | ( lua_assert((obj)->tt_==LUA_TNUMBER), (obj)->value_.n=(x) ) |
125 | 147 | ||
@@ -313,8 +335,7 @@ typedef union Closure { | |||
313 | } Closure; | 335 | } Closure; |
314 | 336 | ||
315 | 337 | ||
316 | #define iscfunction(o) (ttisfunction(o) && clvalue(o)->c.isC) | 338 | #define isLfunction(o) (ttisclosure(o) && !clvalue(o)->c.isC) |
317 | #define isLfunction(o) (ttisfunction(o) && !clvalue(o)->c.isC) | ||
318 | 339 | ||
319 | #define getproto(o) (clvalue(o)->l.p) | 340 | #define getproto(o) (clvalue(o)->l.p) |
320 | 341 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 2.61 2010/04/08 17:16:46 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.62 2010/04/12 16:07:06 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -105,7 +105,6 @@ typedef struct CallInfo { | |||
105 | #define CIST_TAIL (1<<6) /* call was tail called */ | 105 | #define CIST_TAIL (1<<6) /* call was tail called */ |
106 | 106 | ||
107 | 107 | ||
108 | #define curr_func(L) (clvalue(L->ci->func)) | ||
109 | #define ci_func(ci) (clvalue((ci)->func)) | 108 | #define ci_func(ci) (clvalue((ci)->func)) |
110 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) | 109 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) |
111 | 110 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 2.47 2009/12/17 15:46:44 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 2.48 2010/04/05 16:26:37 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -109,6 +109,8 @@ static Node *mainposition (const Table *t, const TValue *key) { | |||
109 | return hashboolean(t, bvalue(key)); | 109 | return hashboolean(t, bvalue(key)); |
110 | case LUA_TLIGHTUSERDATA: | 110 | case LUA_TLIGHTUSERDATA: |
111 | return hashpointer(t, pvalue(key)); | 111 | return hashpointer(t, pvalue(key)); |
112 | case LUA_TCFP: | ||
113 | return hashpointer(t, fvalue(key)); | ||
112 | default: | 114 | default: |
113 | return hashpointer(t, gcvalue(key)); | 115 | return hashpointer(t, gcvalue(key)); |
114 | } | 116 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 2.92 2010/04/12 12:42:07 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.93 2010/04/12 16:07:39 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -191,7 +191,7 @@ static void printobj (global_State *g, GCObject *o) { | |||
191 | GCObject *p; | 191 | GCObject *p; |
192 | for (p = g->allgc; p != o && p != NULL; p = gch(p)->next) i++; | 192 | for (p = g->allgc; p != o && p != NULL; p = gch(p)->next) i++; |
193 | if (p == NULL) i = -1; | 193 | if (p == NULL) i = -1; |
194 | printf("%d:%s(%p)-%c(%02X)", i, typename(gch(o)->tt), (void *)o, | 194 | printf("%d:%s(%p)-%c(%02X)", i, ttypename(gch(o)->tt), (void *)o, |
195 | isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', gch(o)->marked); | 195 | isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', gch(o)->marked); |
196 | } | 196 | } |
197 | 197 | ||
@@ -519,7 +519,7 @@ static int mem_query (lua_State *L) { | |||
519 | const char *t = luaL_checkstring(L, 1); | 519 | const char *t = luaL_checkstring(L, 1); |
520 | int i; | 520 | int i; |
521 | for (i = LUA_NUMTAGS - 1; i >= 0; i--) { | 521 | for (i = LUA_NUMTAGS - 1; i >= 0; i--) { |
522 | if (strcmp(t, typename(i)) == 0) { | 522 | if (strcmp(t, ttypename(i)) == 0) { |
523 | lua_pushinteger(L, l_memcontrol.objcount[i]); | 523 | lua_pushinteger(L, l_memcontrol.objcount[i]); |
524 | return 1; | 524 | return 1; |
525 | } | 525 | } |
@@ -944,6 +944,9 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { | |||
944 | else if EQ("tonumber") { | 944 | else if EQ("tonumber") { |
945 | lua_pushnumber(L1, lua_tonumber(L1, getindex)); | 945 | lua_pushnumber(L1, lua_tonumber(L1, getindex)); |
946 | } | 946 | } |
947 | else if EQ("topointer") { | ||
948 | lua_pushlightuserdata(L1, cast(void *, lua_topointer(L1, getindex))); | ||
949 | } | ||
947 | else if EQ("tostring") { | 950 | else if EQ("tostring") { |
948 | const char *s = lua_tostring(L1, getindex); | 951 | const char *s = lua_tostring(L1, getindex); |
949 | const char *s1 = lua_pushstring(L1, s); | 952 | const char *s1 = lua_pushstring(L1, s); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.c,v 2.10 2009/11/19 19:06:52 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 2.11 2010/01/13 16:18:25 roberto Exp roberto $ |
3 | ** Tag methods | 3 | ** Tag methods |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -70,7 +70,7 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { | |||
70 | mt = uvalue(o)->metatable; | 70 | mt = uvalue(o)->metatable; |
71 | break; | 71 | break; |
72 | default: | 72 | default: |
73 | mt = G(L)->mt[ttype(o)]; | 73 | mt = G(L)->mt[ttypenv(o)]; |
74 | } | 74 | } |
75 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); | 75 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); |
76 | } | 76 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.h,v 2.8 2009/11/19 19:06:52 roberto Exp roberto $ | 2 | ** $Id: ltm.h,v 2.9 2010/01/13 16:18:25 roberto Exp roberto $ |
3 | ** Tag methods | 3 | ** Tag methods |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -43,7 +43,8 @@ typedef enum { | |||
43 | 43 | ||
44 | #define fasttm(l,et,e) gfasttm(G(l), et, e) | 44 | #define fasttm(l,et,e) gfasttm(G(l), et, e) |
45 | 45 | ||
46 | #define typename(x) luaT_typenames_[(x) + 1] | 46 | #define ttypename(x) luaT_typenames_[(x) + 1] |
47 | #define objtypename(x) ttypename(ttypenv(x)) | ||
47 | 48 | ||
48 | LUAI_DDEC const char *const luaT_typenames_[]; | 49 | LUAI_DDEC const char *const luaT_typenames_[]; |
49 | 50 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.109 2010/04/02 15:39:07 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.110 2010/04/05 16:26:37 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -218,7 +218,7 @@ static int l_strcmp (const TString *ls, const TString *rs) { | |||
218 | 218 | ||
219 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { | 219 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { |
220 | int res; | 220 | int res; |
221 | if (ttype(l) != ttype(r)) | 221 | if (ttypenv(l) != ttypenv(r)) |
222 | return luaG_ordererror(L, l, r); | 222 | return luaG_ordererror(L, l, r); |
223 | else if (ttisnumber(l)) | 223 | else if (ttisnumber(l)) |
224 | return luai_numlt(L, nvalue(l), nvalue(r)); | 224 | return luai_numlt(L, nvalue(l), nvalue(r)); |
@@ -232,7 +232,7 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { | |||
232 | 232 | ||
233 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { | 233 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { |
234 | int res; | 234 | int res; |
235 | if (ttype(l) != ttype(r)) | 235 | if (ttypenv(l) != ttypenv(r)) |
236 | return luaG_ordererror(L, l, r); | 236 | return luaG_ordererror(L, l, r); |
237 | else if (ttisnumber(l)) | 237 | else if (ttisnumber(l)) |
238 | return luai_numle(L, nvalue(l), nvalue(r)); | 238 | return luai_numle(L, nvalue(l), nvalue(r)); |
@@ -254,6 +254,7 @@ int luaV_equalval_ (lua_State *L, const TValue *t1, const TValue *t2) { | |||
254 | case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); | 254 | case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); |
255 | case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ | 255 | case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ |
256 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); | 256 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); |
257 | case LUA_TCFP: return fvalue(t1) == fvalue(t2); | ||
257 | case LUA_TSTRING: return eqstr(rawtsvalue(t1), rawtsvalue(t2)); | 258 | case LUA_TSTRING: return eqstr(rawtsvalue(t1), rawtsvalue(t2)); |
258 | case LUA_TUSERDATA: { | 259 | case LUA_TUSERDATA: { |
259 | if (uvalue(t1) == uvalue(t2)) return 1; | 260 | if (uvalue(t1) == uvalue(t2)) return 1; |