diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2007-03-26 12:56:23 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2007-03-26 12:56:23 -0300 |
commit | 1a455acc81463489c9e08f037cc71dc61b54935c (patch) | |
tree | dbf838cbc073cd2f025a2d8707d41dfd79982bf3 /lvm.c | |
parent | 60bc151ed70bce0d534edcbbba4380dee4306708 (diff) | |
download | lua-1a455acc81463489c9e08f037cc71dc61b54935c.tar.gz lua-1a455acc81463489c9e08f037cc71dc61b54935c.tar.bz2 lua-1a455acc81463489c9e08f037cc71dc61b54935c.zip |
two small bugs: some metamethods do not accept callable non-function
objects + __concat converts numbers to strings before calling metamethod
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 13 |
1 files changed, 6 insertions, 7 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.69 2006/09/19 14:06:45 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.70 2007/02/09 13:04:52 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 | */ |
@@ -162,7 +162,7 @@ static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, | |||
162 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ | 162 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ |
163 | if (ttisnil(tm)) | 163 | if (ttisnil(tm)) |
164 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | 164 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ |
165 | if (!ttisfunction(tm)) return 0; | 165 | if (ttisnil(tm)) return 0; |
166 | callTMres(L, res, tm, p1, p2); | 166 | callTMres(L, res, tm, p1, p2); |
167 | return 1; | 167 | return 1; |
168 | } | 168 | } |
@@ -257,8 +257,7 @@ int luaV_equalval_ (lua_State *L, const TValue *t1, const TValue *t2) { | |||
257 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); | 257 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); |
258 | case LUA_TUSERDATA: { | 258 | case LUA_TUSERDATA: { |
259 | if (uvalue(t1) == uvalue(t2)) return 1; | 259 | if (uvalue(t1) == uvalue(t2)) return 1; |
260 | tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, | 260 | tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); |
261 | TM_EQ); | ||
262 | break; /* will try TM */ | 261 | break; /* will try TM */ |
263 | } | 262 | } |
264 | case LUA_TTABLE: { | 263 | case LUA_TTABLE: { |
@@ -278,12 +277,12 @@ void luaV_concat (lua_State *L, int total, int last) { | |||
278 | do { | 277 | do { |
279 | StkId top = L->base + last + 1; | 278 | StkId top = L->base + last + 1; |
280 | int n = 2; /* number of elements handled in this pass (at least 2) */ | 279 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
281 | if (!tostring(L, top-2) || !tostring(L, top-1)) { | 280 | if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { |
282 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) | 281 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) |
283 | luaG_concaterror(L, top-2, top-1); | 282 | luaG_concaterror(L, top-2, top-1); |
284 | } else if (tsvalue(top-1)->len == 0) { /* second operand is empty? */ | 283 | } else if (tsvalue(top-1)->len == 0) { /* second operand is empty? */ |
285 | /* do nothing; result is already first operand */ ; | 284 | (void)tostring(L, top - 2); /* result is first operand */ ; |
286 | } else if (tsvalue(top-2)->len == 0) { /* fist operand is empty? */ | 285 | } else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { |
287 | setsvalue2s(L, top-2, rawtsvalue(top-1)); /* result is second op. */ | 286 | setsvalue2s(L, top-2, rawtsvalue(top-1)); /* result is second op. */ |
288 | } else { | 287 | } else { |
289 | /* at least two (non-empty) string values; get as many as possible */ | 288 | /* at least two (non-empty) string values; get as many as possible */ |