view runtime/context.c @ 139:a68e6828d896

Global stores and transactions are working. Definately leaks memory on retries. Probably a fair number of bugs to work out. However, a basic test program works.
author Mike Pavone <pavone@retrodev.com>
date Fri, 19 Nov 2010 04:04:14 -0500
parents d1569087348f
children c14698c512f1
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;
	c->transaction = NULL;
	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;
}