<div dir="ltr"><div>Just a side note: I'm currently using the Spur64 VM generated from this VMMaker version.</div><div>Whoever changes the generator likes to live dangerously and eat own dog food.</div><div>I ran all 6.0 tests, no crash, no new failure.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le mar. 10 mars 2020 à 00:28, <<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br>
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:<br>
<a href="http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2723.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2723.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-nice.2723<br>
Author: nice<br>
Time: 10 March 2020, 12:26:31.04183 am<br>
UUID: c1319382-406c-43a7-9f55-2b48c4007d80<br>
Ancestors: VMMaker.oscog-eem.2722<br>
<br>
Fix the right shift: dont convert to usqInt a type longer than usqInt<br>
<br>
=============== Diff against VMMaker.oscog-eem.2722 ===============<br>
<br>
Item was changed:<br>
----- Method: CCodeGenerator>>generateBitShift:on:indent: (in category 'C translation') -----<br>
generateBitShift: msgNode on: aStream indent: level<br>
"Generate the C code for this message onto the given stream."<br>
<br>
+ | arg shift rightShift |<br>
+ (self isConstantNode: (arg := msgNode args first) valueInto: [:shiftValue| shift := shiftValue])<br>
- | arg rcvr shift |<br>
- arg := msgNode args first.<br>
- rcvr := msgNode receiver.<br>
- (self isConstantNode: arg valueInto: [:shiftValue| shift := shiftValue])<br>
ifTrue: "bit shift amount is a constant"<br>
+ [aStream nextPut: $(.<br>
- [aStream nextPutAll: '((usqInt) '.<br>
- self emitCExpression: rcvr on: aStream.<br>
shift < 0<br>
+ ifTrue:<br>
+ [rightShift := TSendNode new<br>
+ setSelector: #>><br>
+ receiver: msgNode receiver<br>
+ arguments: {TConstantNode new setValue: shift negated}.<br>
+ self generateShiftRight: rightShift on: aStream indent: level]<br>
+ ifFalse: [self generateShiftLeft: msgNode on: aStream indent: level].<br>
- ifTrue: [aStream nextPutAll: ' >> '; print: shift negated]<br>
- ifFalse: [aStream nextPutAll: ' << '; print: shift].<br>
aStream nextPut: $)]<br>
ifFalse: "bit shift amount is an expression"<br>
+ [rightShift := TSendNode new<br>
+ setSelector: #>><br>
+ receiver: msgNode receiver<br>
+ arguments: {TSendNode new<br>
+ setSelector: #negated<br>
+ receiver: arg<br>
+ arguments: #()}.<br>
+ aStream nextPutAll: '(('.<br>
+ self emitCExpression: arg on: aStream.<br>
+ aStream nextPutAll: ' < 0) ? ('.<br>
+ self generateShiftRight: rightShift on: aStream indent: level. <br>
+ aStream nextPutAll: ') : ('.<br>
+ self generateShiftLeft: msgNode on: aStream indent: level.<br>
- [aStream nextPutAll: '(('.<br>
- self emitCExpression: arg on: aStream indent: level.<br>
- aStream nextPutAll: ' < 0) ? ((usqInt) '.<br>
- self emitCExpression: rcvr on: aStream indent: level.<br>
- aStream nextPutAll: ' >> -'.<br>
- self emitCExpression: arg on: aStream indent: level.<br>
- aStream nextPutAll: ') : ((usqInt) '.<br>
- self emitCExpression: rcvr on: aStream indent: level.<br>
- aStream nextPutAll: ' << '.<br>
- self emitCExpression: arg on: aStream indent: level.<br>
aStream nextPutAll: '))']!<br>
<br>
Item was changed:<br>
----- Method: CCodeGenerator>>generateShiftRight:on:indent: (in category 'C translation') -----<br>
generateShiftRight: msgNode on: aStream indent: level<br>
+ "Generate the C code for this message onto the given stream.<br>
+ Note that this generates a Logical Shift (unsigned), not an Arithmetic Shift (signed)."<br>
- "Generate the C code for this message onto the given stream."<br>
<br>
+ | type typeIsUnsigned mustCastToUnsigned unsignedType |<br>
+ type := self typeFor: msgNode receiver in: currentMethod.<br>
+ typeIsUnsigned := type first = $u.<br>
+ mustCastToUnsigned := typeIsUnsigned not or:<br>
+ ["cast to usqInt if the int is shorter: we want to avoid UB related to a shift exceeeding bit width"<br>
+ (self sizeOfIntegralCType: type) < (self sizeOfIntegralCType: #usqInt)].<br>
+ "If not unsigned cast it to unsigned."<br>
+ mustCastToUnsigned<br>
- | type |<br>
- "If the variable is a 64-bit type then don't cast it to usqInt (typically a 32-bit type)"<br>
- (self is64BitIntegralVariable: msgNode receiver typeInto: [:t| type := t])<br>
ifTrue:<br>
+ ["If the variable is a 64-bit type then don't cast it to usqInt (typically a 32-bit type)"<br>
+ unsignedType := (self sizeOfIntegralCType: type) < (self sizeOfIntegralCType: #usqLong)<br>
+ ifTrue: [#usqInt]<br>
+ ifFalse: [self unsignedTypeForIntegralType: type].<br>
+ aStream nextPutAll: '(('; nextPutAll: unsignedType; nextPutAll: ')('.<br>
- ["If not unsigned cast it to unsigned."<br>
- type first ~= $u ifTrue:<br>
- [aStream nextPutAll: '((unsigned '; nextPutAll: type; nextPut: $)].<br>
self emitCExpression: msgNode receiver on: aStream indent: level.<br>
+ aStream nextPutAll: '))']<br>
- type first ~= $u ifTrue:<br>
- [aStream nextPut: $)]]<br>
ifFalse:<br>
+ [aStream nextPutAll: '('.<br>
- [aStream nextPutAll: '((usqInt) '.<br>
self emitCExpression: msgNode receiver on: aStream indent: level.<br>
aStream nextPut: $)].<br>
aStream nextPutAll: ' >> '.<br>
self emitCExpression: msgNode args first on: aStream indent: level!<br>
<br>
Item was changed:<br>
----- Method: CCodeGenerator>>generateSignedBitShift:on:indent: (in category 'C translation') -----<br>
generateSignedBitShift: msgNode on: aStream indent: level<br>
"Generate the C code for this message onto the given stream."<br>
<br>
+ | arg shift rightShift |<br>
- | cast type arg shift |<br>
- "since ``signed'' is a synonym for ``signed int'' do not cast 64-bit values to signed if at all possible."<br>
- cast := (self is64BitIntegralVariable: msgNode receiver typeInto: [:t| type := t])<br>
- ifTrue: ['(', (type first = $u ifTrue: [type allButFirst: (type second = $n ifTrue: [2] ifFalse: [1])] ifFalse: [type]), ')']<br>
- ifFalse: ['(signed)'].<br>
(self isConstantNode: (arg := msgNode args first) valueInto: [:shiftValue| shift := shiftValue])<br>
ifTrue: "bit shift amount is a constant"<br>
+ [aStream nextPut: $(.<br>
- [aStream nextPut: $(; nextPutAll: cast.<br>
- self emitCExpression: msgNode receiver on: aStream.<br>
shift < 0<br>
+ ifTrue:<br>
+ [rightShift := TSendNode new<br>
+ setSelector: #>><br>
+ receiver: msgNode receiver<br>
+ arguments: {TConstantNode new setValue: shift negated}.<br>
+ self generateSignedShiftRight: rightShift on: aStream indent: level]<br>
+ ifFalse: [self generateShiftLeft: msgNode on: aStream indent: level].<br>
- ifTrue: [aStream nextPutAll: ' >> '; print: shift negated]<br>
- ifFalse: [aStream nextPutAll: ' << '; print: shift].<br>
aStream nextPut: $)]<br>
ifFalse: "bit shift amount is an expression"<br>
+ [rightShift := TSendNode new<br>
+ setSelector: #>><br>
+ receiver: msgNode receiver<br>
+ arguments: {TSendNode new<br>
+ setSelector: #negated<br>
+ receiver: arg<br>
+ arguments: #()}.<br>
+ aStream nextPutAll: '(('.<br>
- [aStream nextPutAll: '(('.<br>
self emitCExpression: arg on: aStream.<br>
+ aStream nextPutAll: ' < 0) ? ('.<br>
+ self generateSignedShiftRight: rightShift on: aStream indent: level. <br>
+ aStream nextPutAll: ') : ('.<br>
+ self generateShiftLeft: msgNode on: aStream indent: level.<br>
- aStream nextPutAll: ' < 0) ? ('; nextPutAll: cast.<br>
- self emitCExpression: msgNode receiver on: aStream.<br>
- aStream nextPutAll: ' >> -'.<br>
- self emitCExpression: arg on: aStream.<br>
- aStream nextPutAll: ') : ('; nextPutAll: cast.<br>
- self emitCExpression: msgNode receiver on: aStream.<br>
- aStream nextPutAll: ' << '.<br>
- self emitCExpression: arg on: aStream.<br>
aStream nextPutAll: '))']!<br>
<br>
Item was changed:<br>
----- Method: CCodeGenerator>>generateSignedShiftRight:on:indent: (in category 'C translation') -----<br>
generateSignedShiftRight: msgNode on: aStream indent: level<br>
"Generate the C code for >>> onto the given stream."<br>
<br>
+ | type typeIsUnsigned mustCastToSigned signedType |<br>
+ type := self typeFor: msgNode receiver in: currentMethod.<br>
+ typeIsUnsigned := type first = $u.<br>
+ mustCastToSigned := typeIsUnsigned or:<br>
+ ["cast to sqInt if the int is shorter: we want to avoid UB related to a shift exceeeding bit width"<br>
+ (self sizeOfIntegralCType: type) < (self sizeOfIntegralCType: #usqInt)].<br>
+ mustCastToSigned<br>
- (self is64BitIntegralVariable: msgNode receiver typeInto: [:t|])<br>
ifTrue:<br>
+ ["If the variable is a 64-bit type then don't cast it to usqInt (typically a 32-bit type)"<br>
+ signedType := (self sizeOfIntegralCType: type) < (self sizeOfIntegralCType: #usqLong)<br>
+ ifTrue: [#usqInt]<br>
+ ifFalse: [self signedTypeForIntegralType: type].<br>
+ aStream nextPutAll: '(('; nextPutAll: signedType; nextPutAll: ')('.<br>
+ self emitCExpression: msgNode receiver on: aStream indent: level.<br>
+ aStream nextPutAll: '))']<br>
- [aStream nextPutAll: '((sqLong) ']<br>
ifFalse:<br>
+ [aStream nextPutAll: '('.<br>
+ self emitCExpression: msgNode receiver on: aStream indent: level.<br>
+ aStream nextPut: $)].<br>
+ aStream nextPutAll: ' >> '.<br>
- [aStream nextPutAll: '((sqInt) '].<br>
- self emitCExpression: msgNode receiver on: aStream.<br>
- aStream nextPutAll: ') >> '.<br>
self emitCExpression: msgNode args first on: aStream!<br>
<br>
</blockquote></div>