<br><br><div class="gmail_quote">On Wed, Jan 25, 2012 at 5:21 AM, Andreas Raab <span dir="ltr">&lt;<a href="mailto:andreas.raab@gmx.de">andreas.raab@gmx.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 <br>
  
    
  
  <div bgcolor="#FFFFFF" text="#000000">
    Hi Eliot -<br>
    <br>
    On 1/25/2012 2:43, Eliot Miranda wrote:
    <blockquote type="cite">On Tue, Jan 24, 2012 at 2:02 PM, Mariano Martinez Peck
      <span dir="ltr">&lt;<a href="mailto:marianopeck@gmail.com" target="_blank">marianopeck@gmail.com</a>&gt;</span>
      wrote:<br>
      <div class="gmail_quote">
        <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
           <br>
          sorry...here is the attached. <br>
        </blockquote>
        <div><br>
        </div>
        <div>OK. What you&#39;ve done will work.  <br>
        </div>
      </div>
    </blockquote>
    <br>
    I actually quite like it. Getting rid of all those methods in class
    ProtoObject is definitely a good thing. Is there any downside other
    than some possible performance issues? I.e., the code should work
    everywhere, right?<br></div></blockquote><div><br></div><div>Right.  The primitive I implemented at Qwaq/Teleplace (ContextPart&gt;&gt;#tryNamedPrimitiveIn:for:withArgs:) makes these methods obsolete but since this primitive isn&#39;t yet in the standard VM the body uses those old methods in case the primitive doesn&#39;t exist.  As soon as the primitive is in the standard VM as well there&#39;s neither no need for those methods in ProtoObject nor the need to synthesize a method on each use.  The synthesizing a method approach has a nice conceptual simplicity.  It doesn&#39;t need a special primitive, and uses machinery that already exists.  But IIRC we decided to go the primitive route because ContextPart&gt;&gt;#tryPrimitiveFor:receiver:args: already existed and provided a model.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div bgcolor="#FFFFFF" text="#000000">
    <br>
    <blockquote type="cite">
      <div class="gmail_quote">
        <div>Some criticism: Since the method is new the flushCache
          should be unneeded.  I think either copying a template method
          (e.g. stored in a class variable) and  changing its argument
          count, or creating a method directly (look at the generate:
          method) would be much faster.  Speed can be important in the
          debugger.</div>
      </div>
    </blockquote>
    <br>
    More important in my view is the misuse of the term &quot;temporal&quot; in
    the method names. I find it quite confusing to read about &quot;temporal&quot;
    compiled methods :-)<br>
    <br>
    Cheers,<br>
      - Andreas<br>
    <br>
    <blockquote type="cite">
      <div class="gmail_quote">
        <div><br>
        </div>
        <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
          <div class="gmail_quote">On Tue, Jan 24, 2012 at 11:01 PM,
            Mariano Martinez Peck <span dir="ltr">&lt;<a href="mailto:marianopeck@gmail.com" target="_blank">marianopeck@gmail.com</a>&gt;</span>
            wrote:<br>
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
              <div class="gmail_quote">
                <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                  <div class="gmail_quote">
                    <div>
                      <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                        <div class="gmail_quote">
                          <blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                            <div class="gmail_quote">
                              <div><br>
                              </div>
                              <div>Analogously, one needs a way of
                                invoking named primitives in the
                                debugger, and using
                                tryNamedPrimitive[:with:with:...] et al
                                has exactly the same weaknesses
                                as tryPrimitiveN above.  So introducing
                                a primitive to run named primitives is
                                in keeping with tryPrimitive:withArgs:.
                                 Using the VisualWorks approach is
                                feasible but violates Occam&#39;s razor.</div>
                            </div>
                          </blockquote>
                          <div><br>
                            What what about temporally (to be removed in
                            the future) just when we are using older
                            VMs?<br>
                          </div>
                        </div>
                      </blockquote>
                      <div><br>
                      </div>
                    </div>
                    <div>If temporary, then fine.  But its all work :)</div>
                  </div>
                </blockquote>
                <div><br>
                  <br>
                  Well...writing papers can be boring ;)<br>
                  Please, could you take a look to the attached .cs?  I
                  tried to do what I had in mind. Since this part of the
                  system is new for me, I have not sure it is correct,
                  nor how to test it. So far what I did for testing it
                  is to take the  #tryNamedPrimitiveIn: aCompiledMethod
                  for: aReceiver withArgs: arguments<br>
                  and (temporally) remove the &lt;primitive: 218 error:
                  ec&gt; and define &#39;ec&#39; as a temporal variable. Since
                  it will be nil, the following code will be executed.<br>
                  Then I put a halt in #open: fileName forWrite:
                  writeMode   from StandardFileStream and then I do it:<br>
                  FileDirectory default forceNewFileNamed: &#39;xxxxx&#39;.<br>
                  Once in the debugger, I went to:<br>
                  <br>
                  StandardFileStream retryWithGC:[self primOpen: f
                  writable: writeMode] <br>
                                      until:[:id| id notNil] <br>
                                      forFileNamed: fileName.<br>
                  <br>
                  did a &quot;through&quot; in the close, and be sure I could do
                  &quot;into&quot; and &quot;step&quot; for #self primOpen: f writable:
                  writeMode  (which is a named primitive).<br>
                  <br>
                  is this ok?<br>
                  <br>
                  Thanks Eliot!<br>
                  <br>
                    <br>
                </div>
                <div>
                  <div>
                    <blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                      <div class="gmail_quote">
                        <div>
                           </div>
                        <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                          <div class="gmail_quote">
                            <div> </div>
                            <blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                              <div class="gmail_quote">
                                <div><br>
                                </div>
                                <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                                  Why do we need them in ProtoObject?<br>
                                </blockquote>
                                <div><br>
                                </div>
                                <div>Once
                                  tryNamedPrimitiveIn:for:withArgs: is
                                  implemented in all relevant virtual
                                  machines we don&#39;t need them.  You&#39;ll
                                  notice that there is no trace of the
                                  tryPrimitiveN methods anymore, even
                                  though they&#39;re in Smalltalk-80.</div>
                                <div> </div>
                                <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                                  Because I&#39;m not sure that adding
                                  primitive to VM is always a good
                                  solution.<br>
                                </blockquote>
                                <div><br>
                                </div>
                                <div>Agreed.  But it is in keeping with
                                  the primitive for invoking numbered
                                  primitives,  tryPrimitive:withArgs:.</div>
                                <div><br>
                                </div>
                                <div><br>
                                </div>
                                <div>HTH</div>
                                <div>Eliot</div>
                                <div><br>
                                </div>
                                <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                                  <br>
                                  Stef<br>
                                  <div>
                                    <div><br>
                                      &gt; On Mon, Jan 23, 2012 at 8:52
                                      AM, Mariano Martinez Peck &lt;<a href="mailto:marianopeck@gmail.com" target="_blank">marianopeck@gmail.com</a>&gt;
                                      wrote:<br>
                                      &gt; Hi guys. I usually like to
                                      take a look to ProtoObject and see
                                      what is really needed for the
                                      minimal object. But having 30% of
                                      the methods being
                                       #tryNamedPrimitive:with: *  is
                                      not fun.<br>
                                      &gt; So...I wonder, do you think
                                      there could be another way so that
                                      to avoid having all those methods
                                      in ProtoObject ?<br>
                                      &gt;<br>
                                      &gt; Yes there is.  I implemented
                                      primitive 218 in Cog,
                                      primitiveDoNamedPrimitiveWithArgs,
                                      which is accessed via<br>
                                      &gt;<br>
                                      &gt;<br>
                                      &gt;              
                                      tryNamedPrimitiveIn:
                                      aCompiledMethod for: aReceiver
                                      withArgs: arguments<br>
                                      &gt;                       |
                                      selector theMethod spec
                                      receiverClass |<br>
                                      &gt;                      
                                      &lt;primitive: 218 error: ec&gt;<br>
                                      &gt;                       ec
                                      ifNotNil:<br>
                                      &gt;                              
                                      [&quot;If ec is an integer other than
                                      -1 there was a problem with
                                      primitive 218,<br>
                                      &gt;                              
                                        not with the external primitive
                                      itself.  -1 indicates a generic
                                      failure (where<br>
                                      &gt;                              
                                        ec should be nil) but ec = nil
                                      means primitive 218 is not
                                      implemented.  So<br>
                                      &gt;                              
                                        interpret -1 to mean the
                                      external primitive failed with a
                                      nil error code.&quot;<br>
                                      &gt;                              
                                       ec isInteger ifTrue:<br>
                                      &gt;                              
                                              [ec = -1<br>
                                      &gt;                              
                                                      ifTrue: [ec :=
                                      nil]<br>
                                      &gt;                              
                                                      ifFalse: [self
                                      primitiveFailed]].<br>
                                      &gt;                              
                                      ^{PrimitiveFailToken. ec}].<br>
                                      &gt;                       &quot;Assume
                                      a nil error code implies the
                                      primitive is not implemented and
                                      fall back on the old code.&quot;<br>
                                      &gt;                       &quot;Hack.
                                      Attempt to execute the named
                                      primitive from the given compiled
                                      method&quot;<br>
                                      &gt;                      
                                      arguments size &gt; 8 ifTrue:<br>
                                      &gt;                              
                                      [^{PrimitiveFailToken. nil}].<br>
                                      &gt;                      
                                      selector := #(<br>
                                      &gt;                              
                                      tryNamedPrimitive<br>
                                      &gt;                              
                                      tryNamedPrimitive:<br>
                                      &gt;                              
                                      tryNamedPrimitive:with:<br>
                                      &gt;                              
                                      tryNamedPrimitive:with:with:<br>
                                      &gt;                              
                                      tryNamedPrimitive:with:with:with:<br>
                                      &gt;                              
tryNamedPrimitive:with:with:with:with:<br>
                                      &gt;                              
tryNamedPrimitive:with:with:with:with:with:<br>
                                      &gt;                              
tryNamedPrimitive:with:with:with:with:with:with:<br>
                                      &gt;                              
                                      tryNamedPrimitive:with:with:with:with:with:with:with:)
                                      at: arguments size+1.<br>
                                      &gt;                      
                                      receiverClass := self objectClass:
                                      aReceiver.<br>
                                      &gt;                      
                                      theMethod := receiverClass
                                      lookupSelector: selector.<br>
                                      &gt;                      
                                      theMethod == nil ifTrue:<br>
                                      &gt;                              
                                      [^{PrimitiveFailToken. nil}].<br>
                                      &gt;                       spec :=
                                      theMethod literalAt: 1.<br>
                                      &gt;                       spec
                                      replaceFrom: 1 to: spec size with:
                                      (aCompiledMethod literalAt: 1)
                                      startingAt: 1.<br>
                                      &gt;                      
                                      Smalltalk
                                      unbindExternalPrimitives.<br>
                                      &gt;                       ^self
                                      object: aReceiver perform:
                                      selector withArguments: arguments
                                      inClass: receiverClass<br>
                                      &gt;<br>
                                      &gt; (cf tryPrimitive: withArgs:)
                                      and used in<br>
                                      &gt;<br>
                                      &gt;<br>
                                      &gt;               doPrimitive:
                                      primitiveIndex method: meth
                                      receiver: receiver args: arguments<br>
                                      &gt;                      
                                      &quot;Simulate a primitive method whose
                                      index is primitiveIndex.  The
                                      simulated receiver<br>
                                      &gt;                        and
                                      arguments are given as arguments
                                      to this message. Any primitive
                                      which provokes<br>
                                      &gt;                      
                                       execution needs to be intercepted
                                      and simulated to avoid execution
                                      running away.&quot;<br>
                                      &gt;<br>
                                      &gt;                       | value
                                      |<br>
                                      &gt;                       &quot;If
                                      successful, push result and return
                                      resuming context, else ^ {
                                      PrimitiveFailToken. errorCode }&quot;<br>
                                      &gt;                      
                                      (primitiveIndex = 19) ifTrue:<br>
                                      &gt;                              
                                      [ToolSet<br>
                                      &gt;                              
                                              debugContext: self<br>
                                      &gt;                              
                                              label:&#39;Code simulation
                                      error&#39;<br>
                                      &gt;                              
                                              contents: nil].<br>
                                      &gt;<br>
                                      &gt;                      
                                      &quot;ContextPart&gt;&gt;blockCopy:;
                                      simulated to get startpc right&quot;<br>
                                      &gt;                      
                                      (primitiveIndex = 80 and: [(self
                                      objectClass: receiver)
                                      includesBehavior: ContextPart])<br>
                                      &gt;                              
                                      ifTrue: [^self push:
                                      ((BlockContext newForMethod:
                                      receiver method)<br>
                                      &gt;                              
                                                                     
                                      home: receiver home<br>
                                      &gt;                              
                                                                     
                                      startpc: pc + 2<br>
                                      &gt;                              
                                                                     
                                      nargs: (arguments at: 1))].<br>
                                      &gt;                      
                                      (primitiveIndex = 81 and: [(self
                                      objectClass: receiver) ==
                                      BlockContext])
                                      &quot;BlockContext&gt;&gt;value[:value:...]&quot;<br>
                                      &gt;                              
                                      ifTrue: [^receiver pushArgs:
                                      arguments from: self].<br>
                                      &gt;                      
                                      (primitiveIndex = 82 and: [(self
                                      objectClass: receiver) ==
                                      BlockContext])
                                      &quot;BlockContext&gt;&gt;valueWithArguments:&quot;<br>
                                      &gt;                              
                                      ifTrue: [^receiver pushArgs:
                                      arguments first from: self].<br>
                                      &gt;                      
                                      primitiveIndex = 83 &quot;afr 9/11/1998
                                      19:50&quot;
                                      &quot;Object&gt;&gt;perform:[with:...]&quot;<br>
                                      &gt;                              
                                      ifTrue: [^self send: arguments
                                      first<br>
                                      &gt;                              
                                                              to:
                                      receiver<br>
                                      &gt;                              
                                                              with:
                                      arguments allButFirst<br>
                                      &gt;                              
                                                              super:
                                      false].<br>
                                      &gt;                      
                                      primitiveIndex = 84 &quot;afr 9/11/1998
                                      19:50 &amp; eem 8/18/2009 17:04&quot;
                                      &quot;Object&gt;&gt;perform:withArguments:&quot;<br>
                                      &gt;                              
                                      ifTrue: [^self send: arguments
                                      first<br>
                                      &gt;                              
                                                              to:
                                      receiver<br>
                                      &gt;                              
                                                              with:
                                      (arguments at: 2)<br>
                                      &gt;                              
                                                             
                                      startClass: nil].<br>
                                      &gt;                      
                                      primitiveIndex = 100 &quot;eem
                                      8/18/2009 16:57&quot;
                                      &quot;Object&gt;&gt;perform:withArguments:inSuperclass:&quot;<br>
                                      &gt;                              
                                      ifTrue: [^self send: arguments
                                      first<br>
                                      &gt;                              
                                                              to:
                                      receiver<br>
                                      &gt;                              
                                                              with:
                                      (arguments at: 2)<br>
                                      &gt;                              
                                                             
                                      startClass: (arguments at: 3)].<br>
                                      &gt;<br>
                                      &gt;                      
                                      &quot;Mutex&gt;&gt;primitiveEnterCriticalSection<br>
                                      &gt;                      
                                       Mutex&gt;&gt;primitiveTestAndSetOwnershipOfCriticalSection&quot;<br>
                                      &gt;                      
                                      (primitiveIndex = 186 or:
                                      [primitiveIndex = 187]) ifTrue:<br>
                                      &gt;                              
                                      [| active effective |<br>
                                      &gt;                              
                                       active := Processor
                                      activeProcess.<br>
                                      &gt;                              
                                       effective := active
                                      effectiveProcess.<br>
                                      &gt;                              
                                       &quot;active == effective&quot;<br>
                                      &gt;                              
                                       value := primitiveIndex = 186<br>
                                      &gt;                              
                                                              ifTrue:
                                      [receiver
                                      primitiveEnterCriticalSectionOnBehalfOf:
                                      effective]<br>
                                      &gt;                              
                                                              ifFalse:
                                      [receiver
                                      primitiveTestAndSetOwnershipOfCriticalSectionOnBehalfOf:
                                      effective].<br>
                                      &gt;                              
                                       ^(value isArray<br>
                                      &gt;                              
                                          and: [value size = 2<br>
                                      &gt;                              
                                          and: [value first ==
                                      PrimitiveFailToken]])<br>
                                      &gt;                              
                                              ifTrue: [value]<br>
                                      &gt;                              
                                              ifFalse: [self push:
                                      value]].<br>
                                      &gt;<br>
                                      &gt;                      
                                      primitiveIndex = 188 ifTrue: &quot;eem
                                      5/27/2008 11:10
                                      Object&gt;&gt;withArgs:executeMethod:&quot;<br>
                                      &gt;                              
                                      [^MethodContext<br>
                                      &gt;                              
                                              sender: self<br>
                                      &gt;                              
                                              receiver: receiver<br>
                                      &gt;                              
                                              method: (arguments at: 2)<br>
                                      &gt;                              
                                              arguments: (arguments at:
                                      1)].<br>
                                      &gt;<br>
                                      &gt;                      
                                      &quot;Closure primitives&quot;<br>
                                      &gt;                      
                                      (primitiveIndex = 200 and: [self
                                      == receiver]) ifTrue:<br>
                                      &gt;                              
                                      &quot;ContextPart&gt;&gt;closureCopy:copiedValues:;
                                      simulated to get startpc right&quot;<br>
                                      &gt;                              
                                      [^self push: (BlockClosure<br>
                                      &gt;                              
                                                                     
                                      outerContext: receiver<br>
                                      &gt;                              
                                                                     
                                      startpc: pc + 2<br>
                                      &gt;                              
                                                                     
                                      numArgs: arguments first<br>
                                      &gt;                              
                                                                     
                                      copiedValues: arguments last)].<br>
                                      &gt;                      
                                      ((primitiveIndex between: 201 and:
                                      205)                
                                       &quot;BlockClosure&gt;&gt;value[:value:...]&quot;<br>
                                      &gt;                       or:
                                      [primitiveIndex between: 221 and:
                                      222]) ifTrue:
                                      &quot;BlockClosure&gt;&gt;valueNoContextSwitch[:]&quot;<br>
                                      &gt;                              
                                      [^receiver
                                      simulateValueWithArguments:
                                      arguments caller: self].<br>
                                      &gt;                      
                                      primitiveIndex = 206 ifTrue:      
                                                                       
                                       
                                       &quot;BlockClosure&gt;&gt;valueWithArguments:&quot;<br>
                                      &gt;                              
                                      [^receiver
                                      simulateValueWithArguments:
                                      arguments first caller: self].<br>
                                      &gt;<br>
                                      &gt;                      
                                      primitiveIndex = 118 ifTrue:
                                      &quot;tryPrimitive:withArgs:; avoid
                                      recursing in the VM&quot;<br>
                                      &gt;                              
                                      [(arguments size = 2<br>
                                      &gt;                              
                                       and: [arguments first isInteger<br>
                                      &gt;                              
                                       and: [arguments last class ==
                                      Array]]) ifFalse:<br>
                                      &gt;                              
                                              [^ContextPart
                                      primitiveFailTokenFor: nil].<br>
                                      &gt;                              
                                       ^self doPrimitive: arguments
                                      first method: meth receiver:
                                      receiver args: arguments last].<br>
                                      &gt;<br>
                                      &gt;                       value
                                      := primitiveIndex = 120 &quot;FFI
                                      method&quot;<br>
                                      &gt;                              
                                                      ifTrue: [(meth
                                      literalAt: 1)
                                      tryInvokeWithArguments: arguments]<br>
                                      &gt;                              
                                                      ifFalse:<br>
                                      &gt;                              
                                                             
                                      [primitiveIndex = 117 &quot;named
                                      primitives&quot;<br>
                                      &gt;                              
                                                                     
                                      ifTrue: [self tryNamedPrimitiveIn:
                                      meth for: receiver withArgs:
                                      arguments]<br>
                                      &gt;                              
                                                                     
                                      ifFalse:<br>
                                      &gt;                              
                                                                       
                                            [receiver tryPrimitive:
                                      primitiveIndex withArgs:
                                      arguments]].<br>
                                      &gt;                       ^(value
                                      isArray<br>
                                      &gt;                          
                                      and: [value size = 2<br>
                                      &gt;                          
                                      and: [value first ==
                                      PrimitiveFailToken]])<br>
                                      &gt;                              
                                      ifTrue: [value]<br>
                                      &gt;                              
                                      ifFalse: [self push: value]<br>
                                      &gt;<br>
                                      &gt; (find attached).  But these
                                      need implementing in the standard
                                      VM before they can be used in
                                      Pharo, Squeak, etc.<br>
                                      &gt;<br>
                                      &gt;<br>
                                      &gt; Thanks<br>
                                      &gt;<br>
                                      &gt; --<br>
                                      &gt; Mariano<br>
                                      &gt; <a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br>
                                      &gt;<br>
                                      &gt;<br>
                                      &gt;<br>
                                      &gt;<br>
                                      &gt; --<br>
                                      &gt; best,<br>
                                      &gt; Eliot<br>
                                      &gt;<br>
                                      <br>
                                      <br>
                                    </div>
                                  </div>
                                </blockquote>
                              </div>
                              <br>
                              <br clear="all">
                              <div><br>
                              </div>
                              -- <br>
                              best,
                              <div>Eliot</div>
                              <br>
                              <br>
                            </blockquote>
                          </div>
                          <br>
                          <br clear="all">
                          <br>
                          -- <br>
                          Mariano<br>
                          <a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br>
                          <br>
                          <br>
                        </blockquote>
                      </div>
                      <br>
                      <br clear="all">
                      <div><br>
                      </div>
                      -- <br>
                      best,
                      <div>Eliot</div>
                      <br>
                      <br>
                    </blockquote>
                  </div>
                </div>
              </div>
              <span><font color="#888888"><br>
                  <br clear="all">
                  <br>
                  -- <br>
                  Mariano<br>
                  <a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br>
                  <br>
                </font></span></blockquote>
          </div>
          <br>
          <br clear="all">
          <br>
          -- <br>
          Mariano<br>
          <a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br>
          <br>
          <br>
        </blockquote>
      </div>
      <br>
      <br clear="all">
      <div><br>
      </div>
      -- <br>
      best,
      <div>Eliot</div>
      <br>
    </blockquote>
  </div>

<br></blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div><br>