diff options
| -rw-r--r-- | include/mruby.h | 4 | ||||
| -rw-r--r-- | include/mruby/string.h | 3 | ||||
| -rw-r--r-- | src/codegen.c | 17 | ||||
| -rw-r--r-- | src/load.c | 30 | ||||
| -rw-r--r-- | src/state.c | 19 | ||||
| -rw-r--r-- | src/string.c | 4 | ||||
| -rw-r--r-- | src/symbol.c | 2 |
7 files changed, 50 insertions, 29 deletions
diff --git a/include/mruby.h b/include/mruby.h index bc71c84d7..e92550213 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -230,8 +230,8 @@ mrb_value mrb_funcall_argv(mrb_state*, mrb_value, mrb_sym, int, mrb_value*); mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, mrb_sym, int, mrb_value*, mrb_value); mrb_sym mrb_intern_cstr(mrb_state*,const char*); mrb_sym mrb_intern(mrb_state*,const char*,size_t); -mrb_sym mrb_intern_literal(mrb_state*,const char*,size_t); -#define mrb_intern_lit(mrb, lit) mrb_intern_literal(mrb, (lit), sizeof(lit) - 1) +mrb_sym mrb_intern_static(mrb_state*,const char*,size_t); +#define mrb_intern_lit(mrb, lit) mrb_intern_static(mrb, (lit), sizeof(lit) - 1) mrb_sym mrb_intern_str(mrb_state*,mrb_value); mrb_value mrb_check_intern_cstr(mrb_state*,const char*); mrb_value mrb_check_intern(mrb_state*,const char*,size_t); diff --git a/include/mruby/string.h b/include/mruby/string.h index 594965134..c6d2e0e70 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -32,6 +32,9 @@ struct RString { #define RSTRING_CAPA(s) (RSTRING(s)->aux.capa) #define RSTRING_END(s) (RSTRING(s)->ptr + RSTRING(s)->len) +#define MRB_STR_SHARED 1 +#define MRB_STR_NOFREE 2 + void mrb_gc_free_str(mrb_state*, struct RString*); void mrb_str_modify(mrb_state*, struct RString*); mrb_value mrb_str_literal(mrb_state*, mrb_value); 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); } |
