view runtime/context.c @ 56:d2f9b0a9403d

Initial experiment with goto and switch
author Mike Pavone <pavone@retrodev.com>
date Thu, 08 Oct 2009 01:52:38 -0400
parents 640f541e9116
children 04baa003de5a
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->used = 0;
	return st;
}

context * new_context()
{
	context * c = malloc(sizeof(context));
	c->stack_begin = new_stack();
	c->current_stack = c->stack_begin;
	return c;
}

void * alloc_stack(context * ct, uint32_t size)
{
	void * ret;
	stackchunk * current = ct->current_stack;
	if(size > STACK_CHUNK_SIZE)
	{
		fprintf(stderr, "%d is bigger than stack chunk size of %d\n", size, STACK_CHUNK_SIZE);
		return NULL;
	}
	while(current && STACK_CHUNK_SIZE - current->used < size)
	{
		if(!current->next)
		{
			current->next = new_stack();
			current->next->prev = current;
		}
		current = current->next;
	}
	if(!current)
	{
		fprintf(stderr, "Failed to allocate stack chunk");
		return NULL;
	}
	ct->current_stack = current;
	ret = current->data + current->used;
	current->used += size;
	return ret;
}

calldata * alloc_cdata(context * ct, calldata * lastframe, uint32_t num_params)
{
	calldata * retval = (calldata *)(((char *)alloc_stack(ct, sizeof(calldata)+(num_params-1)*sizeof(object *))) + sizeof(object *)*(num_params-1));
	retval->lastframe = lastframe;
	return retval;
}

void free_stack(context * ct, void * data)
{
	char * cdata = data;
	while(cdata < ct->current_stack->data || cdata >= ct->current_stack->data+STACK_CHUNK_SIZE) {
		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->used = 0;
		ct->current_stack = ct->current_stack->prev;
	}
	ct->current_stack->used = cdata-ct->current_stack->data;
	if(!ct->current_stack->used && ct->current_stack->prev)
		ct->current_stack = ct->current_stack->prev;
}