aboutsummaryrefslogtreecommitdiff
path: root/src/core/vmrunner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/vmrunner.cpp')
-rw-r--r--src/core/vmrunner.cpp280
1 files changed, 280 insertions, 0 deletions
diff --git a/src/core/vmrunner.cpp b/src/core/vmrunner.cpp
new file mode 100644
index 0000000..1942d74
--- /dev/null
+++ b/src/core/vmrunner.cpp
@@ -0,0 +1,280 @@
+#include "vmrunner.hpp"
+#include "coreshared.hpp"
+#include <cstdlib>
+unsigned getHash(const char *s)
+{
+ unsigned r=5381;char c;
+ while((c=(*s++)))r=((r<<5)+r)+c;
+ return r;
+}
+Idata& blrScriptVM::fetchData(SPara para,bool forcerw)
+{
+ static Idata cret;
+ switch (para.type)
+ {
+ case 0:
+ if(forcerw)throw;
+ cret.i()=para.data.i;cret.type=0;
+ return cret;
+ case 1:
+ if(forcerw)throw;
+ cret.r()=para.data.r;cret.type=1;
+ return cret;
+ case 2:
+ return ir[para.data.i];
+ case 3:
+ return rr[para.data.i];
+ case 4:
+ return ia[para.data.i];
+ case 5:
+ return ra[para.data.i];
+ case 6:
+ return ia[ir[para.data.i].i()];
+ case 7:
+ return ra[ir[para.data.i].i()];
+ default:
+ throw;
+ }
+}
+int blrScriptVM::mgetc()
+{
+ if(cbyte-sbyte<fsize)
+ {++cbyte;return (int)*(cbyte-1);}
+ else return -1;
+}
+void blrScriptVM::readPara(SPara *para)
+{
+ para->type=mgetc();
+ para->data.d=0;
+ int l=0;
+ switch(para->type)
+ {
+ case 1: l=8;break;
+ case 0: case 4: case 5: l=4;break;
+ case 2: case 3: case 6: case 7: l=1;break;
+ default: break;
+ }
+ for(int i=0;i<l;++i)
+ {
+ para->data.d<<=8LL;
+ para->data.d|=(unsigned long long)mgetc();
+ }
+}
+int blrScriptVM::loadLSBFromMemory(const char *ptr,DWORD size)
+{
+ cbyte=sbyte=ptr;fsize=size;
+ int ibyt=0,infunc=0;
+ while(~(ibyt=mgetc()))
+ {
+ ++ic;inst[ic].id=ibyt;
+ switch(inst[ic].id)
+ {
+ case 0xFF: case 0x02:
+ {
+ int nl=mgetc();
+ if(nl==-1)return 1;
+ if(inst[ic].id==0xFF){if(infunc)return 1;else infunc=1;}
+ if(inst[ic].id==0x02)if(!infunc)return 1;
+ inst[ic].para1.fnc=(char*)calloc(sizeof(char),nl+1);
+ inst[ic].para1.type=8;
+ for(int i=0;i<nl;++i)inst[ic].para1.fnc[i]=mgetc();
+ if(inst[ic].id==0xFF)
+ {
+ fncent[fncnt].pos=ic;
+ fncent[fncnt++].hash=getHash(inst[ic].para1.fnc);
+ }
+ }
+ break;
+ case 0x00: break;
+ case 0xFE:
+ if(!infunc)return 1;
+ infunc=0;
+ break;
+ case 0x0F:
+ if(!infunc)return 1;
+ break;
+ case 0x01: case 0x0C: case 0x0D:
+ case 0x0E: case 0x11: case 0x12:
+ case 0x13: case 0x14: case 0x15:
+ case 0x16: case 0x21:
+ if(!infunc)return 1;
+ readPara(&inst[ic].para1);
+ break;
+ case 0x03: case 0x04: case 0x05:
+ case 0x06: case 0x07: case 0x08:
+ case 0x09: case 0x0A: case 0x0B:
+ case 0x22: case 0x23:
+ if(!infunc)return 1;
+ readPara(&inst[ic].para1);
+ readPara(&inst[ic].para2);
+ break;
+ }
+ }
+ return 0;
+}
+int blrScriptVM::getInstCount(){return pinst;}
+void blrScriptVM::runFunction(const char *fncnym)
+{
+ int nymhash=getHash(fncnym),cur=0;pinst=0;
+ for(int i=0;i<fncnt;++i)if(nymhash==fncent[i].hash){cur=fncent[i].pos;break;}
+ while(inst[cur].id!=0xFE)
+ {
+ int jmp=0;++pinst;
+ //printf("@offset %d, instId 0x%x\n",cur,inst[cur].id);
+ rr[100].r()=0.01667;
+ //printf("r00: %f, r01: %f\n",rr[0].r(),rr[1].r());
+ switch(inst[cur].id)
+ {
+ case 0x00:
+ //no-op
+ break;
+ case 0xFF:
+ //no-op
+ break;
+ case 0x01:
+ callStk.push(fetchData(inst[cur].para1));
+ break;
+ case 0x02:
+ //callFnc(inst[cur].para1.fnc);
+ //callstk.clear();
+ //printf("stubbed call %s\n",inst[cur].para1.fnc);
+ break;
+ case 0x03:
+ fetchData(inst[cur].para1,true)=fetchData(inst[cur].para2);
+ break;
+ case 0x04:
+ fetchData(inst[cur].para1,true)+=fetchData(inst[cur].para2);
+ break;
+ case 0x05:
+ fetchData(inst[cur].para1,true)-=fetchData(inst[cur].para2);
+ break;
+ case 0x06:
+ fetchData(inst[cur].para1,true)*=fetchData(inst[cur].para2);
+ break;
+ case 0x07:
+ fetchData(inst[cur].para1,true)/=fetchData(inst[cur].para2);
+ break;
+ case 0x08:
+ fetchData(inst[cur].para1,true)%=fetchData(inst[cur].para2);
+ break;
+ case 0x09:
+ fetchData(inst[cur].para1,true)&=fetchData(inst[cur].para2);
+ break;
+ case 0x0A:
+ fetchData(inst[cur].para1,true)|=fetchData(inst[cur].para2);
+ break;
+ case 0x0B:
+ fetchData(inst[cur].para1,true)^=fetchData(inst[cur].para2);
+ break;
+ case 0x0C:
+ fetchData(inst[cur].para1,true)=~fetchData(inst[cur].para1,true);
+ break;
+ case 0x0D:
+ ++fetchData(inst[cur].para1,true);
+ break;
+ case 0x0E:
+ --fetchData(inst[cur].para1,true);
+ break;
+ case 0x0F:
+ callStk.clear();
+ break;
+ case 0x11:
+ switch (fetchData(inst[cur].para1,true).type)
+ {
+ case 0:
+ fetchData(inst[cur].para1,true)=
+ fetchData(inst[cur].para1,true).ltz()?ione:izero;
+ break;
+ case 1:
+ fetchData(inst[cur].para1,true)=
+ fetchData(inst[cur].para1,true).ltz()?rone:rzero;
+ break;
+ }
+ break;
+ case 0x12:
+ switch (fetchData(inst[cur].para1,true).type)
+ {
+ case 0:
+ fetchData(inst[cur].para1,true)=
+ fetchData(inst[cur].para1,true).elz()?ione:izero;
+ break;
+ case 1:
+ fetchData(inst[cur].para1,true)=
+ fetchData(inst[cur].para1,true).elz()?rone:rzero;
+ break;
+ }
+ break;
+ case 0x13:
+ switch (fetchData(inst[cur].para1,true).type)
+ {
+ case 0:
+ fetchData(inst[cur].para1,true)=
+ fetchData(inst[cur].para1,true).gtz()?ione:izero;
+ break;
+ case 1:
+ fetchData(inst[cur].para1,true)=
+ fetchData(inst[cur].para1,true).gtz()?rone:rzero;
+ break;
+ }
+ break;
+ case 0x14:
+ switch (fetchData(inst[cur].para1,true).type)
+ {
+ case 0:
+ fetchData(inst[cur].para1,true)=
+ fetchData(inst[cur].para1,true).egz()?ione:izero;
+ break;
+ case 1:
+ fetchData(inst[cur].para1,true)=
+ fetchData(inst[cur].para1,true).egz()?rone:rzero;
+ break;
+ }
+ break;
+ case 0x15:
+ switch (fetchData(inst[cur].para1,true).type)
+ {
+ case 0:
+ fetchData(inst[cur].para1,true)=
+ fetchData(inst[cur].para1,true).eqz()?ione:izero;
+ break;
+ case 1:
+ fetchData(inst[cur].para1,true)=
+ fetchData(inst[cur].para1,true).eqz()?rone:rzero;
+ break;
+ }
+ break;
+ case 0x16:
+ switch (fetchData(inst[cur].para1,true).type)
+ {
+ case 0:
+ fetchData(inst[cur].para1,true)=
+ fetchData(inst[cur].para1,true).nez()?ione:izero;
+ break;
+ case 1:
+ fetchData(inst[cur].para1,true)=
+ fetchData(inst[cur].para1,true).nez()?rone:rzero;
+ break;
+ }
+ break;
+ case 0x21:
+ cur=fetchData(inst[cur].para1).i();
+ jmp=1;
+ break;
+ case 0x22:
+ if(fetchData(inst[cur].para1).eqz())
+ cur=fetchData(inst[cur].para2).i(),jmp=1;
+ break;
+ case 0x23:
+ if(fetchData(inst[cur].para1).nez())
+ cur=fetchData(inst[cur].para2).i(),jmp=1;
+ break;
+ }
+ if(!jmp)++cur;
+ }
+}
+void blrScriptVM::vmInit()
+{
+}
+void blrScriptVM::vmDeinit()
+{
+}