[Newcompiler] How to decompile #while{True,False}

Klaus D. Witzel klaus.witzel at cobss.com
Wed Sep 5 05:12:25 UTC 2007


Hi Math,

when the old decompiler decompiles #sweep: it finds

[(ind := ind + 1) > list size
		ifTrue: [false]
		ifFalse: [(parts at: ind) first asLowercase = projectName
				and: [versions
						add: (parts at: ind).
					true]]] whileTrue.

which is what can be expected, the inner #ifTrue:ifFalse: is rendered as  
an #and: (... ifFalse: [false]).

The place where a #not message send is inserted is  
IRDecompiler>>#endAndOr2: (reducing the jump structures).

HTH.

Cheers
Klaus

On Wed, 05 Sep 2007 00:06:55 +0200, Mathieu Suen wrote:

> Hi
>
> In a very particular case the compiler optimize the #whileTrue in a way  
> that the Decompiler can't find the roght code.
>
> This particular case is:
>
> [
> self somthings
>
> aTest
> 	ifTrue:[ok anOtherThings
> 		ifTrue:[here doSomthings. true]
> 		ifFalse:[false]]
> 	ifFalse:[false]
> ] whileTrue
>
> The typical exemple is from  Project class>>#sweep: :
>
>>>> 		[(ind _ ind + 1) > list size
>> 			ifFalse: [(parts at: ind) first asLowercase = projectName
>> 				ifTrue: [versions add: (parts at: ind).  true]
>> 				ifFalse: [false]]
>> 			ifTrue: [false]] whileTrue.
>>>
> The corresponding bytecode is:
>
>> 199 <14> pushTemp: 4
>> 200 <76> pushConstant: 1
>> 201 <B0> send: +
>> 202 <81 44> storeIntoTemp: 4
>> 204 <12> pushTemp: 2
>> 205 <C2> send: size
>> 206 <B3> send: >
>> 207 <A8 16> jumpTrue: 231
>>
>> 209 <13> pushTemp: 3
>> 210 <14> pushTemp: 4
>> 211 <C0> send: at:
>> 212 <83 14> send: first
>> 214 <83 15> send: asLowercase
>> 216 <16> pushTemp: 6
>> 217 <B6> send: =
>> 218 <AC 0B> jumpFalse: 231
>>
>> 220 <17> pushTemp: 7
>> 221 <13> pushTemp: 3
>> 222 <14> pushTemp: 4
>> 223 <C0> send: at:
>> 224 <83 37> send: add:
>> 226 <87> pop
>> 227 <71> pushConstant: true
>> 228 <99> jumpFalse: 231
>>
>> 229 <A3 E0> jumpTo: 199
>
>
> So the first #ifFlase:ifTrue: has been compact to a single jump:
> 207 <A8 16> jumpTrue: 231
>
> This avoid pushing false and make an unconditional jump to the end of  
> the nearly end of the block.
> We also have the same optimazation for the inner #iTrue:ifFalse: message  
> (i.e. at bytecode: 218 and: 228).
>
> We can rewrite the code to produce the same flow :
>
>> [((ind _ ind + 1) > list size) not
>> 			or: [(parts at: ind) first asLowercase = projectName
>> 				and: [versions add: (parts at: ind)]]]] whileTrue
>
> This is what the decompiler found out.
> But this do not produce the same bytecode:
>
>> 203 <14> pushTemp: 4
>> 204 <76> pushConstant: 1
>> 205 <B0> send: +
>> 206 <81 44> storeIntoTemp: 4
>> 208 <12> pushTemp: 2
>> 209 <C2> send: size
>> 210 <B3> send: >
>> 211 <83 18> send: not
>> 213 <A8 12> jumpTrue: 233
>>
>> 215 <13> pushTemp: 3
>> 216 <14> pushTemp: 4
>> 217 <C0> send: at:
>> 218 <83 14> send: first
>> 220 <83 15> send: asLowercase
>> 222 <16> pushTemp: 6
>> 223 <B6> send: =
>> 224 <AC 09> jumpFalse: 235
>>
>> 226 <17> pushTemp: 7
>> 227 <13> pushTemp: 3
>> 228 <14> pushTemp: 4
>> 229 <C0> send: at:
>> 230 <83 37> send: add:
>> 232 <99> jumpFalse: 235
>>
>> 233 <A3 E0> jumpTo: 203
>
> The only difference is in the bytecode 211 and 213:
> A "send: not" is added and the jump don't have the same destination.
>
> The old compiler dose not make this smart optimization.
> So I have several  question.
>
> Do we want the decompiler produce different bytecode (i.e. adding a  
> "send: not"…)?
> Should we do such optimization? (IMO I don't thinks so.)
> where dose the optimization take place? I can't figure out where it is.  
> I get lost inside ASTTranslator and IRTranslator.
>
>
> Thanks
>
> 	Mth
>
>
>




More information about the Newcompiler mailing list