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
This commit is contained in:
Yukihiro "Matz" Matsumoto
2020-06-09 14:39:38 +09:00
parent daa37be549
commit d428fa0c4a
14 changed files with 258 additions and 217 deletions
-2
View File
@@ -51,8 +51,6 @@ typedef struct mrb_value {
};
} mrb_value;
#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
#define mrb_tt(o) ((enum mrb_vtype)(((o).value.ttt & 0xfc000)>>14)-1)
#define mrb_type(o) (enum mrb_vtype)((uint32_t)0xfff00000 < (o).value.ttt ? mrb_tt(o) : MRB_TT_FLOAT)
#define mrb_ptr(o) ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)((o).value.p)))<<2))
-4
View File
@@ -24,10 +24,6 @@ typedef struct mrb_value {
enum mrb_vtype tt;
} mrb_value;
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
#endif
#define mrb_ptr(o) (o).value.p
#define mrb_cptr(o) mrb_ptr(o)
#ifndef MRB_WITHOUT_FLOAT
-5
View File
@@ -90,11 +90,6 @@ typedef union mrb_value {
MRB_API mrb_value mrb_word_boxing_cptr_value(struct mrb_state*, void*);
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_value mrb_word_boxing_float_value(struct mrb_state*, mrb_float);
MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
#endif
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float_pool(mrb,f) mrb_word_boxing_float_pool(mrb,f)
#endif
#define mrb_ptr(o) (o).value.p
-19
View File
@@ -127,16 +127,6 @@ uint32_to_bin(uint32_t l, uint8_t *bin)
return sizeof(uint32_t);
}
static inline size_t
uint32l_to_bin(uint32_t l, uint8_t *bin)
{
bin[3] = (l >> 24) & 0xff;
bin[2] = (l >> 16) & 0xff;
bin[1] = (l >> 8) & 0xff;
bin[0] = l & 0xff;
return sizeof(uint32_t);
}
static inline uint32_t
bin_to_uint32(const uint8_t *bin)
{
@@ -146,15 +136,6 @@ bin_to_uint32(const uint8_t *bin)
(uint32_t)bin[3];
}
static inline uint32_t
bin_to_uint32l(const uint8_t *bin)
{
return (uint32_t)bin[3] << 24 |
(uint32_t)bin[2] << 16 |
(uint32_t)bin[1] << 8 |
(uint32_t)bin[0];
}
static inline uint16_t
bin_to_uint16(const uint8_t *bin)
{
+22 -4
View File
@@ -16,11 +16,29 @@
MRB_BEGIN_DECL
enum irep_pool_type {
IREP_TT_STRING,
IREP_TT_FIXNUM,
IREP_TT_FLOAT,
IREP_TT_STR = 0, /* string (need free) */
IREP_TT_SSTR = 2, /* string (static) */
IREP_TT_INT32 = 1, /* 32bit integer */
IREP_TT_INT64 = 3, /* 64bit integer */
IREP_TT_FLOAT = 5, /* float (double/float) */
};
#define IREP_TT_NFLAG 1 /* number (non string) flag */
#define IREP_TT_SFLAG 2 /* static string flag */
#define IREP_TT_SFLAG 2 /* static string flag */
typedef struct mrb_pool_value {
uint32_t tt; /* packed type and length (for string) */
union {
const char *str;
int32_t i32;
#ifdef MRB_INT64
int64_t i64;
#endif
mrb_float f;
} u;
} mrb_pool_value;
struct mrb_lvinfo { /* local variable info (name, idx) */
mrb_sym name;
uint16_t r;
@@ -33,7 +51,7 @@ typedef struct mrb_irep {
uint8_t flags;
const mrb_code *iseq;
const mrb_value *pool;
const mrb_pool_value *pool;
const mrb_sym *syms;
const struct mrb_irep **reps;
+2 -8
View File
@@ -92,9 +92,6 @@ struct RStringEmbed {
# define RSTR_COPY_ASCII_FLAG(dst, src) (void)0
#endif
#define RSTR_POOL_P(s) ((s)->flags & MRB_STR_POOL)
#define RSTR_SET_POOL_FLAG(s) ((s)->flags |= MRB_STR_POOL)
/**
* Returns a pointer from a Ruby string
*/
@@ -112,13 +109,11 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*);
#define MRB_STR_FSHARED 2
#define MRB_STR_NOFREE 4
#define MRB_STR_EMBED 8 /* type flags up to here */
#define MRB_STR_POOL 16 /* status flags from here */
#define MRB_STR_ASCII 32
#define MRB_STR_ASCII 16
#define MRB_STR_EMBED_LEN_SHIFT 6
#define MRB_STR_EMBED_LEN_BIT 5
#define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BIT) - 1) << MRB_STR_EMBED_LEN_SHIFT)
#define MRB_STR_TYPE_MASK (MRB_STR_POOL - 1)
#define MRB_STR_TYPE_MASK 15
void mrb_gc_free_str(mrb_state*, struct RString*);
@@ -447,7 +442,6 @@ MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
*/
MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_pool(mrb_state *mrb, const char *s, mrb_int len, mrb_bool nofree);
uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
+44 -18
View File
@@ -70,7 +70,7 @@ typedef struct scope {
uint32_t icapa;
mrb_irep *irep;
mrb_value *pool;
mrb_pool_value *pool;
mrb_sym *syms;
mrb_irep **reps;
uint32_t pcapa, scapa, rcapa;
@@ -554,17 +554,17 @@ static inline int
new_lit(codegen_scope *s, mrb_value val)
{
int i;
mrb_value *pv;
mrb_pool_value *pv;
switch (mrb_type(val)) {
case MRB_TT_STRING:
for (i=0; i<s->irep->plen; i++) {
mrb_int len;
pv = &s->pool[i];
if (!mrb_string_p(*pv)) continue;
if ((len = RSTRING_LEN(*pv)) != RSTRING_LEN(val)) continue;
if (memcmp(RSTRING_PTR(*pv), RSTRING_PTR(val), len) == 0)
if (pv->tt & IREP_TT_NFLAG) continue;
len = pv->tt>>2;
if (RSTRING_LEN(val) != len) continue;
if (memcmp(pv->u.str, RSTRING_PTR(val), len) == 0)
return i;
}
break;
@@ -573,8 +573,9 @@ new_lit(codegen_scope *s, mrb_value val)
for (i=0; i<s->irep->plen; i++) {
mrb_float f1, f2;
pv = &s->pool[i];
if (!mrb_float_p(*pv)) continue;
f1 = mrb_float(*pv);
if (pv->tt != IREP_TT_FLOAT) continue;
pv = &s->pool[i];
f1 = pv->u.f;
f2 = mrb_float(val);
if (f1 == f2 && !signbit(f1) == !signbit(f2)) return i;
}
@@ -582,9 +583,17 @@ new_lit(codegen_scope *s, mrb_value val)
#endif
case MRB_TT_FIXNUM:
for (i=0; i<s->irep->plen; i++) {
mrb_int v = mrb_fixnum(val);
pv = &s->pool[i];
if (!mrb_fixnum_p(*pv)) continue;
if (mrb_fixnum(*pv) == mrb_fixnum(val)) return i;
if (pv->tt == IREP_TT_INT32) {
if (v == pv->u.i32) return i;
}
#ifdef MRB_INT64
else if (pv->tt == IREP_TT_INT64) {
if (v == pv->u.i64) return i;
}
continue;
#endif
}
break;
default:
@@ -594,7 +603,7 @@ new_lit(codegen_scope *s, mrb_value val)
if (s->irep->plen == s->pcapa) {
s->pcapa *= 2;
s->pool = (mrb_value *)codegen_realloc(s, s->pool, sizeof(mrb_value)*s->pcapa);
s->pool = (mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*s->pcapa);
}
pv = &s->pool[s->irep->plen];
@@ -602,18 +611,35 @@ new_lit(codegen_scope *s, mrb_value val)
switch (mrb_type(val)) {
case MRB_TT_STRING:
*pv = mrb_str_pool(s->mrb, RSTRING_PTR(val), RSTRING_LEN(val), RSTR_NOFREE_P(RSTRING(val)));
if (RSTR_NOFREE_P(RSTRING(val))) {
pv->tt = (RSTRING_LEN(val)<<2) | IREP_TT_SSTR;
pv->u.str = RSTRING_PTR(val);
}
else {
char *p;
mrb_int len = RSTRING_LEN(val);
pv->tt = (len<<2) | IREP_TT_STR;
p = (char*)codegen_realloc(s, NULL, len+1);
memcpy(p, RSTRING_PTR(val), len);
p[len] = '\0';
pv->u.str = p;
}
break;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT:
#ifdef MRB_WORD_BOXING
*pv = mrb_float_pool(s->mrb, mrb_float(val));
pv->tt = IREP_TT_FLOAT;
pv->u.f = mrb_float(val);
break;
#endif
#endif
case MRB_TT_FIXNUM:
*pv = val;
#ifdef MRB_INT64
pv->tt = IREP_TT_INT64;
pv->u.i64 = mrb_fixnum(val);
#else
pv->tt = IREP_TT_INT32;
pv->u.i32 = mrb_fixnum(val);
#endif
break;
default:
@@ -3045,7 +3071,7 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *nlv)
s->irep->iseq = NULL;
s->pcapa = 32;
s->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value)*s->pcapa);
s->pool = (mrb_pool_value*)mrb_malloc(mrb, sizeof(mrb_pool_value)*s->pcapa);
s->irep->plen = 0;
s->scapa = 256;
@@ -3110,7 +3136,7 @@ scope_finish(codegen_scope *s)
irep->iseq = (const mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc);
irep->ilen = s->pc;
}
irep->pool = (const mrb_value*)codegen_realloc(s, s->pool, sizeof(mrb_value)*irep->plen);
irep->pool = (const mrb_pool_value*)codegen_realloc(s, s->pool, sizeof(mrb_pool_value)*irep->plen);
irep->syms = (const mrb_sym*)codegen_realloc(s, s->syms, sizeof(mrb_sym)*irep->slen);
irep->reps = (const mrb_irep**)codegen_realloc(s, s->reps, sizeof(mrb_irep*)*irep->rlen);
if (s->filename_sym) {
+25 -12
View File
@@ -115,10 +115,21 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
print_lv_ab(mrb, irep, a, b);
break;
CASE(OP_LOADL, BB):
{
mrb_value v = irep->pool[b];
mrb_value s = mrb_inspect(mrb, v);
printf("OP_LOADL\tR%d\tL(%d)\t; %s", a, b, RSTRING_PTR(s));
switch (irep->pool[b].tt) {
case IREP_TT_FLOAT:
printf("OP_LOADL\tR%d\tL(%d)\t; %f", a, b, (double)irep->pool[b].u.f);
break;
case IREP_TT_INT32:
printf("OP_LOADL\tR%d\tL(%d)\t; %" PRId32, a, b, irep->pool[b].u.i32);
break;
#ifdef MRB_INT64
case IREP_TT_INT64:
printf("OP_LOADL\tR%d\tL(%d)\t; %" PRId64, a, b, irep->pool[b].u.i64);
break;
#endif
default:
printf("OP_LOADL\tR%d\tL(%d)\t", a, b);
break;
}
print_lv_a(mrb, irep, a);
break;
@@ -404,10 +415,11 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
print_lv_a(mrb, irep, a);
break;
CASE(OP_STRING, BB):
{
mrb_value v = irep->pool[b];
mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v)));
printf("OP_STRING\tR%d\tL(%d)\t; %s", a, b, RSTRING_PTR(s));
if ((irep->pool[b].tt & IREP_TT_NFLAG) == 0) {
printf("OP_STRING\tR%d\tL(%d)\t; %s", a, b, irep->pool[b].u.str);
}
else {
printf("OP_STRING\tR%d\tL(%d)\t", a, b);
}
print_lv_a(mrb, irep, a);
break;
@@ -453,10 +465,11 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
print_lv_a(mrb, irep, a);
break;
CASE(OP_ERR, B):
{
mrb_value v = irep->pool[a];
mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v)));
printf("OP_ERR\t%s\n", RSTRING_PTR(s));
if ((irep->pool[a].tt & IREP_TT_NFLAG) == 0) {
printf("OP_ERR\t%s\n", irep->pool[a].u.str);
}
else {
printf("OP_ERR\tL(%d)\n", a);
}
break;
CASE(OP_EPUSH, B):
+76 -57
View File
@@ -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,44 +104,49 @@ 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;
}
break;
int64_t i = irep->pool[pool_no].u.i64;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT:
str = float_to_str(mrb, irep->pool[pool_no]);
{
mrb_int len = RSTRING_LEN(str);
mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
size += (size_t)len;
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 MRB_TT_STRING:
case IREP_TT_FLOAT:
#ifndef MRB_WITHOUT_FLOAT
{
mrb_int len = RSTRING_LEN(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;
}
#endif
break;
default:
default: /* packed IREP_TT_STRING */
{
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+1;
}
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);
break;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT:
cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */
str = float_to_str(mrb, irep->pool[pool_no]);
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 MRB_TT_STRING:
cur += uint8_to_bin(IREP_TT_STRING, cur); /* data type */
str = irep->pool[pool_no];
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;
default:
continue;
case IREP_TT_FLOAT:
cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */
#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
break;
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;
}
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;
}
cur += uint16_to_bin(len, cur); /* data length */
memcpy(cur, char_ptr, (size_t)len);
cur += len;
mrb_gc_arena_restore(mrb, ai);
}
-11
View File
@@ -158,17 +158,6 @@ mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f)
MRB_SET_FROZEN_FLAG(v.value.bp);
return v;
}
MRB_API mrb_value
mrb_word_boxing_float_pool(mrb_state *mrb, mrb_float f)
{
struct RFloat *nf = (struct RFloat *)mrb_malloc(mrb, sizeof(struct RFloat));
nf->tt = MRB_TT_FLOAT;
nf->c = mrb->float_class;
nf->f = f;
MRB_SET_FROZEN_FLAG(nf);
return mrb_obj_value(nf);
}
#endif /* MRB_WITHOUT_FLOAT */
#endif /* MRB_WORD_BOXING */
+55 -26
View File
@@ -73,10 +73,10 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
uint16_t tt, pool_data_len, snl;
int plen;
struct RData *irep_obj = mrb_data_object_alloc(mrb, mrb->object_class, NULL, &tempirep_type);
mrb_value *pool;
mrb_pool_value *pool;
mrb_sym *syms;
mrb_int ai = mrb_gc_arena_save(mrb);
mrb_irep *irep = mrb_add_irep(mrb);
int ai = mrb_gc_arena_save(mrb);
irep_obj->data = irep;
@@ -120,51 +120,81 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
}
/* POOL BLOCK */
plen = bin_to_uint32(src); /* number of pool */
src += sizeof(uint32_t);
plen = bin_to_uint16(src); /* number of pool */
src += sizeof(uint16_t);
if (plen > 0) {
if (SIZE_ERROR_MUL(plen, sizeof(mrb_value))) {
return NULL;
}
irep->pool = pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * plen);
irep->pool = pool = (mrb_pool_value*)mrb_calloc(mrb, sizeof(mrb_pool_value), plen);
for (i = 0; i < plen; i++) {
const char *s;
mrb_bool st = (flags & FLAG_SRC_MALLOC)==0;
tt = *src++; /* pool TT */
pool_data_len = bin_to_uint16(src); /* pool data length */
src += sizeof(uint16_t);
s = (const char*)src;
src += pool_data_len;
switch (tt) { /* pool data */
case IREP_TT_FIXNUM: {
mrb_value num = mrb_str_len_to_inum(mrb, s, pool_data_len, 10, FALSE);
#ifdef MRB_WITHOUT_FLOAT
pool[i] = num;
case IREP_TT_INT32:
{
mrb_int v = (int32_t)bin_to_uint32(src);
src += sizeof(uint32_t);
#ifdef MRB_INT64
pool[i].tt = IREP_TT_INT64;
pool[i].u.i64 = (int64_t)v;
#else
pool[i] = mrb_float_p(num)? mrb_float_pool(mrb, mrb_float(num)) : num;
pool[i].tt = IREP_TT_INT32;
pool[i].u.i32 = v;
#endif
}
break;
#ifndef MRB_WITHOUT_FLOAT
case IREP_TT_FLOAT:
pool[i] = mrb_float_pool(mrb, str_to_double(mrb, s, pool_data_len));
case IREP_TT_INT64:
#ifdef MRB_INT64
{
uint64_t i = bin_to_uint32(src);
src += sizeof(uint32_t);
i <<= 32;
i |= bin_to_uint32(src);
src += sizeof(uint32_t);
pool[i].u.i64 = (int64_t)i;
}
#else
return NULL; /* INT64 not supported on MRB_INT32 */
#endif
break;
case IREP_TT_FLOAT:
#ifndef MRB_WITHOUT_FLOAT
pool[i].tt = tt;
pool_data_len = bin_to_uint16(src); /* pool data length */
src += sizeof(uint16_t);
pool[i].u.f = str_to_double(mrb, (const char*)src, pool_data_len);
src += pool_data_len;
break;
#else
return NULL; /* MRB_WITHOUT_FLOAT */
#endif
case IREP_TT_STRING:
pool[i] = mrb_str_pool(mrb, s, pool_data_len, st);
case IREP_TT_STR:
pool_data_len = bin_to_uint16(src); /* pool data length */
src += sizeof(uint16_t);
if (st) {
pool[i].tt = (pool_data_len<<2) | IREP_TT_SSTR;
pool[i].u.str = (const char*)src;
}
else {
char *p;
pool[i].tt = (pool_data_len<<2) | IREP_TT_STR;
p = (char*)mrb_malloc(mrb, pool_data_len+1);
memcpy(p, src, pool_data_len+1);
pool[i].u.str = (const char*)p;
}
src += pool_data_len + 1;
break;
default:
/* should not happen */
pool[i] = mrb_nil_value();
break;
return NULL;
}
irep->plen++;
mrb_gc_arena_restore(mrb, ai);
irep->plen = i+1;
}
}
@@ -193,7 +223,6 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
syms[i] = mrb_intern_static(mrb, (char *)src, snl);
}
src += snl + 1;
mrb_gc_arena_restore(mrb, ai);
}
}
+6 -10
View File
@@ -144,18 +144,14 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
if (irep->flags & MRB_IREP_NO_FREE) return;
if (!(irep->flags & MRB_ISEQ_NO_FREE))
mrb_free(mrb, (void*)irep->iseq);
if (irep->pool) for (i=0; i<irep->plen; i++) {
if (mrb_string_p(irep->pool[i])) {
mrb_gc_free_str(mrb, RSTRING(irep->pool[i]));
mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
if (irep->pool) {
for (i=0; i<irep->plen; i++) {
if ((irep->pool[i].tt & 3) == IREP_TT_STR) {
mrb_free(mrb, (void*)irep->pool[i].u.str);
}
}
#if defined(MRB_WORD_BOXING) && !defined(MRB_WITHOUT_FLOAT)
else if (mrb_float_p(irep->pool[i])) {
mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
}
#endif
mrb_free(mrb, (void*)irep->pool);
}
mrb_free(mrb, (void*)irep->pool);
mrb_free(mrb, (void*)irep->syms);
if (irep->reps) {
for (i=0; i<irep->rlen; i++) {
-26
View File
@@ -583,9 +583,6 @@ str_share(mrb_state *mrb, struct RString *orig, struct RString *s)
else if (RSTR_FSHARED_P(orig)) {
str_init_fshared(orig, s, orig->as.heap.aux.fshared);
}
else if (mrb_frozen_p(orig) && !RSTR_POOL_P(orig)) {
str_init_fshared(orig, s, orig);
}
else {
if (orig->as.heap.aux.capa > orig->as.heap.len) {
orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1);
@@ -596,29 +593,6 @@ str_share(mrb_state *mrb, struct RString *orig, struct RString *s)
}
}
mrb_value
mrb_str_pool(mrb_state *mrb, const char *p, mrb_int len, mrb_bool nofree)
{
struct RString *s = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
s->tt = MRB_TT_STRING;
s->c = mrb->string_class;
s->flags = 0;
if (RSTR_EMBEDDABLE_P(len)) {
str_init_embed(s, p, len);
}
else if (nofree) {
str_init_nofree(s, p, len);
}
else {
str_init_normal(mrb, s, p, len);
}
RSTR_SET_POOL_FLAG(s);
MRB_SET_FROZEN_FLAG(s);
return mrb_obj_value(s);
}
mrb_value
mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
{
+28 -15
View File
@@ -966,7 +966,7 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *pc)
/* mrb_assert(MRB_PROC_CFUNC_P(proc)) */
const mrb_code *pc0 = pc;
const mrb_irep *irep = proc->body.irep;
const mrb_value *pool = irep->pool;
const mrb_pool_value *pool = irep->pool;
const mrb_sym *syms = irep->syms;
mrb_code insn;
int ai = mrb_gc_arena_save(mrb);
@@ -1013,17 +1013,25 @@ RETRY_TRY_BLOCK:
}
CASE(OP_LOADL, BB) {
#ifdef MRB_WORD_BOXING
mrb_value val = pool[b];
switch (pool[b].tt) { /* number */
case IREP_TT_INT32:
regs[a] = mrb_fixnum_value((mrb_int)pool[b].u.i32);
break;
#ifdef MRB_INT64
case IREP_TT_INT64:
regs[a] = mrb_fixnum_value((mrb_int)pool[b].u.i64);
break;
#endif
#ifndef MRB_WITHOUT_FLOAT
if (mrb_float_p(val)) {
val = mrb_float_value(mrb, mrb_float(val));
case IREP_TT_FLOAT:
regs[a] = mrb_float_value(mrb, pool[b].u.f);
break;
#endif
default:
/* should not happen (tt:string) */
regs[a] = mrb_nil_value();
break;
}
#endif
regs[a] = val;
#else
regs[a] = pool[b];
#endif
NEXT;
}
@@ -2499,9 +2507,13 @@ RETRY_TRY_BLOCK:
}
CASE(OP_STRING, BB) {
mrb_value str = mrb_str_dup(mrb, pool[b]);
regs[a] = str;
size_t len = pool[b].tt >> 2;
if (pool[b].tt & IREP_TT_SFLAG) {
regs[a] = mrb_str_new_static(mrb, pool[b].u.str, len);
}
else {
regs[a] = mrb_str_new(mrb, pool[b].u.str, len);
}
mrb_gc_arena_restore(mrb, ai);
NEXT;
}
@@ -2703,10 +2715,11 @@ RETRY_TRY_BLOCK:
}
CASE(OP_ERR, B) {
mrb_value msg = mrb_str_dup(mrb, pool[a]);
size_t len = pool[a].tt >> 2;
mrb_value exc;
exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);
mrb_assert((pool[a].tt&IREP_TT_NFLAG)==0);
exc = mrb_exc_new(mrb, E_LOCALJUMP_ERROR, pool[a].u.str, len);
ERR_PC_SET(mrb);
mrb_exc_set(mrb, exc);
goto L_RAISE;