mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
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:
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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++) {
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user