<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 19, 2016 at 3:42 PM, Ben Coman <span dir="ltr">&lt;<a href="mailto:btc@openinworld.com" target="_blank">btc@openinworld.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><br>
The hierarchy goes<br>
  VMClass<br>
     InterpreterPrimitives<br>
        StackIntepreter<br>
          StackIntepreterPrimitives<br>
             CoInterpreter<br>
               CoInterpreterPrimitives<br>
<br>
from which a tick / tock (XXInterpreter / XXInterpreterPrimitives)<br>
pattern is apparent,<br>
and I wonder why Interpreter is missing above InterpreterPrimitives<br>
sitting off to the side.  I guess it is something to do with<br>
InterpreterPrimitives composing objectMemory as an instance variable<br>
rather than inheriting from ObjectMemory as Interpeter does?<br></blockquote><div><br></div><div>I think this is exactly that.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
The reason I ask is that I&#39;m trying a new approach to the OwnedLock primitives<br>
where if waitAcquire primitive sleeps, when the process wakes up it<br>
retries the primitive.<br>
So effectively the process sleeps at the top of the waitAquire rather<br>
than the bottom,<br>
and the process truly cannot proceed past that point until it gains<br>
the lock. I have this working if StackInterpreterPrimitives holds the<br>
primitive, but if I move the primitive to InterpreterPrimitives,<br>
instructionPointer is unknown.<br>
<br></blockquote><div> </div><div>In general, you implement in InterpreterPrimitives the primitives that would work with the Interpreter, and in StackInterpreterPrimitives the ones specific to the StackInterpreter. If you have a bug in InterpreterPrimitives, it&#39;s likely to be specific to the StackInterpreter.</div><div><br></div><div>In the future the Cog branch may merge with the trunk, hence Interpreter will be back in the hierarchy. </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
P.S. For the curious, here is the proof of concept I tried.  A single<br>
call to the primitive counts up to four by backing up the<br>
instructionPointer such that the primitive is executed again, until<br>
the exit condition of four is reached.<br>
<br>
(Note the use of Semaphore and ExcessSignalsIndex is not significant,<br>
just an expedient template I was familiar with.)<br>
<br>
# VM SIDE...<br>
<br>
StackInterpreterPrimitives &gt;&gt; primitiveRetryExperiment<br>
    | excessSignals stackTop |<br>
    stackTop := self stackTop.<br>
    excessSignals := objectMemory fetchInteger: ExcessSignalsIndex<br>
ofObject: stackTop.<br>
    excessSignals := excessSignals + 1.<br>
    objectMemory storeInteger: ExcessSignalsIndex<br>
        ofObject: stackTop<br>
        withValue: excessSignals.<br>
    [ excessSignals &gt; 3 ] ifFalse: [ instructionPointer :=<br>
instructionPointer - 1 ].<br>
<br>
StackInterpreter class &gt;&gt; initializePrimitiveTable<br>
    (234 primitiveRetryExperiment)<br>
<br></blockquote><div><br></div><div>... Why instructionPointer - 1 ? It works if the send is encoded in a single byte as by chance is the case in your example, else your interpretation get misaligned, which is a complete nonsense (unless you&#39;re working with a Smalltalk-78 VM ;-) ). Going backward in the instructions is not that trivial, you need a scanner to find the previous pc. See #skipBackBeforeJump for example, which goes backward 1 instruction in the image side. You need to implement something similar in the interpreter if you want to do that... but you don&#39;t. </div><div><br></div><div>Although going back one instruction is very funny, it won&#39;t work with the JIT, unless you do something completely evil, crazy and hackish. Most likely you want in fact to implement your primitive with a while loop instead, so you don&#39;t need that ip modification hack. Why didn&#39;t you do a while loop in the first place ? Primitive calls are not interrupt points anyway, it would be exactly the same behavior, wouldn&#39;t it ?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
# IMAGE SIDE...<br>
<br>
Semaphore subclass: #PrimExp<br>
    instanceVariableNames: &#39;&#39;<br>
    classVariableNames: &#39;&#39;<br>
    package: &#39;0PrimitiveRetryExperiment&#39;<br>
<br>
PrimExp &gt;&gt; initialize<br>
    excessSignals := 1.<br>
<br>
PrimExp &gt;&gt; primRetryExperiment<br>
    &lt;primitive: 234&gt;<br>
<br>
PrimExp &gt;&gt; excessSignals<br>
    ^ excessSignals<br>
<br>
# TEST CASE...<br>
<br>
PrimExp new primRetryExperiment excessSignals<br>
    --&gt; 4<br>
<br>
I&#39;ve only done this with the Stack VM so far.  I&#39;ll report further<br>
when I try it with Cog.<br>
<br></blockquote><div><br></div><div>It&#39;s nice to see people trying to hack the VM :-). I&#39;ll try to answer your other questions.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
cheers -ben<br>
</blockquote></div><br></div></div>