diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-12-05 15:28:58 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-12-05 15:28:58 +0900 |
| commit | 6e5a0f623fdc848339ce33091b7857c57ba238c7 (patch) | |
| tree | 1fe55f1557c8e5511dbe50aec939c1bc6e780baa /mrbgems/mruby-compiler/core/codegen.c | |
| parent | 63d82142a8d3915d977fd97fc2ee82b5951065ed (diff) | |
| download | mruby-6e5a0f623fdc848339ce33091b7857c57ba238c7.tar.gz mruby-6e5a0f623fdc848339ce33091b7857c57ba238c7.zip | |
Fixed a memory leak bug on `codegen_error()` when `irep->rlen>255`.
Diffstat (limited to 'mrbgems/mruby-compiler/core/codegen.c')
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index d2365f903..28a484133 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -115,25 +115,27 @@ codegen_error(codegen_scope *s, const char *message) if (!s) return; while (s->prev) { codegen_scope *tmp = s->prev; - mrb_free(s->mrb, s->iseq); - for (int i=0; i<s->irep->plen; i++) { - mrb_pool_value *pv = &s->pool[i]; - if ((pv->tt & 0x3) == IREP_TT_STR) { - mrb_free(s->mrb, (void*)pv->u.str); + if (s->irep) { + mrb_free(s->mrb, s->iseq); + for (int i=0; i<s->irep->plen; i++) { + mrb_pool_value *pv = &s->pool[i]; + if ((pv->tt & 0x3) == IREP_TT_STR) { + mrb_free(s->mrb, (void*)pv->u.str); + } } - } - mrb_free(s->mrb, s->pool); - mrb_free(s->mrb, s->syms); - mrb_free(s->mrb, s->catch_table); - if (s->reps) { - /* copied from mrb_irep_free() in state.c */ - for (i=0; i<s->irep->rlen; i++) { - if (s->reps[i]) - mrb_irep_decref(s->mrb, (mrb_irep*)s->reps[i]); + mrb_free(s->mrb, s->pool); + mrb_free(s->mrb, s->syms); + mrb_free(s->mrb, s->catch_table); + if (s->reps) { + /* copied from mrb_irep_free() in state.c */ + for (i=0; i<s->irep->rlen; i++) { + if (s->reps[i]) + mrb_irep_decref(s->mrb, (mrb_irep*)s->reps[i]); + } + mrb_free(s->mrb, s->reps); } - mrb_free(s->mrb, s->reps); + mrb_free(s->mrb, s->lines); } - mrb_free(s->mrb, s->lines); mrb_pool_close(s->mpool); s = tmp; } @@ -3020,18 +3022,28 @@ codegen(codegen_scope *s, node *tree, int val) } static void -scope_add_irep(codegen_scope *s, mrb_irep *irep) +scope_add_irep(codegen_scope *s) { - if (s->irep == NULL) { - s->irep = irep; + mrb_irep *irep; + codegen_scope *prev = s->prev; + + if (prev->irep == NULL) { + irep = mrb_add_irep(s->mrb); + prev->irep = s->irep = irep; return; } - if (s->irep->rlen == s->rcapa) { - s->rcapa *= 2; - s->reps = (mrb_irep**)codegen_realloc(s, s->reps, sizeof(mrb_irep*)*s->rcapa); + else { + if (prev->irep->rlen == UINT8_MAX) { + codegen_error(s, "too many nested blocks/methods"); + } + s->irep = irep = mrb_add_irep(s->mrb); + if (prev->irep->rlen == prev->rcapa) { + prev->rcapa *= 2; + prev->reps = (mrb_irep**)codegen_realloc(s, prev->reps, sizeof(mrb_irep*)*prev->rcapa); + } + prev->reps[prev->irep->rlen] = irep; + prev->irep->rlen++; } - s->reps[s->irep->rlen] = irep; - s->irep->rlen++; } static codegen_scope* @@ -3054,23 +3066,19 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *nlv) s->ainfo = -1; s->mscope = 0; - s->irep = mrb_add_irep(mrb); - scope_add_irep(prev, s->irep); + scope_add_irep(s); s->rcapa = 8; s->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*s->rcapa); s->icapa = 1024; s->iseq = (mrb_code*)mrb_malloc(mrb, sizeof(mrb_code)*s->icapa); - s->irep->iseq = NULL; s->pcapa = 32; s->pool = (mrb_pool_value*)mrb_malloc(mrb, sizeof(mrb_pool_value)*s->pcapa); - s->irep->plen = 0; s->scapa = 256; s->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*s->scapa); - s->irep->slen = 0; s->lv = nlv; s->sp += node_len(nlv)+1; /* add self */ @@ -3116,7 +3124,7 @@ scope_finish(codegen_scope *s) mrb_state *mrb = s->mrb; mrb_irep *irep = s->irep; - if (s->nlocals >= 0x3ff) { + if (s->nlocals > 0xff) { codegen_error(s, "too many local variables"); } irep->flags = 0; |
