From 4ae5ae353564291cdb28108c26382c32242966a8 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 12 Mar 2021 16:21:32 +0900 Subject: codegen.c: no integer overflow error in `codegen`; close #5376 Add new pool value type `IREP_TT_BIGINT` and generate integer overflow error in the VM. In the future, `mruby` will support `Bignum` for integers bigger than `mrb_int` (probably using `mpz`). --- src/codedump.c | 2 +- src/dump.c | 29 ++++++++++++++++++++++++++++- src/load.c | 13 +++++++++++++ src/state.c | 3 ++- src/vm.c | 2 ++ 5 files changed, 46 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/codedump.c b/src/codedump.c index f382bb7eb..3a5f0eadb 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -6,7 +6,7 @@ #include #include -#ifndef MRB_NO_STDIO +#ifndef MRB_NOP_STDIO static void print_r(mrb_state *mrb, const mrb_irep *irep, size_t n) { diff --git a/src/dump.c b/src/dump.c index 51e8dca4e..0822b2fac 100644 --- a/src/dump.c +++ b/src/dump.c @@ -129,6 +129,15 @@ get_pool_block_size(mrb_state *mrb, const mrb_irep *irep) size += 4; /* 32bits = 4bytes */ break; + case IREP_TT_BIGINT: + { + mrb_int len = irep->pool[pool_no].u.str[0]; + mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); + size += sizeof(uint8_t); + size += (size_t)len+2; + } + break; + case IREP_TT_FLOAT: #ifndef MRB_NO_FLOAT { @@ -187,6 +196,14 @@ write_pool_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf) cur += uint32_to_bin(irep->pool[pool_no].u.i32, cur); /* i32 */ break; + case IREP_TT_BIGINT: + cur += uint8_to_bin(IREP_TT_BIGINT, cur); /* data type */ + len = irep->pool[pool_no].u.str[0]; + memcpy(cur, irep->pool[pool_no].u.str, (size_t)len+2); + cur += len+2; + *cur++ = '\0'; + break; + case IREP_TT_FLOAT: cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */ #ifndef MRB_NO_FLOAT @@ -216,7 +233,6 @@ write_pool_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf) return cur - buf; } - static size_t get_syms_block_size(mrb_state *mrb, const mrb_irep *irep) { @@ -941,6 +957,17 @@ dump_pool(mrb_state *mrb, const mrb_pool_value *p, FILE *fp) } #endif break; + case IREP_TT_BIGINT: + { + const char *s = p->u.str; + int len = s[0]+2; + fputs("{IREP_TT_BIGINT, {\"", fp); + for (int i=0; iiseq); if (irep->pool) { for (i=0; iplen; i++) { - if ((irep->pool[i].tt & 3) == IREP_TT_STR) { + if ((irep->pool[i].tt & 3) == IREP_TT_STR || + irep->pool[i].tt == IREP_TT_BIGINT) { mrb_free(mrb, (void*)irep->pool[i].u.str); } } diff --git a/src/vm.c b/src/vm.c index 2607ba308..1009fb638 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1143,6 +1143,8 @@ RETRY_TRY_BLOCK: #endif goto L_INT_OVERFLOW; #endif + case IREP_TT_BIGINT: + goto L_INT_OVERFLOW; #ifndef MRB_NO_FLOAT case IREP_TT_FLOAT: regs[a] = mrb_float_value(mrb, pool[b].u.f); -- cgit v1.2.3