Added support for functions and dynamic contexts. Improved work with constant pool

This commit is contained in:
Alex Vanin 2014-01-27 16:09:25 +04:00
parent 792724bcd1
commit 7712440064
9 changed files with 202 additions and 31 deletions

39
VaninVM/CodeHeader.h Normal file
View file

@ -0,0 +1,39 @@
#ifndef CODE_HEADER
#define CODE_HEADER
#pragma pack(push, 1)
struct
{
char signature[4];
int version;
int count_const;
int size_const;
}First_Header;
struct
{
short id_start;
int count_code;
}ByteCodeH_Common;
struct
{
int size_func;
int size_bytecode;
int size_signature;
}ByteCodeH_Signat;
struct
{
short id;
int count_locals;
int count_args;
}ByteCodeH_Primary;
typedef struct
{
int count_locals;
int count_args;
char* code;
} func;
#endif
#pragma pop

33
VaninVM/Context.c Normal file
View file

@ -0,0 +1,33 @@
#include "Context.h"
#include <malloc.h>
context* create_context(int function, func** hash, char** code)
{
context* cont;
cont = (context*)malloc(sizeof(context));
cont->id = function;
cont->locals=malloc(8*hash[function]->count_locals);
*(code)=hash[function]->code;
return cont;
}
void remove_context(context* cont)
{
free(cont->locals);
free(cont);
}
void push_context(context* cont)
{
c_node* node;
node = (c_node*)malloc(sizeof(c_node));
node->obj=cont;
node->prev = node_last;
node_last = node;
}
context* pop_context()
{
c_node* last = node_last;
node_last = node_last->prev;
return last->obj;
}

27
VaninVM/Context.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef CONTEXT_H
#define CONTEXT_H
#include "CodeHeader.h"
#include <stdio.h>
typedef struct
{
int id;
void* locals;
} context;
typedef struct NODE
{
context* obj;
struct NODE* prev;
} c_node;
c_node* node_last;
context* create_context(int function, func** hash,char** code);
void push_context(context*);
context* pop_context();
void remove_context(context*);
#endif

View file

@ -1,12 +1,37 @@
#include "IOcode.h"
#include "CodeHeader.h"
#include <string.h>
char* read_bytecode(FILE* stream)
int read_bytecode(FILE* stream, func*** hash)
{
char* buffer = (char*)calloc(1, 1000); //Early version without bytecode file
fread_s(buffer, 1000, sizeof(char), 1000, stream); //Early version without bytecode file
int i;
char* name;
char* code;
func* function;
*(hash) = (func**)malloc(sizeof(func*)*65536);
fread_s(&ByteCodeH_Common, sizeof(ByteCodeH_Common), sizeof(ByteCodeH_Common), 1, stream);
for (i=0; i<ByteCodeH_Common.count_code; i++)
{
function = (func*)malloc(sizeof(func));
fread(&ByteCodeH_Signat, sizeof(ByteCodeH_Signat), 1, stream);
name = (char*)malloc(ByteCodeH_Signat.size_signature);
fread(name, ByteCodeH_Signat.size_signature, 1, stream);
free(name);
fread(&ByteCodeH_Primary, sizeof(ByteCodeH_Primary), 1, stream);
code = (char*)malloc(ByteCodeH_Signat.size_bytecode);
fread(code, ByteCodeH_Signat.size_bytecode, 1, stream);
function->code=code;
function->count_args=ByteCodeH_Primary.count_args;
function->count_locals=ByteCodeH_Primary.count_locals;
(*(hash))[ByteCodeH_Primary.id]=function;
}
return ByteCodeH_Common.id_start;
return buffer;
}
int read_constant(FILE* stream, int* count, char*** index)
@ -17,17 +42,16 @@ int read_constant(FILE* stream, int* count, char*** index)
fread_s(&First_Header, sizeof(First_Header), sizeof(First_Header), 1, stream); //Reading first part of header
*(count) = First_Header.count_const;
buffer = (char*)malloc(First_Header.size_const);
*(index) = (char**)malloc(sizeof(char**)*2);
buffer = (char*)malloc(First_Header.size_const+1);
buffer[0]=0;
*(index) = (char**)malloc(sizeof(char**)*First_Header.count_const);
fread_s(buffer, First_Header.size_const, sizeof(char), First_Header.size_const, stream); //Reading constant values
fread_s(buffer+1, First_Header.size_const, sizeof(char), First_Header.size_const, stream); //Reading constant values
j=0;
if (First_Header.count_const>0)
{
(*(index))[j++] = buffer;
for (i = 0; i<First_Header.size_const; i++)
(*(index))[j++]=buffer;
for (i = 0; i<First_Header.size_const+1; i++)
{
if (j==First_Header.count_const)
break;
@ -35,6 +59,5 @@ int read_constant(FILE* stream, int* count, char*** index)
if (buffer[i] == 0)
(*(index))[j++]=&buffer[i+1];
}
}
return 0;
}

View file

@ -1,9 +1,10 @@
#ifndef IOCODE_H
#define IOCODE_H
#include "CodeHeader.h"
#include <malloc.h>
#include <stdio.h>
char* read_bytecode(FILE*);
int read_bytecode(FILE*, func***);
int read_constant(FILE*, int*, char***);
#endif

View file

@ -2,6 +2,8 @@
#include "TOS.h"
#include "OpCode.h"
#include "CodeHeader.h"
#include "Context.h"
#include "ReturnStack.h"
@ -15,29 +17,33 @@ int main(int argc, char** argv)
long long i1, i2;
short s1;
char* code;
int ip;
int ip, startfunc;
//ConstSection Variables
int const_count;
char** const_index;
//Execution Variable
//CodeSection Variables
func** phash_table;
context* current_context;
//Running Variable
int exec_status = 1;
fopen_s(&input, "bytecode", "rb");
//const_pull
read_constant(input, &const_count, &const_index);
code=read_bytecode(input);
//code_pull
startfunc = read_bytecode(input, &phash_table);
fclose(input);
initTOS();
initRStack();
ip = 0;
current_context = create_context(startfunc, phash_table, &code);
while (exec_status)
{
switch (code[ip])
@ -54,11 +60,11 @@ int main(int argc, char** argv)
//DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9)
i1 = *((long long*)(code+(++ip)));
push_int(i1);
ip++; break;
ip+=8; break;
case SLOAD:
s1 = *((short*)(code+(++ip)));
push_int((long long)(const_index[s1]));
ip++; break;
ip+=2; break;
case DLOAD0:
// DO(DLOAD0, "Load double 0 on TOS.", 1)
push_double(0);
@ -173,18 +179,16 @@ int main(int argc, char** argv)
case IPRINT:
//DO(IPRINT, "Pop and print integer TOS.", 1)
i1 = pop_int();
push_int(i1);
printf("%d", i1);
ip++; break;
case DPRINT:
//DO(DPRINT, "Pop and print double TOS.", 1)
d1 = pop_double();
push_double(d1);
printf("%f", d1);
ip++; break;
case SPRINT:
//DO(SPRINT, "Pop and print string TOS.", 1)
i1 = pop_int();
push_int(i1);
printf("%s", (char*)i1);
ip++; break;
case I2D:
@ -214,8 +218,21 @@ int main(int argc, char** argv)
//DO(STOP, "Stop execution.", 1)
exec_status = 0;
break;
case CALL:
s1 = *((short*)(code+(++ip)));
ip+=2; push_ret(ip);
push_context(current_context);
current_context = create_context(s1, phash_table, &code);
ip = 0; break;
case RETURN:
remove_context(current_context);
current_context = pop_context();
code = phash_table[current_context->id]->code;
ip = pop_ret(); break;
}
}
remove_context(current_context);
getchar();
return 0;
}

View file

@ -33,6 +33,8 @@ enum opcode
D2I,
SWAP,
POP,
STOP
STOP,
CALL,
RETURN
};
#endif

20
VaninVM/ReturnStack.c Normal file
View file

@ -0,0 +1,20 @@
#include <malloc.h>
#include "ReturnStack.h"
void push_ret(int num)
{
RStack[rp++] = num;
}
int pop_ret()
{
int num = RStack[--rp];
return num;
}
int initRStack()
{
RStack = (int*)calloc(1, 1000);
rp = 0;
return 0;
}

9
VaninVM/ReturnStack.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef RETURNSTACK_H
#define RETURNSTACK_H
int* RStack;
int rp;
int initRStack();
void push_ret(int);
int pop_ret();
#endif