<div dir="ltr">Another explanation for VM foolproofing is here:<br><br><a href="http://forum.world.st/VM-safety-td4816223.html">http://forum.world.st/VM-safety-td4816223.html</a><br></div><div class="gmail_extra"><br><div class="gmail_quote">2016-03-05 3:16 GMT+01:00 <span dir="ltr"><<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:<br>
<a href="http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1713.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1713.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-nice.1713<br>
Author: nice<br>
Time: 5 March 2016, 3:15:22.817 am<br>
UUID: ac270981-d3ba-4c42-a2b1-3a83693776be<br>
Ancestors: VMMaker.oscog-nice.1712<br>
<br>
The size of [unsigned] long long was not infered...<br>
<br>
VM fool proofing:<br>
<br>
Fix a missing guard in SmartSyntaxPlugin like explained at<br>
<a href="http://forum.world.st/VM-safety-missing-failing-guards-in-SmartSyntaxPlugin-td4816518.html" rel="noreferrer" target="_blank">http://forum.world.st/VM-safety-missing-failing-guards-in-SmartSyntaxPlugin-td4816518.html</a><br>
<br>
Fix two missing guards in VM profiling primitives: one should not use the result of stackObjectValue: before checking for success, otherwise a null pointer exception will occur in case of failure.<br>
<br>
=============== Diff against VMMaker.oscog-nice.1712 ===============<br>
<br>
Item was changed:<br>
----- Method: CCodeGenerator>>sizeOfIntegralCType: (in category 'inlining') -----<br>
sizeOfIntegralCType: anIntegralCType "<String>"<br>
"N.B. Only works for values for which isIntegralCType: answers true."<br>
| prunedCType index |<br>
(anIntegralCType beginsWith: 'register ') ifTrue:<br>
[^self sizeOfIntegralCType: (anIntegralCType allButFirst: 9)].<br>
prunedCType := (anIntegralCType beginsWith: 'unsigned ')<br>
ifTrue: [(anIntegralCType allButFirst: 9) withBlanksTrimmed]<br>
ifFalse: [(anIntegralCType beginsWith: 'signed ')<br>
ifTrue: [(anIntegralCType allButFirst: 7) withBlanksTrimmed]<br>
ifFalse: [anIntegralCType]].<br>
^prunedCType asString caseOf: {<br>
['sqLong'] -> [8].<br>
['usqLong'] -> [8].<br>
+ ['long long'] -> [8].<br>
['sqInt'] -> [BytesPerWord].<br>
['usqInt'] -> [BytesPerWord].<br>
['int'] -> [4].<br>
['short'] -> [2].<br>
['short int'] -> [2].<br>
['char'] -> [1].<br>
['long'] -> [BytesPerWord].<br>
['size_t'] -> [BytesPerWord].<br>
['pid_t'] -> [BytesPerWord].<br>
}<br>
otherwise:<br>
[((anIntegralCType beginsWith: 'unsigned') "e.g. 'unsigned : 8'"<br>
and: [(anIntegralCType includesAnyOf: '[*]') not<br>
and: [(index := anIntegralCType indexOf: $:) > 0]])<br>
ifTrue: [(Integer readFrom: (anIntegralCType copyFrom: index + 1 to: anIntegralCType size) withBlanksTrimmed readStream) + 7 // 8]<br>
ifFalse: [self error: 'unrecognized integral type']]!<br>
<br>
Item was changed:<br>
----- Method: InterpreterPrimitives>>primitiveVMProfileInfoInto (in category 'process primitives') -----<br>
primitiveVMProfileInfoInto<br>
"Primitive. Answer whether the profiler is running or not.<br>
If the argument is an Array of suitable size fill it with the following information:<br>
1. the addresses of the first element of the VM histogram (the first address in the executable)<br>
2. the address following the last element (the last address in the executable, excluding dynamically linked libraries)<br>
3. the size of the VM histogram in bins (each bin is a 4 byte unsigned long)<br>
4. the size of the VM histogram in bins (each bin is a 4 byte unsigned long)"<br>
| info running exeStart exeLimit vmBins easBins |<br>
<var: #exeStart type: #'char *'><br>
<var: #exeLimit type: #'char *'><br>
<var: #vmBins type: #long><br>
<var: #easBins type: #long><br>
self success: argumentCount = 1.<br>
self successful ifTrue:<br>
+ [info := self stackObjectValue: 0].<br>
+ self successful ifTrue:<br>
+ [info ~= objectMemory nilObject ifTrue:<br>
- [info := self stackObjectValue: 0.<br>
- info ~= objectMemory nilObject ifTrue:<br>
[self assertClassOf: info is: (objectMemory splObj: ClassArray).<br>
self success: (objectMemory numSlotsOf: info) >= 4]].<br>
self successful ifFalse:<br>
[^nil].<br>
<br>
self cCode: 'ioProfileStatus(&running,&exeStart,&exeLimit,0,&vmBins,0,&easBins)'<br>
inSmalltalk: [running := exeStart := exeLimit := vmBins := easBins := 0].<br>
info ~= objectMemory nilObject ifTrue:<br>
[objectMemory storePointerUnchecked: 0<br>
ofObject: info<br>
withValue: (objectMemory integerObjectOf: (self oopForPointer: exeStart)).<br>
objectMemory storePointerUnchecked: 1<br>
ofObject: info<br>
withValue: (objectMemory integerObjectOf: (self oopForPointer: exeLimit)).<br>
objectMemory storePointerUnchecked: 2<br>
ofObject: info<br>
withValue: (objectMemory integerObjectOf: vmBins).<br>
objectMemory storePointerUnchecked: 3<br>
ofObject: info<br>
withValue: (objectMemory integerObjectOf: easBins)].<br>
self pop: 2 thenPushBool: running!<br>
<br>
Item was changed:<br>
----- Method: InterpreterPrimitives>>primitiveVMProfileSamplesInto (in category 'process primitives') -----<br>
primitiveVMProfileSamplesInto<br>
"Primitive.<br>
0 args: Answer whether the VM Profiler is running or not.<br>
1 arg: Copy the sample data into the supplied argument, which must be a Bitmap<br>
of suitable size. Answer the number of samples copied into the buffer."<br>
| sampleBuffer sampleBufferAddress running bufferSize numSamples |<br>
<var: #bufferSize type: #long><br>
<var: #sampleBufferAddress type: #'unsigned long *'><br>
self cCode: 'ioNewProfileStatus(&running,&bufferSize)'<br>
inSmalltalk: [running := false. bufferSize := 0].<br>
argumentCount = 0 ifTrue:<br>
[^self pop: 1 thenPushBool: running].<br>
self success: argumentCount = 1.<br>
self successful ifTrue:<br>
+ [sampleBuffer := self stackObjectValue: 0].<br>
+ self successful ifTrue:<br>
+ [self assertClassOf: sampleBuffer is: (objectMemory splObj: ClassBitmap).<br>
- [sampleBuffer := self stackObjectValue: 0.<br>
- self assertClassOf: sampleBuffer is: (objectMemory splObj: ClassBitmap).<br>
self success: (objectMemory numSlotsOf: sampleBuffer) >= bufferSize].<br>
self successful ifFalse:<br>
[^nil].<br>
sampleBufferAddress := objectMemory firstFixedField: sampleBuffer.<br>
numSamples := self cCode: 'ioNewProfileSamplesInto(sampleBufferAddress)'<br>
inSmalltalk: [sampleBufferAddress := sampleBufferAddress].<br>
self pop: argumentCount + 1 thenPushInteger: numSamples!<br>
<br>
Item was changed:<br>
----- Method: SmartSyntaxPluginTMethod>>fixUpReturnOneStmt:on: (in category 'transforming') -----<br>
fixUpReturnOneStmt: stmt on: sStream<br>
<br>
stmt isReturn ifFalse: [^sStream nextPut: stmt].<br>
(stmt expression isSend<br>
and: [#('primitiveFail' 'primitiveFailFor:') includes: stmt expression selector]) ifTrue:<br>
["failure return"<br>
sStream nextPut: stmt expression.<br>
sStream nextPut: self nullReturnExpr.<br>
^nil].<br>
(stmt expression isVariable and: ['nil' = stmt expression name]) ifTrue:<br>
["^ nil -- this is never right unless automatically generated"<br>
sStream nextPut: stmt.<br>
^nil].<br>
(stmt expression isVariable and: ['self' = stmt expression name]) ifTrue:<br>
["^ self"<br>
self generateFailureGuardOn: sStream.<br>
fullArgs isEmpty ifFalse:[ sStream nextPut: (self popExpr: fullArgs size)].<br>
sStream nextPut: self nullReturnExpr.<br>
^nil].<br>
(stmt expression isVariable | stmt expression isConstant | suppressingFailureGuards) ifTrue:<br>
["^ variable or ^ constant or ^ expr without guardchecking"<br>
self generateFailureGuardOn: sStream.<br>
sStream nextPut: (self pop: fullArgs size + 1 thenReturnExpr: stmt expression).<br>
sStream nextPut: self nullReturnExpr.<br>
^nil].<br>
"^ expr with guardchecking"<br>
+ self generateFailureGuardOn: sStream.<br>
sStream nextPut: (self assign: (self oopVariable: '_return_value') expression: stmt expression).<br>
self generateFailureGuardOn: sStream.<br>
sStream nextPut: (self pop: fullArgs size + 1 thenReturnExpr: (self oopVariable: '_return_value')).<br>
sStream nextPut: self nullReturnExpr<br>
!<br>
<br>
</blockquote></div><br></div>