<br><br><div class="gmail_quote">On Wed, Jan 25, 2012 at 6:40 PM, Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@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><br><br><div class="gmail_quote">On Wed, Jan 25, 2012 at 3:13 AM, 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><br><br><div class="gmail_quote">On Wed, Jan 25, 2012 at 2:43 AM, Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@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><br><br><div class="gmail_quote">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><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.  Some criticism: Since the method is new the flushCache should be unneeded. </div></div></blockquote><div><br>True. <br>




 </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> I think either copying a template method (e.g. stored in a class variable) and  changing its argument count, </div>




</div></blockquote><div><br>Let&#39;s see if I understand. I have attaached a new version that supposes to do this. I tested and seems to work. <br>Is it better?  If you agree, I can put a nice comment and commit.<br> </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>or creating a method directly (look at the generate: method) would be much faster.  Speed can be important in the debugger.</div>




</div></blockquote><div><br>I am not sure if I understood. Maybe you mean something along the lines of:<br><br>MethodNode new<br>selector: #tryNamedPrimitive:arg2: <br>arguments: (OrderedCollection with: (TempVariableNode new name: &#39;arg1&#39; index: 0 type: 2 scope: 0; nowHasDef; nowHasRef; beMethodArg; yourself) with: (TempVariableNode new name: &#39;arg1&#39; index: 0 type: 2 scope: 0; nowHasDef; nowHasRef; beMethodArg; yourself)) <br>


precedence: 3 <br>temporaries: #() <br>block: BlockNode new <br>encoder: (EncoderForV3PlusClosures new <br>instVarNamed: &#39;class&#39; put: UndefinedObject; yourself)<br>primitive: 117 <br><br>and then send #generate:<br>

</div></div></blockquote><div><br></div><div>No, I meant create the method directly as does the body of generate:using:.  e.g. if the method looks like</div><div> </div><div>tryNamedPrimitiveWith: a with: b ... with: n</div>

<div>     &lt;primitive: &#39;function to be filled in later&#39; module: &#39;module to be filled in later&#39;&gt;</div><div>    ^ContextPart primitiveFailToken</div><div><br></div><div>then it looks something like</div>

<div><br></div><div>tempMethodForNamedPrimitive: functionName inModule: moduleName numArgs: nArgs</div><div><br></div><div><span style="white-space:pre-wrap">        </span>literals := { { moduleName. functionName. 0. 0. }.</div>

<div><span style="white-space:pre-wrap">        </span><span style="white-space:pre-wrap">        </span><span style="white-space:pre-wrap">        </span> Smalltalk bindingOf: #ContextPart.</div>
<div><span style="white-space:pre-wrap">        </span><span style="white-space:pre-wrap">        </span><span style="white-space:pre-wrap">        </span> #primitiveFailToken.</div><div><span style="white-space:pre-wrap">        </span><span style="white-space:pre-wrap">        </span><span style="white-space:pre-wrap">        </span> self additionalMethodStateForNamedPrimitiveWithNArgs: nArgs.</div>

<div><span style="white-space:pre-wrap">        </span><span style="white-space:pre-wrap">        </span><span style="white-space:pre-wrap">        </span> Smalltalk bindingOf: #Object }.</div>
<div><span style="white-space:pre-wrap">        </span>bytes := #( 17 &quot;push lit var 1 (ContextPart)&quot; 210 &quot;send lit 2 with 0 args (primitiveFailToken)&quot; 124 &quot;return top&quot; ).</div><div>
<div><span style="white-space:pre-wrap">        </span>method := aCompiledMethodClass</div><div><span style="white-space:pre-wrap">                                </span>newBytes: bytes size</div><div><span style="white-space:pre-wrap">                                </span>trailerBytes: CompiledMethodTrailer empty </div>

<div><span style="white-space:pre-wrap">                                </span>nArgs: nargs</div><div><span style="white-space:pre-wrap">                                </span>nTemps: nargs</div><div><span style="white-space:pre-wrap">                                </span>nStack: 0</div>
<div><span style="white-space:pre-wrap">                                </span>nLits: literals size</div><div><span style="white-space:pre-wrap">                                </span>primitive: 117.</div><div><span style="white-space:pre-wrap">        </span>1 to: literals size do: [:i | method literalAt: i put: (literals at: i)].</div>

</div><div> <span style="white-space:pre-wrap">        </span>0 to: bytes size - 1 do: [:i| method byteAt: method initialPC + i put: (bytes at: i + 1)].</div><div> <span style="white-space:pre-wrap">        </span>^method</div>
<div><br></div><div>But since the bytecodes don&#39;t change with the argument count it is even faster to create the above, copy it and smash the selector and argument count into the copy.  MethodWrappers4.2 has an example of this kind of thing.</div>

<div><br></div></div></blockquote><div><br>Ok. I will try to give it a try to this approach as well. <br>But what happened with the version I attached in the previous email that uses a template method and just change the arguments number?<br>
It looks quite fast since the only thing I have to do is to set the arguments number (which are bitAnd:, bitShift: and bitOr: only), and quite easy to understand at the same time. <br><br> </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><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>but I get lost to get this working...the previous solution seems easier.<br>

</div></div></blockquote><div><br></div><div>Do you want to build Trabants or BMWs?  </div></div></blockquote><div><br>I didn&#39;t understand. Which solution which be each car?<br> </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>Documentation helps.</div><div> </div></div></blockquote><div><br>I didn&#39;t understand either. If you refer to the fact I didn&#39;t put comments in the .cs I attached, I explicitly said in my previous email &quot;If you agree, I can put a nice comment and commit.&quot;. It already took me the whole morning (yes, I am completly noob here) to do the version of changing the argument count, so I was waiting the confirmation in the solution before documenting it and make it better. <br>
 <br> </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"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="gmail_quote"><div><br>Thanks!<br><br><br> </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"><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></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>
<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><br><br clear="all"><br>-- <br>Mariano<br><a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br><br>