| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203 |
- --Java class editor
- --[[
- This will show an userinterface for editing java classes and will return a list of "patch" commands
- that can be used with the runtime java class edit commands
- e.g:
- DefineLabel(spot)
- InsertBytecode(spot, command)
- ModifyBytecode(spot, command)
- DeleteBytecode(spot) (could be ModifyBytecode(spot,"nop") )
- The user should not have to know about exceptions and how their positions change with each insert/delete
- gui:
- listview:
- index|byteindex|label |exception|instruction|
- -----|---------|------|---------|-----------|
- 0 |0 | | |nop | Insert
- 0 |1 |l1: |ex1: |branch l1 | Delete
- Modify
- --]]
- --http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html
- java_bytecodes={}
- --[[
- paramtypes:
- s1=signed 1 byte
- s2=signed 2 byte
- s4=signed 4 byte
- u1=unsigned 1 byte
- u2=unsigned 2 byte
- u4=unsigned 4 byte
- 02=null 2 bytes
- wide=special wide operand
- pad4=pad till 4 byte alignment
- [s4]=array of 4 byte signed values
- [s4s4]=array of 2 4 byte signed values
- --]]
- function signExtendByte(byte)
- --byte is a value between 0 and 255
- --if bit 7 is 1, it's a negative
- if bAnd(byte,0x80)~=0 then
- return byte-0x100
- else
- return byte
- end
- end
- function signExtendWord(word)
- if bAnd(word,0x8000)~=0 then
- return word-0x10000
- else
- return word
- end
- end
- function signExtendDword(dword)
- --assuming dword is in the range of 0 to 0xffffffff
- if bAnd(dword,0x80000000)~=0 then
- return dword-0x100000000
- else
- return dword
- end
- end
- function calculateTableSwitch(address, bytes)
- local result=nil
- if bytes[address]==0xaa then
- local padding=0
- if (address-1) % 4>0 then
- padding=4-(address-1) % 4
- end
- --local defaultbyte=byteTableToDword({bytes[8],bytes[7],bytes[6],bytes[5]})
- local low=byteTableToDword({bytes[address+1+padding+7],bytes[address+1+padding+6],bytes[address+1+padding+5],bytes[address+1+padding+4]})
- local high=byteTableToDword({bytes[address+1+padding+11],bytes[address+1+padding+10],bytes[address+1+padding+9],bytes[address+1+padding+8]})
- result=padding+4+4+4+((high-low)+1)*4 --paramsize
- end
- return result;
- end
- function calculateLookupSwitch(address, bytes)
- local result=nil
- if bytes[address]==0xab then
- local padding=0
- if (address-1) % 4>0 then
- padding=4-(address-1) % 4
- end
- --local defaultbyte=byteTableToDword({bytes[8],bytes[7],bytes[6],bytes[5]})
- local npairs=byteTableToDword({bytes[address+1+padding+7],bytes[address+1+padding+6],bytes[address+1+padding+5],bytes[address+1+padding+4]})
- result=padding+4+4+npairs*8 --paramsize
- end
- return result;
- end
- java_bytecodes[0x00]={operation="nop", description="Do nothing"}
- java_bytecodes[0x01]={operation="aconst_null", description="Push null"}
- java_bytecodes[0x02]={operation="iconst_m1", description="Push int -1"}
- java_bytecodes[0x03]={operation="iconst_0", description="Push int 0"}
- java_bytecodes[0x04]={operation="iconst_1", description="Push int 1"}
- java_bytecodes[0x05]={operation="iconst_2", description="Push int 2"}
- java_bytecodes[0x06]={operation="iconst_3", description="Push int 3"}
- java_bytecodes[0x07]={operation="iconst_4", description="Push int 4"}
- java_bytecodes[0x08]={operation="iconst_5", description="Push int 5"}
- java_bytecodes[0x09]={operation="lconst_0", description="Push long 0"}
- java_bytecodes[0x0a]={operation="lconst_1", description="Push long 1"}
- java_bytecodes[0x0b]={operation="fconst_0", description="Push float 0.0"}
- java_bytecodes[0x0c]={operation="fconst_1", description="Push float 1.0"}
- java_bytecodes[0x0d]={operation="fconst_2", description="Push float 2.0"}
- java_bytecodes[0x0e]={operation="dconst_0", description="Push double 0.0"}
- java_bytecodes[0x0f]={operation="dconst_1", description="Push double 1.0"}
- java_bytecodes[0x10]={operation="bipush", parameters={bytecount=1, {paramname="const", paramtype="s1"}}, description="Push byte"}
- java_bytecodes[0x11]={operation="sipush", parameters={bytecount=2, {paramname="const", paramtype="s2"}}, description="Push short"}
- java_bytecodes[0x12]={operation="ldc", parameters={bytecount=1, {paramname="index", paramtype="u1"}}, description="Push item from run-time constant pool"}
- java_bytecodes[0x13]={operation="ldc_w", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Push item from run-time constant pool(wide)"}
- java_bytecodes[0x14]={operation="ldc2_w", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Push long or double from run-time constant pool(wide)"}
- java_bytecodes[0x15]={operation="iload", parameters={bytecount=1, {paramname="index", paramtype="u1"}}, wideparameters={bytecount=2, {paramname="index", paramtype="u2"}},description="Load int from local variable"}
- java_bytecodes[0x16]={operation="lload", parameters={bytecount=1, {paramname="index", paramtype="u1"}}, wideparameters={bytecount=2, {paramname="index", paramtype="u2"}},description="Load long from local variable"}
- java_bytecodes[0x17]={operation="fload", parameters={bytecount=1, {paramname="index", paramtype="u1"}}, wideparameters={bytecount=2, {paramname="index", paramtype="u2"}},description="Load float from local variable"}
- java_bytecodes[0x18]={operation="dload", parameters={bytecount=1, {paramname="index", paramtype="u1"}}, wideparameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Load double from local variable"}
- java_bytecodes[0x19]={operation="aload", parameters={bytecount=1, {paramname="index", paramtype="u1"}}, wideparameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Load reference from local variable"}
- java_bytecodes[0x1a]={operation="iload_0", description="Load int from local variable at index 0"}
- java_bytecodes[0x1b]={operation="iload_1", description="Load int from local variable at index 1"}
- java_bytecodes[0x1c]={operation="iload_2", description="Load int from local variable at index 2"}
- java_bytecodes[0x1d]={operation="iload_3", description="Load int from local variable at index 3"}
- java_bytecodes[0x1e]={operation="lload_0", description="Load long from local variable at index 0"}
- java_bytecodes[0x1f]={operation="lload_1", description="Load long from local variable at index 1"}
- java_bytecodes[0x20]={operation="lload_2", description="Load long from local variable at index 2"}
- java_bytecodes[0x21]={operation="lload_3", description="Load long from local variable at index 3"}
- java_bytecodes[0x22]={operation="fload_0", description="Load float from local variable at index 0"}
- java_bytecodes[0x23]={operation="fload_1", description="Load float from local variable at index 1"}
- java_bytecodes[0x24]={operation="fload_2", description="Load float from local variable at index 2"}
- java_bytecodes[0x25]={operation="fload_3", description="Load float from local variable at index 3"}
- java_bytecodes[0x26]={operation="dload_0", description="Load double from local variable at index 0"}
- java_bytecodes[0x27]={operation="dload_1", description="Load double from local variable at index 1"}
- java_bytecodes[0x28]={operation="dload_2", description="Load double from local variable at index 2"}
- java_bytecodes[0x29]={operation="dload_3", description="Load double from local variable at index 3"}
- java_bytecodes[0x2a]={operation="aload_0", description="Load reference from local variable at index 0"}
- java_bytecodes[0x2b]={operation="aload_1", description="Load reference from local variable at index 1"}
- java_bytecodes[0x2c]={operation="aload_2", description="Load reference from local variable at index 2"}
- java_bytecodes[0x2d]={operation="aload_3", description="Load reference from local variable at index 3"}
- java_bytecodes[0x2e]={operation="iaload", description="Load int from array"}
- java_bytecodes[0x2f]={operation="laload", description="Load long from array"}
- java_bytecodes[0x30]={operation="faload", description="Load float from array"}
- java_bytecodes[0x31]={operation="daload", description="Load double from array"}
- java_bytecodes[0x32]={operation="aaload", description="Load reference from array"}
- java_bytecodes[0x33]={operation="baload", description="Load byte or boolean from array"}
- java_bytecodes[0x34]={operation="caload", description="Load char from array"}
- java_bytecodes[0x35]={operation="saload", description="Load short from array"}
- java_bytecodes[0x36]={operation="istore", parameters={bytecount=1, {paramname="index", paramtype="u1"}}, wideparameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Store float into local variable"}
- java_bytecodes[0x37]={operation="lstore", parameters={bytecount=1, {paramname="index", paramtype="u1"}}, wideparameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Store float into local variable"}
- java_bytecodes[0x38]={operation="fstore", parameters={bytecount=1, {paramname="index", paramtype="u1"}}, wideparameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Store float into local variable"}
- java_bytecodes[0x39]={operation="dstore", parameters={bytecount=1, {paramname="index", paramtype="u1"}}, wideparameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Store double into local variable"}
- java_bytecodes[0x3a]={operation="astore", parameters={bytecount=1, {paramname="index", paramtype="u1"}}, wideparameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Store reference into local variable"}
- java_bytecodes[0x3b]={operation="istore_0", description="Store int into local variable at index 0"}
- java_bytecodes[0x3c]={operation="istore_1", description="Store int into local variable at index 1"}
- java_bytecodes[0x3d]={operation="istore_2", description="Store int into local variable at index 2"}
- java_bytecodes[0x3e]={operation="istore_3", description="Store int into local variable at index 3"}
- java_bytecodes[0x3f]={operation="lstore_0", description="Store long into local variable at index 0"}
- java_bytecodes[0x40]={operation="lstore_1", description="Store long into local variable at index 1"}
- java_bytecodes[0x41]={operation="lstore_2", description="Store long into local variable at index 2"}
- java_bytecodes[0x42]={operation="lstore_3", description="Store long into local variable at index 3"}
- java_bytecodes[0x43]={operation="fstore_0", description="Store float into local variable at index 0"}
- java_bytecodes[0x44]={operation="fstore_1", description="Store float into local variable at index 1"}
- java_bytecodes[0x45]={operation="fstore_2", description="Store float into local variable at index 2"}
- java_bytecodes[0x46]={operation="fstore_3", description="Store float into local variable at index 3"}
- java_bytecodes[0x47]={operation="dstore_0", description="Store double into local variable at index 0"}
- java_bytecodes[0x48]={operation="dstore_1", description="Store double into local variable at index 1"}
- java_bytecodes[0x49]={operation="dstore_2", description="Store double into local variable at index 2"}
- java_bytecodes[0x4a]={operation="dstore_3", description="Store double into local variable at index 3"}
- java_bytecodes[0x4b]={operation="astore_0", description="Store reference into local variable at index 0"}
- java_bytecodes[0x4c]={operation="astore_1", description="Store reference into local variable at index 1"}
- java_bytecodes[0x4d]={operation="astore_2", description="Store reference into local variable at index 2"}
- java_bytecodes[0x4e]={operation="astore_3", description="Store reference into local variable at index 3"}
- java_bytecodes[0x4f]={operation="iastore", description="Store into int array"}
- java_bytecodes[0x50]={operation="lastore", description="Store into long array"}
- java_bytecodes[0x51]={operation="fastore", description="Store into float array"}
- java_bytecodes[0x52]={operation="dastore", description="Store into double array"}
- java_bytecodes[0x53]={operation="aastore", description="Store into reference array"}
- java_bytecodes[0x54]={operation="bastore", description="Store into byte or boolean array"}
- java_bytecodes[0x55]={operation="castore", description="Store into char array"}
- java_bytecodes[0x56]={operation="sastore", description="Store into short array"}
- java_bytecodes[0x57]={operation="pop", description="Pop the top operand stack value"}
- java_bytecodes[0x58]={operation="pop", description="Pop the top one or two operand stack values"}
- java_bytecodes[0x59]={operation="dup", description="Duplicate the top operand stack value"}
- java_bytecodes[0x5a]={operation="dup_x1", description="Duplicate the top operand stack value and insert two values down"}
- java_bytecodes[0x5b]={operation="dup_x2", description="Duplicate the top operand stack value and insert three values down"}
- java_bytecodes[0x5c]={operation="dup2", description="Duplicate the top one or two operand stack values"}
- java_bytecodes[0x5d]={operation="dup2_x1", description="Duplicate the top one or two operand stack values and insert two or three values down"}
- java_bytecodes[0x5e]={operation="dup2_x2", description="Duplicate the top one or two operand stack values and insert two, three, or four values down "}
- java_bytecodes[0x5f]={operation="swap", description="Swap the two operand stack values"}
- java_bytecodes[0x60]={operation="iadd", description="Add int"}
- java_bytecodes[0x61]={operation="ladd", description="Add long"}
- java_bytecodes[0x62]={operation="fadd", description="Add float"}
- java_bytecodes[0x63]={operation="dadd", description="Add double"}
- java_bytecodes[0x64]={operation="isub", description="Subtract int"}
- java_bytecodes[0x65]={operation="lsub", description="Subtract long"}
- java_bytecodes[0x66]={operation="fsub", description="Subtract float"}
- java_bytecodes[0x67]={operation="dsub", description="Subtract double"}
- java_bytecodes[0x68]={operation="imul", description="Multiply int"}
- java_bytecodes[0x69]={operation="lmul", description="Multiply long"}
- java_bytecodes[0x6a]={operation="fmul", description="Multiply float"}
- java_bytecodes[0x6b]={operation="dmul", description="Multiply double"}
- java_bytecodes[0x6c]={operation="idiv", description="Divide int"}
- java_bytecodes[0x6d]={operation="ldiv", description="Divide long"}
- java_bytecodes[0x6e]={operation="fdiv", description="Divide float"}
- java_bytecodes[0x6f]={operation="ddiv", description="Divide double"}
- java_bytecodes[0x70]={operation="irem", description="Remainder int"}
- java_bytecodes[0x71]={operation="lrem", description="Remainder long"}
- java_bytecodes[0x72]={operation="frem", description="Remainder float"}
- java_bytecodes[0x73]={operation="drem", description="Remainder double"}
- java_bytecodes[0x74]={operation="ineg", description="Negate int"}
- java_bytecodes[0x75]={operation="lneg", description="Negate long"}
- java_bytecodes[0x76]={operation="fneg", description="Negate float"}
- java_bytecodes[0x77]={operation="dneg", description="Negate double"}
- java_bytecodes[0x78]={operation="ishl", description="Shift left int"}
- java_bytecodes[0x79]={operation="lshl", description="Shift left long"}
- java_bytecodes[0x7a]={operation="ishr", description="Shift right int"}
- java_bytecodes[0x7b]={operation="lshr", description="Aritmetic shift right long"}
- java_bytecodes[0x7c]={operation="iushr", description="Logical shift right int"}
- java_bytecodes[0x7d]={operation="lushr", description="Logical shift right long"}
- java_bytecodes[0x7e]={operation="iand", description="Boolean AND int"}
- java_bytecodes[0x7f]={operation="land", description="Boolean AND long"}
- java_bytecodes[0x80]={operation="ior", description="Boolean OR int"}
- java_bytecodes[0x81]={operation="lor", description="Boolean OR long"}
- java_bytecodes[0x82]={operation="ixor", description="Boolean XOR int"}
- java_bytecodes[0x83]={operation="lxor", description="Boolean XOR long"}
- java_bytecodes[0x84]={operation="iinc", parameters={bytecount=2, {paramname="index", paramtype="u1"}, {paramname="const", paramtype="s1"}}, wideparameters={bytecount=4, {paramname="index", paramtype="u2"}, {paramname="const", paramtype="s2"}}, description="Increment local variable by constant"}
- java_bytecodes[0x85]={operation="i2l", description="Convert int to long"}
- java_bytecodes[0x86]={operation="i2f", description="Convert int to float"}
- java_bytecodes[0x87]={operation="i2d", description="Convert int to double"}
- java_bytecodes[0x88]={operation="l2i", description="Convert long to int"}
- java_bytecodes[0x89]={operation="l2f", description="Convert long to float"}
- java_bytecodes[0x8a]={operation="l2d", description="Convert long to double"}
- java_bytecodes[0x8b]={operation="f2i", description="Convert float to int"}
- java_bytecodes[0x8c]={operation="f2l", description="Convert float to long"}
- java_bytecodes[0x8d]={operation="f2d", description="Convert float to double"}
- java_bytecodes[0x8e]={operation="d2i", description="Convert double to int"}
- java_bytecodes[0x8f]={operation="d2l", description="Convert double to long"}
- java_bytecodes[0x90]={operation="d2f", description="Convert double to float"}
- java_bytecodes[0x91]={operation="i2b", description="Convert int to byte"}
- java_bytecodes[0x92]={operation="i2c", description="Convert int to char"}
- java_bytecodes[0x93]={operation="i2s", description="Convert int to short"}
- java_bytecodes[0x94]={operation="lcmp", description="Compare long"}
- java_bytecodes[0x95]={operation="fcmpl", description="Compare float"}
- java_bytecodes[0x96]={operation="fcmpg", description="Compare float"}
- java_bytecodes[0x97]={operation="dcmpl", description="Compare double"}
- java_bytecodes[0x98]={operation="dcmpg", description="Compare double"}
- java_bytecodes[0x99]={operation="ifeq", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if int comparison with 0 is equal"}
- java_bytecodes[0x9a]={operation="ifne", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if int comparison with 0 is not equal"}
- java_bytecodes[0x9b]={operation="iflt", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if int comparison with 0 is less"}
- java_bytecodes[0x9c]={operation="ifge", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if int comparison with 0 is greater or equal"}
- java_bytecodes[0x9d]={operation="ifgt", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if int comparison with 0 is greater"}
- java_bytecodes[0x9e]={operation="ifle", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if int comparison with 0 is less or equal"}
- java_bytecodes[0x9f]={operation="if_icmpeq", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if int comparison is equal"}
- java_bytecodes[0xa0]={operation="if_icmpne", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if int comparison is not equal"}
- java_bytecodes[0xa1]={operation="if_icmplt", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if int comparison is less"}
- java_bytecodes[0xa2]={operation="if_icmpge", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if int comparison is greater or equal"}
- java_bytecodes[0xa3]={operation="if_icmpgt", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if int comparison is greater"}
- java_bytecodes[0xa4]={operation="if_icmple", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if int comparison is less or equal"}
- java_bytecodes[0xa5]={operation="if_acmpeq", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if reference comparison is true"}
- java_bytecodes[0xa6]={operation="if_acmpne", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if reference comparison is false"}
- java_bytecodes[0xa7]={operation="goto", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch always"}
- java_bytecodes[0xa8]={operation="jsr", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Jump subroutine"}
- java_bytecodes[0xa9]={operation="ret", parameters={bytecount=1, {paramname="index", paramtype="u1"}}, description="Return from subroutine"}
- java_bytecodes[0xaa]={operation="tableswitch", parameters={bytecount=calculateTableSwitch, {paramname="padding", paramtype="pad4"}, {paramname="default", paramtype="s4"},{paramname="low", paramtype="s4"},{paramname="high", paramtype="s4"},{paramname="array",paramtype="[s4]"}}, description="Access jump table by key match and jump"}
- java_bytecodes[0xab]={operation="lookupswitch", parameters={bytecount=calculateLookupSwitch, {paramname="padding", paramtype="pad4"}, {paramname="default", paramtype="s4"},{paramname="npairs", paramtype="s4"},{paramname="array",paramtype="[s4s4]"}}, description="Access jump table by key match and jump"}
- java_bytecodes[0xac]={operation="ireturn", description="Return int from method"}
- java_bytecodes[0xad]={operation="lreturn", description="Return long from method"}
- java_bytecodes[0xae]={operation="freturn", description="Return float from method"}
- java_bytecodes[0xaf]={operation="dreturn", description="Return double from method"}
- java_bytecodes[0xb0]={operation="areturn", description="Return reference from method"}
- java_bytecodes[0xb1]={operation="return", description="Return void from method"}
- java_bytecodes[0xb2]={operation="getstatic", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Get static field from class"}
- java_bytecodes[0xb3]={operation="putstatic", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Set static field in class"}
- java_bytecodes[0xb4]={operation="getfield", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Fetch field from object"}
- java_bytecodes[0xb5]={operation="putfield", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Set field in object"}
- java_bytecodes[0xb6]={operation="invokevirtual", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Invoke instance method; dispatch based on class"}
- java_bytecodes[0xb7]={operation="invokespecial", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Invoke instance method; special handling for superclass, private, and instance initialization method invocations"}
- java_bytecodes[0xb8]={operation="invokestatic", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Invoke static method"}
- java_bytecodes[0xb9]={operation="invokeinterface", parameters={bytecount=4, {paramname="index", paramtype="u2"}, {paramname="count", paramtype="u1"}, {paramname="null", paramtype="01"}}, description="Invoke interface method"}
- java_bytecodes[0xba]={operation="invokedynamic", parameters={bytecount=4, {paramname="index", paramtype="u2"}, {paramname="null", paramtype="02"}}, description="Invoke dynamic method"}
- java_bytecodes[0xbb]={operation="new", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Create new object"}
- java_bytecodes[0xbc]={operation="newarray", parameters={bytecount=2, {paramname="atype", paramtype="u1"}}, description="Create new array"}
- java_bytecodes[0xbd]={operation="anewarray", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Create new array of reference"}
- java_bytecodes[0xbe]={operation="arraylength", description="Get length of array"}
- java_bytecodes[0xbf]={operation="athrow", description="Throw exception or error"}
- java_bytecodes[0xc0]={operation="checkcast", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Check wheter object is of given type"}
- java_bytecodes[0xc1]={operation="instanceof", parameters={bytecount=2, {paramname="index", paramtype="u2"}}, description="Determine if object is of given type"}
- java_bytecodes[0xc2]={operation="monitorenter", description="Enter monitor for object"}
- java_bytecodes[0xc3]={operation="monitorexit", description="Exit monitor for object"}
- java_bytecodes[0xc4]={operation="wide", parameters={bytecount=nil, {paramname="instruction", paramtype="wide"}}, description="Extend local variable index by additional bytes"}
- java_bytecodes[0xc5]={operation="multianewarray", parameters={bytecount=3, {paramname="index", paramtype="u2"}, {paramname="dimensions", paramtype="u1"}}, description="Create new multidimensional array"}
- java_bytecodes[0xc6]={operation="ifnull", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if reference is null"}
- java_bytecodes[0xc7]={operation="ifnonnull", parameters={bytecount=2, {paramname="branchoffset", paramtype="s2"}}, description="Branch if reference is not null"}
- java_bytecodes[0xc8]={operation="goto_w", parameters={bytecount=4, {paramname="branchoffset", paramtype="s4"}}, description="Branch always(wide)"}
- java_bytecodes[0xc9]={operation="jsr_w", parameters={bytecount=4, {paramname="branchoffset", paramtype="s4"}}, description="Jump subroutine(wide)"}
- java_operations={}
- function java_buildoptobytecodetable()
- --parse through java_bytecodes and fill in java_operations
- for x,y in pairs(java_bytecodes) do
- java_operations[y.operation]=java_bytecodes[x]
- java_operations[y.operation].byte=x
- end
- end
- function bytecodeDisassembler(bytes)
- --note: Bytes start at index 1. Some instructions like values on an alignment of 4 byte, so keep in mind that that is (address-1) % 4
- local i,j
- result={}
- result.labels={}
- local byteindex=1
- local index=1
- while byteindex<=#bytes do
- local startindex=byteindex
- local wide=false
- if bytes[byteindex]==0xc4 then --wide
- wide=true
- byteindex=byteindex+1
- end
- local data=java_bytecodes[bytes[byteindex]]
- result[index]={}
- result[index].data=data
- result[index].operation=data.operation
- result[index].parameter=''
- result[index].byteindex=startindex-1
- local parameters=data.parameters
- if wide then
- parameters=data.wideparameters
- end
- if parameters~=nil then
- for i=1,#parameters do
- if parameters[i].paramtype=='s1' then
- result[index].parameter=result[index].parameter..signExtendByte(bytes[byteindex+1])..' '
- elseif parameters[i].paramtype=='s2' then
- result[index].parameter=result[index].parameter..signExtendWord(byteTableToWord({bytes[byteindex+2], bytes[byteindex+1]}))..' '
- elseif parameters[i].paramtype=='s4' then
- result[index].parameter=result[index].parameter..signExtendWord(byteTableToDword({bytes[byteindex+4], bytes[byteindex+3], bytes[byteindex+2], bytes[byteindex+1]}))..' '
- elseif parameters[i].paramtype=='u1' then
- result[index].parameter=result[index].parameter..bytes[byteindex+1]..' '
- elseif parameters[i].paramtype=='u2' then
- result[index].parameter=result[index].parameter..byteTableToWord({bytes[byteindex+2], bytes[byteindex+1]})..' '
- elseif parameters[i].paramtype=='u4' then
- result[index].parameter=result[index].parameter..byteTableToDword({bytes[byteindex+4], bytes[byteindex+3], bytes[byteindex+2], bytes[byteindex+1]})..' '
- end
- if (i==1) and (parameters[i].paramname=="branchoffset") then
- local destination=tonumber(result[index].byteindex+result[index].parameter)
- local label=nil
- for j=1, #result.labels do
- --check if it's already defined
- if result.labels[j].destination==destination then
- label=result.labels[j]
- break
- end
- end
- if label==nil then
- --new label, define it
- label={}
- label.destination=destination
- label.labelname='lbl'..(#result.labels+1)
- label.origins={}
- table.insert(result.labels, label)
- end
- result[index].parameter='lbl'..#result.labels
- table.insert(label.origins, startindex)
- end
- end
- end
- if parameters==nil then
- result[index].bytesize=1
- else
- if type(parameters.bytecount)=='function' then
- result[index].bytesize=1+parameters.bytecount(byteindex, bytes)
- else
- result[index].bytesize=1+parameters.bytecount
- end
- end
- --copy the bytes
- result[index].bytes={}
- for j=startindex, startindex+result[index].bytesize-1 do
- result[index].bytes[1+(j-startindex)]=bytes[j]
- end
- byteindex=byteindex+result[index].bytesize
- index=index+1
- end
- return result
- end
- function singleLineBytecodeAssembler(address, instruction, labels, updatelabels)
- local result=nil
- local operation
- local parameterstring
- local userparameters={}
- local wide=false
- local i,j,s
- s=0
- i=0
- for s in string.gmatch(instruction, "%S+") do
- if i==0 then
- if s~='wide' then
- operation=s
- i=i+1
- else
- wide=true
- end
- else
- userparameters[i]=s
- i=i+1
- end
- end
- parameterstring=''
- for i=1, #userparameters do
- parameterstring=parameterstring..userparameters[i]..' '
- end
- local data=java_operations[operation]
- if data~=nil then
- if type(data.bytecount)=='function' then
- error(data.operation..' is currently not implemented')
- end
- result={}
- result.bytes={}
- result.data=data
- result.operation=data.operation
- result.byteindex=address
- result.parameters=userparams
- result.parameter=parameterstring
- local parameters
- if wide then
- parameters=data.wideparameters
- if parameters==nil then
- error('wide can not be used with '..data.operation)
- end
- table.insert(result, 0xc4)
- else
- parameters=data.parameters
- end
- table.insert(result.bytes, data.byte)
- if parameters~=nil then
- if #userparameters~=#parameters then
- error('Invalid amount of parameters provided for '..data.operation)
- end
- for i=1, #parameters do
- local bytes={}
- if (i==1) and (parameters[i].paramname=="branchoffset") then --this instruction has a label reference
- --convert the parameter to the current label
- local label=nil
- if labels~=nil then
- for j=1, #labels do
- if labels[j].labelname==result.parameters[i] then
- label=labels[j]
- result.parameters[i]=labels[j].destination-address
- end
- end
- end
- if tonumber(result.parameters[i])==nil then
- error("The label "..userparameters[i].."is not yet defined")
- end
- if (updatelabels~=nil) and (updatelabels==true) then
- if label==nil then --add it
- label={}
- label.destination=result.parameters[i]
- label.labelname='lbl'..(#labels+1)
- label.origins={}
- table.insert(labels, label)
- end
- table.insert(label.origins, address)
- end
- end
- if parameters[i].paramtype=='s1' then
- bytes={tonumber(userparameters[i]) % 256}
- elseif parameters[i].paramtype=='s2' then
- bytes=wordToByteTable(tonumber(userparameters[i]) % 65536)
- elseif parameters[i].paramtype=='s4' then
- bytes=dwordToByteTable(tonumber(userparameters[i]) % 65536)
- elseif parameters[i].paramtype=='u1' then
- bytes={tonumber(userparameters[i]) % 256}
- elseif parameters[i].paramtype=='u2' then
- bytes=wordToByteTable(tonumber(userparameters[i]) % 65536)
- elseif parameters[i].paramtype=='u4' then
- bytes=dwordToByteTable(tonumber(userparameters[i]) % 65536)
- else
- error('This instruction is currently not implemented')
- end
- for j=1, #bytes do
- table.insert(result.bytes, bytes[j])
- end
- end
- end
- result.bytesize=#result.bytes
- else
- error('unknown instruction:'..operation);
- end
- return result
- end
- function javaclass_applyAssembleCommand(class, method, byteindex, instruction, insert)
- local codeattribute=javaclass_method_findCodeAttribute(method)
- local labels=codeattribute.code.labels
- local exceptions=codeattribute.exception_table
- --get the size of the instruction to be assembled (plus side: unlike intel with it's horrible and easily reachable 128 byte limit for small branches, java gives 32768 bytes, so less chance of an insertion causing problems)
- local newcode
- local codeattribute_codeIndex=nil
- newcode=singleLineBytecodeAssembler(byteindex, instruction, labels,false) --get the size, but don't mess with the labels
- local i,j
- local startindex=byteindex
- local offset=0
- --update the labels and exception table based on the size
- startindex=byteindex
- if insert then
- offset=newcode.bytesize
- else
- local oldcode=nil
- for i=1, #codeattribute.code do
- if codeattribute.code[i].byteindex==byteindex then
- oldcode=codeattribute.code[i]
- break
- end
- end
- if oldcode==nil then
- error('You can only replace instructions on an instruction boundary')
- end
- offset=newcode.bytesize-oldcode.bytesize
- end
- javaclass_updateOffsets(class, method, startindex, offset)
- --labels and other byteindex are updated. Now you can insert/modify the instruction
- newcode=singleLineBytecodeAssembler(byteindex, instruction, labels,true)
- local currentbyteindex=0
- for i=1, #codeattribute.code do
- if insert then
- --the byteindex has already been updated
- if currentbyteindex==byteindex then
- table.insert(codeattribute.code, i, newcode)
- break
- end
- else
- if currentbyteindex==byteindex then
- codeattribute.code[i]=newcode
- break
- end
- end
- currentbyteindex=currentbyteindex+codeattribute.code[i].bytesize
- end
- end
- function javaclass_updateOffsets(class, method, startindex, offset)
- print("si="..startindex.." offset="..offset)
- local i,j
- local codeattribute=javaclass_method_findCodeAttribute(method)
- local code=codeattribute.code
- local labels=codeattribute.code.labels
- local exceptions=codeattribute.exception_table
- for i=1, #labels do
- if labels[i].destination>=startindex then --the destination has been updated
- labels[i].destination=labels[i].destination+offset
- end
- for j=1, #labels[i].origins do
- local originaladdress=labels[i].origins[j]
- if originaladdress>=startindex then --this got shifted as well
- labels[i].origins[j]=originaladdress+offset
- end
- --adjust this branch instruction (note though, if originaddress was bigger than destination address, there should be no branchoffset change)
- --find the instruction in the code
- local k
- for k=1, #codeattribute.code do
- if codeattribute.code[k].byteindex==originaladdress then --check the original address (the byteindex hasn't been updated)
- local size=codeattribute.code[k].dataparameters[1].paramtype:sub(2,2) --branches only have type s2 or s4
- local newbranchoffset=labels[i].destination-labels[i].origins[j]
- local newbytes
- if size=='2' then --remember, it's big endian
- newbytes=wordToByteTable(newbranchoffset)
- codeattribute.code[k].bytes[2]=newbytes[2]
- codeattribute.code[k].bytes[3]=newbytes[1]
- elseif size=='4' then
- newbytes=dwordToByteTable(newbranchoffset)
- codeattribute.code[k].bytes[2]=newbytes[4]
- codeattribute.code[k].bytes[3]=newbytes[3]
- codeattribute.code[k].bytes[4]=newbytes[2]
- codeattribute.code[k].bytes[5]=newbytes[1]
- end
- end
- end
- end
- end
- --update tableswitch and lookupswitch commands
- for i=1,#code do
- if code[i].data.byte==0xaa then
- --tableswitch
- local defaultbyteindex=code[i].byteindex+1
- local defaultindex=2
- --find alignment padding
- local rest=defaultbyteindex%4
- if rest>0 then
- defaultindex=defaultindex+(4-rest)
- defaultbyteindex=defaultbyteindex+(4-rest)
- end
- local lowindex=defaultindex+4
- local highindex=lowindex+4
- local offsetindex=highindex+4
- local low=byteTableToDword({code[i].bytes[lowindex+3], code[i].bytes[lowindex+2], code[i].bytes[lowindex+1], code[i].bytes[lowindex]}) --big endian
- local high=byteTableToDword({code[i].bytes[highindex+3], code[i].bytes[highindex+2], code[i].bytes[highindex+1], code[i].bytes[highindex]})
- local count=high-low+1
- for j=1,count do
- local currentoffsetindex=offsetindex+(i-1)*4
- local currentoffset=byteTableToDword({code[i].bytes[currentoffsetindex+3], code[i].bytes[currentoffsetindex+2], code[i].bytes[currentoffsetindex+1], code[i].bytes[currentoffsetindex]})
- if currentoffset>=startindex then
- --update the address it points to
- currentoffset=currentoffset+offset
- local newbytes=dwordToByteTable(currentoffset)
- code.bytes[currentoffsetindex]=newbytes[4]
- code.bytes[currentoffsetindex+1]=newbytes[3]
- code.bytes[currentoffsetindex+2]=newbytes[2]
- code.bytes[currentoffsetindex+3]=newbytes[1]
- end
- end
- elseif code[i].data.byte==0xab then
- --lookupswitch
- local defaultbyteindex=code[i].byteindex+1
- local defaultindex=2
- --find alignment padding
- local rest=defaultbyteindex%4
- if rest>0 then
- defaultindex=defaultindex+(4-rest)
- defaultbyteindex=defaultbyteindex+(4-rest)
- end
- local countindex=defaultindex+4
- local count=byteTableToDword({code[i].bytes[countindex+3], code[i].bytes[countindex+2], code[i].bytes[countindex+1], code[i].bytes[countindex]})
- for j=1,count do
- local currentoffsetindex=countindex+(j-1)*8+4
- local currentoffset=byteTableToDword({code[i].bytes[currentoffsetindex+3], code[i].bytes[currentoffsetindex+2], code[i].bytes[currentoffsetindex+1], code[i].bytes[currentoffsetindex]})
- if currentoffset>=startindex then
- --update the address it points to
- currentoffset=currentoffset+offset
- local newbytes=dwordToByteTable(currentoffset)
- code.bytes[currentoffsetindex]=newbytes[4]
- code.bytes[currentoffsetindex+1]=newbytes[3]
- code.bytes[currentoffsetindex+2]=newbytes[2]
- code.bytes[currentoffsetindex+3]=newbytes[1]
- end
- end
- end
- end
- --update the exception table
- for i=1, #exceptions do
- if exceptions[i].start_pc>=startindex then
- exceptions[i].start_pc=exceptions[i].start_pc+offset
- end
- if exceptions[i].start_pc>=startindex then
- exceptions[i].end_pc=exceptions[i].end_pc+offset
- end
- if exceptions[i].start_pc>=startindex then
- exceptions[i].handler_pc=exceptions[i].handler_pc+offset
- end
- end
- --finally update the byteindexes
- for i=1, #codeattribute.code do
- if codeattribute.code[i].byteindex>=startindex then
- codeattribute.code[i].byteindex=codeattribute.code[i].byteindex+offset
- end
- end
- end
- function javaclasseditor_editMethod_fillInstructionsListview(lv, method)
- local i
- local codeattribute=javaclass_method_findCodeAttribute(method)
- local code=codeattribute.code
- local labels=code.labels
- local exceptions=codeattribute.exception_table
- local haslabels=false
- local hasexceptions=false
- lv.Items.clear()
- for i=1, #code do
- local j
- local item=lv.Items.add()
- local bytestring=''
- item.Caption=i-1
- for j=1, code[i].bytesize do
- bytestring=bytestring..string.format("%.2x ", code[i].bytes[j])
- end
- item.SubItems.Add(code[i].byteindex .. ':'..bytestring) --display as 0 start
- local labelname=''
- if #labels>0 then
- haslabels=true
- for j=1, #labels do
- if code[i].byteindex==labels[j].destination then
- labelname='lbl'..j
- break
- end
- end
- end
- local exceptionstr=''
- if #exceptions>0 then
- hasexceptions=true
- for j=1, #exceptions do
- if code[i].byteindex==exceptions[j].start_pc then
- exceptionstr=exceptionstr..'start'..j..' '
- end
- if code[i].byteindex==exceptions[j].end_pc then
- exceptionstr=exceptionstr..'end'..j..' '
- end
- if code[i].byteindex==exceptions[j].handler_pc then
- exceptionstr=exceptionstr..'handler'..j..' '
- end
- end
- end
- item.SubItems.Add(labelname)
- item.SubItems.Add(exceptionstr)
- item.SubItems.Add(code[i].operation..' '..code[i].parameter)
- end
- end
- function javaclasseditor_editMethod_insertLine(sender)
- local classMethod=getRef(sender.Tag)
- local codeattribute=javaclass_method_findCodeAttribute(classMethod.method)
- local code=codeattribute.code
- local lv=classMethod.method.editor.lvInstructions
- local linenr
- if lv.Selected==nil then
- linenr=0
- else
- linenr=lv.Selected.Index
- end
- local byteindex=code[linenr+1].byteindex
- local line=inputQuery('Insert line', 'Input the java assembly code you wish to insert at line '..linenr..'(byteindex '..byteindex..')','')
- if line~=nil then
- --showMessage('Assembling '..line)
- --assemble
- javaclass_applyAssembleCommand(classMethod.class, classMethod.method, byteindex, line, true)
- --show update
- javaclasseditor_editMethod_fillInstructionsListview(classMethod.method.editor.lvInstructions, classMethod.method)
- end
- end
- function javaclasseditor_editMethod_editLine(sender)
- local classMethod=getRef(sender.Tag)
- local codeattribute=javaclass_method_findCodeAttribute(classMethod.method)
- local code=codeattribute.code
- local lv=classMethod.method.editor.lvInstructions
- local linenr
- if lv.Selected==nil then
- return
- else
- linenr=lv.Selected.Index
- end
- local byteindex=code[linenr+1].byteindex
- local originalcode=code[linenr+1].operation..' '..code[linenr+1].parameter
- local line=inputQuery('Edit line', 'Input the java assembly code you wish to insert at line '..linenr..'(byteindex '..byteindex..')',originalcode)
- if line~=nil then
- javaclass_applyAssembleCommand(classMethod.class, classMethod.method, byteindex, line, false)
- --show update
- javaclasseditor_editMethod_fillInstructionsListview(classMethod.method.editor.lvInstructions, classMethod.method)
- end
- end
- function javaclasseditor_editMethod_defineLabel(sender)
- local classMethod=getRef(sender.Tag)
- local codeattribute=javaclass_method_findCodeAttribute(classMethod.method)
- local code=codeattribute.code
- local labels=code.labels
- local lv=classMethod.method.editor.lvInstructions
- local linenr
- if lv.Selected==nil then
- return
- else
- linenr=lv.Selected.Index
- end
- local byteindex=code[linenr+1].byteindex
- local labelname=inputQuery('Define new label', 'Give a labelname for line '..linenr..'(byteindex '..byteindex..')','')
- if (labelname~=nil) and (labelname~='') then
- local i
- --check if it already exists
- for i=1,#labels do
- if labels[i].labelname==labelname then
- error('There is already a label with this name')
- end
- end
- --still here, so the it wasn't in the list
- local newlabel={}
- newlabel.labelname=labelname
- newlabel.destination=byteindex
- newlabel.origins={}
- table.insert(labels, newlabel)
- end
- end
- function javaclasseditor_editMethod_applyUpdates(method)
- --converts the bytes of the interpreted code into the .info field of the code attribute (used by the writer)
- local i
- local codeattribute=javaclass_method_findCodeAttribute(method)
- local code=codeattribute.code
- codeattribute.max_stack=tonumber(method.editor.edtMaxStack.Text)
- codeattribute.max_locals=tonumber(method.editor.edtMaxLocals.Text)
- ca=codeattribute
- local s={} --write stream
- s.data=''
- s.index=0 --not really needed by writes but helps with debugging
- java_write_u2(s, codeattribute.max_stack)
- java_write_u2(s, codeattribute.max_locals)
- local bytesize=0
- for i=1,#code do
- bytesize=bytesize+#code[i].bytes
- end
- java_write_u4(s, bytesize) --code_length
- for i=1,#code do
- local j
- for j=1,#code[i].bytes do
- s.data=s.data..string.char(code[i].bytes[j])
- end
- end
- s.index=s.index+#code
- --exception table (genius to allow code size to be specified by 4 bytes but not exception addresses)
- java_write_u2(s, codeattribute.exception_table_length);
- for i=1, codeattribute.exception_table_length do
- java_write_u2(s, codeattribute.exception_table[i].start_pc)
- java_write_u2(s, codeattribute.exception_table[i].end_pc)
- java_write_u2(s, codeattribute.exception_table[i].handler_pc)
- java_write_u2(s, codeattribute.exception_table[i].catch_type)
- end
- java_write_u2(s, codeattribute.attributes_count)
- java_writeAttributes(s, codeattribute.attributes, codeattribute.attributes_count)
- print(string.format("old bsize=%d new bsize=%d", codeattribute.code_length, bytesize))
- print(string.format("old size=%d new size=%d", #codeattribute.info, #s.data))
- codeattribute.info=s.data
- codeattribute.attribute_length=#codeattribute.info
- end
- function btnApplyChangesClick(sender)
- --apply the changes
- local classMethod=getRef(sender.Tag)
- local method=classMethod.method
- javaclasseditor_editMethod_applyUpdates(method)
- if method.editor.callbackfunction~=nil then
- method.editor.callbackfunction(classMethod.class, method.editor.callbackparam)
- end
- end
- function javaclasseditor_editMethod(class, method, callbackfunction, callbackparam)
- --create a gui for this method
- --note that throughout this file we call the parsed class "class". It's not the jclass object
- if method.editor==nil then
- local ca=javaclass_method_findCodeAttribute(method)
- local classMethodRef=createRef({class=class, method=method})
- --build a gui
- method.editor={}
- method.editor.form=createForm()
- method.editor.form.onClose=nil --do not destroy on close
- method.editor.form.tag=classMethodRef --this way gui launched functions can find the base form and fetch this data if it needs it
- method.editor.form.borderstyle=bsSizeable
- method.editor.form.width=640
- method.editor.form.height=480
- method.editor.form.caption="Method: "..class.constant_pool[class.constant_pool[class.this_class].name_index].utf8.."."..class.constant_pool[method.name_index].utf8
- method.editor.form.Position=poScreenCenter
- method.editor.lblMaxStack=createLabel(method.editor.form)
- method.editor.lblMaxLocals=createLabel(method.editor.form)
- method.editor.lblMaxStack.caption="Max Stack"
- method.editor.lblMaxLocals.caption="Max Locals"
- method.editor.edtMaxStack=createEdit(method.editor.form)
- method.editor.edtMaxLocals=createEdit(method.editor.form)
- method.editor.edtMaxStack.Text=ca.max_stack
- method.editor.edtMaxLocals.Text=ca.max_locals
- method.editor.lblMaxStack.AnchorSideLeft.Control=method.editor.form
- method.editor.lblMaxStack.AnchorSideLeft.Side=asrLeft
- method.editor.lblMaxStack.AnchorSideTop.Control=method.editor.form
- method.editor.lblMaxStack.AnchorSideTop.Side=asrTop
- method.editor.lblMaxStack.Anchors="[akTop, akLeft]"
- method.editor.edtMaxStack.AnchorSideLeft.Control=method.editor.form
- method.editor.edtMaxStack.AnchorSideLeft.Side=asrLeft
- method.editor.edtMaxStack.AnchorSideTop.Control=method.editor.lblMaxStack
- method.editor.edtMaxStack.AnchorSideTop.Side=asrBottom
- method.editor.edtMaxStack.Anchors="[akTop, akLeft]"
- method.editor.lblMaxLocals.AnchorSideLeft.Control=method.editor.edtMaxStack
- method.editor.lblMaxLocals.AnchorSideLeft.Side=asrRight
- method.editor.lblMaxLocals.AnchorSideTop.Control=method.editor.form
- method.editor.lblMaxLocals.AnchorSideTop.Side=asrTop
- method.editor.lblMaxLocals.BorderSpacing.Left=6
- method.editor.lblMaxLocals.Anchors="[akTop, akLeft]"
- method.editor.edtMaxLocals.AnchorSideLeft.Control=method.editor.lblMaxLocals
- method.editor.edtMaxLocals.AnchorSideLeft.Side=asrLeft
- method.editor.edtMaxLocals.AnchorSideTop.Control=method.editor.edtMaxStack
- method.editor.edtMaxLocals.AnchorSideTop.Side=asrTop
- method.editor.edtMaxLocals.Anchors="[akTop, akLeft]"
- method.editor.btnApplyChanges=createButton(method.editor.form)
- method.editor.btnApplyChanges.AutoSize=true
- method.editor.btnApplyChanges.Caption="Save changes"
- method.editor.btnApplyChanges.OnClick=btnApplyChangesClick
- method.editor.btnApplyChanges.Tag=classMethodRef
- method.editor.btnApplyChanges.AnchorSideLeft.Control=method.editor.edtMaxLocals
- method.editor.btnApplyChanges.AnchorSideLeft.Side=asrRight
- method.editor.btnApplyChanges.AnchorSideTop.Control=method.editor.edtMaxLocals
- method.editor.btnApplyChanges.AnchorSideTop.Side=asrTop
- method.editor.lblMaxLocals.BorderSpacing.Left=12
- method.editor.btnApplyChanges.Anchors="[akTop, akLeft]"
- method.editor.lvInstructions=createListView(method.editor.form)
- method.editor.lvInstructions.Name="lvInstructions"
- local columns=method.editor.lvInstructions.Columns
- local lcIndex=columns.add()
- local lcByteIndex=columns.add()
- local lcLabel=columns.add()
- local lcException=columns.add()
- local lcInstruction=columns.add()
- lcIndex.Caption="Index"
- lcByteIndex.Caption="ByteIndex"
- lcLabel.Caption="Label"
- lcException.Caption="Exception"
- lcInstruction.Caption="Instruction"
- lcByteIndex.width=100
- lcInstruction.AutoSize=true
- method.editor.lvInstructions.AutoWidthLastColumn=true
- method.editor.lvInstructions.RowSelect=true
- method.editor.lvInstructions.HideSelection=false
- method.editor.lvInstructions.ReadOnly=true
- method.editor.lvInstructions.AnchorSideLeft.Control=method.editor.form
- method.editor.lvInstructions.AnchorSideLeft.Side=asrLeft
- method.editor.lvInstructions.AnchorSideTop.Control=method.editor.edtMaxStack
- method.editor.lvInstructions.AnchorSideTop.Side=asrBottom
- method.editor.lvInstructions.BorderSpacing.Top=6
- method.editor.lvInstructions.AnchorSideRight.Control=method.editor.form
- method.editor.lvInstructions.AnchorSideRight.Side=asrRight
- method.editor.lvInstructions.AnchorSideBottom.Control=method.editor.form
- method.editor.lvInstructions.AnchorSideBottom.Side=asrBottom
- method.editor.lvInstructions.Anchors="[akTop, akLeft, akRight, akBottom]"
- --create a popupmenu for adding/editing lines, and adding new labels
- method.editor.pmEdit=createPopupMenu(method.editor.form)
- method.editor.pmEdit.Tag=classMethodRef
- local miInsertLine=createMenuItem(method.editor.pmEdit)
- miInsertLine.caption="Insert line"
- miInsertLine.onClick=javaclasseditor_editMethod_insertLine
- miInsertLine.Shortcut="Ctrl+I"
- miInsertLine.Tag=classMethodRef
- local miEditLine=createMenuItem(method.editor.pmEdit)
- miEditLine.caption="Edit line"
- miEditLine.onClick=javaclasseditor_editMethod_editLine
- miEditLine.Shortcut="Ctrl+E"
- miEditLine.Tag=classMethodRef
- local miDefineLine=createMenuItem(method.editor.pmEdit)
- miDefineLine.caption="Define label"
- miDefineLine.onClick=javaclasseditor_editMethod_defineLabel
- miDefineLine.Shortcut="Ctrl+L"
- miDefineLine.Tag=classMethodRef
- method.editor.lvInstructions.OnDblClick=javaclasseditor_editMethod_editLine
- method.editor.lvInstructions.Tag=classMethodRef
- method.editor.pmEdit.Items.add(miInsertLine)
- method.editor.pmEdit.Items.add(miEditLine)
- method.editor.pmEdit.Items.add(miDefineLine)
- method.editor.lvInstructions.PopupMenu=method.editor.pmEdit
- method.editor.callbackfunction=callbackfunction
- method.editor.callbackparam=callbackparam
- end
- javaclasseditor_editMethod_fillInstructionsListview(method.editor.lvInstructions, method)
- method.editor.form.show()
- end
- java_buildoptobytecodetable()
|