[squeak-dev] FFI Inbox: FFI-Kernel-mt.78.mcz

commits at source.squeak.org commits at source.squeak.org
Fri May 29 14:18:43 UTC 2020


A new version of FFI-Kernel was added to project FFI Inbox:
http://source.squeak.org/FFIinbox/FFI-Kernel-mt.78.mcz

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

Name: FFI-Kernel-mt.78
Author: mt
Time: 29 May 2020, 4:18:42.331595 pm
UUID: 1d41e42b-d401-5e41-8bb8-bec2813972e0
Ancestors: FFI-Kernel-mt.77

Proposal to store type information for C code generation in FFI's atomic types.

An alternative would be to add two new tables as class variables -- just like AtomicTypeNames -- to not increase the size of ExternalType instances. I am not familiar with the implementation of the FFI plugin in the osvm. So this is just a guess. :-)

(Also see my question about byte alignment here: http://forum.world.st/FFI-Byte-alignment-tp5117408.html --- I discarded the dead code path in this proposal already.)

=============== Diff against FFI-Kernel-mt.77 ===============

Item was changed:
  Object subclass: #ExternalType
+ 	instanceVariableNames: 'compiledSpec referentClass referencedType pointerSize byteAlignment cTypeName cFormatPlaceholder'
- 	instanceVariableNames: 'compiledSpec referentClass referencedType pointerSize byteAlignment'
  	classVariableNames: 'AtomicSelectors AtomicTypeNames AtomicTypes StructTypes'
  	poolDictionaries: 'FFIConstants'
  	category: 'FFI-Kernel'!
  
  !ExternalType commentStamp: 'eem 6/25/2019 10:39' prior: 0!
  An external type represents the type of external objects.
  
  Instance variables:
  	compiledSpec	<WordArray>		Compiled specification of the external type
  	referentClass	<Behavior | nil>	Class type of argument required
  	referencedType	<ExternalType>	Associated (non)pointer type with the receiver
  	pointerSize		<Integer | nil>		The size of a pointer if the external type is a pointer or is a structure containing a pointer.
  	byteAlignment	<Integer | nil>		The desired alignment for a field of the external type within a structure.  If nil it has yet to be computed.
  
  Compiled Spec:
  The compiled spec defines the type in terms which are understood by the VM. Each word is defined as:
  	bits 0...15 	- byte size of the entity
  	bit 16		- structure flag (FFIFlagStructure)
  				  This flag is set if the following words define a structure
  	bit 17		- pointer flag (FFIFlagPointer)
  				  This flag is set if the entity represents a pointer to another object
  	bit 18		- atomic flag (FFIFlagAtomic)
  				  This flag is set if the entity represents an atomic type.
  				  If the flag is set the atomic type bits are valid.
  	bits 19...23	- unused
  	bits 24...27	- atomic type (FFITypeVoid ... FFITypeDoubleFloat)
  	bits 28...31	- unused
  
  Note that all combinations of the flags FFIFlagPointer, FFIFlagAtomic, and FFIFlagStructure are invalid, EXCEPT from the following:
  
  	FFIFlagPointer + FFIFlagAtomic:
  		This defines a pointer to an atomic type (e.g., 'char*', 'int*').
  		The actual atomic type is represented in the atomic type bits.
  
  	FFIFlagPointer + FFIFlagStructure:
  		This defines a structure which is a typedef of a pointer type as in
  			typedef void* VoidPointer;
  			typedef Pixmap* PixmapPtr;
  		It requires a byte size of four or eight (e.g. a 32-bit or 64-bit pointer) to work correctly.
  
  [Note: Other combinations may be allowed in the future]
  !

Item was changed:
  ----- Method: ExternalType class>>initializeAtomicTypes (in category 'class initialization') -----
  initializeAtomicTypes
+ 	"For a discussion about long vs. int see http://forum.world.st/Re-squeak-dev-64-bit-FFI-was-porting-Croquet-to-Squeak6-0-alpha-tp5113318.html."
+ 	
  	"ExternalType initialize"
+ 	| atomicType byteSize type typeName byteAlignment cTypeName cFormatPlaceholder |
- 	| atomicType byteSize type typeName byteAlignment |
  	#(
+ 		"name		atomic id		byte size	byte alignment	C type name			C printf % format"
+ 		('void' 		0 				0			0				'void'					'p')
+ 		('bool' 		1 				1			1				'int'						'd')
+ 		('byte' 		2 				1			1				'unsigned char'			'hhu') "Not 'c' to avoid conversion issues"
+ 		('sbyte' 	3 				1			1				'signed char'			'hhd') "Not 'c' to avoid conversion issues"
+ 		('ushort' 	4 				2			2				'unsigned short'		'hu')
+ 		('short' 		5 				2			2				'signed short'			'hd')
+ "!!!!!!"	('ulong' 	6 				4 "!!!!!!"		4				'unsigned int'			'u') "Not 'lu' bc. not unsigned long, see above"
+ "!!!!!!"	('long' 		7 				4 "!!!!!!"		4				'signed int'				'd') "Not 'ld' bc. not signed long, see above"
+ 		('ulonglong' 8 				8			8				'unsigned long long'	'llu')
+ 		('longlong' 	9 				8			8				'signed long long'		'lld')
+ 		('char' 		10 				1			1				'unsigned char'			'hhu') "Not 'c' to avoid conversion issues"
+ 		('schar' 	11 				1			1				'signed char'			'hhd') "Not 'c' to avoid conversion issues"
+ 		('float' 		12 				4			4				'float'					'g') "Not 'G' bc. notation in lowercase letters"
+ 		('double' 	13 				8			8 				'double'					'g') "Not 'G' bc. notation in lowercase letters"
+ "TODO: ('longdouble' 14			10			16? 4?			'long double'			'Lg')"
- 		"name		atomic id		byte size	byte alignment"
- 		('void' 		0 				0			0)
- 		('bool' 		1 				1			1)
- 		('byte' 		2 				1			1)
- 		('sbyte' 	3 				1			1)
- 		('ushort' 	4 				2			2)
- 		('short' 		5 				2			2)
- 		('ulong' 	6 				4			4)
- 		('long' 		7 				4			4)
- 		('ulonglong' 8 				8			8)
- 		('longlong' 	9 				8			8)
- 		('char' 		10 				1			1)
- 		('schar' 	11 				1			1)
- 		('float' 		12 				4			4)
- 		('double' 	13 				8			8)
  	) do:[:typeSpec| | compiled |
  		typeName := typeSpec first.
  		atomicType := typeSpec second.
  		byteSize := typeSpec third.
  		byteAlignment := typeSpec fourth.
+ 		cTypeName := typeSpec fifth.
+ 		cFormatPlaceholder := typeSpec sixth.
+ 		
+ 		"1) Regular type form"
- 		"On 32 bits Windows and MacOS, double and long have an alignment of 8. But on Linux, their alignment is 4"
- 		(FFIPlatformDescription current wordSize = 4 and: [FFIPlatformDescription current isUnix]) ifTrue: [
- 			(#('double longlong ulonglong') includes: typeName) ifTrue: [
- 				byteAlignment := 4
- 			]
- 		].
  		compiled := WordArray with: ((byteSize bitOr: FFIFlagAtomic) bitOr:
  				(atomicType bitShift: FFIAtomicTypeShift)).
  		type := (AtomicTypes at: typeName).
+ 		type
+ 			compiledSpec: compiled;
+ 			byteAlignment: byteAlignment;
+ 			cTypeName: cTypeName;
+ 			cFormatPlaceholder: '%', cFormatPlaceholder.
+ 		
+ 		"2) Pointer type form"
- 		type compiledSpec: compiled;
- 			byteAlignment: byteAlignment.
  		compiled := WordArray with: ((self pointerSpec bitOr: FFIFlagAtomic) bitOr:
  				(atomicType bitShift: FFIAtomicTypeShift)).
  		type asPointerType
  			byteAlignment: self pointerAlignment;
+ 			compiledSpec: compiled;
+ 			cTypeName: cTypeName, ' *';
+ 			cFormatPlaceholder: '%p'.
+ 
- 			compiledSpec: compiled.
  	].!

Item was added:
+ ----- Method: ExternalType>>cFormatPlaceholder (in category 'accessing') -----
+ cFormatPlaceholder
+ 
+ 	^ cFormatPlaceholder!

Item was added:
+ ----- Method: ExternalType>>cFormatPlaceholder: (in category 'accessing') -----
+ cFormatPlaceholder: aString
+ 
+ 	cFormatPlaceholder := aString.!

Item was added:
+ ----- Method: ExternalType>>cTypeName (in category 'accessing') -----
+ cTypeName
+ 
+ 	^ cTypeName!

Item was added:
+ ----- Method: ExternalType>>cTypeName: (in category 'accessing') -----
+ cTypeName: aString
+ 
+ 	cTypeName := aString.!



More information about the Squeak-dev mailing list