First full version. Added all opcodes, improved work with contexts
This commit is contained in:
parent
7712440064
commit
159c5ed01f
11 changed files with 767 additions and 251 deletions
|
@ -3,11 +3,11 @@
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
char signature[4];
|
char signature[2];
|
||||||
int version;
|
int version;
|
||||||
int count_const;
|
int count_const;
|
||||||
int size_const;
|
int size_const;
|
||||||
}First_Header;
|
}Const_Header;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,3 +31,21 @@ context* pop_context()
|
||||||
node_last = node_last->prev;
|
node_last = node_last->prev;
|
||||||
return last->obj;
|
return last->obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Find Context in Context Stack.
|
||||||
|
context* find_context(int id)
|
||||||
|
{
|
||||||
|
context* result = NULL;
|
||||||
|
c_node* current = node_last;
|
||||||
|
while (current != NULL || current->prev != NULL)
|
||||||
|
{
|
||||||
|
if (current->obj->id == id)
|
||||||
|
{
|
||||||
|
result = current->obj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
current = current->prev;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -23,5 +23,6 @@ context* create_context(int function, func** hash,char** code);
|
||||||
void push_context(context*);
|
void push_context(context*);
|
||||||
context* pop_context();
|
context* pop_context();
|
||||||
void remove_context(context*);
|
void remove_context(context*);
|
||||||
|
context* find_context(int id);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -2,6 +2,8 @@
|
||||||
#include "CodeHeader.h"
|
#include "CodeHeader.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
int version = 0100;
|
||||||
|
|
||||||
int read_bytecode(FILE* stream, func*** hash)
|
int read_bytecode(FILE* stream, func*** hash)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -39,21 +41,33 @@ int read_constant(FILE* stream, int* count, char*** index)
|
||||||
int i, j;
|
int i, j;
|
||||||
char* buffer;
|
char* buffer;
|
||||||
|
|
||||||
fread_s(&First_Header, sizeof(First_Header), sizeof(First_Header), 1, stream); //Reading first part of header
|
fread_s(&Const_Header, sizeof(Const_Header), sizeof(Const_Header), 1, stream); //Reading first part of header
|
||||||
*(count) = First_Header.count_const;
|
if (Const_Header.signature[0]==Const_Header.signature[1]== 0xBA)
|
||||||
|
{
|
||||||
|
printf("%s", "Wrong file-format");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
buffer = (char*)malloc(First_Header.size_const+1);
|
if (Const_Header.version != version)
|
||||||
|
{
|
||||||
|
printf("%s", "Unsupported bytecode format");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(count) = Const_Header.count_const;
|
||||||
|
|
||||||
|
buffer = (char*)malloc(Const_Header.size_const+1);
|
||||||
buffer[0]=0;
|
buffer[0]=0;
|
||||||
*(index) = (char**)malloc(sizeof(char**)*First_Header.count_const);
|
*(index) = (char**)malloc(sizeof(char**)*Const_Header.count_const);
|
||||||
|
|
||||||
|
|
||||||
fread_s(buffer+1, First_Header.size_const, sizeof(char), First_Header.size_const, stream); //Reading constant values
|
fread_s(buffer+1, Const_Header.size_const, sizeof(char), Const_Header.size_const, stream); //Reading constant values
|
||||||
|
|
||||||
j=0;
|
j=0;
|
||||||
(*(index))[j++]=buffer;
|
(*(index))[j++]=buffer;
|
||||||
for (i = 0; i<First_Header.size_const+1; i++)
|
for (i = 0; i<Const_Header.size_const+1; i++)
|
||||||
{
|
{
|
||||||
if (j==First_Header.count_const)
|
if (j>Const_Header.count_const)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (buffer[i] == 0)
|
if (buffer[i] == 0)
|
||||||
|
|
38
VaninVM/LocalVars.c
Normal file
38
VaninVM/LocalVars.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include "LocalVars.h"
|
||||||
|
|
||||||
|
long long getlocal_int(context* cont, int id)
|
||||||
|
{
|
||||||
|
long long result;
|
||||||
|
result = ((long long*)(cont->locals))[id];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getlocal_double(context* cont, int id)
|
||||||
|
{
|
||||||
|
double result;
|
||||||
|
result = ((double*)(cont->locals))[id];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getlocal_string(context* cont, int id)
|
||||||
|
{
|
||||||
|
long long result;
|
||||||
|
result = ((long long*)(cont->locals))[id];
|
||||||
|
return (int)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void putlocal_int(long long* num, context* cont, int id)
|
||||||
|
{
|
||||||
|
memcpy(((long long*)cont->locals)+id, num, sizeof(long long));
|
||||||
|
}
|
||||||
|
|
||||||
|
void putlocal_double(double* num, context* cont, int id)
|
||||||
|
{
|
||||||
|
memcpy(((double*)cont->locals)+id, num, sizeof(double));
|
||||||
|
}
|
||||||
|
|
||||||
|
void putlocal_string(int* str, context* cont, int id)
|
||||||
|
{
|
||||||
|
memcpy(((long long*)cont->locals)+id, (long long*)str, sizeof(long long));
|
||||||
|
}
|
12
VaninVM/LocalVars.h
Normal file
12
VaninVM/LocalVars.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef LOCALVARS_H
|
||||||
|
#define LOCALVARS_H
|
||||||
|
#include "Context.h"
|
||||||
|
|
||||||
|
long long getlocal_int(context*, int);
|
||||||
|
double getlocal_double(context*, int);
|
||||||
|
int getlocal_string(context*, int);
|
||||||
|
|
||||||
|
void putlocal_int(long long*, context*, int);
|
||||||
|
void putlocal_double(double*, context*, int);
|
||||||
|
void putlocal_string(int*, context*, int);
|
||||||
|
#endif
|
748
VaninVM/Main.c
748
VaninVM/Main.c
|
@ -1,11 +1,16 @@
|
||||||
#include "IOcode.h"
|
|
||||||
#include "TOS.h"
|
|
||||||
#include "OpCode.h"
|
#include "OpCode.h"
|
||||||
|
|
||||||
|
#include "IOcode.h"
|
||||||
#include "CodeHeader.h"
|
#include "CodeHeader.h"
|
||||||
|
|
||||||
|
#include "TOS.h"
|
||||||
#include "Context.h"
|
#include "Context.h"
|
||||||
#include "ReturnStack.h"
|
#include "ReturnStack.h"
|
||||||
|
#include "LocalVars.h"
|
||||||
|
|
||||||
|
|
||||||
|
long long cmp_int(long long* a, long long* b);
|
||||||
|
double cmp_double(double* a, double* b);
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
@ -15,7 +20,7 @@ int main(int argc, char** argv)
|
||||||
//ExecutionProcess Variables
|
//ExecutionProcess Variables
|
||||||
double d1, d2;
|
double d1, d2;
|
||||||
long long i1, i2;
|
long long i1, i2;
|
||||||
short s1;
|
short s1, s2;
|
||||||
char* code;
|
char* code;
|
||||||
int ip, startfunc;
|
int ip, startfunc;
|
||||||
|
|
||||||
|
@ -30,9 +35,17 @@ int main(int argc, char** argv)
|
||||||
//Running Variable
|
//Running Variable
|
||||||
int exec_status = 1;
|
int exec_status = 1;
|
||||||
|
|
||||||
fopen_s(&input, "bytecode", "rb");
|
|
||||||
|
if (argc<2)
|
||||||
|
{
|
||||||
|
printf("%s", "File is not specified");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fopen_s(&input, argv[1], "rb");
|
||||||
//const_pull
|
//const_pull
|
||||||
read_constant(input, &const_count, &const_index);
|
if (read_constant(input, &const_count, &const_index) != 0)
|
||||||
|
return 1;
|
||||||
//code_pull
|
//code_pull
|
||||||
startfunc = read_bytecode(input, &phash_table);
|
startfunc = read_bytecode(input, &phash_table);
|
||||||
fclose(input);
|
fclose(input);
|
||||||
|
@ -43,196 +56,559 @@ int main(int argc, char** argv)
|
||||||
ip = 0;
|
ip = 0;
|
||||||
|
|
||||||
current_context = create_context(startfunc, phash_table, &code);
|
current_context = create_context(startfunc, phash_table, &code);
|
||||||
|
node_last = NULL;
|
||||||
|
|
||||||
while (exec_status)
|
while (exec_status)
|
||||||
{
|
{
|
||||||
switch (code[ip])
|
switch (code[ip])
|
||||||
{
|
{
|
||||||
case INVALID:
|
case INVALID:
|
||||||
//DO(INVALID, "Invalid instruction.", 1)
|
//DO(INVALID, "Invalid instruction.", 1)
|
||||||
ip++; break;
|
ip++; break;
|
||||||
case DLOAD:
|
case DLOAD:
|
||||||
//DO(DLOAD, "Load double on TOS, inlined into insn stream.", 9)
|
//DO(DLOAD, "Load double on TOS, inlined into insn stream.", 9)
|
||||||
d1 = *((double*)(code+(++ip)));
|
d1 = *((double*)(code+(++ip)));
|
||||||
|
push_double(d1);
|
||||||
|
ip+=8; break;
|
||||||
|
case ILOAD:
|
||||||
|
//DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9)
|
||||||
|
i1 = *((long long*)(code+(++ip)));
|
||||||
|
push_int(i1);
|
||||||
|
ip+=8; break;
|
||||||
|
case SLOAD:
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
push_int((long long)(const_index[s1]));
|
||||||
|
ip+=2; break;
|
||||||
|
case DLOAD0:
|
||||||
|
// DO(DLOAD0, "Load double 0 on TOS.", 1)
|
||||||
|
push_double(0);
|
||||||
|
ip++; break;
|
||||||
|
case ILOAD0:
|
||||||
|
//DO(ILOAD0, "Load int 0 on TOS.", 1)
|
||||||
|
push_int(0);
|
||||||
|
ip++; break;
|
||||||
|
case SLOAD0:
|
||||||
|
//DO(SLOAD0, "Load empty string on TOS.", 1)
|
||||||
|
push_int((long long)(const_index[0]));
|
||||||
|
ip++; break;
|
||||||
|
case DLOAD1:
|
||||||
|
//DO(DLOAD1, "Load double 1 on TOS.", 1)
|
||||||
|
push_double(1);
|
||||||
|
ip++; break;
|
||||||
|
case ILOAD1:
|
||||||
|
//DO(ILOAD1, "Load int 1 on TOS.", 1)
|
||||||
|
push_int(1);
|
||||||
|
ip++; break;
|
||||||
|
case DLOADM1:
|
||||||
|
//DO(DLOADM1, "Load double -1 on TOS.", 1)
|
||||||
|
push_double(-1);
|
||||||
|
ip++; break;
|
||||||
|
case ILOADM1:
|
||||||
|
//DO(ILOADM1, "Load int -1 on TOS.", 1)
|
||||||
|
push_int(-1);
|
||||||
|
ip++; break;
|
||||||
|
case DADD:
|
||||||
|
//DO(DADD, "Add 2 doubles on TOS, push value back.", 1)
|
||||||
|
d1 = pop_double();
|
||||||
|
d2 = pop_double();
|
||||||
|
d1 += d2;
|
||||||
|
push_double(d1);
|
||||||
|
ip++; break;
|
||||||
|
case IADD:
|
||||||
|
//DO(IADD, "Add 2 ints on TOS, push value back.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
i2 = pop_int();
|
||||||
|
i1 += i2;
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case DSUB:
|
||||||
|
//DO(DSUB, "Subtract 2 doubles on TOS (lower from upper), push value back.", 1)
|
||||||
|
d1 = pop_double();
|
||||||
|
d2 = pop_double();
|
||||||
|
d2 -= d1;
|
||||||
|
push_double(d2);
|
||||||
|
ip++; break;
|
||||||
|
case ISUB:
|
||||||
|
//DO(ISUB, "Subtract 2 ints on TOS (lower from upper), push value back.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
i2 = pop_int();
|
||||||
|
i2 -= i1;
|
||||||
|
push_int(i2);
|
||||||
|
ip++; break;
|
||||||
|
case DMUL:
|
||||||
|
//DO(DMUL, "Multiply 2 doubles on TOS, push value back.", 1)
|
||||||
|
d1 = pop_double();
|
||||||
|
d2 = pop_double();
|
||||||
|
d1 *= d2;
|
||||||
|
push_double(d1);
|
||||||
|
ip++; break;
|
||||||
|
case IMUL:
|
||||||
|
//DO(IMUL, "Multiply 2 ints on TOS, push value back.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
i2 = pop_int();
|
||||||
|
i1 *= i2;
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case DDIV:
|
||||||
|
//DO(DDIV, "Divide 2 doubles on TOS (upper to lower), push value back.", 1)
|
||||||
|
d1 = pop_double();
|
||||||
|
d2 = pop_double();
|
||||||
|
d1 = d1/d2;
|
||||||
|
push_double(d1);
|
||||||
|
ip++; break;
|
||||||
|
case IDIV:
|
||||||
|
//DO(IDIV, "Divide 2 ints on TOS (upper to lower), push value back.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
i2 = pop_int();
|
||||||
|
i1 = i1/i2;
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case IMOD:
|
||||||
|
//DO(IMOD, "Modulo operation on 2 ints on TOS (upper to lower), push value back.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
i2 = pop_int();
|
||||||
|
i1 = i1 % i2;
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case DNEG:
|
||||||
|
//DO(DNEG, "Negate double on TOS.", 1)
|
||||||
|
d1 = pop_double();
|
||||||
|
d1 = -d1;
|
||||||
|
push_double(d1);
|
||||||
|
ip++; break;
|
||||||
|
case INEG:
|
||||||
|
//DO(INEG, "Negate int on TOS.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
i1 = - i1;
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case IAOR:
|
||||||
|
//DO(IAOR, "Arithmetic OR of 2 ints on TOS, push value back.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
i2 = pop_int();
|
||||||
|
i1 = i1 | i2;
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case IAAND:
|
||||||
|
//DO(IAAND, "Arithmetic AND of 2 ints on TOS, push value back.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
i2 = pop_int();
|
||||||
|
i1 = i1 & i2;
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case IAXOR:
|
||||||
|
//DO(IAXOR, "Arithmetic XOR of 2 ints on TOS, push value back.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
i2 = pop_int();
|
||||||
|
i1 = i1 ^ i2;
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case IPRINT:
|
||||||
|
//DO(IPRINT, "Pop and print integer TOS.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
printf("%llu", i1);
|
||||||
|
ip++; break;
|
||||||
|
case DPRINT:
|
||||||
|
//DO(DPRINT, "Pop and print double TOS.", 1)
|
||||||
|
d1 = pop_double();
|
||||||
|
printf("%f", d1);
|
||||||
|
ip++; break;
|
||||||
|
case SPRINT:
|
||||||
|
//DO(SPRINT, "Pop and print string TOS.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
printf("%s", (char*)i1);
|
||||||
|
ip++; break;
|
||||||
|
case I2D:
|
||||||
|
//DO(I2D, "Convert int on TOS to double.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
d1 = (double)i1;
|
||||||
|
push_double(d1);
|
||||||
|
ip++; break;
|
||||||
|
case D2I:
|
||||||
|
//DO(D2I, "Convert double on TOS to int.", 1)
|
||||||
|
d1 = pop_double();
|
||||||
|
i1 = (int)d1;
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case S2I:
|
||||||
|
//DO(S2I, "Convert string on TOS to int.", 1)
|
||||||
|
ip++; break;
|
||||||
|
case SWAP:
|
||||||
|
//DO(SWAP, "Swap 2 topmost values.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
i2 = pop_int();
|
||||||
|
push_int(i1);
|
||||||
|
push_int(i2);
|
||||||
|
ip++; break;
|
||||||
|
case POP:
|
||||||
|
//DO(POP, "Remove topmost value.", 1)
|
||||||
|
TOS--;
|
||||||
|
ip++; break;
|
||||||
|
case LOADDVAR0:
|
||||||
|
//DO(LOADDVAR0, "Load double from variable 0, push on TOS.", 1)
|
||||||
|
d1 = getlocal_double(current_context, 0);
|
||||||
|
push_double(d1);
|
||||||
|
ip++;break;
|
||||||
|
case LOADDVAR1:
|
||||||
|
//DO(LOADDVAR1, "Load double from variable 1, push on TOS.", 1)
|
||||||
|
d1 = getlocal_double(current_context, 1);
|
||||||
|
push_double(d1);
|
||||||
|
ip++;break;
|
||||||
|
case LOADDVAR2:
|
||||||
|
//DO(LOADDVAR2, "Load double from variable 2, push on TOS.", 1)
|
||||||
|
d1 = getlocal_double(current_context, 2);
|
||||||
|
push_double(d1);
|
||||||
|
ip++;break;
|
||||||
|
case LOADDVAR3:
|
||||||
|
//DO(LOADDVAR3, "Load double from variable 3, push on TOS.", 1)
|
||||||
|
d1 = getlocal_double(current_context, 3);
|
||||||
|
push_double(d1);
|
||||||
|
ip++; break;
|
||||||
|
case LOADIVAR0:
|
||||||
|
//DO(LOADIVAR0, "Load int from variable 0, push on TOS.", 1)
|
||||||
|
i1 = getlocal_int(current_context, 0);
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case LOADIVAR1:
|
||||||
|
//DO(LOADIVAR1, "Load int from variable 1, push on TOS.", 1)
|
||||||
|
i1 = getlocal_int(current_context, 1);
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case LOADIVAR2:
|
||||||
|
//DO(LOADIVAR2, "Load int from variable 2, push on TOS.", 1)
|
||||||
|
i1 = getlocal_int(current_context, 2);
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case LOADIVAR3:
|
||||||
|
//DO(LOADIVAR3, "Load int from variable 3, push on TOS.", 1)
|
||||||
|
i1 = getlocal_int(current_context, 3);
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case LOADSVAR0:
|
||||||
|
//DO(LOADSVAR0, "Load string from variable 0, push on TOS.", 1)
|
||||||
|
i1 = (long long)getlocal_string(current_context, 0);
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case LOADSVAR1:
|
||||||
|
//DO(LOADSVAR1, "Load string from variable 1, push on TOS.", 1)
|
||||||
|
i1 = (long long)getlocal_string(current_context, 1);
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case LOADSVAR2:
|
||||||
|
//DO(LOADSVAR2, "Load string from variable 2, push on TOS.", 1)
|
||||||
|
i1 = (long long)getlocal_string(current_context, 2);
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case LOADSVAR3:
|
||||||
|
//DO(LOADSVAR3, "Load string from variable 3, push on TOS.", 1)
|
||||||
|
i1 = (long long)getlocal_string(current_context, 3);
|
||||||
|
push_int(i1);
|
||||||
|
ip++; break;
|
||||||
|
case STOREDVAR0:
|
||||||
|
//DO(STOREDVAR0, "Pop TOS and store to double variable 0.", 1)
|
||||||
|
d1 = pop_double();
|
||||||
|
putlocal_double(&d1, current_context, 0);
|
||||||
|
ip++; break;
|
||||||
|
case STOREDVAR1:
|
||||||
|
//DO(STOREDVAR1, "Pop TOS and store to double variable 1.", 1)
|
||||||
|
d1 = pop_double();
|
||||||
|
putlocal_double(&d1, current_context, 1);
|
||||||
|
ip++; break;
|
||||||
|
case STOREDVAR2:
|
||||||
|
//DO(STOREDVAR2, "Pop TOS and store to double variable 2.", 1)
|
||||||
|
d1 = pop_double();
|
||||||
|
putlocal_double(&d1, current_context, 2);
|
||||||
|
ip++; break;
|
||||||
|
case STOREDVAR3:
|
||||||
|
//DO(STOREDVAR3, "Pop TOS and store to double variable 3.", 1)
|
||||||
|
d1 = pop_double();
|
||||||
|
putlocal_double(&d1, current_context, 3);
|
||||||
|
ip++; break;
|
||||||
|
case STOREIVAR0:
|
||||||
|
//DO(STOREIVAR0, "Pop TOS and store to int variable 0.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
putlocal_int(&i1, current_context, 0);
|
||||||
|
ip++; break;
|
||||||
|
case STOREIVAR1:
|
||||||
|
//DO(STOREIVAR1, "Pop TOS and store to int variable 1.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
putlocal_int(&i1, current_context, 1);
|
||||||
|
ip++; break;
|
||||||
|
case STOREIVAR2:
|
||||||
|
//DO(STOREIVAR2, "Pop TOS and store to int variable 2.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
putlocal_int(&i1, current_context, 2);
|
||||||
|
ip++; break;
|
||||||
|
case STOREIVAR3:
|
||||||
|
//DO(STOREIVAR3, "Pop TOS and store to int variable 3.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
putlocal_int(&i1, current_context, 3);
|
||||||
|
ip++; break;
|
||||||
|
case STORESVAR0:
|
||||||
|
//DO(STORESVAR0, "Pop TOS and store to string variable 0.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
putlocal_string((int*)&i1, current_context, 0);
|
||||||
|
ip++; break;
|
||||||
|
case STORESVAR1:
|
||||||
|
//DO(STORESVAR1, "Pop TOS and store to string variable 1.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
putlocal_string((int*)&i1, current_context, 1);
|
||||||
|
ip++; break;
|
||||||
|
case STORESVAR2:
|
||||||
|
//DO(STORESVAR2, "Pop TOS and store to string variable 2.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
putlocal_string((int*)&i1, current_context, 2);
|
||||||
|
ip++; break;
|
||||||
|
case STORESVAR3:
|
||||||
|
//DO(STORESVAR3, "Pop TOS and store to string variable 3.", 1)
|
||||||
|
i1 = pop_int();
|
||||||
|
putlocal_string((int*)&i1, current_context, 3);
|
||||||
|
ip++; break;
|
||||||
|
case LOADDVAR:
|
||||||
|
//DO(LOADDVAR, "Load double from variable, whose 2-byte is id inlined to insn stream, push on TOS.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
d1 = getlocal_double(current_context, s1);
|
||||||
|
push_double(d1);
|
||||||
|
ip+=2; break;
|
||||||
|
case LOADIVAR:
|
||||||
|
//DO(LOADIVAR, "Load int from variable, whose 2-byte id is inlined to insn stream, push on TOS.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
i1 = getlocal_int(current_context, s1);
|
||||||
|
push_int(i1);
|
||||||
|
ip+=2; break;
|
||||||
|
case LOADSVAR:
|
||||||
|
//DO(LOADSVAR, "Load string from variable, whose 2-byte id is inlined to insn stream, push on TOS.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
i1 = (long long)getlocal_string(current_context, s1);
|
||||||
|
push_int(i1);
|
||||||
|
ip+=2; break;
|
||||||
|
case STOREDVAR:
|
||||||
|
//DO(STOREDVAR, "Pop TOS and store to double variable, whose 2-byte id is inlined to insn stream.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
d1 = pop_double();
|
||||||
|
putlocal_double(&d1, current_context, s1);
|
||||||
|
ip+=2; break;
|
||||||
|
case STOREIVAR:
|
||||||
|
//DO(STOREIVAR, "Pop TOS and store to int variable, whose 2-byte id is inlined to insn stream.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
i1 = pop_int();
|
||||||
|
putlocal_int(&i1, current_context, s1);
|
||||||
|
ip+=2; break;
|
||||||
|
case STORESVAR:
|
||||||
|
//DO(STORESVAR, "Pop TOS and store to string variable, whose 2-byte id is inlined to insn stream.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
i1 = pop_int();
|
||||||
|
putlocal_string((int*)&i1, current_context, s1);
|
||||||
|
ip+=2; break;
|
||||||
|
case LOADCTXDVAR:
|
||||||
|
//DO(LOADCTXDVAR, "Load double from variable, whose 2-byte context and 2-byte id inlined to insn stream, push on TOS.", 5)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
ip+=2;
|
||||||
|
s2 = *((short*)(code+(ip)));
|
||||||
|
if (find_context(s1) != NULL)
|
||||||
|
{
|
||||||
|
d1 = getlocal_double(find_context(s1), s2);
|
||||||
push_double(d1);
|
push_double(d1);
|
||||||
ip+=8; break;
|
}
|
||||||
case ILOAD:
|
else
|
||||||
//DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9)
|
{
|
||||||
i1 = *((long long*)(code+(++ip)));
|
printf("%s", "Context Not Found");
|
||||||
push_int(i1);
|
|
||||||
ip+=8; break;
|
|
||||||
case SLOAD:
|
|
||||||
s1 = *((short*)(code+(++ip)));
|
|
||||||
push_int((long long)(const_index[s1]));
|
|
||||||
ip+=2; break;
|
|
||||||
case DLOAD0:
|
|
||||||
// DO(DLOAD0, "Load double 0 on TOS.", 1)
|
|
||||||
push_double(0);
|
|
||||||
ip++; break;
|
|
||||||
case ILOAD0:
|
|
||||||
//DO(ILOAD0, "Load int 0 on TOS.", 1)
|
|
||||||
push_int(0);
|
|
||||||
ip++; break;
|
|
||||||
case DLOAD1:
|
|
||||||
//DO(DLOAD1, "Load double 1 on TOS.", 1)
|
|
||||||
push_double(1);
|
|
||||||
ip++; break;
|
|
||||||
case ILOAD1:
|
|
||||||
//DO(ILOAD1, "Load int 1 on TOS.", 1)
|
|
||||||
push_int(1);
|
|
||||||
ip++; break;
|
|
||||||
case DLOADM1:
|
|
||||||
//DO(DLOADM1, "Load double -1 on TOS.", 1)
|
|
||||||
push_double(-1);
|
|
||||||
ip++; break;
|
|
||||||
case ILOADM1:
|
|
||||||
//DO(ILOADM1, "Load int -1 on TOS.", 1)
|
|
||||||
push_int(-1);
|
|
||||||
ip++; break;
|
|
||||||
case DADD:
|
|
||||||
//DO(DADD, "Add 2 doubles on TOS, push value back.", 1)
|
|
||||||
d1 = pop_double();
|
|
||||||
d2 = pop_double();
|
|
||||||
d1 += d2;
|
|
||||||
push_double(d1);
|
|
||||||
ip++; break;
|
|
||||||
case IADD:
|
|
||||||
//DO(IADD, "Add 2 ints on TOS, push value back.", 1)
|
|
||||||
i1 = pop_int();
|
|
||||||
i2 = pop_int();
|
|
||||||
i1 += i2;
|
|
||||||
push_int(i1);
|
|
||||||
ip++; break;
|
|
||||||
case DSUB:
|
|
||||||
//DO(DSUB, "Subtract 2 doubles on TOS (lower from upper), push value back.", 1)
|
|
||||||
d1 = pop_double();
|
|
||||||
d2 = pop_double();
|
|
||||||
d1 -= d2;
|
|
||||||
push_double(d1);
|
|
||||||
ip++; break;
|
|
||||||
case ISUB:
|
|
||||||
//DO(ISUB, "Subtract 2 ints on TOS (lower from upper), push value back.", 1)
|
|
||||||
i1 = pop_int();
|
|
||||||
i2 = pop_int();
|
|
||||||
i1 -= i2;
|
|
||||||
push_int(i1);
|
|
||||||
ip++; break;
|
|
||||||
case DMUL:
|
|
||||||
//DO(DMUL, "Multiply 2 doubles on TOS, push value back.", 1)
|
|
||||||
d1 = pop_double();
|
|
||||||
d2 = pop_double();
|
|
||||||
d1 *= d2;
|
|
||||||
push_double(d1);
|
|
||||||
ip++; break;
|
|
||||||
case IMUL:
|
|
||||||
//DO(IMUL, "Multiply 2 ints on TOS, push value back.", 1)
|
|
||||||
i1 = pop_int();
|
|
||||||
i2 = pop_int();
|
|
||||||
i1 *= i2;
|
|
||||||
push_int(i1);
|
|
||||||
ip++; break;
|
|
||||||
case DDIV:
|
|
||||||
//DO(DDIV, "Divide 2 doubles on TOS (upper to lower), push value back.", 1)
|
|
||||||
d1 = pop_double();
|
|
||||||
d2 = pop_double();
|
|
||||||
d1 /= d2;
|
|
||||||
push_double(d1);
|
|
||||||
ip++; break;
|
|
||||||
case IDIV:
|
|
||||||
//DO(IDIV, "Divide 2 ints on TOS (upper to lower), push value back.", 1)
|
|
||||||
i1 = pop_int();
|
|
||||||
i2 = pop_int();
|
|
||||||
i1 /= i2;
|
|
||||||
push_int(i1);
|
|
||||||
ip++; break;
|
|
||||||
case IMOD:
|
|
||||||
//DO(IMOD, "Modulo operation on 2 ints on TOS (upper to lower), push value back.", 1)
|
|
||||||
i1 = pop_int();
|
|
||||||
i2 = pop_int();
|
|
||||||
i1 %= i2;
|
|
||||||
push_int(i1);
|
|
||||||
ip++; break;
|
|
||||||
case DNEG:
|
|
||||||
//DO(DNEG, "Negate double on TOS.", 1)
|
|
||||||
d1 = pop_double();
|
|
||||||
d1 = -d1;
|
|
||||||
push_double(d1);
|
|
||||||
ip++; break;
|
|
||||||
case INEG:
|
|
||||||
//DO(INEG, "Negate int on TOS.", 1)
|
|
||||||
i1 = pop_int();
|
|
||||||
i1 = - i1;
|
|
||||||
push_int(i1);
|
|
||||||
ip++; break;
|
|
||||||
case IAOR:
|
|
||||||
//DO(IAOR, "Arithmetic OR of 2 ints on TOS, push value back.", 1)
|
|
||||||
i1 = pop_int();
|
|
||||||
i2 = pop_int();
|
|
||||||
i1 = i1 | i2;
|
|
||||||
push_int(i1);
|
|
||||||
ip++; break;
|
|
||||||
case IAAND:
|
|
||||||
//DO(IAAND, "Arithmetic AND of 2 ints on TOS, push value back.", 1)
|
|
||||||
ip++; break;
|
|
||||||
case IAXOR:
|
|
||||||
//DO(IAXOR, "Arithmetic XOR of 2 ints on TOS, push value back.", 1)
|
|
||||||
case IPRINT:
|
|
||||||
//DO(IPRINT, "Pop and print integer TOS.", 1)
|
|
||||||
i1 = pop_int();
|
|
||||||
printf("%d", i1);
|
|
||||||
ip++; break;
|
|
||||||
case DPRINT:
|
|
||||||
//DO(DPRINT, "Pop and print double TOS.", 1)
|
|
||||||
d1 = pop_double();
|
|
||||||
printf("%f", d1);
|
|
||||||
ip++; break;
|
|
||||||
case SPRINT:
|
|
||||||
//DO(SPRINT, "Pop and print string TOS.", 1)
|
|
||||||
i1 = pop_int();
|
|
||||||
printf("%s", (char*)i1);
|
|
||||||
ip++; break;
|
|
||||||
case I2D:
|
|
||||||
//DO(I2D, "Convert int on TOS to double.", 1)
|
|
||||||
i1 = pop_int();
|
|
||||||
d1 = (double)i1;
|
|
||||||
push_double(d1);
|
|
||||||
ip++; break;
|
|
||||||
case D2I:
|
|
||||||
//DO(D2I, "Convert double on TOS to int.", 1)
|
|
||||||
d1 = pop_double();
|
|
||||||
i1 = (int)d1;
|
|
||||||
push_int(i1);
|
|
||||||
ip++; break;
|
|
||||||
case SWAP:
|
|
||||||
//DO(SWAP, "Swap 2 topmost values.", 1)
|
|
||||||
i1 = pop_int();
|
|
||||||
i2 = pop_int();
|
|
||||||
push_int(i1);
|
|
||||||
push_int(i2);
|
|
||||||
ip++; break;
|
|
||||||
case POP:
|
|
||||||
//DO(POP, "Remove topmost value.", 1)
|
|
||||||
TOS--;
|
|
||||||
ip++; break;
|
|
||||||
case STOP:
|
|
||||||
//DO(STOP, "Stop execution.", 1)
|
|
||||||
exec_status = 0;
|
exec_status = 0;
|
||||||
break;
|
}
|
||||||
case CALL:
|
ip+=2; break;
|
||||||
s1 = *((short*)(code+(++ip)));
|
case LOADCTXIVAR:
|
||||||
ip+=2; push_ret(ip);
|
//DO(LOADCTXIVAR, "Load int from variable, whose 2-byte context and 2-byte id is inlined to insn stream, push on TOS.", 5)
|
||||||
push_context(current_context);
|
s1 = *((short*)(code+(++ip)));
|
||||||
current_context = create_context(s1, phash_table, &code);
|
ip+=2;
|
||||||
ip = 0; break;
|
s2 = *((short*)(code+(ip)));
|
||||||
case RETURN:
|
if (find_context(s1) != NULL)
|
||||||
remove_context(current_context);
|
{
|
||||||
current_context = pop_context();
|
i1 = getlocal_int(find_context(s1), s2);
|
||||||
code = phash_table[current_context->id]->code;
|
push_int(i1);
|
||||||
ip = pop_ret(); break;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%s", "Context Not Found");
|
||||||
|
exec_status = 0;
|
||||||
|
}
|
||||||
|
ip+=2; break;
|
||||||
|
case LOADCTXSVAR:
|
||||||
|
//DO(LOADCTXSVAR, "Load string from variable, whose 2-byte context and 2-byte id is inlined to insn stream, push on TOS.", 5)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
ip+=2;
|
||||||
|
s2 = *((short*)(code+(ip)));
|
||||||
|
if (find_context(s1) != NULL)
|
||||||
|
{
|
||||||
|
i1 = (long long)getlocal_string(find_context(s1), s2);
|
||||||
|
push_double(i1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%s", "Context Not Found");
|
||||||
|
exec_status = 0;
|
||||||
|
}
|
||||||
|
ip+=2; break;
|
||||||
|
case STORECTXDVAR:
|
||||||
|
//DO(STORECTXDVAR, "Pop TOS and store to double variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
ip+=2;
|
||||||
|
s2 = *((short*)(code+(ip)));
|
||||||
|
d1 = pop_double();
|
||||||
|
if (find_context(s1) != NULL)
|
||||||
|
{
|
||||||
|
putlocal_double(&d1, find_context(s1), s2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%s", "Context Not Found");
|
||||||
|
exec_status = 0;
|
||||||
|
}
|
||||||
|
ip+=2; break;
|
||||||
|
case STORECTXIVAR:
|
||||||
|
//DO(STORECTXIVAR, "Pop TOS and store to int variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
ip+=2;
|
||||||
|
s2 = *((short*)(code+(ip)));
|
||||||
|
i1 = pop_int();
|
||||||
|
if (find_context(s1) != NULL)
|
||||||
|
{
|
||||||
|
putlocal_int(&i1, find_context(s1), s2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%s", "Context Not Found");
|
||||||
|
exec_status = 0;
|
||||||
|
}
|
||||||
|
ip+=2; break;
|
||||||
|
case STORECTXSVAR:
|
||||||
|
//DO(STORECTXSVAR, "Pop TOS and store to string variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
ip+=2;
|
||||||
|
s2 = *((short*)(code+(ip)));
|
||||||
|
i1 = pop_int();
|
||||||
|
if (find_context(s1) != NULL)
|
||||||
|
{
|
||||||
|
putlocal_string((int*)&d1, find_context(s1), s2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%s", "Context Not Found");
|
||||||
|
exec_status = 0;
|
||||||
|
}
|
||||||
|
ip+=2; break;
|
||||||
|
case DCMP:
|
||||||
|
//DO(DCMP, "Compare 2 topmost doubles, pushing libc-style comparator value cmp(upper, lower) as integer.", 1)
|
||||||
|
d1 = TOS[tp-1];
|
||||||
|
d2 = TOS[tp-2];
|
||||||
|
push_double(cmp_double(&d1, &d2));
|
||||||
|
ip++; break;
|
||||||
|
case ICMP:
|
||||||
|
//DO(ICMP, "Compare 2 topmost ints, pushing libc-style comparator value cmp(upper, lower) as integer.", 1)
|
||||||
|
i1 = get_int(tp-1);
|
||||||
|
i2 = get_int(tp-2);
|
||||||
|
push_int(cmp_int(&i1, &i2));
|
||||||
|
ip++; break;
|
||||||
|
case JA:
|
||||||
|
//DO(JA, "Jump always, next two bytes - signed offset of jump destination.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
ip += (2+s1); break;
|
||||||
|
case IFICMPNE:
|
||||||
|
// DO(IFICMPNE, "Compare two topmost integers and jump if upper != lower, next two bytes - signed offset of jump destination.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
ip+=2;
|
||||||
|
i1 = get_int(tp-1);
|
||||||
|
i2 = get_int(tp-2);
|
||||||
|
if (i1 != i2)
|
||||||
|
ip += s1;
|
||||||
|
break;
|
||||||
|
case IFICMPE:
|
||||||
|
//DO(IFICMPE, "Compare two topmost integers and jump if upper == lower, next two bytes - signed offset of jump destination.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
ip+=2;
|
||||||
|
i1 = get_int(tp-1);
|
||||||
|
i2 = get_int(tp-2);
|
||||||
|
if (i1 == i2)
|
||||||
|
ip += s1;
|
||||||
|
break;
|
||||||
|
case IFICMPG:
|
||||||
|
//DO(IFICMPG, "Compare two topmost integers and jump if upper > lower, next two bytes - signed offset of jump destination.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
ip+=2;
|
||||||
|
i1 = get_int(tp-1);
|
||||||
|
i2 = get_int(tp-2);
|
||||||
|
if (i1 > i2)
|
||||||
|
ip += s1;
|
||||||
|
break;
|
||||||
|
case IFICMPGE:
|
||||||
|
//DO(IFICMPGE, "Compare two topmost integers and jump if upper >= lower, next two bytes - signed offset of jump destination.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
ip+=2;
|
||||||
|
i1 = get_int(tp-1);
|
||||||
|
i2 = get_int(tp-2);
|
||||||
|
if (i1 >= i2)
|
||||||
|
ip += s1;
|
||||||
|
break;
|
||||||
|
case IFICMPL:
|
||||||
|
//DO(IFICMPL, "Compare two topmost integers and jump if upper < lower, next two bytes - signed offset of jump destination.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
ip+=2;
|
||||||
|
i1 = get_int(tp-1);
|
||||||
|
i2 = get_int(tp-2);
|
||||||
|
if (i1 < i2)
|
||||||
|
ip += s1;
|
||||||
|
break;
|
||||||
|
case IFICMPLE:
|
||||||
|
//DO(IFICMPLE, "Compare two topmost integers and jump if upper <= lower, next two bytes - signed offset of jump destination.", 3)
|
||||||
|
s1 = *((short*)(code+(++ip)));
|
||||||
|
ip+=2;
|
||||||
|
i1 = get_int(tp-1);
|
||||||
|
i2 = get_int(tp-2);
|
||||||
|
if (i1 <= i2)
|
||||||
|
ip += s1;
|
||||||
|
break;
|
||||||
|
case DUMP:
|
||||||
|
//DO(DUMP, "Dump value on TOS, without removing it.", 1)
|
||||||
|
i1 = get_int(tp-1);
|
||||||
|
d1 = TOS[tp-1];
|
||||||
|
printf("TOS: Double:%e Integer:%llu Hex:%#08llx", d1, i1, i1);
|
||||||
|
ip++; break;
|
||||||
|
case STOP:
|
||||||
|
//DO(STOP, "Stop execution.", 1)
|
||||||
|
exec_status = 0;
|
||||||
|
break;
|
||||||
|
case CALL:
|
||||||
|
//DO(CALL, "Call function, next two bytes - unsigned function id.", 3)
|
||||||
|
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:
|
||||||
|
//DO(RETURN, "Return to call location", 1)
|
||||||
|
remove_context(current_context);
|
||||||
|
current_context = pop_context();
|
||||||
|
code = phash_table[current_context->id]->code;
|
||||||
|
ip = pop_ret(); break;
|
||||||
|
case BREAK:
|
||||||
|
//DO(BREAK, "Breakpoint for the debugger.", 1)
|
||||||
|
getchar();
|
||||||
|
ip++; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
remove_context(current_context);
|
remove_context(current_context);
|
||||||
getchar();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double cmp_double(long long* a, long long* b)
|
||||||
|
{
|
||||||
|
if (*a == *b) return 0;
|
||||||
|
else if (*a > *b) return 1;
|
||||||
|
else return -1;
|
||||||
|
}
|
||||||
|
long long cmp_int(long long* a, long long* b)
|
||||||
|
{
|
||||||
|
if (*a == *b) return 0;
|
||||||
|
else if (*a > *b) return 1;
|
||||||
|
else return -1;
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ enum opcode
|
||||||
SLOAD,
|
SLOAD,
|
||||||
DLOAD0,
|
DLOAD0,
|
||||||
ILOAD0,
|
ILOAD0,
|
||||||
|
SLOAD0,
|
||||||
DLOAD1,
|
DLOAD1,
|
||||||
ILOAD1,
|
ILOAD1,
|
||||||
DLOADM1,
|
DLOADM1,
|
||||||
|
@ -31,10 +32,58 @@ enum opcode
|
||||||
SPRINT,
|
SPRINT,
|
||||||
I2D,
|
I2D,
|
||||||
D2I,
|
D2I,
|
||||||
|
S2I,
|
||||||
SWAP,
|
SWAP,
|
||||||
POP,
|
POP,
|
||||||
|
LOADDVAR0,
|
||||||
|
LOADDVAR1,
|
||||||
|
LOADDVAR2,
|
||||||
|
LOADDVAR3,
|
||||||
|
LOADIVAR0,
|
||||||
|
LOADIVAR1,
|
||||||
|
LOADIVAR2,
|
||||||
|
LOADIVAR3,
|
||||||
|
LOADSVAR0,
|
||||||
|
LOADSVAR1,
|
||||||
|
LOADSVAR2,
|
||||||
|
LOADSVAR3,
|
||||||
|
STOREDVAR0,
|
||||||
|
STOREDVAR1,
|
||||||
|
STOREDVAR2,
|
||||||
|
STOREDVAR3,
|
||||||
|
STOREIVAR0,
|
||||||
|
STOREIVAR1,
|
||||||
|
STOREIVAR2,
|
||||||
|
STOREIVAR3,
|
||||||
|
STORESVAR0,
|
||||||
|
STORESVAR1,
|
||||||
|
STORESVAR2,
|
||||||
|
STORESVAR3,
|
||||||
|
LOADDVAR,
|
||||||
|
LOADIVAR,
|
||||||
|
LOADSVAR,
|
||||||
|
STOREDVAR,
|
||||||
|
STOREIVAR,
|
||||||
|
STORESVAR,
|
||||||
|
LOADCTXDVAR,
|
||||||
|
LOADCTXIVAR,
|
||||||
|
LOADCTXSVAR,
|
||||||
|
STORECTXDVAR,
|
||||||
|
STORECTXIVAR,
|
||||||
|
STORECTXSVAR,
|
||||||
|
DCMP,
|
||||||
|
ICMP,
|
||||||
|
JA,
|
||||||
|
IFICMPNE,
|
||||||
|
IFICMPE,
|
||||||
|
IFICMPG,
|
||||||
|
IFICMPGE,
|
||||||
|
IFICMPL,
|
||||||
|
IFICMPLE,
|
||||||
|
DUMP,
|
||||||
STOP,
|
STOP,
|
||||||
CALL,
|
CALL,
|
||||||
RETURN
|
RETURN,
|
||||||
|
BREAK
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
|
@ -15,6 +15,13 @@ long long pop_int()
|
||||||
return number.num_i;
|
return number.num_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long long get_int(int id)
|
||||||
|
{
|
||||||
|
tos_num number;
|
||||||
|
number.num_d = TOS[id];
|
||||||
|
return number.num_i;
|
||||||
|
}
|
||||||
|
|
||||||
void push_double(double num)
|
void push_double(double num)
|
||||||
{
|
{
|
||||||
TOS[tp++] = num;
|
TOS[tp++] = num;
|
||||||
|
|
|
@ -13,6 +13,7 @@ int initTOS();
|
||||||
void push_int(long long);
|
void push_int(long long);
|
||||||
void push_double(double);
|
void push_double(double);
|
||||||
long long pop_int();
|
long long pop_int();
|
||||||
|
long long get_int(int);
|
||||||
double pop_double();
|
double pop_double();
|
||||||
|
|
||||||
#endif
|
#endif
|
108
VaninVM/opc.txt
108
VaninVM/opc.txt
|
@ -1,11 +1,11 @@
|
||||||
#define FOR_BYTECODES(DO) \
|
#define FOR_BYTECODES(DO) \
|
||||||
-DO(INVALID, "Invalid instruction.", 1) \
|
?-DO(INVALID, "Invalid instruction.", 1) \
|
||||||
+DO(DLOAD, "Load double on TOS, inlined into insn stream.", 9) \
|
+DO(DLOAD, "Load double on TOS, inlined into insn stream.", 9) \
|
||||||
+DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9) \
|
+DO(ILOAD, "Load int on TOS, inlined into insn stream.", 9) \
|
||||||
+DO(SLOAD, "Load string reference on TOS, next two bytes - constant id.", 3) \
|
+DO(SLOAD, "Load string reference on TOS, next two bytes - constant id.", 3) \
|
||||||
+DO(DLOAD0, "Load double 0 on TOS.", 1) \
|
+DO(DLOAD0, "Load double 0 on TOS.", 1) \
|
||||||
+DO(ILOAD0, "Load int 0 on TOS.", 1) \
|
+DO(ILOAD0, "Load int 0 on TOS.", 1) \
|
||||||
DO(SLOAD0, "Load empty string on TOS.", 1) \
|
+DO(SLOAD0, "Load empty string on TOS.", 1) \
|
||||||
+DO(DLOAD1, "Load double 1 on TOS.", 1) \
|
+DO(DLOAD1, "Load double 1 on TOS.", 1) \
|
||||||
+DO(ILOAD1, "Load int 1 on TOS.", 1) \
|
+DO(ILOAD1, "Load int 1 on TOS.", 1) \
|
||||||
+DO(DLOADM1, "Load double -1 on TOS.", 1) \
|
+DO(DLOADM1, "Load double -1 on TOS.", 1) \
|
||||||
|
@ -26,60 +26,60 @@
|
||||||
+DO(IAXOR, "Arithmetic XOR of 2 ints on TOS, push value back.", 1) \
|
+DO(IAXOR, "Arithmetic XOR of 2 ints on TOS, push value back.", 1) \
|
||||||
+DO(IPRINT, "Pop and print integer TOS.", 1) \
|
+DO(IPRINT, "Pop and print integer TOS.", 1) \
|
||||||
+DO(DPRINT, "Pop and print double TOS.", 1) \
|
+DO(DPRINT, "Pop and print double TOS.", 1) \
|
||||||
DO(SPRINT, "Pop and print string TOS.", 1) \
|
+DO(SPRINT, "Pop and print string TOS.", 1) \
|
||||||
+DO(I2D, "Convert int on TOS to double.", 1) \
|
+DO(I2D, "Convert int on TOS to double.", 1) \
|
||||||
+DO(D2I, "Convert double on TOS to int.", 1) \
|
+DO(D2I, "Convert double on TOS to int.", 1) \
|
||||||
DO(S2I, "Convert string on TOS to int.", 1) \
|
+DO(S2I, "Convert string on TOS to int.", 1) \
|
||||||
+DO(SWAP, "Swap 2 topmost values.", 1) \
|
+DO(SWAP, "Swap 2 topmost values.", 1) \
|
||||||
+DO(POP, "Remove topmost value.", 1) \
|
+DO(POP, "Remove topmost value.", 1) \
|
||||||
DO(LOADDVAR0, "Load double from variable 0, push on TOS.", 1) \
|
+DO(LOADDVAR0, "Load double from variable 0, push on TOS.", 1) \
|
||||||
DO(LOADDVAR1, "Load double from variable 1, push on TOS.", 1) \
|
+DO(LOADDVAR1, "Load double from variable 1, push on TOS.", 1) \
|
||||||
DO(LOADDVAR2, "Load double from variable 2, push on TOS.", 1) \
|
+DO(LOADDVAR2, "Load double from variable 2, push on TOS.", 1) \
|
||||||
DO(LOADDVAR3, "Load double from variable 3, push on TOS.", 1) \
|
+DO(LOADDVAR3, "Load double from variable 3, push on TOS.", 1) \
|
||||||
DO(LOADIVAR0, "Load int from variable 0, push on TOS.", 1) \
|
+DO(LOADIVAR0, "Load int from variable 0, push on TOS.", 1) \
|
||||||
DO(LOADIVAR1, "Load int from variable 1, push on TOS.", 1) \
|
+DO(LOADIVAR1, "Load int from variable 1, push on TOS.", 1) \
|
||||||
DO(LOADIVAR2, "Load int from variable 2, push on TOS.", 1) \
|
+DO(LOADIVAR2, "Load int from variable 2, push on TOS.", 1) \
|
||||||
DO(LOADIVAR3, "Load int from variable 3, push on TOS.", 1) \
|
+DO(LOADIVAR3, "Load int from variable 3, push on TOS.", 1) \
|
||||||
DO(LOADSVAR0, "Load string from variable 0, push on TOS.", 1) \
|
+DO(LOADSVAR0, "Load string from variable 0, push on TOS.", 1) \
|
||||||
DO(LOADSVAR1, "Load string from variable 1, push on TOS.", 1) \
|
+DO(LOADSVAR1, "Load string from variable 1, push on TOS.", 1) \
|
||||||
DO(LOADSVAR2, "Load string from variable 2, push on TOS.", 1) \
|
+DO(LOADSVAR2, "Load string from variable 2, push on TOS.", 1) \
|
||||||
DO(LOADSVAR3, "Load string from variable 3, push on TOS.", 1) \
|
+DO(LOADSVAR3, "Load string from variable 3, push on TOS.", 1) \
|
||||||
DO(STOREDVAR0, "Pop TOS and store to double variable 0.", 1) \
|
+DO(STOREDVAR0, "Pop TOS and store to double variable 0.", 1) \
|
||||||
DO(STOREDVAR1, "Pop TOS and store to double variable 1.", 1) \
|
+DO(STOREDVAR1, "Pop TOS and store to double variable 1.", 1) \
|
||||||
DO(STOREDVAR2, "Pop TOS and store to double variable 2.", 1) \
|
+DO(STOREDVAR2, "Pop TOS and store to double variable 2.", 1) \
|
||||||
DO(STOREDVAR3, "Pop TOS and store to double variable 3.", 1) \
|
+DO(STOREDVAR3, "Pop TOS and store to double variable 3.", 1) \
|
||||||
DO(STOREIVAR0, "Pop TOS and store to int variable 0.", 1) \
|
+DO(STOREIVAR0, "Pop TOS and store to int variable 0.", 1) \
|
||||||
DO(STOREIVAR1, "Pop TOS and store to int variable 1.", 1) \
|
+DO(STOREIVAR1, "Pop TOS and store to int variable 1.", 1) \
|
||||||
DO(STOREIVAR2, "Pop TOS and store to int variable 2.", 1) \
|
+DO(STOREIVAR2, "Pop TOS and store to int variable 2.", 1) \
|
||||||
DO(STOREIVAR3, "Pop TOS and store to int variable 3.", 1) \
|
+DO(STOREIVAR3, "Pop TOS and store to int variable 3.", 1) \
|
||||||
DO(STORESVAR0, "Pop TOS and store to string variable 0.", 1) \
|
+DO(STORESVAR0, "Pop TOS and store to string variable 0.", 1) \
|
||||||
DO(STORESVAR1, "Pop TOS and store to string variable 1.", 1) \
|
+DO(STORESVAR1, "Pop TOS and store to string variable 1.", 1) \
|
||||||
DO(STORESVAR2, "Pop TOS and store to string variable 2.", 1) \
|
+DO(STORESVAR2, "Pop TOS and store to string variable 2.", 1) \
|
||||||
DO(STORESVAR3, "Pop TOS and store to string variable 3.", 1) \
|
+DO(STORESVAR3, "Pop TOS and store to string variable 3.", 1) \
|
||||||
DO(LOADDVAR, "Load double from variable, whose 2-byte is id inlined to insn stream, push on TOS.", 3) \
|
+DO(LOADDVAR, "Load double from variable, whose 2-byte is id inlined to insn stream, push on TOS.", 3) \
|
||||||
DO(LOADIVAR, "Load int from variable, whose 2-byte id is inlined to insn stream, push on TOS.", 3) \
|
+DO(LOADIVAR, "Load int from variable, whose 2-byte id is inlined to insn stream, push on TOS.", 3) \
|
||||||
DO(LOADSVAR, "Load string from variable, whose 2-byte id is inlined to insn stream, push on TOS.", 3) \
|
+DO(LOADSVAR, "Load string from variable, whose 2-byte id is inlined to insn stream, push on TOS.", 3) \
|
||||||
DO(STOREDVAR, "Pop TOS and store to double variable, whose 2-byte id is inlined to insn stream.", 3) \
|
+DO(STOREDVAR, "Pop TOS and store to double variable, whose 2-byte id is inlined to insn stream.", 3) \
|
||||||
DO(STOREIVAR, "Pop TOS and store to int variable, whose 2-byte id is inlined to insn stream.", 3) \
|
+DO(STOREIVAR, "Pop TOS and store to int variable, whose 2-byte id is inlined to insn stream.", 3) \
|
||||||
DO(STORESVAR, "Pop TOS and store to string variable, whose 2-byte id is inlined to insn stream.", 3) \
|
+DO(STORESVAR, "Pop TOS and store to string variable, whose 2-byte id is inlined to insn stream.", 3) \
|
||||||
DO(LOADCTXDVAR, "Load double from variable, whose 2-byte context and 2-byte id inlined to insn stream, push on TOS.", 5) \
|
+DO(LOADCTXDVAR, "Load double from variable, whose 2-byte context and 2-byte id inlined to insn stream, push on TOS.", 5) \
|
||||||
DO(LOADCTXIVAR, "Load int from variable, whose 2-byte context and 2-byte id is inlined to insn stream, push on TOS.", 5) \
|
+DO(LOADCTXIVAR, "Load int from variable, whose 2-byte context and 2-byte id is inlined to insn stream, push on TOS.", 5) \
|
||||||
DO(LOADCTXSVAR, "Load string from variable, whose 2-byte context and 2-byte id is inlined to insn stream, push on TOS.", 5) \
|
+DO(LOADCTXSVAR, "Load string from variable, whose 2-byte context and 2-byte id is inlined to insn stream, push on TOS.", 5) \
|
||||||
DO(STORECTXDVAR, "Pop TOS and store to double variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \
|
+DO(STORECTXDVAR, "Pop TOS and store to double variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \
|
||||||
DO(STORECTXIVAR, "Pop TOS and store to int variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \
|
+DO(STORECTXIVAR, "Pop TOS and store to int variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \
|
||||||
DO(STORECTXSVAR, "Pop TOS and store to string variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \
|
+DO(STORECTXSVAR, "Pop TOS and store to string variable, whose 2-byte context and 2-byte id is inlined to insn stream.", 5) \
|
||||||
DO(DCMP, "Compare 2 topmost doubles, pushing libc-style comparator value cmp(upper, lower) as integer.", 1) \
|
?+DO(DCMP, "Compare 2 topmost doubles, pushing libc-style comparator value cmp(upper, lower) as integer.", 1) \
|
||||||
DO(ICMP, "Compare 2 topmost ints, pushing libc-style comparator value cmp(upper, lower) as integer.", 1) \
|
?+DO(ICMP, "Compare 2 topmost ints, pushing libc-style comparator value cmp(upper, lower) as integer.", 1) \
|
||||||
DO(JA, "Jump always, next two bytes - signed offset of jump destination.", 3) \
|
+DO(JA, "Jump always, next two bytes - signed offset of jump destination.", 3) \
|
||||||
DO(IFICMPNE, "Compare two topmost integers and jump if upper != lower, next two bytes - signed offset of jump destination.", 3) \
|
+DO(IFICMPNE, "Compare two topmost integers and jump if upper != lower, next two bytes - signed offset of jump destination.", 3) \
|
||||||
DO(IFICMPE, "Compare two topmost integers and jump if upper == lower, next two bytes - signed offset of jump destination.", 3) \
|
+DO(IFICMPE, "Compare two topmost integers and jump if upper == lower, next two bytes - signed offset of jump destination.", 3) \
|
||||||
DO(IFICMPG, "Compare two topmost integers and jump if upper > lower, next two bytes - signed offset of jump destination.", 3) \
|
+DO(IFICMPG, "Compare two topmost integers and jump if upper > lower, next two bytes - signed offset of jump destination.", 3) \
|
||||||
DO(IFICMPGE, "Compare two topmost integers and jump if upper >= lower, next two bytes - signed offset of jump destination.", 3) \
|
+DO(IFICMPGE, "Compare two topmost integers and jump if upper >= lower, next two bytes - signed offset of jump destination.", 3) \
|
||||||
DO(IFICMPL, "Compare two topmost integers and jump if upper < lower, next two bytes - signed offset of jump destination.", 3) \
|
+DO(IFICMPL, "Compare two topmost integers and jump if upper < lower, next two bytes - signed offset of jump destination.", 3) \
|
||||||
DO(IFICMPLE, "Compare two topmost integers and jump if upper <= lower, next two bytes - signed offset of jump destination.", 3) \
|
+DO(IFICMPLE, "Compare two topmost integers and jump if upper <= lower, next two bytes - signed offset of jump destination.", 3) \
|
||||||
DO(DUMP, "Dump value on TOS, without removing it.", 1) \
|
+DO(DUMP, "Dump value on TOS, without removing it.", 1) \
|
||||||
+DO(STOP, "Stop execution.", 1) \
|
+DO(STOP, "Stop execution.", 1) \
|
||||||
DO(CALL, "Call function, next two bytes - unsigned function id.", 3) \
|
+DO(CALL, "Call function, next two bytes - unsigned function id.", 3) \
|
||||||
DO(CALLNATIVE, "Call native function, next two bytes - id of the native function.", 3) \
|
?DO(CALLNATIVE, "Call native function, next two bytes - id of the native function.", 3) \
|
||||||
DO(RETURN, "Return to call location", 1) \
|
+DO(RETURN, "Return to call location", 1) \
|
||||||
DO(BREAK, "Breakpoint for the debugger.", 1)
|
?+DO(BREAK, "Breakpoint for the debugger.", 1)
|
Loading…
Reference in a new issue