ref: 676c163887770438587b64aae2679a93ba836de2
dir: /vm.c/
#include <u.h> #include <libc.h> #include "vm.h" #include "ops.h" #include "objects.h" extern int debug; Frame *stack = nil; u32int runinst(u32int *ptr) { u32int len, opcode; void (*func)(Frame*,u32int); opcode = (*ptr) & 0x0000ffff; len = ((*ptr) & 0xffff0000) >> 16; if (oplookup(opcode, &func)) { func(stack, len); // if (func) changes pc, ignore it if (ptr == stack->pc) { stack->pc += len; } return len; } fprint(2, "error: %r\n"); return 0; } void runstack(u32int *ptr) { Frame *n = malloc(sizeof(Frame)); n->next = stack; stack = n; stack->pc = ptr; while (runinst(stack->pc)) { ; } } void retstack(void) { Frame *p, *c; p = stack->next; c = stack; if (!p) goto fin; stack = p; fin: free(c); } void vmrun(u32int *ptr) { stack = nil; // TODO clean stack runstack(ptr); } int compile = 0; typedef struct Object Object; struct Object { int id; char type; union { Shader s; Buffer b; }; }; Object objects[256]; int numobjects = 0; int genshader(void) { int id; if (numobjects >= 256) { werrstr("not enough free objects!"); return -1; } id = numobjects++; objects[id].id = id; objects[id].type = SHADER; objects[id].s.buffer = nil; objects[id].s.len = -1; return id; } int genbuffer(long size) { int id; if (numobjects >= 256) { werrstr("not enough free objects!"); return -1; } id = numobjects; objects[id].id = id; objects[id].type = BUFFER; objects[id].b.len = size; objects[id].b.buffer = malloc(size); if (!objects[id].b.buffer) { werrstr("cannot allocate memory: %r"); return -1; } numobjects++; return id; } int getnumobjects() { return numobjects; } long getbufferlength(int id) { if (objects[id].type != BUFFER) { werrstr("invalid object type!"); return -1; } return objects[id].b.len; } long getshaderlength(int id) { long len; if (objects[id].type != SHADER) { werrstr("invalid object type!"); return -1; } len = objects[id].s.len; return len < 0 ? 0 : len; } int getobjecttype(int id) { return objects[id].type; } vlong getobjectid(int num) { if (num >= numobjects) { werrstr("invalid object number: %d", num); return -1; } return objects[num].id; }