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 | |
| 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
| -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 */ |
