[squeak-dev] The Trunk: Compiler-eem.397.mcz
commits at source.squeak.org
commits at source.squeak.org
Thu Jan 3 23:15:11 UTC 2019
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]!
More information about the Squeak-dev
mailing list
|