<div dir="ltr">JIT builds still <a href="https://travis-ci.org/newspeaklanguage/nsvm-linux-ci/jobs/96659717">failing</a>.<div><br></div>/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c: In function ‘genNSSendnumArgsdepthsendTable’:<br>/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c:23996:15: warning: assignment makes integer from pointer without a cast [enabled by default]<div>/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c:23997:10: error: called object ‘selector’ is not a function<br>/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c:23998:9: error: called object ‘numArgs’ is not a function<br>/home/travis/build/newspeaklanguage/nsvm-linux-ci/oscogvm/nsspursrc/vm/cogitIA32.c:23999:7: error: called object ‘depth’ is not a function</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Dec 13, 2015 at 5:25 PM, <span dir="ltr"><<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;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.1594.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1594.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-eem.1594<br>
Author: eem<br>
Time: 13 December 2015, 5:24:57.076 pm<br>
UUID: 79da8b81-d1f3-469a-869c-16c79d12649a<br>
Ancestors: VMMaker.oscog-eem.1593<br>
<br>
Cogit:<br>
Don't inline AndCq:R:R: because its translation contains a jump and hence won't work in a statement list expression (e.g. as in x86's genJumpSmallInteger:scratchReg:).<br>
<br>
Nuke genJump[Not]SmallInteger:scratch: in favour of genJump[Not]SmallInteger:scratchReg:<br>
<br>
Slang:<br>
Eliminate leaves in statement lists generated as expressions.<br>
<br>
=============== Diff against VMMaker.oscog-eem.1593 ===============<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentation>>genJumpNotSmallInteger:scratch: (in category 'compile abstract instructions') -----<br>
- genJumpNotSmallInteger: aRegister scratch: scratchReg<br>
- "Generate a test for aRegister containing a SmallInteger and a jump if not, answering the jump.<br>
- If necessary use scratch reg (since testing for SmallInteger may be destructive)."<br>
- <returnTypeC: #'AbstractInstruction *'><br>
- | jumpNotInt |<br>
- <inline: true><br>
- <var: 'jumpNotInt' type: #'AbstractInstruction *'><br>
- jumpNotInt := self genJumpNotSmallInteger: aRegister.<br>
- jumpNotInt asInteger = UnimplementedOperation ifTrue:<br>
- [cogit MoveR: aRegister R: scratchReg.<br>
- jumpNotInt := self genJumpNotSmallIntegerInScratchReg: TempReg].<br>
- ^jumpNotInt!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genJumpNotSmallInteger:scratchReg: (in category 'compile abstract instructions') -----<br>
genJumpNotSmallInteger: aRegister scratchReg: scratch<br>
"Generate a compare and branch to test if aRegister contains other than a SmallInteger.<br>
Answer the jump. Use scratch if required. Subclasses will override if scratch is needed."<br>
+ <inline: true><br>
- <returnTypeC: #'AbstractInstruction *'><br>
^self genJumpNotSmallInteger: aRegister!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentation>>genJumpSmallInteger:scratch: (in category 'compile abstract instructions') -----<br>
- genJumpSmallInteger: aRegister scratch: scratchReg<br>
- "Generate a test for aRegister containing a SmallInteger and a jump if so, answering the jump.<br>
- If necessary use scratch reg (since testing for SmallInteger may be destructive)."<br>
- <returnTypeC: #'AbstractInstruction *'><br>
- | jumpInt |<br>
- <inline: true><br>
- <var: 'jumpInt' type: #'AbstractInstruction *'><br>
- jumpInt := self genJumpSmallInteger: aRegister.<br>
- jumpInt asInteger = UnimplementedOperation ifTrue:<br>
- [cogit MoveR: aRegister R: scratchReg.<br>
- jumpInt := self genJumpSmallIntegerInScratchReg: TempReg].<br>
- ^jumpInt!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genJumpSmallInteger:scratchReg: (in category 'compile abstract instructions') -----<br>
genJumpSmallInteger: aRegister scratchReg: scratch<br>
"Generate a compare and branch to test if aRegister contains a SmallInteger.<br>
Answer the jump. Use scratch if required. Subclasses will override if scratch is needed."<br>
- <returnTypeC: #'AbstractInstruction *'><br>
^self genJumpSmallInteger: aRegister!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveAt: (in category 'primitive generators') -----<br>
genInnerPrimitiveAt: retNoffset<br>
"Implement the guts of primitiveAt"<br>
| formatReg convertToIntAndReturn<br>
jumpNotIndexable jumpImmediate jumpBadIndex<br>
jumpIsBytes jumpIsShorts jumpIsWords jumpWordTooBig jumpIsArray jumpHasFixedFields jumpIsContext<br>
jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds |<br>
<inline: true><br>
"c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"<br>
<var: #jumpIsBytes type: #'AbstractInstruction *'><br>
<var: #jumpIsShorts type: #'AbstractInstruction *'><br>
<var: #jumpBadIndex type: #'AbstractInstruction *'><br>
<var: #jumpIsContext type: #'AbstractInstruction *'><br>
<var: #jumpImmediate type: #'AbstractInstruction *'><br>
<var: #jumpWordTooBig type: #'AbstractInstruction *'><br>
<var: #jumpNotIndexable type: #'AbstractInstruction *'><br>
<var: #jumpHasFixedFields type: #'AbstractInstruction *'><br>
<var: #convertToIntAndReturn type: #'AbstractInstruction *'><br>
<var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'><br>
<var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'><br>
<var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'><br>
<var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'><br>
<var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'><br>
<br>
jumpImmediate := self genJumpImmediate: ReceiverResultReg.<br>
cogit MoveR: Arg0Reg R: Arg1Reg.<br>
+ jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.<br>
- jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.<br>
self genConvertSmallIntegerToIntegerInReg: Arg1Reg.<br>
cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"<br>
<br>
"formatReg := self formatOf: ReceiverResultReg"<br>
self genGetFormatOf: ReceiverResultReg<br>
into: (formatReg := SendNumArgsReg)<br>
leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.<br>
<br>
self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.<br>
<br>
"dispatch on format in a combination of highest dynamic frequency order first and convenience.<br>
0 = 0 sized objects (UndefinedObject True False et al)<br>
1 = non-indexable objects with inst vars (Point et al)<br>
2 = indexable objects with no inst vars (Array et al)<br>
3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)<br>
4 = weak indexable objects with inst vars (WeakArray et al)<br>
5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)<br>
6 unused, reserved for exotic pointer objects?<br>
7 Forwarded Object, 1st field is pointer, rest of fields are ignored<br>
8 unused, reserved for exotic non-pointer objects?<br>
9 (?) 64-bit indexable<br>
10 - 11 32-bit indexable<br>
12 - 15 16-bit indexable<br>
16 - 23 byte indexable<br>
24 - 31 compiled method"<br>
cogit CmpCq: objectMemory firstByteFormat R: formatReg.<br>
jumpIsBytes := cogit JumpAboveOrEqual: 0.<br>
cogit CmpCq: objectMemory arrayFormat R: formatReg.<br>
jumpIsArray := cogit JumpZero: 0.<br>
jumpNotIndexable := cogit JumpBelow: 0.<br>
cogit CmpCq: objectMemory weakArrayFormat R: formatReg.<br>
jumpHasFixedFields := cogit JumpBelowOrEqual: 0.<br>
cogit CmpCq: objectMemory firstShortFormat R: formatReg.<br>
jumpIsShorts := cogit JumpAboveOrEqual: 0.<br>
cogit CmpCq: objectMemory firstLongFormat R: formatReg.<br>
jumpIsWords := cogit JumpAboveOrEqual: 0.<br>
"For now ignore 64-bit indexability."<br>
jumpNotIndexable jmpTarget: cogit Label.<br>
jumpNotIndexable := cogit Jump: 0.<br>
<br>
jumpIsBytes jmpTarget:<br>
(cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).<br>
cogit AndCq: objectMemory wordSize - 1 R: formatReg.<br>
cogit SubR: formatReg R: ClassReg;<br>
CmpR: Arg1Reg R: ClassReg.<br>
jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.<br>
cogit backEnd byteReadsZeroExtend<br>
ifTrue:<br>
[cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg]<br>
ifFalse:<br>
[cogit "formatReg already contains a value <= 16r1f, so no need to zero it"<br>
MoveXbr: Arg1Reg R: ReceiverResultReg R: formatReg;<br>
MoveR: formatReg R: ReceiverResultReg].<br>
convertToIntAndReturn := cogit Label.<br>
self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.<br>
cogit RetN: retNoffset.<br>
<br>
jumpIsShorts jmpTarget:<br>
(cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).<br>
cogit AndCq: 1 R: formatReg.<br>
cogit SubR: formatReg R: ClassReg;<br>
CmpR: Arg1Reg R: ClassReg.<br>
jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
cogit AddR: Arg1Reg R: ReceiverResultReg.<br>
cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.<br>
cogit Jump: convertToIntAndReturn.<br>
<br>
jumpIsWords jmpTarget:<br>
(cogit CmpR: Arg1Reg R: ClassReg).<br>
jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.<br>
cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: TempReg.<br>
cogit SubCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.<br>
jumpWordTooBig := self jumpNotSmallIntegerUnsignedValueInRegister: TempReg.<br>
cogit MoveR: TempReg R: ReceiverResultReg.<br>
cogit Jump: convertToIntAndReturn.<br>
<br>
jumpHasFixedFields jmpTarget:<br>
(cogit AndCq: objectMemory classIndexMask R: TempReg).<br>
cogit MoveR: TempReg R: formatReg.<br>
cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.<br>
jumpIsContext := cogit JumpZero: 0.<br>
cogit PushR: ClassReg.<br>
self genGetClassObjectOfClassIndex: formatReg into: ClassReg scratchReg: TempReg.<br>
self genLoadSlot: InstanceSpecificationIndex sourceReg: ClassReg destReg: formatReg.<br>
cogit PopR: ClassReg.<br>
self genConvertSmallIntegerToIntegerInReg: formatReg.<br>
cogit<br>
AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;<br>
SubR: formatReg R: ClassReg;<br>
CmpR: Arg1Reg R: ClassReg.<br>
jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
"index is (formatReg (fixed fields) + Arg1Reg (0-rel index)) * wordSize + baseHeaderSize"<br>
cogit AddR: formatReg R: Arg1Reg.<br>
cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.<br>
cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.<br>
cogit RetN: retNoffset.<br>
<br>
jumpIsArray jmpTarget:<br>
(cogit CmpR: Arg1Reg R: ClassReg).<br>
jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.<br>
cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.<br>
cogit RetN: retNoffset.<br>
<br>
jumpFixedFieldsOutOfBounds jmpTarget:<br>
(jumpArrayOutOfBounds jmpTarget:<br>
(jumpBytesOutOfBounds jmpTarget:<br>
(jumpShortsOutOfBounds jmpTarget:<br>
(jumpWordsOutOfBounds jmpTarget:<br>
(jumpWordTooBig jmpTarget:<br>
(jumpNotIndexable jmpTarget:<br>
(jumpIsContext jmpTarget:<br>
(jumpBadIndex jmpTarget:<br>
(jumpImmediate jmpTarget: cogit Label))))))))).<br>
<br>
^0!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentationFor64BitSpur>>genInnerPrimitiveAt: (in category 'primitive generators') -----<br>
genInnerPrimitiveAt: retNoffset<br>
"Implement the guts of primitiveAt"<br>
| formatReg convertToIntAndReturn<br>
jumpNotIndexable jumpImmediate jumpBadIndex<br>
jumpIsBytes jumpIsShorts jumpIsWords jumpIsArray jumpHasFixedFields jumpIsContext<br>
jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds |<br>
<inline: true><br>
"c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"<br>
<var: #jumpIsBytes type: #'AbstractInstruction *'><br>
<var: #jumpIsShorts type: #'AbstractInstruction *'><br>
<var: #jumpBadIndex type: #'AbstractInstruction *'><br>
<var: #jumpIsContext type: #'AbstractInstruction *'><br>
<var: #jumpImmediate type: #'AbstractInstruction *'><br>
<var: #jumpNotIndexable type: #'AbstractInstruction *'><br>
<var: #jumpHasFixedFields type: #'AbstractInstruction *'><br>
<var: #convertToIntAndReturn type: #'AbstractInstruction *'><br>
<var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'><br>
<var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'><br>
<var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'><br>
<var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'><br>
<var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'><br>
<br>
jumpImmediate := self genJumpImmediate: ReceiverResultReg.<br>
cogit MoveR: Arg0Reg R: Arg1Reg.<br>
+ jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.<br>
- jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.<br>
self genConvertSmallIntegerToIntegerInReg: Arg1Reg.<br>
cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"<br>
<br>
"formatReg := self formatOf: ReceiverResultReg"<br>
self genGetFormatOf: ReceiverResultReg<br>
into: (formatReg := SendNumArgsReg)<br>
leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.<br>
<br>
self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.<br>
<br>
"dispatch on format in a combination of highest dynamic frequency order first and convenience.<br>
0 = 0 sized objects (UndefinedObject True False et al)<br>
1 = non-indexable objects with inst vars (Point et al)<br>
2 = indexable objects with no inst vars (Array et al)<br>
3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)<br>
4 = weak indexable objects with inst vars (WeakArray et al)<br>
5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)<br>
6 unused, reserved for exotic pointer objects?<br>
7 Forwarded Object, 1st field is pointer, rest of fields are ignored<br>
8 unused, reserved for exotic non-pointer objects?<br>
9 (?) 64-bit indexable<br>
10 - 11 32-bit indexable<br>
12 - 15 16-bit indexable<br>
16 - 23 byte indexable<br>
24 - 31 compiled method"<br>
cogit CmpCq: objectMemory firstByteFormat R: formatReg.<br>
jumpIsBytes := cogit JumpAboveOrEqual: 0.<br>
cogit CmpCq: objectMemory arrayFormat R: formatReg.<br>
jumpIsArray := cogit JumpZero: 0.<br>
jumpNotIndexable := cogit JumpBelow: 0.<br>
cogit CmpCq: objectMemory weakArrayFormat R: formatReg.<br>
jumpHasFixedFields := cogit JumpBelowOrEqual: 0.<br>
cogit CmpCq: objectMemory firstShortFormat R: formatReg.<br>
jumpIsShorts := cogit JumpAboveOrEqual: 0.<br>
cogit CmpCq: objectMemory firstLongFormat R: formatReg.<br>
jumpIsWords := cogit JumpAboveOrEqual: 0.<br>
"For now ignore 64-bit indexability."<br>
jumpNotIndexable jmpTarget: cogit Label.<br>
jumpNotIndexable := cogit Jump: 0.<br>
<br>
jumpIsBytes jmpTarget:<br>
(cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).<br>
cogit AndCq: objectMemory wordSize - 1 R: formatReg.<br>
cogit SubR: formatReg R: ClassReg;<br>
CmpR: Arg1Reg R: ClassReg.<br>
jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.<br>
cogit backEnd byteReadsZeroExtend<br>
ifTrue:<br>
[cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg]<br>
ifFalse:<br>
[cogit "formatReg already contains a value <= 16r1f, so no need to zero it"<br>
MoveXbr: Arg1Reg R: ReceiverResultReg R: formatReg;<br>
MoveR: formatReg R: ReceiverResultReg].<br>
convertToIntAndReturn := cogit Label.<br>
self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.<br>
cogit RetN: retNoffset.<br>
<br>
jumpIsShorts jmpTarget:<br>
(cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).<br>
cogit AndCq: 1 R: formatReg.<br>
cogit SubR: formatReg R: ClassReg;<br>
CmpR: Arg1Reg R: ClassReg.<br>
jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
cogit AddR: Arg1Reg R: ReceiverResultReg.<br>
cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.<br>
cogit Jump: convertToIntAndReturn.<br>
<br>
jumpIsWords jmpTarget:<br>
(cogit CmpR: Arg1Reg R: ClassReg).<br>
jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
cogit AddCq: objectMemory baseHeaderSize >> (objectMemory shiftForWord - 1) R: Arg1Reg.<br>
cogit MoveX32r: Arg1Reg R: ReceiverResultReg R: TempReg.<br>
cogit MoveR: TempReg R: ReceiverResultReg.<br>
cogit Jump: convertToIntAndReturn.<br>
<br>
jumpHasFixedFields jmpTarget:<br>
(cogit AndCq: objectMemory classIndexMask R: TempReg).<br>
cogit MoveR: TempReg R: formatReg.<br>
cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.<br>
jumpIsContext := cogit JumpZero: 0.<br>
self genGetClassObjectOfClassIndex: formatReg into: Scratch0Reg scratchReg: TempReg.<br>
self genLoadSlot: InstanceSpecificationIndex sourceReg: Scratch0Reg destReg: formatReg.<br>
self genConvertSmallIntegerToIntegerInReg: formatReg.<br>
cogit<br>
AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;<br>
SubR: formatReg R: ClassReg;<br>
CmpR: Arg1Reg R: ClassReg.<br>
jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
"index is (formatReg (fixed fields) + Arg1Reg (0-rel index)) * wordSize + baseHeaderSize"<br>
cogit AddR: formatReg R: Arg1Reg.<br>
cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.<br>
cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.<br>
cogit RetN: retNoffset.<br>
<br>
jumpIsArray jmpTarget:<br>
(cogit CmpR: Arg1Reg R: ClassReg).<br>
jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.<br>
cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.<br>
cogit RetN: retNoffset.<br>
<br>
jumpFixedFieldsOutOfBounds jmpTarget:<br>
(jumpArrayOutOfBounds jmpTarget:<br>
(jumpBytesOutOfBounds jmpTarget:<br>
(jumpShortsOutOfBounds jmpTarget:<br>
(jumpWordsOutOfBounds jmpTarget:<br>
(jumpNotIndexable jmpTarget:<br>
(jumpIsContext jmpTarget:<br>
(jumpBadIndex jmpTarget:<br>
(jumpImmediate jmpTarget: cogit Label)))))))).<br>
<br>
^0!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentationFor64BitSpur>>genInnerPrimitiveNewWithArg: (in category 'primitive generators') -----<br>
genInnerPrimitiveNewWithArg: retNoffset<br>
"Implement primitiveNewWithArg for convenient cases:<br>
- the receiver has a hash<br>
- the receiver is variable and not compiled method<br>
- single word header/num slots < numSlotsMask<br>
- the result fits in eden<br>
See superclass method for dynamic frequencies of formats.<br>
For the moment we implement only arrayFormat, firstByteFormat & firstLongFormat"<br>
<br>
| headerReg fillReg instSpecReg byteSizeReg maxSlots<br>
jumpArrayTooBig jumpByteTooBig jumpLongTooBig<br>
jumpArrayFormat jumpByteFormat jumpBytePrepDone jumpLongPrepDone<br>
jumpUnhashed jumpNElementsNonInt jumpFailCuzFixed jumpNoSpace jumpHasSlots fillLoop skip |<br>
<var: 'skip' type: #'AbstractInstruction *'><br>
<var: 'fillLoop' type: #'AbstractInstruction *'><br>
<var: 'jumpHasSlots' type: #'AbstractInstruction *'><br>
<var: 'jumpNoSpace' type: #'AbstractInstruction *'><br>
<var: 'jumpUnhashed' type: #'AbstractInstruction *'><br>
<var: 'jumpByteFormat' type: #'AbstractInstruction *'><br>
<var: 'jumpByteTooBig' type: #'AbstractInstruction *'><br>
<var: 'jumpLongTooBig' type: #'AbstractInstruction *'><br>
<var: 'jumpArrayFormat' type: #'AbstractInstruction *'><br>
<var: 'jumpArrayTooBig' type: #'AbstractInstruction *'><br>
<var: 'jumpFailCuzFixed' type: #'AbstractInstruction *'><br>
<var: 'jumpBytePrepDone' type: #'AbstractInstruction *'><br>
<var: 'jumpLongPrepDone' type: #'AbstractInstruction *'><br>
<var: 'jumpNElementsNonInt' type: #'AbstractInstruction *'><br>
<br>
"header will contain classIndex/class's hash & format & numSlots/fixed size"<br>
headerReg := SendNumArgsReg.<br>
"Assume there's an available scratch register on 64-bit machines. This holds the saved numFixedFileds and then the value to fill with"<br>
fillReg := Scratch0Reg.<br>
self assert: (cogit backEnd concreteRegister: fillReg) > 0.<br>
"inst spec will hold class's instance specification and then byte size"<br>
instSpecReg := byteSizeReg := ClassReg.<br>
"The max slots we'll allocate here are those for a single header"<br>
maxSlots := objectMemory numSlotsMask - 1.<br>
<br>
"get freeStart as early as possible so as not to wait later..."<br>
cogit MoveAw: objectMemory freeStartAddress R: Arg1Reg.<br>
"get class's hash & fail if 0"<br>
self genGetHashFieldNonImmOf: ReceiverResultReg into: headerReg.<br>
jumpUnhashed := cogit JumpZero: 0.<br>
"get index and fail if not a +ve integer"<br>
+ jumpNElementsNonInt := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.<br>
- jumpNElementsNonInt := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.<br>
"get class's format inst var for inst spec (format field)"<br>
self genLoadSlot: InstanceSpecificationIndex sourceReg: ReceiverResultReg destReg: instSpecReg.<br>
cogit LogicalShiftRightCq: objectMemory fixedFieldsFieldWidth + self numSmallIntegerTagBits R: instSpecReg.<br>
cogit AndCq: objectMemory formatMask R: instSpecReg.<br>
"Add format to classIndex/format header now"<br>
cogit MoveR: instSpecReg R: TempReg.<br>
cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.<br>
cogit AddR: TempReg R: headerReg.<br>
"get integer value of num fields in fillReg now"<br>
cogit MoveR: Arg0Reg R: fillReg.<br>
self genConvertSmallIntegerToIntegerInReg: fillReg.<br>
"dispatch on format, failing if not variable or if compiled method"<br>
cogit CmpCq: objectMemory arrayFormat R: instSpecReg.<br>
jumpArrayFormat := cogit JumpZero: 0.<br>
cogit CmpCq: objectMemory firstByteFormat R: instSpecReg.<br>
jumpByteFormat := cogit JumpZero: 0.<br>
cogit CmpCq: objectMemory firstLongFormat R: instSpecReg.<br>
jumpFailCuzFixed := cogit JumpNonZero: 0.<br>
<br>
cogit CmpCq: (objectMemory integerObjectOf: maxSlots * 2) R: Arg0Reg.<br>
jumpLongTooBig := cogit JumpAbove: 0.<br>
"save num elements/slot size to instSpecReg"<br>
cogit MoveR: fillReg R: instSpecReg.<br>
"compute odd bits and add into headerReg; oddBits := 2 - nElements bitAnd: 1"<br>
cogit MoveCq: objectMemory wordSize / 4 R: TempReg.<br>
cogit SubR: instSpecReg R: TempReg.<br>
cogit AndCq: objectMemory wordSize / 4 - 1 R: TempReg.<br>
cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.<br>
cogit AddR: TempReg R: headerReg.<br>
"round up num elements to numSlots in instSpecReg"<br>
cogit AddCq: objectMemory wordSize / 4 - 1 R: instSpecReg.<br>
cogit LogicalShiftRightCq: objectMemory shiftForWord - 2 R: instSpecReg.<br>
cogit MoveCq: 0 R: fillReg.<br>
jumpLongPrepDone := cogit Jump: 0. "go allocate"<br>
<br>
jumpByteFormat jmpTarget:<br>
(cogit CmpCq: (objectMemory integerObjectOf: maxSlots * objectMemory wordSize) R: Arg0Reg).<br>
jumpByteTooBig := cogit JumpAbove: 0.<br>
"save num elements to instSpecReg"<br>
cogit MoveR: fillReg R: instSpecReg.<br>
"compute odd bits and add into headerReg; oddBits := 4 - nElements bitAnd: 3"<br>
cogit MoveCq: objectMemory wordSize R: TempReg.<br>
cogit SubR: instSpecReg R: TempReg.<br>
cogit AndCq: objectMemory wordSize - 1 R: TempReg.<br>
cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.<br>
cogit AddR: TempReg R: headerReg.<br>
"round up num elements to numSlots in instSpecReg"<br>
cogit AddCq: objectMemory wordSize - 1 R: instSpecReg.<br>
cogit LogicalShiftRightCq: objectMemory shiftForWord R: instSpecReg.<br>
cogit MoveCq: 0 R: fillReg.<br>
jumpBytePrepDone := cogit Jump: 0. "go allocate"<br>
<br>
jumpArrayFormat jmpTarget:<br>
(cogit CmpCq: (objectMemory integerObjectOf: maxSlots) R: Arg0Reg).<br>
jumpArrayTooBig := cogit JumpAbove: 0.<br>
"save num elements/slot size to instSpecReg"<br>
cogit MoveR: fillReg R: instSpecReg.<br>
cogit MoveCq: objectMemory nilObject R: fillReg.<br>
"fall through to allocate"<br>
<br>
jumpBytePrepDone jmpTarget:<br>
(jumpLongPrepDone jmpTarget: cogit Label).<br>
<br>
"store numSlots to headerReg"<br>
cogit MoveR: instSpecReg R: TempReg.<br>
cogit LogicalShiftLeftCq: objectMemory numSlotsFullShift R: TempReg.<br>
cogit AddR: TempReg R: headerReg.<br>
"compute byte size; remember 0-sized objects still need 1 slot."<br>
cogit CmpCq: 0 R: byteSizeReg. "a.k.a. instSpecReg"<br>
jumpHasSlots := cogit JumpNonZero: 0.<br>
cogit MoveCq: objectMemory baseHeaderSize * 2 R: byteSizeReg.<br>
skip := cogit Jump: 0.<br>
jumpHasSlots jmpTarget:<br>
(cogit AddCq: objectMemory baseHeaderSize / objectMemory wordSize R: byteSizeReg).<br>
cogit LogicalShiftLeftCq: objectMemory shiftForWord R: byteSizeReg.<br>
skip jmpTarget:<br>
"check if allocation fits"<br>
(cogit AddR: Arg1Reg R: byteSizeReg).<br>
cogit CmpCq: objectMemory getScavengeThreshold R: byteSizeReg.<br>
jumpNoSpace := cogit JumpAboveOrEqual: 0.<br>
"get result, increment freeStart and write it back. Arg1Reg holds new freeStart, the limit of the object"<br>
cogit MoveR: Arg1Reg R: ReceiverResultReg.<br>
cogit MoveR: byteSizeReg Aw: objectMemory freeStartAddress.<br>
"write other half of header (numSlots/0 identityHash)"<br>
cogit MoveR: headerReg Mw: 0 r: ReceiverResultReg.<br>
"now fill"<br>
cogit LoadEffectiveAddressMw: objectMemory baseHeaderSize r: ReceiverResultReg R: Arg1Reg.<br>
fillLoop :=<br>
cogit MoveR: fillReg Mw: 0 r: Arg1Reg.<br>
cogit AddCq: 8 R: Arg1Reg.<br>
cogit CmpR: Arg1Reg R: byteSizeReg.<br>
cogit JumpAbove: fillLoop.<br>
cogit RetN: retNoffset.<br>
<br>
jumpNoSpace jmpTarget:<br>
(jumpUnhashed jmpTarget:<br>
(jumpFailCuzFixed jmpTarget:<br>
(jumpArrayTooBig jmpTarget:<br>
(jumpByteTooBig jmpTarget:<br>
(jumpLongTooBig jmpTarget:<br>
(jumpNElementsNonInt jmpTarget: cogit Label)))))).<br>
<br>
^0!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveAsCharacter:inReg: (in category 'primitive generators') -----<br>
genInnerPrimitiveAsCharacter: retNOffset inReg: reg<br>
| jumpNotInt jumpOutOfRange |<br>
<var: 'jumpNotInt' type: #'AbstractInstruction *'><br>
<var: 'jumpOutOfRange' type: #'AbstractInstruction *'><br>
reg ~= ReceiverResultReg ifTrue:<br>
+ [jumpNotInt := self genJumpNotSmallInteger: reg scratchReg: TempReg].<br>
- [jumpNotInt := self genJumpNotSmallInteger: reg scratch: TempReg].<br>
cogit MoveR: reg R: TempReg.<br>
self genConvertSmallIntegerToIntegerInReg: TempReg.<br>
cogit CmpCq: 1 << 30 - 1 R: TempReg.<br>
jumpOutOfRange := cogit JumpAbove: 0.<br>
self genConvertSmallIntegerToCharacterInReg: reg.<br>
reg ~= ReceiverResultReg ifTrue:<br>
[cogit MoveR: reg R: ReceiverResultReg].<br>
cogit RetN: retNOffset.<br>
jumpOutOfRange jmpTarget: cogit Label.<br>
reg ~= ReceiverResultReg ifTrue:<br>
[jumpNotInt jmpTarget: jumpOutOfRange getJmpTarget].<br>
^0!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveObjectAt: (in category 'primitive generators') -----<br>
genInnerPrimitiveObjectAt: retNOffset<br>
| headerReg<br>
jumpBadIndex jumpNotCogMethod jumpBounds jumpNotHeaderIndex |<br>
<var: #jumpBounds type: #'AbstractInstruction *'><br>
<var: #jumpBadIndex type: #'AbstractInstruction *'><br>
<var: #jumpNotCogMethod type: #'AbstractInstruction *'><br>
<var: #jumpNotHeaderIndex type: #'AbstractInstruction *'><br>
+ jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.<br>
- jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.<br>
"get header into Arg1Reg..."<br>
cogit MoveMw: objectMemory baseHeaderSize r: ReceiverResultReg R: (headerReg := Arg1Reg).<br>
+ jumpNotCogMethod := self genJumpSmallInteger: headerReg scratchReg: TempReg.<br>
- jumpNotCogMethod := self genJumpSmallInteger: headerReg scratch: TempReg.<br>
cogit MoveMw: (cogit offset: CogMethod of: #methodHeader) r: headerReg R: headerReg.<br>
jumpNotCogMethod jmpTarget: (cogit<br>
CmpCq: (objectMemory integerObjectOf: 1) R: Arg0Reg).<br>
jumpNotHeaderIndex := cogit JumpNonZero: 0.<br>
cogit<br>
MoveR: headerReg R: ReceiverResultReg;<br>
RetN: retNOffset.<br>
jumpNotHeaderIndex jmpTarget: (cogit<br>
AndCq: (objectMemory integerObjectOf: coInterpreter alternateHeaderNumLiteralsMask) R: headerReg).<br>
cogit<br>
SubCq: (objectMemory integerObjectOf: 1) - objectMemory smallIntegerTag R: Arg0Reg;<br>
CmpR: headerReg R: Arg0Reg.<br>
jumpBounds := cogit JumpAbove: 0.<br>
<br>
self genConvertSmallIntegerToIntegerInReg: Arg0Reg.<br>
cogit<br>
AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg0Reg;<br>
MoveXwr: Arg0Reg R: ReceiverResultReg R: ReceiverResultReg;<br>
RetN: retNOffset.<br>
<br>
jumpBounds jmpTarget: (cogit<br>
AddCq: (objectMemory integerObjectOf: 1) - objectMemory smallIntegerTag R: Arg0Reg).<br>
jumpBadIndex jmpTarget: cogit Label.<br>
^CompletePrimitive!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveStringAt: (in category 'primitive generators') -----<br>
genInnerPrimitiveStringAt: retNoffset<br>
"Implement the guts of primitiveStringAt; dispatch on size"<br>
| formatReg jumpNotIndexable jumpBadIndex done<br>
jumpIsBytes jumpIsShorts jumpIsWords jumpWordTooBig<br>
jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds |<br>
<inline: true><br>
"c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"<br>
<var: #done type: #'AbstractInstruction *'><br>
<var: #jumpIsBytes type: #'AbstractInstruction *'><br>
<var: #jumpIsShorts type: #'AbstractInstruction *'><br>
<var: #jumpIsWords type: #'AbstractInstruction *'><br>
<var: #jumpBadIndex type: #'AbstractInstruction *'><br>
<var: #jumpWordTooBig type: #'AbstractInstruction *'><br>
<var: #jumpNotIndexable type: #'AbstractInstruction *'><br>
<var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'><br>
<var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'><br>
<var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'><br>
<br>
cogit MoveR: Arg0Reg R: Arg1Reg.<br>
+ jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg.<br>
- jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratch: TempReg.<br>
self genConvertSmallIntegerToIntegerInReg: Arg1Reg.<br>
cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"<br>
<br>
self genGetFormatOf: ReceiverResultReg<br>
into: (formatReg := SendNumArgsReg)<br>
leastSignificantHalfOfBaseHeaderIntoScratch: NoReg.<br>
<br>
self genGetNumSlotsOf: ReceiverResultReg into: ClassReg.<br>
<br>
"dispatch on format in a combination of highest dynamic frequency order first and convenience.<br>
0 = 0 sized objects (UndefinedObject True False et al)<br>
1 = non-indexable objects with inst vars (Point et al)<br>
2 = indexable objects with no inst vars (Array et al)<br>
3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)<br>
4 = weak indexable objects with inst vars (WeakArray et al)<br>
5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)<br>
6 unused, reserved for exotic pointer objects?<br>
7 Forwarded Object, 1st field is pointer, rest of fields are ignored<br>
8 unused, reserved for exotic non-pointer objects?<br>
9 (?) 64-bit indexable<br>
10 - 11 32-bit indexable<br>
12 - 15 16-bit indexable<br>
16 - 23 byte indexable<br>
24 - 31 compiled method"<br>
cogit CmpCq: objectMemory firstByteFormat R: formatReg.<br>
jumpIsBytes := cogit JumpGreaterOrEqual: 0.<br>
cogit CmpCq: objectMemory firstShortFormat R: formatReg.<br>
jumpIsShorts := cogit JumpGreaterOrEqual: 0.<br>
cogit CmpCq: objectMemory firstLongFormat R: formatReg.<br>
jumpIsWords := cogit JumpGreaterOrEqual: 0.<br>
jumpNotIndexable := cogit Jump: 0.<br>
<br>
jumpIsBytes jmpTarget:<br>
(cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).<br>
cogit AndCq: objectMemory wordSize - 1 R: formatReg.<br>
cogit SubR: formatReg R: ClassReg;<br>
CmpR: Arg1Reg R: ClassReg.<br>
jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.<br>
cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.<br>
cogit backEnd byteReadsZeroExtend ifFalse:<br>
[cogit AndCq: 255 R: ReceiverResultReg].<br>
done := cogit Label.<br>
self genConvertIntegerToCharacterInReg: ReceiverResultReg.<br>
cogit RetN: retNoffset.<br>
<br>
jumpIsShorts jmpTarget:<br>
(cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).<br>
cogit AndCq: 1 R: formatReg.<br>
cogit SubR: formatReg R: ClassReg;<br>
CmpR: Arg1Reg R: ClassReg.<br>
jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
cogit AddR: Arg1Reg R: ReceiverResultReg.<br>
cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.<br>
cogit Jump: done.<br>
<br>
jumpIsWords jmpTarget:<br>
(cogit CmpR: Arg1Reg R: ClassReg).<br>
jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.<br>
cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.<br>
cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: TempReg.<br>
cogit SubCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.<br>
jumpWordTooBig := self jumpNotCharacterUnsignedValueInRegister: TempReg.<br>
cogit MoveR: TempReg R: ReceiverResultReg.<br>
cogit Jump: done.<br>
<br>
jumpBytesOutOfBounds jmpTarget:<br>
(jumpShortsOutOfBounds jmpTarget:<br>
(jumpWordsOutOfBounds jmpTarget:<br>
(jumpWordTooBig jmpTarget:<br>
(jumpNotIndexable jmpTarget:<br>
(jumpBadIndex jmpTarget: cogit Label))))).<br>
<br>
^0!<br>
<br>
Item was changed:<br>
----- Method: Cogit>>AndCq:R:R: (in category 'abstract instructions') -----<br>
AndCq: quickConstant R: srcReg R: destReg<br>
+ <inline: false><br>
- <inline: true><br>
<returnTypeC: #'AbstractInstruction *'><br>
| first |<br>
<var: 'first' type: #'AbstractInstruction *'><br>
backEnd hasThreeAddressArithmetic ifTrue:<br>
[^self gen: AndCqRR quickConstant: quickConstant operand: srcReg operand: destReg].<br>
srcReg = destReg ifTrue:<br>
[^self gen: AndCqR quickConstant: quickConstant operand: destReg.].<br>
first := self gen: MoveRR operand: srcReg operand: destReg.<br>
self gen: AndCqR quickConstant: quickConstant operand: destReg.<br>
^first!<br>
<br>
Item was changed:<br>
----- Method: OutOfLineLiteralsManager>>checkQuickConstant:forInstruction: (in category 'compile abstract instructions') -----<br>
checkQuickConstant: literal forInstruction: anInstruction<br>
<var: #anInstruction type: #'AbstractInstruction *'><br>
<returnTypeC: #'AbstractInstruction *'><br>
+ <inline: true><br>
anInstruction usesOutOfLineLiteral ifTrue:<br>
+ [anInstruction dependent: (self locateLiteral: (self cCode: [literal] inSmalltalk: [literal bitAnd: 1 << (objectMemory wordSize * 8) - 1]))].<br>
- [anInstruction dependent: (self locateLiteral: (self cCode: [literal] inSmalltalk: [literal bitAnd: 16rFFFFFFFF]))].<br>
^anInstruction!<br>
<br>
Item was changed:<br>
----- Method: StackToRegisterMappingCogit>>genDoubleArithmetic:preOpCheck: (in category 'primitive generators') -----<br>
genDoubleArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil<br>
"Receiver and arg in registers.<br>
Stack looks like<br>
return address"<br>
<var: #preOpCheckOrNil declareC: 'AbstractInstruction *(*preOpCheckOrNil)(int rcvrReg, int argReg)'><br>
| jumpFailClass jumpFailClass2 jumpFailAlloc jumpFailCheck jumpImmediate jumpNonInt doOp |<br>
<var: #jumpFailClass type: #'AbstractInstruction *'><br>
<var: #jumpFailClass2 type: #'AbstractInstruction *'><br>
<var: #jumpFailAlloc type: #'AbstractInstruction *'><br>
<var: #jumpImmediate type: #'AbstractInstruction *'><br>
<var: #jumpNonInt type: #'AbstractInstruction *'><br>
<var: #jumpFailCheck type: #'AbstractInstruction *'><br>
<var: #doOp type: #'AbstractInstruction *'><br>
objectRepresentation genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.<br>
self MoveR: Arg0Reg R: ClassReg.<br>
jumpImmediate := objectRepresentation genJumpImmediate: Arg0Reg.<br>
objectRepresentation genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
objectRepresentation genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
jumpFailClass := self JumpNonZero: 0.<br>
objectRepresentation genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
doOp := self Label.<br>
preOpCheckOrNil ifNotNil:<br>
[jumpFailCheck := self perform: preOpCheckOrNil with: DPFPReg0 with: DPFPReg1].<br>
self gen: arithmeticOperator operand: DPFPReg1 operand: DPFPReg0.<br>
jumpFailAlloc := objectRepresentation<br>
genAllocFloatValue: DPFPReg0<br>
into: SendNumArgsReg<br>
scratchReg: ClassReg<br>
scratchReg: TempReg.<br>
self MoveR: SendNumArgsReg R: ReceiverResultReg.<br>
self RetN: 0.<br>
jumpImmediate jmpTarget: self Label.<br>
objectRepresentation maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: doOp.<br>
objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:<br>
+ [jumpNonInt := objectRepresentation genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg].<br>
- [jumpNonInt := objectRepresentation genJumpNotSmallInteger: Arg0Reg scratch: TempReg].<br>
objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.<br>
self ConvertR: ClassReg Rd: DPFPReg1.<br>
self Jump: doOp.<br>
"We need to push the register args on two paths; this one and the interpreter primitive path.<br>
But the interpreter primitive path won't unless regArgsHaveBeenPushed is false."<br>
self assert: methodOrBlockNumArgs <= self numRegArgs.<br>
jumpFailClass jmpTarget: self Label.<br>
objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:<br>
[jumpNonInt jmpTarget: jumpFailClass getJmpTarget].<br>
preOpCheckOrNil ifNotNil:<br>
[jumpFailCheck jmpTarget: jumpFailClass getJmpTarget].<br>
backEnd genPushRegisterArgsForNumArgs: methodOrBlockNumArgs scratchReg: SendNumArgsReg.<br>
jumpFailClass2 := self Jump: 0.<br>
jumpFailAlloc jmpTarget: self Label.<br>
self compileFallbackToInterpreterPrimitive: 0.<br>
jumpFailClass2 jmpTarget: self Label.<br>
^0!<br>
<br>
Item was changed:<br>
----- Method: TReturnNode>>emitCCodeOn:level:generator: (in category 'C code generation') -----<br>
emitCCodeOn: aStream level: level generator: aCodeGen<br>
<br>
(expression isSwitch<br>
or: [expression isCaseStmt]) ifTrue:<br>
[^expression emitCCodeOn: aStream addToEndOfCases: self level: level generator: aCodeGen].<br>
<br>
(expression isSend and: [expression isValueExpansion]) ifTrue:<br>
[^self emitValueExpansionOn: aStream level: level generator: aCodeGen].<br>
<br>
'void' = aCodeGen currentMethod returnType ifTrue: "If the function is void, don't say 'return x' instead say ' x; return' "<br>
[expression isLeaf ifFalse:<br>
[expression emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen.<br>
aStream nextPut: $;; crtab: level].<br>
aStream nextPutAll: 'return'.<br>
^self].<br>
aStream nextPutAll: 'return '.<br>
+ expression<br>
+ emitCCodeAsArgumentOn: aStream<br>
+ level: (expression isStmtList ifTrue: [level + 1] ifFalse: [level])<br>
+ generator: aCodeGen!<br>
- expression emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen!<br>
<br>
Item was changed:<br>
----- Method: TStmtListNode>>emitCCodeAsArgumentOn:level:generator: (in category 'C code generation') -----<br>
emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen<br>
+ | size |<br>
+ (size := statements size) = 1 ifTrue:<br>
-<br>
- | statementWasComment |<br>
- statements size = 1 ifTrue:<br>
[^statements first emitCCodeAsArgumentOn: aStream level: level generator: aCodeGen].<br>
- statementWasComment := false.<br>
aStream nextPut: $(. "N.B. Comma binds weakest of all C operators."<br>
+ statements withIndexDo:<br>
+ [:s :idx| | p1 p2 |<br>
+ p1 := aStream position.<br>
+ s emitCCommentOn: aStream level: level.<br>
+ (s isLeaf and: [s isLabel not and: [idx < statements size]]) ifFalse:<br>
+ [s emitCCodeAsArgumentOn: aStream level: level + 1 generator: aCodeGen].<br>
+ p2 := aStream position.<br>
+ (idx < size and: [p2 > p1]) ifTrue:<br>
- statements<br>
- do:<br>
- [:s |<br>
- s emitCCommentOn: aStream level: level.<br>
- s emitCCodeAsArgumentOn: aStream level: level + 1 generator: aCodeGen.<br>
- statementWasComment := s isComment]<br>
- separatedBy:<br>
[((self endsWithCloseBracket: aStream)<br>
+ or: [s isComment]) ifFalse: [aStream nextPut: $,].<br>
+ aStream crtab: level]].<br>
- or: [statementWasComment]) ifFalse: [aStream nextPut: $,].<br>
- aStream crtab: level].<br>
aStream nextPut: $)!<br>
<br>
</blockquote></div><br></div>