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 "IOcode.h"
|
||||||
#include "CodeHeader.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
|
int i;
|
||||||
fread_s(buffer, 1000, sizeof(char), 1000, stream); //Early version without bytecode file
|
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)
|
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
|
fread_s(&First_Header, sizeof(First_Header), sizeof(First_Header), 1, stream); //Reading first part of header
|
||||||
*(count) = First_Header.count_const;
|
*(count) = First_Header.count_const;
|
||||||
|
|
||||||
buffer = (char*)malloc(First_Header.size_const);
|
buffer = (char*)malloc(First_Header.size_const+1);
|
||||||
*(index) = (char**)malloc(sizeof(char**)*2);
|
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;
|
j=0;
|
||||||
if (First_Header.count_const>0)
|
(*(index))[j++]=buffer;
|
||||||
|
for (i = 0; i<First_Header.size_const+1; i++)
|
||||||
{
|
{
|
||||||
(*(index))[j++] = buffer;
|
if (j==First_Header.count_const)
|
||||||
for (i = 0; i<First_Header.size_const; i++)
|
break;
|
||||||
{
|
|
||||||
if (j==First_Header.count_const)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (buffer[i] == 0)
|
if (buffer[i] == 0)
|
||||||
(*(index))[j++]=&buffer[i+1];
|
(*(index))[j++]=&buffer[i+1];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#ifndef IOCODE_H
|
#ifndef IOCODE_H
|
||||||
#define IOCODE_H
|
#define IOCODE_H
|
||||||
|
|
||||||
|
#include "CodeHeader.h"
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
char* read_bytecode(FILE*);
|
int read_bytecode(FILE*, func***);
|
||||||
int read_constant(FILE*, int*, char***);
|
int read_constant(FILE*, int*, char***);
|
||||||
#endif
|
#endif
|
|
@ -2,6 +2,8 @@
|
||||||
#include "TOS.h"
|
#include "TOS.h"
|
||||||
#include "OpCode.h"
|
#include "OpCode.h"
|
||||||
#include "CodeHeader.h"
|
#include "CodeHeader.h"
|
||||||
|
#include "Context.h"
|
||||||
|
#include "ReturnStack.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,29 +17,33 @@ int main(int argc, char** argv)
|
||||||
long long i1, i2;
|
long long i1, i2;
|
||||||
short s1;
|
short s1;
|
||||||
char* code;
|
char* code;
|
||||||
int ip;
|
int ip, startfunc;
|
||||||
|
|
||||||
//ConstSection Variables
|
//ConstSection Variables
|
||||||
int const_count;
|
int const_count;
|
||||||
char** const_index;
|
char** const_index;
|
||||||
|
|
||||||
//Execution Variable
|
//CodeSection Variables
|
||||||
|
func** phash_table;
|
||||||
|
context* current_context;
|
||||||
|
|
||||||
|
//Running Variable
|
||||||
int exec_status = 1;
|
int exec_status = 1;
|
||||||
|
|
||||||
fopen_s(&input, "bytecode", "rb");
|
fopen_s(&input, "bytecode", "rb");
|
||||||
|
|
||||||
//const_pull
|
//const_pull
|
||||||
read_constant(input, &const_count, &const_index);
|
read_constant(input, &const_count, &const_index);
|
||||||
|
//code_pull
|
||||||
code=read_bytecode(input);
|
startfunc = read_bytecode(input, &phash_table);
|
||||||
|
|
||||||
fclose(input);
|
fclose(input);
|
||||||
|
|
||||||
|
|
||||||
initTOS();
|
initTOS();
|
||||||
|
initRStack();
|
||||||
ip = 0;
|
ip = 0;
|
||||||
|
|
||||||
|
current_context = create_context(startfunc, phash_table, &code);
|
||||||
|
|
||||||
while (exec_status)
|
while (exec_status)
|
||||||
{
|
{
|
||||||
switch (code[ip])
|
switch (code[ip])
|
||||||
|
@ -54,11 +60,11 @@ int main(int argc, char** argv)
|
||||||
//DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9)
|
//DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9)
|
||||||
i1 = *((long long*)(code+(++ip)));
|
i1 = *((long long*)(code+(++ip)));
|
||||||
push_int(i1);
|
push_int(i1);
|
||||||
ip++; break;
|
ip+=8; break;
|
||||||
case SLOAD:
|
case SLOAD:
|
||||||
s1 = *((short*)(code+(++ip)));
|
s1 = *((short*)(code+(++ip)));
|
||||||
push_int((long long)(const_index[s1]));
|
push_int((long long)(const_index[s1]));
|
||||||
ip++; break;
|
ip+=2; break;
|
||||||
case DLOAD0:
|
case DLOAD0:
|
||||||
// DO(DLOAD0, "Load double 0 on TOS.", 1)
|
// DO(DLOAD0, "Load double 0 on TOS.", 1)
|
||||||
push_double(0);
|
push_double(0);
|
||||||
|
@ -173,18 +179,16 @@ int main(int argc, char** argv)
|
||||||
case IPRINT:
|
case IPRINT:
|
||||||
//DO(IPRINT, "Pop and print integer TOS.", 1)
|
//DO(IPRINT, "Pop and print integer TOS.", 1)
|
||||||
i1 = pop_int();
|
i1 = pop_int();
|
||||||
push_int(i1);
|
|
||||||
printf("%d", i1);
|
printf("%d", i1);
|
||||||
ip++; break;
|
ip++; break;
|
||||||
case DPRINT:
|
case DPRINT:
|
||||||
//DO(DPRINT, "Pop and print double TOS.", 1)
|
//DO(DPRINT, "Pop and print double TOS.", 1)
|
||||||
d1 = pop_double();
|
d1 = pop_double();
|
||||||
push_double(d1);
|
|
||||||
printf("%f", d1);
|
printf("%f", d1);
|
||||||
ip++; break;
|
ip++; break;
|
||||||
case SPRINT:
|
case SPRINT:
|
||||||
|
//DO(SPRINT, "Pop and print string TOS.", 1)
|
||||||
i1 = pop_int();
|
i1 = pop_int();
|
||||||
push_int(i1);
|
|
||||||
printf("%s", (char*)i1);
|
printf("%s", (char*)i1);
|
||||||
ip++; break;
|
ip++; break;
|
||||||
case I2D:
|
case I2D:
|
||||||
|
@ -213,9 +217,22 @@ int main(int argc, char** argv)
|
||||||
case STOP:
|
case STOP:
|
||||||
//DO(STOP, "Stop execution.", 1)
|
//DO(STOP, "Stop execution.", 1)
|
||||||
exec_status = 0;
|
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();
|
getchar();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -33,6 +33,8 @@ enum opcode
|
||||||
D2I,
|
D2I,
|
||||||
SWAP,
|
SWAP,
|
||||||
POP,
|
POP,
|
||||||
STOP
|
STOP,
|
||||||
|
CALL,
|
||||||
|
RETURN
|
||||||
};
|
};
|
||||||
#endif
|
#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