diff options
Diffstat (limited to 'ltm.c')
-rw-r--r-- | ltm.c | 63 |
1 files changed, 36 insertions, 27 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.c,v 1.52 2000/10/03 14:27:44 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 1.53 2000/10/05 12:14:08 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 | */ |
@@ -17,7 +17,7 @@ | |||
17 | #include "ltm.h" | 17 | #include "ltm.h" |
18 | 18 | ||
19 | 19 | ||
20 | const char *const luaT_eventname[] = { /* ORDER IM */ | 20 | const char *const luaT_eventname[] = { /* ORDER TM */ |
21 | "gettable", "settable", "index", "getglobal", "setglobal", "add", "sub", | 21 | "gettable", "settable", "index", "getglobal", "setglobal", "add", "sub", |
22 | "mul", "div", "pow", "unm", "lt", "concat", "gc", "function", | 22 | "mul", "div", "pow", "unm", "lt", "concat", "gc", "function", |
23 | "le", "gt", "ge", /* deprecated options!! */ | 23 | "le", "gt", "ge", /* deprecated options!! */ |
@@ -36,9 +36,9 @@ static int findevent (const char *name) { | |||
36 | 36 | ||
37 | static int luaI_checkevent (lua_State *L, const char *name, int t) { | 37 | static int luaI_checkevent (lua_State *L, const char *name, int t) { |
38 | int e = findevent(name); | 38 | int e = findevent(name); |
39 | if (e >= IM_N) | 39 | if (e >= TM_N) |
40 | luaO_verror(L, "event `%.50s' is deprecated", name); | 40 | luaO_verror(L, "event `%.50s' is deprecated", name); |
41 | if (e == IM_GC && t == LUA_TTABLE) | 41 | if (e == TM_GC && t == LUA_TTABLE) |
42 | luaO_verror(L, "event `gc' for tables is deprecated"); | 42 | luaO_verror(L, "event `gc' for tables is deprecated"); |
43 | if (e < 0) | 43 | if (e < 0) |
44 | luaO_verror(L, "`%.50s' is not a valid event name", name); | 44 | luaO_verror(L, "`%.50s' is not a valid event name", name); |
@@ -50,8 +50,8 @@ static int luaI_checkevent (lua_State *L, const char *name, int t) { | |||
50 | /* events in LUA_TNIL are all allowed, since this is used as a | 50 | /* events in LUA_TNIL are all allowed, since this is used as a |
51 | * 'placeholder' for "default" fallbacks | 51 | * 'placeholder' for "default" fallbacks |
52 | */ | 52 | */ |
53 | /* ORDER LUA_T, ORDER IM */ | 53 | /* ORDER LUA_T, ORDER TM */ |
54 | static const char luaT_validevents[NUM_TAGS][IM_N] = { | 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 */ | 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 */ | 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 */ | 57 | {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, /* LUA_TNUMBER */ |
@@ -67,16 +67,16 @@ int luaT_validevent (int t, int e) { /* ORDER LUA_T */ | |||
67 | 67 | ||
68 | static void init_entry (lua_State *L, int tag) { | 68 | static void init_entry (lua_State *L, int tag) { |
69 | int i; | 69 | int i; |
70 | for (i=0; i<IM_N; i++) | 70 | for (i=0; i<TM_N; i++) |
71 | ttype(luaT_getim(L, tag, i)) = LUA_TNIL; | 71 | luaT_gettm(L, tag, i) = NULL; |
72 | L->IMtable[tag].collected = NULL; | 72 | L->TMtable[tag].collected = NULL; |
73 | } | 73 | } |
74 | 74 | ||
75 | 75 | ||
76 | void luaT_init (lua_State *L) { | 76 | void luaT_init (lua_State *L) { |
77 | int t; | 77 | int t; |
78 | luaM_growvector(L, L->IMtable, 0, NUM_TAGS, struct IM, "", MAX_INT); | 78 | luaM_growvector(L, L->TMtable, 0, NUM_TAGS, struct TM, "", MAX_INT); |
79 | L->nblocks += NUM_TAGS*sizeof(struct IM); | 79 | L->nblocks += NUM_TAGS*sizeof(struct TM); |
80 | L->last_tag = NUM_TAGS-1; | 80 | L->last_tag = NUM_TAGS-1; |
81 | for (t=0; t<=L->last_tag; t++) | 81 | for (t=0; t<=L->last_tag; t++) |
82 | init_entry(L, t); | 82 | init_entry(L, t); |
@@ -84,9 +84,9 @@ void luaT_init (lua_State *L) { | |||
84 | 84 | ||
85 | 85 | ||
86 | int lua_newtag (lua_State *L) { | 86 | int lua_newtag (lua_State *L) { |
87 | luaM_growvector(L, L->IMtable, L->last_tag, 1, struct IM, | 87 | luaM_growvector(L, L->TMtable, L->last_tag, 1, struct TM, |
88 | "tag table overflow", MAX_INT); | 88 | "tag table overflow", MAX_INT); |
89 | L->nblocks += sizeof(struct IM); | 89 | L->nblocks += sizeof(struct TM); |
90 | L->last_tag++; | 90 | L->last_tag++; |
91 | init_entry(L, L->last_tag); | 91 | init_entry(L, L->last_tag); |
92 | return L->last_tag; | 92 | return L->last_tag; |
@@ -108,9 +108,9 @@ int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) { | |||
108 | int e; | 108 | int e; |
109 | checktag(L, tagto); | 109 | checktag(L, tagto); |
110 | checktag(L, tagfrom); | 110 | checktag(L, tagfrom); |
111 | for (e=0; e<IM_N; e++) { | 111 | for (e=0; e<TM_N; e++) { |
112 | if (luaT_validevent(tagto, e)) | 112 | if (luaT_validevent(tagto, e)) |
113 | *luaT_getim(L, tagto, e) = *luaT_getim(L, tagfrom, e); | 113 | luaT_gettm(L, tagto, e) = luaT_gettm(L, tagfrom, e); |
114 | } | 114 | } |
115 | return tagto; | 115 | return tagto; |
116 | } | 116 | } |
@@ -130,8 +130,10 @@ void lua_gettagmethod (lua_State *L, int t, const char *event) { | |||
130 | int e; | 130 | int e; |
131 | e = luaI_checkevent(L, event, t); | 131 | e = luaI_checkevent(L, event, t); |
132 | checktag(L, t); | 132 | checktag(L, t); |
133 | if (luaT_validevent(t, e)) | 133 | if (luaT_validevent(t, e) && luaT_gettm(L, t, e)) { |
134 | *L->top = *luaT_getim(L, t,e); | 134 | clvalue(L->top) = luaT_gettm(L, t, e); |
135 | ttype(L->top) = LUA_TFUNCTION; | ||
136 | } | ||
135 | else | 137 | else |
136 | ttype(L->top) = LUA_TNIL; | 138 | ttype(L->top) = LUA_TNIL; |
137 | incr_top; | 139 | incr_top; |
@@ -139,19 +141,26 @@ void lua_gettagmethod (lua_State *L, int t, const char *event) { | |||
139 | 141 | ||
140 | 142 | ||
141 | void lua_settagmethod (lua_State *L, int t, const char *event) { | 143 | void lua_settagmethod (lua_State *L, int t, const char *event) { |
142 | TObject temp; | 144 | Closure *oldtm; |
143 | int e; | 145 | int e = luaI_checkevent(L, event, t); |
144 | LUA_ASSERT(lua_isnil(L, -1) || lua_isfunction(L, -1), | ||
145 | "function or nil expected"); | ||
146 | e = luaI_checkevent(L, event, t); | ||
147 | checktag(L, t); | 146 | checktag(L, t); |
148 | if (!luaT_validevent(t, e)) | 147 | if (!luaT_validevent(t, e)) |
149 | luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s", | 148 | luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s", |
150 | luaT_eventname[e], luaO_typenames[t], | 149 | luaT_eventname[e], luaO_typenames[t], |
151 | (t == LUA_TTABLE || t == LUA_TUSERDATA) ? " with default tag" | 150 | (t == LUA_TTABLE || t == LUA_TUSERDATA) ? |
152 | : ""); | 151 | " with default tag" : ""); |
153 | temp = *(L->top - 1); | 152 | oldtm = luaT_gettm(L, t, e); |
154 | *(L->top - 1) = *luaT_getim(L, t,e); | 153 | switch (ttype(L->top - 1)) { |
155 | *luaT_getim(L, t, e) = temp; | 154 | case LUA_TNIL: |
155 | luaT_gettm(L, t, e) = NULL; | ||
156 | break; | ||
157 | case LUA_TFUNCTION: | ||
158 | luaT_gettm(L, t, e) = clvalue(L->top - 1); | ||
159 | break; | ||
160 | default: | ||
161 | lua_error(L, "tag method must be a function (or nil)"); | ||
162 | } | ||
163 | clvalue(L->top - 1) = oldtm; | ||
164 | ttype(L->top - 1) = (oldtm ? LUA_TFUNCTION : LUA_TNIL); | ||
156 | } | 165 | } |
157 | 166 | ||