2 ** $Id: ltm.c,v 1.56 2000/10/31 13:10:24 roberto Exp $
4 ** See Copyright Notice in lua.h
20 const char *const luaT_eventname
[] = { /* ORDER TM */
21 "gettable", "settable", "index", "getglobal", "setglobal", "add", "sub",
22 "mul", "div", "pow", "unm", "lt", "concat", "gc", "function",
23 "le", "gt", "ge", /* deprecated options!! */
28 static int findevent (const char *name
) {
30 for (i
=0; luaT_eventname
[i
]; i
++)
31 if (strcmp(luaT_eventname
[i
], name
) == 0)
33 return -1; /* name not found */
37 static int luaI_checkevent (lua_State
*L
, const char *name
, int t
) {
38 int e
= findevent(name
);
40 luaO_verror(L
, "event `%.50s' is deprecated", name
);
41 if (e
== TM_GC
&& t
== LUA_TTABLE
)
42 luaO_verror(L
, "event `gc' for tables is deprecated");
44 luaO_verror(L
, "`%.50s' is not a valid event name", name
);
50 /* events in LUA_TNIL are all allowed, since this is used as a
51 * 'placeholder' for "default" fallbacks
53 /* ORDER LUA_T, ORDER TM */
54 static const char luaT_validevents
[NUM_TAGS
][TM_N
] = {
55 {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TUSERDATA */
56 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_TNIL */
57 {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, /* LUA_TNUMBER */
58 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_TSTRING */
59 {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TTABLE */
60 {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0} /* LUA_TFUNCTION */
63 int luaT_validevent (int t
, int e
) { /* ORDER LUA_T */
64 return (t
>= NUM_TAGS
) ? 1 : luaT_validevents
[t
][e
];
68 static void init_entry (lua_State
*L
, int tag
) {
70 for (i
=0; i
<TM_N
; i
++)
71 luaT_gettm(L
, tag
, i
) = NULL
;
72 L
->TMtable
[tag
].collected
= NULL
;
76 void luaT_init (lua_State
*L
) {
78 luaM_growvector(L
, L
->TMtable
, 0, NUM_TAGS
, struct TM
, "", MAX_INT
);
79 L
->nblocks
+= NUM_TAGS
*sizeof(struct TM
);
80 L
->last_tag
= NUM_TAGS
-1;
81 for (t
=0; t
<=L
->last_tag
; t
++)
86 LUA_API
int lua_newtag (lua_State
*L
) {
87 luaM_growvector(L
, L
->TMtable
, L
->last_tag
, 1, struct TM
,
88 "tag table overflow", MAX_INT
);
89 L
->nblocks
+= sizeof(struct TM
);
91 init_entry(L
, L
->last_tag
);
96 static void checktag (lua_State
*L
, int tag
) {
97 if (!(0 <= tag
&& tag
<= L
->last_tag
))
98 luaO_verror(L
, "%d is not a valid tag", tag
);
101 void luaT_realtag (lua_State
*L
, int tag
) {
103 luaO_verror(L
, "tag %d was not created by `newtag'", tag
);
107 LUA_API
int lua_copytagmethods (lua_State
*L
, int tagto
, int tagfrom
) {
110 checktag(L
, tagfrom
);
111 for (e
=0; e
<TM_N
; e
++) {
112 if (luaT_validevent(tagto
, e
))
113 luaT_gettm(L
, tagto
, e
) = luaT_gettm(L
, tagfrom
, e
);
119 int luaT_tag (const TObject
*o
) {
122 case LUA_TUSERDATA
: return tsvalue(o
)->u
.d
.tag
;
123 case LUA_TTABLE
: return hvalue(o
)->htag
;
129 LUA_API
void lua_gettagmethod (lua_State
*L
, int t
, const char *event
) {
131 e
= luaI_checkevent(L
, event
, t
);
133 if (luaT_validevent(t
, e
) && luaT_gettm(L
, t
, e
)) {
134 clvalue(L
->top
) = luaT_gettm(L
, t
, e
);
135 ttype(L
->top
) = LUA_TFUNCTION
;
138 ttype(L
->top
) = LUA_TNIL
;
143 LUA_API
void lua_settagmethod (lua_State
*L
, int t
, const char *event
) {
144 int e
= luaI_checkevent(L
, event
, t
);
146 if (!luaT_validevent(t
, e
))
147 luaO_verror(L
, "cannot change `%.20s' tag method for type `%.20s'%.20s",
148 luaT_eventname
[e
], luaO_typenames
[t
],
149 (t
== LUA_TTABLE
|| t
== LUA_TUSERDATA
) ?
150 " with default tag" : "");
151 switch (ttype(L
->top
- 1)) {
153 luaT_gettm(L
, t
, e
) = NULL
;
156 luaT_gettm(L
, t
, e
) = clvalue(L
->top
- 1);
159 lua_error(L
, "tag method must be a function (or nil)");