Eliot Miranda uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-eem.397.mcz ==================== Summary ==================== Name: Compiler-eem.397 Author: eem Time: 3 January 2019, 3:15:09.938414 pm UUID: 0561e11a-8d91-4ed1-b806-535264b98ef8 Ancestors: Compiler-eem.396 Fix the recorded pcs for inlined blocks. The old code assumed one-byte branches and so generated off-by-one pcs for all multiple byte branches. In addition the code for case guards was simply wrong, always off-by-one. The fix is to use emncoder nextPC in teh right place, not encoder pc after branch/send generation when a multibyte send will compute the wrong pc. Tests exist in Tests-eem.405 and later. Play via debugging e.g.: 5 caseOf: { [4] -> [#nope]. [3] -> [#nope]. [2] -> [#nope]. [1] -> [#nope]. [0] -> [#nope] } otherwise: [#dope] =============== Diff against Compiler-eem.396 =============== Item was changed: ----- Method: MessageNode>>emitCodeForCase:encoder:value: (in category 'code generation') ----- emitCodeForCase: stack encoder: encoder value: forValue | braceNode sizeStream allReturn | forValue ifFalse: [^super emitCodeForEffect: stack encoder: encoder]. braceNode := arguments first. sizeStream := ReadStream on: sizes. receiver emitCodeForValue: stack encoder: encoder. "There must be at least one branch around the otherwise/caseError so the decompiler can identify the end of the otherwise/caseError." allReturn := true. "assume every case ends with a return" braceNode casesForwardDo: [:keyNode :valueNode :last | | thenSize elseSize | thenSize := sizeStream next. elseSize := sizeStream next. last ifFalse: [encoder genDup. stack push: 1]. keyNode emitCodeForEvaluatedValue: stack encoder: encoder. + keyNode pc: encoder nextPC. - keyNode pc: encoder pc. equalNode emitCode: stack args: 1 encoder: encoder. self emitCodeForBranchOn: false dist: thenSize pop: stack encoder: encoder. last ifFalse: [encoder genPop. stack pop: 1]. valueNode emitCodeForEvaluatedValue: stack encoder: encoder. last ifTrue: [stack pop: 1]. valueNode returns ifFalse: [self emitCodeForJump: elseSize encoder: encoder. allReturn := false]. (last and: [allReturn]) ifTrue: [self emitCodeForJump: elseSize encoder: encoder]]. arguments size = 2 ifTrue: [arguments last emitCodeForEvaluatedValue: stack encoder: encoder] "otherwise: [...]" ifFalse: [NodeSelf emitCodeForValue: stack encoder: encoder. caseErrorNode emitCode: stack args: 0 encoder: encoder]! Item was changed: ----- Method: MessageNode>>emitCodeForIf:encoder:value: (in category 'code generation') ----- emitCodeForIf: stack encoder: encoder value: forValue | thenExpr thenSize elseExpr elseSize | thenSize := sizes at: 1. elseSize := sizes at: 2. thenExpr := arguments at: 1. elseExpr := arguments at: 2. receiver emitCodeForValue: stack encoder: encoder. + pc := encoder nextPC. elseSize * thenSize > 0 ifTrue: "Code for two-armed" [self emitCodeForBranchOn: false dist: thenSize pop: stack encoder: encoder. - pc := encoder pc. thenExpr emitCodeForEvaluatedValue: stack encoder: encoder. stack pop: 1. "then and else alternate; they don't accumulate" + thenExpr returns ifFalse: "Elide jump over else after a return" - thenExpr returns ifFalse: - "Elide jump over else after a return" [self emitCodeForJump: elseSize encoder: encoder]. elseExpr emitCodeForEvaluatedValue: stack encoder: encoder. + forValue ifFalse: "Two-armed IFs forEffect share a single pop - except if both return" + [(arguments allSatisfy: #returns) ifFalse: [encoder genPop]. + stack pop: 1]] - forValue - ifFalse: - ["Two-armed IFs forEffect share a single pop - except if both return" - (arguments allSatisfy: #returns) ifFalse: [encoder genPop]. - stack pop: 1]] ifFalse: "One arm is empty here (this can only ever be for effect)" [thenSize > 0 ifTrue: [self emitCodeForBranchOn: false dist: thenSize pop: stack encoder: encoder. - pc := encoder pc. thenExpr emitCodeForEvaluatedEffect: stack encoder: encoder] ifFalse: [self emitCodeForBranchOn: true dist: elseSize pop: stack encoder: encoder. - pc := encoder pc. elseExpr emitCodeForEvaluatedEffect: stack encoder: encoder]]! Item was changed: ----- Method: MessageNode>>emitCodeForIfNil:encoder:value: (in category 'code generation') ----- emitCodeForIfNil: stack encoder: encoder value: forValue | theNode theSize ifNotNilSelector | theNode := arguments first. theSize := sizes at: 1. ifNotNilSelector := #ifNotNil:. receiver emitCodeForValue: stack encoder: encoder. forValue ifTrue: [encoder genDup. stack push: 1]. encoder genPushSpecialLiteral: nil. stack push: 1. equalNode emitCode: stack args: 1 encoder: encoder. + pc := encoder nextPC. - pc := encoder pc. self emitCodeForBranchOn: (selector key == ifNotNilSelector) dist: theSize pop: stack encoder: encoder. forValue ifTrue: [encoder genPop. stack pop: 1. theNode emitCodeForEvaluatedValue: stack encoder: encoder] ifFalse: [theNode emitCodeForEvaluatedEffect: stack encoder: encoder]! Item was changed: ----- Method: MessageNode>>emitCodeForToDo:encoder:value: (in category 'code generation') ----- emitCodeForToDo: stack encoder: encoder value: forValue " var := rcvr. L1: [var <= arg1] Bfp(L2) [block body. var := var + inc] Jmp(L1) L2: " | loopSize initStmt limitInit test block incStmt blockSize | initStmt := arguments at: 4. limitInit := arguments at: 7. test := arguments at: 5. block := arguments at: 3. incStmt := arguments at: 6. blockSize := sizes at: 1. loopSize := sizes at: 2. "This will return the receiver of to:do: which is the initial value of the loop" forValue ifTrue: [initStmt emitCodeForValue: stack encoder: encoder] ifFalse: [initStmt emitCodeForEffect: stack encoder: encoder]. limitInit ifNotNil: [limitInit emitCodeForEffect: stack encoder: encoder]. test emitCodeForValue: stack encoder: encoder. + pc := encoder nextPC. self emitCodeForBranchOn: false dist: blockSize pop: stack encoder: encoder. - pc := encoder pc. block emitCodeForEvaluatedEffect: stack encoder: encoder. incStmt emitCodeForEffect: stack encoder: encoder. self emitCodeForJump: 0 - loopSize encoder: encoder! Item was changed: ----- Method: MessageNode>>emitCodeForWhile:encoder:value: (in category 'code generation') ----- emitCodeForWhile: stack encoder: encoder value: forValue "L1: ... Bfp(L2)|Btp(L2) ... Jmp(L1) L2: " | cond stmt stmtSize loopSize | cond := receiver. stmt := arguments at: 1. stmtSize := sizes at: 1. loopSize := sizes at: 2. cond emitCodeForEvaluatedValue: stack encoder: encoder. + pc := encoder nextPC. self emitCodeForBranchOn: (selector key == #whileFalse:) "Bfp for whileTrue" dist: stmtSize pop: stack encoder: encoder. "Btp for whileFalse" - pc := encoder pc. stmt emitCodeForEvaluatedEffect: stack encoder: encoder. self emitCodeForJump: 0 - loopSize encoder: encoder. forValue ifTrue: [encoder genPushSpecialLiteral: nil. stack push: 1]! |
Free forum by Nabble | Edit this page |