Added documentation to vvm
This commit is contained in:
@@ -3,6 +3,25 @@ Veits Virtual Machine
|
|||||||
|
|
||||||
A virtual machine that executes assembler-like code.
|
A virtual machine that executes assembler-like code.
|
||||||
|
|
||||||
|
Performance
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Performance is pretty okay on basic, small programs. The included factorial
|
||||||
|
function takes 0.1 second on 100000 iterations. As a scale, a Python 3.3 program
|
||||||
|
on the same machine using the code:
|
||||||
|
|
||||||
|
``
|
||||||
|
def fac(n):
|
||||||
|
if n < 2: return 1
|
||||||
|
else: return n * fac(n-1)
|
||||||
|
fac(12)
|
||||||
|
``
|
||||||
|
|
||||||
|
takes about 3.7 seconds on 100000 iterations.
|
||||||
|
|
||||||
|
This does not say anything about overall performance though and I am not
|
||||||
|
sure whether this small, funny test has any real value in measuring performance.
|
||||||
|
Also, Python is much more feature-rich, so you cannot compare the two at all.
|
||||||
|
|
||||||
Instruction set
|
Instruction set
|
||||||
---------------
|
---------------
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
|
||||||
|
/*A factorial program in my dsl*/
|
||||||
int factorial[] = {
|
int factorial[] = {
|
||||||
LOAD, -3,
|
LOAD, -3,
|
||||||
ICONST, 2,
|
ICONST, 2,
|
||||||
@@ -20,7 +21,11 @@ int factorial[] = {
|
|||||||
HALT
|
HALT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief main
|
||||||
|
*
|
||||||
|
* executes code in my dsl.
|
||||||
|
*/
|
||||||
int main(){
|
int main(){
|
||||||
int code[] = { ICONST, 72, PRINT, ICONST, 101, PRINT, ICONST, 108,
|
int code[] = { ICONST, 72, PRINT, ICONST, 101, PRINT, ICONST, 108,
|
||||||
PRINT, ICONST, 108, PRINT, ICONST, 111, PRINT, ICONST, 44, PRINT,
|
PRINT, ICONST, 108, PRINT, ICONST, 111, PRINT, ICONST, 44, PRINT,
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "opcode.h"
|
#include "opcode.h"
|
||||||
|
|
||||||
|
/*The opcodes as chars*/
|
||||||
const char* opcodes[] = {"IADD", "ISUB", "IMULT", "IDIV", "IMOD",
|
const char* opcodes[] = {"IADD", "ISUB", "IMULT", "IDIV", "IMOD",
|
||||||
"ILT", "IEQ", "IGT", "BR", "BRT", "BRF", "ICONST", "LOAD", "GLOAD",
|
"ILT", "IEQ", "IGT", "BR", "BRT", "BRF", "ICONST", "LOAD", "GLOAD",
|
||||||
"STORE", "GSTORE", "PRINT", "POP", "HALT", "ILEQ", "IGEQ", "CALL", "RET",
|
"STORE", "GSTORE", "PRINT", "POP", "HALT", "ILEQ", "IGEQ", "CALL", "RET",
|
||||||
"IPRINT", "FETCH", "IINC", "IDEC" };
|
"IPRINT", "FETCH", "IINC", "IDEC" };
|
||||||
|
|
||||||
|
/*The argument counter for the opcodes*/
|
||||||
int nargs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
|
int nargs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
|
||||||
0, 2, 0, 0, 0, 0, 0 };
|
0, 2, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ instruction* setup_instructions(){
|
|||||||
int i;
|
int i;
|
||||||
static instruction ins[IDEC+1];
|
static instruction ins[IDEC+1];
|
||||||
ins[0].operands = 0;
|
ins[0].operands = 0;
|
||||||
ins[0].name = NULL;
|
ins[0].name = "\0";
|
||||||
for(i = 1; i <= IDEC; i++){
|
for(i = 1; i <= IDEC; i++){
|
||||||
ins[i].operands = nargs[i-1];
|
ins[i].operands = nargs[i-1];
|
||||||
ins[i].name = opcodes[i-1];
|
ins[i].name = opcodes[i-1];
|
||||||
|
@@ -1,38 +1,72 @@
|
|||||||
#ifndef OPCODE_H
|
#ifndef OPCODE_H
|
||||||
#define OPCODE_H
|
#define OPCODE_H
|
||||||
|
/*Addition operation*/
|
||||||
#define IADD 1
|
#define IADD 1
|
||||||
|
/*Subtraction operation*/
|
||||||
#define ISUB 2
|
#define ISUB 2
|
||||||
|
/*Multiplication operation*/
|
||||||
#define IMULT 3
|
#define IMULT 3
|
||||||
|
/*Division operation*/
|
||||||
#define IDIV 4
|
#define IDIV 4
|
||||||
|
/*Modulo operation*/
|
||||||
#define IMOD 5
|
#define IMOD 5
|
||||||
|
/*< operation*/
|
||||||
#define ILT 6
|
#define ILT 6
|
||||||
|
/*== operation*/
|
||||||
#define IEQ 7
|
#define IEQ 7
|
||||||
|
/*> operation*/
|
||||||
#define IGT 8
|
#define IGT 8
|
||||||
|
/*branch operation*/
|
||||||
#define BR 9
|
#define BR 9
|
||||||
|
/*branch if true operation*/
|
||||||
#define BRT 10
|
#define BRT 10
|
||||||
|
/*branch if false operation*/
|
||||||
#define BRF 11
|
#define BRF 11
|
||||||
|
/*put operation*/
|
||||||
#define ICONST 12
|
#define ICONST 12
|
||||||
|
/*load variable operation*/
|
||||||
#define LOAD 13
|
#define LOAD 13
|
||||||
|
/*load global variable operation*/
|
||||||
#define GLOAD 14
|
#define GLOAD 14
|
||||||
|
/*store variable operation*/
|
||||||
#define STORE 15
|
#define STORE 15
|
||||||
|
/*store global variable operation*/
|
||||||
#define GSTORE 16
|
#define GSTORE 16
|
||||||
|
/*print operation*/
|
||||||
#define PRINT 17
|
#define PRINT 17
|
||||||
|
/*pop operation*/
|
||||||
#define POP 18
|
#define POP 18
|
||||||
|
/*end/halt operation*/
|
||||||
#define HALT 19
|
#define HALT 19
|
||||||
|
/*<= operation*/
|
||||||
#define ILEQ 20
|
#define ILEQ 20
|
||||||
|
/*>= operation*/
|
||||||
#define IGEQ 21
|
#define IGEQ 21
|
||||||
|
/*call subroutine operation*/
|
||||||
#define CALL 22
|
#define CALL 22
|
||||||
|
/*return from subroutine operation*/
|
||||||
#define RET 23
|
#define RET 23
|
||||||
|
/*print integer operation*/
|
||||||
#define IPRINT 24
|
#define IPRINT 24
|
||||||
|
/*fetch operation*/
|
||||||
#define FETCH 25
|
#define FETCH 25
|
||||||
|
/*++ operation*/
|
||||||
#define IINC 26
|
#define IINC 26
|
||||||
|
/*-- operation*/
|
||||||
#define IDEC 27
|
#define IDEC 27
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief An instruction struct
|
||||||
|
*
|
||||||
|
* Defines an instruction based on
|
||||||
|
* its number of operands and its name.
|
||||||
|
*/
|
||||||
typedef struct{
|
typedef struct{
|
||||||
int operands;
|
int operands;
|
||||||
const char* name;
|
const char* name;
|
||||||
}instruction;
|
}instruction;
|
||||||
|
|
||||||
|
/*sets up the instruction struct*/
|
||||||
instruction* setup_instructions();
|
instruction* setup_instructions();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -3,8 +3,13 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define LENGTH(x) (sizeof(x) / sizeof(x[0]))
|
/**
|
||||||
|
* @brief die
|
||||||
|
* @param code -> the error code
|
||||||
|
* @param message -> the error message
|
||||||
|
*
|
||||||
|
* Lets the program die and emits an error message.
|
||||||
|
*/
|
||||||
static inline void die(int code, const char* message){
|
static inline void die(int code, const char* message){
|
||||||
fprintf(stderr, "%s", message);
|
fprintf(stderr, "%s", message);
|
||||||
exit(code);
|
exit(code);
|
||||||
|
13
vvm/src/vm.c
13
vvm/src/vm.c
@@ -5,6 +5,19 @@
|
|||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
#define DEBUG FALSE
|
#define DEBUG FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief disassemble
|
||||||
|
* @param sp -> stack pointer
|
||||||
|
* @param fp -> function pointer
|
||||||
|
* @param ip -> instruction pointer
|
||||||
|
* @param opcode -> current opcode
|
||||||
|
* @param ins -> instruction struct
|
||||||
|
* @param code -> opcodes
|
||||||
|
* @param stack -> stack
|
||||||
|
*
|
||||||
|
* prints current operations and a stack trace.
|
||||||
|
* Is invoked if DEBUG is defined.
|
||||||
|
*/
|
||||||
static inline void disassemble(int sp, int fp, int ip, int opcode, instruction* ins, int code[], int stack[]){
|
static inline void disassemble(int sp, int fp, int ip, int opcode, instruction* ins, int code[], int stack[]){
|
||||||
if(opcode > 0 && opcode < 24)
|
if(opcode > 0 && opcode < 24)
|
||||||
printf("%04d: %s(%d)\n", ip, ins[opcode].name, opcode);
|
printf("%04d: %s(%d)\n", ip, ins[opcode].name, opcode);
|
||||||
|
@@ -6,5 +6,13 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "opcode.h"
|
#include "opcode.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief vm_execute
|
||||||
|
* @param code -> instructions
|
||||||
|
* @param ip -> starting point
|
||||||
|
* @param datasize -> maximum data size
|
||||||
|
* @param length -> length of program
|
||||||
|
*/
|
||||||
void vm_execute(int[], int, int, int);
|
void vm_execute(int[], int, int, int);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user