Class new title: Decompiler subclassof: Object fields: 'method temps instvars literals stack isReference literalNames' declare: 'highlight breakPC '; sharing: ByteCodes block: t1 to: t2 pc t3 hasValue t4 | t5 t6 t7 t8 t9 t10 [t5 _ ParsedBlock default. t3 value_ t2 + 1. t9 _ stack position. t6 _ Stream new of: method from: t1 to: t2. for t7 from: t6 do [t7 < 128  [self loadByte: t7 code: t6] t7 < 136  [self controlByte: t7 code: t6 block: t5] t7 < 140  [self loadByte: t7 code: t6] t7 = 140  [self selectorByte: t7 code: t6 at: t6 position] t7 < 176  [t8 _ self jumpByte: t7 code: t6 block: t5. t6 end  [t3 value_ t8]] self selectorByte: t7 code: t6 at: t6 position]. stack position > t9  [t10 _ stack pop. t4 value_ true. t5 empty and (t10 is: ParsedBlock)  [t10] t5 next_ t10. t5] t4 value_ false. [t5 empty  [t5 next_ nil]]. [t5 returns or (t5  t5 position) returns  [t3 value_ method length + 1]]. t5] checkForRemoteCode: t1 code: t2 block: t3 | t4 t5 t6 t7 t8 [t1 > t2 limit  [false] method  (t1 - 3)  toEnd  [false] t6 _ method  (t1 - 2). t6 < 160 or t6 > 163  [false] t7 _ t6 - 164 * 256 + (method  (t1 - 1)). t1 + t7  (t2 position + 1)  [false] t4 _ stack pop. ((t4 isnt: ParsedMessage) or t4 rcvr  toLoadThisCtxt  false) or (self selector: t4 op)  remoteCopy  [stack next_ t4. false] t8 _ self block: t2 position + 1 to: t1 - 4 pc [t5] hasValue [t5]. stack next_ ParsedRemote new expr: t8. t2 position_ t1 - 1] conditionalJump: t1 code: t2 block: t3 | t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 [t5 _ stack pop. t6 _ self block: t2 position + 1 to: t1 - 1 pc [t8] hasValue [t12]. t8 _ t8 min: t2 limit + 1. t8 < t1  [self loop: t8 whileExpr: t5 doExpr: t6 code: t2 block: t3 doSize: t1 - t2 position - 1. t2 position_ t1 - 1] t7 _ self block: t1 to: t8 - 1 pc [t9] hasValue [t10]. [t9 < t2 position  [t2 position_ t8 - 3. t13 _ true] t2 position_ t8 - 1]. [t8 + 1 = t2 limit and (method  t8  160 and method  t8  167)  [t13 _ true]]. [t8 = t2 limit and (method  t8  144 and method  t8  151)  [t13 _ true]]. t12 and (t6 position = 1 and t6  1  toLoadTrue)  [stack next_ ParsedDisjunct new left: t5 right: [t7 position = 1  [t7  1] t7]] t12 and (t7 position = 1 and t7  1  toLoadFalse)  [stack next_ ParsedConjunct new left: t5 right: [t6 position = 1  [t6  1] t6]] t4 _ ParsedConditional new ifExpr: t5 thenExpr: t6 elseExpr: t7. t12  [t11 _ ParsedBlock default. t11 next_ t4. stack next_ t11] (t2 end or t13  true) or (t8 + 1 = method length and method  t8 = toLoadSelf)  [t3 next_ t4] t11 _ ParsedBlock default. t11 next_ t4. t3 next_ t11] controlByte: t1 code: t2 block: t3 | t4 t5 t6 [t1 = toSmashPop  [t4 _ self makeLoad: t2 next code: t2. t3 next_ ParsedAssignment new var: t4 expr: stack pop] t1 = toSmash  [t2 end  [t6 _ Stream new of: method from: t2 limit + 1 to: method length. t4 _ self makeLoad: t6 next code: t6. t3 next_ ParsedAssignment new var: t4 expr: stack pop] t4 _ self makeLoad: t2 next code: t2. t3 next_ ParsedAssignment new var: t4 expr: stack pop. stack next_ t4] t1 = toPop  [t3 next_ stack pop] t1 = toReturn  [t5 _ stack pop. stack empty  false  [user notify: 'stack not empty'] t5  toLoadSelf and t2 position = method length  [] t3 doesReturn. t3 next_ t5] t1 = toEnd  [user notify: 'unexpected'] t1 = toLoadThisCtxt  [stack next_ t1] t1 = toSuper  [stack pop. stack next_ t1] user notify: 'unknown control byte'] convertMacros: t1 sel: t2 | t3 t4 t5 t6 t7 [t3 _ (Vector new: 10) asStream. t4 _ Vector new: temps length. for t7 to: t2 numArgs do [t4  t7 _ false]. t1 findMacros: t3 compilerTemps: t4. t5 _ t3 contents. for t7 from: t5 length - 1 to: 1 by: 2 do [t5  t7  nil  [] t5  t7 insertMacro: t5  (t7 + 1) decompiler: self]. for t7 to: temps length do [t4  t7  true  [temps  t7 _ '']]] decompile: t1 class: t2 | t3 t4 t5 t6 t7 t8 [method _ t2 method: t1. method length < [NoteTaker  [3] 8]  [self quickCode: t1 class: t2] [NoteTaker  [literals _ method literals. t6 _ method primitive. t7 _ method initialPC - 1. t8 _ method numArgs + method numTemps] literals _ MessageDict new literalsIn: method. t6 _ method  2. t7 _ method  6. t8 _ method  5]. temps _ Vector new: t8. self initSymbols: t2. stack _ (Vector new: 10) asStream. t4 _ self block: t7 + 1 to: method length pc [t5] hasValue [t5]. stack empty  false  [user notify: 'stack not empty'] self convertMacros: t4 sel: t1. t3 _ Stream default. self printPattern: t1 on: t3. t3 crtab: 1. t4 printon: t3 indent: 1 precedence: 0 forValue: false decompiler: self. [t6  0  [t3 append: ' primitive: '. t3 print: t6]]. t3 contents asParagraph makeBoldPattern] findPC: t1 [breakPC _ t1. highlight _ 1 to: 1] highlight [highlight] highlight: t1 [highlight _ t1. highlight] initSymbols: t1 | t2 t3 t4 [for t2 to: temps length do [temps  t2 _ 't' + t2 asString]. instvars _ t1 instvars. literalNames _ Vector new: literals length. t4 _ t1 wholeEnvironment , Smalltalk , Undeclared. for t2 to: literals length do [t3 _ literals  t2. literalNames  t2 _ [t3 is: UniqueString  [t3] t3 is: ObjectReference  [self invertRef: t3 environment: t4] t3  FieldReference  [''] t3 asString]]] instvar: t1 [instvars  (t1 - codeLoadField + 1)] invertRef: t1 environment: t2 | t3 t4 [for t3 from: t2 do [t4 _ t3 invertRef: t1. t4  [t4]]. 'unknown'] jumpByte: t1 code: t2 block: t3 | t4 t5 [t1 < 152  [t1 - 144 + t2 position + 2] t1 < 160  [self conditionalJump: t1 - 152 + t2 position + 2 code: t2 block: t3. t2 position + 1] t1 < 168  [t4 _ t2 next. t5 _ t1 - 164 * 256 + t4 + t2 position + 1. self checkForRemoteCode: t5 code: t2 block: t3. t5] t1 < 172  [t2 skip: 1. user notify: 'conditional jump backward not expected'] t1 < 176  [t4 _ t2 next. self conditionalJump: t1 - 172 * 256 + t4 + t2 position + 1 code: t2 block: t3. t2 position + 1] user notify: 'not a jump byte'] literal: t1 | t2 t3 t4 [t2 _ t1 - codeLoadLit + 1. t3 _ literals  t2. t4 _ literalNames  t2. t3 is: ObjectReference  [t4] (t3 is: UniqueString) or (t3 is: Vector)  ['' + t4] t4] literalIndirect: t1 [literalNames  (t1 - codeLoadLitInd + 1)] loadByte: t1 code: t2 | t3 t4 [t3 _ self makeLoad: t1 code: t2. t3  codeLoadLit and t3 < codeLoadLitInd  [t4 _ literals  (t3 - codeLoadLit + 1). t4  FieldReference  [self remoteReference: t2] t4 is: ObjectReference  [stack next_ ParsedObjectReference new var: t3] stack next_ t3] stack next_ t3] loop: t1 whileExpr: t2 doExpr: t3 code: t4 block: t5 doSize: t6 | t7 t8 t9 [t7 _ t4 position - t6 jmpSize. t8 _ self block: t1 to: t7 pc [t9] hasValue [t9]. t5 skip: 1 - t8 position. t5 next_ ParsedLoop new whileExpr: [t8 position = 1  [t2] t8] doExpr: t3] makeLoad: t1 code: t2 | t3 [t1  136 and t1  139  [t3 _ 256 * (t1 - 135). t2 next + t3] t1 asCompilerCode] printPattern: t1 on: t2 | t3 t4 t5 [t4 _ t1 numArgs. [t4 = 0  [t2 append: t1. t2 space] t5 _ t1 keywords. for t3 to: t5 length do [t2 append: t5  t3. t2 space. t2 append: temps  t3. t2 space]]. t4 = temps length  [] t2 append: '| '. for t3 from: t4 + 1 to: temps length do [t2 append: temps  t3. t2 space]] quickCode: t1 class: t2 | t3 [[NoteTaker  [method isReturnSelf  [t1] t3 _ method isReturnField. [t3  [t1 + ' [' + (t2 instvars  t3) + ']'] 'undecipherable method']] method length = 2  [t1] method length = 5  [t1 + ' [' + (t2 instvars  (method  5 + 1)) + ']'] 'undecipherable method'] asParagraph makeBoldPattern] remoteReference: t1 | t2 t3 t4 t5 [t2 _ stack pop. t4 _ [t2  124  [(0 1 2 10 )  (t2 - 120)] literals  (t2 - codeLoadLit + 1)]. t3 _ stack pop. t1 skip: 2. t5 _ [t3 = toLoadTempframe  [codeLoadTemp + t4 - 1] t3 = toLoadSelf  [codeLoadField + t4 - 1] user notify: 'bad remote reference']. stack next_ ParsedFieldReference new var: t5] selector: t1 [t1 > 166 and t1 < 208  [SpecialOops  (t1 - 166)] literalNames  (t1 - codeSendLit + 1)] selectorByte: t1 code: t2 at: t3 | t4 t5 t6 t7 t8 t9 [t4 _ [t1 = toSendLitLong  [t2 next + codeSendLit] t1 asCompilerCode]. t5 _ self selector: t4. t7 _ t5 numArgs. t9 _ stack pop. [t7 = 0  [t8 _ false] t7 = 1  [t8 _ stack pop] t8 _ Vector new: t7. for t6 from: t7 to: 1 by: 1 do [t8  t6 _ stack pop]]. stack next_ ParsedMessage new rcvr: t9 op: t4 args: t8. t3 = breakPC  [stack last hasPC]] temp: t1 [temps  (t1 - codeLoadTemp + 1)]