view runtime/context.c @ 37:640f541e9116

Added support for type declarations on user defined workers and added a few more methods to Int32 in the runtime for the C backend
author Mike Pavone <pavone@retrodev.com>
date Mon, 05 Oct 2009 23:12:43 -0400
parents 31f8182f3433
children 079200bc3e75 d2f9b0a9403d
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;
	c->unwind = NULL;
	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, uint32_t num_params)
{
	calldata * out = alloc_stack(ct, sizeof(calldata)+(num_params-1)*sizeof(object *));
	if(out)
		out->ct = ct;
	return out;
}

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;
}