diff options
Diffstat (limited to 'src/lj_meta.c')
-rw-r--r-- | src/lj_meta.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/src/lj_meta.c b/src/lj_meta.c index 23f11f58..48cee510 100644 --- a/src/lj_meta.c +++ b/src/lj_meta.c | |||
@@ -393,13 +393,27 @@ void LJ_FASTCALL lj_meta_for(lua_State *L, TValue *o) | |||
393 | lj_err_msg(L, LJ_ERR_FORLIM); | 393 | lj_err_msg(L, LJ_ERR_FORLIM); |
394 | if (!(tvisnumber(o+2) || (tvisstr(o+2) && lj_str_tonumber(strV(o+2), o+2)))) | 394 | if (!(tvisnumber(o+2) || (tvisstr(o+2) && lj_str_tonumber(strV(o+2), o+2)))) |
395 | lj_err_msg(L, LJ_ERR_FORSTEP); | 395 | lj_err_msg(L, LJ_ERR_FORSTEP); |
396 | #if LJ_DUALNUM | 396 | if (LJ_DUALNUM) { |
397 | /* Ensure all slots are integers or all slots are numbers. */ | 397 | /* Ensure all slots are integers or all slots are numbers. */ |
398 | if (!(tvisint(o) && tvisint(o+1) && tvisint(o+2))) { | 398 | int32_t k[3]; |
399 | if (tvisint(o)) setnumV(o, (lua_Number)intV(o)); | 399 | int nint = 0; |
400 | if (tvisint(o+1)) setnumV(o+1, (lua_Number)intV(o+1)); | 400 | ptrdiff_t i; |
401 | if (tvisint(o+2)) setnumV(o+2, (lua_Number)intV(o+2)); | 401 | for (i = 0; i <= 2; i++) { |
402 | if (tvisint(o+i)) { | ||
403 | k[i] = intV(o+i); nint++; | ||
404 | } else { | ||
405 | k[i] = lj_num2int(numV(o+i)); nint += ((lua_Number)k[i] == numV(o+i)); | ||
406 | } | ||
407 | } | ||
408 | if (nint == 3) { /* Narrow to integers. */ | ||
409 | setintV(o, k[0]); | ||
410 | setintV(o+1, k[1]); | ||
411 | setintV(o+2, k[2]); | ||
412 | } else if (nint != 0) { /* Widen to numbers. */ | ||
413 | if (tvisint(o)) setnumV(o, (lua_Number)intV(o)); | ||
414 | if (tvisint(o+1)) setnumV(o+1, (lua_Number)intV(o+1)); | ||
415 | if (tvisint(o+2)) setnumV(o+2, (lua_Number)intV(o+2)); | ||
416 | } | ||
402 | } | 417 | } |
403 | #endif | ||
404 | } | 418 | } |
405 | 419 | ||