[Vm-dev] VM Maker: VMMaker.oscog-EstebanLorenzano.1454.mcz

commits at source.squeak.org commits at source.squeak.org
Tue Sep 15 13:10:33 UTC 2015


Esteban Lorenzano uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-EstebanLorenzano.1454.mcz

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

Name: VMMaker.oscog-EstebanLorenzano.1454
Author: EstebanLorenzano
Time: 15 September 2015, 3:07:49.521664 pm
UUID: 6d3ecc16-3f07-4f72-bf4c-9b1b9ee83e87
Ancestors: VMMaker.oscog-eem.1453

fix coercion problems on FFI plugin (IA32)
- character were not correctly mapped back
- floats were not being well chequed
- external addressed needs to be treated as aliens for the purpose of coercing them as pointers

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

Item was changed:
  ----- Method: ThreadedFFIPlugin>>ffiAtomicArgByReference:Class:in: (in category 'callout support') -----
  ffiAtomicArgByReference: oop Class: oopClass in: calloutState
  	<var: #calloutState type: #'CalloutState *'>
  	"Support for generic callout. Prepare a pointer reference to an atomic type for callout.
  	 Note: for type 'void*' we allow ByteArray/String/Symbol, wordVariableSubclass or Alien."
  	| atomicType isString isAlien |
  	<inline: true>
  	atomicType := self atomicTypeOf: calloutState ffiArgHeader.
  	(atomicType = FFITypeBool) ifTrue: "No bools on input"
  		[^FFIErrorCoercionFailed].
  	isAlien := (isString := interpreterProxy 
  					includesBehavior: oopClass 
  					ThatOf: interpreterProxy classString)
  				ifTrue: [false]
  				ifFalse:
  					[interpreterProxy 
  						includesBehavior: oopClass 
  						ThatOf: interpreterProxy classAlien].
  	((atomicType >> 1) = (FFITypeSignedChar >> 1)) ifTrue:"string value (char*)"
  		"note: the only types allowed for passing into char* types are
  		ByteArray, String, Symbol, Alien and *no* other byte indexed objects
  		(e.g., CompiledMethod, LargeInteger). We only check for strings
  		here and fall through to the byte* check otherwise."
  		[isString ifTrue:"String/Symbol"
  			"Strings must be allocated by the ffi support code"
  			[^self ffiPushString: (interpreterProxy firstIndexableField: oop)
  				OfLength: (interpreterProxy byteSizeOf: oop)
  				in: calloutState].
  		"Fall through to byte* test"
  		atomicType := FFITypeUnsignedByte].
  
  	self cppIf: COGMTVM ifTrue:
  	["Since all the following pass the address of the first indexable field we need to fail
  	 the call if it is threaded and the object is young, since it may move during the call."
  	((calloutState callFlags anyMask: FFICallFlagThreaded)
  	and: [(isAlien not or: [self isDirectAlien: oop])
  	and: [interpreterProxy isYoung: oop]]) ifTrue:
  		[^PrimErrObjectMayMove negated]].
  
  	(atomicType = FFITypeVoid or:[(atomicType >> 1) = (FFITypeSignedByte >> 1)]) ifTrue:
  		"byte* -- see comment on string above"
  		[(isString
  		  or: [oopClass = interpreterProxy classByteArray]) ifTrue:"String/Symbol/ByteArray"
  			[^self ffiPushPointer: (interpreterProxy firstIndexableField: oop) in: calloutState].
+ 		(isAlien or: [oopClass = interpreterProxy classExternalAddress]) ifTrue:
- 		isAlien ifTrue:
  			[^self ffiPushPointer: (self pointerForOop: (self startOfData: oop)) in: calloutState].
  		atomicType = FFITypeVoid ifFalse:
  			[^FFIErrorCoercionFailed]].
  		"note: type void falls through"
  
  	(atomicType <= FFITypeSignedInt "void/short/int"
  	or:[atomicType = FFITypeSingleFloat]) ifTrue:
  		["require a word subclass to work"
  		(interpreterProxy isWords: oop) ifTrue:
  			[^self ffiPushPointer: (interpreterProxy firstIndexableField: oop) in: calloutState]].
  
  	^FFIErrorCoercionFailed!

Item was changed:
  ----- Method: ThreadedFFIPlugin>>ffiCreateIntegralResultOop:ofAtomicType:in: (in category 'callout support') -----
  ffiCreateIntegralResultOop: retVal ofAtomicType: atomicType in: calloutState
  	<inline: true>
  	<var: #calloutState type: #'CalloutState *'>
  	<var: #retVal type: #usqLong>
  	"Callout support. Return the appropriate oop for the given atomic type"
  	| shift value mask byteSize |
  	self assert: atomicType < FFITypeSingleFloat.
  
  	atomicType = FFITypeBool ifTrue:
  		["Make sure bool honors the byte size requested"
  		 byteSize := calloutState ffiRetHeader bitAnd: FFIStructSizeMask.
  		 value := byteSize = (self sizeof: retVal)
  					ifTrue:[retVal]
  					ifFalse:[retVal bitAnd: 1 << (byteSize * 8) - 1].
  		 ^value = 0
  			ifTrue:[interpreterProxy falseObject]
  			ifFalse:[interpreterProxy trueObject]].
  	atomicType <= FFITypeSignedInt ifTrue:
  		["these are all generall integer returns"
  		atomicType <= FFITypeSignedShort ifTrue:
  			["byte/short. first extract partial word, then sign extend"
  			shift := (atomicType >> 1) * 8. "# of significant bits"
  			value := retVal bitAnd: (1 << shift - 1). 
  			(atomicType anyMask: 1) ifTrue:
  				["make the guy signed"
  				mask := 1 << (shift-1).
  				value := (value bitAnd: mask-1) - (value bitAnd: mask)].
  			^interpreterProxy integerObjectOf: value].
  		"32bit integer return"
  		^(atomicType anyMask: 1)
  			ifTrue:[interpreterProxy signed32BitIntegerFor: retVal] "signed return"
  			ifFalse:[interpreterProxy positive32BitIntegerFor: retVal]]. "unsigned return"
  
  	"longlong, char"
  	^(atomicType >> 1) = (FFITypeSignedLongLong >> 1) 
  		ifTrue:
  			[(atomicType anyMask: 1)
  				ifTrue:[interpreterProxy signed64BitIntegerFor: retVal] "signed return"
  				ifFalse:[interpreterProxy positive64BitIntegerFor: retVal]]
  		ifFalse:
  			[interpreterProxy characterObjectOf:
  				(retVal bitAnd: (self cppIf: #SPURVM
+ 									ifTrue: [Byte0Mask]
- 									ifTrue: [16rFFFFFFFF]
  									ifFalse: [255]))]!

Item was changed:
  ----- Method: ThreadedIA32FFIPlugin>>ffiCalloutTo:SpecOnStack:in: (in category 'callout support') -----
  ffiCalloutTo: procAddr SpecOnStack: specOnStack in: calloutState
  	<var: #procAddr type: #'void *'>
  	<var: #calloutState type: #'CalloutState *'>
  	"Go out, call this guy and create the return value.  This *must* be inlined because of
  	 the alloca of the outgoing stack frame in ffiCall:WithFlags:NumArgs:Args:AndTypes:"
  	| myThreadIndex atomicType floatRet intRet oop |
  	<var: #floatRet type: #double>
  	<var: #intRet type: #usqLong>
  	<inline: true>
  	self cppIf: COGMTVM ifTrue:
  	[(calloutState callFlags anyMask: FFICallFlagThreaded) ifTrue:
  		[myThreadIndex := interpreterProxy disownVM: 0]].
  
  	self registerArgsSlop + self cStackAlignment > 0 ifTrue:
  		[self setsp: calloutState argVector].
  
  	atomicType := self atomicTypeOf: calloutState ffiRetHeader.
+ 	(atomicType >> 1) = (FFITypeSingleFloat >> 1)
- 	(atomicType >> 1) = (FFITypeSingleFloat > 1)
  		ifTrue:
  			[floatRet := self dispatchFunctionPointer: (self cCoerceSimple: procAddr to: 'double (*)()')]
  		ifFalse:
  			[intRet := self dispatchFunctionPointer: (self cCoerceSimple: procAddr to: 'usqLong (*)()')].
  	"undo any callee argument pops because it may confuse stack management with the alloca."
  	(self isCalleePopsConvention: calloutState callFlags) ifTrue:
  		[self setsp: calloutState argVector].
  
  	self cppIf: COGMTVM ifTrue:
  	[(calloutState callFlags anyMask: FFICallFlagThreaded) ifTrue:
  		[interpreterProxy ownVM: myThreadIndex]].
  
  	(calloutState ffiRetHeader anyMask: FFIFlagPointer+FFIFlagStructure) ifTrue:
  		["Note: Order is important here since FFIFlagPointer + FFIFlagStructure is used to represent
  		 'typedef void* VoidPointer' and VoidPointer must be returned as pointer *not* as struct."
  		 (calloutState ffiRetHeader anyMask: FFIFlagPointer)
  			ifTrue:
  				[oop := self ffiReturnPointer: intRet ofType: (self ffiReturnType: specOnStack) in: calloutState]
  			ifFalse:
  				[oop := self ffiReturnStruct: intRet ofType: (self ffiReturnType: specOnStack) in: calloutState].
  		 ^oop].
  	
+ 	(atomicType >> 1) = (FFITypeSingleFloat >> 1)
- 	(atomicType >> 1) = (FFITypeSingleFloat > 1)
  		ifTrue:
  			[oop := interpreterProxy floatObjectOf: floatRet]
  		ifFalse:
  			[oop := self ffiCreateIntegralResultOop: intRet
  						ofAtomicType: atomicType
  						in: calloutState].
  	^interpreterProxy methodReturnValue: oop!



More information about the Vm-dev mailing list