[prev in list] [next in list] [prev in thread] [next in thread] 

List:       squeak-vm-dev
Subject:    Re: [Vm-dev] VM Maker: VMMaker.oscog-eem.2266.mcz
From:       Eliot Miranda <eliot.miranda () gmail ! com>
Date:       2017-09-16 12:21:23
Message-ID: 7524F1C8-5458-46C3-B77C-4E1BB88C544D () gmail ! com
[Download RAW message or body]

[Attachment #2 (text/plain)]

 
[Attachment #3 (multipart/alternative)]


Hi Nicolas,


> On Sep 3, 2017, at 6:38 AM, Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com> \
> wrote: 
> 
> 
> 2017-08-31 21:21 GMT+02:00 <commits@source.squeak.org>:
> > 
> > Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
> > http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2266.mcz
> > 
> > ==================== Summary ====================
> > 
> > Name: VMMaker.oscog-eem.2266
> > Author: eem
> > Time: 31 August 2017, 12:20:30.681037 pm
> > UUID: 0501d71a-3185-4bdb-a99c-76a5fbbeee22
> > Ancestors: VMMaker.oscog-eem.2265
> > 
> > Spur:
> > Simplify cleverSwapHeaders:and:copyHashFlag: via xor.
> > Fix the type of currentAllocatedBytes given the Slang changes below.
> > 
> > Slang:
> > Fix a regression caused by the Slang fixes in VMMaker.oscog-eem.2243.
> > Since inferTypesForImplicitlyTypedVariablesIn: no longer sets the types of locals \
> > as it goes along (which was incorrect) we can no longer default the types of \
> > untyped variables to sqInt for the purposes of returnTypeForSend:in:ifNil:.  To \
> > allow returnTypeForSend:in:ifNil: to answer nil for arithmetic on untyped \
> > expressions typeForArithmetic:in: uses TParseNode>>typeOrNilFrom:in: instead of \
> > CCodeGenerator>>typeFor:in: to avoid the defaulting.  returnTypeForSend:in:ifNil: \
> > has been refactored to use the more direct TParseNode>>typeFrom:in: instead of \
> > CCodeGenerator>>typeFor:in: for clarity. Teh regression caused Slang to fail to \
> > infer the types of remembered1/2 & hash1/2 in \
> > cleverSwapHeaders:and:copyHashFlag:.  The new code correctly infers the types of \
> > remembered & hashBits as sqLong. 
> 
> OK, the differences seem a bit germane at first glance, but I can try to understand \
> better: 
> So CCodeGenerator>>typeFor:in: / TParseNode>>typeFrom:in: do default to #sqInt \
> rather than nil,. This did cause a premature typing of some local variables.
> So it was better to use typeOrNilFrom:in:in some place.
> 
> But If we forget to replace some occurrence by typeOrNilFrom:in: ,
> then we might chain a type inference returning nil with with a type inference \
> returning default #sqInt value, and thus we will bypass the correct type \
> inferencing. Was it the scenario of the problem?

Yes.  (Sorry, I missed your message)

> 
> > SoundPlugin:
> > Eliminate a couple of warnings by using 0 instead of NULL.
> > 
> > =============== Diff against VMMaker.oscog-eem.2265 ===============
> > 
> > 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: (sendNode receiver typeFrom: self in: aTMethod) \
> >                 and: #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..." +       \
> > [#>>]                                   ->      [sendNode receiver typeFrom: self \
> > in: aTMethod]. +                               [#<<]                              \
> > ->      [sendNode receiver typeFrom: self in: aTMethod]. +                        \
> > [#addressOf:]                   ->      [(sendNode receiver typeFrom: self in: \
> >                 aTMethod)
> > -                               [#>>]                                   ->      \
> >                 [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: (sendNode receiver typeFrom: self in: \
> >                 aTMethod) and: #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] }
> > 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: CCodeGenerator>>typeForArithmetic:in: (in category 'type \
> >                 inference') -----
> > typeForArithmetic: sendNode in: aTMethod
> > "Answer the return type for an arithmetic sendThis is so that the inliner can \
> > still inline simple expressions.  Deal with pointer arithmetic, floating point \
> > arithmetic and promotion."
> > +       | rcvrType argType arg |
> > +       rcvrType := sendNode receiver typeOrNilFrom: self in: aTMethod.
> > +       argType := (arg := sendNode args first) typeOrNilFrom: self in: aTMethod.
> > -       | rcvrType argType arg promotedType |
> > -       rcvrType := self typeFor: sendNode receiver in: aTMethod.
> > -       argType := self typeFor: (arg := sendNode args first) in: aTMethod.
> > "deal with pointer arithmetic"
> > ((rcvrType notNil and: [rcvrType last == $*]) or: [argType notNil and: [argType \
> > last == $*]]) ifTrue: [(rcvrType isNil or: [argType isNil]) ifTrue:
> > [^nil].
> > (rcvrType last == $* and: [argType last == $*]) ifTrue:
> > [sendNode selector == #- ifTrue:
> > [^#int].
> > self error: 'invalid pointer arithmetic'].
> > ^rcvrType last == $*
> > ifTrue: [rcvrType]
> > ifFalse: [argType]].
> > +       ^(self promoteArithmeticTypes: rcvrType and: argType) ifNotNil:
> > +               [:promotedType|
> > +                "We have to be very careful with subtraction.  The difference \
> > between two unsigned types is signed. +                 But we don't want \
> > unsigned - constant to be signed.  We almost always want this to stay unsigned." \
> > +                (sendNode selector == #- and: [promotedType first == $u and: \
> > [(arg isConstant and: [arg value isInteger]) not]]) +                       \
> > ifTrue: [promotedType allButFirst: ((promotedType beginsWith: 'unsigned') ifTrue: \
> > [9] ifFalse: [1])] +                       ifFalse: [promotedType]]!
> > -       promotedType := self promoteArithmeticTypes: rcvrType and: argType.
> > -       "We have to be very careful with subtraction.  The difference between two \
> >                 unsigned types is signed.
> > -        But we don't want unsigned - constant to be signed.  We almost always \
> >                 want this to stay unsigned."
> > -       ^(sendNode selector == #- and: [promotedType first == $u and: [(arg \
> >                 isConstant and: [arg value isInteger]) not]])
> > -               ifTrue: [promotedType allButFirst: ((promotedType beginsWith: \
> >                 'unsigned') ifTrue: [9] ifFalse: [1])]
> > -               ifFalse: [promotedType]!
> > 
> > Item was changed:
> > ----- Method: SoundPlugin>>primitiveSetDefaultSoundPlayer (in category \
> > 'primitives') ----- primitiveSetDefaultSoundPlayer
> > "Tell the operating system to use the specified device name as the output device \
> > for sound." "arg at top of stack is the String"
> > > deviceName obj srcPtr sz |
> > <export: true>
> > <var: 'deviceName' declareC: 'char deviceName[257]'>
> > <var: 'srcPtr' type: #'char *'>
> > 
> > "Parse arguments"
> > interpreterProxy methodArgumentCount = 1 ifFalse:
> > [^interpreterProxy primitiveFail].
> > obj := interpreterProxy stackValue: 0.
> > (interpreterProxy isBytes: obj) ifFalse:
> > [^interpreterProxy primitiveFail].
> > (sz := interpreterProxy byteSizeOf: obj) <= 256 ifFalse:
> > [^interpreterProxy primitiveFail].
> > srcPtr := interpreterProxy firstIndexableField: obj.
> > self touch: srcPtr.
> > self touch: deviceName.
> > self touch: sz.
> > self cCode: 'strncpy(deviceName, srcPtr, sz)'.
> > +       self cCode: 'deviceName[sz] = 0'.
> > -       self cCode: 'deviceName[sz] = NULL'.
> > 
> > "do the work"
> > self cCode: 'setDefaultSoundPlayer(deviceName)'.
> > interpreterProxy failed ifFalse: "pop arg, leave receiver"
> > [interpreterProxy pop: 1]!
> > 
> > Item was changed:
> > ----- Method: SoundPlugin>>primitiveSetDefaultSoundRecorder (in category \
> > 'primitives') ----- primitiveSetDefaultSoundRecorder
> > "Tell the operating system to use the specified device name as the input device \
> > for sound." "arg at top of stack is the String"
> > > deviceName obj srcPtr sz |
> > <export: true>
> > <var: 'deviceName' declareC: 'char deviceName[257]'>
> > <var: 'srcPtr' type: #'char *'>
> > 
> > "Parse arguments"
> > interpreterProxy methodArgumentCount = 1 ifFalse:
> > [^interpreterProxy primitiveFail].
> > obj := interpreterProxy stackValue: 0.
> > (interpreterProxy isBytes: obj) ifFalse:
> > [^interpreterProxy primitiveFail].
> > (sz := interpreterProxy byteSizeOf: obj) <= 256 ifFalse:
> > [^interpreterProxy primitiveFail].
> > srcPtr := interpreterProxy firstIndexableField: obj.
> > self touch: srcPtr.
> > self touch: deviceName.
> > self touch: sz.
> > self cCode: 'strncpy(deviceName, srcPtr, sz)'.
> > +       self cCode: 'deviceName[sz] = 0'.
> > -       self cCode: 'deviceName[sz] = NULL'.
> > 
> > "do the work"
> > self cCode: 'setDefaultSoundRecorder(deviceName)'.
> > interpreterProxy failed ifFalse: "pop arg, leave receiver"
> > [interpreterProxy pop: 1]!
> > 
> > Item was changed:
> > ----- Method: SpurMemoryManager>>cleverSwapHeaders:and:copyHashFlag: (in category \
> >                 'become implementation') -----
> > cleverSwapHeaders: obj1 and: obj2 copyHashFlag: copyHashFlag
> > "swap headers, but swapping headers swaps remembered bits and hashes;
> > remembered bits must be unswapped and hashes may be unswapped if
> > copyHash is false."
> > "This variant doesn't tickle a compiler bug in gcc and clang.  See \
> > naiveSwapHeaders:and:copyHashFlag:" <inline: true>
> > +       | header1 header2 remembered |
> > -       | header1 header2 remembered1 remembered2 |
> > header1 := self long64At: obj1.
> > header2 := self long64At: obj2.
> > +       remembered := (header1 bitXor: header2) bitAnd: 1 << self \
> > rememberedBitShift. +       remembered ~= 0 ifTrue:
> > +               [header1 := header1 bitXor: remembered.
> > +                header2 := header2 bitXor: remembered].
> 
> +1 for this one, much more clever as the selector tells AND much more robust
> (previous signed arithmetic could overflow, which might work but is UB).
> 
> > -       remembered1 := header1 bitAnd: 1 << self rememberedBitShift.
> > -       remembered2 := header2 bitAnd: 1 << self rememberedBitShift.
> > -       remembered1 ~= remembered2 ifTrue:
> > -               [header1 := header1 - remembered1 + remembered2.
> > -                header2 := header2 - remembered2 + remembered1].
> > "swapping headers swaps hash; if not copyHashFlag then unswap hash"
> > copyHashFlag ifFalse:
> > +               [| hashBits |
> > +                hashBits := (header1 bitXor: header2) bitAnd: self \
> > identityHashFullWordMask. +                hashBits ~= 0 ifTrue:
> > +                       [header1 := header1 bitXor: hashBits.
> > +                        header2 := header2 bitXor: hashBits]].
> > -               [| hash1 hash2 |
> > -                hash1 := header1 bitAnd: self identityHashFullWordMask.
> > -                hash2 := header2 bitAnd: self identityHashFullWordMask.
> > -                hash1 ~= hash2 ifTrue:
> > -                       [header1 := header1 - hash1 + hash2.
> > -                        header2 := header2 - hash2 + hash1]].
> > self long64At: obj1 put: header2.
> > self long64At: obj2 put: header1!
> > 
> > Item was changed:
> > ----- Method: SpurMemoryManager>>currentAllocatedBytes (in category 'allocation \
> > accounting') ----- currentAllocatedBytes
> > "Compute the current allocated bytes since last set.
> > This is the cumulative total in statAllocatedBytes plus the allocation since the \
> > last scavenge." | use |
> > +       "Slang infers the type of the difference between two unsigned variables \
> > as signed. +        In this case we want it to be unsigned."
> > +       <var: 'use' type: #usqInt>
> > use := segmentManager totalOldSpaceCapacity - totalFreeOldSpace.
> > ^statAllocatedBytes
> > + (freeStart - scavenger eden start)
> > + (use - oldSpaceUsePriorToScavenge)!
> > 
> 


[Attachment #6 (text/html)]

<html><head><meta http-equiv="content-type" content="text/html; \
charset=utf-8"></head><body dir="auto"><div>Hi Nicolas,<br><br></div><div><br>On Sep \
3, 2017, at 6:38 AM, Nicolas Cellier &lt;<a \
href="mailto:nicolas.cellier.aka.nice@gmail.com">nicolas.cellier.aka.nice@gmail.com</a>&gt; \
wrote:<br><br></div><blockquote \
type="cite"><div><span></span></div></blockquote><blockquote type="cite"><div><div \
dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2017-08-31 21:21 \
GMT+02:00  <span dir="ltr">&lt;<a href="mailto:commits@source.squeak.org" \
target="_blank">commits@source.squeak.org</a>&gt;</span>:<br><blockquote \
class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid \
rgb(204,204,204);padding-left:1ex"><br> Eliot Miranda uploaded a new version of \
VMMaker to project VM Maker:<br> <a \
href="http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2266.mcz" rel="noreferrer" \
target="_blank">http://source.squeak.org/VMMak<wbr>er/VMMaker.oscog-eem.2266.mcz</a><br>
 <br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-eem.2266<br>
Author: eem<br>
Time: 31 August 2017, 12:20:30.681037 pm<br>
UUID: 0501d71a-3185-4bdb-a99c-76a5fb<wbr>beee22<br>
Ancestors: VMMaker.oscog-eem.2265<br>
<br>
Spur:<br>
Simplify cleverSwapHeaders:and:copyHash<wbr>Flag: via xor.<br>
Fix the type of currentAllocatedBytes given the Slang changes below.<br>
<br>
Slang:<br>
Fix a regression caused by the Slang fixes in VMMaker.oscog-eem.2243.<br>
Since inferTypesForImplicitlyTypedVa<wbr>riablesIn: no longer sets the types of \
locals as it goes along (which was incorrect) we can no longer default the types of \
untyped variables to sqInt for the purposes of returnTypeForSend:in:ifNil:.&nbsp; To \
allow returnTypeForSend:in:ifNil: to answer nil for arithmetic on untyped expressions \
typeForArithmetic:in: uses TParseNode&gt;&gt;typeOrNilFrom:in: instead of \
CCodeGenerator&gt;&gt;typeFor:in: to avoid the defaulting.&nbsp; \
returnTypeForSend:in:ifNil: has been refactored to use the more direct \
TParseNode&gt;&gt;typeFrom:in: instead of CCodeGenerator&gt;&gt;typeFor:in: for \
clarity.<br> Teh regression caused Slang to fail to infer the types of remembered1/2 \
&amp; hash1/2 in cleverSwapHeaders:and:copyHash<wbr>Flag:.&nbsp; The new code \
correctly infers the types of remembered &amp; hashBits as sqLong.<br> \
<br></blockquote><div><br></div><div>OK, the differences seem a bit germane at first \
glance, but I can try to understand better:<br></div><div><br></div><div>So \
CCodeGenerator&gt;&gt;typeFor:in: / TParseNode&gt;&gt;typeFrom:in: do default to \
#sqInt rather than nil,.</div><div>This did cause a premature typing of some local \
variables.</div><div>So it was better to use typeOrNilFrom:in:in some \
place.<br></div><div><br></div><div>But If we forget to replace some occurrence by \
typeOrNilFrom:in: ,</div><div>then we might chain a type inference returning nil with \
with a type inference returning default #sqInt value,</div><div>and thus we will \
bypass the correct type inferencing.</div><div>Was it the scenario of the \
problem?<br></div></div></div></div></div></blockquote><div><br></div>Yes. \
&nbsp;(Sorry, I missed your message)<div><br><blockquote type="cite"><div><div \
dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> \
<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px \
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> SoundPlugin:<br>
Eliminate a couple of warnings by using 0 instead of NULL.<br>
<br>
=============== Diff against VMMaker.oscog-eem.2265 ===============<br>
<br>
Item was changed:<br>
&nbsp; ----- Method: CCodeGenerator&gt;&gt;returnTypeForS<wbr>end:in:ifNil: (in \
category 'type inference') -----<br> &nbsp; returnTypeForSend: sendNode in: aTMethod \
ifNil: typeIfNil<br> &nbsp; &nbsp; &nbsp; &nbsp; "Answer the return type for a \
send.&nbsp; Unbound sends default to typeIfNil.<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;Methods with types as yet unknown have a type determined either by the<br> \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;kernelReturnTypes or the table below, or, if they \
are in neither set, then nil.<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;The inferred type \
should match as closely as possible the C type of<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;generated expessions so that inlining would not change the expression.<br> \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If there is a method for sel but its return type is \
as yet unknown it mustn't<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;be defaulted, since \
on a subsequent pass its type may be computable."<br> &nbsp; &nbsp; &nbsp; &nbsp; | \
sel methodOrNil |<br> &nbsp; &nbsp; &nbsp; &nbsp; methodOrNil := self anyMethodNamed: \
(sel := sendNode selector).<br> &nbsp; &nbsp; &nbsp; &nbsp; (methodOrNil notNil and: \
[methodOrNil returnType notNil]) ifTrue:<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; [^self baseTypeForType: methodOrNil returnType].<br> &nbsp; \
&nbsp; &nbsp; &nbsp; ^kernelReturnTypes<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; at: sel<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
ifAbsent:<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; [sel<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; caseOf: {<br> &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; [#integerValueOf:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; \
&nbsp; &nbsp; [#sqInt].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#isIntegerObject:]&nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#int].<br> \
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;[#negated]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; \
[self promoteArithmeticTypes: (sendNode receiver typeFrom: self in: aTMethod) and: \
                #int].<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;[#negated]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; \
[self promoteArithmeticTypes: (self typeFor: sendNode receiver in: aTMethod) and: \
#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#+]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; -&gt;&nbsp; &nbsp; &nbsp; [self typeForArithmetic: sendNode in: aTMethod].<br> \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; [#-]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [self typeForArithmetic: sendNode in: \
aTMethod].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#*]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; -&gt;&nbsp; &nbsp; &nbsp; [self typeForArithmetic: sendNode in: aTMethod].<br> \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; [#/]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [self typeForArithmetic: sendNode in: \
aTMethod].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#//]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;-&gt;&nbsp; &nbsp; &nbsp; [self typeForArithmetic: sendNode in: aTMethod].<br> \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; [#\\]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;-&gt;&nbsp; &nbsp; &nbsp; [self typeForArithmetic: sendNode in: aTMethod].<br> \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; [#rem:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; \
&nbsp; &nbsp; [self typeForArithmetic: sendNode in: aTMethod].<br> &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; [#quo:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; \
[self typeForArithmetic: sendNode in: aTMethod].<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
"C99 Sec Bitwise shift operators ... 3 Sematics ...<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;The integer promotions are performed on each of the operands. The type of the \
result is that of the promoted left operand..."<br> +&nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;[#&gt;&gt;]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; \
&nbsp; [sendNode receiver typeFrom: self in: aTMethod].<br> +&nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;[#&lt;&lt;]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; \
&nbsp; [sendNode receiver typeFrom: self in: aTMethod].<br> +&nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;[#addressOf:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
                &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [(sendNode receiver typeFrom: self \
                in: aTMethod)<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;[#&gt;&gt;]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
                &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [self typeFor: sendNode receiver in: \
                aTMethod].<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;[#&lt;&lt;]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
                &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [self typeFor: sendNode receiver in: \
                aTMethod].<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;[#addressOf:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [(self typeFor: sendNode \
receiver in: aTMethod)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; ifNil: [#sqInt]<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ifNotNil: [:type| type, (type last \
isLetter ifTrue: [' *'] ifFalse: ['*'])]].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#at:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [self \
typeForDereference: sendNode in: aTMethod].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#bitAnd:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [self typeForArithmetic: \
sendNode in: aTMethod].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#bitOr:]&nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;-&gt;&nbsp; &nbsp; &nbsp; [self typeForArithmetic: sendNode in: aTMethod].<br> \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; [#bitXor:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; \
&nbsp; [self typeForArithmetic: sendNode in: aTMethod].<br> &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; [#bitClear:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [self typeForArithmetic: \
sendNode in: aTMethod].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#bitInvert32]&nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; \
[#'unsigned int'].<br> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[#bitInvert64]&nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [self \
promoteArithmeticTypes: (sendNode receiver typeFrom: self in: aTMethod) and: \
                #int].<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;[#bitInvert64]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [self promoteArithmeticTypes: (self \
typeFor: sendNode receiver in: aTMethod) and: #int].<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#byteSwap32]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#'unsigned int'].<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#byteSwap64]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#'unsigned long long'].<br> &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; [#byteSwapped32IfBigEndian:]&nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; \
[#'unsigned int'].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#byteSwapped64IfBigEndian:]&nbsp; \
&nbsp; -&gt;&nbsp; &nbsp; &nbsp; [#'unsigned long long'].<br> &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; [#=]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; \
[#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#~=]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#==]&nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#int].<br> &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; [#~~]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; \
&nbsp; [#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#&lt;]&nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#&lt;=]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#int].<br> \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; [#&gt;]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
-&gt;&nbsp; &nbsp; &nbsp; [#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#&gt;=]&nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#int].<br> &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; [#between:and:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; \
&nbsp; [#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#anyMask:]&nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#allMask:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#int].<br> &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; [#noMask:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; \
[#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#isNil]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [#int].<br> &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; [#notNil]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#int].<br> &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; [#&amp;]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; \
&nbsp; &nbsp; [#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#|]&nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; \
[#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#not]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
-&gt;&nbsp; &nbsp; &nbsp; [#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#asFloat]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [#double].<br> &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; [#atan]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; \
&nbsp; [#double].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#exp]&nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; -&gt;&nbsp; &nbsp; &nbsp; [#double].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#log]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [#double].<br> \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; [#sin]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; \
&nbsp; &nbsp; [#double].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#sqrt]&nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#double].<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#asLong]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#long].<br> &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; [#asInteger]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [#sqInt].<br> &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; [#asIntegerPtr]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#'sqIntptr_t'].<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#asUnsignedInteger]&nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [#usqInt].<br> &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; [#asUnsignedIntegerPtr]-&gt;&nbsp; &nbsp; &nbsp; \
&nbsp;[#'usqIntptr_t'].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#asUnsignedLong]&nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#'unsigned \
long'].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#asUnsignedLongLong]&nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#'unsigned long long'].<br> &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; [#asVoidPointer]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; -&gt;&nbsp; &nbsp; &nbsp; [#'void *'].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#signedIntToLong]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; \
&nbsp; [#usqInt]. "c.f. generateSignedIntToLong:on:ind<wbr>ent:"<br> &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; [#signedIntToShort]&nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; \
[#usqInt]. "c.f. generateSignedIntToShort:on:in<wbr>dent:"<br> &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; [#cCoerce:to:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
-&gt;&nbsp; &nbsp; &nbsp; [sendNode args last value].<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#cCoerceSimple:to:]&nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [sendNode args last \
value].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#sizeof:]&nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
-&gt;&nbsp; &nbsp; &nbsp; [#'usqIntptr_t']. "Technically it's a size_t but it matches \
on target architectures so far..."<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#ifTrue:ifFalse:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; \
&nbsp; [self typeForConditional: sendNode in: aTMethod].<br> &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; [#ifFalse:ifTrue:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; \
&nbsp; &nbsp; [self typeForConditional: sendNode in: aTMethod].<br> &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; [#ifTrue:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [self \
typeForConditional: sendNode in: aTMethod].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#ifFalse:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [self typeForConditional: \
sendNode in: aTMethod].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [#and:]&nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp;-&gt;&nbsp; &nbsp; &nbsp; [#sqInt].<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[#or:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; &nbsp; [#sqInt].<br> \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; [#caseOf:]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;&nbsp; &nbsp; \
&nbsp; [self typeFor: sendNode args first in: aTMethod] }<br> &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; otherwise: "If there /is/ a method for sel but its return type is as yet \
unknown it /mustn't/ be defaulted,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; since on a \
subsequent pass its type may be computable.&nbsp; Only default unbound \
selectors."<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [methodOrNil \
ifNotNil: [nil] ifNil: [typeIfNil]]]!<br> <br>
Item was changed:<br>
&nbsp; ----- Method: CCodeGenerator&gt;&gt;typeForArithme<wbr>tic:in: (in category \
'type inference') -----<br> &nbsp; typeForArithmetic: sendNode in: aTMethod<br>
&nbsp; &nbsp; &nbsp; &nbsp; "Answer the return type for an arithmetic sendThis is so \
that the inliner can still<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;inline simple \
expressions.&nbsp; Deal with pointer arithmetic, floating point arithmetic<br> &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;and promotion."<br> +&nbsp; &nbsp; &nbsp; &nbsp;| rcvrType \
argType arg |<br> +&nbsp; &nbsp; &nbsp; &nbsp;rcvrType := sendNode receiver \
typeOrNilFrom: self in: aTMethod.<br> +&nbsp; &nbsp; &nbsp; &nbsp;argType := (arg := \
                sendNode args first) typeOrNilFrom: self in: aTMethod.<br>
-&nbsp; &nbsp; &nbsp; &nbsp;| rcvrType argType arg promotedType |<br>
-&nbsp; &nbsp; &nbsp; &nbsp;rcvrType := self typeFor: sendNode receiver in: \
                aTMethod.<br>
-&nbsp; &nbsp; &nbsp; &nbsp;argType := self typeFor: (arg := sendNode args first) in: \
aTMethod.<br> &nbsp; &nbsp; &nbsp; &nbsp; "deal with pointer arithmetic"<br>
&nbsp; &nbsp; &nbsp; &nbsp; ((rcvrType notNil and: [rcvrType last == $*]) or: \
[argType notNil and: [argType last == $*]]) ifTrue:<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; [(rcvrType isNil or: [argType isNil]) ifTrue:<br> &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[^nil].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(rcvrType \
last == $* and: [argType last == $*]) ifTrue:<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [sendNode selector == #- ifTrue:<br> \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; [^#int].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;self error: 'invalid pointer \
arithmetic'].<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;^rcvrType last == $*<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ifTrue: [rcvrType]<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ifFalse: [argType]].<br> \
+&nbsp; &nbsp; &nbsp; &nbsp;^(self promoteArithmeticTypes: rcvrType and: argType) \
ifNotNil:<br> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;[:promotedType|<br> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
"We have to be very careful with subtraction.&nbsp; The difference between two \
unsigned types is signed.<br> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp;But we don't want unsigned - constant to be signed.&nbsp; We almost \
always want this to stay unsigned."<br> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; (sendNode selector == #- and: [promotedType first == $u and: [(arg \
isConstant and: [arg value isInteger]) not]])<br> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ifTrue: [promotedType allButFirst: \
((promotedType beginsWith: 'unsigned') ifTrue: [9] ifFalse: [1])]<br> +&nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ifFalse: \
                [promotedType]]!<br>
-&nbsp; &nbsp; &nbsp; &nbsp;promotedType := self promoteArithmeticTypes: rcvrType \
                and: argType.<br>
-&nbsp; &nbsp; &nbsp; &nbsp;"We have to be very careful with subtraction.&nbsp; The \
                difference between two unsigned types is signed.<br>
-&nbsp; &nbsp; &nbsp; &nbsp; But we don't want unsigned - constant to be \
                signed.&nbsp; We almost always want this to stay unsigned."<br>
-&nbsp; &nbsp; &nbsp; &nbsp;^(sendNode selector == #- and: [promotedType first == $u \
                and: [(arg isConstant and: [arg value isInteger]) not]])<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ifTrue: [promotedType \
                allButFirst: ((promotedType beginsWith: 'unsigned') ifTrue: [9] \
                ifFalse: [1])]<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ifFalse: [promotedType]!<br>
<br>
Item was changed:<br>
&nbsp; ----- Method: SoundPlugin&gt;&gt;primitiveSetDefau<wbr>ltSoundPlayer (in \
category 'primitives') -----<br> &nbsp; primitiveSetDefaultSoundPlayer<br>
&nbsp; &nbsp; &nbsp; &nbsp; "Tell the operating system to use the specified device \
name as the output device for sound."<br> &nbsp; &nbsp; &nbsp; &nbsp; "arg at top of \
stack is the String"<br> &nbsp; &nbsp; &nbsp; &nbsp; | deviceName obj srcPtr sz |<br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;export: true&gt;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;var: 'deviceName' declareC: 'char \
deviceName[257]'&gt;<br> &nbsp; &nbsp; &nbsp; &nbsp; &lt;var: 'srcPtr' type: #'char \
*'&gt;<br> <br>
&nbsp; &nbsp; &nbsp; &nbsp; "Parse arguments"<br>
&nbsp; &nbsp; &nbsp; &nbsp; interpreterProxy methodArgumentCount = 1 ifFalse:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [^interpreterProxy \
primitiveFail].<br> &nbsp; &nbsp; &nbsp; &nbsp; obj := interpreterProxy stackValue: \
0.<br> &nbsp; &nbsp; &nbsp; &nbsp; (interpreterProxy isBytes: obj) ifFalse:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [^interpreterProxy \
primitiveFail].<br> &nbsp; &nbsp; &nbsp; &nbsp; (sz := interpreterProxy byteSizeOf: \
obj) &lt;= 256 ifFalse:<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[^interpreterProxy primitiveFail].<br> &nbsp; &nbsp; &nbsp; &nbsp; srcPtr := \
interpreterProxy firstIndexableField: obj.<br> &nbsp; &nbsp; &nbsp; &nbsp; self \
touch: srcPtr.<br> &nbsp; &nbsp; &nbsp; &nbsp; self touch: deviceName.<br>
&nbsp; &nbsp; &nbsp; &nbsp; self touch: sz.<br>
&nbsp; &nbsp; &nbsp; &nbsp; self cCode: 'strncpy(deviceName, srcPtr, sz)'.<br>
+&nbsp; &nbsp; &nbsp; &nbsp;self cCode: 'deviceName[sz] = 0'.<br>
-&nbsp; &nbsp; &nbsp; &nbsp;self cCode: 'deviceName[sz] = NULL'.<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; "do the work"<br>
&nbsp; &nbsp; &nbsp; &nbsp; self cCode: 'setDefaultSoundPlayer(deviceN<wbr>ame)'.<br>
&nbsp; &nbsp; &nbsp; &nbsp; interpreterProxy failed ifFalse: "pop arg, leave \
receiver"<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[interpreterProxy pop: 1]!<br> <br>
Item was changed:<br>
&nbsp; ----- Method: SoundPlugin&gt;&gt;primitiveSetDefau<wbr>ltSoundRecorder (in \
category 'primitives') -----<br> &nbsp; primitiveSetDefaultSoundRecord<wbr>er<br>
&nbsp; &nbsp; &nbsp; &nbsp; "Tell the operating system to use the specified device \
name as the input device for sound."<br> &nbsp; &nbsp; &nbsp; &nbsp; "arg at top of \
stack is the String"<br> &nbsp; &nbsp; &nbsp; &nbsp; | deviceName obj srcPtr sz |<br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;export: true&gt;<br>
&nbsp; &nbsp; &nbsp; &nbsp; &lt;var: 'deviceName' declareC: 'char \
deviceName[257]'&gt;<br> &nbsp; &nbsp; &nbsp; &nbsp; &lt;var: 'srcPtr' type: #'char \
*'&gt;<br> <br>
&nbsp; &nbsp; &nbsp; &nbsp; "Parse arguments"<br>
&nbsp; &nbsp; &nbsp; &nbsp; interpreterProxy methodArgumentCount = 1 ifFalse:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [^interpreterProxy \
primitiveFail].<br> &nbsp; &nbsp; &nbsp; &nbsp; obj := interpreterProxy stackValue: \
0.<br> &nbsp; &nbsp; &nbsp; &nbsp; (interpreterProxy isBytes: obj) ifFalse:<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [^interpreterProxy \
primitiveFail].<br> &nbsp; &nbsp; &nbsp; &nbsp; (sz := interpreterProxy byteSizeOf: \
obj) &lt;= 256 ifFalse:<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
[^interpreterProxy primitiveFail].<br> &nbsp; &nbsp; &nbsp; &nbsp; srcPtr := \
interpreterProxy firstIndexableField: obj.<br> &nbsp; &nbsp; &nbsp; &nbsp; self \
touch: srcPtr.<br> &nbsp; &nbsp; &nbsp; &nbsp; self touch: deviceName.<br>
&nbsp; &nbsp; &nbsp; &nbsp; self touch: sz.<br>
&nbsp; &nbsp; &nbsp; &nbsp; self cCode: 'strncpy(deviceName, srcPtr, sz)'.<br>
+&nbsp; &nbsp; &nbsp; &nbsp;self cCode: 'deviceName[sz] = 0'.<br>
-&nbsp; &nbsp; &nbsp; &nbsp;self cCode: 'deviceName[sz] = NULL'.<br>
<br>
&nbsp; &nbsp; &nbsp; &nbsp; "do the work"<br>
&nbsp; &nbsp; &nbsp; &nbsp; self cCode: \
'setDefaultSoundRecorder(devic<wbr>eName)'.<br> &nbsp; &nbsp; &nbsp; &nbsp; \
interpreterProxy failed ifFalse: "pop arg, leave receiver"<br> &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [interpreterProxy pop: 1]!<br> <br>
Item was changed:<br>
&nbsp; ----- Method: \
SpurMemoryManager&gt;&gt;cleverSwapH<wbr>eaders:and:copyHashFlag: (in category \
'become implementation') -----<br> &nbsp; cleverSwapHeaders: obj1 and: obj2 \
copyHashFlag: copyHashFlag<br> &nbsp; &nbsp; &nbsp; &nbsp; "swap headers, but \
swapping headers swaps remembered bits and hashes;<br> &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp;remembered bits must be unswapped and hashes may be unswapped if<br> &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp;copyHash is false."<br> &nbsp; &nbsp; &nbsp; &nbsp; "This \
variant doesn't tickle a compiler bug in gcc and clang.&nbsp; See \
naiveSwapHeaders:and:copyHashF<wbr>lag:"<br> &nbsp; &nbsp; &nbsp; &nbsp; &lt;inline: \
true&gt;<br> +&nbsp; &nbsp; &nbsp; &nbsp;| header1 header2 remembered |<br>
-&nbsp; &nbsp; &nbsp; &nbsp;| header1 header2 remembered1 remembered2 |<br>
&nbsp; &nbsp; &nbsp; &nbsp; header1 := self long64At: obj1.<br>
&nbsp; &nbsp; &nbsp; &nbsp; header2 := self long64At: obj2.<br>
+&nbsp; &nbsp; &nbsp; &nbsp;remembered := (header1 bitXor: header2) bitAnd: 1 \
&lt;&lt; self rememberedBitShift.<br> +&nbsp; &nbsp; &nbsp; &nbsp;remembered ~= 0 \
ifTrue:<br> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[header1 := \
header1 bitXor: remembered.<br> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; header2 := header2 bitXor: remembered].<br></blockquote><div><br></div><div>+1 \
for this one, much more clever as the selector tells AND much more \
robust</div><div>(previous signed arithmetic could overflow, which might work but is \
UB).</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px \
                0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
-&nbsp; &nbsp; &nbsp; &nbsp;remembered1 := header1 bitAnd: 1 &lt;&lt; self \
                rememberedBitShift.<br>
-&nbsp; &nbsp; &nbsp; &nbsp;remembered2 := header2 bitAnd: 1 &lt;&lt; self \
                rememberedBitShift.<br>
-&nbsp; &nbsp; &nbsp; &nbsp;remembered1 ~= remembered2 ifTrue:<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[header1 := header1 - \
                remembered1 + remembered2.<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; header2 := header2 - \
remembered2 + remembered1].<br> &nbsp; &nbsp; &nbsp; &nbsp; "swapping headers swaps \
hash; if not copyHashFlag then unswap hash"<br> &nbsp; &nbsp; &nbsp; &nbsp; \
copyHashFlag ifFalse:<br> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[| \
hashBits |<br> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hashBits := \
(header1 bitXor: header2) bitAnd: self identityHashFullWordMask.<br> +&nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hashBits ~= 0 ifTrue:<br> +&nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[header1 := \
header1 bitXor: hashBits.<br> +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
                &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; header2 := header2 bitXor: \
                hashBits]].<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[| hash1 hash2 |<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hash1 := header1 bitAnd: \
                self identityHashFullWordMask.<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hash2 := header2 bitAnd: \
                self identityHashFullWordMask.<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hash1 ~= hash2 ifTrue:<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
                &nbsp;[header1 := header1 - hash1 + hash2.<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
header2 := header2 - hash2 + hash1]].<br> &nbsp; &nbsp; &nbsp; &nbsp; self long64At: \
obj1 put: header2.<br> &nbsp; &nbsp; &nbsp; &nbsp; self long64At: obj2 put: \
header1!<br> <br>
Item was changed:<br>
&nbsp; ----- Method: SpurMemoryManager&gt;&gt;currentAllo<wbr>catedBytes (in category \
'allocation accounting') -----<br> &nbsp; currentAllocatedBytes<br>
&nbsp; &nbsp; &nbsp; &nbsp; "Compute the current allocated bytes since last set.<br>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;This is the cumulative total in statAllocatedBytes \
plus the allocation since the last scavenge."<br> &nbsp; &nbsp; &nbsp; &nbsp; | use \
|<br> +&nbsp; &nbsp; &nbsp; &nbsp;"Slang infers the type of the difference between \
two unsigned variables as signed.<br> +&nbsp; &nbsp; &nbsp; &nbsp; In this case we \
want it to be unsigned."<br> +&nbsp; &nbsp; &nbsp; &nbsp;&lt;var: 'use' type: \
#usqInt&gt;<br> &nbsp; &nbsp; &nbsp; &nbsp; use := segmentManager \
totalOldSpaceCapacity - totalFreeOldSpace.<br> &nbsp; &nbsp; &nbsp; &nbsp; \
^statAllocatedBytes<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ (freeStart - scavenger \
eden start)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ (use - \
oldSpaceUsePriorToScavenge)!<br> <br>
</blockquote></div><br></div></div>
</div></blockquote></div></body></html>



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic