Added support for functions and dynamic contexts. Improved work with constant pool
This commit is contained in:
parent
792724bcd1
commit
7712440064
9 changed files with 202 additions and 31 deletions
39
VaninVM/CodeHeader.h
Normal file
39
VaninVM/CodeHeader.h
Normal 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
33
VaninVM/Context.c
Normal 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
27
VaninVM/Context.h
Normal 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
|
|
@ -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,24 +42,22 @@ 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+1; i++)
|
||||
{
|
||||
(*(index))[j++] = buffer;
|
||||
for (i = 0; i<First_Header.size_const; i++)
|
||||
{
|
||||
if (j==First_Header.count_const)
|
||||
break;
|
||||
if (j==First_Header.count_const)
|
||||
break;
|
||||
|
||||
if (buffer[i] == 0)
|
||||
(*(index))[j++]=&buffer[i+1];
|
||||
}
|
||||
if (buffer[i] == 0)
|
||||
(*(index))[j++]=&buffer[i+1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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:
|
||||
|
@ -213,9 +217,22 @@ int main(int argc, char** argv)
|
|||
case STOP:
|
||||
//DO(STOP, "Stop execution.", 1)
|
||||
exec_status = 0;
|
||||
break;
|
||||
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;
|
||||
}
|
|
@ -33,6 +33,8 @@ enum opcode
|
|||
D2I,
|
||||
SWAP,
|
||||
POP,
|
||||
STOP
|
||||
STOP,
|
||||
CALL,
|
||||
RETURN
|
||||
};
|
||||
#endif
|
20
VaninVM/ReturnStack.c
Normal file
20
VaninVM/ReturnStack.c
Normal 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
9
VaninVM/ReturnStack.h
Normal 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
|
Loading…
Reference in a new issue