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

commits at source.squeak.org commits at source.squeak.org
Wed Dec 19 02:13:30 UTC 2018


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

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

Name: VMMaker.oscog-eem.2493
Author: eem
Time: 18 December 2018, 6:13:17.614216 pm
UUID: d7437cc5-75c7-4a43-af6b-0f85bf0cebe6
Ancestors: VMMaker.oscog-nice.2492

SmartSyntaxPlugin Slang:
Improve failure guard & result returning interleaving to avoid extra returns and tests of failed (see fixUpReturnOneStmt:on:).  Eliminate the unused suppressFailureGuards: support and inst vars.

Separate argument validation from argument marshalling to fix the bug Levente identified in SocketPlugin>>primitiveSocket:connectTo:port:/primitiveSocketConnectToPort.  Because the old scheme interleaved validation and marshalling, marshalling could be done on invalid objects and cause crashes.  See http://lists.squeakfoundation.org/pipermail/vm-dev/2018-December/029511.html.  Also have teh primitives answer primErrBadArgument if validation fails.

To this end add InterpreterProxy>>isBooleanObject: & InterpreterProxy>>isPositiveMachineIntegerObject:

Remember to mark the 1.14 InterpreterProxy methods as being of that version.

=============== Diff against VMMaker.oscog-nice.2492 ===============

Item was changed:
  ----- Method: CogVMSimulator>>primitiveDoPrimitiveWithArgs (in category 'debugging traps') -----
  primitiveDoPrimitiveWithArgs
  	| primIndex |
  	primIndex := objectMemory integerValueOf: (self stackValue: 1).
  	NewspeakVM ifFalse:
  		[transcript nextPutAll: 'DO PRIMITIVE: '; print: (self functionPointerFor: primIndex inClass: nil); cr; flush].
+ 	(#(76 "primitiveStoreStackp" 188 189 "eval method") includes: primIndex) ifTrue:
- 	primIndex = 76 ifTrue:
  		[self halt].
  	^super primitiveDoPrimitiveWithArgs!

Item was added:
+ ----- Method: InterpreterPrimitives>>isPositiveMachineIntegerObject: (in category 'primitive support') -----
+ isPositiveMachineIntegerObject: oop
+ 	"Answer if oop is a value of an integer in address range, i.e up to the size of a machine word.
+ 	The object may be either a positive SmallInteger or a LargePositiveInteger of size <= word size."
+ 	| ok |
+ 	(objectMemory isIntegerObject: oop) ifTrue:
+ 		[^(objectMemory integerValueOf: oop) >= 0].
+ 
+ 	(objectMemory isNonIntegerImmediate: oop) ifTrue:
+ 		[^false].
+ 
+ 	ok := objectMemory
+ 			isClassOfNonImm: oop
+ 			equalTo: (objectMemory splObj: ClassLargePositiveInteger)
+ 			compactClassIndex: ClassLargePositiveIntegerCompactIndex.
+ 	^ok and: [(objectMemory numBytesOfBytes: oop) <= (self sizeof: #'usqIntptr_t')]!

Item was added:
+ ----- Method: InterpreterProxy>>isBooleanObject: (in category 'testing') -----
+ isBooleanObject: oop
+ 	<option: #(atLeastVMProxyMajor:minor: 1 15)>
+ 	^oop == true or: [oop == false]!

Item was added:
+ ----- Method: InterpreterProxy>>isPositiveMachineIntegerObject: (in category 'testing') -----
+ isPositiveMachineIntegerObject: oop
+ 	<option: #(atLeastVMProxyMajor:minor: 1 15)>
+ 	^oop isInteger and: [oop >= 0 and: [oop digitLength <= Smalltalk wordSize]]!

Item was changed:
  ----- Method: InterpreterProxy>>primitiveFailForFFIException:at: (in category 'other') -----
  primitiveFailForFFIException: exceptionCode at: pc
  	<var: 'exceptionCode' type: #usqLong>
  	<var: 'pc' type: #usqInt>
+ 	<option: #(atLeastVMProxyMajor:minor: 1 14)>
  	"Set PrimErrFFIException primitive failure and associated exceptionCode (a.k.a. 
  	 osErrorCode) and exceptionPC."
  	<primitive: 255>
  	osErrorCode := exceptionCode.
  	exceptionPC := pc.
  	^primFailCode := PrimErrFFIException!

Item was changed:
  ----- Method: InterpreterProxy>>primitiveFailForOSError: (in category 'other') -----
  primitiveFailForOSError: osError
  	<var: 'osError' type: #sqLong>
+ 	<option: #(atLeastVMProxyMajor:minor: 1 14)>
  	"Set PrimErrOSError primitive failure and associated osErrorCode.
  	 Primitive 255 is called to indicate that we are currently simulating a primitive that should fail and the VM should handle that case appropriately (if supported by the VM)."
  	<primitive: 255>
  	osErrorCode := osError.
  	^primFailCode := PrimErrOSError!

Item was changed:
  ----- Method: InterpreterProxy>>statNumGCs (in category 'other') -----
  statNumGCs
+ 	<option: #(atLeastVMProxyMajor:minor: 1 14)>
  	^(Smalltalk vmParameterAt: 7 "statFullGCs") + (Smalltalk vmParameterAt: 9 "statScavenges/statIncrGCs")!

Item was changed:
  ----- Method: InterpreterProxy>>stringForCString: (in category 'testing') -----
  stringForCString: aCString
  	"Answer a ByteString object containing the bytes (possibly UTF-8?) in the null-terminated C string aCString."
+ 	<option: #(atLeastVMProxyMajor:minor: 1 14)>
  	<returnTypeC: #sqInt>
  	<var: #aCString type: #'char *'>
  	self notYetImplemented!

Item was added:
+ ----- Method: NewObjectMemory>>isBooleanObject: (in category 'simulation only') -----
+ isBooleanObject: oop
+ 	"hack around the CoInterpreter/ObjectMemory split refactoring"
+ 	<doNotGenerate>
+ 	^coInterpreter isBooleanObject: oop!

Item was added:
+ ----- Method: NewObjectMemory>>isPositiveMachineIntegerObject: (in category 'simulation only') -----
+ isPositiveMachineIntegerObject: oop
+ 	"hack around the CoInterpreter/ObjectMemory split refactoring"
+ 	<doNotGenerate>
+ 	^coInterpreter isPositiveMachineIntegerObject: oop!

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

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>assign:coerceTo:from: (in category 'coercing support') -----
+ assign: variableName coerceTo: cType from: stackIndex
+ 	^String streamContents:
+ 		[:aStream |
+ 		 aStream
+ 			nextPutAll: variableName;
+ 			nextPutAll: ' := self cCoerce: (interpreterProxy firstIndexableField:';
+ 			nextPutAll: (self stackAccessorFor: stackIndex);
+ 			nextPutAll: ') to: ';
+ 			store: cType]!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asBooleanValueFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asBooleanValueFrom: stackIndex
+ 	^(aString, ' := '), (self loadAs: #booleanValueOf: from: stackIndex)!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asCharPtrFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asCharPtrFrom: stackIndex
+ 	^self assign: aString coerceTo: #'char *' from: stackIndex!

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

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asFloatValueFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asFloatValueFrom: anInteger
+ 	^String streamContents:
+ 		[:aStream |
+ 		aStream
+ 			nextPutAll: aString;
+ 			nextPutAll: ' := interpreterProxy stackFloatValue: ';
+ 			print: anInteger]!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asIntPtrFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asIntPtrFrom: stackIndex
+ 	^self assign: aString coerceTo: #'int *' from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asIntPtrFrom:andThen: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asIntPtrFrom: stackIndex andThen: valBlock
+ 	^self assign: aString coerceTo: #'int *' from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asIntegerValueFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asIntegerValueFrom: anInteger
+ 	^String streamContents:
+ 		[:aStream |
+ 		aStream
+ 			nextPutAll: aString;
+ 			nextPutAll: ' := interpreterProxy stackIntegerValue: ';
+ 			print: anInteger]!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asKindOf:from: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asKindOf: aClass from: stackIndex
+ 	^self ccgLoad: aBlock expr: aString asRawOopFrom: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asKindOfIntegerFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asKindOfIntegerFrom: stackIndex
+ 	^self ccgLoad: aBlock expr: aString asRawOopFrom: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asMemberOf:from: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asMemberOf: aClass from: stackIndex
+ 	^self ccgLoad: aBlock expr: aString asRawOopFrom: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asMemberOfLargeNegativeIntegerFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asMemberOfLargeNegativeIntegerFrom: stackIndex
+ 	^self ccgLoad: aBlock expr: aString asRawOopFrom: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asMemberOfLargePositiveIntegerFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asMemberOfLargePositiveIntegerFrom: stackIndex
+ 	^self ccgLoad: aBlock expr: aString asRawOopFrom: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asNonIntegerValueFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asNonIntegerValueFrom: stackIndex
+ 	^self ccgLoad: aBlock expr: aString asRawOopFrom: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asOopPtrFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asOopPtrFrom: stackIndex
+ 	^self assign: aString coerceTo: 'sqInt *' from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asOopPtrFrom:andThen: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asOopPtrFrom: stackIndex andThen: valBlock
+ 	^self assign: aString coerceTo: 'sqInt *' from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asRawOopFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asRawOopFrom: stackIndex
+ 	^aString, ' := ', (self stackAccessorFor: stackIndex)!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asUnsignedPtrFrom:andThen: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asUnsignedPtrFrom: stackIndex andThen: valBlock
+ 	^self assign: aString coerceTo: 'unsigned *' from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asUnsignedValueFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asUnsignedValueFrom: stackIndex
+ 	^String streamContents:
+ 		[:aStream |
+ 		aStream
+ 			nextPutAll: aString;
+ 			nextPutAll: ' := (interpreterProxy bytesPerOop = 4';
+ 			crtab: 2;
+ 			nextPutAll: 'ifTrue: [interpreterProxy positive32BitValueOf:';
+ 			nextPutAll: (self stackAccessorFor: stackIndex);
+ 			nextPutAll: '] ifFalse: [interpreterProxy positive64BitValueOf:';
+ 			nextPutAll: (self stackAccessorFor: stackIndex);
+ 			nextPutAll: '])']!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asWBCharPtrFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asWBCharPtrFrom: stackIndex
+ 	^self assign: aString coerceTo: #'char *' from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asWBFloatPtrFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asWBFloatPtrFrom: stackIndex
+ 	^self assign: aString coerceTo: #'float *' from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgLoad:expr:asWBIntPtrFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asWBIntPtrFrom: stackIndex
+ 	^self assign: aString coerceTo: #'int *' from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>ccgValBlock: (in category 'coercing support') -----
+ ccgValBlock: aString
+ 	"ignore"!

Item was added:
+ ----- Method: SmartSyntaxPluginAssignmentCodeGenerator>>loadAs:from: (in category 'coercing support') -----
+ loadAs: coercionSelector from: stackIndex
+ 
+ 	^String streamContents:
+ 		[:aStream |
+ 		 aStream
+ 			nextPutAll: 'interpreterProxy ';
+ 			nextPutAll: coercionSelector;
+ 			nextPutAll: (self stackAccessorFor: stackIndex)]!

Item was added:
+ ----- Method: SmartSyntaxPluginCodeGenerator>>anyMethodNamed: (in category 'utilities') -----
+ anyMethodNamed: selector
+ 	"Answer any method in the code base (including api methods) with the given selector.
+ 	 Override to find smart syntax methods that get  entered in the dictionary under the
+ 	 name specified in the primitive:parameters: send."
+ 
+ 	^(super anyMethodNamed: selector) ifNil:
+ 		[methods
+ 			detect: [:m| m smalltalkSelector == selector]
+ 			ifNone: []]!

Item was removed:
- ----- Method: SmartSyntaxPluginCodeGenerator>>ccgLoad:expr:asNamedPtr:from: (in category 'coercing') -----
- ccgLoad: aBlock expr: exprString asNamedPtr: recordString from: anInteger
- 	"Answer codestring for integer pointer to first indexable field of object (without validating side-effect), as described in comment to ccgLoad:expr:asRawOopFrom:"
- 
- 	^aBlock value: (String streamContents: [:aStream | aStream
- 		nextPutAll: 'self cCoerce: (interpreterProxy firstIndexableField:';
- 		crtab: 4;
- 		nextPutAll: '(interpreterProxy stackValue:';
- 		nextPutAll: anInteger asString;
- 		nextPutAll:	'))';
- 		crtab: 3;
- 		nextPutAll: 'to: ''';
- 		nextPutAll: recordString;
- 		nextPutAll: ' *'''])!

Item was removed:
- ----- Method: SmartSyntaxPluginCodeGenerator>>ccgLoad:expr:asNamedPtr:from:andThen: (in category 'coercing') -----
- ccgLoad: aBlock expr: exprString asNamedPtr: recordString from: anInteger andThen: valBlock
- 	"Answer codestring for integer pointer to first indexable field of object (without validating side-effect), as described in comment to ccgLoad:expr:asRawOopFrom:"
- 
- 	^(valBlock value: anInteger), '.',
- 	 (aBlock value: (String streamContents: [:aStream | aStream
- 		nextPutAll: 'self cCoerce: (interpreterProxy firstIndexableField:';
- 		crtab: 4;
- 		nextPutAll: '(interpreterProxy stackValue:';
- 		nextPutAll: anInteger asString;
- 		nextPutAll:	'))';
- 		crtab: 3;
- 		nextPutAll: 'to: ''';
- 		nextPutAll: recordString;
- 		nextPutAll: ' *''']))!

Item was changed:
  ----- Method: SmartSyntaxPluginCodeGenerator>>ccgLoad:expr:asRawOopFrom: (in category 'coercing') -----
  ccgLoad: aBlock expr: aString asRawOopFrom: anInteger
+ 	"Answer a string for a Slang expression that will load an oop (without validation) from stack index anInteger.  Apply aBlock that when passed an expression, will answer a string assigning the expression to the desired identifier, to the string before answering.  aString is a Slang expression that refers to the stack value, once it has been loaded."
- 	"Answer a string for a Slang expression that will load an oop (without validation) from stack index anInteger.  Apply aBlock, a BlockContext instance that when passed an expression, will return a string assigning the expression to the desired identifier, to the string before answering.  aString is a Slang expression that refers to the stack value, once it has been loaded."
  
+ 	^aBlock value: 'interpreterProxy stackValue: ', anInteger printString!
- 	^aBlock value: (String streamContents: [:aStream | aStream
- 		nextPutAll: 'interpreterProxy stackValue: ';
- 		nextPutAll: anInteger asString])!

Item was added:
+ Object subclass: #SmartSyntaxPluginPrologCodeGenerator
+ 	instanceVariableNames: ''
+ 	classVariableNames: ''
+ 	poolDictionaries: ''
+ 	category: 'VMMaker-SmartSyntaxPlugins'!
+ 
+ !SmartSyntaxPluginPrologCodeGenerator commentStamp: 'eem 12/17/2018 10:08' prior: 0!
+ SmartSyntaxPluginPrologCodeGenerator is an abstract superclass for two subclasses that generate the validations and assignments at the beginning of SmartSyntaxInterpreterPlugin primitives in response to the primitive:parameters:... sends.!

Item was added:
+ ----- Method: SmartSyntaxPluginPrologCodeGenerator>>stackAccessorFor: (in category 'utilities') -----
+ stackAccessorFor: index
+ 	self assert: index isInteger.
+ 	^'(interpreterProxy stackValue: ', (index printString, ')')!

Item was changed:
  TMethod subclass: #SmartSyntaxPluginTMethod
+ 	instanceVariableNames: 'isPrimitive fullSelector fullArgs parmSpecs rcvrSpec'
+ 	classVariableNames: 'Them'
- 	instanceVariableNames: 'isPrimitive suppressingFailureGuards fullSelector fullArgs parmSpecs rcvrSpec'
- 	classVariableNames: ''
  	poolDictionaries: ''
  	category: 'VMMaker-SmartSyntaxPlugins'!
  
  !SmartSyntaxPluginTMethod commentStamp: 'eem 6/6/2018 14:06' prior: 0!
  Variation of TMethod node of the Smalltalk C Code Generator, used in conjunction with SmartSyntaxPluginCodeGenerator and SmartSyntaxInterpreterPlugin to generate named primitives from methods containing type coercion specifications such as
  	primitive: functionName parameters: #(Boolean Oop String WordsArray WordsOrBytes)
  	primitive: functionName parameters: #(SmallInteger LargeNegativeInteger LargePositiveInteger Integer Unsigned) receiver: #Oop!

Item was removed:
- ----- Method: SmartSyntaxPluginTMethod>>extractSuppressFailureGuardDirective (in category 'transforming') -----
- extractSuppressFailureGuardDirective
- 	"Scan the top-level statements for a pragma directive of the form:
- 
- 		self suppressFailureGuards: <boolean>
- 
- 	 and remove the directive from the method body. Answer the argument
- 	 of the directive or false if there is no #supressFailureGuards: directive."
- 
- 	^self
- 		extractDirective: #suppressFailureGuards:
- 		valueBlock: [:sendNode| sendNode args first name = 'true']
- 		default: false!

Item was changed:
  ----- Method: SmartSyntaxPluginTMethod>>fixUpReturnOneStmt:on: (in category 'transforming') -----
  fixUpReturnOneStmt: stmt on: sStream
+ 	| expr exprRetStmts "p t" |
- 
  	stmt isReturn ifFalse: [^sStream nextPut: stmt].
+ 	expr := stmt expression.
+ 	(expr isSend
+ 	 and: [self resultSendAlwaysFails: expr]) ifTrue: 
+ 		["failure returns"
+ 		 sStream nextPut: expr; nextPut: self nullReturnExpr.
- 	(stmt expression isSend
- 	 and: [#('primitiveFail' 'primitiveFailFor:') includes: stmt expression selector]) ifTrue: 
- 		["failure return"
- 		 sStream nextPut: stmt expression.
- 		 sStream nextPut: self nullReturnExpr.
  		 ^nil].
+ 	(expr isVariable and: ['nil' = expr name]) ifTrue: 
- 	(stmt expression isVariable and: ['nil' = stmt expression name]) ifTrue: 
  		["^ nil -- this is never right unless automatically generated"
  		 sStream nextPut: stmt.
  		 ^nil].
+ 	(expr isVariable and: ['self' = expr name]) ifTrue: 
- 	(stmt expression isVariable and: ['self' = stmt expression name]) ifTrue: 
  		["^ self"
+ 		 fullArgs isEmpty ifFalse:
+ 			[sStream nextPut: (self statementGuardedWithSuccess: (self popExpr: fullArgs size))].
- 		 self generateFailureGuardOn: sStream.
- 		 fullArgs isEmpty ifFalse:[ sStream nextPut: (self popExpr: fullArgs size)].
  		 sStream nextPut: self nullReturnExpr.
  		 ^nil].
+ 	(expr isVariable or: [expr isConstant]) ifTrue:
- 	(stmt expression isVariable | stmt expression isConstant | suppressingFailureGuards) ifTrue:
  		["^ variable or ^ constant or ^ expr without guardchecking"
+ 		 fullArgs isEmpty ifFalse:
+ 			[sStream nextPut: (self statementGuardedWithSuccess: (self pop: fullArgs size + 1 thenReturnExpr: expr))].
- 		 self generateFailureGuardOn: sStream.
- 		 sStream nextPut: (self pop: fullArgs size + 1 thenReturnExpr: stmt expression).
  		 sStream nextPut: self nullReturnExpr.
  		 ^nil].
  	"^ expr with necessary guard checking"
+ 	"p := sStream position."
+ 	exprRetStmts := Array streamContents:
+ 		[:ersStream|
+ 		 (self resultExpressionCanFail: expr)
+ 			ifTrue:
+ 				["t := 1."
+ 				ersStream
+ 					nextPut: (self assign: (self oopVariable: '_return_value') expression: expr);
+ 					nextPut: (self statementGuardedWithSuccess: (self pop: fullArgs size + 1
+ 																		thenReturnExpr: (self oopVariable: '_return_value')))]
+ 			ifFalse:
+ 				["t := 2."
+ 				 ersStream nextPut: (self pop: fullArgs size + 1 thenReturnExpr: expr)]].
+ 		sStream isEmpty "No statements to cause failure, therefore no need for an initial failure guard."
+ 			ifTrue: [sStream nextPutAll: exprRetStmts]
+ 			ifFalse:
+ 				["t := t + 2."
+ 				 sStream nextPut: (self statementGuardedWithSuccess: exprRetStmts)].
+ 	sStream nextPut: self nullReturnExpr.
+ 	"Them := Dictionary new"
+ 	"(Them at: t ifAbsentPut: [Dictionary new])
+ 		at: self selector
+ 		put: (sStream originalContents copyFrom: p + 1 to: sStream position)"!
- 	sStream isEmpty ifFalse: [self generateFailureGuardOn: sStream].
- 	(self resultExpressionAlwaysFails: stmt expression)
- 		ifTrue:
- 			[sStream nextPut: stmt expression]
- 		ifFalse:
- 			[sStream nextPut: (self assign: (self oopVariable: '_return_value') expression: stmt expression).
- 			 (self resultExpressionCanFail: stmt expression) ifTrue:
- 				[self generateFailureGuardOn: sStream].
- 			 sStream nextPut: (self pop: fullArgs size + 1 thenReturnExpr: (self oopVariable: '_return_value'))].
- 	sStream nextPut: self nullReturnExpr!

Item was removed:
- ----- Method: SmartSyntaxPluginTMethod>>generateFailureGuardOn: (in category 'private') -----
- generateFailureGuardOn: sStream
- 	suppressingFailureGuards ifTrue: [^nil].
- 	sStream nextPutAll: self checkSuccessExpr
- !

Item was changed:
  ----- Method: SmartSyntaxPluginTMethod>>handlePrimitiveDirective:on: (in category 'specifying primitives') -----
  handlePrimitiveDirective: aStmt on: sStream
  
  	isPrimitive := true.
  	fullArgs := args.
  	locals addAll: args.
  	args := OrderedCollection new.
  	fullArgs with: parmSpecs do:
  		[:argName :spec |
  		self declarationAt: argName
  			put: (spec ccgDeclareCForVar: argName)].
  	aStmt isAssignment ifTrue:
  		[self declarationAt: aStmt variable name
  			put: (rcvrSpec ccgDeclareCForVar: aStmt variable name).
  		 sStream nextPutAll: (self
  			statementsFor:
  				(rcvrSpec
+ 					ccg:	SmartSyntaxPluginCodeGenerator new
- 					ccg:		SmartSyntaxPluginCodeGenerator new
  					prolog:  [:expr | aStmt variable name, ' := ', expr]
  					expr: 	aStmt variable name
+ 					index: 	fullArgs size)
- 					index: 	(fullArgs size))
  			varName: '')].
  
  	"only add the failure guard if there are args or it is an assignment"
+ 	(fullArgs isEmpty not or: [aStmt isAssignment]) ifTrue:
+ 		[sStream nextPutAll: self checkSuccessExpr].
- 	(fullArgs isEmpty not or:[aStmt isAssignment]) ifTrue:[self generateFailureGuardOn: sStream].
  	^true.
  !

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 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)].
+ 	validations := validations reject: [:validation| validation isNil].
+ 	validations isEmpty ifFalse:
+ 		[statements addAllLast: (self statementsFor:
+ 									(String streamContents:
+ 										[:s|
+ 										s nextPut: $(.
+ 										validations
+ 											do: [:validation| s nextPut: $(; nextPutAll: validation; nextPut: $)]
+ 											separatedBy: [s crtab; nextPutAll: 'and: ['].
+ 										s next: validations size - 1 put: $].
+ 										s	nextPutAll: ') ifFalse:';
+ 											crtab: 2;
+ 											nextPutAll: '[interpreterProxy primitiveFailFor: PrimErrBadArgument.';
+ 											crtab: 2;
+ 											nextPutAll: '^nil';
+ 											crtab: 2;
+ 											nextPut: $]])
+ 									varName: '')].
+ 	assigner := SmartSyntaxPluginAssignmentCodeGenerator new.
+ 	fullArgs withIndexDo:
+ 		[:arg :i|
+ 		statements addAllLast:
+ 			(self 
+ 				statementsFor: 
+ 					((parmSpecs at: i) 
+ 						ccg: 	assigner
+ 						prolog:  nil
+ 						expr: arg
+ 						index: (fullArgs size - i))
+ 				varName: '')].
+ 	^statements!
- 
- 	| cg |
- 	cg := SmartSyntaxPluginCodeGenerator new.
- 	^Array streamContents: [:sStream |
- 		1 to: fullArgs size do:
- 			[:i |
- 			 sStream nextPutAll: 
- 				(self 
- 					statementsFor: 
- 						((parmSpecs at: i) 
- 							ccg: 	cg
- 							prolog:  [:expr | (fullArgs at: i), ' := ', expr]
- 							expr: (fullArgs at: i)
- 							index: (fullArgs size - i))
- 					varName: '')]]!

Item was changed:
  ----- Method: SmartSyntaxPluginTMethod>>pop:thenReturnExpr: (in category 'private') -----
  pop: anInteger thenReturnExpr: anExpression
  
  	^TSendNode new
  		setSelector: #pop:thenPush:
  		receiver: (TVariableNode new setName: 'interpreterProxy')
+ 		arguments: {TConstantNode new setValue: anInteger. anExpression}!
- 		arguments: (Array 
- 			with: (TConstantNode new 
- 				setValue: anInteger)
- 			with: anExpression)!

Item was changed:
  ----- Method: SmartSyntaxPluginTMethod>>printTempsAndVar:on: (in category 'private') -----
  printTempsAndVar: varName on: aStream 
  	"add the required temps and the varname to the stream"
+ 	aStream nextPut: $|; space.
+ 	(#('rcvr' 'stackPointer' 'interpreterProxy') reject: [:each | locals includes: each]) do:
+ 		[:each | aStream nextPutAll: each;  space].
+ 	(locals reject: [:each | each first = $_]) do:
+ 		[:each | aStream nextPutAll: each;  space].
- 	aStream nextPutAll: '| '.
- 	(#('rcvr' 'stackPointer' 'interpreterProxy') reject: [:each | locals includes: each])
- 		do: [:each | aStream nextPutAll: each;
- 			 space].
- 	(locals reject: [:each | each first = $_])
- 		do: [:each | aStream nextPutAll: each;
- 			 space].
  "don't add varName twice. Probably a deeper reason for this, but WTH. TPR"
+ 	(locals includes: varName) ifFalse:
+ 		[aStream nextPutAll: varName; space].
+ 	aStream nextPut: $|; cr!
- 	(locals includes: varName) ifFalse:[aStream nextPutAll: varName].
- 	aStream nextPutAll: '|';
- 	 cr!

Item was removed:
- ----- Method: SmartSyntaxPluginTMethod>>resultExpressionAlwaysFails: (in category 'private') -----
- resultExpressionAlwaysFails: aTSendNode
- 	^aTSendNode selector == #success:
- 	 and: [aTSendNode args first isConstant
- 	 and: [aTSendNode args first value == false]]!

Item was changed:
  ----- Method: SmartSyntaxPluginTMethod>>resultExpressionCanFail: (in category 'private') -----
  resultExpressionCanFail: aTSendNode
  	"Neither asSmallIntegerObj nor asBooleanObj can fail."
+ 	^(#(asSmallIntegerObj asBooleanObj nilObject trueObject falseObject) includes: aTSendNode selector) not!
- 	^(#(asSmallIntegerObj asBooleanObj) includes: aTSendNode selector) not!

Item was added:
+ ----- Method: SmartSyntaxPluginTMethod>>resultSendAlwaysFails: (in category 'private') -----
+ resultSendAlwaysFails: aTSendNode
+ 	^(#(primitiveFail primitiveFailFor:) includes: aTSendNode selector)
+ 		or: [aTSendNode selector == #success:
+ 			 and: [aTSendNode args first isConstant
+ 			 and: [aTSendNode args first value == false]]]!

Item was changed:
  ----- Method: SmartSyntaxPluginTMethod>>setSelector:definingClass:args:locals:block:primitive:properties:comment: (in category 'initialization') -----
  setSelector: sel definingClass: class args: argList locals: localList block: aBlockNode primitive: aNumber properties: methodProperties comment: aComment
  	"Initialize this method using the given information."
  
  	selector := sel.
  	definingClass := class.
  	returnType := #sqInt. 	 "assume return type is sqInt for now"
  	args := argList asOrderedCollection collect: [:arg | arg key].
  	locals := (localList collect: [:arg | arg key]) asSet.
  	declarations := Dictionary new.
  	primitive := aNumber.
  	properties := methodProperties.
  	comment := aComment.
  	parseTree := aBlockNode asTranslatorNodeIn: self.
  	labels := Set new.
  	complete := false.  "set to true when all possible inlining has been done"
  	export := self extractExportDirective.
  	static := self extractStaticDirective.
  	self extractSharedCase.
  	isPrimitive := false.  "set to true only if you find a primtive direction."
- 	suppressingFailureGuards := self extractSuppressFailureGuardDirective.
  	self recordDeclarationsIn: CCodeGenerator basicNew. "Just for conventionalTypeForType:"
  	self extractPrimitiveDirectives.
  !

Item was added:
+ ----- Method: SmartSyntaxPluginTMethod>>statementGuardedWithSuccess: (in category 'private') -----
+ statementGuardedWithSuccess: aTParseNodeOrSequenceThereof
+ 	"Answer a TSendNode for interpreterProxy failed ifFalse: [aTParseNodeOrSequenceThereof]"
+ 	^TSendNode new
+ 		setSelector: #ifFalse:
+ 		receiver: (TSendNode new
+ 					setSelector: #failed
+ 					receiver: (TVariableNode new setName: 'interpreterProxy')
+ 					arguments: #())
+ 		arguments: {(aTParseNodeOrSequenceThereof isTParseNode and: [aTParseNodeOrSequenceThereof isStmtList])
+ 						ifTrue: [aTParseNodeOrSequenceThereof]
+ 						ifFalse: [TStmtListNode new
+ 									setArguments: #()
+ 									statements: (aTParseNodeOrSequenceThereof isCollection
+ 													ifTrue: [aTParseNodeOrSequenceThereof]
+ 													ifFalse: [{aTParseNodeOrSequenceThereof}])]}!

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

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asBooleanValueFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asBooleanValueFrom: stackIndex
+ 	^self loadAs: #isBooleanObject: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asCharPtrFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asCharPtrFrom: stackIndex
+ 	^self loadAs: #isWordsOrBytes: from: stackIndex!

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

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asFloatValueFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asFloatValueFrom: stackIndex
+ 	^self loadAs: #isFloatObject: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asIntPtrFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asIntPtrFrom: stackIndex
+ 	^self loadAs: #isWordsOrBytes: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asIntPtrFrom:andThen: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asIntPtrFrom: stackIndex andThen: validationString
+ 	^validationString, (self stackAccessorFor: stackIndex)!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asIntegerValueFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asIntegerValueFrom: stackIndex
+ 	^self loadAs: #isIntegerObject: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asKindOf:from: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asKindOf: aClass from: stackIndex
+ 	^self loadAs: #is:KindOf: class: aClass from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asKindOfIntegerFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asKindOfIntegerFrom: stackIndex
+ 	^self loadAs: #isKindOfInteger: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asMemberOf:from: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asMemberOf: aClass from: stackIndex
+ 	^self loadAs: #is:MemberOf: class: aClass from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asMemberOfLargeNegativeIntegerFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asMemberOfLargeNegativeIntegerFrom: stackIndex
+ 	^self loadAs: #isLargeNegativeIntegerObject: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asMemberOfLargePositiveIntegerFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asMemberOfLargePositiveIntegerFrom: stackIndex
+ 	^self loadAs: #isLargePositiveIntegerObject: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asNonIntegerValueFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asNonIntegerValueFrom: stackIndex
+ 	^self loadAs: #isNonImmediate: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asOopPtrFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asOopPtrFrom: stackIndex
+ 	^self loadAs: #isNonImmediate: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asOopPtrFrom:andThen: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asOopPtrFrom: stackIndex andThen: validationString
+ 	^String streamContents:
+ 		[:s|
+ 		 s	nextPut: $(;
+ 			nextPutAll: (self loadAs: #isPointers: from: stackIndex);
+ 			nextPutAll: ') and: [';
+ 			nextPutAll: validationString;
+ 			nextPutAll: (self stackAccessorFor: stackIndex);
+ 			nextPut: $]]!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asRawOopFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asRawOopFrom: anInteger
+ 	^nil!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asUnsignedPtrFrom:andThen: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asUnsignedPtrFrom: stackIndex andThen: validationString
+ 	^validationString, (self stackAccessorFor: stackIndex)!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asUnsignedValueFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asUnsignedValueFrom: 	stackIndex
+ 	^self loadAs: #isPositiveMachineIntegerObject: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asWBCharPtrFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asWBCharPtrFrom: stackIndex
+ 	^self loadAs: #isWordsOrBytes: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asWBFloatPtrFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asWBFloatPtrFrom: stackIndex
+ 	^self loadAs: #isWordsOrBytes: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgLoad:expr:asWBIntPtrFrom: (in category 'coercing') -----
+ ccgLoad: aBlock expr: aString asWBIntPtrFrom: stackIndex
+ 	^self loadAs: #isWordsOrBytes: from: stackIndex!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>ccgValBlock: (in category 'coercing support') -----
+ ccgValBlock: aString
+ 	^'interpreterProxy ', (aString, ': ')!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>loadAs:class:from: (in category 'coercing support') -----
+ loadAs: classMembershipSelector class: aClass from: stackIndex
+ 
+ 	^String streamContents:
+ 		[:aStream | | keywords |
+ 		 keywords := classMembershipSelector keywords.
+ 		 aStream
+ 			nextPutAll: 'interpreterProxy ';
+ 			nextPutAll: keywords first;
+ 			nextPutAll: (self stackAccessorFor: stackIndex);
+ 			space;
+ 			nextPutAll: keywords last;
+ 			nextPutAll:	' ''';
+ 			nextPutAll:	aClass asString;
+ 			nextPutAll: '''']!

Item was added:
+ ----- Method: SmartSyntaxPluginValidationCodeGenerator>>loadAs:from: (in category 'coercing support') -----
+ loadAs: classMembershipSelector from: stackIndex
+ 
+ 	^String streamContents:
+ 		[:aStream |
+ 		 aStream
+ 			nextPutAll: 'interpreterProxy ';
+ 			nextPutAll: classMembershipSelector;
+ 			nextPutAll: (self stackAccessorFor: stackIndex)]!

Item was changed:
  ----- Method: SocketPlugin>>socketValueOf: (in category 'primitives') -----
  socketValueOf: socketOop 
+ 	"Answer a pointer to the first byte of of the socket record within the  
- 	"Return a pointer to the first byte of of the socket record within the  
  	 given Smalltalk object, or nil if socketOop is not a socket record."
+ 	<returnTypeC: #SocketPtr>
+ 	^((interpreterProxy isBytes: socketOop)
+ 	   and: [(interpreterProxy byteSizeOf: socketOop) = self socketRecordSize])
+ 		ifTrue: [self cCoerce: (interpreterProxy firstIndexableField: socketOop) to: #SocketPtr]
+ 		ifFalse: [interpreterProxy primitiveFailFor: PrimErrBadArgument. nil]!
- 	<returnTypeC: 'SocketPtr'>
- 	interpreterProxy success: ((interpreterProxy isBytes: socketOop)
- 			and: [(interpreterProxy byteSizeOf: socketOop)
- 					= self socketRecordSize]).
- 	^interpreterProxy failed
- 		ifTrue: [nil]
- 		ifFalse: [self cCoerce: (interpreterProxy firstIndexableField: socketOop) to: 'SocketPtr']!

Item was added:
+ ----- Method: SpurMemoryManager>>isBooleanObject: (in category 'simulation only') -----
+ isBooleanObject: oop
+ 	"hack around the CoInterpreter/ObjectMemory split refactoring"
+ 	<doNotGenerate>
+ 	^coInterpreter isBooleanObject: oop!

Item was added:
+ ----- Method: SpurMemoryManager>>isPositiveMachineIntegerObject: (in category 'simulation only') -----
+ isPositiveMachineIntegerObject: oop
+ 	"hack around the CoInterpreter/ObjectMemory split refactoring"
+ 	<doNotGenerate>
+ 	^coInterpreter isPositiveMachineIntegerObject: oop!

Item was added:
+ ----- Method: StackInterpreter>>isBooleanObject: (in category 'plugin primitive support') -----
+ isBooleanObject: oop
+ 	^oop = objectMemory trueObject or: [oop = objectMemory falseObject]!

Item was changed:
  ----- Method: TMethod>>statementsFor:varName: (in category 'primitive compilation') -----
  statementsFor: sourceText varName: varName
  	"Return the parse tree for the given expression. The result is the statements list of the method parsed from the given source text."
  	"Details: Various variables are declared as locals to avoid Undeclared warnings from the parser."
  
  	| s |
  	s := WriteStream on: String new.
  	s nextPutAll: 'temp'; cr; crtab.
  	self printTempsAndVar: varName on: s.
  	s nextPutAll: sourceText.
+ 	^(([ | compiler |
+ 		compiler := Smalltalk compiler class: VMBasicConstants. "for primitive error codes"
+ 		(compiler parse: s contents)
- 	^ (([ | compiler |
- 		compiler := Smalltalk compiler class: Object.
- 	   (compiler parse: s contents)
  			compilationContext: compiler compilationContext;
  			yourself] "Pharo"
+ 		on: MessageNotUnderstood
+ 		do: [:ex|
+ 			ex message selector == #compiler ifFalse:
+ 				[ex pass].
+ 			Compiler new parse: s contents in: VMBasicConstants notifying: nil]) "Squeak"
+ 		asTranslationMethodOfClass: self class)
+ 			removeFinalSelfReturnIn: nil;
+ 			statements!
- 			on: MessageNotUnderstood
- 			do: [:ex|
- 				ex message selector == #compiler ifFalse:
- 					[ex pass].
- 				Compiler new parse: s contents in: Object notifying: nil]) "Squeak"
- 			asTranslationMethodOfClass: self class)
- 				removeFinalSelfReturnIn: nil;
- 				statements!

Item was added:
+ ----- Method: TestOSAPlugin class>>shouldBeTranslated (in category 'translation') -----
+ shouldBeTranslated
+ 	"As yet this can't be translated because a DescType parameter can't be handled."
+ 	^false!




More information about the Vm-dev mailing list