summaryrefslogtreecommitdiffhomepage
path: root/src/dump.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2020-06-09 14:39:38 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2020-10-12 16:21:08 +0900
commitd428fa0c4acfe4f70ab534d420052c193bd83281 (patch)
tree903e5ab41d1c358e3b512be90d36837e54580e29 /src/dump.c
parentdaa37be5495393ce3e4654e00e44099f627e6cd4 (diff)
downloadmruby-d428fa0c4acfe4f70ab534d420052c193bd83281.tar.gz
mruby-d428fa0c4acfe4f70ab534d420052c193bd83281.zip
Replace entire `irep->pool`.
Changes: - `pool format is completely replaced - supported types: `STR`, `INT32`, `INT64`, `FLOAT` - `FLOAT` may be replaced by binary representation in the future - insert `NUL` after string literals in `mrb` files - `irep->pool` no longer store values in `mrb_value` - instead it stores in `mrb_pool_value` - less allocation - `mrb_irep` can be stored in ROM
Diffstat (limited to 'src/dump.c')
-rw-r--r--src/dump.c123
1 files changed, 71 insertions, 52 deletions
diff --git a/src/dump.c b/src/dump.c
index 093e4c256..a1c539e50 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -90,14 +90,12 @@ write_iseq_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf, uint8_t fla
#ifndef MRB_WITHOUT_FLOAT
static mrb_value
-float_to_str(mrb_state *mrb, mrb_value flt)
+float_to_str(mrb_state *mrb, mrb_float f)
{
- mrb_float f = mrb_float(flt);
-
if (isinf(f)) {
return f < 0 ? mrb_str_new_lit(mrb, "I") : mrb_str_new_lit(mrb, "i");
}
- return mrb_float_to_str(mrb, flt, MRB_FLOAT_FMT);
+ return mrb_float_to_str(mrb, mrb_float_value(mrb, f), MRB_FLOAT_FMT);
}
#endif
@@ -106,45 +104,50 @@ get_pool_block_size(mrb_state *mrb, const mrb_irep *irep)
{
int pool_no;
size_t size = 0;
- mrb_value str;
- size += sizeof(uint32_t); /* plen */
- size += irep->plen * (sizeof(uint8_t) + sizeof(uint16_t)); /* len(n) */
+ size += sizeof(uint16_t); /* plen */
+ size += irep->plen * sizeof(uint8_t); /* len(n) */
for (pool_no = 0; pool_no < irep->plen; pool_no++) {
int ai = mrb_gc_arena_save(mrb);
- switch (mrb_type(irep->pool[pool_no])) {
- case MRB_TT_FIXNUM:
- str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10);
+ switch (irep->pool[pool_no].tt) {
+ case IREP_TT_INT64:
+#ifdef MRB_INT64
{
- mrb_int len = RSTRING_LEN(str);
- mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
- size += (size_t)len;
+ int64_t i = irep->pool[pool_no].u.i64;
+
+ if (i < INT32_MIN || INT32_MAX < i)
+ size += 8;
+ else
+ size += 4;
}
break;
+#else
+ /* fall through */
+#endif
+ case IREP_TT_INT32:
+ size += 4; /* 32bits = 4bytes */
+ break;
+ case IREP_TT_FLOAT:
#ifndef MRB_WITHOUT_FLOAT
- case MRB_TT_FLOAT:
- str = float_to_str(mrb, irep->pool[pool_no]);
{
+ mrb_value str = float_to_str(mrb, irep->pool[pool_no].u.f);
mrb_int len = RSTRING_LEN(str);
mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
size += (size_t)len;
}
- break;
#endif
+ break;
- case MRB_TT_STRING:
+ default: /* packed IREP_TT_STRING */
{
- mrb_int len = RSTRING_LEN(irep->pool[pool_no]);
+ mrb_int len = irep->pool[pool_no].tt >> 1; /* unpack length */
mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
- size += (size_t)len;
+ size += (size_t)len+1;
}
break;
-
- default:
- break;
}
mrb_gc_arena_restore(mrb, ai);
}
@@ -157,48 +160,64 @@ write_pool_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf)
{
int pool_no;
uint8_t *cur = buf;
- uint16_t len;
- mrb_value str;
- const char *char_ptr;
+ int len;
+ const char *ptr;
- cur += uint32_to_bin(irep->plen, cur); /* number of pool */
+ cur += uint16_to_bin(irep->plen, cur); /* number of pool */
for (pool_no = 0; pool_no < irep->plen; pool_no++) {
int ai = mrb_gc_arena_save(mrb);
- switch (mrb_type(irep->pool[pool_no])) {
- case MRB_TT_FIXNUM:
- cur += uint8_to_bin(IREP_TT_FIXNUM, cur); /* data type */
- str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10);
+ switch (irep->pool[pool_no].tt) {
+#ifdef MRB_INT64
+ case IREP_TT_INT64:
+ {
+ int64_t i = irep->pool[pool_no].u.i64;
+ if (i < INT32_MIN || INT32_MAX < i) {
+ cur += uint8_to_bin(IREP_TT_INT64, cur); /* data type */
+ cur += uint32_to_bin((uint32_t)((i>>32) & 0xffffffff), cur); /* i64 hi */
+ cur += uint32_to_bin((uint32_t)((i ) & 0xffffffff), cur); /* i64 lo */
+ }
+ else {
+ cur += uint8_to_bin(IREP_TT_INT32, cur); /* data type */
+ cur += uint32_to_bin(irep->pool[pool_no].u.i32, cur); /* i32 */
+ }
+ }
+ break;
+#endif
+ case IREP_TT_INT32:
+ cur += uint8_to_bin(IREP_TT_INT32, cur); /* data type */
+ cur += uint32_to_bin(irep->pool[pool_no].u.i32, cur); /* i32 */
break;
-#ifndef MRB_WITHOUT_FLOAT
- case MRB_TT_FLOAT:
+ case IREP_TT_FLOAT:
cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */
- str = float_to_str(mrb, irep->pool[pool_no]);
- break;
+#ifndef MRB_WITHOUT_FLOAT
+ {
+ mrb_value str = float_to_str(mrb, irep->pool[pool_no].u.f);
+ ptr = RSTRING_PTR(str);
+ len = RSTRING_LEN(str);
+ mrb_assert_int_fit(mrb_int, len, uint16_t, UINT16_MAX);
+ cur += uint16_to_bin((uint16_t)len, cur); /* data length */
+ memcpy(cur, ptr, (size_t)len);
+ cur += len;
+ }
+#else
+ cur += uint16_to_bin(0, cur); /* zero length */
#endif
-
- case MRB_TT_STRING:
- cur += uint8_to_bin(IREP_TT_STRING, cur); /* data type */
- str = irep->pool[pool_no];
break;
- default:
- continue;
- }
-
- char_ptr = RSTRING_PTR(str);
- {
- mrb_int tlen = RSTRING_LEN(str);
- mrb_assert_int_fit(mrb_int, tlen, uint16_t, UINT16_MAX);
- len = (uint16_t)tlen;
+ default: /* string */
+ cur += uint8_to_bin(IREP_TT_STR, cur); /* data type */
+ ptr = irep->pool[pool_no].u.str;
+ len = irep->pool[pool_no].tt>>2;
+ mrb_assert_int_fit(mrb_int, len, uint16_t, UINT16_MAX);
+ cur += uint16_to_bin((uint16_t)len, cur); /* data length */
+ memcpy(cur, ptr, (size_t)len);
+ cur += len;
+ *cur++ = '\0';
+ break;
}
-
- cur += uint16_to_bin(len, cur); /* data length */
- memcpy(cur, char_ptr, (size_t)len);
- cur += len;
-
mrb_gc_arena_restore(mrb, ai);
}