diff options
| author | Drahflow <drahflow@gmx.de> | 2013-09-24 10:40:37 +0200 |
|---|---|---|
| committer | Drahflow <drahflow@gmx.de> | 2013-09-24 10:40:37 +0200 |
| commit | c2182784d2237b15dddebec66473a5726faa07a4 (patch) | |
| tree | 02943cc1fb8d8886d2a0abb00e1d3769e92beb25 | |
| parent | bd4fe14e2a77ceac5c8c234de05c514fdd6d7bf4 (diff) | |
Saner patching of static loads
| -rw-r--r-- | compiler/elymasAsm.ey | 20 | ||||
| -rw-r--r-- | compiler/elymasGlobal.ey | 142 | ||||
| -rw-r--r-- | compiler/standardClient.ey | 14 | ||||
| -rw-r--r-- | elymas/lib/sys/opt.ey | 133 |
4 files changed, 165 insertions, 144 deletions
diff --git a/compiler/elymasAsm.ey b/compiler/elymasAsm.ey index fcb584a..15ed57b 100644 --- a/compiler/elymasAsm.ey +++ b/compiler/elymasAsm.ey @@ -12,16 +12,16 @@ } "%" defq # registers - < [ /rax /rcx /rdx /rbx /rsp /rbp /rsi /rdi /r8 /r9 /r10 /r11 /r12 /r13 /r14 /r15 ] { 1 -01 defv }' each > ==bit64table + < [ /rax /rcx /rdx /rbx /rsp /rbp /rsi /rdi /r8 /r9 /r10 /r11 /r12 /r13 /r14 /r15 ] { 1 -01 defv }' each > ==:bit64table { bit64table -01 . -- } /bit64assert deff - < [ /eax /ecx /edx /ebx /esp /ebp /esi /edi /r8d /r9d /r10d /r11d /r12d /r13d /r14d /r15d ] { 1 -01 defv }' each > ==bit32table + < [ /eax /ecx /edx /ebx /esp /ebp /esi /edi /r8d /r9d /r10d /r11d /r12d /r13d /r14d /r15d ] { 1 -01 defv }' each > ==:bit32table { bit32table -01 . -- } /bit32assert deff - < [ /ax /cx /dx /bx /sp /bp /si /di /r8w /r9w /r10w /r11w /r12w /r13w /r14w /r15w ] { 1 -01 defv }' each > ==bit16table + < [ /ax /cx /dx /bx /sp /bp /si /di /r8w /r9w /r10w /r11w /r12w /r13w /r14w /r15w ] { 1 -01 defv }' each > ==:bit16table { bit16table -01 . -- } /bit16assert deff - < [ /al /cl /dl /bl /spl /ah /bpl /ch /sil /dh /dil /bh /r8b /r9b /r10b /r11b /r12b /r13b /r14b /r15b ] { 1 -01 defv }' each > ==bit8table + < [ /al /cl /dl /bl /spl /ah /bpl /ch /sil /dh /dil /bh /r8b /r9b /r10b /r11b /r12b /r13b /r14b /r15b ] { 1 -01 defv }' each > ==:bit8table { bit8table -01 . -- } /bit8assert deff < @@ -41,7 +41,7 @@ [ /r13b /r13w /r13d /r13 ] { 13 -01 defv }' each [ /r14b /r14w /r14d /r14 ] { 14 -01 defv }' each [ /r15b /r15w /r15d /r15 ] { 15 -01 defv }' each - > ==regnoTable + > ==:regnoTable { regnoTable -01 . } /regno deff @@ -49,7 +49,7 @@ [ /al /cl /dl /bl ] { 0 -01 defv }' each [ /spl /bpl /sil /dil ] { 1 -01 defv }' each [ /r8b /r9b /r10b /r11b /r12b /r13b /r14b /r15b ] { 1 -01 defv }' each - > ==rexreqbyteTable + > ==:rexreqbyteTable { rexreqbyteTable -01 . } /rexreqbyte deff @@ -228,13 +228,13 @@ } /encode deff > } ==Mem # base register plus 8 bit displacement - { < _ bit64assert ==base _ 128 lt assert ==disp /none ==idx { ==r + { < _ bit64assert ==base /none ==idx _ 128 lt assert ==disp { ==r r base modrm01 disp imm8 } /encode deff > } ==MemDisp8 # base register plus 32 bit displacement - { < _ bit64assert ==base ==disp /none ==idx { ==r + { < _ bit64assert ==base /none ==idx ==disp { ==r r base modrm10 disp imm32 } /encode deff > @@ -1196,10 +1196,10 @@ }' each STACKSIZE sys .asm .alloc _ globalAllocations .register - .base ==quoteEncodingBufferCode + .base ==:quoteEncodingBufferCode STACKSIZE sys .asm .alloc _ globalAllocations .register - .base ==quoteEncodingBufferObjects + .base ==:quoteEncodingBufferObjects { ==opcodes opcodes len 1 sub PAGESIZE div 1 add PAGESIZE mul sys .asm .alloc /codearea defv diff --git a/compiler/elymasGlobal.ey b/compiler/elymasGlobal.ey index 1820725..1b36b1b 100644 --- a/compiler/elymasGlobal.ey +++ b/compiler/elymasGlobal.ey @@ -1079,7 +1079,7 @@ %40 /dl :testbImmReg /patchConstant :jnzLbl8 - %10 /dl :testbImmReg + %30 /dl :testbImmReg # TODO separate cases for static and typed /patchStatic :jnzLbl32 /rdx /rcx :movqRegReg @@ -1102,11 +1102,11 @@ /rax :callqReg :ud2 - @active + @active # TODO patch late resolve call away |ey* /rax :movqImmReg /rax :callqReg - @inactive + @inactive # TODO patch late resolve call away @done 16 /r15 :addqImm8Reg @@ -1301,18 +1301,38 @@ :ud2 @patchStaticPassive + 0 /rax :movqImmReg + /rax :pushqReg + /patchStaticImplementation :jmpLbl8 + + @patchStaticActive + 1 /rax :movqImmReg + /rax :pushqReg + + @patchStaticImplementation + /rdi /rcx :movqRegReg # save parent pointer count # FIXME: keep enough place for repeated parent dereference when creating the to-be-patched-code 15 /rcx :cmpqImm8Reg - /patchStaticPassiveParentCountWithinLimits :jbeLbl8 + /patchStaticParentCountWithinLimits :jbeLbl8 "parent count out of save limits in internalExecuteIdentifierUnquotedAndPatchLateResolve" ::outputError :ud2 - @patchStaticPassiveParentCountWithinLimits + @patchStaticParentCountWithinLimits 8 /r15 /rdi :movqMemDisp8Reg - # TODO: could reset string reference here + # replace string reference with example object (for later optimizer inspection) + 8 /rdi /rdx :movqMemDisp8Reg + 16 1 /rdx /rdi /rdx :leaqMemIndexScaleDisp8Reg + /rdi /eax :movlMemReg + /rdi /rax :addqRegReg + /rdx /rax :cmpqRegReg + /patchStaticParentCountWithinLimitsSpaceExists :jaLbl8 + "no space available for example object" ::outputError + :ud2 + @patchStaticParentCountWithinLimitsSpaceExists + 0 /rdx :andqImm8Mem # reset example object pointer 16 /rdi :addqImm8Reg [ @@ -1321,125 +1341,67 @@ ] ::loadToRdi /rcx /rcx :testqRegReg - /patchStaticPassiveNoFollowParents :jzLbl8 - @patchStaticPassiveFollowParents + /patchStaticNoFollowParents :jzLbl8 + @patchStaticFollowParents [ 16 /rax /rax :movqMemDisp8Reg ] ::loadToRdi - /patchStaticPassiveFollowParents :loopLbl8 - @patchStaticPassiveNoFollowParents + /patchStaticFollowParents :loopLbl8 + @patchStaticNoFollowParents %01 /bpl :testbImmReg - /patchStaticPassiveLoadFromExtensionArea :jnzLbl8 + /patchStaticLoadFromExtensionArea :jnzLbl8 - # @patchStaticPassiveLoadFromScope + # @patchStaticLoadFromScope 32 /rsi :addqImm8Reg # now: rsi == offset of entry in scope [ /rbx :popqReg - %EE /rax :pushqMemDisp32 - /rbx :jmpqReg + %EE /rax /rax :movqMemDisp32Reg ] ::loadToRdi - 6 /rdi :subqImm8Reg - /esi /rdi :movlRegMem # patch offset - - 8 /r15 /rdi :movqMemDisp8Reg - 16 /rdi :addqImm8Reg - - 16 /r15 :addqImm8Reg - /r15 :pushqMem - 8 /r15 :addqImm8Reg - /rdi :jmpqReg # continue with freshly patched code + /esi 4 neg /rdi :movlRegMemDisp8 # patch offset + /patchStaticLoadTail :jmpLbl8 - @patchStaticPassiveLoadFromExtensionArea + @patchStaticLoadFromExtensionArea 40 /rsi :addqImm8Reg # now: rsi == offset of entry in extension area + scope length - [ 24 /rax /rcx :movqMemDisp8Reg # load extension area pointer /rax /edx :movlMemReg # load scope length /rdx :negqReg # prepare for substraction /rbx :popqReg - %EE 1 /rdx /rcx :pushqMemIndexScaleDisp32 # push loaded entry to stack - /rbx :jmpqReg + %EE 1 /rdx /rcx /rax :movqMemIndexScaleDisp32Reg # load entry ] ::loadToRdi - 6 /rdi :subqImm8Reg - /esi /rdi :movlRegMem # patch offset - - 8 /r15 /rdi :movqMemDisp8Reg - 16 /rdi :addqImm8Reg - - 16 /r15 :addqImm8Reg - /r15 :pushqMem - 8 /r15 :addqImm8Reg - /rdi :jmpqReg # continue with freshly patched code - - @patchStaticActive - /rdi /rcx :movqRegReg # save parent pointer count - # FIXME: keep enough place for repeated parent dereference when creating the to-be-patched-code - - 15 /rcx :cmpqImm8Reg - /patchStaticActiveParentCountWithinLimits :jbeLbl8 - - "parent count out of save limits in internalExecuteIdentifierUnquotedAndPatchLateResolve" ::outputError - :ud2 - - @patchStaticActiveParentCountWithinLimits - 8 /r15 /rdi :movqMemDisp8Reg - # TODO: could reset string reference here - 16 /rdi :addqImm8Reg + /esi 4 neg /rdi :movlRegMemDisp8 # patch offset + @patchStaticLoadTail [ - ::currentScope /rax :movqImmReg - /rax /rax :movqMemReg + /rax :pushqReg + /rcx :movqImmOOBReg ] ::loadToRdi - - /rcx /rcx :testqRegReg - /patchStaticActiveNoFollowParents :jzLbl8 - @patchStaticActiveFollowParents + /rdx /rdi :movqRegMem + 8 /rdi :addqImm8Reg [ - 16 /rax /rax :movqMemDisp8Reg + /rax /rcx :movqRegMem ] ::loadToRdi - /patchStaticActiveFollowParents :loopLbl8 - @patchStaticActiveNoFollowParents - %01 /bpl :testbImmReg - /patchStaticActiveLoadFromExtensionArea :jnzLbl8 + /rax :popqReg + /rax /rax :testqRegReg + /patchStaticLoadActive :jnzLbl8 - # @patchStaticActiveLoadFromScope - 32 /rsi :addqImm8Reg # now: rsi == offset of entry in scope + # @patchStaticLoadPassive [ - /rbx :popqReg - %EE /rax :pushqMemDisp32 - /rbx :pushqReg - |ey* /rax :movqImmReg - /rax :jmpqReg + /rbx :jmpqReg ] ::loadToRdi - 17 /rdi :subqImm8Reg - /esi /rdi :movlRegMem # patch offset - - 8 /r15 /rdi :movqMemDisp8Reg - 16 /rdi :addqImm8Reg - - 16 /r15 :addqImm8Reg - /r15 :pushqMem - 8 /r15 :addqImm8Reg - /rdi :jmpqReg # continue with freshly patched code - @patchStaticActiveLoadFromExtensionArea - 40 /rsi :addqImm8Reg # now: rsi == offset of entry in extension area + scope length + /patchStaticLoadTail2 :jmpLbl8 + @patchStaticLoadActive [ - 24 /rax /rcx :movqMemDisp8Reg # load extension area pointer - /rax /edx :movlMemReg # load scope length - /rdx :negqReg # prepare for substraction - /rbx :popqReg - %EE 1 /rdx /rcx :pushqMemIndexScaleDisp32 # push loaded entry to stack /rbx :pushqReg |ey* /rax :movqImmReg /rax :jmpqReg ] ::loadToRdi - 17 /rdi :subqImm8Reg - /esi /rdi :movlRegMem # patch offset + @patchStaticLoadTail2 8 /r15 /rdi :movqMemDisp8Reg 16 /rdi :addqImm8Reg diff --git a/compiler/standardClient.ey b/compiler/standardClient.ey index 643a805..e00279f 100644 --- a/compiler/standardClient.ey +++ b/compiler/standardClient.ey @@ -220,17 +220,20 @@ }" /cloneThread deffd { #==thread ==newpc + 0 -1201 =[] + }" /updateThread deffd + + { #==thread ==newpc [ -0201 threadGetCaptures _ len dearray ] ] }" /fullCloneThread deffd |add /origadd deffd + str .|bitTest /bitTest deffd + str .|bitSet /bitSet deffd + str .|zero /zero deffd # TODO think about implementation efficiency { ==maxSize - str .|bitTest /bitTest deffd - str .|bitSet /bitSet deffd - str .|zero /zero deffd - < 0 ==size [ maxSize { 0 }" rep ] =*get @@ -281,7 +284,7 @@ clist .clear }" { # TERM position maxPosition lt { - position string * 1 code * { pc 1 add thread cloneThread nlist .add }" rep + position string * 1 code * { pc 1 add thread updateThread nlist .add }" rep }" rep }" { # JUMP pc 1 code add thread cloneThread iPush @@ -302,6 +305,7 @@ 0 ==i { position maxPosition le }" { 0 =i + { i clist .size lt }" { i clist .get _ =thread threadGetPC _ =pc diff --git a/elymas/lib/sys/opt.ey b/elymas/lib/sys/opt.ey index bd7600f..b281171 100644 --- a/elymas/lib/sys/opt.ey +++ b/elymas/lib/sys/opt.ey @@ -85,37 +85,32 @@ [ /rbx :popqReg - 0 /rax :pushqMemDisp32 - /rbx :jmpqReg - ] ==:staticLoadPassiveFromScopePattern + 0 /rax /rax :movqMemDisp32Reg + ] ==:staticLoadFromScopePattern [ 24 /rax /rcx :movqMemDisp8Reg # load extension area pointer /rax /edx :movlMemReg # load scope length /rdx :negqReg # prepare for substraction /rbx :popqReg - 0 1 /rdx /rcx :pushqMemIndexScaleDisp32 # push loaded entry to stack - /rbx :jmpqReg - ] ==:staticLoadPassiveFromExtensionPattern + 0 1 /rdx /rcx /rax :movqMemIndexScaleDisp32Reg # load entry + ] ==:staticLoadFromExtensionPattern [ - /rbx :popqReg - 0 /rax :pushqMemDisp32 - /rbx :pushqReg - 0 /rax :movqImmReg - /rax :jmpqReg - ] ==:staticLoadActiveFromScopePattern + /rax :pushqReg + 0 /rcx :movqImmReg + /rax /rcx :movqRegMem + /rbx :jmpqReg + ] ==:staticLoadPassivePattern [ - 24 /rax /rcx :movqMemDisp8Reg # load extension area pointer - /rax /edx :movlMemReg # load scope length - /rdx :negqReg # prepare for substraction - /rbx :popqReg - 0 1 /rdx /rcx :pushqMemIndexScaleDisp32 # push loaded entry to stack + /rax :pushqReg + 0 /rcx :movqImmReg + /rax /rcx :movqRegMem /rbx :pushqReg 0 /rax :movqImmReg /rax :jmpqReg - ] ==:staticLoadActiveFromExtensionPattern + ] ==:staticLoadActivePattern [ 8 /r15 :subqImm8Reg @@ -127,7 +122,9 @@ /CALL ==:CALL /CALLSCOPED ==:CALLSCOPED /STATIC ==:STATIC + /STATICTYPED ==:STATICTYPED /STATICWRITE ==:STATICWRITE + /STATICDOT ==:STATICDOT /NATIVE ==:NATIVE { =*f ==t @@ -152,7 +149,7 @@ } /testScopeModifications deffst { ==logic - [ /NOP ] ==last + [ NOP ] ==last [ logic { ==entry 0 entry * ==action [ { action CALL streq { 1 entry * "|" | +rawCodeAddress eq }' andif { 0 last * PUSH streq }' andif }' { @@ -164,7 +161,7 @@ mode 16 div 1 band { [ STATIC offsetInScope parentCount inExtensionArea ] =last - [ /NOP ] =entry + [ NOP ] =entry } { } ? * } { executingScope dump @@ -181,7 +178,7 @@ } /rewriteConstantPipe deffst { ==logic - [ /NOP ] ==last + [ NOP ] ==last [ logic { ==entry 0 entry * ==action [ { action CALL streq { 1 entry * "=" | +rawCodeAddress eq }' andif { 0 last * PUSH streq }' andif }' { @@ -193,7 +190,7 @@ mode 16 div 1 band { [ STATICWRITE offsetInScope parentCount inExtensionArea ] =last - [ /NOP ] =entry + [ NOP ] =entry } { } ? * } { executingScope dump @@ -209,8 +206,42 @@ } each last ] } /rewriteConstantEquals deffst + { _ ==logic + 2 logic len range { ==i i logic * ==entry 0 entry * ==action i 1 sub logic * ==last i 2 sub logic * ==secondLast + [ + { action CALL streq + { 1 entry * "." | +rawCodeAddress eq }' andif + { 0 last * PUSH streq }' andif + { 0 secondLast * STATICTYPED streq }' andif + }' { + 1 last * +rawObject ==constant + 4 secondLast * +rawObject ==relevantScope + + constant relevantScope sys .resolveInfo { + ==mode -- ==parentCount 32 add ==offsetInScope ==inExtensionArea + inExtensionArea { offsetInScope 8 add =offsetInScope } rep + + mode 16 div 1 band { + [ STATICDOT offsetInScope parentCount inExtensionArea ] i 1 sub logic =[] + mode 1 band { # TODO bail out for activation mode of 2 + [ CALL "*" | +rawCodeAddress ] i logic =[] + } { + [ NOP ] i logic =[] + } ? * + } { } ? * + } { + relevantScope dump + relevantScope keys dump + constant dump + "resolution failed" die + } ? * + } + ] conds + } each + } /rewriteConstantDot deffst + { ==logic - [ /NOP ] ==last + [ NOP ] ==last [ logic { ==entry 0 entry * ==action [ { action CALL streq { 1 entry * "_" | +rawCodeAddress eq }' andif }' { @@ -306,30 +337,37 @@ j ==loadStart [ - { staticLoadPassiveFromScopePattern callTargetMatch }' { - [ loadStart 3 add _ 4 add range peek each ] 256 math .unbase ==offsetInScope + { staticLoadFromScopePattern callTargetMatch }' { + [ loadStart 4 add _ 4 add range peek each ] 256 math .unbase ==offsetInScope + [ calledAddress 8 sub _ 8 add range peek each ] 256 math .unbase ==exampleObjectOffset + [ calledAddress exampleObjectOffset add _ 8 add range peek each ] 256 math .unbase ==exampleObject - [ STATIC offsetInScope parentCount 0 ] emitLogic + [ STATICTYPED offsetInScope parentCount 0 exampleObject ] emitLogic } - { staticLoadPassiveFromExtensionPattern callTargetMatch }' { - [ loadStart 13 add _ 4 add range peek each ] 256 math .unbase ==offsetInScope + { staticLoadFromExtensionPattern callTargetMatch }' { + [ loadStart 14 add _ 4 add range peek each ] 256 math .unbase ==offsetInScope + [ calledAddress 8 sub _ 8 add range peek each ] 256 math .unbase ==exampleObjectOffset + [ calledAddress exampleObjectOffset add _ 8 add range peek each ] 256 math .unbase ==exampleObject - [ STATIC offsetInScope parentCount 1 ] emitLogic + [ STATICTYPED offsetInScope parentCount 1 exampleObject ] emitLogic } - { staticLoadActiveFromScopePattern callTargetMatch }' { - [ loadStart 3 add _ 4 add range peek each ] 256 math .unbase ==offsetInScope + { 1 }' { + [ j j 16 add range peek each ] dump + o dump + j dump + "unparsed static load opcodes in sys .opt .hook (optimizing version)" die + } + ] conds - [ STATIC offsetInScope parentCount 0 ] emitLogic + [ + { staticLoadActivePattern callTargetMatch }' { [ CALL "*" | +rawCodeAddress ] emitLogic } - { staticLoadActiveFromExtensionPattern callTargetMatch }' { - [ loadStart 13 add _ 4 add range peek each ] 256 math .unbase ==offsetInScope - - [ STATIC offsetInScope parentCount 1 ] emitLogic - [ CALL "*" | +rawCodeAddress ] emitLogic + { staticLoadPassivePattern callTargetMatch }' { + # nothing to emit } { 1 }' { @@ -396,6 +434,7 @@ testScopeModifications containsScopeModifications not |rewriteConstantPipe rep containsScopeModifications not |rewriteConstantEquals rep + containsScopeModifications not |rewriteConstantDot rep rewriteStackOps { =*entry 0 entry ==action [ @@ -439,7 +478,7 @@ 2 entry emitReference } - { action STATIC streq }' { + { action [ STATIC STATICTYPED ] streq any }' { [ ::currentScope /rax :movqImmReg /rax /rax :movqMemReg @@ -448,7 +487,7 @@ 3 entry { 24 /rax /rcx :movqMemDisp8Reg # load extension area pointer /rax /edx :movlMemReg # load scope length - /rdx :negqReg # prepare for substraction + /rdx :negqReg # prepare for substraction # TODO the length calculation could be done beforehand 1 entry 1 /rdx /rcx :pushqMemIndexScaleDisp32 # push loaded entry to stack } { 1 entry /rax :pushqMemDisp32 @@ -473,6 +512,22 @@ ] emitOpcodes } + { action STATICDOT streq }' { + [ + /rax :popqReg + 2 entry { 16 /rax /rax :movqMemDisp8Reg } rep + + 3 entry { + 24 /rax /rcx :movqMemDisp8Reg # load extension area pointer + /rax /edx :movlMemReg # load scope length + /rdx :negqReg # prepare for substraction + 1 entry 1 /rdx /rcx :pushqMemIndexScaleDisp32 # push loaded entry to stack + } { + 1 entry /rax :pushqMemDisp32 + } ? * + ] emitOpcodes + } + { action NATIVE streq }' { 1 entry emitOpcodes } |
