commit 363896004c2e541fecb8d0cf60b1f5408720a9fe parent 1432b7f51653fdf3c317735633cee91517f103d6 Author: Paul Longtine <paullongtine@gmail.com> Date: Wed Apr 27 14:17:01 2016 Started work on getting objects implemented. This is a breaking change, runtime needs some love still. Diffstat: doc/SPECIFICATION | 23 +++--- src/lc/parser.py | 1 +- src/lc/test_files/fibb.ti | 4 +- src/vm/Makefile | 2 +- src/vm/inc/ins_def.h | 8 +- src/vm/inc/ins_mdata.h | 27 +++---- src/vm/inc/ns.h | 19 +++++- src/vm/inc/object.h | 26 +++++++- src/vm/inc/proc.h | 8 +-- src/vm/inc/rt.h | 35 +--------- src/vm/inc/var.h | 62 ++++++++++------ src/vm/src/ins_def.c | 130 +++++++++++++++++++++++++++++----- src/vm/src/ns.c | 48 +++++++++++++- src/vm/src/object.c | 29 ++++++++- src/vm/src/proc.c | 12 +--- src/vm/src/rt.c | 10 ++- src/vm/src/stk.c | 4 +- src/vm/src/var.c | 72 +++++++++++++++++++- src/vm/tests/cases/bc/bytecode | Bin 87 -> 0 bytes src/vm/tests/cases/bc/expected_output | 12 +-- src/vm/tests/cases/program_fibb/fibb | Bin 87 -> 0 bytes src/vm/tests/cases/stk/expected_output | 24 +++--- 22 files changed, 413 insertions(+), 143 deletions(-)
diff --git a/doc/SPECIFICATION b/doc/SPECIFICATION @@ -20,16 +20,17 @@ are deemed inferior. 2 TYPE - A `type` type 3 PLIST - Parameter list 4 FUNC - Function - 5 OBJECT - Object/Class - 6 G_PTR - Generic pointer - 7 G_INT - Generic integer - 8 G_FLOAT - Generic double - 9 G_CHAR - Generic character -10 G_STR - Generic string -11 S_ARRAY - Static array -12 D_ARRAY - Dynamic array -13 H_TABLE - Hashtable -14 G_FIFO - Stack + 5 OBJBLDR - Object builder + 6 OBJECT - Object/Class + 7 G_PTR - Generic pointer + 8 G_INT - Generic integer + 9 G_FLOAT - Generic double +10 G_CHAR - Generic character +11 G_STR - Generic string +12 S_ARRAY - Static array +13 D_ARRAY - Dynamic array +14 H_TABLE - Hashtable +15 G_FIFO - Stack RUNTIME @@ -296,6 +297,8 @@ FF DEFUN N<ref> S<type> D<args> - Un-funs everything. no, no- it defines a FE DECLASS N<ref> D<args> - Defines a class. TBI +F2 ENDCLASS - End of class block + F1 NEW N<ref> - Instantiates class TBI F0 RETURN - Returns from function diff --git a/src/lc/parser.py b/src/lc/parser.py @@ -43,6 +43,7 @@ class Parser(): "_type", "_plist", "_sub", + "objbldr", "object", "int", "float", diff --git a/src/lc/test_files/fibb.ti b/src/lc/test_files/fibb.ti @@ -1,7 +1,5 @@ func fibo(int limit) -> void: { - string thing = "starting this shit yo"; - print thing; int a = 0; int b = 1; @@ -13,3 +11,5 @@ func fibo(int limit) -> void: print a; } } + +fibo(1000); diff --git a/src/vm/Makefile b/src/vm/Makefile @@ -14,6 +14,7 @@ DEPS = $(INC_DIR)/is_mdata.h \ var_ops.h \ stk.h \ ns.h \ + object.h \ pc.h \ rt.h \ ins_def.h \ @@ -27,6 +28,7 @@ OBJ = $(SRC_DIR)/main.o \ $(SRC_DIR)/var_ops.o \ $(SRC_DIR)/stk.o \ $(SRC_DIR)/ns.o \ + $(SRC_DIR)/object.o \ $(SRC_DIR)/rt.o \ $(SRC_DIR)/ins_def.o \ $(SRC_DIR)/pc.o \ diff --git a/src/vm/inc/ins_def.h b/src/vm/inc/ins_def.h @@ -98,14 +98,14 @@ void _ins_def_ELSE (rt_t*, bc_cont*); void _ins_def_DONE (rt_t*, bc_cont*); void _ins_def_CALL (rt_t*, bc_cont*); -void _ins_def_PUSH (rt_t*, bc_cont*); -void _ins_def_DEL (rt_t*, bc_cont*); -void _ins_def_GET (rt_t*, bc_cont*); -void _ins_def_GETP (rt_t*, bc_cont*); +void _ins_def_GETN (rt_t*, bc_cont*); void _ins_def_CALLM (rt_t*, bc_cont*); +void _ins_def_INDEXO (rt_t*, bc_cont*); +void _ins_def_MODO (rt_t*, bc_cont*); void _ins_def_RETURN (rt_t*, bc_cont*); void _ins_def_NEW (rt_t*, bc_cont*); +void _ins_def_ENDCLASS (rt_t*, bc_cont*); void _ins_def_DECLASS (rt_t*, bc_cont*); void _ins_def_DEFUN (rt_t*, bc_cont*); diff --git a/src/vm/inc/ins_mdata.h b/src/vm/inc/ins_mdata.h @@ -81,21 +81,21 @@ /* DONE */ INS_MDATA[0x7E] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ /* CALL */ INS_MDATA[0x7F] = encode(1, A_ADDR, A_BYTE, A_BYTE); \ \ -/* PUSH */ INS_MDATA[0x80] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ -/* DEL */ INS_MDATA[0x81] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ -/* GET */ INS_MDATA[0x82] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ -/* GETP */ INS_MDATA[0x83] = encode(1, A_NAME, A_BYTE, A_BYTE); \ -/* CALLM */ INS_MDATA[0x84] = encode(1, A_NAME, A_BYTE, A_BYTE); \ +/* GETN */ INS_MDATA[0x80] = encode(1, A_NAME, A_BYTE, A_BYTE); \ +/* CALLM */ INS_MDATA[0x81] = encode(1, A_NAME, A_BYTE, A_BYTE); \ +/* INDEXO */ INS_MDATA[0x82] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ +/* MODO */ INS_MDATA[0x83] = encode(1, A_BYTE, A_BYTE, A_BYTE); \ \ /* RETURN */ INS_MDATA[0xF0] = encode(0, A_BYTE, A_BYTE, A_BYTE); \ /* NEW */ INS_MDATA[0xF1] = encode(1, A_NAME, A_BYTE, A_BYTE); \ /* DECLASS */ INS_MDATA[0xFE] = encode(2, A_NAME, A_DYNC, A_BYTE); \ /* DEFUN */ INS_MDATA[0xFF] = encode(3, A_NAME, A_BYTE, A_DYNC); -#define BTOI 0 -#define BTOT 1 -#define DTOL 2 -#define DTOV 3 + +#define BTOI 0 // Byte to Integer +#define BTOT 1 // Byte to Type +#define DTOL 2 // Dynamic to Byte List +#define DTOV 3 // Dynamic to Variable /* This definition is ran in `is.c` * @@ -161,11 +161,10 @@ /* DONE */ INS_ADATA[0x7E] = encode(0, BTOI, BTOI, BTOI); \ /* CALL */ INS_ADATA[0x7F] = encode(1, BTOI, BTOI, BTOI); \ \ -/* PUSH */ INS_ADATA[0x80] = encode(0, BTOI, BTOI, BTOI); \ -/* DEL */ INS_ADATA[0x81] = encode(0, BTOI, BTOI, BTOI); \ -/* GET */ INS_ADATA[0x82] = encode(0, BTOI, BTOI, BTOI); \ -/* GETP */ INS_ADATA[0x83] = encode(1, BTOI, BTOI, BTOI); \ -/* CALLM */ INS_ADATA[0x84] = encode(1, BTOI, BTOI, BTOI); \ +/* GETN */ INS_ADATA[0x80] = encode(1, BTOI, BTOI, BTOI); \ +/* CALLM */ INS_ADATA[0x81] = encode(1, BTOI, BTOI, BTOI); \ +/* INDEXO */ INS_ADATA[0x82] = encode(0, BTOI, BTOI, BTOI); \ +/* MODO */ INS_ADATA[0x83] = encode(1, BTOI, BTOI, BTOI); \ \ /* RETURN */ INS_ADATA[0xF0] = encode(0, BTOI, BTOI, BTOI); \ /* NEW */ INS_ADATA[0xF1] = encode(1, BTOI, BTOI, BTOI); \ diff --git a/src/vm/inc/ns.h b/src/vm/inc/ns.h @@ -23,6 +23,25 @@ typedef struct ns_t { ns_cont* last; } ns_t; +#define NS_CTX_DEPTH 256 +typedef struct ns_ctx { + int ptr; + ns_t** spaces; +} ns_ctx; + +/* Initializes namespace context + */ +ns_ctx* ns_ctx_init(void); +void ns_ctx_del(ns_ctx*); + +/* Push namespace to context + */ +void ns_ctx_push(ns_ctx*, ns_t*); + +/* Pop namespace out of context + */ +ns_t* ns_ctx_pop(ns_ctx*); + /* Initializes namespace of size * ns_addr - name limit */ diff --git a/src/vm/inc/object.h b/src/vm/inc/object.h @@ -0,0 +1,26 @@ +/* `object.h` Object implementation + */ + +#ifndef OBJECT_H +#define OBJECT_H + +#include <stdlib.h> + +#include "ns.h" + +#include "helper.h" + +typedef struct obj_t { + ns_t* names; + ns_addr mod_ops[0x100]; +} obj_t; + +/* Initalize an empty object of size + */ +obj_t* object_init(); + +/* Deconstruct an object + */ +void object_del(void*); + +#endif // OBJECT_H diff --git a/src/vm/inc/proc.h b/src/vm/inc/proc.h @@ -29,14 +29,6 @@ void proc_run(rt_t*); */ void proc_clean(rt_t*); -/* Function call subroutine. - * rt_t* - Runtime context - * var_cont* - Variable in type of function - * - * This function is used to support an interface to multithreaded instances - */ -var_cont* proc_callfun(rt_t*, var_cont*); - /* Set a variable subroutine * rt_t* - Runtime context * int - Scope diff --git a/src/vm/inc/rt.h b/src/vm/inc/rt.h @@ -29,48 +29,17 @@ typedef struct rt_t { stk_t* stack; stk_t* argstk; ns_t* vars; + ns_ctx* varctx; } rt_t; /* Creates new runtime context. * char* - Filename * stk_t* - Arguement stack - * ns_cont*- Copy of the global namespace */ rt_t* rt_ctx_new(char*, stk_t*); -/* Destroys runtime context. This can be *very* slow. +/* Destroys runtime context. */ void rt_ctx_del(rt_t*); - -#ifdef THREADING -#include <pthread.h> - -typedef struct rt_pool { - int thread_count; - rt_worker** threads; - ns_cont* gvars; -} rt_pool; - - -typedef struct rt_worker { - pthread_t* thread_ctx; - rt_t runtime_ctx; -} rt_worker - -#endif // THREADING - -#ifdef THREADING - -rt_pool* rt_pool_init(int); - -void rt_pool_kill(rt_pool*); - -void *rt_worker_run(void*); - -rt_worker* rt_worker_new(void); - -void rt_worker_del(rt_worker*); - -#endif //THREADING #endif // RT_H diff --git a/src/vm/inc/var.h b/src/vm/inc/var.h @@ -18,16 +18,16 @@ typedef enum { TYPE, // 2 PLIST, // 3 FUNC, // 4 - OBJECT, // 5 - G_INT, // 6 - G_FLOAT,// 7 - G_CHAR, // 8 - G_STR, // 9 - S_ARRAY,// A - D_ARRAY,// B - H_TABLE,// C - G_FIFO, // D - G_IO, // E + OBJBLDR,// 5 + OBJECT, // 6 + G_INT, // 7 + G_FLOAT,// 8 + G_CHAR, // 9 + G_STR, // A + S_ARRAY,// B + D_ARRAY,// C + H_TABLE,// D + G_FIFO, // E G_PTR // F } b_type; @@ -54,9 +54,21 @@ typedef struct var_data_func { b_type* param; } var_data_func; -typedef struct var_data_ptr { - var_cont* v; -} var_data_ptr; +typedef struct var_data_objbldr { + ns_addr id; + bc_addr loc; + bc_addr end; + ns_addr size; + ns_addr instc; + size_t paramlen; + b_type* param; +} var_data_objbldr; + +typedef struct var_data_object { + ns_addr id; + void* ref; + void (*objfree)(void*); +} var_data_object; typedef struct var_data_int { int v; @@ -80,6 +92,10 @@ typedef struct var_data_array { var_cont* v; } var_data_array; +typedef struct var_data_ptr { + var_cont* v; +} var_data_ptr; + #include "bc.h" /* Initialze variable with type @@ -89,6 +105,8 @@ var_cont* var_new(b_type); void* var_data_alloc_TYPE(b_type); void* var_data_alloc_PLIST(size_t); void* var_data_alloc_FUNC(b_type); +void* var_data_alloc_OBJBLDR(void); +void* var_data_alloc_OBJECT(void (*freefunc)(void*)); void* var_data_alloc_G_INT(int); void* var_data_alloc_G_FLOAT(double); void* var_data_alloc_G_CHAR(char); @@ -102,6 +120,8 @@ void var_data_free(void*, b_type); void var_data_free_PLIST(void*); void var_data_free_FUNC(void*); +void var_data_free_OBJBLDR(void*); +void var_data_free_OBJECT(void*); void var_data_free_G_STR(void*); /* Sets variable @@ -109,13 +129,15 @@ void var_data_free_G_STR(void*); */ void var_set(var_cont*, void*, b_type); -b_type var_data_get_TYPE(var_cont*); -var_data_func* var_data_get_FUNC(var_cont*); -int var_data_get_G_INT(var_cont*); -double var_data_get_G_FLOAT(var_cont*); -char var_data_get_G_CHAR(var_cont*); -char* var_data_get_G_STR(var_cont*); -b_type* var_data_get_PLIST(var_cont*); +b_type var_data_get_TYPE(var_cont*); +var_data_func* var_data_get_FUNC(var_cont*); +var_data_objbldr*var_data_get_OBJBLDR(var_cont*); +var_data_object* var_data_get_OBJECT(var_cont*); +int var_data_get_G_INT(var_cont*); +double var_data_get_G_FLOAT(var_cont*); +char var_data_get_G_CHAR(var_cont*); +char* var_data_get_G_STR(var_cont*); +b_type* var_data_get_PLIST(var_cont*); void* var_data_cpy_G_INT(var_data_int*); diff --git a/src/vm/src/ins_def.c b/src/vm/src/ins_def.c @@ -7,6 +7,7 @@ #include "rt.h" #include "bc.h" #include "stk.h" +#include "object.h" #include "var.h" #include "var_ops.h" #include "pc.h" @@ -76,14 +77,14 @@ void init_ins_def( void ) INS_DEF[0x7E] = _ins_def_DONE; INS_DEF[0x7F] = _ins_def_CALL; - INS_DEF[0x80] = _ins_def_PUSH; - INS_DEF[0x81] = _ins_def_DEL; - INS_DEF[0x82] = _ins_def_GET; - INS_DEF[0x83] = _ins_def_GETP; - INS_DEF[0x84] = _ins_def_CALLM; + INS_DEF[0x80] = _ins_def_GETN; + INS_DEF[0x81] = _ins_def_CALLM; + INS_DEF[0x82] = _ins_def_INDEXO; + INS_DEF[0x83] = _ins_def_MODO; INS_DEF[0xF0] = _ins_def_RETURN; INS_DEF[0xF1] = _ins_def_NEW; + INS_DEF[0xF2] = _ins_def_ENDCLASS; INS_DEF[0xFE] = _ins_def_DECLASS; INS_DEF[0xFF] = _ins_def_DEFUN; } @@ -92,7 +93,7 @@ int ins_def_is_valid(bc_cont* line) { int rv = 0; - if(INS_DEF[line->op] != NULL) + if (INS_DEF[line->op] != NULL) { rv = 1; } @@ -569,23 +570,19 @@ void _ins_def_CALL (rt_t* ctx, bc_cont* line) pc_branch(ctx->pc, func->loc); } -void _ins_def_PUSH (rt_t* ctx, bc_cont* line) +void _ins_def_GETN (rt_t* ctx, bc_cont* line) { pc_inc(ctx->pc, 1); } -void _ins_def_DEL (rt_t* ctx, bc_cont* line) -{ - pc_inc(ctx->pc, 1); -} -void _ins_def_GET (rt_t* ctx, bc_cont* line) +void _ins_def_CALLM (rt_t* ctx, bc_cont* line) { pc_inc(ctx->pc, 1); } -void _ins_def_GETP (rt_t* ctx, bc_cont* line) +void _ins_def_INDEXO (rt_t* ctx, bc_cont* line) { pc_inc(ctx->pc, 1); } -void _ins_def_CALLM (rt_t* ctx, bc_cont* line) +void _ins_def_MODO (rt_t* ctx, bc_cont* line) { pc_inc(ctx->pc, 1); } @@ -610,17 +607,116 @@ void _ins_def_RETURN (rt_t* ctx, bc_cont* line) } void _ins_def_NEW (rt_t* ctx, bc_cont* line) { - pc_inc(ctx->pc, 1); + int name = var_data_get_G_INT(line->varg[0]); + + // Get the object builder + var_cont* var = proc_getvar(ctx, 1, name); + var_data_objbldr* builder = var_data_get_OBJBLDR(var); + + // Init a new namespace of proper size + ns_t* new_ns = ns_init(builder->size); + + // Push current namespace to namespace context + ns_ctx_push(ctx->varctx, ctx->vars); + + // Set the current namespace to new namespace + ctx->vars = new_ns; + + int offset = 1; + int i; + for (i = 0; i < builder->paramlen; i++) + { + // Pop the arguement stack + var_cont* arg = stk_pop(ctx->argstk); + + // Is the arguement of the right type? + ASSERT(arg->type == builder->param[i], "Invalid object instantiation\n"); + + // Declare the name in the new namespace and pass the arguements + ns_dec(ctx->vars, arg->type, 0, i+offset); + ns_set(ctx->vars, 0, i+offset, arg); + } + // Push new stack levels for the stack and the arguement stack + stk_newlevel(&ctx->stack); + stk_newlevel(&ctx->argstk); + + pc_branch(ctx->pc, builder->loc); +} +void _ins_def_ENDCLASS (rt_t* ctx, bc_cont* line) +{ + var_cont* new = var_new(OBJECT); + var_data_object* data = var_data_alloc_OBJECT(object_del); + + obj_t* obj = object_init(); + obj->names = ctx->vars; + + data->ref = (void*)obj; + + var_set(new, data, OBJECT); + + stk_poplevel(&ctx->stack); + stk_poplevel(&ctx->argstk); + + ctx->vars = ns_ctx_pop(ctx->varctx); + + stk_push(ctx->stack, new); + + pc_return(ctx->pc); } void _ins_def_DECLASS (rt_t* ctx, bc_cont* line) { - pc_inc(ctx->pc, 1); + int name = var_data_get_G_INT(line->varg[0]); + b_type* args = var_data_get_PLIST(line->varg[1]); + size_t alen = line->sarg[1]; + + // Create a new variable for the object builder + var_cont* obj = var_new(OBJBLDR); + + // Allocate memory for this variable + var_data_objbldr* data = var_data_alloc_OBJBLDR(); + + // Set this objects ID + data->id = name; + // Set the location + data->loc = line->real_addr + 1; + + /* Determine namespace size for this object + */ + int nsize; + for (nsize = 0; pc_safe(ctx->pc); pc_update(ctx->pc)) + { + pc_inc(ctx->pc, 1); + + // Are we at the end of the object builder? + if (ctx->pc->line->op == 0xF2) + { + break; + } else + // Are we declaring a variable or function? + if (ctx->pc->line->op == 0x20 || ctx->pc->line->op == 0xFF) + { + nsize++; + } + } + + data->end = ctx->pc->line->real_addr; + data->size = nsize + alen + 1; + data->paramlen = alen; + data->param = args; + + // Throw the data in a variable container + var_set(obj, data, OBJBLDR); + + // Declare a name for this object + proc_decvar(ctx, OBJBLDR, 1, name); + // Set the object to the name we just declared + proc_setvar(ctx, 1, name, obj); } void _ins_def_DEFUN (rt_t* ctx, bc_cont* line) { int name = var_data_get_G_INT(line->varg[0]); b_type type = var_data_get_TYPE(line->varg[1]); - b_type* args = var_data_get_PLIST(line->varg[2]); + b_type* args = var_data_get_PLIST(line->varg[2]); size_t alen = line->sarg[2]; // Create a new variable for the new function diff --git a/src/vm/src/ns.c b/src/vm/src/ns.c @@ -4,6 +4,54 @@ #include "var.h" #include "helper.h" +/* Initializes namespace context + */ +ns_ctx* ns_ctx_init(void) +{ + ns_ctx* new = (ns_ctx*)malloc(sizeof(ns_ctx*)); + M_ASSERT(new); + + new->spaces = (ns_t**)malloc(sizeof(ns_t*)*NS_CTX_DEPTH); + M_ASSERT(new->spaces); + + new->ptr = 0; + return new; +} + +void ns_ctx_del(ns_ctx* ctx) +{ + N_ASSERT(ctx, "ns_ctx_del\n"); + N_ASSERT(ctx->spaces, "ns_ctx_del\n"); + + free(ctx->spaces); + free(ctx); +} + +/* Push namespace to context + */ +void ns_ctx_push(ns_ctx* ctx, ns_t* ns) +{ + N_ASSERT(ctx, "ns_ctx_push\n"); + N_ASSERT(ns, "ns_ctx_push\n"); + + ASSERT((ctx->ptr + 1) < NS_CTX_DEPTH, "ns_ctx overflow"); + + ctx->spaces[ctx->ptr] = ns; + ctx->ptr = ctx->ptr + 1; +} + +/* Pop namespace to context + */ +ns_t* ns_ctx_pop(ns_ctx* ctx) +{ + N_ASSERT(ctx, "ns_ctx_push\n"); + + ASSERT((ctx->ptr - 1) >= NS_CTX_DEPTH, "ns_ctx overflow"); + + ctx->ptr = ctx->ptr - 1; + return ctx->spaces[ctx->ptr]; +} + /* Initialize namespace container of size * ns_addr - name limit * int - Namespace level diff --git a/src/vm/src/object.c b/src/vm/src/object.c @@ -0,0 +1,29 @@ +#include <stdlib.h> + +#include "object.h" + +#include "ns.h" + +#include "helper.h" + +obj_t* object_init() +{ + obj_t* rv = (obj_t*)malloc(sizeof(obj_t)); + M_ASSERT(rv); + + rv->names = NULL; + + return rv; +} + +void object_del(void* object) +{ + N_ASSERT(object, "object_del\n"); + + obj_t* o = object; + + if (o->names != NULL) + ns_del(o->names); + + free(o); +} diff --git a/src/vm/src/proc.c b/src/vm/src/proc.c @@ -54,18 +54,6 @@ void proc_clean(rt_t* ctx) rt_ctx_del(ctx); } -/* Function call subroutine. - * rt_t* - Runtime context - * var_cont* - Variable in type of function - * - * This function is used to support an interface to multithreaded instances - */ -var_cont* proc_callfun(rt_t* ctx, var_cont* func) -{ - N_ASSERT(ctx, "proc_callfun\n"); - return 0; -} - /* Set a variable subroutine * rt_t* - Runtime context * b_type - Type diff --git a/src/vm/src/rt.c b/src/vm/src/rt.c @@ -24,8 +24,9 @@ rt_t* rt_ctx_new(char* fname, stk_t* args) ctx->pc = pc_new(fname); ctx->stack = stk_new(); - ctx->vars = ns_init(1024); ctx->argstk = args; + ctx->vars = ns_init(1024); + ctx->varctx = ns_ctx_init(); return ctx; } @@ -42,9 +43,12 @@ void rt_ctx_del(rt_t* ctx) N_ASSERT(ctx->argstk, "rt_ctx_del\n"); stk_del(ctx->argstk); + N_ASSERT(ctx->pc, "rt_ctx_del\n"); + pc_del(ctx->pc); + N_ASSERT(ctx->vars, "rt_ctx_del\n"); ns_del(ctx->vars); - N_ASSERT(ctx->pc, "rt_ctx_del\n"); - pc_del(ctx->pc); + N_ASSERT(ctx->varctx, "rt_ctx_del\n"); + ns_ctx_del(ctx->varctx); } diff --git a/src/vm/src/stk.c b/src/vm/src/stk.c @@ -120,8 +120,8 @@ var_cont* stk_pop(stk_t* stack) ASSERT(((stack->stack->ptr - 1) >= 0), "Stack Underflow\n"); stack->stack->ptr = stack->stack->ptr - 1; - var_cont* rv = stack->stack->data[stack->stack->ptr]; - return rv; + + return stack->stack->data[stack->stack->ptr]; } /* Pushes var_cont* to the stack diff --git a/src/vm/src/var.c b/src/vm/src/var.c @@ -3,6 +3,7 @@ #include "var.h" #include "bc.h" + #include "helper.h" void* var_data_alloc_TYPE(b_type type) @@ -39,6 +40,35 @@ void* var_data_alloc_FUNC(b_type type) return rv; } +void* var_data_alloc_OBJBLDR(void) +{ + var_data_objbldr* rv = (var_data_objbldr*)malloc(sizeof(var_data_objbldr)); + M_ASSERT(rv); + + rv->id = 0; + rv->loc = 0; + rv->end = 0; + rv->size = 0; + rv->instc = 0; + rv->param = NULL; + + return rv; +} + +void* var_data_alloc_OBJECT(void (*freefunc)(void*)) +{ + N_ASSERT(freefunc, "var_data_alloc_OBJECT\n"); + + var_data_object* rv = (var_data_object*)malloc(sizeof(var_data_object)); + M_ASSERT(rv); + + rv->id = 0; + rv->ref = NULL; + rv->objfree = freefunc; + + return rv; +} + void* var_data_alloc_G_INT(int value) { var_data_int* rv = (var_data_int*)malloc(sizeof(var_data_int)); @@ -114,6 +144,16 @@ void var_data_free(void* data, b_type type) var_data_free_FUNC(data); } + if (type == OBJBLDR) + { + var_data_free_OBJBLDR(data); + } + + if (type == OBJECT) + { + var_data_free_OBJECT(data); + } + if (type == G_STR) { var_data_free_G_STR(data); @@ -140,6 +180,18 @@ void var_data_free_FUNC(void* data) if (d->param != NULL) free(d->param); } +void var_data_free_OBJBLDR(void* data) +{ + var_data_objbldr* d = data; + if (d->param != NULL) + free(d->param); +} +void var_data_free_OBJECT(void* data) +{ + var_data_object* d = data; + if (d->ref != NULL) + d->objfree(d->ref); +} void var_data_free_G_STR(void* data) { var_data_str* d = data; @@ -193,6 +245,26 @@ var_data_func* var_data_get_FUNC(var_cont* var) return t; } +var_data_objbldr* var_data_get_OBJBLDR(var_cont* var) +{ + N_ASSERT(var, "var_data_get_OBJBLDR\n"); + ASSERT( var->type == OBJBLDR, "TypeError" ); + + var_data_objbldr* t = var->data; + + return t; +} + +var_data_object* var_data_get_OBJECT(var_cont* var) +{ + N_ASSERT(var, "var_data_get_OBJECT\n"); + ASSERT( var->type == OBJECT, "TypeError" ); + + var_data_object* t = var->data; + + return t; +} + int var_data_get_G_INT(var_cont* var) { N_ASSERT(var, "var_data_get_G_INT\n"); diff --git a/src/vm/tests/cases/bc/bytecode b/src/vm/tests/cases/bc/bytecode Binary files differ diff --git a/src/vm/tests/cases/bc/expected_output b/src/vm/tests/cases/bc/expected_output @@ -1,9 +1,9 @@ -20 1, 6, 0 3, -23 1, 0 3, 6 ff -20 1, 6, 0 1, -23 1, 0 1, 6 0 -20 1, 6, 0 2, -23 1, 0 2, 6 1 +20 1, 7, 0 3, +23 1, 0 3, 7 ff +20 1, 7, 0 1, +23 1, 0 1, 7 0 +20 1, 7, 0 2, +23 1, 0 2, 7 1 60 21 1, 0 2, 21 1, 0 3, diff --git a/src/vm/tests/cases/program_fibb/fibb b/src/vm/tests/cases/program_fibb/fibb Binary files differ diff --git a/src/vm/tests/cases/stk/expected_output b/src/vm/tests/cases/stk/expected_output @@ -1,23 +1,23 @@ init: -9, 8, 7, 6 +10, 9, 8, 7 stk_pop: -8, 7, 6, 0 +9, 8, 7, 0 stk_rot_top: -7, 8, 6, 0 +8, 9, 7, 0 stk_rot_top + stk_rot_three: -6, 7, 8, 0 +7, 8, 9, 0 stk_rot_three: -8, 7, 6, 0 +9, 8, 7, 0 -- NEW STACK LEVEL -- init: -9, 8, 7, 6 +10, 9, 8, 7 stk_pop: -8, 7, 6, 0 +9, 8, 7, 0 stk_rot_top: -7, 8, 6, 0 +8, 9, 7, 0 stk_rot_top + stk_rot_three: -6, 7, 8, 0 +7, 8, 9, 0 stk_rot_three: -8, 7, 6, 0 --- LEVEL 1: 8, 7, 6, 0 --- LEVEL 0: 8, 7, 6, 0 +9, 8, 7, 0 +-- LEVEL 1: 9, 8, 7, 0 +-- LEVEL 0: 9, 8, 7, 0