diff options
-rw-r--r-- | lvm.c | 60 |
1 files changed, 42 insertions, 18 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.310 2017/11/13 15:36:52 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.311 2017/11/16 12:59:14 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 | */ |
@@ -326,6 +326,7 @@ static int LEintfloat (lua_Integer i, lua_Number f) { | |||
326 | ** Return 'l < r', for numbers. | 326 | ** Return 'l < r', for numbers. |
327 | */ | 327 | */ |
328 | static int LTnum (const TValue *l, const TValue *r) { | 328 | static int LTnum (const TValue *l, const TValue *r) { |
329 | lua_assert(ttisnumber(l) && ttisnumber(r)); | ||
329 | if (ttisinteger(l)) { | 330 | if (ttisinteger(l)) { |
330 | lua_Integer li = ivalue(l); | 331 | lua_Integer li = ivalue(l); |
331 | if (ttisinteger(r)) | 332 | if (ttisinteger(r)) |
@@ -349,6 +350,7 @@ static int LTnum (const TValue *l, const TValue *r) { | |||
349 | ** Return 'l <= r', for numbers. | 350 | ** Return 'l <= r', for numbers. |
350 | */ | 351 | */ |
351 | static int LEnum (const TValue *l, const TValue *r) { | 352 | static int LEnum (const TValue *l, const TValue *r) { |
353 | lua_assert(ttisnumber(l) && ttisnumber(r)); | ||
352 | if (ttisinteger(l)) { | 354 | if (ttisinteger(l)) { |
353 | lua_Integer li = ivalue(l); | 355 | lua_Integer li = ivalue(l); |
354 | if (ttisinteger(r)) | 356 | if (ttisinteger(r)) |
@@ -369,13 +371,12 @@ static int LEnum (const TValue *l, const TValue *r) { | |||
369 | 371 | ||
370 | 372 | ||
371 | /* | 373 | /* |
372 | ** Main operation less than; return 'l < r'. | 374 | ** return 'l < r' for non-numbers. |
373 | */ | 375 | */ |
374 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { | 376 | static int lessthanothers (lua_State *L, const TValue *l, const TValue *r) { |
375 | int res; | 377 | int res; |
376 | if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ | 378 | lua_assert(!ttisnumber(l) || !ttisnumber(r)); |
377 | return LTnum(l, r); | 379 | if (ttisstring(l) && ttisstring(r)) /* both are strings? */ |
378 | else if (ttisstring(l) && ttisstring(r)) /* both are strings? */ | ||
379 | return l_strcmp(tsvalue(l), tsvalue(r)) < 0; | 380 | return l_strcmp(tsvalue(l), tsvalue(r)) < 0; |
380 | else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */ | 381 | else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */ |
381 | luaG_ordererror(L, l, r); /* error */ | 382 | luaG_ordererror(L, l, r); /* error */ |
@@ -384,18 +385,27 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { | |||
384 | 385 | ||
385 | 386 | ||
386 | /* | 387 | /* |
387 | ** Main operation less than or equal to; return 'l <= r'. If it needs | 388 | ** Main operation less than; return 'l < r'. |
388 | ** a metamethod and there is no '__le', try '__lt', based on | ||
389 | ** l <= r iff !(r < l) (assuming a total order). If the metamethod | ||
390 | ** yields during this substitution, the continuation has to know | ||
391 | ** about it (to negate the result of r<l); bit CIST_LEQ in the call | ||
392 | ** status keeps that information. | ||
393 | */ | 389 | */ |
394 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { | 390 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { |
395 | int res; | ||
396 | if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ | 391 | if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ |
397 | return LEnum(l, r); | 392 | return LTnum(l, r); |
398 | else if (ttisstring(l) && ttisstring(r)) /* both are strings? */ | 393 | else return lessthanothers(L, l, r); |
394 | } | ||
395 | |||
396 | |||
397 | /* | ||
398 | ** return 'l <= r' for non-numbers. | ||
399 | ** If it needs a metamethod and there is no '__le', try '__lt', based | ||
400 | ** on l <= r iff !(r < l) (assuming a total order). If the metamethod | ||
401 | ** yields during this substitution, the continuation has to know about | ||
402 | ** it (to negate the result of r<l); bit CIST_LEQ in the call status | ||
403 | ** keeps that information. | ||
404 | */ | ||
405 | static int lessequalothers (lua_State *L, const TValue *l, const TValue *r) { | ||
406 | int res; | ||
407 | lua_assert(!ttisnumber(l) || !ttisnumber(r)); | ||
408 | if (ttisstring(l) && ttisstring(r)) /* both are strings? */ | ||
399 | return l_strcmp(tsvalue(l), tsvalue(r)) <= 0; | 409 | return l_strcmp(tsvalue(l), tsvalue(r)) <= 0; |
400 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */ | 410 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */ |
401 | return res; | 411 | return res; |
@@ -411,6 +421,16 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { | |||
411 | 421 | ||
412 | 422 | ||
413 | /* | 423 | /* |
424 | ** Main operation less than or equal to; return 'l <= r'. | ||
425 | */ | ||
426 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { | ||
427 | if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ | ||
428 | return LEnum(l, r); | ||
429 | else return lessequalothers(L, l, r); | ||
430 | } | ||
431 | |||
432 | |||
433 | /* | ||
414 | ** Main operation for equality of Lua values; return 't1 == t2'. | 434 | ** Main operation for equality of Lua values; return 't1 == t2'. |
415 | ** L == NULL means raw equality (no metamethods) | 435 | ** L == NULL means raw equality (no metamethods) |
416 | */ | 436 | */ |
@@ -1336,8 +1356,10 @@ void luaV_execute (lua_State *L) { | |||
1336 | int res; | 1356 | int res; |
1337 | if (ttisinteger(rb) && ttisinteger(rc)) | 1357 | if (ttisinteger(rb) && ttisinteger(rc)) |
1338 | res = (ivalue(rb) < ivalue(rc)); | 1358 | res = (ivalue(rb) < ivalue(rc)); |
1359 | else if (ttisnumber(rb) && ttisnumber(rc)) | ||
1360 | res = LTnum(rb, rc); | ||
1339 | else | 1361 | else |
1340 | Protect(res = luaV_lessthan(L, rb, rc)); | 1362 | Protect(res = lessthanothers(L, rb, rc)); |
1341 | if (res != GETARG_A(i)) | 1363 | if (res != GETARG_A(i)) |
1342 | pc++; | 1364 | pc++; |
1343 | else | 1365 | else |
@@ -1350,8 +1372,10 @@ void luaV_execute (lua_State *L) { | |||
1350 | int res; | 1372 | int res; |
1351 | if (ttisinteger(rb) && ttisinteger(rc)) | 1373 | if (ttisinteger(rb) && ttisinteger(rc)) |
1352 | res = (ivalue(rb) <= ivalue(rc)); | 1374 | res = (ivalue(rb) <= ivalue(rc)); |
1375 | else if (ttisnumber(rb) && ttisnumber(rc)) | ||
1376 | res = LEnum(rb, rc); | ||
1353 | else | 1377 | else |
1354 | Protect(res = luaV_lessequal(L, rb, rc)); | 1378 | Protect(res = lessequalothers(L, rb, rc)); |
1355 | if (res != GETARG_A(i)) | 1379 | if (res != GETARG_A(i)) |
1356 | pc++; | 1380 | pc++; |
1357 | else | 1381 | else |