diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-20 10:57:39 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-20 10:57:39 -0200 |
| commit | f3ca52bfa994edacfa8fbbc6f1014724b384de9a (patch) | |
| tree | 5302312fd0dc8e6b20a27d4d1413e9da174b9a95 | |
| parent | c47111bd4e33b2dcb4fc2cceb7b268ab02eea452 (diff) | |
| download | lua-f3ca52bfa994edacfa8fbbc6f1014724b384de9a.tar.gz lua-f3ca52bfa994edacfa8fbbc6f1014724b384de9a.tar.bz2 lua-f3ca52bfa994edacfa8fbbc6f1014724b384de9a.zip | |
in order comparison opcodes, fast track for floats too
| -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 |
