> On 17.11.2014, at 00:32, Nicolai Hess <[email protected]> wrote:
> 
> 
> 
> 2014-11-16 19:11 GMT+01:00 Max Leske <[email protected] 
> <mailto:[email protected]>>:
> 
>> On 15.11.2014, at 22:28, Igor Stasenko <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> 
>> 
>> On 15 November 2014 15:53, Max Leske <[email protected] 
>> <mailto:[email protected]>> wrote:
>> Once again I’m struggling with NativeBoost. I’m trying to use 
>> optCoerceNilToNull with this function:
>> 
>> ^self call: #(LGitReturnCodeEnum git_commit_create(
>>      LGitId * theCommitId, 
>>      LGitRepository repo,
>>      String update_ref, 
>>      LGitSignature * theAuthor,
>>      LGitSignature * theCommitter,
>>      String message_encoding,
>>      String theMessage,
>>      LGitTree theTree,
>>      int parent_count, 
>>      LGitCommit * parentsPointer)) options: #( optCoerceNilToNull )
>> 
>> The last argument can be NULL, per documentation, (no parents).
>> LGitCommit is a subclass of NBExternalObject and apparently 
>> NBExternalObjctType>>pushAsPointer: does *not* use the optCoerceNilToNull 
>> option (the super implementation in NBExternalType>>pushAsPointer: however 
>> does). The upshot of course is that the call fails with “an instance of 
>> LGitCommit expected”.
>> 
>> My questions:
>> - The documentation says:
>> 
>> "#optCoerceNilToNull"
>> "passing nil as a pointer-type argument, converts it to C NULL “
>>      
>>      but apparently this doesn’t apply to every pointer type. Should the 
>> documentation be updated?
>> - Why does NBExternlObjectType not use optCoerceNilToNull? I don’t want to 
>> use tricks to pass null if I don’t have to.
>> 
>> perhaps because it is not there? :)
>> So, lets add it.
> 
> Yay! :) I have zero assembly skills… I’ve tried the following but then get an 
> “undefined label done18” error:
> 
> 
> if coerceNilToNull is set *and* the argument is indeed nil, you want to jump 
> over all other operations on this argument (see below).
> (and if coerceNilToNull is set, and the argument is not nil, you should still 
> verify the class of the oop, this is missing
> in your code!)

That’s true, thanks.

> 
>  
> 
> NBExternalObject>>pushAsPointer: gen 
>       "push a pointer to handle value"
>       | asm proxy oop notNil done |
>       
>       proxy := gen proxy.
>       asm := gen asm.
> 
> <<<<<<<<<<<<<< new
> 
>       done := asm uniqueLabelName: 'done’.
> 
> >>>>>>>>>>>>>>> new
> 
>       oop := gen reserveTemp.
>       loader emitLoad: gen to: oop.
> 
> <<<<<<<<<<<<<< new
> 
>       "handle nils, if we care"
>       gen optCoerceNilToNull 
>               ifTrue: [
>                       notNil := asm uniqueLabelName: 'notNil'.
>                       proxy nilObject.
>                       asm cmp: asm EAX with: oop;
>                       jne: notNil;
>                       xor: asm EAX with: asm EAX;
>                       jmp: done;
>                       label: notNil ]
>               ifFalse: [
>                       "we can skip class verification, if loader loads 
> receiver, since nothing to fear there"
>                       loader isReceiver ifFalse: [
>                               self verifyClassOf: oop is: objectClass 
> generator: gen.
>                       ] ].
> 
> >>>>>>>>>>>>>>> new
>       
>       proxy fetchPointer: (self handleIvarIndex) ofObject: oop. "handle ivar"
>       proxy varBytesFirstFieldOf: asm EAX. "handle value ptr"
> 
>            "done label here:"
>            asm label: done.
>  
>       asm push: asm EAX.
>       
>       gen releaseTemps: 1.
> 
> 
>> 
>> - Related: there are instances where even non-pointer arguments are allowed 
>> to be NULL. Why does optCoerceNilToNull only work for pointer types?
>> 
>>  
>> like what? Suppose the argument type is a structure, e.g
>> "struct foo bar", that is non-pointer type. What in this case the NULL value 
>> for the structure?
> 
> Ok, I think I understand. Are you saying that, since NULL is a macro, you 
> have no way of telling during runtime how NULL is defined? For a pointer it 
> is simply 0 or (void *) 0, but for a non pointer it depends on the context. 
> Is that about right?
> 
>>  
>> Igor! Help! :)
>> 
>> Cheers,
>> Max
>> 
>> 
>> 
>> 
>> -- 
>> Best regards,
>> Igor Stasenko.

Reply via email to