<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Eliot,&nbsp;<div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">On 03 Nov 2015, at 03:05, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com" class="">eliot.miranda@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi Esteban,<div class=""><br class=""></div><div class="">&nbsp; &nbsp; I *think* I understand the point of&nbsp;</div><div class=""><br style="font-size: 14px;" class=""><span style="font-size: 14px;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "don't you dare to read from object memory!!"</span><br style="font-size: 14px;" class=""><span style="font-size: 14px;" class="">+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(addr == 0 "or:[interpreterProxy isInMemory: addr]")</span><br style="font-size: 14px;" class=""><span style="font-size: 14px;" class="">-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(addr == 0 or:[interpreterProxy isInMemory: addr])</span><br class=""></div><div class=""><span style="font-size: 14px;" class=""><br class=""></span></div><div class=""><font class="">there are&nbsp;circumstances in which we *do* want to pass in an address in object memory.&nbsp; But this seems a bit drastic.&nbsp; Could you give a specific example?&nbsp; Also, shouldn't we be doing something like checking that the address is associated with an object that is pinned?</font></div></div></div></blockquote><div><br class=""></div><div><div class="">Well… &nbsp;for same same behaviour (in primitiveFFIDoubleAt,&nbsp;primitiveFFIDoubleAtPut,&nbsp;primitiveFFIFloatAt,&nbsp;primitiveFFIFloatAtPut,&nbsp;primitiveFFIIntegerAt and&nbsp;primitiveFFIIntegerAtPut) in the corresponding primitives of IA32ABIPlugin this check does not exist. I just adapted the behaviour already present in the other side. It’s your code, not mine ;)</div><div class="">In any case, the pinned check seems reasonable :)</div><div class=""><br class=""></div><div class="">I’m taking a plane to Argentina now… give me some days and I will propose a proper change (would be cool to start using pinned objects also, heh).</div><div class=""><br class=""></div><div class="">cheers,&nbsp;</div><div class="">Esteban</div><div class=""><br class=""></div></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><font class=""><br class=""></font></div><div class=""><font class="">So this change makes me nervous and I want you to calm my nerves ;-)</font></div><div class=""><font class=""><br class=""></font></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Fri, Oct 30, 2015 at 9:39 AM,  <span dir="ltr" class="">&lt;<a href="mailto:commits@source.squeak.org" target="_blank" class="">commits@source.squeak.org</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br class="">
Esteban Lorenzano uploaded a new version of VMMaker to project VM Maker:<br class="">
<a href="http://source.squeak.org/VMMaker/VMMaker.oscog-EstebanLorenzano.1503.mcz" rel="noreferrer" target="_blank" class="">http://source.squeak.org/VMMaker/VMMaker.oscog-EstebanLorenzano.1503.mcz</a><br class="">
<br class="">
==================== Summary ====================<br class="">
<br class="">
Name: VMMaker.oscog-EstebanLorenzano.1503<br class="">
Author: EstebanLorenzano<br class="">
Time: 30 October 2015, 2:37:07.998518 pm<br class="">
UUID: 2cc25296-b733-4968-bd6b-8f3db5277693<br class="">
Ancestors: VMMaker.oscog-eem.1502<br class="">
<br class="">
general:<br class="">
- applying correct cast so compiler does not fails.<br class="">
<br class="">
ThreadedFFIPlugin:<br class="">
- ExternalAddress now are taken correctly (nor as ByteArray or Alien, because they are&nbsp; different beasts).<br class="">
&nbsp;- allow pushing of pointers to any type (into a ByteArray, an ExternalAddress or an Alien), to allow passing parameters style int*, float*, etc.<br class="">
- allow reading in memory to allow read chunks of ByteArray<br class="">
<br class="">
=============== Diff against VMMaker.oscog-eem.1502 ===============<br class="">
<br class="">
Item was changed:<br class="">
&nbsp; ----- Method: Cogit&gt;&gt;addressIsInInstructions: (in category 'testing') -----<br class="">
&nbsp; addressIsInInstructions: address<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &lt;var: #address type: #'AbstractInstruction *'&gt;<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp;^self cCode: '!!((((unsigned)address) &amp; BytesPerWord-1)) \<br class="">
-&nbsp; &nbsp; &nbsp; &nbsp;^self cCode: '!!((unsigned)((address) &amp; BytesPerWord-1)) \<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; (address) &gt;= &amp;abstractOpcodes[0] \<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;&amp; (address) &lt; &amp;abstractOpcodes[opcodeIndex]'<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inSmalltalk: [(abstractOpcodes object identityIndexOf: address) between: 1 and: opcodeIndex]!<br class="">
<br class="">
Item was changed:<br class="">
&nbsp; ----- Method: ThreadedFFIPlugin&gt;&gt;ffiAddressOf:startingAt:size: (in category 'primitive support') -----<br class="">
&nbsp; ffiAddressOf: rcvr startingAt: byteOffset size: byteSize<br class="">
&nbsp; "return an int of the address of the byteSize slot (byte, short, int, whatever) at byteOffset in rcvr. Nominally intended for use with ExternalAddress objects, this code will work (for obscure historical reasons) with plain Byte or Word Arrays as well. "<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; | rcvrClass rcvrSize addr |<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; (interpreterProxy isBytes: rcvr) ifFalse:[^interpreterProxy primitiveFail].<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; (byteOffset &gt; 0) ifFalse:[^interpreterProxy primitiveFail].<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; rcvrClass := interpreterProxy fetchClassOf: rcvr.<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; rcvrSize := interpreterProxy byteSizeOf: rcvr.<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; rcvrClass = interpreterProxy classExternalAddress ifTrue:[<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (rcvrSize = 4) ifFalse:[^interpreterProxy primitiveFail].<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addr := interpreterProxy fetchPointer: 0 ofObject: rcvr.<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "don't you dare to read from object memory!!"<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(addr == 0 "or:[interpreterProxy isInMemory: addr]")<br class="">
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(addr == 0 or:[interpreterProxy isInMemory: addr])<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ifTrue:[^interpreterProxy primitiveFail].<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; ] ifFalse:[<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (byteOffset+byteSize-1 &lt;= rcvrSize)<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ifFalse:[^interpreterProxy primitiveFail].<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addr := self cCoerce: (interpreterProxy firstIndexableField: rcvr) to: 'int'.<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; ].<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; addr := addr + byteOffset - 1.<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; ^addr!<br class="">
<br class="">
Item was changed:<br class="">
&nbsp; ----- Method: ThreadedFFIPlugin&gt;&gt;ffiAtomicArgByReference:Class:in: (in category 'callout support') -----<br class="">
&nbsp; ffiAtomicArgByReference: oop Class: oopClass in: calloutState<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &lt;var: #calloutState type: #'CalloutState *'&gt;<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; "Support for generic callout. Prepare a pointer reference to an atomic type for callout.<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; Note:<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for type 'void*' we allow ByteArray/String/Symbol, wordVariableSubclass, Alien or ExternalAddress.<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for other types we allow ByteArray, wordVariableSubclass, Alien or ExternalAddress."<br class="">
-&nbsp; &nbsp; &nbsp; &nbsp; Note: for type 'void*' we allow ByteArray/String/Symbol, wordVariableSubclass or Alien."<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; | atomicType isString isAlien |<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &lt;inline: true&gt;<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; atomicType := self atomicTypeOf: calloutState ffiArgHeader.<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; (atomicType = FFITypeBool) ifTrue: "No bools on input"<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [^FFIErrorCoercionFailed].<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; isAlien := (isString := interpreterProxy<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; includesBehavior: oopClass<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ThatOf: interpreterProxy classString)<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ifTrue: [false]<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ifFalse:<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [interpreterProxy<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; includesBehavior: oopClass<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ThatOf: interpreterProxy classAlien].<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; ((atomicType &gt;&gt; 1) = (FFITypeSignedChar &gt;&gt; 1)) ifTrue:"string value (char*)"<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "note: the only types allowed for passing into char* types are<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ByteArray, String, Symbol, Alien and *no* other byte indexed objects<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (e.g., CompiledMethod, LargeInteger). We only check for strings<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; here and fall through to the byte* check otherwise."<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [isString ifTrue:"String/Symbol"<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Strings must be allocated by the ffi support code"<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [^self ffiPushString: (interpreterProxy firstIndexableField: oop)<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OfLength: (interpreterProxy byteSizeOf: oop)<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in: calloutState].<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Fall through to byte* test"<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; atomicType := FFITypeUnsignedByte].<br class="">
<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; self cppIf: COGMTVM ifTrue:<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; ["Since all the following pass the address of the first indexable field we need to fail<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;the call if it is threaded and the object is young, since it may move during the call."<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; ((calloutState callFlags anyMask: FFICallFlagThreaded)<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; and: [(isAlien not or: [self isDirectAlien: oop])<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; and: [interpreterProxy isYoung: oop]]) ifTrue:<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [^PrimErrObjectMayMove negated]].<br class="">
<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; (atomicType = FFITypeVoid or:[(atomicType &gt;&gt; 1) = (FFITypeSignedByte &gt;&gt; 1)]) ifTrue:<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "byte* -- see comment on string above"<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[(isString or: [oopClass = interpreterProxy classByteArray]) ifTrue: "String/Symbol/ByteArray"<br class="">
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[(isString<br class="">
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;or: [oopClass = interpreterProxy classByteArray]) ifTrue:"String/Symbol/ByteArray"<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [^self ffiPushPointer: (interpreterProxy firstIndexableField: oop) in: calloutState].<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(oopClass = interpreterProxy classExternalAddress) ifTrue:<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[^self ffiPushPointer: (self longAt: oop + interpreterProxy baseHeaderSize) in: calloutState].<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;isAlien ifTrue:<br class="">
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(isAlien or: [oopClass = interpreterProxy classExternalAddress]) ifTrue:<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [^self ffiPushPointer: (self pointerForOop: (self startOfData: oop)) in: calloutState].<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; atomicType = FFITypeVoid ifFalse:<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [^FFIErrorCoercionFailed]].<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "note: type void falls through"<br class="">
<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp;"I can push pointers to any type (take for instance calls who receive int* output arguments, etc.)<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; but I need to store them into a ByteArray, ExternalAddress or Alien"<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp;(atomicType &lt;= FFITypeDoubleFloat) ifTrue:<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[((interpreterProxy isWords: oop) or: [oopClass = interpreterProxy classByteArray]) ifTrue:<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[^self ffiPushPointer: (interpreterProxy firstIndexableField: oop) in: calloutState].<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(oopClass = interpreterProxy classExternalAddress) ifTrue:<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[^self ffiPushPointer: (self longAt: oop + interpreterProxy baseHeaderSize) in: calloutState].<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;isAlien ifTrue:<br class="">
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[^self ffiPushPointer: (self pointerForOop: (self startOfData: oop)) in: calloutState]].<br class="">
-&nbsp; &nbsp; &nbsp; &nbsp;(atomicType &lt;= FFITypeSignedInt "void/short/int"<br class="">
-&nbsp; &nbsp; &nbsp; &nbsp;or:[atomicType = FFITypeSingleFloat]) ifTrue:<br class="">
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;["require a word subclass to work"<br class="">
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(interpreterProxy isWords: oop) ifTrue:<br class="">
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[^self ffiPushPointer: (interpreterProxy firstIndexableField: oop) in: calloutState]].<br class="">
<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; ^FFIErrorCoercionFailed!<br class="">
<br class="">
</blockquote></div><br class=""><br clear="all" class=""><div class=""><br class=""></div>-- <br class=""><div class="gmail_signature"><div dir="ltr" class=""><div class=""><span style="font-size:small;border-collapse:separate" class=""><div class="">_,,,^..^,,,_<br class=""></div><div class="">best,&nbsp;Eliot</div></span></div></div></div>
</div>
</div></blockquote></div><br class=""></div></body></html>