[Vm-dev] VM Maker: VMMaker.oscog-nice.1994.mcz

commits at source.squeak.org commits at source.squeak.org
Fri Nov 18 03:23:03 UTC 2016


Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1994.mcz

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

Name: VMMaker.oscog-nice.1994
Author: nice
Time: 18 November 2016, 4:21:24.158309 am
UUID: f00dbc12-d05a-4c73-b825-6281ee7ec54f
Ancestors: VMMaker.oscog-eem.1993

Fix an unused value warning in Balloon/Bezier

I think that the intention was to use 2nd derivative to decide direction when 1st derivative is null.

Fix a typo in tempolines comment.

Fix primitiveBeCursor - generated code could dereference a null pointer offsetObj due to misplaced block end.
Also a null pointer cursorObj could be dereferenced if 2 arguments or more were passed to the primitive.

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

Item was changed:
  ----- Method: BalloonEnginePlugin>>stepToFirstWideBezierIn:at: (in category 'beziers-wide') -----
  stepToFirstWideBezierIn: bezier at: yValue
  	"Initialize the bezier at yValue"	
  	| lineWidth startY nLines yEntry yExit lineOffset endX xDir |
  	<inline: false>
  
  	"Get some values"
  	lineWidth := self wideBezierExtentOf: bezier.
  	lineOffset := self offsetFromWidth: lineWidth.
  
  	"Compute the incremental values of the bezier"
  	endX := self bezierEndXOf: bezier.
  	startY := self edgeYValueOf: bezier.
  	self stepToFirstBezierIn: bezier at: startY.
  	nLines := (self edgeNumLinesOf: bezier).
  
  	"Copy the incremental update data"
  	0 to: 5 do:[:i|
  		(self wideBezierUpdateDataOf: bezier) at: i put:
  			((self bezierUpdateDataOf: bezier) at: i).
  	].
  
  	"Compute primary x direction of curve (e.g., 1: left to right; -1: right to left)."
  	xDir := ((self bezierUpdateDataOf: bezier) at: GBUpdateDX).
+ 	xDir = 0 ifTrue:[xDir := ((self bezierUpdateDataOf: bezier) at: GBUpdateDDX)].
- 	xDir = 0 ifTrue:[((self bezierUpdateDataOf: bezier) at: GBUpdateDDX)].
  	xDir >= 0 ifTrue:[xDir := 1] ifFalse:[xDir := -1].
  
  	"Adjust the curve to start/end at the right position"
  	xDir < 0
  		ifTrue:[self adjustWideBezierLeft: bezier width: lineWidth offset: lineOffset endX: endX]
  		ifFalse:[self adjustWideBezierRight: bezier width: lineWidth offset: lineOffset endX: endX].
  
  	"Adjust the last value for horizontal lines"
  	nLines = 0 ifTrue:[(self bezierUpdateDataOf: bezier) at: GBUpdateX put: 
  						(self bezierFinalXOf: bezier) * 256].
  	"Adjust the number of lines to include the lineWidth"
  	self edgeNumLinesOf: bezier put: nLines + lineWidth.
  
  	"Compute the points where we have to turn on/off the fills"
  	yEntry := 0.						"turned on at lineOffset"
  	yExit := 0 - nLines - lineOffset.	"turned off at zero"
  	self wideBezierEntryOf: bezier put: yEntry.
  	self wideBezierExitOf: bezier put: yExit.
  
  	"Turn the fills on/off as necessary"
  	(yEntry >= lineOffset and:[yExit < 0])
  		ifTrue:[self edgeFillsValidate: bezier]
  		ifFalse:[self edgeFillsInvalidate: bezier].
  
  	self computeFinalWideBezierValues: bezier width: lineWidth.
  
  	"And step to the first scan line"
  	startY = yValue ifFalse:[
  		"Note: Must single step here so that entry/exit works"
  		startY to: yValue-1 do:[:i| self stepToNextWideBezierIn: bezier at: i].
  		"Adjust number of lines remaining"
  		self edgeNumLinesOf: bezier put: (self edgeNumLinesOf: bezier) - (yValue - startY).
  	].!

Item was changed:
  ----- Method: Cogit class>>trampolines (in category 'documentation') -----
  trampolines
  	"Trampolines are called from machine-code for a number of tasks (e.g. doing an unlinked send,
  	 creating a closure, doing a non-local return, etc, etc.
  	 Some trampolines save their return pc on the Smalltalk stack, and some pop it into instructionPointer,
  	 depending on whether the trampoline always returns or whether control might transfer elsewhere,
  	 or depending on whether the callee run-time routine expects to see a normal Smalltalk stack.  This
  	 documents which trampolines do what and why.
  
  ceSend0Args .. ceSendNArgs, ceSuperSend0Args..ceSuperSendNArgs
  	return pc left on stack because it is the return pc of the send and must be there
  
  ceMethodAbort, cePICAbort
  	return pc left on stack because it is used to locate the failing send target method/PIC of a linked send
  
  ceClosureCopyTrampoline
  	return pc left on stack because ceClosureCopy:... always returns directly
  
  cePushActiveContextTrampoline
  	return pc left on stack because cePushActiveContext always returns directly
  
  ceNonLocalReturnTrampoline
  	pops return pc into instructionPointer
  
  ceBaseFrameReturnTrampoline
  	this is returned-to and never called; i.e. it is the return pc of a base machine-code frame
  
  ceCreateNewArrayTrampoline
  	return pc left on stack because ceNewArraySlotSize always returns directly
  
  ceSendMustBeBooleanTrampoline
  	return pc left on stack because it is the return pc of the send and must be there
  
  ceCheckForInterruptsTrampoline
  	pops return pc into instructionPointer
  
  ceCPICMissTrampoline
  	return pc left on stack because it is used to locate the failing send target PIC of a linked send
  
  ceSendFromInLineCacheMissTrampoline
+ 	not used, but its address is used as a key in the simulator.  An open PIC calls ceSendFromInLineCacheMiss
+ 	after it has switched from the Smalltalk to the C stack (an inline trampoline) hence there is no return pc
- 	not used, but its addres is used as a key in the simulator.  An open PIC calls ceSendFromInLineCacheMiss
- 	after it has switched from the Smalltalk to teh C stack (an inline trampoline) hence there is no return pc
  	left on the Smalltalk stack (except that of the send that invoked the open PIC).
  
  ceStoreCheckTrampoline
  	return pc left on stack because ceStoreCheck always returns directly
  
  ceFetchContextInstVarTrampoline
  	return pc left on stack because ceContextInstVar always returns directly.
  	ceContextInstVar manages popping the pc into instructionPointer if necessary.
  
  ceStoreContextInstVarTrampoline
  	return pc left on stack because ceContextInstVarvalue always returns directly.
  	ceContextInstVarvalue manages popping the pc into instructionPointer if necessary.
  
  cePositive32BitIntegerTrampoline
  	return pc left on stack because cePositive32BitInteger always returns directly
  	
  ceReturnToInterpreterTrampoline
  	this is returned-to and never called; i.e. it is the return pc of a machine-code frame with an interpreted callee
  
  ceResendCannotReturnTrampoline
  	this is returned-to and never called; it is the pc for a machine-code frame which has been returned from
  
  ceEnterCogCodePopReceiverReg
  	this is an enilopmart and not called from machine code
  
  cePrimReturnEnterCogCode
  	this is an enilopmart and not called from machine code
  
  ceTraceLinkedSendTrampoline
  	return pc left on stack because ceTraceLinkedSend always returns directly
  
  ceTraceBlockActivationTrampoline
  	return pc left on stack because ceTraceBlockActivation always returns directly
  
  ceTraceStoreTrampoline
  	return pc left on stack because ceTraceStore always returns directly"!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveBeCursor (in category 'I/O primitives') -----
  primitiveBeCursor
  	"Set the cursor to the given shape. The Mac only supports 16x16 pixel cursors. Cursor offsets are handled by Smalltalk."
  
  	| cursorObj maskBitsIndex maskObj bitsObj extentX extentY depth offsetObj offsetX offsetY cursorBitsIndex ourCursor |
  
  	argumentCount = 0 ifTrue: [
  		cursorObj := self stackTop.
  		maskBitsIndex := nil].
  	argumentCount = 1 ifTrue: [
  		cursorObj := self stackValue: 1.
  		maskObj := self stackTop].
  	self success: argumentCount < 2.
  
- 	self success: ((objectMemory isPointers: cursorObj) and: [(objectMemory lengthOf: cursorObj) >= 5]).
  	self successful ifTrue: [
+ 		self success: ((objectMemory isPointers: cursorObj) and: [(objectMemory lengthOf: cursorObj) >= 5])].
+ 	self successful ifTrue: [
  		bitsObj := objectMemory fetchPointer: 0 ofObject: cursorObj.
  		extentX := self fetchInteger: 1 ofObject: cursorObj.
  		extentY := self fetchInteger: 2 ofObject: cursorObj.
  		depth := self fetchInteger: 3 ofObject: cursorObj.
+ 		offsetObj := objectMemory fetchPointer: 4 ofObject: cursorObj.
+ 		self success: ((objectMemory isPointers: offsetObj) and: [(objectMemory lengthOf: offsetObj) >= 2])].
- 		offsetObj := objectMemory fetchPointer: 4 ofObject: cursorObj].
- 		self success: ((objectMemory isPointers: offsetObj) and: [(objectMemory lengthOf: offsetObj) >= 2]).
  
  	self successful ifTrue: [
  		offsetX := self fetchInteger: 0 ofObject: offsetObj.
  		offsetY := self fetchInteger: 1 ofObject: offsetObj.
  		(argumentCount = 0 and: [depth = 32])
  			ifTrue: [
  				"Support arbitrary-sized 32 bit ARGB forms --bf 3/1/2007 23:51"
  				self success: ((extentX > 0) and: [extentY > 0]).
  				self success: ((offsetX >= (extentX * -1)) and: [offsetX <= 0]).
  				self success: ((offsetY >= (extentY * -1)) and: [offsetY <= 0]).
  				self success: ((objectMemory isWords: bitsObj) and: [(objectMemory lengthOf: bitsObj) = (extentX * extentY)]).
  				cursorBitsIndex := bitsObj + objectMemory baseHeaderSize.
  				self cCode: '' inSmalltalk:
  					[ourCursor := Cursor
  						extent: extentX @ extentY
  						depth: 32
  						fromArray: ((1 to: extentX * extentY) collect: [:i |
  							objectMemory fetchLong32: i-1 ofObject: bitsObj])
  						offset: offsetX  @ offsetY]]
  			ifFalse: [
  				self success: ((extentX = 16) and: [extentY = 16 and: [depth = 1]]).
  				self success: ((offsetX >= -16) and: [offsetX <= 0]).
  				self success: ((offsetY >= -16) and: [offsetY <= 0]).
  				self success: ((objectMemory isWords: bitsObj) and: [(objectMemory lengthOf: bitsObj) = 16]).
  				cursorBitsIndex := bitsObj + objectMemory baseHeaderSize.
  				self cCode: '' inSmalltalk:
  					[ourCursor := Cursor
  						extent: extentX @ extentY
  						fromArray: ((1 to: 16) collect: [:i |
  							((objectMemory fetchLong32: i-1 ofObject: bitsObj) >> (objectMemory wordSize*8 - 16)) bitAnd: 16rFFFF])
  						offset: offsetX  @ offsetY]]].
  
  	argumentCount = 1 ifTrue: [
  		self success: ((objectMemory isPointers: maskObj) and: [(objectMemory lengthOf: maskObj) >= 5]).
  		self successful ifTrue: [
  			bitsObj := objectMemory fetchPointer: 0 ofObject: maskObj.
  			extentX := self fetchInteger: 1 ofObject: maskObj.
  			extentY := self fetchInteger: 2 ofObject: maskObj.
  			depth := self fetchInteger: 3 ofObject: maskObj].
  
  		self successful ifTrue: [
  			self success: ((extentX = 16) and: [extentY = 16 and: [depth = 1]]).
  			self success: ((objectMemory isWords: bitsObj) and: [(objectMemory lengthOf: bitsObj) = 16]).
  			maskBitsIndex := bitsObj + objectMemory baseHeaderSize]].
  
  	self successful ifTrue: [
  		argumentCount = 0
  			ifTrue: [
  				depth = 32
  					ifTrue: [(self cCode: 'ioSetCursorARGB(cursorBitsIndex, extentX, extentY, offsetX, offsetY)'
  						inSmalltalk: [ourCursor show. Cursor currentCursor == ourCursor])	
  							ifFalse: [^self success: false]]
  					ifFalse: [self cCode: 'ioSetCursor(cursorBitsIndex, offsetX, offsetY)'
  						inSmalltalk: [ourCursor show]]]
  			ifFalse: [self cCode: 'ioSetCursorWithMask(cursorBitsIndex, maskBitsIndex, offsetX, offsetY)'
  						inSmalltalk: [cursorBitsIndex == maskBitsIndex. "placate compiler"
  									ourCursor show]].
  		self pop: argumentCount]!



More information about the Vm-dev mailing list