Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1601.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.1601 Author: eem Time: 16 December 2015, 2:09:56.371 pm UUID: faa527e8-769c-4c9d-b4c9-8ce48b8edbd5 Ancestors: VMMaker.oscog-eem.1600
Slang: Fix determining types for implicitly typed pointer variables.
Fix indenting of some arithmetic expressions.
=============== Diff against VMMaker.oscog-eem.1600 ===============
Item was changed: ----- Method: CCodeGenerator>>generateAnd:on:indent: (in category 'C translation') ----- generateAnd: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream."
+ self emitCExpression: msgNode receiver on: aStream indent: level. - self emitCExpression: msgNode receiver on: aStream. aStream nextPutAll: ' && '. + self emitCExpression: msgNode args first on: aStream indent: level! - self emitCExpression: msgNode args first on: aStream.!
Item was changed: ----- Method: CCodeGenerator>>generateBitAnd:on:indent: (in category 'C translation') ----- generateBitAnd: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream."
+ self emitCExpression: msgNode receiver on: aStream indent: level. - self emitCExpression: msgNode receiver on: aStream. aStream nextPutAll: ' & '. + self emitCExpression: msgNode args first on: aStream indent: level! - self emitCExpression: msgNode args first on: aStream.!
Item was changed: ----- Method: CCodeGenerator>>generateBitOr:on:indent: (in category 'C translation') ----- generateBitOr: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream."
+ self emitCExpression: msgNode receiver on: aStream indent: level. - self emitCExpression: msgNode receiver on: aStream. aStream nextPutAll: ' | '. + self emitCExpression: msgNode args first on: aStream indent: level! - self emitCExpression: msgNode args first on: aStream.!
Item was changed: ----- Method: CCodeGenerator>>generateBitShift:on:indent: (in category 'C translation') ----- generateBitShift: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream."
| arg rcvr | arg := msgNode args first. rcvr := msgNode receiver. + arg isConstant + ifTrue: "bit shift amount is a constant" + [aStream nextPutAll: '((usqInt) '. + self emitCExpression: rcvr on: aStream. + arg value < 0 + ifTrue: [aStream nextPutAll: ' >> ', arg value negated printString] + ifFalse: [aStream nextPutAll: ' << ', arg value printString]. + aStream nextPutAll: ')'] + ifFalse: "bit shift amount is an expression" + [aStream nextPutAll: '(('. + self emitCExpression: arg on: aStream indent: level. + aStream nextPutAll: ' < 0) ? ((usqInt) '. + self emitCExpression: rcvr on: aStream indent: level. + aStream nextPutAll: ' >> -'. + self emitCExpression: arg on: aStream indent: level. + aStream nextPutAll: ') : ((usqInt) '. + self emitCExpression: rcvr on: aStream indent: level. + aStream nextPutAll: ' << '. + self emitCExpression: arg on: aStream indent: level. + aStream nextPutAll: '))']! - arg isConstant ifTrue: [ - "bit shift amount is a constant" - aStream nextPutAll: '((usqInt) '. - self emitCExpression: rcvr on: aStream. - arg value < 0 ifTrue: [ - aStream nextPutAll: ' >> ', arg value negated printString. - ] ifFalse: [ - aStream nextPutAll: ' << ', arg value printString. - ]. - aStream nextPutAll: ')'. - ] ifFalse: [ - "bit shift amount is an expression" - aStream nextPutAll: '(('. - self emitCExpression: arg on: aStream. - aStream nextPutAll: ' < 0) ? ((usqInt) '. - self emitCExpression: rcvr on: aStream. - aStream nextPutAll: ' >> -'. - self emitCExpression: arg on: aStream. - aStream nextPutAll: ') : ((usqInt) '. - self emitCExpression: rcvr on: aStream. - aStream nextPutAll: ' << '. - self emitCExpression: arg on: aStream. - aStream nextPutAll: '))'. - ].!
Item was changed: ----- Method: CCodeGenerator>>generateBitXor:on:indent: (in category 'C translation') ----- generateBitXor: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream."
+ self emitCExpression: msgNode receiver on: aStream indent: level. - self emitCExpression: msgNode receiver on: aStream. aStream nextPutAll: ' ^ '. + self emitCExpression: msgNode args first on: aStream indent: level! - self emitCExpression: msgNode args first on: aStream.!
Item was changed: ----- Method: CCodeGenerator>>generateEqual:on:indent: (in category 'C translation') ----- generateEqual: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream."
+ self emitCExpression: msgNode receiver on: aStream indent: level. - self emitCExpression: msgNode receiver on: aStream. aStream nextPutAll: ' == '. + self emitCExpression: msgNode args first on: aStream indent: level! - self emitCExpression: msgNode args first on: aStream.!
Item was changed: ----- Method: CCodeGenerator>>generateGreaterThan:on:indent: (in category 'C translation') ----- generateGreaterThan: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream."
+ self emitCExpression: msgNode receiver on: aStream indent: level. - self emitCExpression: msgNode receiver on: aStream. aStream nextPutAll: ' > '. + self emitCExpression: msgNode args first on: aStream indent: level! - self emitCExpression: msgNode args first on: aStream.!
Item was changed: ----- Method: CCodeGenerator>>generateGreaterThanOrEqual:on:indent: (in category 'C translation') ----- generateGreaterThanOrEqual: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream."
+ self emitCExpression: msgNode receiver on: aStream indent: level. - self emitCExpression: msgNode receiver on: aStream. aStream nextPutAll: ' >= '. + self emitCExpression: msgNode args first on: aStream indent: level! - self emitCExpression: msgNode args first on: aStream.!
Item was changed: ----- Method: CCodeGenerator>>generateLessThan:on:indent: (in category 'C translation') ----- generateLessThan: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream."
+ self emitCExpression: msgNode receiver on: aStream indent: level. - self emitCExpression: msgNode receiver on: aStream. aStream nextPutAll: ' < '. + self emitCExpression: msgNode args first on: aStream indent: level! - self emitCExpression: msgNode args first on: aStream.!
Item was changed: ----- Method: CCodeGenerator>>generateLessThanOrEqual:on:indent: (in category 'C translation') ----- generateLessThanOrEqual: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream."
+ self emitCExpression: msgNode receiver on: aStream indent: level. - self emitCExpression: msgNode receiver on: aStream. aStream nextPutAll: ' <= '. + self emitCExpression: msgNode args first on: aStream indent: level! - self emitCExpression: msgNode args first on: aStream.!
Item was changed: ----- Method: CCodeGenerator>>generateNotEqual:on:indent: (in category 'C translation') ----- generateNotEqual: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream."
+ self emitCExpression: msgNode receiver on: aStream indent: level. - self emitCExpression: msgNode receiver on: aStream. aStream nextPutAll: ' !!= '. + self emitCExpression: msgNode args first on: aStream indent: level! - self emitCExpression: msgNode args first on: aStream.!
Item was changed: ----- Method: CCodeGenerator>>generateShiftRight:on:indent: (in category 'C translation') ----- generateShiftRight: msgNode on: aStream indent: level "Generate the C code for this message onto the given stream."
| type | "If the variable is a 64-bit type then don't cast it to usqInt (typically a 32-bit type)" (self is64BitIntegralVariable: msgNode receiver typeInto: [:t| type := t]) ifTrue: ["If not unsigned cast it to unsigned." type first ~= $u ifTrue: [aStream nextPutAll: '((unsigned '; nextPutAll: type; nextPut: $)]. + self emitCExpression: msgNode receiver on: aStream indent: level. - self emitCExpression: msgNode receiver on: aStream. type first ~= $u ifTrue: [aStream nextPut: $)]] ifFalse: [aStream nextPutAll: '((usqInt) '. + self emitCExpression: msgNode receiver on: aStream indent: level. - self emitCExpression: msgNode receiver on: aStream. aStream nextPut: $)]. aStream nextPutAll: ' >> '. + self emitCExpression: msgNode args first on: aStream indent: level! - self emitCExpression: msgNode args first on: aStream!
Item was added: + ----- Method: CCodeGenerator>>isPointerCType: (in category 'type inference') ----- + isPointerCType: aType + ^aType last == $*!
Item was changed: ----- Method: CCodeGenerator>>isSimpleType: (in category 'type inference') ----- isSimpleType: aType "For the purposes of the read-before-written initializer, answer if aType is simple, e.g. not a structure, and array or an opaque type." + ^(self isPointerCType: aType) + or: [self isIntegralCType: aType]! - ^aType last = $* - or: [#( sqInt usqInt sqLong usqLong - int #'unsigned int' double float - short #'unsigned short' - char #'unsigned char' #'signed char') includes: aType]!
Item was removed: - ----- Method: CCodeGenerator>>mergeTypeOf:in:with: (in category 'type inference') ----- - mergeTypeOf: var in: aDictionary with: newType - "var is a variable that has been assigned an expression of type newType. - Either assign its type, if it is as yet untyped, or merge newType with its existing type. - N.B. We refuse to promote a variable that already has integral type to a floating point - type. The existing plugins depend on this; one can always use an explicit type in future." - | existingType mergedType | - existingType := self - extractTypeFor: var - fromDeclaration: (aDictionary at: var ifAbsentPut: [newType, ' ', var]). - existingType ~= newType ifTrue: - [((self isIntegralCType: existingType) - and: [self isFloatingPointCType: newType]) ifFalse: - [mergedType := self promoteArithmeticTypes: existingType and: newType. - aDictionary at: var put: mergedType, ' ', var]]!
Item was added: + ----- Method: CCodeGenerator>>mergeTypeOf:in:with:method: (in category 'type inference') ----- + mergeTypeOf: var in: aDictionary with: newType method: tMethod + "var is a variable that has been assigned an expression of type newType. + Either assign its type, if it is as yet untyped, or merge newType with its existing type. + N.B. We refuse to promote a variable that already has integral type to a floating point + type. The existing plugins depend on this; one can always use an explicit type in future." + | existingType mergedType | + existingType := self + extractTypeFor: var + fromDeclaration: (aDictionary at: var ifAbsentPut: [newType, ' ', var]). + existingType ~= newType ifTrue: + [((self isPointerCType: existingType) + or: [self isPointerCType: newType]) + ifTrue: + [existingType = #'void *' ifTrue: [^newType]. + newType = #'void *' ifTrue: [^existingType]. + self logger show: 'conflicting types ', existingType, ' ', newType, ' for ', var, ' in ', tMethod selector. + ^existingType] + ifFalse: + [((self isIntegralCType: existingType) + and: [self isFloatingPointCType: newType]) ifFalse: + [mergedType := self promoteArithmeticTypes: existingType and: newType. + aDictionary at: var put: mergedType, ' ', var]]]!
Item was changed: ----- Method: TMethod>>inferTypesForImplicitlyTypedVariablesIn: (in category 'type inference') ----- inferTypesForImplicitlyTypedVariablesIn: aCodeGen "infer types for untyped variables from assignments and arithmetic uses. For debugging answer a Dictionary from var to the nodes that determined types This for debugging: (self copy inferTypesForImplicitlyTypedVariablesIn: aCodeGen)" | alreadyExplicitlyTyped effectiveNodes | aCodeGen maybeBreakForTestToInline: selector in: self. alreadyExplicitlyTyped := declarations keys asSet. effectiveNodes := Dictionary new. "this for debugging" parseTree nodesDo: [:node| | type var | "If there is something of the form i >= 0, then i should be signed, not unsigned." (node isSend and: [(locals includes: (var := node receiver variableNameOrNil)) and: [(alreadyExplicitlyTyped includes: var) not "don't be fooled by inferred unsigned types" and: [(#(<= < >= >) includes: node selector) and: [node args first isConstant and: [node args first value = 0 and: [(type := self typeFor: var in: aCodeGen) notNil and: [type first == $u]]]]]]]) ifTrue: [declarations at: var put: (aCodeGen signedTypeForIntegralType: type), ' ', var. effectiveNodes at: var put: { declarations at: var. node }]. "if an assignment to an untyped local of a known type, set the local's type to that type. Only observe known sends (methods in the current set) and typed local variables." (node isAssignment and: [(locals includes: (var := node variable name)) and: [(alreadyExplicitlyTyped includes: var) not "don't be fooled by previously inferred types" and: [(type := node expression isSend ifTrue: [aCodeGen returnTypeForSend: node expression in: self] ifFalse: [self typeFor: node expression in: aCodeGen]) notNil + and: [aCodeGen isSimpleType: type]]]]) ifTrue: + [aCodeGen mergeTypeOf: var in: declarations with: type method: self. - and: [aCodeGen isIntegralCType: type]]]]) ifTrue: - [aCodeGen mergeTypeOf: var in: declarations with: type. effectiveNodes at: var put: { declarations at: var. node }, (effectiveNodes at: var ifAbsent: [#()])]]. ^effectiveNodes!
vm-dev@lists.squeakfoundation.org