[Vm-dev] VM Maker: VMMaker.oscog-eem.3066.mcz

commits at source.squeak.org commits at source.squeak.org
Fri Sep 10 00:57:55 UTC 2021


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

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

Name: VMMaker.oscog-eem.3066
Author: eem
Time: 9 September 2021, 5:57:44.279204 pm
UUID: 8db97a47-7e9e-4784-8cf2-db4fc404ed95
Ancestors: VMMaker.oscog-eem.3065

BalloonEngine/B2DPlugin: use FastCPrimitiveFlag & FastCPrimitiveAlignForFloatsFlag for all primitives that don't use the copyBitsFn (because copyBitsFn potentially interacts with surfaces and so has an indeterminate stack depth).

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

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveAbortProcessing (in category 'primitives-other') -----
  primitiveAbortProcessing
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	| failureCode |
  	interpreterProxy methodArgumentCount = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 0)) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  	self statePut: GEStateCompleted.
  	self storeEngineStateInto: engine.!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveAddActiveEdgeEntry (in category 'primitives-incremental') -----
  primitiveAddActiveEdgeEntry
  	"Note: No need to load either bitBlt or spanBuffer"
  	| failureCode edgeOop edge |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	doProfileStats ifTrue:[geProfileTime := interpreterProxy ioMicroMSecs].
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)
  						requiredState: GEStateWaitingForEdge) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	edgeOop := interpreterProxy stackObjectValue: 0.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	edge := self loadEdgeStateFrom: edgeOop.
  	edge = nil ifTrue:[^interpreterProxy primitiveFailFor: GEFEdgeDataTooSmall].
  
  	(self needAvailableSpace: 1) 
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWorkTooBig].
  
  	(self edgeNumLinesOf: edge) > 0 ifTrue:[
  		self insertEdgeIntoAET: edge.
  	].
  
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	self statePut: GEStateAddingFromGET. "Back to adding edges from GET"
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 1. "Leave rcvr on stack"
  	doProfileStats ifTrue:[
  		self incrementStat: GWCountAddAETEntry by: 1.
  		self incrementStat: GWTimeAddAETEntry by: (interpreterProxy ioMicroMSecs - geProfileTime)].
  !

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveChangedActiveEdgeEntry (in category 'primitives-incremental') -----
  primitiveChangedActiveEdgeEntry
  	"Note: No need to load either bitBlt or spanBuffer"
  	| failureCode edgeOop edge |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	doProfileStats ifTrue:[geProfileTime := interpreterProxy ioMicroMSecs].
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)
  						requiredState: GEStateWaitingChange) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	edgeOop := interpreterProxy stackObjectValue: 0.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	edge := self loadEdgeStateFrom: edgeOop.
  	edge = nil ifTrue:[^interpreterProxy primitiveFailFor: GEFEdgeDataTooSmall].
  
  	(self edgeNumLinesOf: edge) = 0 
  		ifTrue:[	self removeFirstAETEntry]
  		ifFalse:[	self resortFirstAETEntry.
  				self aetStartPut: self aetStartGet + 1].
  
  	self statePut: GEStateUpdateEdges. "Back to updating edges"
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 1. "Leave rcvr on stack"
  	doProfileStats ifTrue:[
  		self incrementStat: GWCountChangeAETEntry by: 1.
  		self incrementStat: GWTimeChangeAETEntry by: (interpreterProxy ioMicroMSecs - geProfileTime)].
  !

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveCopyBuffer (in category 'primitives-other') -----
  primitiveCopyBuffer
  	| failCode buf1 buf2 diff src dst |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	<var: 'src' type: #'int *'>
  	<var: 'dst' type: #'int *'>
  
  	interpreterProxy methodArgumentCount = 2
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	buf2 := interpreterProxy stackValue: 0.
  	buf1 := interpreterProxy stackValue: 1.
  	"Make sure the old buffer is properly initialized"
  	(failCode := self loadWorkBufferFrom: buf1) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failCode].
  	"Make sure the buffers are of the same type"
  	(interpreterProxy fetchClassOf: buf1) = (interpreterProxy fetchClassOf: buf2)
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFClassMismatch].
  	"Make sure buf2 is at least of the size of buf1"
  	diff := (interpreterProxy slotSizeOf: buf2) - (interpreterProxy slotSizeOf: buf1).
  	diff < 0 ifTrue:[^interpreterProxy primitiveFailFor: GEFSizeMismatch].
  
  	"Okay - ready for copying. First of all just copy the contents up to wbTop"
  	src := workBuffer.
  	dst := interpreterProxy firstIndexableField: buf2.
  	0 to: self wbTopGet-1 do:[:i|
  		dst at: i put: (src at: i).
  	].
  	"Adjust wbSize and wbTop in the new buffer"
  	dst at: GWBufferTop put: self wbTopGet + diff.
  	dst at: GWSize put: self wbSizeGet + diff.
  	"Now copy the entries from wbTop to wbSize"
  	src := src + self wbTopGet.
  	dst := dst + self wbTopGet + diff.
  	0 to: (self wbSizeGet - self wbTopGet - 1) do:[:i|
  		dst at: i put: (src at: i).
  	].
  	"Okay, done. Check the new buffer by loading the state from it"
  	(failCode := self loadWorkBufferFrom: buf2) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failCode].
  	interpreterProxy pop: 2. "Leave rcvr on stack"
  !

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveDoProfileStats (in category 'primitives-other') -----
  primitiveDoProfileStats
  	"Turn on/off profiling. Return the old value of the flag."
  	| oldValue newValue |
  	<inline: false>
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	oldValue := doProfileStats.
  	newValue := interpreterProxy stackObjectValue: 0.
  	newValue := interpreterProxy booleanValueOf: newValue.
  	interpreterProxy failed ifFalse:[
  		doProfileStats := newValue.
  		interpreterProxy pop: 2. "Pop rcvr, arg"
  		interpreterProxy pushBool: oldValue.
  	].!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveFinishedProcessing (in category 'primitives-other') -----
  primitiveFinishedProcessing
  	| finished failureCode |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	doProfileStats ifTrue:[geProfileTime := interpreterProxy ioMicroMSecs].
  	interpreterProxy methodArgumentCount = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 0)) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  	finished := self finishedProcessing.
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 1.
  	interpreterProxy pushBool: finished.
  	doProfileStats ifTrue:[
  		self incrementStat: GWCountFinishTest by: 1.
  		self incrementStat: GWTimeFinishTest by: (interpreterProxy ioMicroMSecs - geProfileTime)].
  !

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveGetAALevel (in category 'primitives-access') -----
  primitiveGetAALevel
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	| failureCode |
  	interpreterProxy methodArgumentCount = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 0)) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  	interpreterProxy pop: 1.
  	interpreterProxy pushInteger: self aaLevelGet.!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveGetClipRect (in category 'primitives-access') -----
  primitiveGetClipRect
  	| failureCode rectOop pointOop |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	rectOop := interpreterProxy stackObjectValue: 0.
  	(interpreterProxy failed not
  	and: [(interpreterProxy isPointers: rectOop)
  	and: [(interpreterProxy slotSizeOf: rectOop) >= 2]])
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	interpreterProxy pushRemappableOop: rectOop.
  	pointOop := interpreterProxy makePointwithxValue: self clipMinXGet yValue: self clipMinYGet.
  	interpreterProxy storePointer: 0 ofObject: interpreterProxy topRemappableOop withValue: pointOop.
  	pointOop := interpreterProxy makePointwithxValue: self clipMaxXGet yValue: self clipMaxYGet.
  	rectOop := interpreterProxy popRemappableOop.
  	interpreterProxy storePointer: 1 ofObject: rectOop withValue: pointOop.
  
  	interpreterProxy pop: 2 thenPush: rectOop.!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveGetCounts (in category 'primitives-access') -----
  primitiveGetCounts
  	| failureCode statOop stats |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	<var: 'stats' type: #'int *'>
  
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	statOop := interpreterProxy stackObjectValue: 0.
  	(interpreterProxy failed not
  	and: [(interpreterProxy isWords: statOop)
  	and: [(interpreterProxy slotSizeOf: statOop) >= 9]])
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	stats := interpreterProxy firstIndexableField: statOop.
  	stats at: 0 put: (stats at: 0) + (workBuffer at: GWCountInitializing).
  	stats at: 1 put: (stats at: 1) + (workBuffer at: GWCountFinishTest).
  	stats at: 2 put: (stats at: 2) + (workBuffer at: GWCountNextGETEntry).
  	stats at: 3 put: (stats at: 3) + (workBuffer at: GWCountAddAETEntry).
  	stats at: 4 put: (stats at: 4) + (workBuffer at: GWCountNextFillEntry).
  	stats at: 5 put: (stats at: 5) + (workBuffer at: GWCountMergeFill).
  	stats at: 6 put: (stats at: 6) + (workBuffer at: GWCountDisplaySpan).
  	stats at: 7 put: (stats at: 7) + (workBuffer at: GWCountNextAETEntry).
  	stats at: 8 put: (stats at: 8) + (workBuffer at: GWCountChangeAETEntry).
  
  	interpreterProxy pop: 1. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveGetDepth (in category 'primitives-access') -----
  primitiveGetDepth
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	| failureCode |
  	interpreterProxy methodArgumentCount = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 0)) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  	interpreterProxy pop: 1.
  	interpreterProxy pushInteger: self currentZGet.!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveGetFailureReason (in category 'primitives-access') -----
  primitiveGetFailureReason
  	"Return the reason why the last operation failed."
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	| failCode |
  	interpreterProxy methodArgumentCount = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	engine := interpreterProxy stackValue: 0.
  	"Note -- don't call loadEngineFrom here because this will override the stopReason with Zero"
  	(interpreterProxy isImmediate: engine) ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineIsInteger].
  	(interpreterProxy isPointers: engine) ifFalse:[^interpreterProxy primitiveFailFor: GEFEngineIsWords].
  	(interpreterProxy slotSizeOf: engine) < BEBalloonEngineSize ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineTooSmall].
  	(failCode := self loadWorkBufferFrom: 
  		(interpreterProxy fetchPointer: BEWorkBufferIndex ofObject: engine)) = 0
  			ifFalse:[^interpreterProxy primitiveFailFor: failCode].
  	interpreterProxy pop: 1.
  	interpreterProxy pushInteger: self stopReasonGet.!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveGetOffset (in category 'primitives-access') -----
  primitiveGetOffset
  	| failureCode pointOop |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	interpreterProxy methodArgumentCount = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 0)) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  	pointOop := interpreterProxy makePointwithxValue: self destOffsetXGet yValue: self destOffsetYGet.
  	interpreterProxy pop: 1 thenPush: pointOop.!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveGetTimes (in category 'primitives-access') -----
  primitiveGetTimes
  	| failureCode statOop stats |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	<var: 'stats' type: #'int *'>
  
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	statOop := interpreterProxy stackObjectValue: 0.
  	(interpreterProxy failed not
  	and: [(interpreterProxy isWords: statOop)
  	and: [(interpreterProxy slotSizeOf: statOop) >= 9]])
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	stats := interpreterProxy firstIndexableField: statOop.
  	stats at: 0 put: (stats at: 0) + (workBuffer at: GWTimeInitializing).
  	stats at: 1 put: (stats at: 1) + (workBuffer at: GWTimeFinishTest).
  	stats at: 2 put: (stats at: 2) + (workBuffer at: GWTimeNextGETEntry).
  	stats at: 3 put: (stats at: 3) + (workBuffer at: GWTimeAddAETEntry).
  	stats at: 4 put: (stats at: 4) + (workBuffer at: GWTimeNextFillEntry).
  	stats at: 5 put: (stats at: 5) + (workBuffer at: GWTimeMergeFill).
  	stats at: 6 put: (stats at: 6) + (workBuffer at: GWTimeDisplaySpan).
  	stats at: 7 put: (stats at: 7) + (workBuffer at: GWTimeNextAETEntry).
  	stats at: 8 put: (stats at: 8) + (workBuffer at: GWTimeChangeAETEntry).
  
  	interpreterProxy pop: 1. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveInitializeBuffer (in category 'primitives-other') -----
  primitiveInitializeBuffer
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	| wbOop size |
  	(interpreterProxy methodArgumentCount = 1
  	 and: [(interpreterProxy isWords: (wbOop := interpreterProxy stackValue: 0)) 
  	 and: [(size := interpreterProxy slotSizeOf: wbOop) >= GWMinimalSize]]) ifFalse:
  		[^interpreterProxy primitiveFail].
  	self workBufferPut: wbOop.
  	objBuffer := workBuffer + GWHeaderSize.
  	self magicNumberPut: GWMagicNumber.
  	self wbSizePut: size.
  	self wbTopPut: size.
  	self statePut: GEStateUnlocked.
  	self objStartPut: GWHeaderSize.
  	self objUsedPut: 4.	"Dummy fill object"
  	self objectTypeOf: 0 put: GEPrimitiveFill.
  	self objectLengthOf: 0 put: 4.
  	self objectIndexOf: 0 put: 0.
  	self getStartPut: 0.
  	self getUsedPut: 0.
  	self aetStartPut: 0.
  	self aetUsedPut: 0.
  	self stopReasonPut: 0.
  	self needsFlushPut: 0.
  	self clipMinXPut: 0.
  	self clipMaxXPut: 0.
  	self clipMinYPut: 0.
  	self clipMaxYPut: 0.
  	self currentZPut: 0.
  	self resetGraphicsEngineStats.
  	self initEdgeTransform.
  	self initColorTransform.
  	interpreterProxy pop: 2 thenPush: wbOop!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveInitializeProcessing (in category 'primitives-incremental') -----
  primitiveInitializeProcessing
  	"Note: No need to load bitBlt but must load spanBuffer"
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	| failureCode |
  	doProfileStats ifTrue:[geProfileTime := interpreterProxy ioMicroMSecs].
  	interpreterProxy methodArgumentCount = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 0)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  	"Load span buffer for clear operation"
  	(failureCode := self loadSpanBufferFrom:
  		(interpreterProxy fetchPointer: BESpanIndex ofObject: engine)) = 0
  			ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  	self initializeGETProcessing.
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  	self statePut: GEStateAddingFromGET. "Initialized"
  	interpreterProxy failed ifFalse:[self storeEngineStateInto: engine].
  	doProfileStats ifTrue:[
  		self incrementStat: GWCountInitializing by: 1.
  		self incrementStat: GWTimeInitializing by: (interpreterProxy ioMicroMSecs - geProfileTime)].
  !

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveMergeFillFrom (in category 'primitives-incremental') -----
  primitiveMergeFillFrom
  	"Note: No need to load bitBlt but must load spanBuffer"
  	| failureCode fillOop bitsOop value |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	doProfileStats ifTrue:[geProfileTime := interpreterProxy ioMicroMSecs].
  	interpreterProxy methodArgumentCount = 2
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 2)
  						requiredState: GEStateWaitingForFill) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  	"Load span buffer for merging the fill"
  	(failureCode := self loadSpanBufferFrom:
  		(interpreterProxy fetchPointer: BESpanIndex ofObject: engine)) = 0
  			ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	fillOop := interpreterProxy stackObjectValue: 0.
  	bitsOop := interpreterProxy stackObjectValue: 1.
  	"Check bitmap"
  	(interpreterProxy failed not
  	and: [(interpreterProxy fetchClassOf: bitsOop) = interpreterProxy classBitmap])
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	"Check fillOop"
  	(interpreterProxy slotSizeOf: fillOop) < FTBalloonFillDataSize
  		ifTrue:[^interpreterProxy primitiveFailFor: GEFFillDataTooSmall].
  	"Check if this was the fill we have exported"
  	value := interpreterProxy fetchInteger: FTIndexIndex ofObject: fillOop.
  	(self objectIndexOf: self lastExportedFillGet) = value
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWrongFill].
  	value := interpreterProxy fetchInteger: FTMinXIndex ofObject: fillOop.
  	self lastExportedLeftXGet = value
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWrongFill].
  	value := interpreterProxy fetchInteger: FTMaxXIndex ofObject: fillOop.
  	self lastExportedRightXGet = value
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWrongFill].
  
  	(interpreterProxy slotSizeOf: bitsOop) < (self lastExportedRightXGet - self lastExportedLeftXGet)
  		ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	interpreterProxy failed ifTrue:[^nil].
  
  	self fillBitmapSpan: (interpreterProxy firstIndexableField: bitsOop)
  		from: self lastExportedLeftXGet
  		to: self lastExportedRightXGet.
  
  	self statePut: GEStateScanningAET. "Back to scanning AET"
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 2. "Leave rcvr on stack"
  	doProfileStats ifTrue:[
  		self incrementStat: GWCountMergeFill by: 1.
  		self incrementStat: GWTimeMergeFill by: (interpreterProxy ioMicroMSecs - geProfileTime)].
  !

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveNeedsFlush (in category 'primitives-access') -----
  primitiveNeedsFlush
  	| failureCode needFlush |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	interpreterProxy methodArgumentCount = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 0)) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  	needFlush := self needsFlush.
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 1.
  	interpreterProxy pushBool: needFlush.!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveNeedsFlushPut (in category 'primitives-access') -----
  primitiveNeedsFlushPut
  	| failureCode needFlush |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	needFlush := interpreterProxy booleanValueOf: (interpreterProxy stackValue: 0).
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	needFlush == true 
  		ifTrue:[self needsFlushPut: 1]
  		ifFalse:[self needsFlushPut: 0].
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 1. "Leave rcvr on stack"
  !

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveNextActiveEdgeEntry (in category 'primitives-incremental') -----
  primitiveNextActiveEdgeEntry
  	"Note: No need to load either bitBlt or spanBuffer"
  	| failureCode edgeOop hasEdge edge |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	doProfileStats ifTrue:[geProfileTime := interpreterProxy ioMicroMSecs].
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)
  						requiredState: GEStateUpdateEdges or: GEStateCompleted) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	edgeOop := interpreterProxy stackObjectValue: 0.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	hasEdge := false.
  	self stateGet = GEStateCompleted ifFalse:[
  		hasEdge := self findNextExternalUpdateFromAET.
  		hasEdge ifTrue:[
  			edge := aetBuffer at: self aetStartGet.
  			self storeEdgeStateFrom: edge into: edgeOop.
  			"Do not advance to the next aet entry yet"
  			"self aetStartPut: self aetStartGet + 1."
  			self statePut: GEStateWaitingChange. "Wait for changed edge"
  		] ifFalse:[self statePut: GEStateAddingFromGET]. "Start over"
  	].
  	interpreterProxy failed ifTrue:[^nil].
  
  	self storeEngineStateInto: engine.
  
  	interpreterProxy pop: 2.
  	interpreterProxy pushBool: hasEdge not.
  	doProfileStats ifTrue:[
  		self incrementStat: GWCountNextAETEntry by: 1.
  		self incrementStat: GWTimeNextAETEntry by: (interpreterProxy ioMicroMSecs - geProfileTime)].
  !

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveNextFillEntry (in category 'primitives-incremental') -----
  primitiveNextFillEntry
  	"Note: No need to load bitBlt but must load spanBuffer"
  	| failureCode fillOop hasFill |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	doProfileStats ifTrue:[geProfileTime := interpreterProxy ioMicroMSecs].
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)
  						requiredState: GEStateScanningAET) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  	"Load span buffer for internal handling of fills"
  	(failureCode := self loadSpanBufferFrom:
  		(interpreterProxy fetchPointer: BESpanIndex ofObject: engine)) = 0
  			ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  	(self loadFormsFrom:
  		(interpreterProxy fetchPointer: BEFormsIndex ofObject: engine))
  			ifFalse:[^interpreterProxy primitiveFailFor: GEFFormLoadFailed].
  
  	"Check if we have to clear the span buffer before proceeding"
  	(self clearSpanBufferGet = 0) ifFalse:[
  		(self currentYGet bitAnd: self aaScanMaskGet) = 0
  			ifTrue:[self clearSpanBuffer].
  		self clearSpanBufferPut: 0].
  
  	fillOop := interpreterProxy stackObjectValue: 0.
  	hasFill := self findNextExternalFillFromAET.
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  	hasFill ifTrue:[self storeFillStateInto: fillOop].
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: GEFWrongFill].
  	hasFill
  		ifTrue:[	self statePut: GEStateWaitingForFill]
  		ifFalse:[	self wbStackClear.
  				self spanEndAAPut: 0.
  				self statePut: GEStateBlitBuffer].
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 2.
  	interpreterProxy pushBool: hasFill not.
  	doProfileStats ifTrue:[
  		self incrementStat: GWCountNextFillEntry by: 1.
  		self incrementStat: GWTimeNextFillEntry by: (interpreterProxy ioMicroMSecs - geProfileTime)]!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveNextGlobalEdgeEntry (in category 'primitives-incremental') -----
  primitiveNextGlobalEdgeEntry
  	"Note: No need to load either bitBlt or spanBuffer"
  	| failureCode edgeOop hasEdge edge |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	doProfileStats ifTrue:[geProfileTime := interpreterProxy ioMicroMSecs].
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)
  						requiredState: GEStateAddingFromGET) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	edgeOop := interpreterProxy stackObjectValue: 0.
  	hasEdge := self findNextExternalEntryFromGET.
  	hasEdge ifTrue:[
  		edge := getBuffer at: self getStartGet.
  		self storeEdgeStateFrom: edge into: edgeOop.
  		self getStartPut: self getStartGet + 1].
  
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: GEFWrongEdge].
  
  	hasEdge
  		ifTrue:[	self statePut: GEStateWaitingForEdge] "Wait for adding edges"
  		ifFalse:[ "Start scanning the AET"
  				self statePut: GEStateScanningAET.
  				self clearSpanBufferPut: 1. "Clear span buffer at next entry"
  				self aetStartPut: 0.
  				self wbStackClear].
  	self storeEngineStateInto: engine.
  
  	interpreterProxy pop: 2.
  	interpreterProxy pushBool: hasEdge not.
  	doProfileStats ifTrue:[
  		self incrementStat: GWCountNextGETEntry by: 1.
  		self incrementStat: GWTimeNextGETEntry by: (interpreterProxy ioMicroMSecs - geProfileTime)].
  !

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveRegisterExternalEdge (in category 'primitives-other') -----
  primitiveRegisterExternalEdge
  	| failureCode rightFillIndex leftFillIndex initialZ initialY initialX index  edge |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	interpreterProxy methodArgumentCount = 6 
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 6)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	rightFillIndex := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 0).
  	leftFillIndex := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 1).
  	initialZ := interpreterProxy stackIntegerValue: 2.
  	initialY := interpreterProxy stackIntegerValue: 3.
  	initialX := interpreterProxy stackIntegerValue: 4.
  	index := interpreterProxy stackIntegerValue: 5.
  	interpreterProxy failed
  		ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	(self allocateObjEntry: GEBaseEdgeSize) 
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWorkTooBig].
  
  	"Make sure the fills are okay"
  	((self isFillOkay: leftFillIndex)
  	and: [self isFillOkay: rightFillIndex])
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWrongFill].
  
  	edge := objUsed.
  	objUsed := edge + GEBaseEdgeSize.
  	"Install type and length"
  	self objectTypeOf: edge put: GEPrimitiveEdge.
  	self objectLengthOf: edge put: GEBaseEdgeSize.
  	self objectIndexOf: edge put: index.
  	"Install remaining stuff"
  	self edgeXValueOf: edge put: initialX.
  	self edgeYValueOf: edge put: initialY.
  	self edgeZValueOf: edge put: initialZ.
  	self edgeLeftFillOf: edge put: (self transformColor: leftFillIndex).
  	self edgeRightFillOf: edge put: (self transformColor: rightFillIndex).
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	interpreterProxy failed ifFalse:[
  		self storeEngineStateInto: engine.
  		interpreterProxy pop: 6. "Leave rcvr on stack"
  	].!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveRegisterExternalFill (in category 'primitives-other') -----
  primitiveRegisterExternalFill
  	| failureCode index  fill |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	interpreterProxy methodArgumentCount = 1 
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	index := interpreterProxy stackIntegerValue: 0.
  	interpreterProxy failed ifTrue:
  		[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	"Note: We *must* not allocate any fill with index 0"
  	fill := 0.
  	[fill = 0] whileTrue:[
  		(self allocateObjEntry: GEBaseEdgeSize) 
  			ifFalse:[^interpreterProxy primitiveFailFor: GEFWorkTooBig].
  		fill := objUsed.
  		objUsed := fill + GEBaseFillSize.
  		"Install type and length"
  		self objectTypeOf: fill put: GEPrimitiveFill.
  		self objectLengthOf: fill put: GEBaseFillSize.
  		self objectIndexOf: fill put: index.
  	].
  
  	interpreterProxy failed ifFalse:[
  		self storeEngineStateInto: engine.
  		interpreterProxy pop: 2.
  		interpreterProxy pushInteger: fill.
  	].!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveSetAALevel (in category 'primitives-access') -----
  primitiveSetAALevel
  	| failureCode level |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  	level := interpreterProxy stackIntegerValue: 0.
  	interpreterProxy failed
  		ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	self setAALevel: level.
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 1. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveSetBitBltPlugin (in category 'primitives-access') -----
  primitiveSetBitBltPlugin
  	"Primitive. Set the BitBlt plugin to use."
  	| pluginName length ptr needReload |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<var: 'ptr' type: #'char *'>
  	pluginName := interpreterProxy stackValue: 0.
  	"Must be string to work"
  	(interpreterProxy isBytes: pluginName) 
  		ifFalse:[^interpreterProxy primitiveFail].
  	length := interpreterProxy byteSizeOf: pluginName.
  	length >= 256 
  		ifTrue:[^interpreterProxy primitiveFail].
  	ptr := interpreterProxy firstIndexableField: pluginName.
  	needReload := false.
  	0 to: length-1 do:[:i|
  		"Compare and store the plugin to be used"
  		(bbPluginName at: i) = (ptr at: i) ifFalse:[
  			bbPluginName at: i put: (ptr at: i).
  			needReload := true]].
  	(bbPluginName at: length) = 0 ifFalse:[
  		bbPluginName at: length put: 0.
  		needReload := true].
  	needReload ifTrue:[
  		self initialiseModule 
  			ifFalse:[^interpreterProxy primitiveFail]].
  	interpreterProxy pop: 1. "Return receiver"!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveSetClipRect (in category 'primitives-access') -----
  primitiveSetClipRect
  	| failureCode rectOop |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	rectOop := interpreterProxy stackObjectValue: 0.
  	(interpreterProxy failed not
  	and: [(interpreterProxy isPointers: rectOop)
  	and: [(interpreterProxy slotSizeOf: rectOop) >= 2]])
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	self loadPoint: self point1Get from: (interpreterProxy fetchPointer: 0 ofObject: rectOop).
  	self loadPoint: self point2Get from: (interpreterProxy fetchPointer: 1 ofObject: rectOop).
  	interpreterProxy failed ifTrue:
  		[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	self clipMinXPut: (self point1Get at: 0).
  	self clipMinYPut: (self point1Get at: 1).
  	self clipMaxXPut: (self point2Get at: 0).
  	self clipMaxYPut: (self point2Get at: 1).
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 1. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveSetColorTransform (in category 'primitives-access') -----
  primitiveSetColorTransform
  	| failureCode transformOop |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	transformOop := interpreterProxy stackObjectValue: 0.
  	interpreterProxy failed
  		ifTrue: [^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	self loadColorTransformFrom: transformOop.
  	interpreterProxy failed
  		ifTrue: [^interpreterProxy primitiveFailFor: GEFEntityLoadFailed].
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 1. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveSetDepth (in category 'primitives-access') -----
  primitiveSetDepth
  	| failureCode depth |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	depth := interpreterProxy stackIntegerValue: 0.
  	interpreterProxy failed
  		ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	self currentZPut: depth.
  
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 1. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveSetEdgeTransform (in category 'primitives-access') -----
  primitiveSetEdgeTransform
  	| failureCode transformOop |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	transformOop := interpreterProxy stackObjectValue: 0.
  	interpreterProxy failed
  		ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	self loadEdgeTransformFrom: transformOop.
  	interpreterProxy failed
  		ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 1. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEngineBase>>primitiveSetOffset (in category 'primitives-access') -----
  primitiveSetOffset
  	| failureCode pointOop |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	pointOop := interpreterProxy stackValue: 0.
  	(interpreterProxy fetchClassOf: pointOop) = interpreterProxy classPoint
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	self loadPoint: self point1Get from: pointOop.
  	interpreterProxy failed
  		ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	self destOffsetXPut: (self point1Get at: 0).
  	self destOffsetYPut: (self point1Get at: 1).
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 1. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEnginePlugin>>primitiveAddBezier (in category 'primitives') -----
  primitiveAddBezier
  	| failureCode leftFill rightFill viaOop endOop startOop nSegments |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	"Fail if we have the wrong number of arguments"
  	interpreterProxy methodArgumentCount = 5 
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	rightFill := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 0).
  	leftFill := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 1).
  	viaOop := interpreterProxy stackObjectValue: 2.
  	endOop := interpreterProxy stackObjectValue: 3.
  	startOop := interpreterProxy stackObjectValue: 4.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 5)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	"Make sure the fills are okay"
  	((self isFillOkay: leftFill) and:[self isFillOkay: rightFill])
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWrongFill].
  
  	"Do a quick check if the fillIndices are equal - if so, just ignore it"
  	leftFill = rightFill & false ifTrue:[
  		^interpreterProxy pop: 6. "Leave rcvr on stack"
  	].
  
  
  	self loadPoint: self point1Get from: startOop.
  	self loadPoint: self point2Get from: viaOop.
  	self loadPoint: self point3Get from: endOop.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	self transformPoints: 3.
  
  	nSegments := self loadAndSubdivideBezierFrom: self point1Get 
  						via: self point2Get 
  						to: self point3Get 
  						isWide: false.
  	self needAvailableSpace: nSegments * GBBaseSize.
  	engineStopped ifFalse:[
  		leftFill := self transformColor: leftFill.
  		rightFill := self transformColor: rightFill].
  	engineStopped ifFalse:[
  		self loadWideBezier: 0 lineFill: 0 leftFill: leftFill rightFill: rightFill n: nSegments.
  	].
  	engineStopped ifTrue:[
  		"Make sure the stack is okay"
  		self wbStackClear.
  		^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	interpreterProxy failed
  		ifTrue:[^interpreterProxy primitiveFailFor: GEFEntityLoadFailed].
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 5. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEnginePlugin>>primitiveAddBezierShape (in category 'primitives') -----
  primitiveAddBezierShape
  	| failureCode points lineFill lineWidth fillIndex length pointsIsArray segSize nSegments |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	"Fail if we have the wrong number of arguments"
  	interpreterProxy methodArgumentCount = 5 
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	lineFill := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 0).
  	lineWidth := interpreterProxy stackIntegerValue: 1.
  	fillIndex := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 2).
  	nSegments := interpreterProxy stackIntegerValue: 3.
  	points := interpreterProxy stackObjectValue: 4.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 5)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	"First, do a check if the points look okay"
  	length := interpreterProxy slotSizeOf: points.
  	(interpreterProxy isWords: points) ifTrue:[
  		pointsIsArray := false.
  		"Either PointArray or ShortPointArray"
  		(length = (nSegments * 3) or:[length = (nSegments * 6)])
  			ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	] ifFalse:["Must be Array of points"
  		(interpreterProxy isArray: points)
  			ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  		length = (nSegments * 3)
  			ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  		pointsIsArray := true.
  	].
  
  	"Now check that we have some hope to have enough free space.
  	Do this by assuming nPoints boundaries of maximum size,
  	hoping that most of the fills will be colors and many boundaries
  	will be line segments"
  
  	(lineWidth = 0 or:[lineFill = 0])
  		ifTrue:[segSize := GLBaseSize]
  		ifFalse:[segSize := GLWideSize].
  	(self needAvailableSpace: segSize * nSegments)
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWorkTooBig].
  
  	"Check the fills"
  	((self isFillOkay: lineFill) and:[self isFillOkay: fillIndex])
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWrongFill]. 
  
  	"Transform colors"
  	lineFill := self transformColor: lineFill.
  	fillIndex := self transformColor: fillIndex.
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	"Check if have anything at all to do"
  	((lineFill = 0 or:[lineWidth = 0]) and:[fillIndex = 0])
  		ifTrue:[^interpreterProxy pop: 5].
  
  	"Transform the lineWidth"
  	lineWidth = 0 ifFalse:[
  		lineWidth := self transformWidth: lineWidth.
  		lineWidth < 1 ifTrue:[lineWidth := 1]].
  
  	"And load the actual shape"
  	pointsIsArray ifTrue:[
  		self loadArrayShape: points nSegments: nSegments
  			fill: fillIndex lineWidth: lineWidth lineFill: lineFill.
  	] ifFalse:[
  		self loadShape: (interpreterProxy firstIndexableField: points) nSegments: nSegments
  			fill: fillIndex lineWidth: lineWidth lineFill: lineFill 
  			pointsShort: (nSegments * 3 = length)].
  
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	interpreterProxy failed
  		ifTrue:[^interpreterProxy primitiveFailFor: GEFEntityLoadFailed].
  	self needsFlushPut: 1.
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 5. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEnginePlugin>>primitiveAddBitmapFill (in category 'primitives') -----
  primitiveAddBitmapFill
  
  	| failureCode nrmOop dirOop originOop tileFlag fill xIndex cmOop formOop |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	"Fail if we have the wrong number of arguments"
  	interpreterProxy methodArgumentCount = 7 
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	xIndex := interpreterProxy stackIntegerValue: 0.
  	xIndex <= 0 ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	nrmOop := interpreterProxy stackObjectValue: 1.
  	dirOop := interpreterProxy stackObjectValue: 2.
  	originOop := interpreterProxy stackObjectValue: 3.
  	tileFlag := interpreterProxy booleanValueOf: (interpreterProxy stackValue: 4).
  	cmOop := interpreterProxy stackObjectValue: 5.
  	formOop := interpreterProxy stackObjectValue: 6.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 7)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	self loadPoint: self point1Get from: originOop.
  	self loadPoint: self point2Get from: dirOop.
  	self loadPoint: self point3Get from: nrmOop.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: GEFBadPoint].
  
  	fill := self loadBitmapFill: formOop 
  				colormap: cmOop
  				tile: (tileFlag ifTrue:[1] ifFalse:[0])
  				from: self point1Get 
  				along: self point2Get 
  				normal: self point3Get 
  				xIndex: xIndex-1.
  	engineStopped ifTrue:[
  		"Make sure the stack is okay"
  		^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	interpreterProxy failed
  		ifTrue:[^interpreterProxy primitiveFailFor: GEFEntityLoadFailed].
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 8 thenPush: (interpreterProxy positive32BitIntegerFor: fill)!

Item was changed:
  ----- Method: BalloonEnginePlugin>>primitiveAddCompressedShape (in category 'primitives') -----
  primitiveAddCompressedShape
  	| failureCode fillIndexList lineFills lineWidths rightFills leftFills nSegments points pointsShort |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	"Fail if we have the wrong number of arguments"
  	interpreterProxy methodArgumentCount = 7 
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	fillIndexList := interpreterProxy stackObjectValue: 0.
  	lineFills := interpreterProxy stackObjectValue: 1.
  	lineWidths := interpreterProxy stackObjectValue: 2.
  	rightFills := interpreterProxy stackObjectValue: 3.
  	leftFills := interpreterProxy stackObjectValue: 4.
  	nSegments := interpreterProxy stackIntegerValue: 5.
  	points := interpreterProxy stackObjectValue: 6.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 7)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	"First, do a check if the compressed shape is okay"
  	(self checkCompressedShape: points 
  			segments: nSegments 
  			leftFills: leftFills 
  			rightFills: rightFills 
  			lineWidths: lineWidths 
  			lineFills: lineFills 
  			fillIndexList: fillIndexList) ifFalse:[^interpreterProxy primitiveFailFor: GEFEntityCheckFailed].
  
  	"Now check that we have some hope to have enough free space.
  	Do this by assuming nSegments boundaries of maximum size,
  	hoping that most of the fills will be colors and many boundaries
  	will be line segments"
  
  	(self needAvailableSpace: (GBBaseSize max: GLBaseSize) * nSegments)
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWorkTooBig].
  
  	"Check if the points are short"
  	pointsShort := (interpreterProxy slotSizeOf: points) = (nSegments * 3).
  
  	"Then actually load the compressed shape"
  	self loadCompressedShape: (interpreterProxy firstIndexableField: points)
  			segments: nSegments 
  			leftFills: (interpreterProxy firstIndexableField: leftFills)
  			rightFills: (interpreterProxy firstIndexableField: rightFills)
  			lineWidths: (interpreterProxy firstIndexableField: lineWidths)
  			lineFills: (interpreterProxy firstIndexableField: lineFills)
  			fillIndexList: (interpreterProxy firstIndexableField: fillIndexList)
  			pointShort: pointsShort.
  
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: GEFEntityLoadFailed].
  	self needsFlushPut: 1.
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 7. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEnginePlugin>>primitiveAddGradientFill (in category 'primitives') -----
  primitiveAddGradientFill
  
  	| failureCode isRadial nrmOop dirOop originOop rampOop fill |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	"Fail if we have the wrong number of arguments"
  	interpreterProxy methodArgumentCount = 5 
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	isRadial := interpreterProxy booleanValueOf: (interpreterProxy stackValue: 0).
  	nrmOop := interpreterProxy stackValue: 1.
  	dirOop := interpreterProxy stackValue: 2.
  	originOop := interpreterProxy stackValue: 3.
  	rampOop := interpreterProxy stackValue: 4.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 5)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	self loadPoint: self point1Get from: originOop.
  	self loadPoint: self point2Get from: dirOop.
  	self loadPoint: self point3Get from: nrmOop.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: GEFBadPoint].
  
  	fill := self loadGradientFill: rampOop 
  				from: self point1Get 
  				along: self point2Get 
  				normal: self point3Get 
  				isRadial: isRadial.
  	engineStopped ifTrue:[
  		"Make sure the stack is okay"
  		^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	interpreterProxy failed
  		ifTrue: [^interpreterProxy primitiveFailFor: GEFEntityLoadFailed].
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 6 thenPush: (interpreterProxy positive32BitIntegerFor: fill)!

Item was changed:
  ----- Method: BalloonEnginePlugin>>primitiveAddLine (in category 'primitives') -----
  primitiveAddLine
  	| failureCode leftFill rightFill endOop startOop |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	"Fail if we have the wrong number of arguments"
  	interpreterProxy methodArgumentCount = 4 
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	rightFill := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 0).
  	leftFill := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 1).
  	endOop := interpreterProxy stackObjectValue: 2.
  	startOop := interpreterProxy stackObjectValue: 3.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 4)
  			requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	"Make sure the fills are okay"
  	((self isFillOkay: leftFill) and:[self isFillOkay: rightFill])
  			ifFalse:[^interpreterProxy primitiveFailFor: GEFWrongFill].
  
  	"Load the points"
  	self loadPoint: self point1Get from: startOop.
  	self loadPoint: self point2Get from: endOop.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: GEFBadPoint].
  
  	"Transform points"
  	self transformPoints: 2.
  
  	"Transform colors"
  	leftFill := self transformColor: leftFill.
  	rightFill := self transformColor: rightFill.
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	"Load line"
  	self loadWideLine: 0 from: self point1Get to: self point2Get 
  		lineFill: 0 leftFill: leftFill rightFill: rightFill.
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: GEFEntityLoadFailed].
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 4. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEnginePlugin>>primitiveAddOval (in category 'primitives') -----
  primitiveAddOval
  	| failureCode fillIndex borderWidth borderIndex endOop startOop |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	"Fail if we have the wrong number of arguments"
  	interpreterProxy methodArgumentCount = 5 
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	borderIndex := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 0).
  	borderWidth := interpreterProxy stackIntegerValue: 1.
  	fillIndex := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 2).
  	endOop := interpreterProxy stackObjectValue: 3.
  	startOop := interpreterProxy stackObjectValue: 4.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 5)
  					requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	"Make sure the fills are okay"
  	((self isFillOkay: borderIndex) and:[self isFillOkay: fillIndex])
  			ifFalse:[^interpreterProxy primitiveFailFor: GEFWrongFill].
  
  	"Transform colors"
  	fillIndex := self transformColor: fillIndex.
  	borderIndex := self transformColor: borderIndex.
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	"Check if we have anything at all to do"
  	(fillIndex = 0 and:[borderIndex = 0 or:[borderWidth <= 0]]) ifTrue:[
  		^interpreterProxy pop: 5. "Leave rcvr on stack"
  	].
  
  	"Make sure we have some space"
  	(self needAvailableSpace: (16 * GBBaseSize)) 
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWorkTooBig].
  
  	"Check if we need a border"
  	(borderWidth > 0 and:[borderIndex ~= 0]) 
  		ifTrue:[borderWidth := self transformWidth: borderWidth]
  		ifFalse:[borderWidth := 0].
  
  
  	"Load the rectangle points"
  	self loadPoint: self point1Get from: startOop.
  	self loadPoint: self point2Get from: endOop.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: GEFBadPoint].
  
  	self loadOval: borderWidth lineFill: borderIndex 
  		leftFill: 0 rightFill: fillIndex.
  
  	engineStopped ifTrue:[
  		self wbStackClear.
  		^interpreterProxy primitiveFailFor: GEFEngineStopped.
  	].
  	interpreterProxy failed
  		ifTrue:[^interpreterProxy primitiveFailFor: GEFEntityLoadFailed].
  	self needsFlushPut: 1.
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 5. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEnginePlugin>>primitiveAddPolygon (in category 'primitives') -----
  primitiveAddPolygon
  	| failureCode points lineFill lineWidth fillIndex nPoints length pointsIsArray segSize |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	"Fail if we have the wrong number of arguments"
  	interpreterProxy methodArgumentCount = 5 
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	lineFill := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 0).
  	lineWidth := interpreterProxy stackIntegerValue: 1.
  	fillIndex := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 2).
  	nPoints := interpreterProxy stackIntegerValue: 3.
  	points := interpreterProxy stackObjectValue: 4.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 5)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	"First, do a check if the points look okay"
  	length := interpreterProxy slotSizeOf: points.
  	(interpreterProxy isWords: points) ifTrue:[
  		pointsIsArray := false.
  		"Either PointArray or ShortPointArray"
  		(length = nPoints or:[nPoints * 2 = length])
  			ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	] ifFalse:["Must be Array of points"
  		(interpreterProxy isArray: points)
  			ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  		length = nPoints
  			ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  		pointsIsArray := true.
  	].
  
  	"Now check that we have some hope to have enough free space.
  	Do this by assuming nPoints boundaries of maximum size,
  	hoping that most of the fills will be colors and many boundaries
  	will be line segments"
  
  	(lineWidth = 0 or:[lineFill = 0])
  		ifTrue:[segSize := GLBaseSize]
  		ifFalse:[segSize := GLWideSize].
  	(self needAvailableSpace: segSize * nPoints)
  		ifFalse:[^interpreterProxy primitiveFail].
  
  	"Check the fills"
  	((self isFillOkay: lineFill) and:[self isFillOkay: fillIndex])
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWrongFill]. 
  
  	"Transform colors"
  	lineFill := self transformColor: lineFill.
  	fillIndex := self transformColor: fillIndex.
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	"Check if have anything at all to do"
  	((lineFill = 0 or:[lineWidth = 0]) and:[fillIndex = 0])
  		ifTrue:[^interpreterProxy pop: 5].
  
  	"Transform the lineWidth"
  	lineWidth = 0 ifFalse:[lineWidth := self transformWidth: lineWidth].
  
  	"And load the actual polygon"
  	pointsIsArray ifTrue:[
  		self loadArrayPolygon: points nPoints: nPoints
  			fill: fillIndex lineWidth: lineWidth lineFill: lineFill
  	] ifFalse:[
  		self loadPolygon: (interpreterProxy firstIndexableField: points) nPoints: nPoints 
  			fill: fillIndex lineWidth: lineWidth lineFill: lineFill 
  			pointsShort: (nPoints = length)].
  
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	interpreterProxy failed ifTrue:
  		[^interpreterProxy primitiveFailFor: GEFEntityLoadFailed].
  	self needsFlushPut: 1.
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 5. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEnginePlugin>>primitiveAddRect (in category 'primitives') -----
  primitiveAddRect
  	| failureCode fillIndex borderWidth borderIndex endOop startOop |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  
  	"Fail if we have the wrong number of arguments"
  	interpreterProxy methodArgumentCount = 5 
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	borderIndex := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 0).
  	borderWidth := interpreterProxy stackIntegerValue: 1.
  	fillIndex := interpreterProxy positive32BitValueOf: (interpreterProxy stackValue: 2).
  	endOop := interpreterProxy stackObjectValue: 3.
  	startOop := interpreterProxy stackObjectValue: 4.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 5)
  						requiredState: GEStateUnlocked) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	"Make sure the fills are okay"
  	((self isFillOkay: borderIndex) and:[self isFillOkay: fillIndex])
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWrongFill].
  
  	"Transform colors"
  	borderIndex := self transformColor: borderIndex.
  	fillIndex := self transformColor: fillIndex.
  	engineStopped ifTrue:[^interpreterProxy primitiveFailFor: GEFEngineStopped].
  
  	"Check if we have anything at all to do"
  	(fillIndex = 0 and:[borderIndex = 0 or:[borderWidth = 0]]) ifTrue:[
  		^interpreterProxy pop: 5. "Leave rcvr on stack"
  	].
  
  	"Make sure we have some space"
  	(self needAvailableSpace: (4 * GLBaseSize)) 
  		ifFalse:[^interpreterProxy primitiveFailFor: GEFWorkTooBig].
  
  	"Check if we need a border"
  	(borderWidth > 0 and:[borderIndex ~= 0]) 
  		ifTrue:[borderWidth := self transformWidth: borderWidth]
  		ifFalse:[borderWidth := 0].
  
  	"Load the rectangle"
  	self loadPoint: self point1Get from: startOop.
  	self loadPoint: self point3Get from: endOop.
  	interpreterProxy failed ifTrue:[^interpreterProxy primitiveFailFor: GEFBadPoint].
  	self point2Get at: 0 put: (self point3Get at: 0).
  	self point2Get at: 1 put: (self point1Get at: 1).
  	self point4Get at: 0 put: (self point1Get at: 0).
  	self point4Get at: 1 put: (self point3Get at: 1).
  	"Transform the points"
  	self transformPoints: 4.
  
  	self loadRectangle: borderWidth lineFill: borderIndex leftFill: 0 rightFill: fillIndex.
  
  	interpreterProxy failed ifTrue:
  		[^interpreterProxy primitiveFailFor: GEFEntityLoadFailed].
  	self needsFlushPut: 1.
  	self storeEngineStateInto: engine.
  	interpreterProxy pop: 5. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEnginePlugin>>primitiveGetBezierStats (in category 'primitives') -----
  primitiveGetBezierStats
  	| failureCode statOop stats |
+ 	<export: true flags: #(FastCPrimitiveFlag FastCPrimitiveAlignForFloatsFlag)>
- 	<export: true>
  	<inline: false>
  	<var: 'stats' type: #'int *'>
  
  	interpreterProxy methodArgumentCount = 1
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadNumArgs].
  
  	(failureCode := self quickLoadEngineFrom: (interpreterProxy stackValue: 1)) = 0
  		ifFalse:[^interpreterProxy primitiveFailFor: failureCode].
  
  	statOop := interpreterProxy stackObjectValue: 0.
  	(interpreterProxy failed not
  	and: [(interpreterProxy isWords: statOop)
  	and: [(interpreterProxy slotSizeOf: statOop) >= 4]])
  		ifFalse:[^interpreterProxy primitiveFailFor: PrimErrBadArgument].
  	stats := interpreterProxy firstIndexableField: statOop.
  	stats at: 0 put: (stats at: 0) + (workBuffer at: GWBezierMonotonSubdivisions).
  	stats at: 1 put: (stats at: 1) + (workBuffer at: GWBezierHeightSubdivisions).
  	stats at: 2 put: (stats at: 2) + (workBuffer at: GWBezierOverflowSubdivisions).
  	stats at: 3 put: (stats at: 3) + (workBuffer at: GWBezierLineConversions).
  
  	interpreterProxy pop: 1. "Leave rcvr on stack"!

Item was changed:
  ----- Method: BalloonEngineSimulation>>stepToFirstBezierIn:at: (in category 'generated overrides') -----
  stepToFirstBezierIn: bezier at: yValue
  	"Initialize the bezier at yValue.
  	TODO: Check if reducing maxSteps from 2*deltaY to deltaY 
  		brings a *significant* performance improvement.
  		In theory this should make for double step performance
  		but will cost in quality. Might be that the AA stuff will
  		compensate for this - but I'm not really sure."
  
  	<inline: false>
+ 	<var: 'updateData' type: #'int *'>
- 	<var: #updateData type: 'int *'>
  	| updateData deltaY maxSteps scaledStepSize squaredStepSize startX startY viaX viaY endX endY fwX1 fwX2 fwY1 fwY2 fwDx fwDDx fwDy fwDDy |
  	((self isWide: bezier) not and: [ yValue >= (self bezierEndYOf: bezier) ])
  		ifTrue: [ ^ self edgeNumLinesOf: bezier put: 0 ].	"Do a quick check if there is anything at all to do"	"Now really initialize bezier"
  	startX := self edgeXValueOf: bezier.
  	startY := self edgeYValueOf: bezier.
  	viaX := self bezierViaXOf: bezier.
  	viaY := self bezierViaYOf: bezier.
  	endX := self bezierEndXOf: bezier.
  	endY := self bezierEndYOf: bezier.
  	deltaY := endY - startY.	"Initialize integer forward differencing"
  	fwX1 := (viaX - startX) * 2.
  	fwX2 := startX + endX - (viaX * 2).
  	fwY1 := (viaY - startY) * 2.
  	fwY2 := startY + endY - (viaY * 2).
  	maxSteps := deltaY * 2.
  	maxSteps < 2
  		ifTrue: [ maxSteps := 2 ].
  	scaledStepSize := 16r1000000 // maxSteps.
  	squaredStepSize := self absoluteSquared8Dot24: scaledStepSize.
  	fwDx := fwX1 * scaledStepSize.
  	fwDDx := fwX2 * squaredStepSize * 2.
  	fwDx := fwDx + (fwDDx // 2).
  	fwDy := fwY1 * scaledStepSize.
  	fwDDy := fwY2 * squaredStepSize * 2.
  	fwDy := fwDy + (fwDDy // 2).	"Store the values"
  	self edgeNumLinesOf: bezier put: deltaY.
  	updateData := self bezierUpdateDataOf: bezier.
  	updateData at: GBUpdateX put: (startX * 256) asC_int.
  	updateData at: GBUpdateY put: (startY * 256) asC_int.
  	updateData at: GBUpdateDX put: fwDx asC_int.
  	updateData at: GBUpdateDY put: fwDy asC_int.
  	updateData at: GBUpdateDDX put: fwDDx asC_int.
  	updateData at: GBUpdateDDY put: fwDDy asC_int.	"And step to the first scan line"
  	(startY := self edgeYValueOf: bezier) = yValue
  		ifFalse: [ 
  			self stepToNextBezierIn: bezier at: yValue.	"Adjust number of lines remaining"
  			self edgeNumLinesOf: bezier put: deltaY - (yValue - startY) ]!

Item was changed:
  ----- Method: BalloonEngineSimulation>>stepToNextBezierForward:at: (in category 'generated overrides') -----
  stepToNextBezierForward: updateData at: yValue
  	"Incrementally step to the next scan line in the given bezier update data.
  	Note: This method has been written so that inlining works, e.g.,
+ 		not declaring updateData as 'int *' but casting it on every use."
- 		not declaring updateData as 'int*' but casting it on every use."
  
+ 	<var: 'updateData' type: #'int *'>
- 	<var: #updateData type: 'int *'>
  	<inline: true>
  	| minY lastX lastY fwDx fwDy |
  	lastX := updateData at: GBUpdateX.
  	lastY := updateData at: GBUpdateY.
  	fwDx := updateData at: GBUpdateDX.
  	fwDy := updateData at: GBUpdateDY.
  	minY := yValue * 256.	"Step as long as we haven't yet reached minY and also
  	as long as fwDy is greater than zero thus stepping down.
  	Note: The test for fwDy should not be necessary in theory
  		but is a good insurance in practice."
  	[ minY > lastY and: [ fwDy >= 0 ] ]
  		whileTrue: [ 
  			lastX := lastX + (fwDx + 16r8000 signedBitShift: -16).
  			lastY := lastY + (fwDy + 16r8000 signedBitShift: -16).
  			fwDx := fwDx + (updateData at: GBUpdateDDX).
  			fwDy := fwDy + (updateData at: GBUpdateDDY) ].
  	updateData at: GBUpdateX put: lastX asC_int.
  	updateData at: GBUpdateY put: lastY asC_int.
  	updateData at: GBUpdateDX put: fwDx asC_int.
  	updateData at: GBUpdateDY put: fwDy asC_int.
  	^ lastX signedBitShift: -8!



More information about the Vm-dev mailing list