diff options
Diffstat (limited to 'src/lj_ffrecord.c')
-rw-r--r-- | src/lj_ffrecord.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index 631321d9..8077bf84 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c | |||
@@ -63,9 +63,9 @@ typedef void (LJ_FASTCALL *RecordFunc)(jit_State *J, RecordFFData *rd); | |||
63 | /* Get runtime value of int argument. */ | 63 | /* Get runtime value of int argument. */ |
64 | static int32_t argv2int(jit_State *J, TValue *o) | 64 | static int32_t argv2int(jit_State *J, TValue *o) |
65 | { | 65 | { |
66 | if (!tvisnum(o) && !(tvisstr(o) && lj_str_tonum(strV(o), o))) | 66 | if (!tvisnumber(o) && !(tvisstr(o) && lj_str_tonumber(strV(o), o))) |
67 | lj_trace_err(J, LJ_TRERR_BADTYPE); | 67 | lj_trace_err(J, LJ_TRERR_BADTYPE); |
68 | return lj_num2bit(numV(o)); | 68 | return tvisint(o) ? intV(o) : lj_num2int(numV(o)); |
69 | } | 69 | } |
70 | 70 | ||
71 | /* Get runtime value of string argument. */ | 71 | /* Get runtime value of string argument. */ |
@@ -75,9 +75,12 @@ static GCstr *argv2str(jit_State *J, TValue *o) | |||
75 | return strV(o); | 75 | return strV(o); |
76 | } else { | 76 | } else { |
77 | GCstr *s; | 77 | GCstr *s; |
78 | if (!tvisnum(o)) | 78 | if (!tvisnumber(o)) |
79 | lj_trace_err(J, LJ_TRERR_BADTYPE); | 79 | lj_trace_err(J, LJ_TRERR_BADTYPE); |
80 | s = lj_str_fromnum(J->L, &o->n); | 80 | if (tvisint(o)) |
81 | s = lj_str_fromint(J->L, intV(o)); | ||
82 | else | ||
83 | s = lj_str_fromnum(J->L, &o->n); | ||
81 | setstrV(J->L, o, s); | 84 | setstrV(J->L, o, s); |
82 | return s; | 85 | return s; |
83 | } | 86 | } |
@@ -128,7 +131,7 @@ static void LJ_FASTCALL recff_type(jit_State *J, RecordFFData *rd) | |||
128 | { | 131 | { |
129 | /* Arguments already specialized. Result is a constant string. Neat, huh? */ | 132 | /* Arguments already specialized. Result is a constant string. Neat, huh? */ |
130 | uint32_t t; | 133 | uint32_t t; |
131 | if (tvisnum(&rd->argv[0])) | 134 | if (tvisnumber(&rd->argv[0])) |
132 | t = ~LJ_TNUMX; | 135 | t = ~LJ_TNUMX; |
133 | else if (LJ_64 && tvislightud(&rd->argv[0])) | 136 | else if (LJ_64 && tvislightud(&rd->argv[0])) |
134 | t = ~LJ_TLIGHTUD; | 137 | t = ~LJ_TLIGHTUD; |
@@ -255,7 +258,7 @@ static void LJ_FASTCALL recff_tonumber(jit_State *J, RecordFFData *rd) | |||
255 | TRef tr = J->base[0]; | 258 | TRef tr = J->base[0]; |
256 | TRef base = J->base[1]; | 259 | TRef base = J->base[1]; |
257 | if (tr && base) { | 260 | if (tr && base) { |
258 | base = lj_ir_toint(J, base); | 261 | base = lj_opt_narrow_toint(J, base); |
259 | if (!tref_isk(base) || IR(tref_ref(base))->i != 10) | 262 | if (!tref_isk(base) || IR(tref_ref(base))->i != 10) |
260 | recff_nyiu(J); | 263 | recff_nyiu(J); |
261 | } | 264 | } |
@@ -332,12 +335,12 @@ static void LJ_FASTCALL recff_ipairs_aux(jit_State *J, RecordFFData *rd) | |||
332 | RecordIndex ix; | 335 | RecordIndex ix; |
333 | ix.tab = J->base[0]; | 336 | ix.tab = J->base[0]; |
334 | if (tref_istab(ix.tab)) { | 337 | if (tref_istab(ix.tab)) { |
335 | if (!tvisnum(&rd->argv[1])) /* No support for string coercion. */ | 338 | if (!tvisnumber(&rd->argv[1])) /* No support for string coercion. */ |
336 | lj_trace_err(J, LJ_TRERR_BADTYPE); | 339 | lj_trace_err(J, LJ_TRERR_BADTYPE); |
337 | setnumV(&ix.keyv, numV(&rd->argv[1])+(lua_Number)1); | 340 | setintV(&ix.keyv, numberVint(&rd->argv[1])+1); |
338 | settabV(J->L, &ix.tabv, tabV(&rd->argv[0])); | 341 | settabV(J->L, &ix.tabv, tabV(&rd->argv[0])); |
339 | ix.val = 0; ix.idxchain = 0; | 342 | ix.val = 0; ix.idxchain = 0; |
340 | ix.key = lj_ir_toint(J, J->base[1]); | 343 | ix.key = lj_opt_narrow_toint(J, J->base[1]); |
341 | J->base[0] = ix.key = emitir(IRTI(IR_ADD), ix.key, lj_ir_kint(J, 1)); | 344 | J->base[0] = ix.key = emitir(IRTI(IR_ADD), ix.key, lj_ir_kint(J, 1)); |
342 | J->base[1] = lj_record_idx(J, &ix); | 345 | J->base[1] = lj_record_idx(J, &ix); |
343 | rd->nres = tref_isnil(J->base[1]) ? 0 : 2; | 346 | rd->nres = tref_isnil(J->base[1]) ? 0 : 2; |
@@ -525,26 +528,26 @@ static void LJ_FASTCALL recff_math_random(jit_State *J, RecordFFData *rd) | |||
525 | /* Record unary bit.tobit, bit.bnot, bit.bswap. */ | 528 | /* Record unary bit.tobit, bit.bnot, bit.bswap. */ |
526 | static void LJ_FASTCALL recff_bit_unary(jit_State *J, RecordFFData *rd) | 529 | static void LJ_FASTCALL recff_bit_unary(jit_State *J, RecordFFData *rd) |
527 | { | 530 | { |
528 | TRef tr = lj_ir_tobit(J, J->base[0]); | 531 | TRef tr = lj_opt_narrow_tobit(J, J->base[0]); |
529 | J->base[0] = (rd->data == IR_TOBIT) ? tr : emitir(IRTI(rd->data), tr, 0); | 532 | J->base[0] = (rd->data == IR_TOBIT) ? tr : emitir(IRTI(rd->data), tr, 0); |
530 | } | 533 | } |
531 | 534 | ||
532 | /* Record N-ary bit.band, bit.bor, bit.bxor. */ | 535 | /* Record N-ary bit.band, bit.bor, bit.bxor. */ |
533 | static void LJ_FASTCALL recff_bit_nary(jit_State *J, RecordFFData *rd) | 536 | static void LJ_FASTCALL recff_bit_nary(jit_State *J, RecordFFData *rd) |
534 | { | 537 | { |
535 | TRef tr = lj_ir_tobit(J, J->base[0]); | 538 | TRef tr = lj_opt_narrow_tobit(J, J->base[0]); |
536 | uint32_t op = rd->data; | 539 | uint32_t op = rd->data; |
537 | BCReg i; | 540 | BCReg i; |
538 | for (i = 1; J->base[i] != 0; i++) | 541 | for (i = 1; J->base[i] != 0; i++) |
539 | tr = emitir(IRTI(op), tr, lj_ir_tobit(J, J->base[i])); | 542 | tr = emitir(IRTI(op), tr, lj_opt_narrow_tobit(J, J->base[i])); |
540 | J->base[0] = tr; | 543 | J->base[0] = tr; |
541 | } | 544 | } |
542 | 545 | ||
543 | /* Record bit shifts. */ | 546 | /* Record bit shifts. */ |
544 | static void LJ_FASTCALL recff_bit_shift(jit_State *J, RecordFFData *rd) | 547 | static void LJ_FASTCALL recff_bit_shift(jit_State *J, RecordFFData *rd) |
545 | { | 548 | { |
546 | TRef tr = lj_ir_tobit(J, J->base[0]); | 549 | TRef tr = lj_opt_narrow_tobit(J, J->base[0]); |
547 | TRef tsh = lj_ir_tobit(J, J->base[1]); | 550 | TRef tsh = lj_opt_narrow_tobit(J, J->base[1]); |
548 | if (!(rd->data < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) && | 551 | if (!(rd->data < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) && |
549 | !tref_isk(tsh)) | 552 | !tref_isk(tsh)) |
550 | tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 31)); | 553 | tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 31)); |
@@ -570,25 +573,25 @@ static void LJ_FASTCALL recff_string_range(jit_State *J, RecordFFData *rd) | |||
570 | int32_t start, end; | 573 | int32_t start, end; |
571 | if (rd->data) { /* string.sub(str, start [,end]) */ | 574 | if (rd->data) { /* string.sub(str, start [,end]) */ |
572 | start = argv2int(J, &rd->argv[1]); | 575 | start = argv2int(J, &rd->argv[1]); |
573 | trstart = lj_ir_toint(J, J->base[1]); | 576 | trstart = lj_opt_narrow_toint(J, J->base[1]); |
574 | trend = J->base[2]; | 577 | trend = J->base[2]; |
575 | if (tref_isnil(trend)) { | 578 | if (tref_isnil(trend)) { |
576 | trend = lj_ir_kint(J, -1); | 579 | trend = lj_ir_kint(J, -1); |
577 | end = -1; | 580 | end = -1; |
578 | } else { | 581 | } else { |
579 | trend = lj_ir_toint(J, trend); | 582 | trend = lj_opt_narrow_toint(J, trend); |
580 | end = argv2int(J, &rd->argv[2]); | 583 | end = argv2int(J, &rd->argv[2]); |
581 | } | 584 | } |
582 | } else { /* string.byte(str, [,start [,end]]) */ | 585 | } else { /* string.byte(str, [,start [,end]]) */ |
583 | if (J->base[1]) { | 586 | if (J->base[1]) { |
584 | start = argv2int(J, &rd->argv[1]); | 587 | start = argv2int(J, &rd->argv[1]); |
585 | trstart = lj_ir_toint(J, J->base[1]); | 588 | trstart = lj_opt_narrow_toint(J, J->base[1]); |
586 | trend = J->base[2]; | 589 | trend = J->base[2]; |
587 | if (tref_isnil(trend)) { | 590 | if (tref_isnil(trend)) { |
588 | trend = trstart; | 591 | trend = trstart; |
589 | end = start; | 592 | end = start; |
590 | } else { | 593 | } else { |
591 | trend = lj_ir_toint(J, trend); | 594 | trend = lj_opt_narrow_toint(J, trend); |
592 | end = argv2int(J, &rd->argv[2]); | 595 | end = argv2int(J, &rd->argv[2]); |
593 | } | 596 | } |
594 | } else { | 597 | } else { |