> On 15.11.2014, at 22:28, Igor Stasenko <[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:

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"
        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