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

commits at source.squeak.org commits at source.squeak.org
Sun Jul 17 22:04:15 UTC 2022


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

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

Name: VMMaker.oscog-eem.3212
Author: eem
Time: 17 July 2022, 3:04:00.266346 pm
UUID: 51b19915-284d-4fdf-9d0f-f6a0802762e8
Ancestors: VMMaker.oscog-eem.3211

Extend SmartSyntaxPlugin with
- Unsigned32 a 32-bit Unisgned value, now that Unsigned means a BytesPerWord-sized unsigned value.
- NullTerminatedString - that does a stackEphemeralValue: to get an alloca'ed null-terminated string
- WordsOrNil - that gets a void *, initialized to 0 if the argument is nil, but otherweise is like WordsOrBytes (but void *, not char *).

Get Slang to constant-fold strlen applied to a constant string so that one can write e.g.
	ttsz := interpreterProxy byteSizeOf: trackType cPtrAsOop.
	newTrackFlags := (self stString: trackType ofSize: ttsz equalsCString: 'video')
							ifTrue: [#MP4NewTrackIsVisual]
				ifFalse: [(self stString: trackType ofSize: ttsz equalsCString: 'audio')
							ifTrue: [#MP4NewTrackIsAudio]
				ifFalse: [(self stString: trackType ofSize: ttsz equalsCString: 'private')
							ifTrue: [#MP4NewTrackIsPrivate]
				ifFalse: [(self stString: trackType ofSize: ttsz equalsCString: 'none')
							ifTrue: [0]
and have strncmp invoked with the length of the string argument as a compile-time constant.

Allow InterpreterPlugin subclasses to implement structTargetKindForDeclaration: on the class side for C APIs that hide pointer types behind defines.

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

Item was added:
+ ----- Method: CCodeGenerator>>generateStrlen:on:indent: (in category 'C translation') -----
+ generateStrlen: msgNode on: aStream indent: level
+ 	"Implement to do compile-time evaluation of strlen for constant strings"
+ 
+ 	(msgNode args first isConstant
+ 	and: [msgNode args first value isString
+ 	and: [msgNode args first value class isBytes]])
+ 		ifTrue: [aStream print: msgNode args first value size]
+ 		ifFalse:
+ 			[aStream nextPutAll: 'strlen('.
+ 			 msgNode args first emitCCodeAsArgumentOn: aStream level: level generator: self.
+ 			 aStream nextPut: $)]!

Item was changed:
  ----- Method: CCodeGenerator>>initializeCTranslationDictionary (in category 'C translation support') -----
  initializeCTranslationDictionary 
  	"Initialize the dictionary mapping message names to actions for C code generation."
  
  	| pairs |
  	
  	translationDict := Dictionary new: 200.
  	pairs := #(
  	#&				#generateAnd:on:indent:
  	#|				#generateOr:on:indent:
  	#abs			#generateAbs:on:indent:
  	#and:			#generateSequentialAnd:on:indent:
  	#or:			#generateSequentialOr:on:indent:
  	#not			#generateNot:on:indent:
  
  	#+				#generatePlus:on:indent:
  	#-				#generateMinus:on:indent:
  	#negated		#generateNegated:on:indent:
  	#*				#generateTimes:on:indent:
  	#/				#generateDivide:on:indent:
  	#//				#generateDivide:on:indent:
  	#\\				#generateModulo:on:indent:
  	#<<			#generateShiftLeft:on:indent:
  	#>>			#generateShiftRight:on:indent:
  	#>>>			#generateSignedShiftRight:on:indent:
  	#,				#generateComma:on:indent:
  	#min:			#generateMin:on:indent:
  	#max:			#generateMax:on:indent:
  	#between:and:	#generateBetweenAnd:on:indent:
  
  	#bitAnd:			#generateBitAnd:on:indent:
  	#bitOr:				#generateBitOr:on:indent:
  	#bitXor:			#generateBitXor:on:indent:
  	#bitShift:			#generateBitShift:on:indent:
  	#signedBitShift:	#generateSignedBitShift:on:indent:
  	#bitInvert			#generateBitInvert:on:indent:
  	#bitInvert32		#generateBitInvert:on:indent:
  	#bitInvert64		#generateBitInvert:on:indent:
  	#bitClear:			#generateBitClear:on:indent:
  	#truncateTo:		#generateTruncateTo:on:indent:
  	#rounded			#generateRounded:on:indent:
  	#even				#generateEven:on:indent:
  	#odd				#generateOdd:on:indent:
  
  	#byteSwap32		#generateByteSwap32:on:indent:
  	#byteSwap64		#generateByteSwap64:on:indent:
  	#byteSwapped32IfBigEndian:	generateByteSwap32IfBigEndian:on:indent:
  	#byteSwapped64IfBigEndian:	generateByteSwap64IfBigEndian:on:indent:
  	
  	#<				#generateLessThan:on:indent:
  	#<=			#generateLessThanOrEqual:on:indent:
  	#=				#generateEqual:on:indent:
  	#>				#generateGreaterThan:on:indent:
  	#>=			#generateGreaterThanOrEqual:on:indent:
  	#~=			#generateNotEqual:on:indent:
  	#==			#generateEqual:on:indent:
  	#~~			#generateNotEqual:on:indent:
  	#isNil			#generateIsNil:on:indent:
  	#notNil			#generateNotNil:on:indent:
  
  	#whileTrue: 	#generateWhileTrue:on:indent:
  	#whileFalse:	#generateWhileFalse:on:indent:
  	#whileTrue 	#generateDoWhileTrue:on:indent:
  	#whileFalse		#generateDoWhileFalse:on:indent:
  	#to:do:			#generateToDo:on:indent:
  	#to:by:do:		#generateToByDo:on:indent:
  	#repeat 		#generateRepeat:on:indent:
  	#timesRepeat:	#generateTimesRepeat:on:indent:
  
  	#ifTrue:			#generateIfTrue:on:indent:
  	#ifFalse:		#generateIfFalse:on:indent:
  	#ifTrue:ifFalse:	#generateIfTrueIfFalse:on:indent:
  	#ifFalse:ifTrue:	#generateIfFalseIfTrue:on:indent:
  
  	#ifNotNil:		#generateIfNotNil:on:indent:
  	#ifNil:			#generateIfNil:on:indent:
  	#ifNotNil:ifNil:	#generateIfNotNilIfNil:on:indent:
  	#ifNil:ifNotNil:	#generateIfNilIfNotNil:on:indent:
  
  	#at:			#generateAt:on:indent:
  	#at:put:		#generateAtPut:on:indent:
  	#basicAt:		#generateAt:on:indent:
  	#basicAt:put:	#generateAtPut:on:indent:
  
  	#integerValueOf:			#generateIntegerValueOf:on:indent:
  	#integerObjectOf:			#generateIntegerObjectOf:on:indent:
  	#isIntegerObject: 			#generateIsIntegerObject:on:indent:
  	#cCode:					#generateInlineCCode:on:indent:
  	#cCode:inSmalltalk:		#generateInlineCCode:on:indent:
  	#cPreprocessorDirective:	#generateInlineCPreprocessorDirective:on:indent:
  	#cppIf:ifTrue:ifFalse:				#generateInlineCppIfElse:on:indent:
  	#cppIf:ifTrue:cppIf:ifTrue:ifFalse:	#generateInlineCppIfElse:on:indent:
  	#cppIf:ifTrue:						#generateInlineCppIfElse:on:indent:
  	#cppIf:ifFalse:						#generateInlineCppIfElse:on:indent:
  	#cCoerce:to:				#generateCCoercion:on:indent:
  	#cCoerceSimple:to:			#generateCCoercion:on:indent:
  	#addressOf:				#generateAddressOf:on:indent:
  	#addressOf:put:			#generateAddressOf:on:indent:
  	#asAddress:put:			#generateAsAddress:on:indent:
  	#signedIntFromLong64	#generateSignedIntFromLong64:on:indent:
  	#signedIntFromLong		#generateSignedIntFromLong:on:indent:
  	#signedIntFromShort		#generateSignedIntFromShort:on:indent:
  	#signedIntToLong64		#generateSignedIntToLong64:on:indent:
  	#signedIntToLong			#generateSignedIntToLong:on:indent:
  	#signedIntToShort			#generateSignedIntToShort:on:indent:
  	#preIncrement				#generatePreIncrement:on:indent:
  	#preDecrement			#generatePreDecrement:on:indent:
  	#inline:						#generateInlineDirective:on:indent:
  	#asFloat					#generateAsFloat:on:indent:
  	#asInteger					#generateAsInteger:on:indent:
  	#asIntegerPtr				#generateAsIntegerPtr:on:indent:
  	#asUnsignedInteger		#generateAsUnsignedInteger:on:indent:
  	#asUnsignedIntegerPtr		#generateAsUnsignedIntegerPtr:on:indent:
  	#asLong					#generateAsLong:on:indent:
  	#asUnsignedLong			#generateAsUnsignedLong:on:indent:
  	#asUnsignedLongLong		#generateAsUnsignedLongLong:on:indent:
  	#asVoidPointer				#generateAsVoidPointer:on:indent:
  	#asSymbol					#generateAsSymbol:on:indent:
  	#asWideString				#generateAsWideString:on:indent:
  	#flag:						#generateFlag:on:indent:
  	#anyMask:					#generateAnyMask:on:indent:
  	#allMask:					#generateAllMask:on:indent:
  	#noMask:					#generateNoMask:on:indent:
  	#raisedTo:					#generateRaisedTo:on:indent:
  	#touch:					#generateTouch:on:indent:
  
  	#bytesPerOop 				#generateBytesPerOop:on:indent:
  	#bytesPerWord 			#generateBytesPerWord:on:indent:
  	#wordSize		 			#generateBytesPerWord:on:indent:
  	#baseHeaderSize			#generateBaseHeaderSize:on:indent:
  	#minSmallInteger			#generateSmallIntegerConstant:on:indent:
  	#maxSmallInteger			#generateSmallIntegerConstant:on:indent:
  	
  	#sharedCodeNamed:inCase:		#generateSharedCodeDirective:on:indent:
  
  	#perform:							#generatePerform:on:indent:
  	#perform:with:						#generatePerform:on:indent:
  	#perform:with:with:				#generatePerform:on:indent:
  	#perform:with:with:with:			#generatePerform:on:indent:
  	#perform:with:with:with:with:		#generatePerform:on:indent:
  	#perform:with:with:with:with:with:	#generatePerform:on:indent:
  
  	#value									#generateValue:on:indent:
  	#value:									#generateValue:on:indent:
  	#value:value:							#generateValue:on:indent:
  	#value:value:value:						#generateValue:on:indent:
  	#value:value:value:value:				#generateValue:on:indent:
  	#value:value:value:value:value:			#generateValue:on:indent:
  	#value:value:value:value:value:value:	#generateValue:on:indent:
  
  	#deny:								#generateDeny:on:indent:
  
  	#shouldNotImplement				#generateSmalltalkMetaError:on:indent:
  	#shouldBeImplemented			#generateSmalltalkMetaError:on:indent:
  	#subclassResponsibility				#generateSmalltalkMetaError:on:indent:
+ 
+ 	#strlen:								#generateStrlen:on:indent:
  	).
  
  	1 to: pairs size by: 2 do: [:i |
  		translationDict at: (pairs at: i) put: (pairs at: i + 1)].
  
  	pairs := #(
  	#ifTrue:				#generateIfTrueAsArgument:on:indent:	
  	#ifFalse:				#generateIfFalseAsArgument:on:indent:
  	#ifTrue:ifFalse:			#generateIfTrueIfFalseAsArgument:on:indent:
  	#ifFalse:ifTrue:			#generateIfFalseIfTrueAsArgument:on:indent:
  	#ifNotNil:				#generateIfNotNilAsArgument:on:indent:	
  	#ifNil:					#generateIfNilAsArgument:on:indent:
  	#ifNotNil:ifNil:			#generateIfNotNilIfNilAsArgument:on:indent:
  	#ifNil:ifNotNil:			#generateIfNilIfNotNilAsArgument:on:indent:
  	#cCode:				#generateInlineCCodeAsArgument:on:indent:
  	#cCode:inSmalltalk:	#generateInlineCCodeAsArgument:on:indent:
  	#cppIf:ifTrue:ifFalse:	#generateInlineCppIfElseAsArgument:on:indent:
  	#cppIf:ifTrue:			#generateInlineCppIfElseAsArgument:on:indent:
  
  	#value					#generateValueAsArgument:on:indent:
  	#value:					#generateValueAsArgument:on:indent:
  	#value:value:			#generateValueAsArgument:on:indent:
  	).
  
  	asArgumentTranslationDict := Dictionary new: 8.
  	1 to: pairs size by: 2 do: [:i |
  		asArgumentTranslationDict at: (pairs at: i) put: (pairs at: i + 1)].
  !

Item was changed:
  ----- Method: InterpreterPlugin class>>isStructType: (in category 'translation') -----
  isStructType: typeName "<String>"
+ 	"Subclasses should override to answer true for struct types they use.
+ 	 This API is deprecated in favour of structTargetKindForDeclaration:"
- 	"Subclasses should override to answer trye for struct types they use."
  	^false!

Item was added:
+ ----- Method: InterpreterPlugin class>>structTargetKindForDeclaration: (in category 'translation') -----
+ structTargetKindForDeclaration: decl "<String>"
+ 	"Subclasses should override to answer #pointer or #struct for struct types they use. and nil for anything else."
+ 	| isPointer |
+ 	^(self isStructType: ((isPointer := decl last == $*)
+ 											ifTrue: [decl allButLast]
+ 											ifFalse: [decl]) withBlanksTrimmed) ifTrue:
+ 		[isPointer
+ 			ifTrue: [#pointer]
+ 			ifFalse: [#struct]]!

Item was added:
+ ----- Method: InterpreterPlugin>>object:equalsString: (in category 'comparison') -----
+ object: anOop equalsString: aCString
+ 	<inline: #always>
+ 	<var: 'aCString' type: #'char *'>
+ 	^self object: anOop equalsString: aCString ofSize: (self strlen: aCString)!

Item was added:
+ ----- Method: InterpreterPlugin>>object:equalsString:ofSize: (in category 'comparison') -----
+ object: anOop equalsString: aCString ofSize: aCStringStrlen
+ 	<inline: #always>
+ 	<var: 'aCString' type: #'char *'>
+ 	^(interpreterProxy isBytes: anOop)
+ 	 and: [(interpreterProxy byteSizeOf: anOop) = aCStringStrlen
+ 	 and: [(self strncmp: aCString _: (interpreterProxy firstIndexableField: anOop) _: aCStringStrlen) = 0]]!

Item was added:
+ ----- Method: InterpreterPlugin>>stString:equalsCString: (in category 'comparison') -----
+ stString: aPointer equalsCString: aCString
+ 	<inline: #always>
+ 	<var: 'aCString' type: #'char *'>
+ 	^self stString: aPointer equalsCString: aCString ofSize: (self strlen: aCString)!

Item was added:
+ ----- Method: InterpreterPlugin>>stString:equalsCString:ofSize: (in category 'comparison') -----
+ stString: aPointer equalsCString: aCString ofSize: aCStringStrlen
+ 	<inline: #always>
+ 	<var: 'aCString' type: #'char *'>
+ 	^self stString: aPointer ofSize: (interpreterProxy byteSizeOf: aPointer cPtrAsOop) equalsCString: aCString ofSize: aCStringStrlen!

Item was added:
+ ----- Method: InterpreterPlugin>>stString:ofSize:equalsCString: (in category 'comparison') -----
+ stString: aPointer ofSize: byteSize equalsCString: aCString
+ 	<inline: #always>
+ 	<var: 'aCString' type: #'char *'>
+ 	^self stString: aPointer ofSize: byteSize equalsCString: aCString ofSize: (self strlen: aCString)!

Item was added:
+ ----- Method: InterpreterPlugin>>stString:ofSize:equalsCString:ofSize: (in category 'comparison') -----
+ stString: aPointer ofSize: byteSize equalsCString: aCString ofSize: aCStringStrlen
+ 	<inline: #always>
+ 	<var: 'aCString' type: #'char *'>
+ 	^byteSize = aCStringStrlen and: [(self strncmp: aCString _: aPointer _: aCStringStrlen) = 0]!

Item was added:
+ Behavior subclass: #NullTerminatedString
+ 	instanceVariableNames: ''
+ 	classVariableNames: ''
+ 	poolDictionaries: ''
+ 	category: 'VMMaker-SmartSyntaxPlugins'!

Item was added:
+ ----- Method: NullTerminatedString class>>ccg:prolog:expr:index: (in category '*VMMaker-plugin generation') -----
+ ccg: cg prolog: aBlock expr: aString index: anInteger
+ 
+ 	^cg 
+ 		ccgLoad: aBlock 
+ 		expr: aString 
+ 		asNullTerminatedCharPtrFrom: anInteger
+ 		andThen: 'interpreterProxy failed not'!

Item was added:
+ ----- Method: NullTerminatedString class>>ccgDeclareCForVar: (in category '*VMMaker-plugin generation') -----
+ ccgDeclareCForVar: aSymbolOrString
+ 
+ 	^#'char *', aSymbolOrString!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>assign:coerceTo:expr: (in category 'plugin generation') -----
+ assign: variableName coerceTo: cType expr: expressionString 
+ 	^variableName, ' := self cCoerce: (', expressionString, ') to: ', cType storeString!

Item was changed:
  ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asCharPtrFrom:andThen: (in category 'coercing') -----
  ccgLoad: aBlock expr: aString asCharPtrFrom: stackIndex andThen: valBlock
+ 	^stackIndex
+ 		ifNil: [self assign: aString coerceTo: #'char *' expr: valBlock]
+ 		ifNotNil: [self assign: aString coerceTo: #'char *' from: stackIndex]!
- 	^self assign: aString coerceTo: #'char *' from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asNullTerminatedCharPtrFrom:andThen: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asNullTerminatedCharPtrFrom: stackIndex andThen: valBlock
+ 	^aString, ' := interpreterProxy ', #stackEphemeralStringValue:, stackIndex printString!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asPtrFrom:andThen: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asPtrFrom: stackIndex andThen: valBlock
+ 	^stackIndex
+ 		ifNil: [aString, ' := ', valBlock]
+ 		ifNotNil: [self assign: aString coerceTo: #'void *' from: stackIndex]!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgValBlock:or:index: (in category 'coercing support') -----
+ ccgValBlock: unarySelector or: keywordSelector index: index
+ 	^String streamContents:
+ 		[:s| | a loadSelector |
+ 		a := self stackAccessorFor: index.
+ 		loadSelector := (keywordSelector caseOf: {
+ 							['isWordsOrBytes:'] -> [#firstIndexableField:].
+ 						}).
+ 		s nextPutAll: 'interpreterProxy '; nextPutAll: unarySelector; nextPutAll: ' = '; nextPutAll: a.
+ 		s nextPutAll: ' ifTrue: [0 asVoidPointer] ifFalse: [interpreterProxy '; nextPutAll: loadSelector; space; nextPutAll: a; nextPut: $]]!

Item was removed:
- ----- Method: SmartSyntaxPluginCodeGenerator>>ccgValBlock:or: (in category 'coercing') -----
- ccgValBlock: valString or: valorString
- 
- 	^[:index | String streamContents:
- 		[:aStream | aStream
- 			nextPutAll: 'interpreterProxy success: ((interpreterProxy ';
- 			nextPutAll: valString;
- 			nextPutAll: ': (interpreterProxy stackValue: ';
- 			nextPutAll: index asString;
- 			nextPutAll: ')) || (interpreterProxy ';
- 			nextPutAll: valorString;
- 			nextPutAll: ': (interpreterProxy stackValue: ';
- 			nextPutAll: index asString;
- 			nextPutAll: ')))']] !

Item was added:
+ ----- Method: SmartSyntaxPluginSimulator>>ccgLoad:expr:asPtrFrom:andThen: (in category 'simulation') -----
+ ccgLoad: codeGen expr: exprBlock asPtrFrom: stackIndexOrNil andThen: validateBlock
+ 	stackIndexOrNil ifNil: [self halt: 'need to figure out how to simulate WordsOrNil'].
+ 	^[:oop|
+ 	   validateBlock value: oop.
+ 	   interpreterProxy cCoerce: (interpreterProxy firstIndexableField: oop) asInteger to: #'int *']!

Item was removed:
- ----- Method: SmartSyntaxPluginSimulator>>ccgLoad:expr:asUnsigned32BitValueFrom: (in category 'simulation') -----
- ccgLoad: codeGen expr: exprBlock asUnsigned32BitValueFrom: stackIndex
- 	^[:oop| interpreterProxy positive32BitValueOf: oop]!

Item was added:
+ ----- Method: SmartSyntaxPluginSimulator>>ccgLoad:expr:asUnsigned32BitValueFrom:andThen: (in category 'simulation') -----
+ ccgLoad: codeGen expr: exprBlock asUnsigned32BitValueFrom: stackIndex andThen: validateBlock
+ 	^[:oop|
+ 	   validateBlock value: oop.
+ 	   interpreterProxy positive32BitValueOf: oop]!

Item was added:
+ ----- Method: SmartSyntaxPluginSimulator>>ccgValBlock:or:index: (in category 'simulation') -----
+ ccgValBlock: unarySelectorString or: keywordSelector index: ignored
+ 	"unarySelector must be simple; nilObject, classArray etc. keywordSelector must be of the list below."
+ 	| unarySelector |
+ 	unarySelector := unarySelectorString asSymbol.
+ 	^keywordSelector caseOf: {
+ 		['isBytes']			-> [	[:oop|
+ 								 interpreterProxy success: ((interpreterProxy perform: unarySelector) = oop or: [interpreterProxy isBytes: oop]).
+ 								 oop]].
+ 		['isShorts']			-> [	[:oop|
+ 								 interpreterProxy success: ((interpreterProxy perform: unarySelector) = oop or: [interpreterProxy isShorts: oop]).
+ 								 oop]].
+ 		['isWords']			-> [	[:oop|
+ 								 interpreterProxy success: ((interpreterProxy perform: unarySelector) = oop or: [interpreterProxy isWords: oop]).
+ 								 oop]].
+ 		['isLong64s']		-> [	[:oop|
+ 								 interpreterProxy success: ((interpreterProxy perform: unarySelector) = oop or: [interpreterProxy isLong64s: oop]).
+ 								 oop]].
+ 		['isWordsOrBytes']	-> [	[:oop|
+ 								 interpreterProxy success: ((interpreterProxy perform: unarySelector) = oop or: [interpreterProxy isWordsOrBytes: oop]).
+ 								 oop]].
+ 		['isIndexable']		-> [	[:oop|
+ 								 interpreterProxy success: ((interpreterProxy perform: unarySelector) = oop or: [interpreterProxy isIndexable: oop]).
+ 								 oop]].
+ 		['isWordsOrShorts']	-> [	[:oop|
+ 								 interpreterProxy success: ((interpreterProxy perform: unarySelector) = oop or: [interpreterProxy isWordsOrShorts: oop]).
+ 								 oop]] }!

Item was changed:
  ----- Method: SmartSyntaxPluginTMethod>>namedPrimitiveProlog (in category 'specifying primitives') -----
  namedPrimitiveProlog
  	"Generate the code for a primitive:parameters:... send.  This is in two parts.
  	 The first is validation; the second is coercing assignment."
+ 	| statements validator validations deferredValidations assigner assignments |
- 	| statements validator validations deferredValidations assigner |
  	fullArgs isEmpty ifTrue:
  		[^#()].
  	validator := SmartSyntaxPluginValidationCodeGenerator new.
  	statements := OrderedCollection new.
  	validations := fullArgs withIndexCollect:
+ 						[:arg :i|
+ 						(parmSpecs at: i) 
+ 								ccg:	validator
+ 								prolog:	nil
+ 								expr:	arg
+ 								index:	fullArgs size - i].
- 					[:arg :i|
- 					(parmSpecs at: i) 
- 							ccg:	validator
- 							prolog:	nil
- 							expr:	arg
- 							index:	fullArgs size - i].
  	validations := validations reject: [:validation| validation isNil].
  	deferredValidations := validations select: [:validation| validation isArray and: [validation size = 2 and: [validation first == #deferred]]].
  	validations := validations copyWithoutAll: deferredValidations.
  	statements addAllLast: (self validationStatementsFor: validations).
  	assigner := SmartSyntaxPluginAssignmentCodeGenerator new.
+ 	assignments := fullArgs withIndexCollect:
+ 						[:arg :i|
+ 						(parmSpecs at: i) 
+ 							ccg:	assigner
+ 							prolog:	nil
+ 							expr:	arg
+ 							index:	fullArgs size - i].
+ 	assignments do:
+ 		[:assignment|  statements addAllLast: (self statementsFor: assignment varName: '')].
+ 	statements addAllLast: (self validationStatementsFor: ((deferredValidations collect: #second) reject: #isNil)).
- 	fullArgs withIndexDo:
- 		[:arg :i|
- 		statements addAllLast:
- 			(self 
- 				statementsFor: 
- 					((parmSpecs at: i) 
- 						ccg:	assigner
- 						prolog:	nil
- 						expr:	arg
- 						index:	fullArgs size - i)
- 				varName: '')].
- 	statements addAllLast: (self validationStatementsFor: (deferredValidations collect: #second)).
  	^statements!

Item was changed:
  ----- Method: SmartSyntaxPluginTMethod>>validationStatementsFor: (in category 'private') -----
  validationStatementsFor: validations
  	validations isEmpty ifTrue: [^#()].
  	^self
  		statementsFor: (String streamContents:
  								[:s|
  								s nextPut: $(.
  								validations
+ 									do: [:validation| | parenthesize |
+ 										parenthesize := (validation includesSubstring: '). ') not.
+ 										parenthesize ifTrue: [s nextPut: $(].
+ 										s nextPutAll: validation.
+ 										parenthesize ifTrue: [s nextPut: $)]]
- 									do: [:validation| s nextPut: $(; nextPutAll: validation; nextPut: $)]
  									separatedBy: [s crtab; nextPutAll: 'and: ['].
  								s next: validations size - 1 put: $].
  								s nextPutAll: ') ifFalse: [^interpreterProxy primitiveFailFor: PrimErrBadArgument]'])
  		varName: ''!

Item was changed:
  ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asCharPtrFrom:andThen: (in category 'coercing') -----
  ccgLoad: aBlock expr: aString asCharPtrFrom: stackIndex andThen: validationString
+ 	^stackIndex
+ 		ifNil: [validationString]
+ 		ifNotNil: [validationString, (self stackAccessorFor: stackIndex)]!
- 	^validationString, (self stackAccessorFor: stackIndex)!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asNullTerminatedCharPtrFrom:andThen: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asNullTerminatedCharPtrFrom: stackIndex andThen: validationString
+ 	^{#deferred. validationString}!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asPtrFrom:andThen: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asPtrFrom: stackIndex andThen: validationString
+ 	^validationString last = $]
+ 		ifTrue: [validationString]
+ 		ifFalse: [validationString, (self stackAccessorFor: stackIndex)]!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgValBlock:or:index: (in category 'coercing support') -----
+ ccgValBlock: unarySelector or: keywordSelector index: index
+ 	^String streamContents:
+ 		[:s| | a |
+ 		a := self stackAccessorFor: index.
+ 		s nextPutAll: 'interpreterProxy '; nextPutAll: unarySelector; nextPutAll: ' = '; nextPutAll: a.
+ 		s nextPutAll: ' or: [interpreterProxy '; nextPutAll: keywordSelector; space; nextPutAll: a; nextPut: $]]!

Item was changed:
  Behavior subclass: #Unsigned
  	instanceVariableNames: ''
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'VMMaker-SmartSyntaxPlugins'!
  
+ !Unsigned commentStamp: 'eem 7/16/2022 11:43' prior: 0!
+ Coercion specification for machine word sized unsigned numbers within plugins.
- !Unsigned commentStamp: '' prior: 0!
- Coercion specification for 32-bit unsigned numbers within plugins.
  
+ Note: "x asOop: Unsigned" can cause garbage collection (but not in Spur) when x is outside SmallInteger range.!
- Note: "x asOop: Unsigned" can cause garbage collection when x is outside SmallInteger range.!

Item was changed:
  Unsigned subclass: #Unsigned32
  	instanceVariableNames: ''
  	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'VMMaker-SmartSyntaxPlugins'!
+ 
+ !Unsigned32 commentStamp: 'eem 7/16/2022 11:43' prior: 0!
+ Coercion specification for 32-bit unsigned numbers within plugins.
+ 
+ Note: "x asOop: Unsigned32" can cause garbage collection (but not in Spur) when x is outside SmallInteger range.!

Item was changed:
  ----- Method: VMPluginCodeGenerator>>structTargetKindForDeclaration: (in category 'C code generator') -----
  structTargetKindForDeclaration: decl "<String>"
  	^(super structTargetKindForDeclaration: decl) ifNil:
  		[pluginClass ifNotNil:
+ 			[pluginClass structTargetKindForDeclaration: decl]]!
- 			[| isPointer |
- 			 (pluginClass isStructType: ((isPointer := decl last == $*)
- 											ifTrue: [decl allButLast]
- 											ifFalse: [decl]) withBlanksTrimmed) ifTrue:
- 				[isPointer
- 					ifTrue: [#pointer]
- 					ifFalse: [#struct]]]]!

Item was added:
+ Behavior subclass: #WordsOrNil
+ 	instanceVariableNames: ''
+ 	classVariableNames: ''
+ 	poolDictionaries: ''
+ 	category: 'VMMaker-SmartSyntaxPlugins'!
+ 
+ !WordsOrNil commentStamp: 'eem 7/16/2022 14:48' prior: 0!
+ Coercion specification for bits objects like ByteString, Bitmap, ByteArray, WordArray, LargePositiveInteger et al to void *, and nil to (void *)0!

Item was added:
+ ----- Method: WordsOrNil class>>ccg:prolog:expr:index: (in category 'plugin generation') -----
+ ccg: cg prolog: aBlock expr: aString index: index
+ 
+ 	^cg 
+ 		ccgLoad: aBlock 
+ 		expr: aString 
+ 		asPtrFrom: nil
+ 		andThen: (cg ccgValBlock: #nilObject or: #isWordsOrBytes: index: index)!

Item was added:
+ ----- Method: WordsOrNil class>>ccgCanConvertFrom: (in category 'plugin generation') -----
+ ccgCanConvertFrom: anObject
+ 
+ 	^anObject class isBits or: [anObject isNil]!

Item was added:
+ ----- Method: WordsOrNil class>>ccgDeclareCForVar: (in category 'plugin generation') -----
+ ccgDeclareCForVar: aSymbolOrString
+ 
+ 	^#'void *', aSymbolOrString!



More information about the Vm-dev mailing list