diff options
Diffstat (limited to 'lbuiltin.c')
-rw-r--r-- | lbuiltin.c | 63 |
1 files changed, 45 insertions, 18 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbuiltin.c,v 1.62 1999/09/08 20:45:18 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.63 1999/09/20 14:57:29 roberto Exp roberto $ |
3 | ** Built-in functions | 3 | ** Built-in functions |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -222,9 +222,15 @@ static void luaB_rawsettable (void) { | |||
222 | } | 222 | } |
223 | 223 | ||
224 | static void luaB_settagmethod (void) { | 224 | static void luaB_settagmethod (void) { |
225 | int tag = luaL_check_int(1); | ||
226 | const char *event = luaL_check_string(2); | ||
225 | lua_Object nf = luaL_nonnullarg(3); | 227 | lua_Object nf = luaL_nonnullarg(3); |
228 | #ifndef LUA_COMPAT_GC | ||
229 | if (strcmp(event, "gc") == 0 && tag != LUA_T_NIL) | ||
230 | lua_error("cannot set this tag method from Lua"); | ||
231 | #endif | ||
226 | lua_pushobject(nf); | 232 | lua_pushobject(nf); |
227 | lua_pushobject(lua_settagmethod(luaL_check_int(1), luaL_check_string(2))); | 233 | lua_pushobject(lua_settagmethod(tag, event)); |
228 | } | 234 | } |
229 | 235 | ||
230 | static void luaB_gettagmethod (void) { | 236 | static void luaB_gettagmethod (void) { |
@@ -437,12 +443,11 @@ static void luaB_foreach (void) { | |||
437 | 443 | ||
438 | 444 | ||
439 | static void luaB_foreachvar (void) { | 445 | static void luaB_foreachvar (void) { |
440 | GCnode *g; | 446 | TaggedString *s; |
441 | TObject f; /* see comment in 'foreachi' */ | 447 | TObject f; /* see comment in 'foreachi' */ |
442 | f = *luaA_Address(luaL_functionarg(1)); | 448 | f = *luaA_Address(luaL_functionarg(1)); |
443 | luaD_checkstack(4); /* for extra var name, f, var name, and globalval */ | 449 | luaD_checkstack(4); /* for extra var name, f, var name, and globalval */ |
444 | for (g = L->rootglobal.next; g; g = g->next) { | 450 | for (s = L->rootglobal; s; s = s->next) { |
445 | TaggedString *s = (TaggedString *)g; | ||
446 | if (s->u.s.globalval.ttype != LUA_T_NIL) { | 451 | if (s->u.s.globalval.ttype != LUA_T_NIL) { |
447 | pushtagstring(s); /* keep (extra) s on stack to avoid GC */ | 452 | pushtagstring(s); /* keep (extra) s on stack to avoid GC */ |
448 | *(L->stack.top++) = f; | 453 | *(L->stack.top++) = f; |
@@ -451,10 +456,10 @@ static void luaB_foreachvar (void) { | |||
451 | luaD_calln(2, 1); | 456 | luaD_calln(2, 1); |
452 | if (ttype(L->stack.top-1) != LUA_T_NIL) { | 457 | if (ttype(L->stack.top-1) != LUA_T_NIL) { |
453 | L->stack.top--; | 458 | L->stack.top--; |
454 | *(L->stack.top-1) = *L->stack.top; /* remove extra s */ | 459 | *(L->stack.top-1) = *L->stack.top; /* remove extra `s' */ |
455 | return; | 460 | return; |
456 | } | 461 | } |
457 | L->stack.top-=2; /* remove result and extra s */ | 462 | L->stack.top-=2; /* remove result and extra `s' */ |
458 | } | 463 | } |
459 | } | 464 | } |
460 | } | 465 | } |
@@ -602,20 +607,42 @@ static void mem_query (void) { | |||
602 | 607 | ||
603 | 608 | ||
604 | static void query_strings (void) { | 609 | static void query_strings (void) { |
605 | lua_pushnumber(L->string_root[luaL_check_int(1)].nuse); | 610 | int h = luaL_check_int(1) - 1; |
611 | int s = luaL_opt_int(2, 0) - 1; | ||
612 | if (s==-1) { | ||
613 | if (h < NUM_HASHS) { | ||
614 | lua_pushnumber(L->string_root[h].nuse); | ||
615 | lua_pushnumber(L->string_root[h].size); | ||
616 | } | ||
617 | } | ||
618 | else { | ||
619 | TaggedString *ts = L->string_root[h].hash[s]; | ||
620 | if (ts == NULL) lua_pushstring("<NIL>"); | ||
621 | else if (ts == &luaS_EMPTY) lua_pushstring("<EMPTY>"); | ||
622 | else if (ts->constindex == -1) lua_pushstring("<USERDATA>"); | ||
623 | else lua_pushstring(ts->str); | ||
624 | } | ||
606 | } | 625 | } |
607 | 626 | ||
608 | 627 | ||
609 | static void countlist (void) { | 628 | static void extra_services (void) { |
610 | const char *s = luaL_check_string(1); | 629 | const char *service = luaL_check_string(1); |
611 | GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next : | 630 | switch (*service) { |
612 | (s[0]=='p') ? L->rootproto.next : L->rootglobal.next; | 631 | case 'U': /* create a userdata with a given value/tag */ |
613 | int i=0; | 632 | lua_pushusertag((void *)luaL_check_int(2), luaL_check_int(3)); |
614 | while (l) { | 633 | break; |
615 | i++; | 634 | |
616 | l = l->next; | 635 | case 'u': /* return the value of a userdata */ |
636 | lua_pushnumber((int)lua_getuserdata(lua_getparam(2))); | ||
637 | break; | ||
638 | |||
639 | case 't': /* set `gc' tag method */ | ||
640 | lua_pushobject(lua_getparam(3)); | ||
641 | lua_settagmethod(luaL_check_int(2), "gc"); | ||
642 | break; | ||
643 | |||
644 | default: luaL_arg_check(0, 1, "invalid service"); | ||
617 | } | 645 | } |
618 | lua_pushnumber(i); | ||
619 | } | 646 | } |
620 | 647 | ||
621 | 648 | ||
@@ -679,9 +706,9 @@ static void testC (void) { | |||
679 | 706 | ||
680 | static const struct luaL_reg builtin_funcs[] = { | 707 | static const struct luaL_reg builtin_funcs[] = { |
681 | #ifdef DEBUG | 708 | #ifdef DEBUG |
709 | {"extra", extra_services}, | ||
682 | {"testC", testC}, | 710 | {"testC", testC}, |
683 | {"totalmem", mem_query}, | 711 | {"totalmem", mem_query}, |
684 | {"count", countlist}, | ||
685 | {"querystr", query_strings}, | 712 | {"querystr", query_strings}, |
686 | #endif | 713 | #endif |
687 | {"_ALERT", luaB_alert}, | 714 | {"_ALERT", luaB_alert}, |