<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">&lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>&gt;</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&gt;&gt;sizeOfIntegralCType: (in category &#39;inlining&#39;) -----<br>
  sizeOfIntegralCType: anIntegralCType &quot;&lt;String&gt;&quot;<br>
        &quot;N.B. Only works for values for which isIntegralCType: answers true.&quot;<br>
        | prunedCType index |<br>
        (anIntegralCType beginsWith: &#39;register &#39;) ifTrue:<br>
                [^self sizeOfIntegralCType: (anIntegralCType allButFirst: 9)].<br>
        prunedCType := (anIntegralCType beginsWith: &#39;unsigned &#39;)<br>
                                                ifTrue: [(anIntegralCType allButFirst: 9) withBlanksTrimmed]<br>
                                                ifFalse: [(anIntegralCType beginsWith: &#39;signed &#39;)<br>
                                                                        ifTrue: [(anIntegralCType allButFirst: 7) withBlanksTrimmed]<br>
                                                                        ifFalse: [anIntegralCType]].<br>
        ^prunedCType asString caseOf: {<br>
                [&#39;sqLong&#39;]      -&gt;      [8].<br>
                [&#39;usqLong&#39;]     -&gt;      [8].<br>
+               [&#39;long long&#39;]   -&gt;      [8].<br>
                [&#39;sqInt&#39;]               -&gt;      [BytesPerWord].<br>
                [&#39;usqInt&#39;]      -&gt;      [BytesPerWord].<br>
                [&#39;int&#39;]         -&gt;      [4].<br>
                [&#39;short&#39;]               -&gt;      [2].<br>
                [&#39;short int&#39;]   -&gt;      [2].<br>
                [&#39;char&#39;]                -&gt;      [1].<br>
                [&#39;long&#39;]                -&gt;      [BytesPerWord].<br>
                [&#39;size_t&#39;]              -&gt;      [BytesPerWord].<br>
                [&#39;pid_t&#39;]               -&gt;      [BytesPerWord].<br>
        }<br>
        otherwise:<br>
                [((anIntegralCType beginsWith: &#39;unsigned&#39;) &quot;e.g. &#39;unsigned  : 8&#39;&quot;<br>
                  and: [(anIntegralCType includesAnyOf: &#39;[*]&#39;) not<br>
                  and: [(index := anIntegralCType indexOf: $:) &gt; 0]])<br>
                        ifTrue: [(Integer readFrom: (anIntegralCType copyFrom: index + 1 to: anIntegralCType size) withBlanksTrimmed readStream) + 7 // 8]<br>
                        ifFalse: [self error: &#39;unrecognized integral type&#39;]]!<br>
<br>
Item was changed:<br>
  ----- Method: InterpreterPrimitives&gt;&gt;primitiveVMProfileInfoInto (in category &#39;process primitives&#39;) -----<br>
  primitiveVMProfileInfoInto<br>
        &quot;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)&quot;<br>
        | info running exeStart exeLimit vmBins easBins |<br>
        &lt;var: #exeStart type: #&#39;char *&#39;&gt;<br>
        &lt;var: #exeLimit type: #&#39;char *&#39;&gt;<br>
        &lt;var: #vmBins type: #long&gt;<br>
        &lt;var: #easBins type: #long&gt;<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) &gt;= 4]].<br>
        self successful ifFalse:<br>
                [^nil].<br>
<br>
        self cCode: &#39;ioProfileStatus(&amp;running,&amp;exeStart,&amp;exeLimit,0,&amp;vmBins,0,&amp;easBins)&#39;<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&gt;&gt;primitiveVMProfileSamplesInto (in category &#39;process primitives&#39;) -----<br>
  primitiveVMProfileSamplesInto<br>
        &quot;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.&quot;<br>
        | sampleBuffer sampleBufferAddress running bufferSize numSamples |<br>
        &lt;var: #bufferSize type: #long&gt;<br>
        &lt;var: #sampleBufferAddress type: #&#39;unsigned long *&#39;&gt;<br>
        self cCode: &#39;ioNewProfileStatus(&amp;running,&amp;bufferSize)&#39;<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) &gt;= bufferSize].<br>
        self successful ifFalse:<br>
                [^nil].<br>
        sampleBufferAddress := objectMemory firstFixedField: sampleBuffer.<br>
        numSamples := self cCode: &#39;ioNewProfileSamplesInto(sampleBufferAddress)&#39;<br>
                                                inSmalltalk: [sampleBufferAddress := sampleBufferAddress].<br>
        self pop: argumentCount + 1 thenPushInteger: numSamples!<br>
<br>
Item was changed:<br>
  ----- Method: SmartSyntaxPluginTMethod&gt;&gt;fixUpReturnOneStmt:on: (in category &#39;transforming&#39;) -----<br>
  fixUpReturnOneStmt: stmt on: sStream<br>
<br>
        stmt isReturn ifFalse: [^sStream nextPut: stmt].<br>
        (stmt expression isSend<br>
         and: [#(&#39;primitiveFail&#39; &#39;primitiveFailFor:&#39;) includes: stmt expression selector]) ifTrue:<br>
                [&quot;failure return&quot;<br>
                 sStream nextPut: stmt expression.<br>
                 sStream nextPut: self nullReturnExpr.<br>
                 ^nil].<br>
        (stmt expression isVariable and: [&#39;nil&#39; = stmt expression name]) ifTrue:<br>
                [&quot;^ nil -- this is never right unless automatically generated&quot;<br>
                 sStream nextPut: stmt.<br>
                 ^nil].<br>
        (stmt expression isVariable and: [&#39;self&#39; = stmt expression name]) ifTrue:<br>
                [&quot;^ self&quot;<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>
                [&quot;^ variable or ^ constant or ^ expr without guardchecking&quot;<br>
                 self generateFailureGuardOn: sStream.<br>
                 sStream nextPut: (self pop: fullArgs size + 1 thenReturnExpr: stmt expression).<br>
                 sStream nextPut: self nullReturnExpr.<br>
                 ^nil].<br>
        &quot;^ expr with guardchecking&quot;<br>
+       self generateFailureGuardOn: sStream.<br>
        sStream nextPut: (self assign: (self oopVariable: &#39;_return_value&#39;) expression: stmt expression).<br>
        self generateFailureGuardOn: sStream.<br>
        sStream nextPut: (self pop: fullArgs size + 1 thenReturnExpr: (self oopVariable: &#39;_return_value&#39;)).<br>
        sStream nextPut: self nullReturnExpr<br>
  !<br>
<br>
</blockquote></div><br></div>