[squeak-dev] detecting if method has an prim error code

Igor Stasenko siguctua at gmail.com
Fri Feb 10 18:32:22 UTC 2012


On 10 February 2012 19:21, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>
>
> On Fri, Feb 10, 2012 at 9:56 AM, Igor Stasenko <siguctua at gmail.com> wrote:
>>
>> Is there a simple way to detect that given method using:
>>
>>
>> myMethod
>>  <primitive: #primFoo module: #moduleBar error: errorCode>
>>
>> but not:
>>
>> myMethod
>>  <primitive: #primFoo module: #moduleBar>
>>
>> ?
>
>
> Yes.  The first bytecode of a method that contains a primitive error code
> will be a temp store bytecode, storing the stack top to the error code (*).
>  e.g. in Decompiler>>#decompile:in:method:using: find
>
> "skip primitive error code store if necessary"
> (method primitive ~= 0 and: [self willStore]) ifTrue:
> [pc := pc + 2.
> tempVars := tempVars asOrderedCollection].
>
> ...
>
> method primitive > 0 ifTrue:
> [node removeAndRenameLastTempIfErrorCode].
>
> So (InstructionStream on: aMethod) willStore is nearly it.  However, quick
> methods confuse InstructionStream, so one needs aMethod isQuick not and:
> [(InstructionStream on: aMethod) willStore]
>
> and so
>
> (SystemNavigation new allSelect: [:m| m primitiveErrorVariableName notNil])
> = (SystemNavigation new allSelect: [:m| m isQuick not and:
> [(InstructionStream on: m) willStore]]) true
>
> and
>
> | m |
> m := Alien >> #sizeFieldPut:.
> { Time millisecondsToRun: [1 to: 1000000 do: [:i| m
> primitiveErrorVariableName notNil]].
> Time millisecondsToRun: [1 to: 1000000 do: [:i| m isQuick not and:
> [(InstructionStream on: m) willStore]]]. } #(3516 161)
>
> If you're searching, e.g. via browseAllSelect: then you'll save time by
> adding a primitive > 0 guard, so
>
> { [:m| m primitiveErrorVariableName notNil].
>   [:m| m primitive > 0 and: [m primitiveErrorVariableName notNil]].
>   [:m| m isQuick not and: [(InstructionStream on: m) willStore]].
>   [:m| m primitive > 0 and: [m isQuick not and: [(InstructionStream on: m)
> willStore]]] } collect:
> [:b|
> Time millisecondsToRun: [10 timesRepeat: [SystemNavigation new allSelect:
> b]]]
>  #(478 468 513 382)
>

No, i just writing a common handler for errors.
In my case, in NativeBoost many  methods using same primitive, in a
form that you can do it like:

myMethod
<primitive: #primitiveNativeCall module: #.. error: errorcode>

CommonErrorHandler handleError


like that i need to extract error code from a context state (a context
which is sender of #handleError), not from parameter which user should
always pass directly..
because forcing users to also pass the error code producing a lot of
extra code, which not necessary since i can access this stuff via
reflection.
Apparently, for making it work, first i need to know if primitive uses
that form of pragma or not, and then read the error code at right
place,
and of course i don't really care if it fast or quick or not :)

Thanks for clearing the fog :) Just wanted to know if i do it right.

>>
>> should i use a method's pragmas to see if it has
>> #primitive:module:error: pragma?
>>
>> And if this check is ok, do i remember correctly, that temp which is
>> used for storing an error is first temp in context, i.e.:
>>
>> err := context tempAt: 1
>>
>> ?
>
>
> No, its always the last.  The first temp is reserved for the first argument,
> if any.
>
>>
>>
>> (ok i checked, it is actually always last temp), no matter if i
>> declare temps before pragma or not.
>>
>> i.e. the order is same for:
>>
>> myMethod
>> | a b c |
>>  <primitive: #primFoo module: #moduleBar error: errorCode>
>>
>> and
>>
>> myMethod
>>  <primitive: #primFoo module: #moduleBar error: errorCode>
>> | a b c |
>
>
> Right.
>
> (*) the scheme is to have a no-op store to "store" the error code.  The
> store is always a store of the stack top to the last temp, but on entry to a
> method the stack top *is* the last temp.  So on old VMs this store has no
> effect, and on new VMs the store is taken as an indication that the last
> temp holds the primitive error code and that on failing a primitive the
> error code should be stored into the last temp.
>
>> --
>> Best regards,
>> Igor Stasenko.
>
> --
> best,
> Eliot
>
>
>
>



-- 
Best regards,
Igor Stasenko.


More information about the Squeak-dev mailing list