12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069 |
- #include <precomp.h>
- #include <wasabicfg.h>
- #include <api/skin/widgets/mb/scriptbrowser.h>
- #include <api/script/scriptmgr.h>
- #include <api/script/script.h>
- #include "vcpu.h"
- #include "opcodes.h"
- #include <api/wndmgr/container.h>
- #include <api/wndmgr/msgbox.h>
- #include <api/script/objecttable.h>
- #include <api/syscb/callbacks/consolecb.h>
- #include "../nu/AutoWide.h"
- ScriptObjectManager *VCPU::scriptManager = NULL;
- void VCPU::shutdown()
- {
- foreach(globalDlfList)
- FREE(globalDlfList.getfor()->functionName);
- delete globalDlfList.getfor();
- endfor
- globalDlfList.removeAll();
- atoms.deleteAll();
- }
- // -------------------------------------------------------------
- void VCPU::push(VCPUscriptVar v) {
- CpuStack.push(v);
- VSP++;
- }
- // -------------------------------------------------------------
- void VCPU::push(scriptVar v) {
- VCPUscriptVar _v;
- _v.v = v;
- CpuStack.push(_v);
- VSP++;
- }
- void VCPU::RemoveOldScripts()
- {
- while (scriptsToRemove.getNumItems())
- {
- int id = scriptsToRemove.getFirst();
- VCPU::removeScript(id);
- scriptsToRemove.delByPos(0);
- }
- }
- // -------------------------------------------------------------
- VCPUscriptVar VCPU::pop() {
- if (VSP <= 0) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_POPEMPTYSTACK);
- VCPUscriptVar v;
- MEMSET(&v, 0, sizeof(v));
- return v;
- // ASSERT(0);
- }
- VCPUscriptVar v;
- CpuStack.pop(&v);
- VSP--;
- if (VSP == 0)
- VCPU::RemoveOldScripts(); // benski> TODO: dunno if this is the best place for this
- return v;
- }
- // -------------------------------------------------------------
- VCPUscriptVar VCPU::peekAt(int n) {
- if (VSP <= n) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_INVALIDPEEKSTACK);
- VCPUscriptVar v;
- MEMSET(&v, 0, sizeof(v));
- return v;
- // ASSERT(0);
- }
- VCPUscriptVar v={0,{0},0};
- CpuStack.peekAt(&v, n);
- return v;
- }
- // -------------------------------------------------------------
- int VCPU::assignNewScriptId() {
- return numScripts++;
- }
- // -------------------------------------------------------------
- int VCPU::oldClassToClassId(int id) {
- if (id < SCRIPT_OBJECT) return id;
- if (id >= 0x10000) return id;
- switch (id) {
- case 7 : return ObjectTable::getClassFromName(L"Object");
- case 8 : return ObjectTable::getClassFromName(L"SystemObject");
- case 9 : return ObjectTable::getClassFromName(L"Container");
- case 10: return ObjectTable::getClassFromName(L"Layout");
- case 11: return ObjectTable::getClassFromName(L"Button");
- case 12: return ObjectTable::getClassFromName(L"Slider");
- case 13: return ObjectTable::getClassFromName(L"Text");
- case 14: return ObjectTable::getClassFromName(L"Image");
- case 15: return ObjectTable::getClassFromName(L"Anim");
- case 16: return ObjectTable::getClassFromName(L"Vis");
- case 17: return ObjectTable::getClassFromName(L"Component");
- case 18: return ObjectTable::getClassFromName(L"ToggleButton");
- case 19: return ObjectTable::getClassFromName(L"Timer");
- case 20: return ObjectTable::getClassFromName(L"Layer");
- case 21: return ObjectTable::getClassFromName(L"GuiObject");
- case 22: return ObjectTable::getClassFromName(L"AnimatedLayer");
- case 23: return ObjectTable::getClassFromName(L"Browser");
- case 24: return ObjectTable::getClassFromName(L"Edit");
- case 25: return ObjectTable::getClassFromName(L"Map");
- case 26: return ObjectTable::getClassFromName(L"Popup");
- case 27: return ObjectTable::getClassFromName(L"Title");
- case 28: return ObjectTable::getClassFromName(L"ComponentBucket");
- case 29: return ObjectTable::getClassFromName(L"Status");
- case 30: return ObjectTable::getClassFromName(L"Region");
- case 31: return ObjectTable::getClassFromName(L"Wac");
- case 32: return ObjectTable::getClassFromName(L"List");
- case 33: return ObjectTable::getClassFromName(L"SBitList");
- case 34: return ObjectTable::getClassFromName(L"SEqVis");
- default: Script::guruMeditation(NULL, GURU_INVALIDOLDID, L"xlat error", id);
- break;
- }
- return SCRIPT_INT; // heh =)
- }
- // -------------------------------------------------------------
- int VCPU::addScript(void *mem, int memsize, int id) {
- int i,j;
- int translateobjects = 0;
- char *p = (char *)mem;
- int hdr=0;
- if (!MEMCMP(p, "FG\x03\x04\x14\00\00\00\00", 8))
- hdr=1;
- else if (!MEMCMP(p, "FG\x03\x04\x15\00\00\00\00", 8))
- hdr=2;
- else if (!MEMCMP(p, "FG\x03\x04\x16\00\00\00\00", 8))
- hdr=3;
- else if (!MEMCMP(p, "FG\x03\x04\x17\00\00\00\00", 8))
- hdr=4;
- else if (!MEMCMP(p, "FG\x03\x04", 4)) {
- if (*(p+4) > 0x17)
- hdr = -1;
- }
- switch (hdr) {
- case -1:
- Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_FUTUREFORMAT, L"NEED LATEST VERSION");
- return -1;
- case 0:
- Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_INVALIDHEADER);
- return -1;
- case 1:
- Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_OLDFORMAT, L"DEPRECATED BINARY");
- return -1;
- case 2:
- translateobjects=1;
- break;
- case 3:
- case 4:
- break;
- }
- SOM::getSystemObjectByScriptId(id)->setIsOldFormat(translateobjects);
- p+=8;
- TList<int> *typetable = SOM::getSystemObjectByScriptId(id)->getTypesList();
- typetable->removeAll();
- if (!translateobjects) {
-
- int nGuids = *(int *)p;
- p+=sizeof(int);
- for (int z=0;z<nGuids;z++) {
- GUID g;
- MEMCPY(&g, p, sizeof(GUID));
- p+=sizeof(GUID);
- char zz[256] = {0};
- nsGUID::toChar(g, zz);
- int t = ObjectTable::getClassFromGuid(g);
- if (t == -1) {
- DebugStringW(L"maki class entry %d not found : %s\n", z, zz);
- // __asm int 3;
- }
- typetable->addItem(t);
- }
- }
- // -------------------------------------------------------------
- // Load DLF Table
- int DLFEntryBase = DLFentryTable.getNumItems();
- int nDLFentries = *(int *)p;
- p+=sizeof(int);
- for (i=0;i<nDLFentries;i++) {
- int basetype = *(int *)p;
- int pt = basetype;
- int type = basetype;
- p+=sizeof(int);
- if (translateobjects) {
- basetype = oldClassToClassId(basetype);
- } else
- if (basetype >= CLASS_ID_BASE && basetype < 0x10000)
- basetype = typetable->enumItem(basetype - CLASS_ID_BASE);
- if (basetype == -1) {
- //CUT!!!! so annoying Std::messageBox("Error while loading a script, a component is missing", "Oops", 0);
- DebugStringW(L"Tried to link DLF %d (class entry %d) but the class isn't here\n", i, pt - CLASS_ID_BASE);
- //return -1;
- }
- type = basetype;
- uint16_t stringLen = *(uint16_t *)p;
- p+=sizeof(uint16_t);
- char functionName[65536+1] = {0};
- MEMCPY(functionName, p, stringLen);
- functionName[stringLen]=0;
- p+=stringLen;
- // check if entry seems valid
- if (!*functionName) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_INVALIDFUNCINDLF);
- // api->messageBox("Invalid function name in DLF table", "Script Error", MSGBOX_OK, NULL, NULL);
- return -1;
- }
- // ok, register this function
- VCPUdlfEntry *e = new VCPUdlfEntry;
- e->basetype = type;
- #ifdef _WIN32
- int size = MultiByteToWideChar(CP_UTF8, 0, functionName, -1, 0,0);
- if (size)
- {
- wchar_t *wide = (wchar_t *)MALLOC(size*sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, functionName, -1, wide,size);
- e->functionName = wide;
- }
- else
- e->functionName = 0;
- #else
- e->functionName = WCSDUP(AutoWide(functionName));
- #warning port me
- #endif
- e->scriptId = id;
- // insert safe values
- e->nparams = -1;
- e->DLFid = -1;
- e->ptr = NULL;
- DLFentryTable.addItem(e);
- setupDLF(e, DLFEntryBase);
- }
- // -------------------------------------------------------------
- // Load VAR Table
- int variableBase = variablesTable.getNumItems();
- int nVariables = *(int *)p;
- p+=sizeof(int);
- for (i=0;i<nVariables;i++) {
- scriptVar e;
- MEMCPY(&e, p, sizeof(scriptVar));
- p+=sizeof(scriptVar);
- VCPUscriptVar *v = new VCPUscriptVar;
- v->isaclass = 0;
- if (e.type >= 0x10000) {
- int type = e.type;
- int id;
- do {
- id = type - 0x10000;
- VCPUscriptVar *v = variablesTable.enumItem(id+variableBase);
- v->isaclass = 1;
- type = v->v.type;
- } while (type >= 0x10000);
-
- }
- if (translateobjects) {
- e.type = oldClassToClassId(e.type);
- } else
- if (e.type >= CLASS_ID_BASE && e.type < 0x10000)
- e.type = typetable->enumItem(e.type - CLASS_ID_BASE);
- v->scriptId = id;
- v->varId = i;
- v->transcient = (*p++ == 0);
- if (hdr >= 4)
- v->isstatic = *p++;
- else
- v->isstatic = 0;
- if (hdr < 4) {
- // Autoassign system variables
- if (e.type == ObjectTable::getClassFromName(L"SystemObject")) {
- SystemObject *so = SOM::getSystemObjectByScriptId(id);
- if (so) e.data.odata = so->getScriptObject(); else e.data.odata = NULL;
- }
- } else {
- if (v->isstatic && e.type == ObjectTable::getClassFromName(L"SystemObject")) {
- SystemObject *so = SOM::getSystemObjectByScriptId(id);
- if (so) e.data.odata = so->getScriptObject(); else e.data.odata = NULL;
- v->isstatic = 0; // disable deletion
- } else if (v->isstatic) {
- // Autoassign class variables
- e.data.odata = ObjectTable::instantiate(e.type);
- if (e.data.odata)
- e.data.odata->vcpu_setScriptId(VSD);
- }
- }
- if (e.type == SCRIPT_STRING)
- {
- wchar_t *emptyString = WMALLOC(1);
- emptyString[0]=0;
- e.data.sdata = emptyString;
- }
- if (e.type == SCRIPT_DOUBLE)
- e.data.ddata = e.data.fdata;
- v->v = e;
- variablesTable.addItem(v);
- }
- // -------------------------------------------------------------
- // Load Strings into string vars
- int nStrings = *(int *)p;
- p+=sizeof(int);
- j=0;
- //CUT: int count=0;
- char string_buf[65536+1] = {0};
- for (i=0;i<nStrings;i++)
- {
- int attach_id = *(int *)p;
- p+=4;
- uint16_t stringLen = *(uint16_t *)p;
- p+=2;
- //char *string;
- //string = (char *)MALLOC(stringLen+1);
- MEMCPY(string_buf, p, stringLen);
- string_buf[stringLen]=0;
- p+=stringLen;
- // find next variable in this script that needs a string attached, and attach it
- VCPUscriptVar *v = variablesTable.enumItem(attach_id+variableBase);
- if (!v)
- {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_EXCEPTION, L"Invalid String ID");
- return -1;
- }
- FREE((wchar_t *)(v->v.data.sdata));
- // strings are stored in UTF-8, but we're using UTF-16 here
- #ifdef _WIN32
- int size = MultiByteToWideChar(CP_UTF8, 0, string_buf, -1, 0,0);
- if (size)
- {
- wchar_t *wide = (wchar_t *)MALLOC(size*sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, string_buf, -1, wide,size);
- v->v.data.sdata = wide;
- }
- else
- v->v.data.sdata = 0;
-
- #else
- #warning port me
- // TODO: benski> change to do one malloc
- v->v.data.sdata = WCSDUP(AutoWide(string_buf));
- #endif
- //FREE(string);
- }
- // -------------------------------------------------------------
- // Load Events into table
- int nEvents = *(int *)p;
- p+=sizeof(int);
- for (i=0;i<nEvents;i++) {
- int varId = *(int *)p;
- p+=sizeof(int);
- int DLFentry = *(int *)p;
- p+=sizeof(int);
- int pointer = *(int *)p;
- p+=sizeof(int);
- // check if this event seems valid
- if (DLFentry >= nDLFentries || DLFentry < 0) {
- // api->messageBox("Invalid event DLF descriptor", "Script Error", MSGBOX_OK, NULL, NULL);
- Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_INVALIDEVENTDLF);
- return -1;
- }
- if (pointer < 0) {
- // api->messageBox("Invalid event address", "Script Error", MSGBOX_OK, NULL, NULL);
- Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_INVALIDEVENTADDR);
- return -1;
- }
- if (varId < 0 || varId >= nVariables) {
- // api->messageBox("Invalid event variable", "Script Error", MSGBOX_OK, NULL, NULL);
- Script::guruMeditation(SOM::getSystemObjectByScriptId(id), GURU_INVALIDEVENTVAR);
- return -1;
- }
- // insert event into table
- VCPUeventEntry *e = new VCPUeventEntry;
- //e->DLFentry = DLFentry + DLFEntryBase;
- e->DLFid = DLFentryTable.enumItem(DLFEntryBase+DLFentry)->DLFid;
- e->pointer = pointer;
- e->scriptId = id;
- e->varId = varId;
- eventsTable.addItem(e);
- }
- // -------------------------------------------------------------
- // Load Code block into code table
- int codeSize = *(int *)p;
- p+=sizeof(int);
- VCPUcodeBlock *c = new VCPUcodeBlock;
- c->codeBlock = p;
- c->dlfBase = DLFEntryBase;
- c->varBase = variableBase;
- c->scriptId = id;
- c->size = codeSize;
- codeTable.addItem(c);
- SystemObject *so = SOM::getSystemObjectByScriptId(id);
- if (so) {
- ScriptObject *sso = so->getScriptObject();
- if (sso)
- sso->vcpu_addAssignedVariable(0, id);
- }
- cacheCount++;
- c->debugsymbols = c->codeBlock+codeSize;
- c->debugsize = memsize - (c->debugsymbols-(char *)mem);
- //WASABI_API_MAKIDEBUG->debugger_createJITD(id); // fucko !!
-
- return id;
- }
- // -------------------------------------------------------------
- int VCPU::varBase(int scriptId) {
- static int lasti=-1;;
- static int lastb=0;
- static int lastid=0;
- if (lastid == scriptId && lasti>=0 && lasti < codeTable.getNumItems()) {
- if (lastid == codeTable.enumItem(lasti)->scriptId)
- return lastb;
- }
- for (int i=0;i<codeTable.getNumItems();i++ ){
- if (codeTable.enumItem(i)->scriptId == scriptId) {
- lasti = i;
- lastid = scriptId;
- lastb = codeTable.enumItem(i)->varBase;
- return lastb;
- }
- }
- Script::guruMeditation(SOM::getSystemObjectByScriptId(scriptId), GURU_INVALIDSCRIPTID);
- ASSERT(0);
- return 0;
- }
- // -------------------------------------------------------------
- int VCPU::nVars(int scriptId) {
- for (int i=0;i<codeTable.getNumItems();i++ ){
- if (codeTable.enumItem(i)->scriptId == scriptId) {
- if (codeTable.getNumItems() == i+1)
- return variablesTable.getNumItems() - codeTable.enumItem(i)->varBase;
- return codeTable.enumItem(i+1)->varBase - codeTable.enumItem(i)->varBase;
- }
- }
- Script::guruMeditation(SOM::getSystemObjectByScriptId(scriptId), GURU_INVALIDSCRIPTID);
- ASSERT(0);
- return 0;
- }
- // -------------------------------------------------------------
- int VCPU::dlfBase(int scriptId) {
- for (int i=0;i<codeTable.getNumItems();i++ ){
- if (codeTable.enumItem(i)->scriptId == scriptId)
- return codeTable.enumItem(i)->dlfBase;
- }
- Script::guruMeditation(SOM::getSystemObjectByScriptId(scriptId), GURU_INVALIDSCRIPTID);
- ASSERT(0);
- return 0;
- }
- // -------------------------------------------------------------
- void VCPU::removeScript(int id)
- {
- // ASSERTPR(VCPU::VSP==0, "Can't unload script while in script");
- if (VCPU::VSP != 0)
- {
- scriptsToRemove.addItem(id);
- return;
- }
- SystemObject *s = SOM::getSystemObjectByScriptId(id);
- if (s)
- {
- s->onUnload();
- delete s;
- }
- PtrList<ScriptObject> *l = SystemObject::getAllScriptObjects();
- int i;
- for (i=0;i<l->getNumItems();i++) {
- ScriptObject *o = l->enumItem(i);
- o->vcpu_delMembers(id);
- }
- int dlfdeleted=0;
- int vardeleted=0;
- for (i=0;i<DLFentryTable.getNumItems();i++) {
- if (DLFentryTable.enumItem(i)->scriptId == id) {
- delrefDLF(DLFentryTable.enumItem(i));
- if (DLFentryTable.enumItem(i)->functionName)
- FREE(DLFentryTable.enumItem(i)->functionName);
- delete DLFentryTable.enumItem(i);
- DLFentryTable.delByPos(i);
- dlfdeleted++;
- i--;
- }
- }
- for (i=0;i<eventsTable.getNumItems();i++) {
- if (eventsTable.enumItem(i)->scriptId == id) {
- delete eventsTable.enumItem(i);
- eventsTable.delByPos(i);
- i--;
- }
- }
- for (i=0;i<variablesTable.getNumItems();i++) {
- if (variablesTable.enumItem(i)->scriptId == id) {
- VCPUscriptVar *v = variablesTable.enumItem(i);
- if (v->isstatic && v->v.type) {
- ObjectTable::destroy(v->v.data.odata);
- }
- if (v->v.type == SCRIPT_STRING)
- if (v->v.data.sdata)
- FREE((wchar_t *)v->v.data.sdata);
- delete v;
- variablesTable.delByPos(i);
- vardeleted++;
- i--;
- }
- }
- for (i=0;i<codeTable.getNumItems();i++) {
- if (codeTable.enumItem(i)->scriptId == id) {
- VCPUcodeBlock *b = codeTable.enumItem(i);
- delete b;
- codeTable.removeByPos(i);
- for (;i<codeTable.getNumItems();i++) {
- codeTable.enumItem(i)->dlfBase-=dlfdeleted;
- codeTable.enumItem(i)->varBase-=vardeleted;
- }
- }
- }
- cacheCount++;
- }
- // -------------------------------------------------------------
- // Find next matching object, starting from start
- int VCPU::findObject(ScriptObject *o, int start, int dlfid, int vcpuid) {
- /* int stop;
- if (vcpuid != -1) {
- int b = varBase(vcpuid);
- if (start < b)
- start = b;
- stop = b + nVars(vcpuid);
- } else {
- stop = variablesTable.getNumItems();
- if (start < 0)
- start = 0;
- }*/
- /* while (start < stop) {
- VCPUscriptVar *v = variablesTable.enumItem(start);
- if (v->v.data.odata == o && !v->transcient && (vcpuid == -1 || v->scriptId == vcpuid))
- return start;
- start++;
- }*/
- return -1;
- }
- // -------------------------------------------------------------
- // Assign DLF functionId to class exported functions, starting from the last non initialized DLF
- void VCPU::setupDLF(VCPUdlfEntry *e, int dlfEntryBase) {
- if (ObjectTable::addrefDLF(e, highestDLFId)) {
- newDlf();
- }
- }
- int VCPU::newDlf() {
- return highestDLFId++;
- }
- void VCPU::resetDlf() {
- highestDLFId = 0;
- }
- void VCPU::registerGlobalDlf(VCPUdlfEntry *e, int dlf) {
- ASSERT(dlf == globalDlfList.getNumItems());
- VCPUdlfEntry *_e = new VCPUdlfEntry;
- MEMCPY(_e, e, sizeof(VCPUdlfEntry));
- _e->functionName = WCSDUP(e->functionName);
- globalDlfList.addItem(_e);
- }
- void VCPU::delrefDLF(VCPUdlfEntry *e) {
- ObjectTable::delrefDLF(e);
- }
- // -------------------------------------------------------------
- TList<VCPUscriptVar> VCPU::plist;
- // -------------------------------------------------------------
- int VCPU::runEvent(VCPUeventEntry *e, int np, int pbase) {
- #ifdef WASABI_COMPILE_MAKIDEBUG
- /*if (WASABI_API_MAKIDEBUG && WASABI_API_MAKIDEBUG->debugger_isActive()) {
- if (WASABI_API_MAKIDEBUG->debugger_filterEvent(e->scriptId, e->DLFid)) {
- DebugString("Skipping event\n");
- scriptVar v;
- v.type = SCRIPT_INT;
- v.data.idata = 0;
- VCPU::push(v);
- return 1;
- }
- }*/
- #endif
- for (int z=0;z<np;z++) {
- VCPU::push(plist[z+pbase]);
- }
- runCode(e->scriptId, e->pointer, np);
- #ifdef WASABI_COMPILE_MAKIDEBUG
- /* if (WASABI_API_MAKIDEBUG && WASABI_API_MAKIDEBUG->debugger_isActive())
- WASABI_API_MAKIDEBUG->debugger_eventComplete();*/
- #endif
- return 1;
- }
- // This is the function that actually executes the event. In the future, it will sequencially parse all loaded scripts in reversed load order and stop
- // either at the end of the chain OR as soon as one of the event used "complete;" in its code
- // -------------------------------------------------------------
- scriptVar VCPU::executeEvent(scriptVar v, int functionId, int np, int vcpuid) {
- VCPUscriptVar retvar={0,{0},0};
- int pbase = plist.getNumItems();
- int varId=0;
- complete = 0;
- for (int z=0;z<np;z++) {
- VCPUscriptVar vcpuv = VCPU::pop();
- plist.addItem(vcpuv);
- }
- // find all variables containing this object, and run their event if it's traped
- int next = 0;
- while (!complete) {
- VCPUscriptVar *vclass=NULL;
- int inheritedevent=0;
- // varId = VCPU::findObject(v.data.odata, varId, vcpuid);
- int event;
- ASSERT(v.data.odata != NULL);
- varId = ((ScriptObject *)v.data.odata)->vcpu_getAssignedVariable(next, vcpuid, functionId, &next, &event, &inheritedevent);
- if (varId < 0) break;
- VCPUscriptVar *vc = variablesTable.enumItem(varId);
- ScriptObject *thisobject = (ScriptObject *)v.data.odata;
- VCPUeventEntry *e = eventsTable.enumItem(event);
- int r_varId = varId;
- if (!vc->isaclass && !inheritedevent) {
- if (e && runEvent(e, np, pbase))
- retvar = pop();
- if (getComplete())
- break;
- }
- while (vc->isaclass) {
- ASSERT(r_varId < variablesTable.getNumItems());
- vclass = variablesTable.enumItem(r_varId);
- vclass->v.data.odata = thisobject;
- if (runEvent(e, np, pbase))
- retvar = pop();
- if (getComplete())
- break;
- vc = vclass;
- if (vc->varId < 0x10000) break;
- r_varId = varBase(vc->scriptId) + vc->v.type - 0x10000;
- }
- if (getComplete())
- break;
- varId++;
- }
- for (int i=0;i<np;i++)
- plist.delByPos(pbase);
- return retvar.v;
- }
- void VCPU::callDlfCommand(void *ptr, int nargs, maki_cmd *cmd) {
- try {
- scriptVar v={0,0};
- switch (nargs) {
- case 0:
- ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *))ptr)(cmd, -1, NULL);
- break;
- case 1:
- ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar))ptr)(cmd, -1, NULL, v);
- break;
- case 2:
- ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v);
- break;
- case 3:
- ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v);
- break;
- case 4:
- ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v);
- break;
- case 5:
- ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v, v);
- break;
- case 6:
- ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v, v, v);
- break;
- case 7:
- ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v, v, v, v);
- break;
- case 8:
- ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v, v, v, v, v);
- break;
- case 9:
- ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v, v, v, v, v, v);
- break;
- case 10:
- ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))ptr)(cmd, -1, NULL, v, v, v, v, v, v, v, v, v, v);
- break;
- }
- }
- catch(...)
- {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VCPU::VSD), GURU_EXCEPTION, L"Script Fatal Error", -1);
- #ifdef ON_FATAL_SKIN_ERROR
- ON_FATAL_SKIN_ERROR
- #endif
- }
- }
- int VCPU::getDLFFromPointer(void *ptr, int nargs) {
- maki_cmd cmd={MAKI_CMD_GETDLF, -1};
- callDlfCommand(ptr, nargs, &cmd);
- return cmd.id;
- }
- // This sends the DLFId to the function itself.
- void VCPU::setupDLFFunction(void *ptr, int nargs, int DLFid, VCPUdlfEntry *e) {
- registerGlobalDlf(e, DLFid);
- maki_cmd cmd={MAKI_CMD_SETDLF, DLFid};
- callDlfCommand(ptr, nargs, &cmd);
- }
- // This sends the DLFId to the function itself.
- void VCPU::DLF_reset(void *ptr, int nargs) {
- maki_cmd cmd={MAKI_CMD_RESETDLF, -1};
- callDlfCommand(ptr, nargs, &cmd);
- }
- void VCPU::DLF_addref(void *ptr, int nargs) {
- maki_cmd cmd={MAKI_CMD_ADDREF, -1};
- callDlfCommand(ptr, nargs, &cmd);
- }
- void VCPU::DLF_remref(void *ptr, int nargs) {
- maki_cmd cmd={MAKI_CMD_REMREF, -1};
- callDlfCommand(ptr, nargs, &cmd);
- }
- // -------------------------------------------------------------
- scriptVar VCPU::safeDiv(VCPUscriptVar *v1, VCPUscriptVar *v2) {
- double _r=0;
- double _v1=SOM::makeDouble(&v1->v);
- double _v2=SOM::makeDouble(&v2->v);
- if (_v2 != 0.0)
- _r = _v1 / _v2;
- else
- Script::guruMeditation(SOM::getSystemObjectByScriptId(v1->scriptId), GURU_DIVBYZERO, L"Division by zero");
- scriptVar r = SOM::makeVar(SCRIPT_DOUBLE);
- SOM::assign(&r, _r);
- return r;
- }
- /*
- Registers :
- VIP : Instruction Pointer
- VSP : Stack Pointer
- VSD : Script Descriptor (ID of script we're in)
- CALLM calls member function, pops a variable ID and a DLF entry, and pushs the result of
- the function. CallC calls an address, so pushs the return address on its stack
- (independant from the Push/Pop stack), and jumps to the code. Ret gets the last
- address pushed and returns there. JIZ jumps to an address if the first value on the stack
- is an int zero. JMP jumps unconditionnaly.
- The stack is a stack of 4 bytes integers containing scriptVar IDs.
- Var IDs from binaries are being added the base ID of the current script so we
- have only one variables segment for all scripts. Same for DLF entries. Events
- aren't references in the bytecode other than in the event table that links
- addresses in code to DLF entries, so we don't need that kind of tweaking.
- */
- // -------------------------------------------------------------
- char *VCPU::getCodeBlock(int id, int *size) {
- for (int i=0;i<codeTable.getNumItems();i++) {
- if (codeTable.enumItem(i)->scriptId == id) {
- if (size != NULL) *size = codeTable.enumItem(i)->size;
- return codeTable.enumItem(i)->codeBlock;
- }
- }
- return NULL;
- }
- // -------------------------------------------------------------
- VCPUcodeBlock *VCPU::getCodeBlockEntry(int id) {
- for (int i=0;i<codeTable.getNumItems();i++) {
- if (codeTable.enumItem(i)->scriptId == id) {
- return codeTable.enumItem(i);
- }
- }
- return NULL;
- }
- // -------------------------------------------------------------
- void VCPU::runCode(int scriptId, int pointer, int np) {
- int quit=0;
- VIP = pointer;
- VSD = scriptId;
- #ifdef WASABI_COMPILE_MAKIDEBUG
- int debugger_present = debugApi ? debugApi->debugger_isActive() : 0;
- #endif
- char *codeblock = (char *)getCodeBlock(VSD);
- char *p = codeblock + VIP;
- unsigned char opcode;
- int stackbase = VSP-np;
- int callcbase = CallStack.peek();
- VCC = callcbase;
- while (!quit) {
- #ifdef WASABI_COMPILE_MAKIDEBUG
- if (debugger_present) {
- VIPstack.push(VIP);
- VSDstack.push(VSD);
- // VSPstack.push(VSP);
- VCCstack.push(VCC);
- debugApi->debugger_trace();
- VIPstack.pop(&VIP);
- VSDstack.pop(&VSD);
- // VSPstack.pop(&VSP);
- VCCstack.pop(&VCC);
- }
- #endif
- opcode = *p;
- p+=sizeof(opcode);
- VIP+=sizeof(opcode);
- switch (opcode) {
- case OPCODE_PUSH: {
- int id; // var id
- id = *(int *)p;
- p+=sizeof(int); VIP+=sizeof(int);
- VCPUscriptVar *var = variablesTable.enumItem(id+varBase(VSD));
- push(*var);
- break;
- }
- case OPCODE_POPI: {
- pop(); // discard
- if (VSP == stackbase)
- statementStringList.freeAll();
- break;
- }
- case OPCODE_POP: {
- int id = *(int *)p; // var id
- p+=sizeof(int); VIP+=sizeof(int);
- VCPUscriptVar v = pop();
- VCPUassign(id, v.v, VSD);
- break;
- }
- case OPCODE_SET: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- if (v1.varId == -1) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_SETNONINTERNAL);
- ASSERT(0);
- }
- scriptVar r = VCPUassign(v1.varId, v2.v, VSD);
- push(r);
- break;
- }
- case OPCODE_RETF: {
- if (/*VSP == stackbase+1 && */CallStack.peek() == callcbase) {
- quit = 1;
- break;
- }
- CallStack.pop(&p);
- VIP = p-(char *)getCodeBlock(VSD);
- break;
- }
- case OPCODE_CALLC: {
- int shift; // jump length
- shift = *(int *)p;
- p+=sizeof(int); VIP+=sizeof(int);
- CallStack.push(p);
- VCC++;
- p+=shift;
- VIP+=shift;
- break;
- }
- case OPCODE_CALLM: {
- int id; // DLF id
- id = *(int *)p;
- p+=sizeof(int); VIP+=sizeof(int);
- VCPUdlfEntry *e = DLFentryTable.enumItem(id+dlfBase(VSD));
- int np = *(int *)p;
- // OLD stack protection - was relying on a shody test based on the fact that the compiler should not be able to generate two FF's at this offset, replaced by new opcode but remains for backward compatibility
- if ((np & 0xFFFF0000) == 0xFFFF0000) {
- p += sizeof(int);
- VIP += sizeof(int);
- np &= 0xFFFF;
- } else np = -1;
- scriptVar r = callDLF(e, np);
- VCPUscriptVar vr;
- vr.scriptId = VSD;
- vr.varId = -1;
- vr.v = r;
- push(vr);
- break;
- }
- case OPCODE_CALLM2: {
- int id; // DLF id
- id = *(int *)p;
- p+=sizeof(int); VIP+=sizeof(int);
- VCPUdlfEntry *e = DLFentryTable.enumItem(id+dlfBase(VSD));
- int np = *(unsigned char *)p; p++; VIP+=1;
- scriptVar r = callDLF(e, np);
- VCPUscriptVar vr;
- vr.scriptId = VSD;
- vr.varId = -1;
- vr.v = r;
- push(vr);
- break;
- }
- case OPCODE_UMV:
- {
- VCPUscriptVar name = pop();
- VCPUscriptVar obj = pop();
- ASSERT(obj.v.data.odata!=NULL);
- ASSERT(name.v.data.sdata!=NULL);
- int rettype = *(int *)p;
- p+=sizeof(int); VIP+=sizeof(int);
- if (rettype >= CLASS_ID_BASE) {
- SystemObject *so = SOM::getSystemObjectByScriptId(VSD);
- TList<int> *typeslist = so->getTypesList();
- rettype = typeslist->enumItem(rettype - CLASS_ID_BASE);
- }
- int oid = ((ScriptObject *)obj.v.data.odata)->vcpu_getMember(name.v.data.sdata, VSD, rettype);
- VCPUscriptVar *v = getOrphan(oid);
- ASSERT(v != NULL);
- push(*v);
- break;
- }
- case OPCODE_CMPEQ: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- VCPUscriptVar r;
- r.v = SOM::makeVar(SCRIPT_INT);
- SOM::assign(&r.v, SOM::compEq(&v1.v, &v2.v));
- push(r);
- break;
- }
- case OPCODE_CMPNE: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- VCPUscriptVar r;
- r.v = SOM::makeVar(SCRIPT_INT);
- SOM::assign(&r.v, SOM::compNeq(&v1.v, &v2.v));
- push(r);
- break;
- }
- case OPCODE_CMPA: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- VCPUscriptVar r;
- r.v = SOM::makeVar(SCRIPT_INT);
- SOM::assign(&r.v, SOM::compA(&v1.v, &v2.v));
- push(r);
- break;
- }
- case OPCODE_CMPAE: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- VCPUscriptVar r;
- r.v = SOM::makeVar(SCRIPT_INT);
- SOM::assign(&r.v, SOM::compAe(&v1.v, &v2.v));
- push(r);
- break;
- }
- case OPCODE_CMPB: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- VCPUscriptVar r;
- r.v = SOM::makeVar(SCRIPT_INT);
- SOM::assign(&r.v, SOM::compB(&v1.v, &v2.v));
- push(r);
- break;
- }
- case OPCODE_CMPBE: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- VCPUscriptVar r;
- r.v = SOM::makeVar(SCRIPT_INT);
- SOM::assign(&r.v, SOM::compBe(&v1.v, &v2.v));
- push(r);
- break;
- }
- case OPCODE_JIZ: {
- int shift; // jump length
- shift = *(int *)p;
- p+=sizeof(int); VIP+=sizeof(int);
- VCPUscriptVar v = pop();
- if (v.v.data.idata == 0) {
- p+=shift;
- VIP+=shift;
- }
- break;
- }
- case OPCODE_JNZ: {
- int shift; // jump length
- shift = *(int *)p;
- p+=sizeof(int); VIP+=sizeof(int);
- VCPUscriptVar v = pop();
- if (v.v.data.idata != 0) {
- p+=shift;
- VIP+=shift;
- }
- break;
- }
- case OPCODE_JMP: {
- int shift; // jump length
- shift = *(int *)p;
- p+=sizeof(int); VIP+=sizeof(int);
- p+=shift;
- VIP+=shift;
- break;
- }
- case OPCODE_NOT: {
- VCPUscriptVar v = pop();
- VCPUscriptVar r;
- r.v = SOM::makeVar(SCRIPT_BOOLEAN);
- switch (v.v.type) {
- case SCRIPT_BOOLEAN:
- case SCRIPT_INT:
- case SCRIPT_FLOAT:
- case SCRIPT_DOUBLE: {
- int i = SOM::makeBoolean(&v.v);
- r.v.data.idata = i == 0 ? 1 : 0;
- }
- break;
- case SCRIPT_STRING:
- r.v.data.idata = (!v.v.data.sdata || !*v.v.data.sdata) ? 1 : 0;
- break;
- default:
- r.v.data.idata = (v.v.data.odata == NULL) ? 1 : 0;
- break;
- }
- push(r);
- break;
- }
- case OPCODE_INCS: {
- VCPUscriptVar v = pop();
- push(v);
- switch (v.v.type) {
- case SCRIPT_BOOLEAN:
- v.v.data.idata = 1;
- break;
- case SCRIPT_INT:
- v.v.data.idata++;
- break;
- case SCRIPT_FLOAT:
- v.v.data.fdata = v.v.data.fdata+1;
- break;
- case SCRIPT_DOUBLE:
- v.v.data.ddata = v.v.data.ddata+1;
- break;
- default:
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_INCSNONNUM);
- ASSERT(0);
- break;
- }
- if (v.varId != -1)
- VCPUassign(v.varId, v.v, VSD);
- break;
- }
- case OPCODE_DECS: {
- VCPUscriptVar v = pop();
- push(v);
- switch (v.v.type) {
- case SCRIPT_BOOLEAN:
- v.v.data.idata = 0;
- break;
- case SCRIPT_INT:
- v.v.data.idata--;
- break;
- case SCRIPT_FLOAT:
- v.v.data.fdata = v.v.data.fdata-1;
- break;
- case SCRIPT_DOUBLE:
- v.v.data.ddata = v.v.data.ddata-1;
- break;
- default:
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_DECSNONNUM);
- ASSERT(0);
- break;
- }
- if (v.varId != -1)
- VCPUassign(v.varId, v.v, VSD);
- break;
- }
- case OPCODE_INCP: {
- VCPUscriptVar v = pop();
- switch (v.v.type) {
- case SCRIPT_BOOLEAN:
- v.v.data.idata = 1;
- break;
- case SCRIPT_INT:
- v.v.data.idata++;
- break;
- case SCRIPT_FLOAT:
- v.v.data.fdata = v.v.data.fdata+1;
- break;
- case SCRIPT_DOUBLE:
- v.v.data.ddata = v.v.data.ddata+1;
- break;
- default:
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_INCPNONNUM);
- ASSERT(0);
- break;
- }
- if (v.varId != -1)
- VCPUassign(v.varId, v.v, VSD);
- push(v);
- break;
- }
- case OPCODE_DECP: {
- VCPUscriptVar v = pop();
- switch (v.v.type) {
- case SCRIPT_BOOLEAN:
- v.v.data.idata = 0;
- break;
- case SCRIPT_INT:
- v.v.data.idata--;
- break;
- case SCRIPT_FLOAT:
- v.v.data.fdata = v.v.data.fdata-1;
- break;
- case SCRIPT_DOUBLE:
- v.v.data.ddata = v.v.data.ddata-1;
- break;
- default:
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_DECSNONNUM);
- ASSERT(0);
- break;
- }
- if (v.varId != -1)
- VCPUassign(v.varId, v.v, VSD);
- push(v);
- break;
- }
- case OPCODE_ADD: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- ASSERT(v1.v.type == SCRIPT_STRING || SOM::isNumeric(&v1.v));
- ASSERT(v2.v.type == SCRIPT_STRING || SOM::isNumeric(&v2.v));
- if (v2.v.type == SCRIPT_STRING)
- {
- int n=0;
- if (!v2.v.data.sdata) break;
- if (v1.v.data.sdata) n+= wcslen(v1.v.data.sdata);
- n+= wcslen(v2.v.data.sdata);
- wchar_t *s = (wchar_t *)WMALLOC((n+1));
- ASSERT(s != NULL);
- if (v1.v.data.sdata)
- {
- wcsncpy(s, v1.v.data.sdata, n);
- wcsncat(s, (v2.v.data.sdata ? v2.v.data.sdata : L""), n);
- } else
- wcsncpy(s, (v2.v.data.sdata ? v2.v.data.sdata : L""), n);
- v1.v = SOM::makeVar(SCRIPT_STRING);
- SOM::assign(&v1.v, s);
- FREE(s);
- push(v1);
- } else {
- scriptVar r = SOM::makeVar(SCRIPT_DOUBLE);
- SOM::assign(&r, SOM::makeDouble(&v1.v) + SOM::makeDouble(&v2.v));
- push(r);
- }
- break;
- }
- case OPCODE_SUB: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- ASSERT(SOM::isNumeric(&v1.v));
- ASSERT(SOM::isNumeric(&v2.v));
- scriptVar r = SOM::makeVar(SCRIPT_DOUBLE);
- SOM::assign(&r, SOM::makeDouble(&v1.v) - SOM::makeDouble(&v2.v));
- push(r);
- break;
- }
- case OPCODE_MUL: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- ASSERT(SOM::isNumeric(&v1.v));
- ASSERT(SOM::isNumeric(&v2.v));
- scriptVar r = SOM::makeVar(SCRIPT_DOUBLE);
- SOM::assign(&r, SOM::makeDouble(&v1.v) * SOM::makeDouble(&v2.v));
- push(r);
- break;
- }
- case OPCODE_DIV: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- scriptVar r = safeDiv(&v1, &v2);
- push(r);
- break;
- }
- case OPCODE_MOD: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- if (!SOM::isNumeric(&v2.v) || !SOM::isNumeric(&v1.v)) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_MODNONNUM);
- ASSERT(0);
- }
- SOM::assign(&v1.v, SOM::makeInt(&v1.v) % SOM::makeInt(&v2.v));
- push(v1);
- break;
- }
- case OPCODE_NEG: {
- VCPUscriptVar v = pop();
- switch (v.v.type) {
- case SCRIPT_BOOLEAN:
- break;
- case SCRIPT_INT:
- v.v.data.idata = -v.v.data.idata;
- break;
- case SCRIPT_FLOAT:
- v.v.data.fdata = -v.v.data.fdata;
- break;
- case SCRIPT_DOUBLE:
- v.v.data.ddata = -v.v.data.ddata;
- break;
- default:
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_NEGNONNUM);
- ASSERT(0);
- break;
- }
- push(v);
- break;
- }
- case OPCODE_BNOT: {
- VCPUscriptVar v = pop();
- if (!SOM::isNumeric(&v.v)) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_BNOTNONNUM);
- ASSERT(0);
- }
- SOM::assign(&v.v, ~SOM::makeInt(&v.v));
- push(v);
- break;
- }
- case OPCODE_SHL: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- if (!SOM::isNumeric(&v1.v) || !SOM::isNumeric(&v2.v)) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_SHLNONNUM);
- ASSERT(0);
- }
- SOM::assign(&v1.v, SOM::makeInt(&v1.v) << SOM::makeInt(&v2.v));
- push(v1);
- break;
- }
- case OPCODE_SHR: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- if (!SOM::isNumeric(&v1.v) || !SOM::isNumeric(&v2.v)) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_SHRNONNUM);
- ASSERT(0);
- }
- SOM::assign(&v1.v, SOM::makeInt(&v1.v) >> SOM::makeInt(&v2.v));
- push(v1);
- break;
- }
- case OPCODE_XOR: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- if (!SOM::isNumeric(&v1.v) || !SOM::isNumeric(&v2.v)) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_XORNONNUM);
- ASSERT(0);
- }
- SOM::assign(&v1.v, SOM::makeInt(&v1.v) ^ SOM::makeInt(&v2.v));
- push(v1);
- break;
- }
- case OPCODE_AND: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- if (!SOM::isNumeric(&v1.v) || !SOM::isNumeric(&v2.v)) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_ANDNONNUM);
- ASSERT(0);
- }
- SOM::assign(&v1.v, SOM::makeInt(&v1.v) & SOM::makeInt(&v2.v));
- push(v1);
- break;
- }
- case OPCODE_OR: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- if (!SOM::isNumeric(&v1.v) || !SOM::isNumeric(&v2.v)) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_ANDNONNUM);
- ASSERT(0);
- }
- SOM::assign(&v1.v, SOM::makeInt(&v1.v) | SOM::makeInt(&v2.v));
- push(v1);
- break;
- }
- case OPCODE_LAND: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- VCPUscriptVar r;
- r.v = SOM::makeVar(SCRIPT_BOOLEAN);
- int a2 = SOM::makeBoolean(&v2.v);
- int a1 = SOM::makeBoolean(&v1.v);
- r.v.data.idata = (a2 && a1) ? 1 : 0;
- push(r);
- break;
- }
- case OPCODE_LOR: {
- VCPUscriptVar v2 = pop();
- VCPUscriptVar v1 = pop();
- VCPUscriptVar r;
- r.v = SOM::makeVar(SCRIPT_BOOLEAN);
- int a2 = SOM::makeBoolean(&v2.v);
- int a1 = SOM::makeBoolean(&v1.v);
- r.v.data.idata = (a2 || a1) ? 1 : 0;
- push(r);
- break;
- }
- case OPCODE_DELETE: {
- VCPUscriptVar v1 = pop();
- int id = 0;
- int type = v1.v.type;
- if (type >= 0x10000)
- do {
- id = type - 0x10000;
- VCPUscriptVar *v = variablesTable.enumItem(id+varBase(VSD));
- type = v->v.type;
- } while (type >= 0x10000);
- if (isInstantiable(type)) {
- ScriptObject *s = (ScriptObject *)v1.v.data.odata;
- scriptVar v = SOM::makeVar(v1.v.type);
- VCPUassign(v1.varId, v, v1.scriptId);
- SystemObject *so = SOM::getSystemObjectByScriptId(VSD);
- so->removeInstantiatedObject(s);
- ObjectTable::destroy(s);
- }
- VCPU::push(v1);
- break;
- }
- case OPCODE_NEW: {
- int id = *(int *)p; // class id
- p+=sizeof(int); VIP+=sizeof(int);
- SystemObject *so = SOM::getSystemObjectByScriptId(VSD);
- TList<int> *typeslist = so->getTypesList();
- int _id;
- if (id >= 0x10000)
- do {
- _id = id - 0x10000;
- VCPUscriptVar *v = variablesTable.enumItem(_id+varBase(VSD));
- id = v->v.type;
- } while (id >= 0x10000);
- if (SOM::getSystemObjectByScriptId(VSD)->isOldFormat())
- id = oldClassToClassId(id);
- else
- id = typeslist->enumItem(id);
- if (isInstantiable(id)) {
- ScriptObject *s = ObjectTable::instantiate(id);
- if (s) s->vcpu_setScriptId(VSD);
- so->addInstantiatedObject(s);
- if (s == NULL) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VSD), GURU_NEWFAILED);
- }
- VCPUscriptVar v={{SCRIPT_OBJECT, {0}}, 0};
- SOM::assign(&v.v, s);
- push(v);
- } else {
- VCPUscriptVar n = {{SCRIPT_OBJECT,NULL}, 0};
- push(n);
- }
- break;
- }
- case OPCODE_CMPLT : {
- complete = 1;
- break;
- }
- case OPCODE_NOP :
- {
- #if defined(_WIN32) || defined(_WIN64)
- OutputDebugStringA("Opcode 0 - NOP encountered, please check!\n");
- #else
- #warning port me
- #endif
- break;
- }
- default: {
- ASSERTALWAYS(StringPrintf("Opcode %X not implemented", opcode));
- break;
- }
- }
- }
- ASSERT(VSP == stackbase + 1);
- }
- // -------------------------------------------------------------
- scriptVar VCPU::VCPUassign(int id, scriptVar sv, int scriptId) {
- VCPUscriptVar *v = NULL;
- if (id & (1 << 31)) {
- id = id & ~(1 << 31);
- v = getOrphan(id);
- } else
- v = variablesTable.enumItem(id+varBase(scriptId));
- if (v->v.type != SCRIPT_STRING) {
- if (!SOM::isNumeric(&v->v)) {
- // assigning an object
- scriptVar _sv = sv;
- if (_sv.data.odata != NULL && !SystemObject::isObjectValid(_sv.data.odata))
- _sv.data.odata = NULL;
- if (v->v.data.odata != _sv.data.odata) {
- if (v->v.data.odata != NULL && !v->transcient && SystemObject::isObjectValid(v->v.data.odata))
- ((ScriptObject *)v->v.data.odata)->vcpu_removeAssignedVariable(v->varId, v->scriptId);
- if (_sv.data.odata == NULL) {
- v->v.data.odata = NULL;
- } else {
- SOM::assign(&v->v, &sv);
- if (SOM::typeCheck(v, 0)) {
- if (!v->isaclass && !v->transcient)
- ((ScriptObject *)sv.data.odata)->vcpu_addAssignedVariable(v->varId, v->scriptId);
- } else {
- int type = v->v.type;
- if (type >= 0x10000)
- do {
- id = type - 0x10000;
- VCPUscriptVar *v = variablesTable.enumItem(id+varBase(VSD));
- type = v->v.type;
- } while (type >= 0x10000);
- class_entry *e = ObjectTable::getClassEntry(type);
- ASSERT(e != NULL);
- GUID g = e->classGuid;
- ScriptObject *o = NULL;
- v->v.data.odata->vcpu_getInterfaceObject(g, &o);
- if (o != NULL) {
- v->v.data.odata = o;
- if (!v->isaclass && !v->transcient)
- o->vcpu_addAssignedVariable(v->varId, v->scriptId);
- } else {
- v->v.data.odata = NULL;
- }
- }
- }
- }
- } else {
- // assigning a number
- SOM::assign(&v->v, &sv);
- }
- } else {
- ASSERT(sv.type == SCRIPT_STRING);
- SOM::persistentstrassign(&v->v, sv.data.sdata);
- }
- return v->v;
- }
- // -------------------------------------------------------------
- void VCPU::traceState(VCPUscriptVar object, VCPUdlfEntry *e) {
- _DebugString("vcpu[%2X]: %04X [%04X].%s", VCPU::VSD, VCPU::VIP, object.varId, e->functionName);
- // CallbackManager::issueCallback(SysCallback::CONSOLE, ConsoleCallback::DEBUGMESSAGE, 0, reinterpret_cast<int>(t));
- }
- // -------------------------------------------------------------
- // Calls the DLF function
- scriptVar VCPU::callDLF(VCPUdlfEntry *e, int np) {
- static Stack<int> cpuidstack;
- cpuidstack.push(VSD);
- cpuidstack.push(VIP);
- cpuidstack.push(VCC);
- /* if (e->external) {
- char t[256] = {0};
- VCPUscriptVar v = VCPU::peekAt(e->nparams);
- SPRINTF(t, "vcpu: %04X [%04X].%s", VCPU::VIP, v.varId, e->functionName);
- Console::outputString(0, t);
- DebugString("%s", t);
- ((void(*)(int))e->ptr)(-1);
- scriptVar rv = pop().v; // returned val
- cpuidstack.pop(&VCC);
- cpuidstack.pop(&VIP);
- cpuidstack.pop(&VSD);
- return rv;
- }*/
-
- /* char t[256] = {0};
- SPRINTF(t, "e->nparams = %d\n", e->nparams);
- DebugString("%s", t); */
- //ASSERT(np == -1 || np == e->nparams); // fucko!!!!!!!!
- if (np == -1) {
- np = e->nparams;
- }
- for (int i=0;i<np;i++) {
- paramList[i] = pop().v;
- }
- VCPUscriptVar object = pop();
- scriptVar r = MAKE_SCRIPT_INT(0);
- //traceState(object, e);
- if (object.v.data.odata == NULL) {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VCPU::VSD), GURU_NULLCALLED, L"Null object called", object.varId);
- cpuidstack.pop(&VCC);
- cpuidstack.pop(&VIP);
- cpuidstack.pop(&VSD);
- return MAKE_SCRIPT_INT(0);
- //ASSERT(0);
- }
- #ifndef _DEBUG
- try
- #endif
- {
- if (object.v.data.odata) object.v.data.odata->vcpu_setScriptId(object.scriptId);
- if (e->ptr != NULL) {
- switch (np) {
- case 0:
- r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *))e->ptr)(NULL, VCPU::VSD, object.v.data.odata);
- break;
- case 1:
- r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0]);
- break;
- case 2:
- r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1]);
- break;
- case 3:
- r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2]);
- break;
- case 4:
- r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3]);
- break;
- case 5:
- r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3], paramList[4]);
- break;
- case 6:
- r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3], paramList[4], paramList[5]);
- break;
- case 7:
- r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3], paramList[4], paramList[5], paramList[6]);
- break;
- case 8:
- r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3], paramList[4], paramList[5], paramList[6], paramList[7]);
- break;
- case 9:
- r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3], paramList[4], paramList[5], paramList[6], paramList[7], paramList[8]);
- break;
- case 10:
- r = ((scriptVar (*)(maki_cmd *, int vsd, class ScriptObject *, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar, scriptVar))e->ptr)(NULL, VCPU::VSD, object.v.data.odata, paramList[0], paramList[1], paramList[2], paramList[3], paramList[4], paramList[5], paramList[6], paramList[7], paramList[8], paramList[9]);
- break;
- }
- }
- }
- #ifndef _DEBUG
- catch(...)
- {
- Script::guruMeditation(SOM::getSystemObjectByScriptId(VCPU::VSD), GURU_EXCEPTION, L"Script Fatal Error", object.varId);
- cpuidstack.pop(&VCC);
- cpuidstack.pop(&VIP);
- cpuidstack.pop(&VSD);
- #ifdef ON_FATAL_SKIN_ERROR
- ON_FATAL_SKIN_ERROR
- #endif
- return MAKE_SCRIPT_INT(0);
- }
- #endif
- cpuidstack.pop(&VCC);
- cpuidstack.pop(&VIP);
- cpuidstack.pop(&VSD);
- return r;
- }
- // -------------------------------------------------------------
- void VCPU::addStatementString(wchar_t *s)
- {
- statementStringList.addItem(s);
- }
- // -------------------------------------------------------------
- int VCPU::getComplete() {
- return complete;
- }
- // -------------------------------------------------------------
- int VCPU::isInstantiable(int id) {
- ASSERT(!SOM::isNumericType(id));
- return ObjectTable::isClassInstantiable(id);
- }
- // -------------------------------------------------------------
- int VCPU::getDlfGlobalIndex(int dlfid, int scriptid) {
- static int lasti=-1;
- static int lastid=0;
- static int lastsid=0;
- if (lasti>=0 && lasti < DLFentryTable.getNumItems()) {
- if (lastsid == scriptid && lastid == dlfid) {
- VCPUdlfEntry *e = DLFentryTable.enumItem(lasti);
- if (e->DLFid == dlfid && e->scriptId == scriptid)
- return lasti;
- }
- }
- for (int i=0;i<DLFentryTable.getNumItems();i++ ){
- VCPUdlfEntry *e = DLFentryTable.enumItem(i);
- if (e->scriptId == scriptid && e->DLFid == dlfid) {
- lasti = i;
- lastsid = scriptid;
- lastid = dlfid;
- return lasti;
- }
- }
- Script::guruMeditation(SOM::getSystemObjectByScriptId(scriptid), GURU_INVALIDEVENTDLF);
- return -1;
- }
- // -------------------------------------------------------------
- int VCPU::isValidScriptId(int id) {
- for (int i=0;i<codeTable.getNumItems();i++)
- if (codeTable[i]->scriptId == id) return 1;
- return 0;
- }
- // -------------------------------------------------------------
- int VCPU::getCacheCount() {
- return cacheCount;
- }
- // -------------------------------------------------------------
- int VCPU::getUserAncestor(int varid, int scriptid) {
- VCPUscriptVar *vc = variablesTable.enumItem(varid+varBase(scriptid)) ;
- if (vc->v.type < 0x10000) return -1;
- int r_varId = vc->v.type - 0x10000;
- ASSERT(r_varId < variablesTable.getNumItems());
- return r_varId;
- }
- // -------------------------------------------------------------
- void VCPU::pushObject(void *o) {
- scriptVar v = SOM::makeVar(SCRIPT_OBJECT, (ScriptObject *)o);
- VCPU::push(v);
- }
- // -------------------------------------------------------------
- void VCPU::pushInt(int i) {
- scriptVar v = SOM::makeVar(SCRIPT_INT);
- SOM::assign(&v, i);
- VCPU::push(v);
- }
- // -------------------------------------------------------------
- void VCPU::pushBoolean(int b) {
- scriptVar v = SOM::makeVar(SCRIPT_BOOLEAN);
- SOM::assign(&v, b);
- VCPU::push(v);
- }
- // -------------------------------------------------------------
- void VCPU::pushFloat(float f) {
- scriptVar v = SOM::makeVar(SCRIPT_FLOAT);
- SOM::assign(&v, f);
- VCPU::push(v);
- }
- // -------------------------------------------------------------
- void VCPU::pushDouble(double d) {
- scriptVar v = SOM::makeVar(SCRIPT_DOUBLE);
- SOM::assign(&v, d);
- VCPU::push(v);
- }
- // -------------------------------------------------------------
- void VCPU::pushString(const wchar_t *s)
- {
- scriptVar v = SOM::makeVar(SCRIPT_STRING);
- SOM::assign(&v, s);
- VCPU::push(v);
- }
- // -------------------------------------------------------------
- void VCPU::pushVoid() {
- scriptVar v = SOM::makeVar(SCRIPT_VOID);
- VCPU::push(v);
- }
- // -------------------------------------------------------------
- void *VCPU::popObject() {
- return (void *)VCPU::pop().v.data.odata;
- }
- // -------------------------------------------------------------
- int VCPU::popInt() {
- scriptVar v = VCPU::pop().v;
- ASSERT(SOM::isNumeric(&v));
- return SOM::makeInt(&v);
- }
- // -------------------------------------------------------------
- bool VCPU::popBoolean() {
- scriptVar v = VCPU::pop().v;
- ASSERT(SOM::isNumeric(&v));
- return SOM::makeBoolean(&v);
- }
- // -------------------------------------------------------------
- float VCPU::popFloat() {
- scriptVar v = VCPU::pop().v;
- ASSERT(SOM::isNumeric(&v));
- return SOM::makeFloat(&v);
- }
- // -------------------------------------------------------------
- double VCPU::popDouble() {
- scriptVar v = VCPU::pop().v;
- ASSERT(SOM::isNumeric(&v));
- return SOM::makeDouble(&v);
- }
- // -------------------------------------------------------------
- const wchar_t *VCPU::popString()
- {
- scriptVar v = VCPU::pop().v;
- ASSERT(v.type == SCRIPT_STRING);
- return v.data.sdata;
- }
- // -------------------------------------------------------------
- void VCPU::popDiscard() {
- VCPU::pop();
- }
- // -------------------------------------------------------------
- VCPUdlfEntry *VCPU::getGlobalDlfEntry(int dlfid) {
- return globalDlfList.enumItem(dlfid);
- }
- // -------------------------------------------------------------
- int VCPU::createOrphan(int type) {
- orphans.addItem(new OrphanEntry(orphanid, type));
- return orphanid++;
- }
- // -------------------------------------------------------------
- void VCPU::killOrphan(int id) {
- int pos;
- OrphanEntry *p = orphans.findItem((const wchar_t *)&id, &pos);
- ASSERT(p != NULL && pos >= 0);
- if (p->v.v.type == SCRIPT_STRING)
- FREE((void *)p->v.v.data.sdata);
- delete p;
- orphans.removeByPos(pos);
- }
- // -------------------------------------------------------------
- VCPUscriptVar *VCPU::getOrphan(int id) {
- OrphanEntry *p = orphans.findItem((const wchar_t *)&id);
- ASSERT(p != NULL);
- return &p->v;
- }
- // -------------------------------------------------------------
- int OrphanQuickSort::compareItem(void *p1, void *p2) {
- if ((static_cast<OrphanEntry *>(p1))->id < (static_cast<OrphanEntry *>(p2))->id) return -1;
- if ((static_cast<OrphanEntry *>(p1))->id > (static_cast<OrphanEntry *>(p2))->id) return 1;
- return 0;
- }
- // -------------------------------------------------------------
- int OrphanQuickSort::compareAttrib(const wchar_t *attr, void *p2)
- {
- int id = *(reinterpret_cast<const int *>(attr));
- int eid = (static_cast<OrphanEntry *>(p2))->id;
- if (id < eid) return -1;
- if (id > eid) return 1;
- return 0;
- }
- // -------------------------------------------------------------
- OrphanEntry::OrphanEntry(int _id, int type) {
- id = _id;
- MEMSET(&v, 0, sizeof(VCPUscriptVar));
- v.v.type = type;
- v.scriptId = -1;
- v.varId = id | (1 << 31);
- v.transcient = 1; // so no event is trapped, will change later when compiler supports it
- }
- // -------------------------------------------------------------
- void VCPU::setAtom(const wchar_t *atomname, ScriptObject *o) {
- int pos;
- ScriptAtom *sa = atoms.findItem(atomname, &pos);
- if (pos >= 0) {
- delete sa;
- atoms.removeByPos(pos);
- }
- if (o)
- atoms.addItem(new ScriptAtom(atomname, o));
- }
- // -------------------------------------------------------------
- ScriptObject *VCPU::getAtom(const wchar_t *atomname) {
- ScriptAtom *sa = atoms.findItem(atomname);
- if (sa) {
- return sa->getAtomObject();
- }
- return NULL;
- }
- // -------------------------------------------------------------
- const wchar_t *VCPU::getClassName(int vcpuid, int localclassid) {
- SystemObject *so = SOM::getSystemObject(vcpuid);
- if (so != NULL) {
- TList<int> *l = so->getTypesList();
- if (l != NULL) {
- int global = l->enumItem(localclassid);
- class_entry *e = ObjectTable::getClassEntry(global);
- if (e != NULL)
- return e->classname;
- }
- }
- return NULL;
- }
- // -------------------------------------------------------------
- int VCPU::cacheCount = 0;
- // segments
- PtrList<VCPUscriptVar> VCPU::variablesTable;
- PtrList<VCPUeventEntry> VCPU::eventsTable;
- PtrList<VCPUdlfEntry> VCPU::DLFentryTable;
- PtrList<VCPUdlfEntry> VCPU::globalDlfList;
- PtrList<VCPUcodeBlock> VCPU::codeTable;
- PtrList<wchar_t> VCPU::statementStringList;
- PtrListInsertSorted<OrphanEntry, OrphanQuickSort> VCPU::orphans;
- PtrListQuickSorted<ScriptAtom, ScriptAtomSort> VCPU::atoms;
- int VCPU::orphanid=0;
- // stacks
- Stack<VCPUscriptVar> VCPU::CpuStack;
- Stack<char *> VCPU::CallStack;
- // registers
- int VCPU::VIP=0;
- int VCPU::VSP=0;
- int VCPU::VSD=0;
- int VCPU::VCC=0;
- Stack<int> VCPU::VIPstack;
- Stack<int> VCPU::VSPstack;
- Stack<int> VCPU::VSDstack;
- Stack<int> VCPU::VCCstack;
- // misc
- int VCPU::numScripts=0;
- int VCPU::highestDLFId=0;
- scriptVar VCPU::paramList[SCRIPT_MAXARGS];
- int VCPU::complete;
- TList<int> VCPU::scriptsToRemove;
- // NOTES
- // There is no reason why people would cast System, Layout and Container
- // back to the common base class... so...
- // GUI objects should descend from a GUIObject rather than ScriptObject
- // GUIObject would descend from ScriptObject for the compiler and should
- // be exported as "Object" for the script, ScriptObject should then not
- // be exported at all, thus preventing someone from doing "Object o = System;"
- // which makes no sense since System is not a GUI object. Of course you
- // could still do "Layout l = System.getContainer("mqlksd").getLayout("lqsdkj");"
- // but you won't be able to cast that to an "Object". Furthermore, to get a
- // GUI object, you'll use the layout's function "getObject", so this
- // will add consistency to the overall thing.
- /*
- --------------------------------------------------------------------------------
- VCPU: Virtual CPU, The virtual machine processor.
- The VCPU actually takes care of some kinds of segments of variables,
- events, and so on. The VCPU's task is to run any number of scripts
- serially in reversed loading order. Last script loaded takes precedence
- over previous ones. Events and functions fall back to the the previous
- script if it also defines them, unless explicitly prevented via 'complete;'
- The VCPU links DLFs in reverse hierarchy order, allowing overriding of
- functions in objects.
- DLF : Dynamically Linked Function. Function name is used to link it to
- whatever layout of functions we have in any release of the VCPU, allowing
- us to reorder our functions in objects.
- TODO: Add versionning info so we can safely expand this format.
- Binaries format :
- <obsolete>
- Size Desc What
- -----------------------------------------------------------------------------
- 8 Header FG\x03\x04\x14\00\00\00\00
- -----------------------------------------------------------------------------
- 4 # of DLF int
- -----------------------------------------------------------------------------
- 4 DLF base type int
- 1 Size of func name char
- N Function name char[n]
- ...
- -----------------------------------------------------------------------------
- 4 # of variables int
- -----------------------------------------------------------------------------
- 8 variable scriptVar
- ...
- -----------------------------------------------------------------------------
- 4 # of strings int
- -----------------------------------------------------------------------------
- 1 Size of string char 1st string assigned to 1st string var
- N String char[n] 2nd string assigned to 2nd string var...
- ...
- -----------------------------------------------------------------------------
- 4 # of events int
- -----------------------------------------------------------------------------
- 4 variable id int Matching variable table
- 4 DLF entry int Matching DLF table
- 4 Function pointer int Pointer in code from base of code
- ...
- -----------------------------------------------------------------------------
- 4 Size of code int
- -----------------------------------------------------------------------------
- N Compiled code char[n]
- -----------------------------------------------------------------------------
- */
|