mirror of
https://github.com/janet-lang/janet
synced 2024-12-25 07:50:27 +00:00
Modify some files. Also begin open addressing hash
dictionary for use in compiler. Might also move normal object to open addressing for less pressure on gc.
This commit is contained in:
parent
08319e62cb
commit
7cdf33eb90
2
Makefile
2
Makefile
@ -6,7 +6,7 @@ TARGET=interp
|
||||
PREFIX=/usr/local
|
||||
|
||||
# C sources
|
||||
HEADERS=vm.h ds.h compile.h parse.h value.h disasm.h datatypes.h gc.h
|
||||
HEADERS=vm.h ds.h compile.h parse.h value.h disasm.h datatypes.h gc.h util.h
|
||||
SOURCES=main.c parse.c value.c vm.c ds.c compile.c disasm.c gc.c
|
||||
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
|
||||
|
||||
|
34
compile.c
34
compile.c
@ -2,7 +2,7 @@
|
||||
#include "ds.h"
|
||||
#include "value.h"
|
||||
#include "vm.h"
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
|
||||
/* During compilation, FormOptions are passed to ASTs
|
||||
* as configuration options to allow for some optimizations. */
|
||||
@ -34,7 +34,7 @@ struct Slot {
|
||||
uint16_t index;
|
||||
/* A nil Slot should not be expected to contain real data. (ignore index).
|
||||
* Forms that have side effects but don't evaulate to
|
||||
* anything will try to return bil slots. */
|
||||
* anything will try to return nil slots. */
|
||||
uint16_t isNil : 1;
|
||||
/* A temp Slot is a Slot on the stack that does not
|
||||
* belong to a named local. They can be freed whenever,
|
||||
@ -170,7 +170,7 @@ static void compiler_free_local(GstCompiler *c, GstScope *scope, uint16_t slot)
|
||||
if (scope->heapSize >= scope->heapCapacity) {
|
||||
uint32_t newCap = 2 * scope->heapSize;
|
||||
uint16_t *newData = gst_alloc(c->vm, newCap * sizeof(uint16_t));
|
||||
memcpy(newData, scope->freeHeap, scope->heapSize * sizeof(uint16_t));
|
||||
gst_memcpy(newData, scope->freeHeap, scope->heapSize * sizeof(uint16_t));
|
||||
scope->freeHeap = newData;
|
||||
scope->heapCapacity = newCap;
|
||||
}
|
||||
@ -287,7 +287,7 @@ static void compiler_tracker_push(GstCompiler *c, SlotTracker *tracker, Slot slo
|
||||
if (tracker->count >= tracker->capacity) {
|
||||
uint32_t newCap = 2 * tracker->count;
|
||||
Slot *newData = gst_alloc(c->vm, newCap * sizeof(Slot));
|
||||
memcpy(newData, tracker->slots, tracker->count * sizeof(Slot));
|
||||
gst_memcpy(newData, tracker->slots, tracker->count * sizeof(Slot));
|
||||
tracker->slots = newData;
|
||||
tracker->capacity = newCap;
|
||||
}
|
||||
@ -536,34 +536,34 @@ static Slot compile_operator(GstCompiler *c, FormOptions opts, GstArray *form,
|
||||
|
||||
/* Math specials */
|
||||
static Slot compile_addition(GstCompiler *c, FormOptions opts, GstArray *form) {
|
||||
return compile_operator(c, opts, form, GST_OP_LD0, -1, GST_OP_ADD, -1, 0);
|
||||
return compile_operator(c, opts, form, -1, -1, GST_OP_ADD, -1, 0);
|
||||
}
|
||||
static Slot compile_subtraction(GstCompiler *c, FormOptions opts, GstArray *form) {
|
||||
return compile_operator(c, opts, form, GST_OP_LD0, -1, GST_OP_SUB, -1, 0);
|
||||
return compile_operator(c, opts, form, -1, -1, GST_OP_SUB, -1, 0);
|
||||
}
|
||||
static Slot compile_multiplication(GstCompiler *c, FormOptions opts, GstArray *form) {
|
||||
return compile_operator(c, opts, form, GST_OP_LD1, -1, GST_OP_MUL, -1, 0);
|
||||
return compile_operator(c, opts, form, -1, -1, GST_OP_MUL, -1, 0);
|
||||
}
|
||||
static Slot compile_division(GstCompiler *c, FormOptions opts, GstArray *form) {
|
||||
return compile_operator(c, opts, form, GST_OP_LD1, -1, GST_OP_DIV, -1, 0);
|
||||
return compile_operator(c, opts, form, -1, -1, GST_OP_DIV, -1, 0);
|
||||
}
|
||||
static Slot compile_equals(GstCompiler *c, FormOptions opts, GstArray *form) {
|
||||
return compile_operator(c, opts, form, GST_OP_TRU, GST_OP_TRU, GST_OP_EQL, -1, 0);
|
||||
return compile_operator(c, opts, form, -1, -1, GST_OP_EQL, -1, 0);
|
||||
}
|
||||
static Slot compile_lt(GstCompiler *c, FormOptions opts, GstArray *form) {
|
||||
return compile_operator(c, opts, form, GST_OP_TRU, GST_OP_TRU, GST_OP_LTN, -1, 0);
|
||||
return compile_operator(c, opts, form, -1, -1, GST_OP_LTN, -1, 0);
|
||||
}
|
||||
static Slot compile_lte(GstCompiler *c, FormOptions opts, GstArray *form) {
|
||||
return compile_operator(c, opts, form, GST_OP_TRU, GST_OP_TRU, GST_OP_LTE, -1, 0);
|
||||
return compile_operator(c, opts, form, -1, -1, GST_OP_LTE, -1, 0);
|
||||
}
|
||||
static Slot compile_gt(GstCompiler *c, FormOptions opts, GstArray *form) {
|
||||
return compile_operator(c, opts, form, GST_OP_TRU, GST_OP_TRU, GST_OP_LTN, -1, 1);
|
||||
return compile_operator(c, opts, form, -1, -1, GST_OP_LTN, -1, 1);
|
||||
}
|
||||
static Slot compile_gte(GstCompiler *c, FormOptions opts, GstArray *form) {
|
||||
return compile_operator(c, opts, form, GST_OP_TRU, GST_OP_TRU, GST_OP_LTE, -1, 1);
|
||||
return compile_operator(c, opts, form, -1, -1, GST_OP_LTE, -1, 1);
|
||||
}
|
||||
static Slot compile_not(GstCompiler *c, FormOptions opts, GstArray *form) {
|
||||
return compile_operator(c, opts, form, GST_OP_FLS, GST_OP_NOT, -1, -1, 0);
|
||||
return compile_operator(c, opts, form, -1, GST_OP_NOT, -1, -1, 0);
|
||||
}
|
||||
static Slot compile_get(GstCompiler *c, FormOptions opts, GstArray *form) {
|
||||
return compile_operator(c, opts, form, -1, -1, GST_OP_GET, -1, 0);
|
||||
@ -686,13 +686,13 @@ static GstFuncDef *compiler_gen_funcdef(GstCompiler *c, uint32_t lastNBytes, uin
|
||||
def->byteCodeLen = lastNBytes / 2;
|
||||
/* Copy the last chunk of bytes in the buffer into the new
|
||||
* memory for the function's byteCOde */
|
||||
memcpy(byteCode, buffer->data + buffer->count - lastNBytes, lastNBytes);
|
||||
gst_memcpy(byteCode, buffer->data + buffer->count - lastNBytes, lastNBytes);
|
||||
/* Remove the byteCode from the end of the buffer */
|
||||
buffer->count -= lastNBytes;
|
||||
/* Create the literals used by this function */
|
||||
if (scope->literalsArray->count) {
|
||||
def->literals = gst_alloc(c->vm, scope->literalsArray->count * sizeof(GstValue));
|
||||
memcpy(def->literals, scope->literalsArray->data,
|
||||
gst_memcpy(def->literals, scope->literalsArray->data,
|
||||
scope->literalsArray->count * sizeof(GstValue));
|
||||
} else {
|
||||
def->literals = NULL;
|
||||
@ -1267,7 +1267,7 @@ GstFunction *gst_compiler_compile(GstCompiler *c, GstValue form) {
|
||||
GstFunction *func = gst_alloc(c->vm, sizeof(GstFunction));
|
||||
if (envSize) {
|
||||
env->values = gst_alloc(c->vm, sizeof(GstValue) * envSize);
|
||||
memcpy(env->values, c->env->data, envSize * sizeof(GstValue));
|
||||
gst_memcpy(env->values, c->env->data, envSize * sizeof(GstValue));
|
||||
} else {
|
||||
env->values = NULL;
|
||||
}
|
||||
|
71
datatypes.h
71
datatypes.h
@ -197,40 +197,43 @@ struct GstCompiler {
|
||||
|
||||
/* Bytecode */
|
||||
enum GstOpCode {
|
||||
GST_OP_ADD = 0, /* 0x0000 */
|
||||
GST_OP_SUB, /* 0x0001 */
|
||||
GST_OP_MUL, /* 0x0002 */
|
||||
GST_OP_DIV, /* 0x0003 */
|
||||
GST_OP_NOT, /* 0x0004 */
|
||||
GST_OP_LD0, /* 0x0005 */
|
||||
GST_OP_LD1, /* 0x0006 */
|
||||
GST_OP_FLS, /* 0x0007 */
|
||||
GST_OP_TRU, /* 0x0008 */
|
||||
GST_OP_NIL, /* 0x0009 */
|
||||
GST_OP_I16, /* 0x000a */
|
||||
GST_OP_UPV, /* 0x000b */
|
||||
GST_OP_JIF, /* 0x000c */
|
||||
GST_OP_JMP, /* 0x000d */
|
||||
GST_OP_CAL, /* 0x000e */
|
||||
GST_OP_RET, /* 0x000f */
|
||||
GST_OP_SUV, /* 0x0010 */
|
||||
GST_OP_CST, /* 0x0011 */
|
||||
GST_OP_I32, /* 0x0012 */
|
||||
GST_OP_F64, /* 0x0013 */
|
||||
GST_OP_MOV, /* 0x0014 */
|
||||
GST_OP_CLN, /* 0x0015 */
|
||||
GST_OP_EQL, /* 0x0016 */
|
||||
GST_OP_LTN, /* 0x0017 */
|
||||
GST_OP_LTE, /* 0x0018 */
|
||||
GST_OP_ARR, /* 0x0019 */
|
||||
GST_OP_DIC, /* 0x001a */
|
||||
GST_OP_TCL, /* 0x001b */
|
||||
GST_OP_RTN, /* 0x0020 */
|
||||
GST_OP_SET, /* 0x0021 */
|
||||
GST_OP_GET, /* 0x0022 */
|
||||
GST_OP_ERR, /* 0x0023 */
|
||||
GST_OP_TRY, /* 0x0024 */
|
||||
GST_OP_UTY /* 0x0025 */
|
||||
GST_OP_ADD = 0, /* Addition */
|
||||
GST_OP_SUB, /* Subtraction */
|
||||
GST_OP_MUL, /* Multiplication */
|
||||
GST_OP_DIV, /* Division */
|
||||
GST_OP_MOD, /* Modulo division */
|
||||
GST_OP_EXP, /* Exponentiation */
|
||||
GST_OP_CCT, /* Concatenation */
|
||||
GST_OP_NOT, /* Invert */
|
||||
GST_OP_LEN, /* Length */
|
||||
GST_OP_TYP, /* Type */
|
||||
GST_OP_FLS,
|
||||
GST_OP_TRU,
|
||||
GST_OP_NIL,
|
||||
GST_OP_I16,
|
||||
GST_OP_UPV,
|
||||
GST_OP_JIF,
|
||||
GST_OP_JMP,
|
||||
GST_OP_CAL,
|
||||
GST_OP_RET,
|
||||
GST_OP_SUV,
|
||||
GST_OP_CST,
|
||||
GST_OP_I32,
|
||||
GST_OP_F64,
|
||||
GST_OP_MOV,
|
||||
GST_OP_CLN,
|
||||
GST_OP_EQL,
|
||||
GST_OP_LTN,
|
||||
GST_OP_LTE,
|
||||
GST_OP_ARR,
|
||||
GST_OP_DIC,
|
||||
GST_OP_TCL,
|
||||
GST_OP_RTN,
|
||||
GST_OP_SET,
|
||||
GST_OP_GET,
|
||||
GST_OP_ERR,
|
||||
GST_OP_TRY,
|
||||
GST_OP_UTY
|
||||
};
|
||||
|
||||
#endif
|
||||
|
147
dict.c
Normal file
147
dict.c
Normal file
@ -0,0 +1,147 @@
|
||||
#include "datatypes.h"
|
||||
#include "util.h"
|
||||
#include "value.h"
|
||||
|
||||
#define GST_DICT_FLAG_OCCUPIED 1
|
||||
#define GST_DICT_FLAG_TOMBSTONE 2
|
||||
|
||||
typedef struct GstDictBucket GstDictBucket;
|
||||
struct GstDictBucket {
|
||||
GstValue key;
|
||||
GstValue value;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
typedef struct GstDict GstDict;
|
||||
struct GstDict {
|
||||
uint32_t capacity;
|
||||
uint32_t count;
|
||||
GstDictBucket *buckets;
|
||||
};
|
||||
|
||||
/* Initialize a dictionary */
|
||||
GstDict *gst_dict_init(GstDict *dict, uint32_t capacity) {
|
||||
GstDictBucket *buckets = gst_raw_calloc(1, sizeof(GstDictBucket) * capacity);
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
dict->buckets = buckets;
|
||||
dict->capacity = capacity;
|
||||
dict->count = 0;
|
||||
return dict;
|
||||
}
|
||||
|
||||
/* Deinitialize a dictionary */
|
||||
GstDict *gst_dict_free(GstDict *dict) {
|
||||
gst_raw_free(dict->buckets);
|
||||
}
|
||||
|
||||
/* Rehash a dictionary */
|
||||
GstDict *gst_dict_rehash(GstDict *dict, uint32_t newCapacity) {
|
||||
GstDictBucket *newBuckets = gst_raw_calloc(1, sizeof(GstDictBucket) * newCapacity);
|
||||
GstDictBucket *buckets = dict->buckets;
|
||||
uint32_t i, j;
|
||||
if (newBuckets == NULL)
|
||||
return NULL;
|
||||
for (i = 0; i < dict->capacity; ++i) {
|
||||
int index;
|
||||
if (!(buckets[i].flags & GST_DICT_FLAG_OCCUPIED)) continue;
|
||||
if (buckets[i].flags & GST_DICT_FLAG_TOMBSTONE) continue;
|
||||
index = gst_hash(buckets[i].key) % newCapacity;
|
||||
for (j = index; j < dict->capacity; ++j) {
|
||||
if (newBuckets[j].flags & GST_DICT_FLAG_OCCUPIED) continue;
|
||||
newBuckets[j] = buckets[i];
|
||||
goto done;
|
||||
}
|
||||
for (j = 0; j < index; ++j) {
|
||||
if (newBuckets[j].flags & GST_DICT_FLAG_OCCUPIED) continue;
|
||||
newBuckets[j] = buckets[i];
|
||||
goto done;
|
||||
}
|
||||
/* Error - could not rehash a bucket - this should never happen */
|
||||
gst_raw_free(newBuckets);
|
||||
return NULL;
|
||||
/* Successfully rehashed bucket */
|
||||
done:
|
||||
}
|
||||
dict->capacity = newCapacity;
|
||||
return dict;
|
||||
}
|
||||
|
||||
/* Find a bucket with a given key */
|
||||
static int gst_dict_find(GstDict *dict, GstValue key, GstDictBucket **out) {
|
||||
uint32_t index, i;
|
||||
GstDictBucket *buckets = dict->buckets;
|
||||
index = gst_hash(key) % dict->capacity;
|
||||
for (i = index; i < dict->capacity; ++i) {
|
||||
if (buckets[i].flags & GST_DICT_FLAGS_TOMBSTONE) continue;
|
||||
if (!(buckets[i].flags & GST_DICT_FLAGS_OCCUPIED)) continue;
|
||||
if (!gst_equals(key, buckets[i].key)) continue;
|
||||
*out = buckets + i;
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; i < index; ++i) {
|
||||
if (buckets[i].flags & GST_DICT_FLAGS_TOMBSTONE) continue;
|
||||
if (!(buckets[i].flags & GST_DICT_FLAGS_OCCUPIED)) continue;
|
||||
if (!gst_equals(key, buckets[i].key)) continue;
|
||||
*out = buckets + i;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get item from dictionary */
|
||||
int gst_dict_get(GstDict *dict, GstValue key, GstValue *value) {
|
||||
GstDictBucket *bucket;
|
||||
int found = gst_dict_find(dict, key, &bucket);
|
||||
if (found)
|
||||
*value = bucket->value;
|
||||
return found;
|
||||
}
|
||||
|
||||
/* Add item to dictionary */
|
||||
GstDict *gst_dict_put(GstDict *dict, GstValue key, GstValue value) {
|
||||
i /* Check if we need to increase capacity. The load factor is low
|
||||
* because we are using linear probing */
|
||||
uint32_t index, i;
|
||||
uint32_t newCap = dict->count * 2 + 1;
|
||||
GstBucket *buckets;
|
||||
if (newCap > dict->capacity) {
|
||||
dict = gst_dict_rehash(dict, newCap);
|
||||
if (!dict) return dict;
|
||||
}
|
||||
index = gst_hash(key) % dict->capacity;
|
||||
buckets = dict->buckets;
|
||||
for (i = index; i < dict->capacity; ++i) {
|
||||
if ((buckets[i].flags & GST_DICT_FLAGS_TOMBSTONE) ||
|
||||
!(buckets[i].flags & GST_DICT_FLAGS_OCCUPIED))
|
||||
continue;
|
||||
dict->buckets[i].key = key;
|
||||
dict->buckets[i].value = value;
|
||||
dict->buckets[i].flags &= GST_DICT_FLAGS_OCCUPIED;
|
||||
dict->count++;
|
||||
return dict;
|
||||
}
|
||||
for (i = 0; i < index; ++i) {
|
||||
if ((buckets[i].flags & GST_DICT_FLAGS_TOMBSTONE) ||
|
||||
!(buckets[i].flags & GST_DICT_FLAGS_OCCUPIED))
|
||||
continue;
|
||||
dict->buckets[i].key = key;
|
||||
dict->buckets[i].value = value;
|
||||
dict->buckets[i].flags &= GST_DICT_FLAGS_OCCUPIED;
|
||||
dict->count++;
|
||||
return dict;
|
||||
}
|
||||
/* Error should never get here */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Remove item from dictionary */
|
||||
int gst_dict_remove(GstDict *dict, GstValue key) {
|
||||
GstDictBucket *bucket;
|
||||
int found = gst_dict_find(dict, key, &bucket);
|
||||
if (found) {
|
||||
bucket->flags |= GST_DICT_FLAGS_TOMBSTONE;
|
||||
dict->count--;
|
||||
}
|
||||
return found;
|
||||
}
|
9
disasm.c
9
disasm.c
@ -68,6 +68,9 @@ void gst_dasm(FILE * out, uint16_t *byteCode, uint32_t len) {
|
||||
|
||||
while (current < end) {
|
||||
switch (*current) {
|
||||
default:
|
||||
current += dasm_fixed_op(out, current, "unknown", 0);
|
||||
break;
|
||||
case GST_OP_ADD:
|
||||
current += dasm_fixed_op(out, current, "add", 3);
|
||||
break;
|
||||
@ -83,12 +86,6 @@ void gst_dasm(FILE * out, uint16_t *byteCode, uint32_t len) {
|
||||
case GST_OP_NOT:
|
||||
current += dasm_fixed_op(out, current, "not", 2);
|
||||
break;
|
||||
case GST_OP_LD0:
|
||||
current += dasm_fixed_op(out, current, "load0", 1);
|
||||
break;
|
||||
case GST_OP_LD1:
|
||||
current += dasm_fixed_op(out, current, "load1", 1);
|
||||
break;
|
||||
case GST_OP_FLS:
|
||||
current += dasm_fixed_op(out, current, "loadFalse", 1);
|
||||
break;
|
||||
|
10
ds.c
10
ds.c
@ -1,7 +1,7 @@
|
||||
#include "util.h"
|
||||
#include "ds.h"
|
||||
#include "value.h"
|
||||
#include "vm.h"
|
||||
#include <string.h>
|
||||
|
||||
/****/
|
||||
/* Buffer functions */
|
||||
@ -23,7 +23,7 @@ void gst_buffer_ensure(Gst *vm, GstBuffer *buffer, uint32_t capacity) {
|
||||
uint8_t * newData;
|
||||
if (capacity <= buffer->capacity) return;
|
||||
newData = gst_alloc(vm, capacity * sizeof(uint8_t));
|
||||
memcpy(newData, buffer->data, buffer->count * sizeof(uint8_t));
|
||||
gst_memcpy(newData, buffer->data, buffer->count * sizeof(uint8_t));
|
||||
buffer->data = newData;
|
||||
buffer->capacity = capacity;
|
||||
}
|
||||
@ -51,7 +51,7 @@ void gst_buffer_append(Gst *vm, GstBuffer *buffer, uint8_t *string, uint32_t len
|
||||
if (newSize > buffer->capacity) {
|
||||
gst_buffer_ensure(vm, buffer, 2 * newSize);
|
||||
}
|
||||
memcpy(buffer->data + buffer->count, string, length);
|
||||
gst_memcpy(buffer->data + buffer->count, string, length);
|
||||
buffer->count = newSize;
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ uint8_t *gst_buffer_to_string(Gst *vm, GstBuffer *buffer) {
|
||||
data += 2 * sizeof(uint32_t);
|
||||
gst_string_length(data) = buffer->count;
|
||||
gst_string_hash(data) = 0;
|
||||
memcpy(data, buffer->data, buffer->count * sizeof(uint8_t));
|
||||
gst_memcpy(data, buffer->data, buffer->count * sizeof(uint8_t));
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ void gst_array_ensure(Gst *vm, GstArray *array, uint32_t capacity) {
|
||||
GstValue *newData;
|
||||
if (capacity <= array->capacity) return;
|
||||
newData = gst_alloc(vm, capacity * sizeof(GstValue));
|
||||
memcpy(newData, array->data, array->capacity * sizeof(GstValue));
|
||||
gst_memcpy(newData, array->data, array->capacity * sizeof(GstValue));
|
||||
array->data = newData;
|
||||
array->capacity = capacity;
|
||||
}
|
||||
|
10
gc.c
10
gc.c
@ -1,7 +1,7 @@
|
||||
#include "datatypes.h"
|
||||
#include "gc.h"
|
||||
#include "vm.h"
|
||||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
|
||||
/* The metadata header associated with an allocated block of memory */
|
||||
#define gc_header(mem) ((GCMemoryHeader *)(mem) - 1)
|
||||
@ -160,7 +160,7 @@ void gst_sweep(Gst *vm) {
|
||||
} else {
|
||||
vm->blocks = next;
|
||||
}
|
||||
free(current);
|
||||
gst_raw_free(current);
|
||||
} else {
|
||||
previous = current;
|
||||
}
|
||||
@ -187,13 +187,13 @@ static void *gst_alloc_prepare(Gst *vm, char *rawBlock, uint32_t size) {
|
||||
/* Allocate some memory that is tracked for garbage collection */
|
||||
void *gst_alloc(Gst *vm, uint32_t size) {
|
||||
uint32_t totalSize = size + sizeof(GCMemoryHeader);
|
||||
return gst_alloc_prepare(vm, malloc(totalSize), totalSize);
|
||||
return gst_alloc_prepare(vm, gst_raw_alloc(totalSize), totalSize);
|
||||
}
|
||||
|
||||
/* Allocate some zeroed memory that is tracked for garbage collection */
|
||||
void *gst_zalloc(Gst *vm, uint32_t size) {
|
||||
uint32_t totalSize = size + sizeof(GCMemoryHeader);
|
||||
return gst_alloc_prepare(vm, calloc(1, totalSize), totalSize);
|
||||
return gst_alloc_prepare(vm, gst_raw_calloc(1, totalSize), totalSize);
|
||||
}
|
||||
|
||||
/* Run garbage collection */
|
||||
@ -222,7 +222,7 @@ void gst_clear_memory(Gst *vm) {
|
||||
GCMemoryHeader *current = vm->blocks;
|
||||
while (current) {
|
||||
GCMemoryHeader *next = current->next;
|
||||
free(current);
|
||||
gst_raw_free(current);
|
||||
current = next;
|
||||
}
|
||||
vm->blocks = NULL;
|
||||
|
5
parse.c
5
parse.c
@ -1,7 +1,4 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
#include "util.h"
|
||||
#include "datatypes.h"
|
||||
#include "ds.h"
|
||||
#include "parse.h"
|
||||
|
34
util.h
Normal file
34
util.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef util_h_INCLUDED
|
||||
#define util_h_INCLUDED
|
||||
|
||||
/* Memcpy for moving memory */
|
||||
#ifndef gst_memcpy
|
||||
#include <string.h>
|
||||
#define gst_memcpy memcpy
|
||||
#endif
|
||||
|
||||
/* Allocation */
|
||||
#ifndef gst_raw_alloc
|
||||
#include <stdlib.h>
|
||||
#define gst_raw_alloc malloc
|
||||
#endif
|
||||
|
||||
/* Clear allocation */
|
||||
#ifndef gst_raw_calloc
|
||||
#include <stdlib.h>
|
||||
#define gst_raw_calloc calloc
|
||||
#endif
|
||||
|
||||
/* Free */
|
||||
#ifndef gst_raw_free
|
||||
#include <stdlib.h>
|
||||
#define gst_raw_free free
|
||||
#endif
|
||||
|
||||
/* Null */
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#endif // util_h_INCLUDED
|
||||
|
8
value.c
8
value.c
@ -1,9 +1,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
#include "value.h"
|
||||
#include "ds.h"
|
||||
#include "vm.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* Boolean truth definition */
|
||||
int gst_truthy(GstValue v) {
|
||||
@ -15,7 +14,7 @@ static uint8_t * load_cstring(Gst *vm, const char *string, uint32_t len) {
|
||||
data += 2 * sizeof(uint32_t);
|
||||
gst_string_hash(data) = 0;
|
||||
gst_string_length(data) = len;
|
||||
memcpy(data, string, len);
|
||||
gst_memcpy(data, string, len);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -30,6 +29,7 @@ static uint8_t * number_to_string(Gst *vm, GstNumber x) {
|
||||
static const uint32_t SIZE = 20;
|
||||
uint8_t *data = gst_alloc(vm, SIZE + 2 * sizeof(uint32_t));
|
||||
data += 2 * sizeof(uint32_t);
|
||||
/* TODO - not depend on stdio */
|
||||
snprintf((char *) data, SIZE, "%.17g", x);
|
||||
gst_string_hash(data) = 0;
|
||||
gst_string_length(data) = strlen((char *) data);
|
||||
|
30
vm.c
30
vm.c
@ -1,7 +1,5 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "vm.h"
|
||||
#include "util.h"
|
||||
#include "value.h"
|
||||
#include "ds.h"
|
||||
#include "gc.h"
|
||||
@ -51,7 +49,7 @@ int gst_start(Gst *vm) {
|
||||
frame.env->thread = NULL;
|
||||
frame.env->stackOffset = frame.size;
|
||||
frame.env->values = gst_alloc(vm, sizeof(GstValue) * frame.size);
|
||||
memcpy(frame.env->values,
|
||||
gst_memcpy(frame.env->values,
|
||||
thread.data + thread.count,
|
||||
frame.size * sizeof(GstValue));
|
||||
}
|
||||
@ -112,20 +110,6 @@ int gst_start(Gst *vm) {
|
||||
pc += 3;
|
||||
break;
|
||||
|
||||
case GST_OP_LD0: /* Load 0 */
|
||||
temp.type = GST_NUMBER;
|
||||
temp.data.number = 0;
|
||||
stack[pc[1]] = temp;
|
||||
pc += 2;
|
||||
break;
|
||||
|
||||
case GST_OP_LD1: /* Load 1 */
|
||||
temp.type = GST_NUMBER;
|
||||
temp.data.number = 1;
|
||||
stack[pc[1]] = temp;
|
||||
pc += 2;
|
||||
break;
|
||||
|
||||
case GST_OP_FLS: /* Load False */
|
||||
temp.type = GST_BOOLEAN;
|
||||
temp.data.boolean = 0;
|
||||
@ -224,7 +208,7 @@ int gst_start(Gst *vm) {
|
||||
if (nextCount + locals > thread.capacity) {
|
||||
uint32_t newCap = (nextCount + locals) * 2;
|
||||
GstValue *newData = gst_alloc(vm, sizeof(GstValue) * newCap);
|
||||
memcpy(newData, thread.data, thread.capacity * sizeof(GstValue));
|
||||
gst_memcpy(newData, thread.data, thread.capacity * sizeof(GstValue));
|
||||
thread.data = newData;
|
||||
thread.capacity = newCap;
|
||||
}
|
||||
@ -388,7 +372,7 @@ int gst_start(Gst *vm) {
|
||||
frame.env->thread = NULL;
|
||||
frame.env->stackOffset = frame.size;
|
||||
frame.env->values = gst_alloc(vm, sizeof(GstValue) * frame.size);
|
||||
memcpy(frame.env->values,
|
||||
gst_memcpy(frame.env->values,
|
||||
thread.data + thread.count,
|
||||
frame.size * sizeof(GstValue));
|
||||
frame.env = NULL;
|
||||
@ -415,7 +399,7 @@ int gst_start(Gst *vm) {
|
||||
if (totalCapacity > thread.capacity) {
|
||||
uint32_t newCap = totalCapacity * 2;
|
||||
GstValue *newData = gst_alloc(vm, sizeof(GstValue) * newCap);
|
||||
memcpy(newData, thread.data, thread.capacity * sizeof(GstValue));
|
||||
gst_memcpy(newData, thread.data, thread.capacity * sizeof(GstValue));
|
||||
thread.data = newData;
|
||||
thread.capacity = newCap;
|
||||
stack = thread.data + thread.count;
|
||||
@ -426,7 +410,7 @@ int gst_start(Gst *vm) {
|
||||
stack[workspace + i] = stack[pc[3 + i]];
|
||||
|
||||
/* Copy the end of the stack to the parameter position */
|
||||
memcpy(stack, stack + workspace, arity * sizeof(GstValue));
|
||||
gst_memcpy(stack, stack + workspace, arity * sizeof(GstValue));
|
||||
|
||||
/* Update the stack frame */
|
||||
frame.callee = temp;
|
||||
@ -492,7 +476,7 @@ int gst_start(Gst *vm) {
|
||||
frame.env->thread = NULL;
|
||||
frame.env->stackOffset = frame.size;
|
||||
frame.env->values = gst_alloc(vm, sizeof(GstValue) * frame.size);
|
||||
memcpy(frame.env->values,
|
||||
gst_memcpy(frame.env->values,
|
||||
thread.data + thread.count,
|
||||
frame.size * sizeof(GstValue));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user