| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873 |
- /******************************************************************************/
- #include "stdafx.h"
- //#define SUPPORT_SCRIPTS
- namespace EE{
- namespace Edit{
- /******************************************************************************/
- struct FuncCall
- {
- CChar8 *name;
- Call::Func func;
- };
- struct GlobalVar
- {
- CChar8 *name;
- CPtr addr;
- };
- /******************************************************************************/
- static Str SymbolToCppName(C Str &s)
- {
- Str n='$';
- FREPA(s)
- {
- Char c=s[i];
- if(c>='a' && c<='z'
- || c>='A' && c<='Z'
- || c>='0' && c<='9'
- || c=='_')n+=c;else n+=S+'$'+TextHex(UInt(c), 2);
- }
- return n;
- }
- Str CppStyle(C Str &s) {return Replace(s, '.', "::");} // "EE.Str" -> "EE::Str"
- Str ModifName(Symbol::Modif &m, Bool spaces=true, Bool include_const=true, Bool include_ref=true, Bool invalid_array_as_1=false, Bool template_space=false) // this function replaces basic types "Int" -> "int"
- {
- //if(m && m->var_type!=VAR_NONE && m->var_type!=VAR_ENUM){Symbol::Modif temp=m; temp.proceedToFinal(&temp.templates); return temp.modifName(spaces, include_const, include_ref);}
- return m.modifName(spaces, include_const, include_ref, invalid_array_as_1, template_space);
- }
- Str FuncName(Symbol &func)
- {
- if(!func.value)return S;
- Str n=ModifName(func.value, false)+' '+func.fullCppName()+'(';
- FREPA(func.params){if(i)n+=',';
- Symbol *param=func.params[i]();
- if(!param || !param->value)return S; n+=ModifName(param->value, false);}
- n+=')';
- if(func.modifiers&Symbol::MODIF_FUNC_CONST )n +="const";
- //if(func.modifiers&Symbol::MODIF_FUNC_FINAL )n.space()+="final";
- //if(func.modifiers&Symbol::MODIF_FUNC_OVERRIDE)n.space()+="override";
- return n;
- }
- Str DtorName(Symbol &Class)
- {
- return S+"void "+Class.fullCppName()+".~"+Class+"()";
- }
- Str NativeOperatorName(C Str &op, Symbol::Modif &result, Symbol::Modif &a)
- {
- return result.modifName(false, false, false)+" operator"+op+'('+a.modifName(false, false, false)+')';
- }
- Str NativeOperatorName(C Str &op, Symbol::Modif &result, Symbol::Modif &a, Symbol::Modif &b)
- {
- return result.modifName(false, false, false)+" operator"+op+'('+a.modifName(false, false, false)+','+b.modifName(false, false, false)+')';
- }
- /******************************************************************************/
- static CChar8 *op_change []={"=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "|=", "^="},
- *op_compare[]={"==", "===", "!=", "!!=", "<", ">", "<=", ">=", "&&", "^^", "||"},
- *op_binary []={"*", "/", "%", "+", "-", "<<", ">>", "&", "^", "|"},
- *op_inc_dec[]={"++", "--"};
- static Mems<FuncCall*> FC2; // 'FC' sorted by FuncCall::func
- /******************************************************************************/
- void CodeEditor::createFuncList()
- {
- FileText ft; ft.writeMem(UTF_8); // xcode had problems with utf-16
- Memc<Str> funcs, vars;
- CodeEnvironment::SetupChildren(); // needed for some functions
- // create call's
- {
- Str name;
- name="nop"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { thread.func_code_pos+=Call::Size(0); }");
- }
- // create call's
- {
- Str name; // use 'getInstructP' and 'getInstructI' for param 0 because they're always stored in INSTRUCT (adjust code positions before making the call, so thread.call will store new positions and will return to them later)
- name="call func" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { thread.func_code_pos+=Call::Size(1); thread.call(*(CodeEnvironment::FuncBody*)call.param(0).getInstructP(), call.param(0).getInstructI2(), null, null); }");
- name="call func result" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { thread.func_code_pos+=Call::Size(2); thread.call(*(CodeEnvironment::FuncBody*)call.param(0).getInstructP(), call.param(0).getInstructI2(), null, call.param(1).address(thread)); }");
- name="call method" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { thread.func_code_pos+=Call::Size(2); thread.call(*(CodeEnvironment::FuncBody*)call.param(0).getInstructP(), call.param(0).getInstructI2(), call.param(1).address(thread), null); }");
- name="call method result"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { thread.func_code_pos+=Call::Size(3); thread.call(*(CodeEnvironment::FuncBody*)call.param(0).getInstructP(), call.param(0).getInstructI2(), call.param(1).address(thread), call.param(2).address(thread)); }");
- }
- // create set const's
- {
- Str name; // use 'getInstructI' and 'raw' for params 0 and 1 because they're always stored in INSTRUCT
- name="set const 1" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { *(byte *)(thread.func_stack+call.param(0).getInstructI()) = (byte &)call.param(1).raw; thread.func_code_pos+=Call::Size(2); }");
- name="set const 2" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { *(short*)(thread.func_stack+call.param(0).getInstructI()) = (short&)call.param(1).raw; thread.func_code_pos+=Call::Size(2); }");
- name="set const 4" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { *(int *)(thread.func_stack+call.param(0).getInstructI()) = (int &)call.param(1).raw; thread.func_code_pos+=Call::Size(2); }");
- name="set const 8" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { *(long *)(thread.func_stack+call.param(0).getInstructI()) = (long &)call.param(1).raw; thread.func_code_pos+=Call::Size(2); }");
- name="set const heap 1"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { *(byte *)(thread.func_stack+call.param(0).getInstructI()) = PARAM(1,byte ); thread.func_code_pos+=Call::Size(2); }");
- name="set const heap 2"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { *(short*)(thread.func_stack+call.param(0).getInstructI()) = PARAM(1,short); thread.func_code_pos+=Call::Size(2); }");
- name="set const heap 4"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { *(int *)(thread.func_stack+call.param(0).getInstructI()) = PARAM(1,int ); thread.func_code_pos+=Call::Size(2); }");
- name="set const heap 8"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { *(long *)(thread.func_stack+call.param(0).getInstructI()) = PARAM(1,long ); thread.func_code_pos+=Call::Size(2); }");
- }
- // create set addr
- {
- Str name; // use 'getInstructI' for param 0 because it's always stored in INSTRUCT
- name="set addr heap" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { *(ptr*)(thread.heap +call.param(0).getInstructI()) = call.param(1).address(thread); thread.func_code_pos+=Call::Size(2); }");
- name="set addr stack" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { *(ptr*)(thread.func_stack+call.param(0).getInstructI()) = call.param(1).address(thread); thread.func_code_pos+=Call::Size(2); }");
- name="set addr result"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { *(ptr*)(thread.func_result ) = call.param(0).address(thread); thread.func_code_pos+=Call::Size(1); }");
- }
- // create indirection + addressOf
- {
- Str name;
- name="indirection"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { *(ptr*)(thread.func_stack+call.param(0).getInstructI()) = PARAM(1,ptr); thread.func_code_pos+=Call::Size(2); }"); // we can't use "PARAM(0,ptr)" because it's always STACK_REF and by using it we would access the value of the address not set yet
- name="address of" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,ptr) = call.param(1).address(thread); thread.func_code_pos+=Call::Size(2); }");
- name="offset 1s" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM_REF(0) = (byte*)call.param(1).address(thread) + PARAM(2,sbyte ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="offset 1u" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM_REF(0) = (byte*)call.param(1).address(thread) + PARAM(2,byte ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="offset 2s" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM_REF(0) = (byte*)call.param(1).address(thread) + PARAM(2,short ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="offset 2u" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM_REF(0) = (byte*)call.param(1).address(thread) + PARAM(2,ushort) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="offset 4s" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM_REF(0) = (byte*)call.param(1).address(thread) + PARAM(2,int ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="offset 4u" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM_REF(0) = (byte*)call.param(1).address(thread) + PARAM(2,uint ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="offset 8s" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM_REF(0) = (byte*)call.param(1).address(thread) + PARAM(2,long ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="offset 8u" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM_REF(0) = (byte*)call.param(1).address(thread) + PARAM(2,ulong ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- }
- // create inc/dec ptr's
- {
- Str name;
- name="inc ptr 2"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { ++PARAM(0,short*); thread.func_code_pos+=Call::Size(1); }");
- name="dec ptr 2"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { --PARAM(0,short*); thread.func_code_pos+=Call::Size(1); }");
- name="inc ptr 4"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { ++PARAM(0,int *); thread.func_code_pos+=Call::Size(1); }");
- name="dec ptr 4"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { --PARAM(0,int *); thread.func_code_pos+=Call::Size(1); }");
- name="inc ptr 8"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { ++PARAM(0,long *); thread.func_code_pos+=Call::Size(1); }");
- name="dec ptr 8"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { --PARAM(0,long *); thread.func_code_pos+=Call::Size(1); }");
- name="inc ptr n"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,byte *) += call.param(1).getInstructI(); thread.func_code_pos+=Call::Size(2); }"); // use 'getInstructI' for param 1 because it's always stored in INSTRUCT
- name="dec ptr n"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,byte *) -= call.param(1).getInstructI(); thread.func_code_pos+=Call::Size(2); }"); // use 'getInstructI' for param 1 because it's always stored in INSTRUCT
- name="add ptr 1s"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,byte*) += PARAM(1,sbyte ) * call.param(2).getInstructI(); thread.func_code_pos+=Call::Size(3); }");
- name="add ptr 1u"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,byte*) += PARAM(1,byte ) * call.param(2).getInstructI(); thread.func_code_pos+=Call::Size(3); }");
- name="add ptr 2s"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,byte*) += PARAM(1,short ) * call.param(2).getInstructI(); thread.func_code_pos+=Call::Size(3); }");
- name="add ptr 2u"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,byte*) += PARAM(1,ushort) * call.param(2).getInstructI(); thread.func_code_pos+=Call::Size(3); }");
- name="add ptr 4s"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,byte*) += PARAM(1,int ) * call.param(2).getInstructI(); thread.func_code_pos+=Call::Size(3); }");
- name="add ptr 4u"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,byte*) += PARAM(1,uint ) * call.param(2).getInstructI(); thread.func_code_pos+=Call::Size(3); }");
- name="add ptr 8s"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,byte*) += PARAM(1,long ) * call.param(2).getInstructI(); thread.func_code_pos+=Call::Size(3); }");
- name="add ptr 8u"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,byte*) += PARAM(1,ulong ) * call.param(2).getInstructI(); thread.func_code_pos+=Call::Size(3); }");
- name="ptr add 1s"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,ptr) = PARAM(1,byte*) + PARAM(2,sbyte ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="ptr add 1u"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,ptr) = PARAM(1,byte*) + PARAM(2,byte ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="ptr add 2s"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,ptr) = PARAM(1,byte*) + PARAM(2,short ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="ptr add 2u"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,ptr) = PARAM(1,byte*) + PARAM(2,ushort) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="ptr add 4s"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,ptr) = PARAM(1,byte*) + PARAM(2,int ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="ptr add 4u"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,ptr) = PARAM(1,byte*) + PARAM(2,uint ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="ptr add 8s"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,ptr) = PARAM(1,byte*) + PARAM(2,long ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="ptr add 8u"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,ptr) = PARAM(1,byte*) + PARAM(2,ulong ) * call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- name="ptr diff"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,uintptr) = (PARAM(1,byte*) - PARAM(2,byte*)) / call.param(3).getInstructI(); thread.func_code_pos+=Call::Size(4); }");
- }
- // create goto's
- {
- Str name; // use 'getInstructP' because goto's are always stored in INSTRUCT
- name="goto" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { thread.func_code_pos = (byte*)call.param(0).getInstructP(); }");
- name="goto cond 1" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { if( PARAM(1,byte )) thread.func_code_pos = (byte*)call.param(0).getInstructP(); else thread.func_code_pos+=Call::Size(2); }");
- name="goto cond 2" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { if( PARAM(1,short)) thread.func_code_pos = (byte*)call.param(0).getInstructP(); else thread.func_code_pos+=Call::Size(2); }");
- name="goto cond 4" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { if( PARAM(1,int )) thread.func_code_pos = (byte*)call.param(0).getInstructP(); else thread.func_code_pos+=Call::Size(2); }");
- name="goto cond 8" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { if( PARAM(1,long )) thread.func_code_pos = (byte*)call.param(0).getInstructP(); else thread.func_code_pos+=Call::Size(2); }");
- name="goto cond f" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { if( PARAM(1,flt )) thread.func_code_pos = (byte*)call.param(0).getInstructP(); else thread.func_code_pos+=Call::Size(2); }");
- name="goto cond d" ; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { if( PARAM(1,dbl )) thread.func_code_pos = (byte*)call.param(0).getInstructP(); else thread.func_code_pos+=Call::Size(2); }");
- name="goto cond n 1"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { if(!PARAM(1,byte )) thread.func_code_pos = (byte*)call.param(0).getInstructP(); else thread.func_code_pos+=Call::Size(2); }");
- name="goto cond n 2"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { if(!PARAM(1,short)) thread.func_code_pos = (byte*)call.param(0).getInstructP(); else thread.func_code_pos+=Call::Size(2); }");
- name="goto cond n 4"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { if(!PARAM(1,int )) thread.func_code_pos = (byte*)call.param(0).getInstructP(); else thread.func_code_pos+=Call::Size(2); }");
- name="goto cond n 8"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { if(!PARAM(1,long )) thread.func_code_pos = (byte*)call.param(0).getInstructP(); else thread.func_code_pos+=Call::Size(2); }");
- name="goto cond n f"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { if(!PARAM(1,flt )) thread.func_code_pos = (byte*)call.param(0).getInstructP(); else thread.func_code_pos+=Call::Size(2); }");
- name="goto cond n d"; funcs.add(name); ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { if(!PARAM(1,dbl )) thread.func_code_pos = (byte*)call.param(0).getInstructP(); else thread.func_code_pos+=Call::Size(2); }");
- }
- ft.endLine();
- ft.putLine("#ifdef SUPPORT_SCRIPTS");
- ft.endLine();
- // create basic operators
- // binary change
- FREPAD(o, op_change)
- for(VAR_TYPE a=VAR_FROM; a<=VAR_TO; a=VAR_TYPE(a+1))
- for(VAR_TYPE b=VAR_FROM; b<=VAR_TO; b=VAR_TYPE(b+1))
- if(!((op_change[o]=="%=" || op_change[o]=="<<=" || op_change[o]==">>=" || op_change[o]=="&=" || op_change[o]=="|=" || op_change[o]=="^=") && (RealType(a) || RealType(b)))) // disallow modulo and binary operators if at least one param is real
- if(SameSizeSignBoolType(a)==a && ((a==VAR_BOOL && op_change[o]=="=") ? SameSizeSignBoolType(b)==b : SameSizeSignType(b)==b)) // keep bool for left side because C++ forces the result to bool (for bool=bool keep bool on the right side as well)
- {
- Symbol::Modif result, pa, pb;
- result=TypeSymbol(VAR_VOID);
- pa =TypeSymbol(a);
- pb =TypeSymbol(b);
- Str name=NativeOperatorName(op_change[o], result, pa, pb); funcs.add(name);
- ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,"+*pa+") "+op_change[o]+" PARAM(1,"+*pb+"); thread.func_code_pos+=Call::Size(2); }"); // A OP B;
- }
- // binary compare
- FREPAD(o, op_compare)
- for(VAR_TYPE a=VAR_FROM; a<=VAR_TO; a=VAR_TYPE(a+1))
- for(VAR_TYPE b=VAR_FROM; b<=VAR_TO; b=VAR_TYPE(b+1))
- if(op_compare[o]!="===" && op_compare[o]!="!!=" && op_compare[o]!="^^") // temporarily skip extra operators
- if((op_compare[o]=="&&" || op_compare[o]=="^^" || op_compare[o]=="||") ? (SameSizeType(a)==a && SameSizeType(b)==b) : (SameSizeSignType(a)==a && SameSizeSignType(b)==b))
- {
- Symbol::Modif result, pa, pb;
- result=TypeSymbol(VAR_BOOL);
- pa =TypeSymbol(a);
- pb =TypeSymbol(b);
- Str name=NativeOperatorName(op_compare[o], result, pa, pb); funcs.add(name);
- ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,"+*result+") = (PARAM(1,"+*pa+") "+op_compare[o]+" PARAM(2,"+*pb+")); thread.func_code_pos+=Call::Size(3); }"); // RESULT = (A OP B);
- }
- // binary
- FREPAD(o, op_binary)
- for(VAR_TYPE a=VAR_FROM; a<=VAR_TO; a=VAR_TYPE(a+1))
- for(VAR_TYPE b=VAR_FROM; b<=VAR_TO; b=VAR_TYPE(b+1))
- {
- VAR_TYPE type=VAR_NONE, ta=SameSizeSignType(a), tb=SameSizeSignType(b);
- if(ta==a && tb==b)
- {
- if(op_binary[o]=="*" )type= MulResult(ta, tb);else
- if(op_binary[o]=="/" )type= DivResult(ta, tb);else
- if(op_binary[o]=="%" )type= ModResult(ta, tb);else
- if(op_binary[o]=="+" )type= AddResult(ta, tb);else
- if(op_binary[o]=="-" )type= SubResult(ta, tb);else
- if(op_binary[o]=="<<" )type= ShiftLeftResult(ta, tb);else
- if(op_binary[o]==">>" )type=ShiftRightResult(ta, tb);else
- if(op_binary[o]=="&" || op_binary[o]=="^" || op_binary[o]=="|")type= BitResult(ta, tb);
- if(type)
- {
- Symbol::Modif result, pa, pb;
- result=TypeSymbol(type);
- pa =TypeSymbol(ta);
- pb =TypeSymbol(tb);
- Str name=NativeOperatorName(op_binary[o], result, pa, pb); funcs.add(name);
- ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,"+*result+") = (PARAM(1,"+*pa+") "+op_binary[o]+" PARAM(2,"+*pb+")); thread.func_code_pos+=Call::Size(3); }"); // RESULT = (A OP B);
- }
- }
- }
- // unary !
- for(VAR_TYPE a=VAR_FROM; a<=VAR_TO; a=VAR_TYPE(a+1))
- if(SameSizeType(a)==a)
- {
- Symbol::Modif result, pa;
- result=TypeSymbol(VAR_BOOL);
- pa =TypeSymbol(a);
- Str name=NativeOperatorName("!", result, pa); funcs.add(name);
- ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,"+*result+") = !PARAM(1,"+*pa+"); thread.func_code_pos+=Call::Size(2); }"); // RESULT = !A;
- }
- // unary ~
- for(VAR_TYPE a=VAR_FROM; a<=VAR_TO; a=VAR_TYPE(a+1))if(!RealType(a))
- if(SameSizeSignType(a)==a)
- {
- Symbol::Modif result, pa;
- result=TypeSymbol(ComplementResult(a));
- pa =TypeSymbol(a);
- Str name=NativeOperatorName("~", result, pa); funcs.add(name);
- ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,"+*result+") = ~PARAM(1,"+*pa+"); thread.func_code_pos+=Call::Size(2); }"); // RESULT = ~A;
- }
- // unary -
- for(VAR_TYPE a=VAR_FROM; a<=VAR_TO; a=VAR_TYPE(a+1))
- if(SameSizeSignType(a)==a)
- {
- Symbol::Modif result, pa;
- result=TypeSymbol(NegativeResult(a));
- pa =TypeSymbol(a);
- Str name=NativeOperatorName("-", result, pa); funcs.add(name);
- ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { PARAM(0,"+*result+") = -PARAM(1,"+*pa+"); thread.func_code_pos+=Call::Size(2); }"); // RESULT = -A;
- }
- // unary ++ --
- FREPAD(o, op_inc_dec)
- for(VAR_TYPE a=VAR_FROM; a<=VAR_TO; a=VAR_TYPE(a+1))
- if(!(a==VAR_BOOL && op_inc_dec[o]=="--")) // C++ doesn't allow "--bool"
- if(SameSizeType(a)==a)
- {
- Symbol::Modif result, pa;
- result=TypeSymbol(VAR_VOID);
- pa =TypeSymbol(a);
- Str name=NativeOperatorName(op_inc_dec[o], result, pa); funcs.add(name);
- ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { "+op_inc_dec[o]+"PARAM(0,"+*pa+"); thread.func_code_pos+=Call::Size(1); }"); // ++A;
- }
- // create EE functions (as first, so binarySearch can be used without sorting native operators, and faster because of fewer functions at this stage)
- // TODO: process virtuals twice (as virtual and as not)
- FREPA(Symbols)
- {
- Symbol &func=Symbols.lockedData(i);
- if(func.isFunc() // functions
- && !(func.modifiers&Symbol::MODIF_FUNC_PARAM) // which are not function parameters "Mems& Mems::sort(Int Compare(C TYPE &a, C TYPE &b));"
- && !func.isTemplateFunc() // skip templates
- && func.fullyPublic() // this and all parents are public, skip "class Parent { private class Child { void func(); } }"
- && func.source && func.source->ee_header) // only stuff from EE headers
- {
- // TODO: skip functions which accept pointers to functions as parameters
- Bool has_func_param=false; REPA(func.params)if(func.params[i]->type==Symbol::FUNC){has_func_param=true; break;} if(has_func_param)continue;
- Str short_name=func.fullCppName();
- if(Equal (short_name, "InitPre", true) || Equal(short_name, "Init", true) || Equal(short_name, "Shut", true) || Equal(short_name, "Update", true) || Equal(short_name, "Draw", true) // skip user provided functions
- || Equal (short_name, "SupportScripts", true) // skip enabling scripts since it's already a script
- || Contains(short_name, "PVRTC" , true))continue; // skip anything PVRTC related so that the EXE is not bigger due to PVRTC compression libraries
- Int index;
- Str name=FuncName(func);
- if(!funcs.binarySearch(name, index, CompareCS))
- {
- Symbol::Modif &result =func.value, result_final=result; result_final.proceedToFinal(null, true);
- Symbol *Class =func.Class();
- Str func_name=func.cppName(), op_name;
- Bool has_result =func.hasResult(),
- has_this =func.isClassNonStaticFunc(),
- is_virtual =func.isVirtualFunc(),
- is_operator=Starts(func_name, "operator", true, true); if(is_operator)op_name=SkipWhiteChars(SkipStart(func_name, "operator"));
- if(has_result && !result
- || has_this && !Class
- || is_operator && (op_name=="new" || op_name=="delete")
- || (func.modifiers&Symbol::MODIF_CTOR) && Class->isAbstractClass() // can't call constructor using placement new for abstract classes
- )continue; // quietly skip incorrect data
- funcs.NewAt(index)=name;
- Str body=S+"thread.func_code_pos+=Call::Size("+(has_result + has_this + func.realParams())+"); ";
- Int params=0;
- if(has_result)
- if(result.modifiers&Symbol::MODIF_REF)body+=S+ "PARAM_REF("+(params++)+ ") = &(";else // PARAM_REF(0 ) = &(
- if(result_final.basicType() )body+=S+ "PARAM(" +(params++)+", "+CppStyle(ModifName(result, false, true, false, false, true))+") = (" ;else // PARAM (0, type) = (
- body+=S+"new(&PARAM(" +(params++)+", "+CppStyle(ModifName(result, false, true, false, false, true))+"))"+CppStyle(ModifName(result, false, false, false, false, true))+'('; // new(&PARAM (0, type))Class(
- if(has_this)
- {
- if(func.modifiers&Symbol::MODIF_CTOR)body+="new(&"; // new(&
- body+=S+"PARAM("+(params++)+", "+CppStyle(Class->fullCppName())+")"; // PARAM(1, type)
- if(func.modifiers&Symbol::MODIF_CTOR)body+=S+')'+CppStyle(ModifName(result, false, false, false, false, true));else // )Class
- if(func.modifiers&Symbol::MODIF_DTOR)body+=S+'.'+*Class+"::";else // ctors/dtors need to have class "XX::" added, sample: "Str::Str()"
- body+= '.';
- }
- if(!(func.modifiers&Symbol::MODIF_CTOR))
- {
- if(is_operator) // operator[], operator+, operator CChar*
- {
- body+="operator ";
- if(op_name=="cast")body+=CppStyle(ModifName(result, false, true, true));else body+=op_name;
- }else
- {
- body+=(has_this ? func_name : CppStyle(func.fullCppName())); // func
- }
- }
- body+='(';
- FREPA(func.params)
- {
- if(i)body+=", ";
- if(InRange(i, func.realParams()))body+=S+"PARAM("+(params++)+", "+CppStyle(ModifName(func.params[i]->value, false, true, false, true, true))+')'; // skip references but keep const in case there are "func(const int x)" and "func(int x)"
- else body+='0'; // 0 for dummy operator++(int)
- }
- body+=')'; // func(|)
- if(has_result)body+=')'; // x = (|)
- body+=';';
- ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { "+body+" }");
- //if(funcs.elms()>=128)break;
- }
- }
- }
- // setup default destructors
- FREPA(Symbols)
- {
- Symbol &Class=Symbols.lockedData(i);
- if( Class.type==Symbol::CLASS // classes
- && !Class.isTemplateClass() // skip templates
- && !(Class.modifiers&Symbol::MODIF_NAMELESS) // skip nameless classes
- && Class.fullyPublic() // this and all parents are public, skip "class Parent { private class Child { void func(); } }"
- && Class.source && Class.source->ee_header) // only stuff from EE headers
- {
- if(Class.hasDestructor() && !FindChild(S+'~'+Class, &Class, null, false)) // should have destructor but doesn't
- {
- Str name=DtorName(Class);
- if(funcs.binaryInclude(name, CompareCS))
- {
- Str body ="thread.func_code_pos+=Call::Size(1); ";
- body+=S+"PARAM(0, "+CppStyle(Class.fullCppName())+").";
- body+=Class+"::~"+Class+"();";
- ft.putLine(S+"static void "+SymbolToCppName(name)+"(PARAMS) { "+body+" }");
- }
- }
- }
- }
- ft.endLine();
- // put list of functions
- funcs.sort(CompareCS); // compare before writing to enable binary search later
- ft.putLine("#ifdef _MSC_VER");
- ft.putLine(" #pragma optimize(\"\", off) // because this file compiles so slow!");
- ft.putLine("#endif");
- ft.endLine();
- #if 0
- ft.putLine("static FuncCall FC[]=");
- ft.putLine("{"); ft.depth++;
- FREPA(funcs)
- {
- Bool shader_compile=(Contains(funcs[i], "EE.ShaderCompile", true, true) || Contains(funcs[i], "EE.ShaderCompileTry", true, true));
- if(shader_compile){ft.depth--; ft.putLine("#if !MAC // disable this on Mac, because compiling shaders on Mac requires CG framework installed and thus all EE based applications would not run without CG"); ft.depth++;}
- ft.putLine(S+"{\""+funcs[i]+"\", "+SymbolToCppName(funcs[i])+"},");
- if(shader_compile){ft.depth--; ft.putLine("#endif"); ft.depth++;}
- }
- ft.depth--; ft.putLine("};");
- ft.putLine("static Int ElmsFC=Elms(FC);");
- ft.putLine("static void InitFC() {}");
- #else
- ft.putLine(S+"static FuncCall FC["+funcs.elms()+"];");
- ft.putLine("static Int ElmsFC;");
- ft.putLine("static void InitFC()");
- ft.putLine("{"); ft.depth++;
- ft.putLine("if(ElmsFC)return;");
- #if 1 // makes .exe files smallest
- ft.putLine("static FuncCall FC2[]=");
- ft.putLine("{"); ft.depth++;
- FREPA(funcs)
- {
- Bool shader_compile=(Contains(funcs[i], "EE.ShaderCompile", true, true) || Contains(funcs[i], "EE.ShaderCompileTry", true, true));
- if(shader_compile){ft.depth--; ft.putLine("#if !MAC // disable this on Mac, because compiling shaders on Mac requires CG framework installed and thus all EE based applications would not run without CG"); ft.depth++;}
- ft.putLine(S+"{\""+funcs[i]+"\", "+SymbolToCppName(funcs[i])+"},");
- if(shader_compile){ft.depth--; ft.putLine("#endif"); ft.depth++;}
- }
- ft.depth--; ft.putLine("};");
- ft.putLine("CopyN(FC, FC2, ElmsFC=Elms(FC2));");
- #else
- ft.putLine("int i=0;");
- FREPA(funcs)
- {
- Bool shader_compile=(Contains(funcs[i], "EE.ShaderCompile", true, true) || Contains(funcs[i], "EE.ShaderCompileTry", true, true));
- if(shader_compile){ft.depth--; ft.putLine("#if !MAC // disable this on Mac, because compiling shaders on Mac requires CG framework installed and thus all EE based applications would not run without CG"); ft.depth++;}
- ft.putLine(S+"FC[i].name=\""+funcs[i]+"\"; FC[i].func="+SymbolToCppName(funcs[i])+"; i++;");
- if(shader_compile){ft.depth--; ft.putLine("#endif"); ft.depth++;}
- }
- ft.putLine("ElmsFC=i;");
- #endif
- ft.depth--; ft.putLine("}");
- #endif
- // put list of variables
- FREPA(Symbols)
- {
- Symbol &var=Symbols.lockedData(i);
- if(var.isVar() // variables
- && var.isGlobalOrStatic()
- && var.fullyPublic()
- && var.source && var.source->ee_header) // only stuff from EE headers
- {
- Str short_name=var.fullCppName();
- if(Contains(short_name, "PVRTC", true))continue; // skip anything PVRTC related so that the EXE is not bigger due to PVRTC compression libraries
- vars.add(short_name);
- }
- }
- vars.sort(CompareCS); // compare before writing to enable binary search later
- ft.endLine();
- ft.putLine("static GlobalVar GV[]=");
- ft.putLine("{"); ft.depth++;
- FREPA(vars)ft.putLine(S+"{\""+vars[i]+"\", &"+CppStyle(vars[i])+"},");
- ft.depth--; ft.putLine("};");
- ft.endLine(); ft.depth++;
- ft.putLine("#ifdef _MSC_VER");
- ft.putLine(" #pragma optimize(\"\", on) // because this file compiles so slow!");
- ft.putLine("#endif"); ft.depth--;
- ft.putLine("#endif // SUPPORT_SCRIPTS");
- if(!OverwriteOnChange(ft, "C:\\Projects\\EsenthelEngine\\Src\\Code\\Compile\\CE Func List.h"))Exit("Can't create FuncList");
- }
- /******************************************************************************/
- // FUNCTION LIST
- /******************************************************************************/
- void Call::Param::set(Expr &expr, Compiler &compiler, Bool auto_map)
- {
- switch(expr.mem.type)
- {
- case Expr::Memory::GLOBAL:
- {
- if(expr.mem.index>=0) {setHeap (expr.mem.index+expr.mem.offset, expr.mem.offset2, FlagTest(expr.symbol.modifiers, Symbol::MODIF_REF)); return;} // set successfully
- if(expr.mem.symbol)if(CPtr addr=FindGlobalVar(expr.mem.symbol->fullCppName())){setGlobal((Byte*)addr +expr.mem.offset, expr.mem.offset2, FlagTest(expr.symbol.modifiers, Symbol::MODIF_REF)); return;} // set successfully
- }break;
- case Expr::Memory::LOCAL:
- {
- if(InRange(expr.mem.index, compiler.locals))
- {
- Local &local=compiler.locals[expr.mem.index];
- if(local.stack_offset< 0 && auto_map)compiler.mapLocalInStack(expr.mem); // auto map only if allowed
- if(local.stack_offset>=0)
- {
- if(local.force_heap)setHeap (local.stack_offset+expr.mem.offset, expr.mem.offset2, FlagTest(expr.symbol.modifiers, Symbol::MODIF_REF));
- else setStack(local.stack_offset+expr.mem.offset, expr.mem.offset2, FlagTest(expr.symbol.modifiers, Symbol::MODIF_REF));
- return; // set successfully
- }
- }
- }break;
- case Expr::Memory::PARAM:
- {
- if(expr.mem.index>=0){setParamStack(expr.mem.index+expr.mem.offset, expr.mem.offset2, FlagTest(expr.symbol.modifiers, Symbol::MODIF_REF)); return;} // set successfully
- }break;
- case Expr::Memory::THIS:
- {
- setThis(expr.mem.offset, expr.mem.offset2, FlagTest(expr.symbol.modifiers, Symbol::MODIF_REF)); return; // set successfully
- }break;
- case Expr::Memory::RESULT:
- {
- if(expr.mem.offset==0 && expr.mem.offset2==0){setResult(); return;} // set successfully
- }break;
- case Expr::Memory::KNOWN:
- {
- if(expr.mem.offset==0 && expr.mem.offset2==0)
- {
- Int size=expr.symbol.rawSize(false);
- U64 raw =expr.asRaw(compiler);
- if(ValueFitsInInstruction(size) || expr.symbol.isPtr() && !raw)setInstruct(raw);else setHeap(compiler.heapConstant(&raw, size, expr.symbol.firstMemberSize()), 0, false);
- return;
- }
- }break;
-
- case Expr::Memory::NONE:
- {
- if(expr.instance && expr.symbol.isArray() && expr.symbol && (expr.symbol->var_type==VAR_CHAR8 || expr.symbol->var_type==VAR_CHAR16)) // "text"
- if(expr[0]=='"' || (expr[1]=='"' && (expr[0]=='8' || expr[0]=='u' || expr[0]=='U' || expr[0]=='L'))) // "", 8"", u"", U"", L""
- {
- Int heap;
- Memc<Char> text=expr.asText(compiler);
- if(expr.symbol->var_type==VAR_CHAR16)heap=compiler.heapConstant(text.data(), text.elms()*SIZE(Char), 2);else
- {
- Mems<Char8> text8; text8.setNum(text.elms()); FREPAO(text8)=Char16To8Fast(text[i]); // convert Str to Str8, we can assume that Str was already initialized
- heap=compiler.heapConstant(text8.data(), text8.elms(), 1);
- }
- setHeap(heap, 0, false);
- return;
- }
- }break;
- }
- compiler.msgs.New().error("Unknown memory address of expression", expr.origin);
- }
- void Call::Param::setRef(Expr &expr, Compiler &compiler)
- {
- set(expr, compiler);
- switch(type)
- {
- default : return; // don't check after switch
- case ADDR_GLOBAL_REF: type=ADDR_GLOBAL; break;
- case ADDR_HEAP_REF : type=ADDR_HEAP ; break;
- case ADDR_STACK_REF : type=ADDR_STACK ; break;
- case ADDR_THIS_REF : type=ADDR_THIS ; break;
- }
- if(offset2!=0)compiler.msgs.New().error("Invalid reference address", expr.origin);
- }
- void Call::Param::setGlobal (Ptr addr , Int offset2, Bool ref) {type=(ref ? ADDR_GLOBAL_REF : ADDR_GLOBAL ); T.addr =addr ; T.offset2=offset2;}
- void Call::Param::setHeap (Int offset, Int offset2, Bool ref) {type=(ref ? ADDR_HEAP_REF : ADDR_HEAP ); T.offset=offset; T.offset2=offset2;}
- void Call::Param::setStack (Int offset, Int offset2, Bool ref) {type=(ref ? ADDR_STACK_REF : ADDR_STACK ); T.offset=offset; T.offset2=offset2;}
- void Call::Param::setParamStack (Int offset, Int offset2, Bool ref) {type=(ref ? ADDR_PARAM_STACK_REF : ADDR_PARAM_STACK); T.offset=offset; T.offset2=offset2;}
- void Call::Param::setThis (Int offset, Int offset2, Bool ref) {type=(ref ? ADDR_THIS_REF : ADDR_THIS ); T.offset=offset; T.offset2=offset2;}
- void Call::Param::setResult ( ) {type= ADDR_RESULT ; T.offset= 0; T.offset2= 0;}
- void Call::Param::setInstruct (U64 raw ) {type= ADDR_INSTRUCT ; T.raw =raw ; }
- void Call::Param::setInstructI (Int raw ) {type= ADDR_INSTRUCT ; T.offset=raw ; T.offset2= 0;}
- void Call::Param::setInstructP (Ptr addr ) {type= ADDR_INSTRUCT ; T.addr =addr ; T.offset2= 0;}
- void Call::Param::setInstructPI2(Ptr addr , Int i ) {type= ADDR_INSTRUCT ; T.addr =addr ; T.offset2= i;}
- #if WINDOWS
- #pragma warning(push)
- #pragma warning(disable:4715) // not all control paths return a value
- #endif
- #if 0
- Ptr Call::Param::address(CodeEnvironment::Thread &thread)
- {
- switch(type)
- {
- case ADDR_STACK : return (thread.func_stack +offset);
- case ADDR_STACK_REF : return (*(Byte**)(thread.func_stack +offset)) + offset2;
- case ADDR_PARAM_STACK : return (thread.func_param_stack+offset);
- case ADDR_PARAM_STACK_REF: return (*(Byte**)(thread.func_param_stack+offset)) + offset2;
- case ADDR_THIS : return (thread.func_this +offset);
- case ADDR_THIS_REF : return (*(Byte**)(thread.func_this +offset)) + offset2;
- case ADDR_RESULT : return (thread.func_result );
- case ADDR_HEAP : return (thread.heap +offset);
- case ADDR_HEAP_REF : return (*(Byte**)(thread.heap +offset)) + offset2;
- case ADDR_GLOBAL : return ( addr);
- case ADDR_GLOBAL_REF : return (*(Byte**)( addr)) + offset2;
- case ADDR_INSTRUCT : return &( raw);
- }
- }
- #else
- // TODO: make all _REF with _REF_OFS and only there apply 'offset2'?
- T1(TYPE) TYPE& Call::Param::value(CodeEnvironment::Thread &thread)
- {
- switch(type)
- {
- case ADDR_STACK : return *(TYPE*) (thread.func_stack +offset);
- case ADDR_STACK_REF : return *(TYPE*)((*(Byte**)(thread.func_stack +offset)) + offset2);
- case ADDR_PARAM_STACK : return *(TYPE*) (thread.func_param_stack+offset);
- case ADDR_PARAM_STACK_REF: return *(TYPE*)((*(Byte**)(thread.func_param_stack+offset)) + offset2);
- case ADDR_THIS : return *(TYPE*) (thread.func_this +offset);
- case ADDR_THIS_REF : return *(TYPE*)((*(Byte**)(thread.func_this +offset)) + offset2);
- case ADDR_RESULT : return *(TYPE*) (thread.func_result );
- case ADDR_HEAP : return *(TYPE*) (thread.heap +offset);
- case ADDR_HEAP_REF : return *(TYPE*)((*(Byte**)(thread.heap +offset)) + offset2);
- case ADDR_GLOBAL : return *(TYPE*) ( addr);
- case ADDR_GLOBAL_REF : return *(TYPE*)((*(Byte**)( addr)) + offset2);
- case ADDR_INSTRUCT : return reinterpret_cast<TYPE&>( raw); // use 'reinterpret_cast' instead of (TYPE&) because 'TYPE' can be const and "(const TYPE&)(raw)" could create new temporary var
- }
- }
- INLINE Ptr Call::Param::address(CodeEnvironment::Thread &thread) {return &value<Byte>(thread);} // use Byte because void can't be used
- #endif
- CPtr& Call::Param::ref(CodeEnvironment::Thread &thread)
- {
- switch(type)
- {
- case ADDR_STACK_REF : return *(CPtr*)(thread.func_stack +offset);
- case ADDR_PARAM_STACK_REF: return *(CPtr*)(thread.func_param_stack+offset);
- case ADDR_THIS_REF : return *(CPtr*)(thread.func_this +offset);
- case ADDR_HEAP_REF : return *(CPtr*)(thread.heap +offset);
- case ADDR_GLOBAL_REF : return *(CPtr*)( addr);
- }
- return *(CPtr*)null; // on purpose return null based pointer so it will trigger exception
- }
- #if WINDOWS
- #pragma warning(pop)
- #endif
- /******************************************************************************/
- #define PARAMS Call &call, CodeEnvironment::Thread &thread
- #define PARAM(i, type) call.param(i).value<type>(thread)
- #define PARAM_REF(i ) call.param(i).ref (thread)
- #define bool Bool // boolean value (8-bit)
- #define char8 Char8 // 8-bit character
- #define char Char // 16-bit character
- #define sbyte I8 // 8-bit signed integer
- #define byte U8 // 8-bit unsigned integer
- #define short I16 // 16-bit signed integer
- #define ushort U16 // 16-bit unsigned integer
- #define int I32 // 32-bit signed integer
- #define uint U32 // 32-bit unsigned integer
- #define long I64 // 64-bit signed integer
- #define ulong U64 // 64-bit unsigned integer
- #define flt Flt // 32-bit floating point
- #define dbl Dbl // 64-bit floating point
- #define ptr Ptr // universal pointer
- #define cptr CPtr // universal pointer to const data
- #define cchar8 CChar8 // const Char8
- #define cchar CChar // const Char16
- #define intptr IntPtr // signed integer capable of storing full memory address
- #define uintptr UIntPtr // unsigned integer capable of storing full memory address
- #if WINDOWS
- #pragma warning(push)
- #pragma warning(disable:4800) // forcing value to bool 'true' or 'false' (performance warning)
- #pragma warning(disable:4804) // unsafe use of type 'bool' in operation
- #pragma warning(disable:4805) // unsafe mix of type A and type B in operation
- #pragma warning(disable:4146) // unary minus operator applied to unsigned type, result still unsigned
- #endif
- #include "CE Func List.h"
- #if WINDOWS
- #pragma warning(pop)
- #endif
- #undef bool
- #undef char8
- #undef char
- #undef sbyte
- #undef byte
- #undef short
- #undef ushort
- #undef int
- #undef uint
- #undef long
- #undef ulong
- #undef flt
- #undef dbl
- #undef ptr
- #undef cptr
- #undef cchar8
- #undef cchar
- #undef intptr
- #undef uintptr
- #undef PARAMS
- #undef PARAM
- #undef PARAM_REF
- /******************************************************************************/
- static Int CompareFC(C FuncCall &fc, C Str &func_name ) {return CompareCS(fc.name, func_name);}
- static Int CompareGV(C GlobalVar &gv, C Str & var_name ) {return CompareCS(gv.name, var_name);}
- static Int CompareFC( FuncCall*C &a , FuncCall*C &b ) {if(a->func < b->func)return -1; if(a->func > b->func)return +1; return 0;}
- static Int CompareFC( FuncCall*C &a , C Call::Func &func) {if(a->func < func)return -1; if(a->func > func)return +1; return 0;}
- #ifdef SUPPORT_SCRIPTS
- CChar8* FindFuncCall(Call::Func func)
- {
- if(!FC2.elms()){FC2.setNum(ElmsFC); FREPAO(FC2)=&FC[i]; FC2.sort(CompareFC);} // create array of functions sorted by their 'func' address
- Int index; return FC2.binarySearch(func, index, CompareFC) ? FC2[index]->name : null;
- }
- Call::Func FindFuncCall(C Str &func_name)
- {
- Int index; return BinarySearch(FC, ElmsFC, func_name, index, CompareFC) ? FC[index].func : null;
- }
- CPtr FindGlobalVar(C Str &var_name)
- {
- Int index; return BinarySearch(GV, Elms(GV), var_name, index, CompareGV) ? GV[index].addr : null;
- }
- #else
- CChar8* FindFuncCall (Call::Func func) {return null;}
- Call::Func FindFuncCall (C Str &func_name) {return null;}
- CPtr FindGlobalVar(C Str & var_name) {return null;}
- #endif
- Call::Func GetFuncCall(C Str &func_name)
- {
- Call::Func func=FindFuncCall(func_name); if(!func)Exit(S+"Can't find \""+func_name+"\" function.");
- return func;
- }
- Call::Func GetIgnoreCall() {return $nop;}
- Call::Func GetCallFunc(Bool has_this, Bool has_result)
- {
- if(has_this)return has_result ? $call$20method$20result : $call$20method;
- return has_result ? $call$20func$20result : $call$20func;
- }
- Call::Func GetIndirectionCall() {return $indirection ;}
- Call::Func GetAddressOfCall () {return $address$20of;}
- Call::Func GetOffsetCall (Symbol::Modif &offset)
- {
- if(offset)switch(offset.rawSize(false))
- {
- case 1: return SignedType(offset->var_type) ? $offset$201s : $offset$201u;
- case 2: return SignedType(offset->var_type) ? $offset$202s : $offset$202u;
- case 4: return SignedType(offset->var_type) ? $offset$204s : $offset$204u;
- case 8: return SignedType(offset->var_type) ? $offset$208s : $offset$208u;
- }
- return null;
- }
- Call::Func GetAddPtrCall(Symbol::Modif &offset)
- {
- if(offset)switch(offset.rawSize(false))
- {
- case 1: return SignedType(offset->var_type) ? $add$20ptr$201s : $add$20ptr$201u;
- case 2: return SignedType(offset->var_type) ? $add$20ptr$202s : $add$20ptr$202u;
- case 4: return SignedType(offset->var_type) ? $add$20ptr$204s : $add$20ptr$204u;
- case 8: return SignedType(offset->var_type) ? $add$20ptr$208s : $add$20ptr$208u;
- }
- return null;
- }
- Call::Func GetPtrAddCall(Symbol::Modif &offset)
- {
- if(offset)switch(offset.rawSize(false))
- {
- case 1: return SignedType(offset->var_type) ? $ptr$20add$201s : $ptr$20add$201u;
- case 2: return SignedType(offset->var_type) ? $ptr$20add$202s : $ptr$20add$202u;
- case 4: return SignedType(offset->var_type) ? $ptr$20add$204s : $ptr$20add$204u;
- case 8: return SignedType(offset->var_type) ? $ptr$20add$208s : $ptr$20add$208u;
- }
- return null;
- }
- Call::Func GetPtrDiffCall() {return $ptr$20diff;}
- Call::Func GetGotoCall() {return $goto;}
- Call::Func GetGotoCondCall(Symbol::Modif &cond)
- {
- if(cond.isPtr())
- {
- if(PtrSize==4)return $goto$20cond$204;
- if(PtrSize==8)return $goto$20cond$208;
- }else
- if(cond.isObj() && cond)switch(cond->var_type)
- {
- case VAR_CHAR8 :
- case VAR_BOOL :
- case VAR_BYTE :
- case VAR_SBYTE : return $goto$20cond$201;
- case VAR_CHAR16:
- case VAR_SHORT :
- case VAR_USHORT: return $goto$20cond$202;
- case VAR_ENUM :
- case VAR_INT :
- case VAR_UINT : return $goto$20cond$204;
- case VAR_LONG :
- case VAR_ULONG : return $goto$20cond$208;
- case VAR_FLT : return $goto$20cond$20f;
- case VAR_DBL : return $goto$20cond$20d;
- }
- return null;
- }
- Call::Func GetGotoCondNCall(Symbol::Modif &cond)
- {
- if(cond.isPtr())
- {
- if(PtrSize==4)return $goto$20cond$20n$204;
- if(PtrSize==8)return $goto$20cond$20n$208;
- }else
- if(cond.isObj() && cond)switch(cond->var_type)
- {
- case VAR_CHAR8 :
- case VAR_BOOL :
- case VAR_BYTE :
- case VAR_SBYTE : return $goto$20cond$20n$201;
- case VAR_CHAR16:
- case VAR_SHORT :
- case VAR_USHORT: return $goto$20cond$20n$202;
- case VAR_ENUM :
- case VAR_INT :
- case VAR_UINT : return $goto$20cond$20n$204;
- case VAR_LONG :
- case VAR_ULONG : return $goto$20cond$20n$208;
- case VAR_FLT : return $goto$20cond$20n$20f;
- case VAR_DBL : return $goto$20cond$20n$20d;
- }
- return null;
- }
- Call::Func GetSetConstCall(Int size, Bool heap)
- {
- switch(size)
- {
- case 1: return heap ? $set$20const$20heap$201 : $set$20const$201;
- case 2: return heap ? $set$20const$20heap$202 : $set$20const$202;
- case 4: return heap ? $set$20const$20heap$204 : $set$20const$204;
- case 8: return heap ? $set$20const$20heap$208 : $set$20const$208;
- default: return null;
- }
- }
- Call::Func GetSetAddrHeapCall () {return $set$20addr$20heap ;}
- Call::Func GetSetAddrStackCall () {return $set$20addr$20stack ;}
- Call::Func GetSetAddrResultCall() {return $set$20addr$20result;}
- /******************************************************************************/
- } // namespace Edit
- /******************************************************************************/
- void SupportScripts()
- {
- #ifdef SUPPORT_SCRIPTS
- Edit::InitFC();
- #endif
- }
- Bool ScriptsSupported()
- {
- #ifdef SUPPORT_SCRIPTS
- return Edit::ElmsFC>0;
- #else
- return false;
- #endif
- }
- /******************************************************************************/
- } // namespace EE
- /******************************************************************************/
|