<div dir="ltr">Hi Alistair,  Hi Clément,<div><br></div><div>  here are the code and an example of the new operating system error primitive fail facility.</div><div><br></div><div>Here's the extract from recreateSpecialObjectsArray that adds the prototype to the table:</div><div><br></div><div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>newArray at: 52 put: #(nil "nil => generic error" #'bad receiver'</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                 </span>#'bad argument' #'bad index'</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                   </span>#'bad number of arguments'</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                     </span>#'inappropriate operation'  #'unsupported operation'</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                  </span>#'no modification' #'insufficient object memory'</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                       </span>#'insufficient C memory' #'not found' #'bad method'</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                    </span>#'internal error in named primitive machinery'</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                 </span>#'object may move' #'resource limit exceeded'</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                  </span>#'object is pinned' #'primitive write beyond end of object'</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                    </span>#'object moved' #'object not pinned' #'callback error'),</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                                       </span>{PrimitiveOSError new errorName: #'operating system error'; yourself}.</div></div><div><br></div><div>Here's the class definition (also attached) for PrimitiveOSError:</div><div><br></div><div><div>!Object methodsFor: '*System-Support-error handling' stamp: 'eem 12/12/2017 09:16'!</div><div>isPrimitiveOSError</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>^false! !</div></div><div><br></div><div><div>Object subclass: #PrimitiveOSError</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>instanceVariableNames: 'errorName errorCode'</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>classVariableNames: ''</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>poolDictionaries: ''</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>category: 'System-Support'!</div><div>!PrimitiveOSError commentStamp: 'eem 12/7/2017 19:31' prior: 0!</div><div>A PrimitiveOSError is used to answer a primitive failure code that has an associated operating system/library error.</div><div><br></div><div>Instance Variables</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>errorName:<span class="gmail-Apple-tab-span" style="white-space:pre">            </span><Symbol></div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>errorValue:<span class="gmail-Apple-tab-span" style="white-space:pre">           </span><Integer></div><div><br></div><div>errorName</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>- typically #'operating system error'</div><div><br></div><div>errorValue</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>- the value of the error, a signed 64-bit value, a representation imposed by the VM; specific clients must map this error value into an unsigned value as appropriate if required!</div><div><br></div><div><br></div><div>!PrimitiveOSError methodsFor: 'accessing' stamp: 'eem 12/7/2017 19:32'!</div><div>errorCode</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>^errorCode! !</div><div><br></div><div>!PrimitiveOSError methodsFor: 'accessing' stamp: 'eem 12/7/2017 19:32'!</div><div>errorCode: anObject</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>errorCode := anObject! !</div><div><br></div><div>!PrimitiveOSError methodsFor: 'accessing' stamp: 'eem 12/7/2017 18:16'!</div><div>errorName</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>^errorName! !</div><div><br></div><div>!PrimitiveOSError methodsFor: 'accessing' stamp: 'eem 12/7/2017 18:16'!</div><div>errorName: anObject</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>errorName := anObject! !</div><div><br></div><div><br></div><div>!PrimitiveOSError methodsFor: 'testing' stamp: 'eem 12/12/2017 09:15'!</div><div>isPrimitiveOSError</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>^true! !</div></div><div><br></div><div><br></div><div>The signature of primitiveFailForOSError: is:</div><div>sqInt primitiveFailForOSError(sqLong)<br></div><div><br></div><div>So in your Slang code use</div><div><br></div><div>    interpreterProxy primitiveFailForOSError: osErrorCode</div><div><br></div><div>or in your platform C code use</div><div><br></div><div><br></div><div>    interpreterProxy->primitiveFailForOSError(osErrorCode)</div><div><br></div><div>In your Smalltalk code write things like</div><div><br></div><div>     <primitive: 'foo' module: '' error: ec></div><div>     ec isOSErrorCode ifTrue:</div><div>         [self processError: ec errorCode]</div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Dec 22, 2017 at 9:11 AM, Alistair Grant <span dir="ltr"><<a href="mailto:akgrant0710@gmail.com" target="_blank">akgrant0710@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Hi Eliot,<br>
<span class=""><br>
On 22 December 2017 at 18:00, Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>> wrote:<br>
><br>
> Hi Alistair,<br>
><br>
><br>
>> On Dec 22, 2017, at 8:33 AM, Alistair Grant <<a href="mailto:akgrant0710@gmail.com">akgrant0710@gmail.com</a>> wrote:<br>
>><br>
>><br>
>> Hi Eliot,<br>
>><br>
>>> On 22 December 2017 at 17:09, Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>> wrote:<br>
>>><br>
>>> Hi Clément, Hi Alistair,<br>
>>><br>
>>>    FileAttrbutesPlugin is not yet ready for use.  The main problem is that it neither fails properly nor communicates error codes back properly.  Basically FileAttrbutesPlugin confuses failing because it gets invalid arguments with reporting error codes due to operating system level errors.  For the FileAttrbutesPlugin's primitives to work in Spur they must fail in the traditional way when given invalid arguments.  This is because the Spur VM will check when a primitive fails if there are any forwarders in the primitive's parameters, and if so, follow (fix up) the forwarders and retry the primitive.<br>
>><br>
>> Is this the feedback you gave me on 2 September, or something different?<br>
><br>
> One and the same.<br>
><br>
>><br>
>> Back then, you wrote:<br>
>>> The change that is required to error handling:<br>
>>> If a primitive fails due to argument marshaling it must use the primitiveFailedWith: mechanism and report the error using one of the error codes.  This is because Spur uses lazy forwarding to implement become:, pin, et al.  The lazy forwarding mechanism follows forwarders in the VM when they are encountered.  For sends this is trivial; any send to a forwarder fails and so the failure side of message lookup follows forwarders and retries the send.  Similarly for the arguments of primitives, when a primitive fails the VM searches for forwarders in the receiver and arguments to a specific pre-computed depth, following any forwarders it finds.  If any forwarders are found the primitive is retried after following all the forwarders found.<br>
>><br>
>><br>
>> My understanding is that this has already been done.  If I've<br>
>> misunderstood, my apologies.<br>
><br>
> I should apologize.  One side effect of answering email in my phone is that I don't look things up as often as I should (blush).  But answering email in bed in the early morning while the kids are still asleep is irresistible.  Anyway, good.  I shall try and review the code this weekend or early next week.  Feel free to nag me.  Feel free to use harsh language ;-)<br>
<br>
</span>No problem.    The email subject where I run over the mods is "Re:<br>
20294 Add FileAttributesPlugin to the linux 32 bit VM", sent 6 Sep<br>
2017.<br>
<span class=""><br>
<br>
<br>
>>> Next, communication no os errors back through the primitives results is acceptable, but a better way would be to use the new #'operating system error' primitive failure code mechanism.  Here, provided a suitable two slot prototype is installed in the primitiveErrorTable (see Squeak trunk) then a plugin can do<br>
>>>        interpreterProxy primitiveFailForOSError(<wbr>signedSixtyFourBitErrorCode)<br>
>>> and the VM will clone the error object whose first slot should be #'operating system error' and whose second slot will be the code.<br>
>>><br>
>>> This gives us a clean way of communicating errors back to a primitive's method body in the traditional way.<br>
>><br>
>> At the moment I'm passing back an error number generated by the<br>
>> plugin, not an OS error number returned by a system call, but I assume<br>
>> that the VM doesn't really care.<br>
>><br>
>> Do you have an example where this is being used in a plugin?<br>
><br>
> Not yet.  This is new.  Monty wanted if god the FilePlugin and we really needed it.  I'll prepare a proper email with examples of usage and a class def for the error prototype soon.  Again, harsh language may be effective ;-)<br>
<br>
</span>OK.  I'll have a look, but the examples will be good.<br>
<br>
Thanks,<br>
Alistair<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
>> Cheers,<br>
>> Alistair<br>
><br>
> Cheers!<br>
><br>
>><br>
>><br>
>>> I do apologize if I hadn't made this clear earlier.  But AFAIA there is significant work to do before the plugin is ready for integration.<br>
>>><br>
>>> _,,,^..^,,,_ (phone)<br>
>>><br>
>>>> On Dec 22, 2017, at 2:48 AM, Alistair Grant <<a href="mailto:akgrant0710@gmail.com">akgrant0710@gmail.com</a>> wrote:<br>
>>>><br>
>>>><br>
>>>> Hi Clément,<br>
>>>><br>
>>>>> On 22 December 2017 at 11:29, Clément Bera <<a href="mailto:bera.clement@gmail.com">bera.clement@gmail.com</a>> wrote:<br>
>>>>><br>
>>>>> Hi,<br>
>>>>><br>
>>>>> What is the status of the FilesAttributesPlugin ?<br>
>>>><br>
>>>> I'm hoping that it will be integrated soon.<br>
>>>><br>
>>>><br>
>>>>> I would like to make it available by default on pharo VMs.<br>
>>>><br>
>>>> Yes, please. :-)<br>
>>>><br>
>>>><br>
>>>>> Questions:<br>
>>>>><br>
>>>>> 1) Is it already merged with another plugin ?<br>
>>>><br>
>>>> I'm not sure that I understand the question.  FileAttributesPlugin<br>
>>>> works along side FilePlugin (which is obviously already part of the<br>
>>>> pharo VM).<br>
>>>><br>
>>>><br>
>>>>> 2) If not, for integration, should I move the FilesAttributesPlugin from its external smalltalkhub repository to VMMaker-Plugins package ?<br>
>>>><br>
>>>> That's my guess, but someone knowledgable needs to answer this.<br>
>>>><br>
>>>><br>
>>>>> 3) What is the right way to generate a plugin ? I use this:<br>
>>>>><br>
>>>>> (VMMaker<br>
>>>>> makerFor: StackInterpreter<br>
>>>>> and: nil<br>
>>>>> with: #()<br>
>>>>> to: (FileDirectory default pathFromURI: '../src')<br>
>>>>> platformDir: (FileDirectory default pathFromURI: '../platforms')<br>
>>>>> including: #(FileAttributesPlugin)<br>
>>>>> ) generateExternalPlugin: FileAttributesPlugin<br>
>>>>><br>
>>>>> Is that correct ?<br>
>>>>> It seems it generates only the C file but no header file.<br>
>>>><br>
>>>> There isn't a FileAttributesPlugin.h.  It does need the platform support file:<br>
>>>><br>
>>>> platforms/win32/plugins/<wbr>FileAttributesPlugin/Makefile.<wbr>plugin<br>
>>>><br>
>>>> which is already part of opensmalltalk-vm.<br>
>>>><br>
>>>> I've always used VMMakerTool to make the plugin, but if it's<br>
>>>> generating the .c file it's probably correct.<br>
>>>><br>
>>>><br>
>>>> My plan was that once the plugin was added to VMMaker-Plugins that I<br>
>>>> would test it again on linux and windows, and then ask for the<br>
>>>> appropriate <a href="http://plugins.int" rel="noreferrer" target="_blank">plugins.int</a> to be updated.<br>
>>>><br>
>>>><br>
>>>> Thanks!<br>
>>>> Alistair<br>
>>>><br>
>>>><br>
>>>>> Thanks,<br>
>>>>><br>
>>>>> --<br>
>>>>> Clément Béra<br>
>>>>> <a href="https://clementbera.wordpress.com/" rel="noreferrer" target="_blank">https://clementbera.wordpress.<wbr>com/</a><br>
>>>>> Bâtiment B 40, avenue Halley 59650 Villeneuve d'Ascq<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div>