VM Maker: VMMaker.oscog-eem.2111.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: VMMaker.oscog-eem.2111.mcz

commits-2
 
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2111.mcz

==================== Summary ====================

Name: VMMaker.oscog-eem.2111
Author: eem
Time: 24 January 2017, 7:33:34.632944 pm
UUID: 7c02b557-bdcc-4a91-92b1-7fc15f1e8605
Ancestors: VMMaker.oscog-eem.2110

Ndewspeak/Slang:

Fix printDecodeMethodHeaderOop: for the Newspeak VM.  Add type inferrence for TBraceNode, including casting the default value to a pointer type in var := expr caseOf: { ... }.

Elide break sends automatically when outputting sources.

=============== Diff against VMMaker.oscog-eem.2110 ===============

Item was changed:
  ----- Method: CCodeGenerator>>returnTypeForSend:in:ifNil: (in category 'type inference') -----
  returnTypeForSend: sendNode in: aTMethod ifNil: typeIfNil
  "Answer the return type for a send.  Unbound sends default to typeIfNil.
  Methods with types as yet unknown have a type determined either by the
  kernelReturnTypes or the table below, or, if they are in neither set, then nil.
  The inferred type should match as closely as possible the C type of
  generated expessions so that inlining would not change the expression.
  If there is a method for sel but its return type is as yet unknown it mustn't
  be defaulted, since on a subsequent pass its type may be computable."
  | sel methodOrNil |
  methodOrNil := self anyMethodNamed: (sel := sendNode selector).
  (methodOrNil notNil and: [methodOrNil returnType notNil]) ifTrue:
  [^self baseTypeForType: methodOrNil returnType].
  ^kernelReturnTypes
  at: sel
  ifAbsent:
  [sel
  caseOf: {
  [#integerValueOf:] -> [#sqInt].
  [#isIntegerObject:] -> [#int].
  [#negated] -> [self promoteArithmeticTypes: (self typeFor: sendNode receiver in: aTMethod) and: #int].
  [#+] -> [self typeForArithmetic: sendNode in: aTMethod].
  [#-] -> [self typeForArithmetic: sendNode in: aTMethod].
  [#*] -> [self typeForArithmetic: sendNode in: aTMethod].
  [#/] -> [self typeForArithmetic: sendNode in: aTMethod].
  [#//] -> [self typeForArithmetic: sendNode in: aTMethod].
  [#\\] -> [self typeForArithmetic: sendNode in: aTMethod].
  [#rem:] -> [self typeForArithmetic: sendNode in: aTMethod].
  [#quo:] -> [self typeForArithmetic: sendNode in: aTMethod].
  "C99 Sec Bitwise shift operators ... 3 Sematics ...
  The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand..."
  [#>>] -> [self typeFor: sendNode receiver in: aTMethod].
  [#<<] -> [self typeFor: sendNode receiver in: aTMethod].
  [#addressOf:] -> [(self typeFor: sendNode receiver in: aTMethod)
  ifNil: [#sqInt]
  ifNotNil: [:type| type, (type last isLetter ifTrue: [' *'] ifFalse: ['*'])]].
  [#at:] -> [self typeForDereference: sendNode in: aTMethod].
  [#bitAnd:] -> [self typeForArithmetic: sendNode in: aTMethod].
  [#bitOr:] -> [self typeForArithmetic: sendNode in: aTMethod].
  [#bitXor:] -> [self typeForArithmetic: sendNode in: aTMethod].
  [#bitClear:] -> [self typeForArithmetic: sendNode in: aTMethod].
  [#bitInvert32] -> [#'unsigned int'].
  [#bitInvert64] -> [self promoteArithmeticTypes: (self typeFor: sendNode receiver in: aTMethod) and: #int].
  [#byteSwap32] -> [#'unsigned int'].
  [#byteSwap64] -> [#'unsigned long long'].
  [#byteSwapped32IfBigEndian:] -> [#'unsigned int'].
  [#byteSwapped64IfBigEndian:] -> [#'unsigned long long'].
  [#=] -> [#int].
  [#~=] -> [#int].
  [#==] -> [#int].
  [#~~] -> [#int].
  [#<] -> [#int].
  [#<=] -> [#int].
  [#>] -> [#int].
  [#>=] -> [#int].
  [#between:and:] -> [#int].
  [#anyMask:] -> [#int].
  [#allMask:] -> [#int].
  [#noMask:] -> [#int].
  [#isNil] -> [#int].
  [#notNil] -> [#int].
  [#&] -> [#int].
  [#|] -> [#int].
  [#not] -> [#int].
  [#asFloat] -> [#double].
  [#atan] -> [#double].
  [#exp] -> [#double].
  [#log] -> [#double].
  [#sin] -> [#double].
  [#sqrt] -> [#double].
  [#asLong] -> [#long].
  [#asInteger] -> [#sqInt].
  [#asIntegerPtr] -> [#'sqIntptr_t'].
  [#asUnsignedInteger] -> [#usqInt].
  [#asUnsignedIntegerPtr]-> [#'usqIntptr_t'].
  [#asUnsignedLong] -> [#'unsigned long'].
  [#asUnsignedLongLong] -> [#'unsigned long long'].
  [#asVoidPointer] -> [#'void *'].
  [#signedIntToLong] -> [#usqInt]. "c.f. generateSignedIntToLong:on:indent:"
  [#signedIntToShort] -> [#usqInt]. "c.f. generateSignedIntToShort:on:indent:"
  [#cCoerce:to:] -> [sendNode args last value].
  [#cCoerceSimple:to:] -> [sendNode args last value].
  [#sizeof:] -> [#'usqIntptr_t']. "Technically it's a size_t but it matches on target architectures so far..."
  [#ifTrue:ifFalse:] -> [self typeForConditional: sendNode in: aTMethod].
  [#ifFalse:ifTrue:] -> [self typeForConditional: sendNode in: aTMethod].
  [#ifTrue:] -> [self typeForConditional: sendNode in: aTMethod].
  [#ifFalse:] -> [self typeForConditional: sendNode in: aTMethod].
  [#and:] -> [#sqInt].
+ [#or:] -> [#sqInt].
+ [#caseOf:] -> [self typeFor: sendNode args first in: aTMethod] }
- [#or:] -> [#sqInt] }
  otherwise: "If there /is/ a method for sel but its return type is as yet unknown it /mustn't/ be defaulted,
  since on a subsequent pass its type may be computable.  Only default unbound selectors."
  [methodOrNil ifNotNil: [nil] ifNil: [typeIfNil]]]!

Item was changed:
  ----- Method: StackInterpreter>>printDecodeMethodHeaderOop: (in category 'printing') -----
  printDecodeMethodHeaderOop: methodHeaderOop
  self printOopShort: methodHeaderOop.
  (self methodHeaderHasPrimitive: methodHeaderOop) ifTrue:
  [self print: ' hasPrim'].
  (self methodHeaderIndicatesLargeFrame: methodHeaderOop) ifTrue:
  [self print: ' largeFrame'].
  (SistaVM and: [self isOptimizedMethodHeader: methodHeaderOop]) ifTrue:
  [self print: ' optimized'].
  (MULTIPLEBYTECODESETS and: [objectMemory integerValueOf: methodHeaderOop]) < 0 ifTrue:
  [self print: ' altSet'].
  NewspeakVM ifTrue:
+ [| s |
+ s := (self accessModifierOfMethodHeader: methodHeaderOop) caseOf: {
- [self print: ((self accessModifierOfMethodHeader: methodHeaderOop) caseOf: {
  [0] -> [' public'].
  [1] -> [' private'].
  [2] -> [' protected'].
+ [3] -> [' access undefined'] }.
+ self print: s].
- [3] -> [' access undefined'] })].
  self print: ' nLits '; printNum: (objectMemory literalCountOfMethodHeader: methodHeaderOop);
  print: ' nArgs '; printNum: (self argumentCountOfMethodHeader: methodHeaderOop);
  print: ' nTemps '; printNum: (self temporaryCountOfMethodHeader: methodHeaderOop)!

Item was added:
+ ----- Method: TBraceCaseNode>>typeOrNilFrom:in: (in category 'type inference') -----
+ typeOrNilFrom: aCodeGenerator in: aTMethod
+ | types |
+ types := Set withAll: (cases collect: [:case| case typeOrNilFrom: aCodeGenerator in: aTMethod]).
+ ^types size = 1 ifTrue: [types anyOne]!

Item was changed:
  ----- Method: TConstantNode>>typeOrNilFrom:in: (in category 'type inference') -----
  typeOrNilFrom: aCodeGenerator in: aTMethod
  "For integers, answer int unless the value does not fit into a 32bits signed int.
  In that case, answer the shortest architecture independant integer type that could hold the constant.
  This method must be consistent with CCodeGenerator>>cLiteralFor:"
  | hb |
  value isInteger
  ifTrue:
  [value positive
  ifTrue:
  [hb := value highBit.
  hb < 32 ifTrue: [^#int].
  hb = 32 ifTrue: [^#'unsigned int'].
  hb = 64 ifTrue: [^#'unsigned long long'].
  ^#'long long']
  ifFalse:
  [hb := value bitInvert highBit.
  hb < 32 ifTrue: [^#int].
  ^#'long long']].
  value isFloat ifTrue: [^#double].
  (#(nil true false) includes: value) ifTrue: [^#int].
+ (value isString and: [value isSymbol not]) ifTrue: [^#'char *'].
  ^nil!

Item was changed:
  ----- Method: TSendNode>>emitCCodeAsFunctionCallOn:level:generator: (in category 'C code generation') -----
  emitCCodeAsFunctionCallOn: aStream level: level generator: aCodeGen
-
  "Translate this message send into a C function call"
+
+ selector == #break ifTrue:
+ [aStream nextPutAll: '/* send of break elided */'.
+ ^self].
+
  "Special case for pluggable modules. Replace messages to interpreterProxy
  by interpreterProxy->message(..) if the message is not builtin"
  (aCodeGen shouldGenerateAsInterpreterProxySend: self) ifTrue:
  [(aCodeGen noteUsedPluginFunction: selector) ifTrue:
  [aStream nextPutAll: 'interpreterProxy->']].
 
- "Translate this message send into a C function call."
  aStream nextPutAll: (aCodeGen cFunctionNameFor: selector); nextPut: $(.
+
  "Only include the receiver as the first argument in certain cases.
  The receiver is always included if it is an expression.
  If it is a variable:
  If the vmClass says it is an implicit variable, don't include it.
  If the variable is 'self' and the method being called is not in
  the method set (i.e. it is some external code), don't include it."
  (self shouldExcludeReceiverAsFirstArgument: aCodeGen) ifFalse:
  [(receiver structTargetKindIn: aCodeGen) == #struct ifTrue:
  [aStream nextPut: $&].
  receiver emitCCodeOn: aStream level: level generator: aCodeGen.
  arguments isEmpty ifFalse:
  [aStream nextPutAll: ', ']].
  arguments
  do: [ :arg| arg emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen]
  separatedBy: [aStream nextPut: $,; space].
  aStream nextPut: $)!

Item was changed:
  ----- Method: TSwitchStmtNode>>emitCCodeOn:addToEndOfCases:level:generator: (in category 'C code generation') -----
  emitCCodeOn: aStream addToEndOfCases: aNodeOrNil level: level generator: aCodeGen
 
  aStream crtab: level.
  aStream nextPutAll: 'switch ('.
  expression emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen.
  aStream nextPutAll: ') {'.
  cases do:
  [:tuple|
  [:labels :case|
   labels do:
  [:label|
  aStream
  crtab: level;
  nextPutAll: 'case '.
  label emitCCodeAsArgumentOn: aStream level: level + 1 generator: aCodeGen.
  aStream nextPut: $:].
   aStream crtab: level + 1.
   case emitCCodeOn: aStream prependToEnd: aNodeOrNil level: level + 1 generator: aCodeGen]
  valueWithArguments: tuple.
   (aNodeOrNil notNil and: [aNodeOrNil isReturn]) ifFalse:
  [aStream crtab: level + 1; nextPutAll: 'break;']].
  aStream
  crtab: level;
  nextPutAll: 'default:';
  crtab: level + 1.
  otherwiseOrNil
  ifNotNil: [otherwiseOrNil emitCCodeOn: aStream prependToEnd: aNodeOrNil level: level + 1 generator: aCodeGen]
  ifNil: [aStream nextPutAll: 'error("Case not found and no otherwise clause");'.
    aNodeOrNil ifNotNil:
+ [| defaultExpr type |
+ aStream crtab: level + 1.
+ defaultExpr := TConstantNode new setValue: -1.
+ (aNodeOrNil isAssignment
+  and: [(type := aCodeGen typeFor: aNodeOrNil variable in: aCodeGen currentMethod) notNil
+  and: [aCodeGen isPointerCType: type]]) ifTrue:
+ [defaultExpr := TSendNode new
+ setSelector: #cCoerceSimple:to:
+ receiver: (TVariableNode new setName: 'self')
+ arguments: {defaultExpr. TConstantNode new setValue: type}].
+ (aNodeOrNil copy setExpression: defaultExpr)
- [aStream crtab: level + 1.
- (aNodeOrNil copy setExpression: (TConstantNode new setValue: -1))
  emitCCodeOn: aStream level: level generator: aCodeGen.
  aStream nextPut: $;]].
  aStream
  crtab: level;
  nextPut: $}!