changeset 7:d61550e2c001

Added current work on new runtime
author Mike Pavone <pavone@retrodev.com>
date Wed, 13 May 2009 00:47:40 -0400
parents f67d9be38ddf
children 8d74ef7fa357
files runtime/array.c runtime/array.h runtime/builtin.c runtime/builtin.h runtime/func.h runtime/integer.c runtime/integer.h runtime/object.c runtime/object.h runtime/plat_types.h runtime/thread.h test/test.c
diffstat 12 files changed, 771 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/array.c	Wed May 13 00:47:40 2009 -0400
@@ -0,0 +1,26 @@
+#include "array.h"
+#include "integer.h"
+
+Func(Array,0,
+	;)
+	Ret(0, new_object(TYPE_ARRAY))
+	Return
+EndFunc
+
+Method(Index,Array,2,
+	_t_Int32 * idx;)
+	Param(1,idx,Int32)
+	if (idx->num < 0 || idx->num >= me->numels) {
+		Ret(0, NULL)
+		Ret(1, me)
+	} else {
+		Ret(1, NULL)
+		if (me->contents_type) {
+			Ret(0, copy_from_raw(me->conents_type, (char *)me + sizeof(*me) + (idx->num * sizeof(object *))))
+		} else {
+			Ret(0, add_ref((object *)((char *)me + sizeof(*me) + (idx->num * sizeof(object *)))))
+		}
+		release_ref(me);
+	}
+EndFunc
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/array.h	Wed May 13 00:47:40 2009 -0400
@@ -0,0 +1,14 @@
+#ifndef _ARRAY_H_
+#define _ARRAH_H_
+
+#include "object.h"
+#include "func.h"
+#include "builtin.h"
+
+MOBegin
+	blueprint *contents_type;
+	int32     numels;
+Object(Array)
+
+
+#endif //_ARRAY_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/builtin.c	Wed May 13 00:47:40 2009 -0400
@@ -0,0 +1,25 @@
+#include "builtin.h"
+#include "object.h"
+#include "integer.h"
+#include <stddef.h>
+
+void register_builtin_type(uint32_t type)
+{
+	blueprint * bp;
+	switch(type)
+	{
+	case TYPE_INT32:
+		bp = register_type_byid(TYPE_INT32, sizeof(int32_t), NULL, NULL, NULL);
+		add_method(bp, METHOD_ADD, MethodName(_PL_,Int32));
+		add_method(bp, METHOD_SUB, MethodName(_MN_,Int32));
+		break;
+	}
+}
+
+void register_builtin_types()
+{
+	uint32_t i;
+	for(i = 0; i < TYPE_FIRST_USER; ++i)
+		register_builtin_type(i);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/builtin.h	Wed May 13 00:47:40 2009 -0400
@@ -0,0 +1,44 @@
+#ifndef _BUILTIN_H_
+#define _BUILTIN_H_
+#include "plat_types.h"
+
+//Builtin Types
+enum {
+	TYPE_UINT8 = 1,
+	TYPE_UINT16,
+	TYPE_UINT32,
+	TYPE_UINT64,
+	TYPE_INT8,
+	TYPE_INT16,
+	TYPE_INT32,
+	TYPE_INT64,
+	TYPE_FLOAT32,
+	TYPE_FLOAT64,
+	TYPE_ARRAY,
+	TYPE_METHODMISSINGEXCEPTION,
+	TYPE_FIELDMISSINGEXCEPTION,
+	TYPE_WRONGTYPEEXCEPTION,
+	TYPE_FIRST_USER //Insert new builtin types before this one
+};
+
+//Builtin Methods
+enum {
+	METHOD_SETFIELDMISSING=1,
+	METHOD_GETFIELDMISSING,
+	METHOD_ADD,
+	METHOD_SUB,
+	METHOD_DIV,
+	METHOD_MUL,
+	METHOD_LSHIFT,
+	METHOD_RSHIFT,
+	METHOD_EQUALS,
+	METHOD_GREATER,
+	METHOD_LESS,
+	METHOD_MISSING,//Insert new builtin methods before this one
+	METHOD_FIRST_USER 
+};
+
+void register_builtin_types();
+void register_builtin_type(uint32_t type);
+
+#endif //_BUILTIN_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/func.h	Wed May 13 00:47:40 2009 -0400
@@ -0,0 +1,17 @@
+#ifndef _FUNC_H_
+#define _FUNC_H_
+
+#define MethodName(name,type) _f_ ## name ## _AT_ ## type
+
+#define Func(name,numparams,locals) returntype _f_ ## name (calldata * cdata) { locals;
+#define EndFunc	return NORMAL_RETURN; }
+#define Method(name,type,numparams,locals) returntype MethodName(name,type) (calldata * cdata) { locals;
+#define Param(num,var,type) var = (_t_##type *)(
+#define Ret(num,val) cdata->params[num] = (object *)(val);
+#define Return return NORMAL_RETURN;
+#define Exception
+#define FuncDef(name) returntype _f_ ## name (calldata * cdata);
+#define MethodDef(name,type) returntype MethodName(name,type) (calldata * cdata);
+
+
+#endif //_FUNC_H_
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/integer.c	Wed May 13 00:47:40 2009 -0400
@@ -0,0 +1,117 @@
+#include "integer.h"
+#include "builtin.h"
+
+Method(_PL_,Int32,2,
+	_t_Int32 * left; _t_Int32 * right; calldata convd; returntype ret; int i)
+	convd.params[0] = cdata->params[0];
+	convd.num_params = 1;
+	switch(coerce_value(TYPE_INT32, &convd))
+	{
+	case TAIL_RETURN:
+		do {
+			ret = convd.tail_func(&convd);
+		} while(ret == TAIL_RETURN);
+		//TODO: Support STACK_UNWIND
+		if(ret == EXCEPTION_RETURN)
+			goto exception_convert_left;
+	case EXCEPTION_RETURN:
+		goto exception_convert_left;
+	}
+	left = (_t_Int32 *)copy_object(convd.params[0]);
+	cdata->params[0] = (object *)left;
+	convd.params[0] = cdata->params[1];
+	switch(coerce_value(TYPE_INT32, &convd))
+	{
+	case TAIL_RETURN:
+		do {
+			ret = convd.tail_func(&convd);
+		} while(ret == TAIL_RETURN);
+		//TODO: Support STACK_UNWIND
+		if(ret == EXCEPTION_RETURN)
+			goto exception_convert_right;
+	case EXCEPTION_RETURN:
+		goto exception_convert_right;
+	}
+	right = (_t_Int32 *)convd.params[0];
+	left->num += right->num;
+	release_ref((object *)right);
+	return NORMAL_RETURN;
+	
+exception_convert_left:
+	//The first params hould have been released when the exception occurred
+	for(i = 1; i < cdata->num_params; ++i)
+		release_ref(cdata->params[i]);
+	//Move exception to our calldata struct
+	cdata->params[0] = convd.params[0];
+	return EXCEPTION_RETURN;
+exception_convert_right:
+	//The second param hould have been released when the exception occurred
+	for(i = 0; i < cdata->num_params; ++i)
+		if(i != 1)
+			release_ref(cdata->params[i]);
+	//Move exception to our calldata struct
+	cdata->params[0] = convd.params[0];
+	return EXCEPTION_RETURN;
+}
+
+Method(_MN_,Int32,2,
+	_t_Int32 * left; _t_Int32 * right; calldata convd; returntype ret; int i)
+	convd.params[0] = cdata->params[0];
+	convd.num_params = 1;
+	switch(coerce_value(TYPE_INT32, &convd))
+	{
+	case TAIL_RETURN:
+		do {
+			ret = convd.tail_func(&convd);
+		} while(ret == TAIL_RETURN);
+		//TODO: Support STACK_UNWIND
+		if(ret == EXCEPTION_RETURN)
+			goto exception_convert_left;
+	case EXCEPTION_RETURN:
+		goto exception_convert_left;
+	}
+	left = (_t_Int32 *)copy_object(convd.params[0]);
+	cdata->params[0] = (object *)left;
+	convd.params[0] = cdata->params[1];
+	switch(coerce_value(TYPE_INT32, &convd))
+	{
+	case TAIL_RETURN:
+		do {
+			ret = convd.tail_func(&convd);
+		} while(ret == TAIL_RETURN);
+		//TODO: Support STACK_UNWIND
+		if(ret == EXCEPTION_RETURN)
+			goto exception_convert_right;
+	case EXCEPTION_RETURN:
+		goto exception_convert_right;
+	}
+	right = (_t_Int32 *)convd.params[0];
+	left->num -= right->num;
+	release_ref((object *)right);
+	return NORMAL_RETURN;
+	
+exception_convert_left:
+	//The first params hould have been released when the exception occurred
+	for(i = 1; i < cdata->num_params; ++i)
+		release_ref(cdata->params[i]);
+	//Move exception to our calldata struct
+	cdata->params[0] = convd.params[0];
+	return EXCEPTION_RETURN;
+exception_convert_right:
+	//The second param hould have been released when the exception occurred
+	for(i = 0; i < cdata->num_params; ++i)
+		if(i != 1)
+			release_ref(cdata->params[i]);
+	//Move exception to our calldata struct
+	cdata->params[0] = convd.params[0];
+	return EXCEPTION_RETURN;
+}
+
+object * make_Int32(int32_t val)
+{
+	_t_Int32 * obj;
+	object * ret = new_object(TYPE_INT32);
+	obj = (_t_Int32 *)ret;
+	obj->num = val;
+	return ret;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/integer.h	Wed May 13 00:47:40 2009 -0400
@@ -0,0 +1,16 @@
+#ifndef _INTEGER_H_
+#define _INTEGER_H_
+
+#include "object.h"
+#include "func.h"
+
+OBegin
+	int32_t num;
+Object(Int32)
+
+MethodDef(_PL_,Int32)
+MethodDef(_MN_,Int32)
+
+object * make_Int32(int32_t val);
+
+#endif //_INTEGER_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/object.c	Wed May 13 00:47:40 2009 -0400
@@ -0,0 +1,343 @@
+#include "object.h"
+#include "builtin.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+blueprint ** registered_types = NULL;
+uint32_t max_registered_type = 0;
+uint32_t type_storage = 0;
+
+returntype call_method(uint32_t methodid, calldata * params)
+{
+	int i;
+	blueprint * bp = get_blueprint(params->params[0]);
+	if(methodid >= bp->first_methodid && methodid < bp->last_methodid && bp->method_lookup[methodid - bp->first_methodid])
+	{
+		params->tail_func =  bp->method_lookup[methodid - bp->first_methodid];
+		return TAIL_RETURN;
+	} else {
+		if(METHOD_MISSING >= bp->first_methodid && METHOD_MISSING < bp->last_methodid && bp->method_lookup[METHOD_MISSING - bp->first_methodid])
+		{
+			params->tail_func = bp->method_lookup[METHOD_MISSING - bp->first_methodid];
+			return TAIL_RETURN;
+		} else {
+			//TODO: Add useful info to exception
+			for(i = 0; i < params->num_params; ++i)
+				release_ref(params->params[i]);
+			params->params[0] = new_object(TYPE_METHODMISSINGEXCEPTION);
+			return EXCEPTION_RETURN;
+		}
+	}
+}
+
+returntype set_field(uint32_t setfieldid, calldata * params)
+{
+	int i;
+	blueprint * bp = get_blueprint(params->params[0]);
+	if(setfieldid >= bp->first_setfieldid && setfieldid < bp->last_setfieldid && bp->setter_lookup[setfieldid - bp->first_setfieldid])
+	{
+		params->tail_func =  bp->setter_lookup[setfieldid - bp->first_setfieldid];
+		return TAIL_RETURN;
+	} else {
+		if(METHOD_SETFIELDMISSING >= bp->first_setfieldid && METHOD_SETFIELDMISSING < bp->last_setfieldid && bp->method_lookup[METHOD_SETFIELDMISSING - bp->first_methodid])
+		{
+			params->tail_func = bp->method_lookup[METHOD_SETFIELDMISSING - bp->first_methodid];
+			params->original_methodid = setfieldid;
+			return TAIL_RETURN;
+		} else {
+			//TODO: Add useful info to exception
+			for(i = 0; i < params->num_params; ++i)
+				release_ref(params->params[i]);
+			params->params[0] = new_object(TYPE_FIELDMISSINGEXCEPTION);
+			return EXCEPTION_RETURN;
+		}
+	}
+}
+
+
+returntype get_field(uint32_t getfieldid, calldata * params)
+{
+	int i;
+	blueprint * bp = get_blueprint(params->params[0]);
+	if(getfieldid >= bp->first_getfieldid && getfieldid < bp->last_getfieldid && bp->getter_lookup[getfieldid - bp->first_getfieldid])
+	{
+		params->tail_func =  bp->getter_lookup[getfieldid - bp->first_getfieldid];
+		return TAIL_RETURN;
+	} else {
+		if(METHOD_GETFIELDMISSING >= bp->first_getfieldid && METHOD_GETFIELDMISSING < bp->last_getfieldid && bp->method_lookup[METHOD_GETFIELDMISSING - bp->first_methodid])
+		{
+			params->tail_func = bp->method_lookup[METHOD_GETFIELDMISSING - bp->first_methodid];
+			params->original_methodid = getfieldid;
+			return TAIL_RETURN;
+		} else {
+			//TODO: Add useful info to exception
+			for(i = 0; i < params->num_params; ++i)
+				release_ref(params->params[i]);
+			params->params[0] = new_object(TYPE_FIELDMISSINGEXCEPTION);
+			return EXCEPTION_RETURN;
+		}
+	}
+}
+
+returntype convert_to(uint32_t convertto, calldata * params)
+{
+	int i;
+	blueprint * bp = get_blueprint(params->params[0]);
+	if(convertto >= bp->first_convertto && convertto < bp->last_convertto && bp->convert_to[convertto])
+	{
+		params->tail_func =  bp->convert_to[convertto - bp->first_convertto];
+		return TAIL_RETURN;
+	} else {
+		return NO_CONVERSION;
+	}
+}
+
+returntype convert_from(uint32_t convertfrom, calldata * params)
+{
+	int i;
+	blueprint * bp = registered_types[convertfrom];
+	if(convertfrom >= bp->first_convertfrom && convertfrom < bp->last_convertfrom && bp->convert_from[convertfrom])
+	{
+		params->tail_func =  bp->convert_from[convertfrom - bp->first_convertfrom];
+		return TAIL_RETURN;
+	} else {
+		return NO_CONVERSION;
+	}
+}
+
+returntype coerce_value(uint32_t type, calldata * params)
+{
+	int i;
+	blueprint * bp = get_blueprint(params->params[0]);
+	if(bp == registered_types[type])
+		return NORMAL_RETURN;
+	if(convert_to(type, params) == TAIL_RETURN)
+		return TAIL_RETURN;
+	if(convert_from(type, params) == TAIL_RETURN)
+		return TAIL_RETURN;
+	//TODO: Add useful info to exception
+	for(i = 0; i < params->num_params; ++i)
+		release_ref(params->params[i]);
+	params->params[0] = new_object(TYPE_WRONGTYPEEXCEPTION);
+	return EXCEPTION_RETURN;
+}
+
+object * alloc_object(blueprint * bp)
+{
+	//TODO: Replace with something more performant
+	return malloc(bp->boxed_size);
+}
+
+void * alloc_variable(uint32_t size)
+{
+	return malloc(size);
+}
+
+void dealloc_object(blueprint * bp, object * obj)
+{
+	//TODO: Replace with something more performant
+	free(obj);
+}
+
+object * new_object(uint32_t type)
+{
+	blueprint * bp;
+	object * ret;
+	if(type >= max_registered_type || !registered_types[type])
+		return NULL;
+	bp = registered_types[type];
+	ret = alloc_object(bp);
+	if(ret)
+	{
+		ret->bprint = bp;
+		rh_atomic_set(ret, refcount, 1);
+		memset(((char *)ret) + sizeof(object), '\0', bp->size);
+		bp->init(ret);
+	}
+	return ret;
+}
+
+multisize * new_multisize(uint32_t type, uint32_t size)
+{
+	blueprint *bp;
+	multisize * ret;
+	if(type >= max_registered_type || !registered_types[type])
+		return NULL;
+	ret = alloc_variable(sizeof(multisize) + type);
+	if(ret)
+	{
+		bp = registered_types[type];
+		ret->base.bprint = bp;
+		ret->size = size;
+		rh_atomic_set(&(ret->base), refcount, 1);
+		memset(((char *)ret) + sizeof(multisize), '\0', size);
+		bp->init((object *)ret);
+	}
+	return ret; 
+}
+
+object * copy_object(object * tocopy)
+{
+	object * copy;
+	multisize * mcopy, *mtocopy;
+	blueprint * bp;
+	if(rh_atomic_get(tocopy, refcount) == 1)
+		return tocopy;
+	bp = get_blueprint(tocopy);
+	if(bp->size < 0) {
+		mtocopy = (multisize *)tocopy;
+		mcopy = alloc_variable(sizeof(multisize) + mtocopy->size);
+		mcopy->size = mtocopy->size;
+		memcpy(((char *)mcopy)+sizeof(multisize), ((char *)mtocopy)+sizeof(multisize), mtocopy->size);
+		copy = (object *)mcopy;
+	} else {
+		copy = alloc_object(bp);
+		memcpy(((char *)copy) + sizeof(object), ((char *)tocopy)+sizeof(object), bp->size);
+	}
+	copy->bprint = bp;
+	rh_atomic_set(copy, refcount, 1);
+	bp->copy(copy);
+	release_ref(tocopy);
+	return copy;
+}
+
+void free_object(object * obj)
+{
+	blueprint * bp = get_blueprint(obj);
+	if(bp->cleanup)
+		bp->cleanup(obj);
+	dealloc_object(bp, obj);
+}
+
+void release_ref(object * obj)
+{
+	if(rh_atomic_sub_testzero(obj, refcount, 1))
+		free_object(obj);
+}
+
+void check_type_storage(type)
+{
+	uint32_t type_storage_temp;
+	blueprint ** temp;
+	if(type >= type_storage)
+		if(type_storage)
+		{
+			type_storage_temp = (type + (type_storage >> 1));
+			temp = realloc(registered_types, type_storage_temp * sizeof(blueprint *));
+			if(temp)
+			{
+				registered_types = temp;
+				memset(registered_types + type_storage, '\0', (type_storage_temp - type_storage) * sizeof(blueprint *));
+				type_storage = type_storage_temp;
+			}
+			else
+			{
+				free(registered_types);
+				fprintf(stderr, "Couldn't allocate %d bytes for type storage array\n", type_storage_temp * sizeof(blueprint *));
+				exit(-1);
+			}
+		} else {
+			
+			if(type < INITIAL_TYPE_STORAGE)
+				type_storage =INITIAL_TYPE_STORAGE;
+			else
+				type_storage = type + 8;
+			registered_types = malloc(type_storage * sizeof(blueprint *));
+			if(registered_types)
+				memset(registered_types, '\0', type_storage * sizeof(blueprint *));
+			else
+			{
+				fprintf(stderr, "Couldn't allocate %d bytes for type storage array\n", type_storage * sizeof(blueprint *));
+				exit(-1);
+			}
+				
+		}
+}
+
+void default_action(object * obj)
+{
+}
+
+blueprint * new_blueprint(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup)
+{
+	blueprint * bp = malloc(sizeof(blueprint));
+	if(bp)
+	{
+		bp->size = size;
+		bp->boxed_size = size >= 0 ? size + sizeof(object) : size;
+		bp->method_lookup = bp->getter_lookup = bp->setter_lookup = bp->convert_to = bp->convert_from = NULL;
+		bp->init = init ? init : default_action;
+		bp->copy = copy ? copy : default_action;
+		bp->cleanup = cleanup ? cleanup : default_action;
+		bp->first_methodid = bp->last_methodid = bp->first_getfieldid = bp->last_getfieldid = bp->first_setfieldid = bp->last_setfieldid = bp->first_convertto = bp->last_convertto = bp->first_convertfrom = bp->last_convertfrom = 0;
+		//TODO: Handle names
+		bp->name = NULL;
+	}
+	return bp;
+}
+
+blueprint * register_type_byid(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup)
+{
+	check_type_storage(type);
+	if(registered_types[type])
+		return registered_types[type];
+	registered_types[type] = new_blueprint(type, size, init, copy, cleanup);
+	if(!registered_types[type])
+	{
+		fputs("Couldn't allocate new object blueprint\n", stderr);
+		exit(-1);
+	}
+	if(type >= max_registered_type)
+		max_registered_type = type + 1;
+	return registered_types[type];
+}
+
+void add_method(blueprint * bp, uint32_t methodid, rhope_func impl)
+{
+	rhope_func * temp;
+	if(methodid < 1) {
+		fputs("Attempt to add a method with an ID < 1\n", stderr);
+		exit(-1);
+	}
+	if (!bp->method_lookup)
+	{
+		bp->method_lookup = malloc(sizeof(rhope_func) * INITIAL_METHOD_LOOKUP);
+		if(!bp->method_lookup) {
+			fprintf(stderr, "Couldn't allocate %d bytes for method lookup table\n", sizeof(rhope_func) * INITIAL_METHOD_LOOKUP);
+			exit(-1);
+		}
+		if(methodid - BELOW_INITIAL_METHOD < 1) {
+			bp->first_methodid = 1;
+			bp->last_methodid = 1+INITIAL_METHOD_LOOKUP;
+		} else {
+			bp->first_methodid = methodid - BELOW_INITIAL_METHOD;
+			bp->last_methodid = bp->first_methodid + INITIAL_METHOD_LOOKUP;
+		}
+		memset(bp->method_lookup, '\0', sizeof(rhope_func) * INITIAL_METHOD_LOOKUP);
+	} else {
+		if (methodid < bp->first_methodid) {
+			temp = bp->method_lookup;
+			//Note: if this gets changed to generating an exception on failure, we need to restore the original buffer
+			bp->method_lookup = malloc(sizeof(rhope_func) * (bp->last_methodid-methodid));
+			if(!bp->method_lookup) {
+				fprintf(stderr, "Couldn't allocate %d bytes for method lookup table\n", sizeof(rhope_func) * (bp->last_methodid-methodid));
+				exit(-1);
+			}
+			memset(bp->method_lookup, '\0', (bp->first_methodid-methodid) * sizeof(rhope_func));
+			memcpy(bp->method_lookup + bp->first_methodid-methodid, temp, (bp->last_methodid-bp->first_methodid)*sizeof(rhope_func));
+			free(temp);
+			bp->first_methodid = methodid;
+		} else if(methodid >= bp->last_methodid) {
+			//Note: if this gets changed to generating an exception on failure, we need to restore the original buffer
+			bp->method_lookup = realloc(bp->method_lookup, (methodid+1-bp->first_methodid) * sizeof(rhope_func));
+			if(!bp->method_lookup) {
+				fprintf(stderr, "Couldn't resize method lookup table to %d bytes\n", (methodid+1-bp->first_methodid) * sizeof(rhope_func));
+				exit(-1);
+			}
+			memset(bp->method_lookup+bp->last_methodid, '\0', (methodid+1)-bp->last_methodid);
+			bp->last_methodid = methodid;
+		}
+	}
+	bp->method_lookup[methodid-bp->first_methodid] = impl;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/object.h	Wed May 13 00:47:40 2009 -0400
@@ -0,0 +1,90 @@
+#ifndef _OBJECT_H_
+#define _OBJECT_H_
+
+#include "plat_types.h"
+#include "thread.h"
+
+typedef enum {
+	NORMAL_RETURN=0,
+	EXCEPTION_RETURN,
+	TAIL_RETURN,
+	NO_CONVERSION,
+	STACK_UNWIND
+} returntype;
+
+
+typedef returntype (*rhope_func)(struct calldata *);
+typedef void (*special_func) (struct object *);
+
+typedef struct{
+	rhope_func     *method_lookup;
+	rhope_func     *getter_lookup;
+	rhope_func     *setter_lookup;
+	rhope_func     *convert_to;
+	rhope_func     *convert_from;
+	special_func   init;
+	special_func   copy;
+	special_func   cleanup;
+	struct object  *name;
+	uint32_t       first_methodid;
+	uint32_t       last_methodid;
+	uint32_t       first_getfieldid;
+	uint32_t       last_getfieldid;
+	uint32_t       first_setfieldid;
+	uint32_t       last_setfieldid;
+	uint32_t       first_convertto;
+	uint32_t       last_convertto;
+	uint32_t       first_convertfrom;
+	uint32_t       last_convertfrom;
+	uint32_t       size;
+	uint32_t       boxed_size;
+} blueprint;
+
+typedef struct object {
+	rh_atomic32(refcount);
+	blueprint  *bprint;
+} object;
+
+typedef struct {
+	object base;
+	uint32_t        size;
+} multisize;
+
+
+typedef struct calldata {
+	rhope_func  tail_func;
+	uint32_t    num_params;
+	uint32_t    original_methodid;
+	object      *params[32];
+} calldata;
+
+#define OBegin typedef struct { object header;
+#define Object(name) } _t_ ## name;
+
+#define MOBegin typedef struct { multisize header;
+
+#define get_blueprint(object) (object)->bprint
+
+#define add_ref(object) rh_atomic_add(&(object->header), refcount, 1)
+
+returntype call_method(uint32_t methodid, calldata * params);
+returntype set_field(uint32_t setfieldid, calldata * params);
+returntype get_field(uint32_t getfieldid, calldata * params);
+object * alloc_object(blueprint * bp);
+void * alloc_variable(uint32_t size);
+object * new_object(uint32_t type);
+multisize * new_multisize(uint32_t type, uint32_t size);
+void release_ref(object * obj);
+blueprint * register_type_byid(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup);
+blueprint * new_blueprint(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup);
+void add_method(blueprint * bp, uint32_t methodid, rhope_func impl);
+returntype convert_to(uint32_t convertto, calldata * params);
+returntype convert_from(uint32_t convertfrom, calldata * params);
+object * copy_object(object * tocopy);
+returntype coerce_value(uint32_t type, calldata * params);
+
+#define INITIAL_TYPE_STORAGE	32
+#define INITIAL_METHOD_LOOKUP	8
+#define BELOW_INITIAL_METHOD	3
+
+#endif //_OBJECT_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/plat_types.h	Wed May 13 00:47:40 2009 -0400
@@ -0,0 +1,19 @@
+#ifndef _PLAT_TYPES_H_
+#define _PLAT_TYPES_H_
+
+#ifdef _WIN32
+
+typedef char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+typedef long long int64_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+#else
+#include <stdint.h>
+#endif
+
+#endif //_PLAT_TYPES_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/thread.h	Wed May 13 00:47:40 2009 -0400
@@ -0,0 +1,27 @@
+#ifndef _THREAD_H_
+#define _THREAD_H_
+#include "plat_types.h"
+
+#ifdef USE_THREADS
+
+#include "plat_thread.h"
+
+#else
+
+#define rh_atomic32(var) int32_t var
+#define rh_atomic_add(parent,var,val) (parent)->var += (val)
+#define rh_atomic_sub(parent,var,val) (parent)->var -= (val)
+#define rh_atomic_sub_testzero(parent,var,val) (((parent)->var -= (val)) == 0)
+#define rh_atomic_set(parent,var,val) (parent)->var = val
+#define rh_atomic_get(parent,var) ((parent)->var)
+
+#define rh_start_thread(func,data,name)
+#define rh_mutex(var)
+#define rh_mutex_init(var)
+#define rh_lock(lock)
+#define rh_unlock(lock)
+#define rh_mutex_del(var)
+
+#endif //USE_THREADS
+
+#endif //_THREAD_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/test.c	Wed May 13 00:47:40 2009 -0400
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include "builtin.h"
+#include "object.h"
+#include "integer.h"
+
+int main(int argc, char ** argv)
+{
+	returntype ret;
+	calldata cdata;
+	register_builtin_types();
+	cdata.params[0] = make_Int32(2);
+	cdata.params[1] = make_Int32(3);
+	cdata.num_params = 2;
+	ret = call_method(METHOD_ADD, &cdata);
+	while(ret == TAIL_RETURN)
+		ret = cdata.tail_func(&cdata);
+	if(ret == EXCEPTION_RETURN) {
+		puts("Exception!");
+		exit(-1);
+	}
+	printf("After METHOD_ADD: %d\n", ((_t_Int32 *)cdata.params[0])->num);
+	cdata.params[1] = make_Int32(1);
+	ret = call_method(METHOD_SUB, &cdata);
+	while(ret == TAIL_RETURN)
+		ret = cdata.tail_func(&cdata);
+	if(ret == EXCEPTION_RETURN) {
+		puts("Exception!");
+		exit(-1);
+	}
+	printf("After METHOD_ADD: %d\n", ((_t_Int32 *)cdata.params[0])->num);
+	return 0;
+}
+