Skip to content

Instantly share code, notes, and snippets.

@maxattack
Last active May 5, 2018 20:36
Show Gist options
  • Save maxattack/c73d49eee35540006284c5534cb72475 to your computer and use it in GitHub Desktop.
Save maxattack/c73d49eee35540006284c5534cb72475 to your computer and use it in GitHub Desktop.
Unstructured Embeddable Scripting VM for a toy game engine, 15 minutes in...
#include <cstdio>
#include <cstdint>
#include <cstdlib>
#include "glm/glm.hpp"
#include "glm/gtx/type_aligned.hpp"
namespace Trinket {
enum class OP : uint8_t {
NOOP,
PUSH32_FROM_ADDR,
POP32_TO_ADDR,
ADD_F32,
EXIT,
};
typedef int32_t Address;
union Slot32 {
int32_t ival;
float fval;
Address aval;
};
typedef glm::aligned_vec4 Slot128;
class VirtualMachine {
private:
Slot32 ram[1024 * 1024];
Slot32 stack[128];
Slot128 vstack[128];
public:
inline Slot32* GetPtr32(Address addr) {
// todo: bounds check
return &ram[addr];
}
void Execute(uint8_t* instructions, int nbytes) {
auto ps = stack;
auto pv = vstack;
auto pc = instructions;
auto pend = instructions + nbytes;
while (pc < pend) {
auto op = (OP) *pc;
++pc;
switch(op) {
default:
case OP::NOOP:
break;
case OP::PUSH32_FROM_ADDR:
// todo: stack bounds check
// todo: instruction bounds check
// todo: ram bounds check
*ps = ram[*(Address*)pc];
++ps;
pc += sizeof(Address);
break;
case OP::POP32_TO_ADDR:
// todo: stack bounds check
// todo: instruction bounds check
// todo: ram bounds check
ram[*(Address*)pc] = *(ps-1);
--ps;
pc += sizeof(Address);
break;
case OP::ADD_F32:
// todo: stack bounds check
(ps-2)->fval += (ps-1)->fval;
--ps;
break;
case OP::EXIT:
pc = pend;
break;
}
}
}
};
}
int main(int argc, char * argv[]) {
puts("Hello, World");
using namespace Trinket;
static VirtualMachine vm;
vm.GetPtr32(1)->fval = 20.0f;
vm.GetPtr32(2)->fval = 22.0f;
static uint8_t instructions[] = {
(uint8_t) OP::PUSH32_FROM_ADDR, 1, 0, 0, 0,
(uint8_t) OP::PUSH32_FROM_ADDR, 2, 0, 0, 0,
(uint8_t) OP::ADD_F32,
(uint8_t) OP::POP32_TO_ADDR, 3, 0, 0, 0,
(uint8_t) OP::EXIT,
};
vm.Execute(instructions, sizeof(instructions));
printf("Result = %f\n", vm.GetPtr32(3)->fval);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment