[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