summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/codegen.c17
-rw-r--r--src/load.c30
-rw-r--r--src/state.c19
-rw-r--r--src/string.c4
-rw-r--r--src/symbol.c2
5 files changed, 45 insertions, 27 deletions
diff --git a/src/codegen.c b/src/codegen.c
index 074d431c1..fc83244f2 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -657,14 +657,17 @@ lambda_body(codegen_scope *s, node *tree, int blk)
}
static int
-scope_body(codegen_scope *s, node *tree)
+scope_body(codegen_scope *s, node *tree, int val)
{
codegen_scope *scope = scope_new(s->mrb, s, tree->car);
- codegen(scope, tree->cdr, VAL);
+ codegen(scope, tree->cdr, val);
if (!s->iseq) {
genop(scope, MKOP_A(OP_STOP, 0));
}
+ else if (!val) {
+ genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
+ }
else {
if (scope->nregs == 0) {
genop(scope, MKOP_A(OP_LOADNIL, 0));
@@ -1235,7 +1238,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_Bx(OP_EPUSH, 0));
s->ensure_level++;
codegen(s, tree->car, val);
- idx = scope_body(s, tree->cdr);
+ idx = scope_body(s, tree->cdr, NOVAL);
s->iseq[epush] = MKOP_Bx(OP_EPUSH, idx);
s->ensure_level--;
genop_peep(s, MKOP_A(OP_EPOP, 1), NOVAL);
@@ -1423,7 +1426,7 @@ codegen(codegen_scope *s, node *tree, int val)
break;
case NODE_SCOPE:
- scope_body(s, tree);
+ scope_body(s, tree, NOVAL);
break;
case NODE_FCALL:
@@ -2283,7 +2286,7 @@ codegen(codegen_scope *s, node *tree, int val)
pop(); pop();
idx = new_msym(s, sym(tree->car->cdr));
genop(s, MKOP_AB(OP_CLASS, cursp(), idx));
- idx = scope_body(s, tree->cdr->cdr->car);
+ idx = scope_body(s, tree->cdr->cdr->car, val);
genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
if (val) {
push();
@@ -2309,7 +2312,7 @@ codegen(codegen_scope *s, node *tree, int val)
pop();
idx = new_msym(s, sym(tree->car->cdr));
genop(s, MKOP_AB(OP_MODULE, cursp(), idx));
- idx = scope_body(s, tree->cdr->car);
+ idx = scope_body(s, tree->cdr->car, val);
genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
if (val) {
push();
@@ -2324,7 +2327,7 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, tree->car, VAL);
pop();
genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp()));
- idx = scope_body(s, tree->cdr->car);
+ idx = scope_body(s, tree->cdr->car, val);
genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
if (val) {
push();
diff --git a/src/load.c b/src/load.c
index dd7da725c..247fce687 100644
--- a/src/load.c
+++ b/src/load.c
@@ -38,7 +38,7 @@ offset_crc_body(void)
}
static mrb_irep*
-read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len)
+read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool alloc)
{
size_t i;
const uint8_t *src = bin;
@@ -98,7 +98,12 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len)
tt = *src++; //pool TT
pool_data_len = bin_to_uint16(src); //pool data length
src += sizeof(uint16_t);
- s = mrb_str_new(mrb, (char *)src, pool_data_len);
+ if (alloc) {
+ s = mrb_str_new(mrb, (char *)src, pool_data_len);
+ }
+ else {
+ s = mrb_str_new_static(mrb, (char *)src, pool_data_len);
+ }
src += pool_data_len;
switch (tt) { //pool data
case IREP_TT_FIXNUM:
@@ -144,7 +149,12 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len)
continue;
}
- irep->syms[i] = mrb_intern(mrb, (char *)src, snl);
+ if (alloc) {
+ irep->syms[i] = mrb_intern(mrb, (char *)src, snl);
+ }
+ else {
+ irep->syms[i] = mrb_intern_static(mrb, (char *)src, snl);
+ }
src += snl + 1;
mrb_gc_arena_restore(mrb, ai);
@@ -158,16 +168,16 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len)
}
static mrb_irep*
-read_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len)
+read_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len, mrb_bool alloc)
{
- mrb_irep *irep = read_irep_record_1(mrb, bin, len);
+ mrb_irep *irep = read_irep_record_1(mrb, bin, len, alloc);
size_t i;
bin += *len;
for (i=0; i<irep->rlen; i++) {
uint32_t rlen;
- irep->reps[i] = read_irep_record(mrb, bin, &rlen);
+ irep->reps[i] = read_irep_record(mrb, bin, &rlen, alloc);
bin += rlen;
*len += rlen;
}
@@ -175,12 +185,12 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len)
}
static mrb_irep*
-read_section_irep(mrb_state *mrb, const uint8_t *bin)
+read_section_irep(mrb_state *mrb, const uint8_t *bin, mrb_bool alloc)
{
uint32_t len;
bin += sizeof(struct rite_section_irep_header);
- return read_irep_record(mrb, bin, &len);
+ return read_irep_record(mrb, bin, &len, alloc);
}
static int
@@ -430,7 +440,7 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
do {
section_header = (const struct rite_section_header *)bin;
if (memcmp(section_header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
- irep = read_section_irep(mrb, bin);
+ irep = read_section_irep(mrb, bin, FALSE);
if (!irep) return NULL;
}
else if (memcmp(section_header->section_identify, RITE_SECTION_LINENO_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
@@ -561,7 +571,7 @@ read_irep_record_file(mrb_state *mrb, FILE *fp)
if (fread(&buf[record_header_size], buf_size - record_header_size, 1, fp) == 0) {
return NULL;
}
- irep = read_irep_record_1(mrb, buf, &len);
+ irep = read_irep_record_1(mrb, buf, &len, TRUE);
mrb_free(mrb, ptr);
if (!irep) return NULL;
for (i=0; i<irep->rlen; i++) {
diff --git a/src/state.c b/src/state.c
index ab6070b7a..813b89aa7 100644
--- a/src/state.c
+++ b/src/state.c
@@ -136,7 +136,9 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
mrb_free(mrb, irep->iseq);
for (i=0; i<irep->plen; i++) {
if (mrb_type(irep->pool[i]) == MRB_TT_STRING) {
- mrb_free(mrb, mrb_str_ptr(irep->pool[i])->ptr);
+ if (mrb_str_ptr(irep->pool[i])->flags & MRB_STR_NOFREE == 0) {
+ mrb_free(mrb, mrb_str_ptr(irep->pool[i])->ptr);
+ }
mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
}
#ifdef MRB_WORD_BOXING
@@ -170,12 +172,17 @@ mrb_str_pool(mrb_state *mrb, mrb_value str)
len = s->len;
ns->len = len;
- ns->ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
- if (s->ptr) {
- memcpy(ns->ptr, s->ptr, len);
+ if (s->flags & MRB_STR_NOFREE) {
+ ns->ptr = s->ptr;
+ ns->flags = MRB_STR_NOFREE;
+ }
+ else {
+ ns->ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
+ if (s->ptr) {
+ memcpy(ns->ptr, s->ptr, len);
+ }
+ ns->ptr[len] = '\0';
}
- ns->ptr[len] = '\0';
-
return mrb_obj_value(ns);
}
diff --git a/src/string.c b/src/string.c
index e11458c7b..1c577188e 100644
--- a/src/string.c
+++ b/src/string.c
@@ -30,9 +30,6 @@ typedef struct mrb_shared_string {
mrb_int len;
} mrb_shared_string;
-#define MRB_STR_SHARED 1
-#define MRB_STR_NOFREE 2
-
static mrb_value str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2);
static mrb_value mrb_str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
@@ -92,6 +89,7 @@ mrb_str_modify(mrb_state *mrb, struct RString *s)
}
s->ptr[s->len] = '\0';
s->aux.capa = s->len;
+ s->flags &= ~MRB_STR_NOFREE;
return;
}
}
diff --git a/src/symbol.c b/src/symbol.c
index 5ced22461..4e78ade66 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -77,7 +77,7 @@ mrb_intern(mrb_state *mrb, const char *name, size_t len)
}
mrb_sym
-mrb_intern_literal(mrb_state *mrb, const char *name, size_t len)
+mrb_intern_static(mrb_state *mrb, const char *name, size_t len)
{
return sym_intern(mrb, name, len, 1);
}