Mercurial > repos > rhope
view runtime/context.c @ 121:1af91ceaaf49
Fixed memory leak when an output is only attached to a single null input
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 28 Oct 2010 21:04:12 -0400 |
parents | d1569087348f |
children | a68e6828d896 |
line wrap: on
line source
#include "context.h" #include "object.h" #include <stdlib.h> #include <stddef.h> #include <stdio.h> stackchunk * new_stack() { stackchunk * st = malloc(sizeof(stackchunk)); st->prev = NULL; st->next = NULL; st->free_space = st->data; return st; } context * new_context() { context * c = malloc(sizeof(context)); c->stack_begin = new_stack(); c->current_stack = c->stack_begin; return c; } void free_context(context * c) { stackchunk *next,*current = c->stack_begin; while(current) { next = current->next; free(current); current = next; } free(c); } void * alloc_stack(context * ct, uint32_t size) { void * ret; stackchunk * current = ct->current_stack; char * next_free = current->free_space + size; if (next_free <= (current->data + STACK_CHUNK_SIZE)) { ret = current->free_space; current->free_space = next_free; return ret; } if (!current->next) { current->next = new_stack(); current->next->prev = current; } current = current->next; ct->current_stack = current; current->free_space = current->data + size; return current->data; } calldata * alloc_cdata(context * ct, calldata * lastframe, uint32_t num_params) { //Make sure we have enough space for at least 32 return values calldata * retval = alloc_stack(ct, sizeof(calldata)+(31)*sizeof(object *)); //But only actually reserve space for the number requested free_stack(ct, retval->params + num_params); retval->lastframe = lastframe; retval->callspace = num_params; return retval; } void free_stack(context * ct, void * data) { char * cdata = data; while(cdata < ct->current_stack->data || cdata >= ct->current_stack->free_space) { if(ct->current_stack == ct->stack_begin) { fprintf(stderr, "Attempt to free memory at %X using free_stack, but %X doesn't appear to be stack allocated\n", data, data); exit(-1); } ct->current_stack = ct->current_stack->prev; } ct->current_stack->free_space = data; if(ct->current_stack->free_space == ct->current_stack->data && ct->current_stack->prev) ct->current_stack = ct->current_stack->prev; }