ref: a66be92f63ec59c1811403eb7b95fa72588beee6
dir: /vm.c/
#include <u.h> #include <libc.h> #include "vm.h" #include "ops.h" #include "objects.h" extern int debug; #define IDVALID(c) (c < numobjects) 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; vlong genshader(void) { vlong 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; } vlong genbuffer(long size) { vlong 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; } vlong getnumobjects() { return numobjects; } long getbufferlength(vlong id) { if (objects[id].type != BUFFER) { werrstr("invalid object type!"); return -1; } return objects[id].b.len; } long getshaderlength(vlong 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(vlong id) { return objects[id].type; } vlong getobjectid(vlong num) { if (num >= numobjects) { werrstr("invalid object number: %lld", num); return -1; } return objects[num].id; } int writeshader(vlong id, void *data, long n, long offset) { char *buf; if (!IDVALID(id)) { werrstr("invalid object id %lld", id); return 0; } if (objects[id].type != SHADER) { werrstr("invalid object type: %lld != SHADER", id); return 0; } buf = (char*)objects[id].s.buffer; if (!buf) { objects[id].s.len = n+offset; objects[id].s.buffer = malloc(objects[id].s.len); buf = (char*)objects[id].s.buffer; } if (!buf) { sysfatal("out of memory"); return 0; } if (offset+n > objects[id].s.len) { objects[id].s.len = n+offset; objects[id].s.buffer = realloc(objects[id].s.buffer, objects[id].s.len); buf = (char*)objects[id].s.buffer; } if (!buf) { sysfatal("out of memory!"); return 0; } buf += offset; memcpy(buf, data, n); return n; } int writebuffer(vlong id, void *data, long n, long offset) { char *buf; if (!IDVALID(id)) { werrstr("invalid object id %lld", id); return 0; } if (objects[id].type != BUFFER) { werrstr("invalid object type: %lld != BUFFER", id); return 0; } if (offset+n > objects[id].b.len) { return -1; } buf = &objects[id].b.buffer[offset]; memcpy(buf, data, n); return n; } int compileshader(vlong id) { werrstr("not implemented!"); return 0; } int readshader(vlong id, void *data, long n, long offset) { char *buf; if (!IDVALID(id)) { werrstr("invalid id %lld", id); return 0; } if (objects[id].type != SHADER) { werrstr("invalid object type: %lld != SHADER", id); return 0; } buf = (char*)objects[id].s.buffer; if (!buf) { werrstr("shader is empty"); return 0; } if (offset+n > objects[id].b.len) { n = objects[id].s.len - offset; } if (n <= 0) return 0; buf = &buf[offset]; memcpy(data, buf, n); return n; } int readbuffer(vlong id, void *data, long n, long offset) { char *buf; if (!IDVALID(id)) { werrstr("invalid id %lld", id); return 0; } if (objects[id].type != BUFFER) { werrstr("invalid object type: %lld != BUFFER", id); return 0; } if (offset+n > objects[id].b.len) { n = objects[id].b.len - offset; } if (n <= 0) return 0; buf = &objects[id].b.buffer[offset]; memcpy(data, buf, n); return n; }