From 8cdc0610e340aa047ebdfc9bd81b6039cf52a553 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Tue, 14 Feb 2017 20:45:34 -0500 Subject: [PATCH] Reintroduce a separate Thread objects for threads instead of using arrays. --- datatypes.h | 47 +++++++++++++++++++++++++++++++---------------- ds.c | 3 +++ ds.h | 5 +++++ vm.c | 43 +++++++++++++++++++++++++++++-------------- 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/datatypes.h b/datatypes.h index 6891da81..9fee407d 100644 --- a/datatypes.h +++ b/datatypes.h @@ -4,10 +4,6 @@ #include #include -#define THREAD_STATUS_ALIVE 0 -#define THREAD_STATUS_DEAD 1 -#define THREAD_STATUS_PENDING 2 - typedef enum Type { TYPE_NIL = 0, TYPE_NUMBER, @@ -39,6 +35,7 @@ typedef struct Parser Parser; typedef struct ParseState ParseState; typedef struct Scope Scope; typedef struct Compiler Compiler; +typedef struct Thread Thread; typedef struct StackFrame StackFrame; union ValueData { @@ -49,28 +46,49 @@ union ValueData { Buffer * buffer; Dictionary * dict; Func * func; + Thread * thread; void * pointer; CFunction cfunction; uint16_t u16[4]; uint8_t u8[8]; } data; +struct Value { + Type type; + ValueData data; +}; + +struct Thread { + uint32_t count; + uint32_t capacity; + Value * data; + enum { + THREAD_PENDING = 0, + THREAD_ALIVE, + TRHEAD_DEAD + } status; +}; + struct Array { uint32_t count; uint32_t capacity; Value * data; + uint32_t flags; }; struct Buffer { uint32_t count; uint32_t capacity; uint8_t * data; + uint32_t flags; }; struct Dictionary { uint32_t count; uint32_t capacity; DictBucket ** buckets; + uint32_t flags; + Value meta; }; struct DictionaryIterator { @@ -89,7 +107,7 @@ struct FuncDef { }; struct FuncEnv { - Array * thread; /* When nil, index the local values */ + Thread * thread; /* When nil, index the local values */ uint32_t stackOffset; /* Used as environment size when off stack */ Value * values; }; @@ -100,11 +118,6 @@ struct Func { Func * parent; }; -struct Value { - Type type; - ValueData data; -}; - struct DictBucket { Value key; Value value; @@ -129,21 +142,19 @@ struct VM { uint32_t lock : 31; /* Thread */ uint16_t * pc; - Array * thread; + Thread * thread; Value * base; StackFrame * frame; /* Return state */ const char * error; jmp_buf jump; Value ret; /* Returned value from VMStart */ + /* Object definitions */ + Value metas[TYPE_DICTIONARY]; }; /* Parsing */ -#define PARSER_PENDING 0 -#define PARSER_FULL 1 -#define PARSER_ERROR -1 - struct Parser { VM * vm; const char * error; @@ -152,7 +163,11 @@ struct Parser { uint32_t count; uint32_t cap; uint32_t index; - uint32_t status; + enum { + PARSER_PENDING = 0, + PARSER_FULL, + PARSER_ERROR + } status; }; /* Compiling */ diff --git a/ds.c b/ds.c index ebc358b4..794275d5 100644 --- a/ds.c +++ b/ds.c @@ -14,6 +14,7 @@ Buffer * BufferNew(VM * vm, uint32_t capacity) { buffer->data = data; buffer->count = 0; buffer->capacity = capacity; + buffer->flags = 0; return buffer; } @@ -75,6 +76,7 @@ Array * ArrayNew(VM * vm, uint32_t capacity) { array->data = data; array->count = 0; array->capacity = capacity; + array->flags = 0; return array; } @@ -154,6 +156,7 @@ Dictionary * DictNew(VM * vm, uint32_t capacity) { dict->buckets = buckets; dict->capacity = capacity; dict->count = 0; + dict->flags = 0; return dict; } diff --git a/ds.h b/ds.h index 06257c5e..c7f7b2e5 100644 --- a/ds.h +++ b/ds.h @@ -3,6 +3,11 @@ #include "datatypes.h" +/* + * Data type flags + */ +#define DS_LOCKED 0x01 + /****/ /* Buffer functions */ /****/ diff --git a/vm.c b/vm.c index fc9a847d..8a155fc3 100644 --- a/vm.c +++ b/vm.c @@ -15,7 +15,7 @@ static const char VMS_EXPECTED_NUMBER_LOP[] = "Expected left operand to be numbe #define FRAME_SIZE ((sizeof(StackFrame) + sizeof(Value) - 1) / sizeof(Value)) /* Get the stack frame pointer for a thread */ -static StackFrame * ThreadFrame(Array * thread) { +static StackFrame * ThreadFrame(Thread * thread) { return (StackFrame *)(thread->data + thread->count - FRAME_SIZE); } @@ -39,7 +39,7 @@ static void VMMarkFuncEnv(VM * vm, FuncEnv * env) { GCHeader(env)->color = vm->black; if (env->thread) { temp.type = TYPE_THREAD; - temp.data.array = env->thread; + temp.data.thread = env->thread; VMMark(vm, &temp); } if (env->values) { @@ -117,8 +117,8 @@ static void VMMark(VM * vm, Value * x) { break; case TYPE_THREAD: - if (GCHeader(x->data.array)->color != vm->black) { - Array * thread = x->data.array; + if (GCHeader(x->data.thread)->color != vm->black) { + Thread * thread = x->data.thread; StackFrame * frame = (StackFrame *)thread->data; StackFrame * end = ThreadFrame(thread); GCHeader(thread)->color = vm->black; @@ -220,7 +220,7 @@ void VMCollect(VM * vm) { if (vm->thread) { Value thread; thread.type = TYPE_THREAD; - thread.data.array = vm->thread; + thread.data.thread = vm->thread; VMMark(vm, &thread); } VMMark(vm, &vm->ret); @@ -234,8 +234,19 @@ void VMMaybeCollect(VM * vm) { VMCollect(vm); } +/* Ensure that a thread has enough space in it */ +static void ThreadEnsure(VM * vm, Thread * thread, uint32_t size) { + if (size > thread->capacity) { + uint32_t newCap = size * 2; + Value * newData = VMAlloc(vm, sizeof(Value) * newCap); + memcpy(newData, thread->data, thread->capacity * sizeof(Value)); + thread->data = newData; + thread->capacity = newCap; + } +} + /* Push a stack frame onto a thread */ -static void VMThreadPush(VM * vm, Array * thread, Value callee, uint32_t size) { +static void VMThreadPush(VM * vm, Thread * thread, Value callee, uint32_t size) { uint16_t oldSize; uint32_t nextCount, i; StackFrame * frame; @@ -246,7 +257,7 @@ static void VMThreadPush(VM * vm, Array * thread, Value callee, uint32_t size) { oldSize = 0; } nextCount = thread->count + oldSize + FRAME_SIZE; - ArrayEnsure(vm, thread, nextCount + size); + ThreadEnsure(vm, thread, nextCount + size); thread->count = nextCount; /* Ensure values start out as nil so as to not confuse * the garabage collector */ @@ -268,7 +279,7 @@ static void VMThreadSplitStack(VM * vm) { FuncEnv * env = frame->env; /* Check for closures */ if (env) { - Array * thread = vm->thread; + Thread * thread = vm->thread; uint32_t size = frame->size; env->thread = NULL; env->stackOffset = size; @@ -279,7 +290,7 @@ static void VMThreadSplitStack(VM * vm) { /* Pop the top-most stack frame from stack */ static void VMThreadPop(VM * vm) { - Array * thread = vm->thread; + Thread * thread = vm->thread; StackFrame * frame = vm->frame; uint32_t delta = FRAME_SIZE + frame->prevSize; if (thread->count) { @@ -335,7 +346,7 @@ static void VMReturn(VM * vm, Value ret) { /* Implementation of the opcode for function calls */ static void VMCallOp(VM * vm) { - Array * thread = vm->thread; + Thread * thread = vm->thread; Value callee = vm->base[vm->pc[1]]; uint32_t arity = vm->pc[3]; uint32_t oldCount = thread->count; @@ -371,7 +382,7 @@ static void VMCallOp(VM * vm) { /* Implementation of the opcode for tail calls */ static void VMTailCallOp(VM * vm) { - Array * thread = vm->thread; + Thread * thread = vm->thread; Value callee = vm->base[vm->pc[1]]; uint32_t arity = vm->pc[2]; uint16_t newFrameSize, currentFrameSize; @@ -388,7 +399,7 @@ static void VMTailCallOp(VM * vm) { } /* Ensure stack has enough space for copies of arguments */ currentFrameSize = vm->frame->size; - ArrayEnsure(vm, thread, thread->count + currentFrameSize + arity); + ThreadEnsure(vm, thread, thread->count + currentFrameSize + arity); vm->base = thread->data + thread->count; /* Copy the arguments into the extra space */ for (i = 0; i < arity; ++i) { @@ -416,7 +427,7 @@ static void VMTailCallOp(VM * vm) { /* Instantiate a closure */ static Value VMMakeClosure(VM * vm, uint16_t literal) { - Array * thread = vm->thread; + Thread * thread = vm->thread; if (vm->frame->callee.type != TYPE_FUNCTION) { VMError(vm, EXPECTED_FUNCTION); } else { @@ -767,7 +778,11 @@ void VMInit(VM * vm) { /* Load a function into the VM. The function will be called with * no arguments when run */ void VMLoad(VM * vm, Value func) { - Array * thread = ArrayNew(vm, 100); + uint32_t startCapacity = 100; + Thread * thread = VMAlloc(vm, sizeof(Thread)); + thread->data = VMAlloc(vm, sizeof(Value) * startCapacity); + thread->capacity = startCapacity; + thread->count = 0; vm->thread = thread; if (func.type == TYPE_FUNCTION) { Func * fn = func.data.func;