aboutsummaryrefslogtreecommitdiffstats
path: root/symbol.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2017-04-04 21:53:44 +0300
committerArnold D. Robbins <arnold@skeeve.com>2017-04-04 21:53:44 +0300
commit070c57daec076e780e81d8b1011a02ea8ac8915f (patch)
tree96d4c7747e2f29398b23cdcc550d92f8d4417439 /symbol.c
parent4271b995d64430e794e344f0c4985162eb991052 (diff)
downloadegawk-070c57daec076e780e81d8b1011a02ea8ac8915f.tar.gz
egawk-070c57daec076e780e81d8b1011a02ea8ac8915f.tar.bz2
egawk-070c57daec076e780e81d8b1011a02ea8ac8915f.zip
fixes for memory leak for user-supplied sorting function.
Diffstat (limited to 'symbol.c')
-rw-r--r--symbol.c71
1 files changed, 20 insertions, 51 deletions
diff --git a/symbol.c b/symbol.c
index 65ed4d90..b2a6a6c2 100644
--- a/symbol.c
+++ b/symbol.c
@@ -37,7 +37,7 @@ static NODE *symbol_list;
static void (*install_func)(NODE *) = NULL;
static NODE *make_symbol(const char *name, NODETYPE type);
static NODE *install(const char *name, NODE *parm, NODETYPE type);
-static void free_bcpool(INSTRUCTION *pl);
+static void free_bcpool(INSTRUCTION_POOL *pl);
static AWK_CONTEXT *curr_ctxt = NULL;
static int ctxt_level;
@@ -693,21 +693,19 @@ check_param_names(void)
return result;
}
-#define pool_size d.dl
#define freei x.xi
-static INSTRUCTION *pool_list;
-
-/* INSTR_CHUNK must be > largest code size (3) */
-#define INSTR_CHUNK 127
+static INSTRUCTION_POOL pools;
/* bcfree --- deallocate instruction */
void
bcfree(INSTRUCTION *cp)
{
+ assert(cp->pool_size >= 1 && cp->pool_size <= MAX_INSTRUCTION_ALLOC);
+
cp->opcode = 0;
- cp->nexti = pool_list->freei;
- pool_list->freei = cp;
+ cp->nexti = pools.pool[cp->pool_size].freei;
+ pools.pool[cp->pool_size].freei = cp;
}
/* bcalloc --- allocate a new instruction */
@@ -717,37 +715,16 @@ bcalloc(OPCODE op, int size, int srcline)
{
INSTRUCTION *cp;
- if (size > 1) {
- /* wide instructions Op_rule, Op_func_call .. */
- emalloc(cp, INSTRUCTION *, (size + 1) * sizeof(INSTRUCTION), "bcalloc");
- cp->pool_size = size;
- cp->nexti = pool_list->nexti;
- pool_list->nexti = cp++;
+ assert(size >= 1 && size <= MAX_INSTRUCTION_ALLOC);
+
+ if ((cp = pools.pool[size].freei) != NULL) {
+ pools.pool[size].freei = cp->nexti;
} else {
- INSTRUCTION *pool;
-
- pool = pool_list->freei;
- if (pool == NULL) {
- INSTRUCTION *last;
- emalloc(cp, INSTRUCTION *, (INSTR_CHUNK + 1) * sizeof(INSTRUCTION), "bcalloc");
-
- cp->pool_size = INSTR_CHUNK;
- cp->nexti = pool_list->nexti;
- pool_list->nexti = cp;
- pool = ++cp;
- last = &pool[INSTR_CHUNK - 1];
- for (; cp <= last; cp++) {
- cp->opcode = 0;
- cp->nexti = cp + 1;
- }
- --cp;
- cp->nexti = NULL;
- }
- cp = pool;
- pool_list->freei = cp->nexti;
+ emalloc(cp, INSTRUCTION *, (size + 1) * sizeof(INSTRUCTION), "bcalloc");
}
memset(cp, 0, size * sizeof(INSTRUCTION));
+ cp->pool_size = size;
cp->opcode = op;
cp->source_line = srcline;
return cp;
@@ -773,7 +750,7 @@ new_context()
static void
set_context(AWK_CONTEXT *ctxt)
{
- pool_list = & ctxt->pools;
+ pools = ctxt->pools;
symbol_list = & ctxt->symbols;
srcfiles = & ctxt->srcfiles;
rule_list = & ctxt->rule_list;
@@ -915,24 +892,16 @@ free_bc_internal(INSTRUCTION *cp)
/* free_bcpool --- free list of instruction memory pools */
static void
-free_bcpool(INSTRUCTION *pl)
+free_bcpool(INSTRUCTION_POOL *pl)
{
- INSTRUCTION *pool, *tmp;
-
- for (pool = pl->nexti; pool != NULL; pool = tmp) {
- INSTRUCTION *cp, *last;
- long psiz;
- psiz = pool->pool_size;
- if (psiz == INSTR_CHUNK)
- last = pool + psiz;
- else
- last = pool + 1;
- for (cp = pool + 1; cp <= last ; cp++) {
+ INSTRUCTION *cp, *next;
+ int i;
+
+ for (i = 1; i <= MAX_INSTRUCTION_ALLOC; i++) {
+ for (cp = pl->pool[i].nexti; cp != NULL; cp = next) {
+ next = cp->nexti;
if (cp->opcode != 0)
free_bc_internal(cp);
}
- tmp = pool->nexti;
- efree(pool);
}
- memset(pl, 0, sizeof(INSTRUCTION));
}