Raku/Perl6, Windows 7 and 10
Does Raku's NativeCall run "LocalFree( )" after it creates buffers? Or do I need to do it myself?
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-localfree
Many thanks, -T
EDIT: this at JJ's request.
https://learn.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regsetvalueexw
C++
LSTATUS RegSetValueExW(
HKEY hKey,
LPCWSTR lpValueName,
DWORD Reserved,
DWORD dwType,
const BYTE *lpData,
DWORD cbData
);
In assembly code:
lea eax,[##lMode]
call RegSetValueExA,HKEY_CURRENT_USER,offset
[##VAL_Type],0,REG_DWORD,eax,DWORD
"offset [##VAL_Type]" -> pointer to the keyvalue string buffer
"eax" -> pointer to the data (in the buffer "##lMode")
"*lpData" and "##lMode" are a buffers in an allocated space in memory. After their use, their memory needs to be given back to the system with "LocalFree".
So to rephrase my question, when NativeCall allocated space in memory for buffers, does it consequently give back the space after it is done with it, or does it just leave it there (memory leak)?
So, do I need to call "LocalFree()" or does NativeCall take care of it for me?
If you already understand that...
What NativeCall does is call C functions. It is not NativeCall's role to allocate or free memory.
LocalFree is a C function. The normal way to call a C function from Raku is via NativeCall.
...then you can safely ignore this answer -- and the question to which this is an answer, and Todd's answer.
If you are not confident about the above, then perhaps this answer will clear up any confusion and reduce the chances you're misled. What I write in the following is pendatic. But I feel it's appropriate to ensure clarity.
Does Raku's NativeCall run “LocalFree( )”?
Yes, if you tell it to.
NativeCall is the feature normally used to call C functions from Raku.1
Does Raku's NativeCall run "LocalFree( )" after it creates buffers?
NativeCall does not create buffers of its own accord. All NativeCall does is call C functions as instructed by users' code.
Let's say you use NativeCall to call a C function that creates a buffer. Does that mean NativeCall created the buffer? Or did you? (In a similar vein, if one uses NativeCall to call LocalFree after one has used NativeCall to call a C function that creates buffers, does that mean the answer to Todd's question is Yes? And if not, does that mean the answer is No?)
You can use NativeCall to call LocalFree because LocalFree is a C function, and calling C functions is precisely what NativeCall does when you use it to do something.2
Or do I need to do it myself?
Depending on your answer to the parenthesized questions a couple paragraphs above...
Given that NativeCall does not create buffers, you can't need to do anything related to NativeCall creating buffers.
In the alternative, if NativeCall creates buffers, then it's because you used it to manually call C functions that create buffers and you therefore also need to manually call C functions to free those buffers if you want them freed.
Footnotes
1 NativeCall is the Raku C FFI.
2 No matter what you "use" NativeCall for you would start with a use NativeCall statement. Then you would typically use it to call C functions. It's possible you might use it for access to nothing more than, say, some of the constants it defines.
NativeCall does not close any WinApi call buffers, so you need to do it yourself.
Related
I recently started a project where I require to do swizzling.
After going through many tutorials I got a question, What is the difference between Implementation and function pointer?
From memory, an IMP is a memory-address just like a function pointer, and can be invoked just like an ordinary C function. However it is guaranteed to use objective-C messaging convention, where:
The first argument is the object to operate on (self).
The second argument is the _cmd (SELECTOR) to be invoked. I believe this is so to support dynamic features, such as ObjC message forwarding where we could wrap the original implementation in a proxy, say to start a transaction or perform a security check, or, for a Cocoa specific example, add some property observation cruft, by magic, at run-time. While we already have the function signature, I could be helpful, in some cases, to know "how did I get here?" with the message signature.
Following arguments, if any, are according to the method contract.
Background as I understand it: Objective-C method invocations are basically a C function call with two hidden parameters (the receiver and the selector). The Objective-C runtime contains a function named objc_msgSend() that allows to invoke methods that way. Unfortunately, when a function returns a struct some special treatment may be needed. There are arcane (some might say insane) rules that govern whether the structure is returned like other values or whether it's actually returned by reference in a hidden first argument. For Objective-C there's another function called objc_msgSend_stret() that must be used in these cases.
The question: Given a method, can NSMethodSignature or something else tell me whether I have to use objc_msgSend() or objc_msgSend_stret()? So far we have found out that NSMethodSignature knows this, it prints it in its debug output, but there doesn't seem to be a public API.
In case you want to respond with "why on earth would you want to do that?!", please read the following before you do: https://github.com/erikdoe/ocmock/pull/41
Objective-C uses the same underlying ABI for C on a given architecture, because methods are just C functions with implicit self and _cmd arguments.
In other words, if you have a method:
- (SomeStructType)myMeth:(SomeArgType)arg;
then really this is a plain C function:
SomeStructType myMeth(id self, SEL _cmd, SomeArgType arg);
I'm pretty sure you already know that, but I'm merely mentioning it for other readers.
In other words, you want to ask libffi or any kind of similar library how SomeStructType would be returned for that architecture.
NSMethodSignature has a -methodReturnType that you can inspect to see if the return type is a struct. Is this what you're trying to do?
From http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html:
The rules for which struct types return in registers are always
arcane, sometimes insane. ppc32 is trivial: structs never return in
registers. i386 is straightforward: structs with sizeof exactly equal
to 1, 2, 4, or 8 return in registers. x86_64 is more complicated,
including rules for returning floating-point struct fields in FPU
registers, and ppc64's rules and exceptions will make your head spin.
The gory details are documented in the Mac OS X ABI Guide, though as
usual if the documentation and the compiler disagree then the
documentation is wrong.
If you're calling objc_msgSend directly and need to know whether to
use objc_msgSend_stret for a particular struct type, I recommend the
empirical approach: write a line of code that calls your method,
compile it on each architecture you care about, and look at the
assembly code to see which dispatch function the compiler uses.
I have heard that C doesn't have closure, and today I saw the use of closure in Objective-C. Is closure supported in Objective-C and not in C?
Update: thanks for all the answers. I found this guide on the web on blocks as well: http://pragmaticstudio.com/blog/2010/7/28/ios4-blocks-1
Apple added the ^ operator to add closure support. It is not tied to Objective-C however, and can be used in C and C++ as well, as long as you compile the project with Apple's brach of GCC or LLVM. This new feature is called blocks.
C has closures in the form of application-defined structures that contain both a function pointer and data pointer. The problem is just that many/most interfaces that take a callback pointer (like qsort) accept only the function pointer and not a corresponding data pointer, making it impossible to pass closures to them.
By the way, it's theoretically possible to add closure support at the library level without assistance from the compiler, i.e. create a library that would return a function pointer to a closure. However, the library code would be rather implementation/machine-dependent. It would need to allocate space for executable code and generate code to pass a fixed pointer value (saved as part of the closure object) along with other arguments to the function.
Background: CamelBones registers Perl classes with the Objective-C runtime.
To do this, every Perl method is registered with the same IMP
function; that function examines its self & _cmd arguments to find
which Perl method to call.
This has worked well enough for several years, for messages that were
dispatched with objc_msgSend. But now I want to add support for
returning floating-point and large struct types from Perl methods.
Floating-point isn't hard; I'll simply write another IMP that returns
double, to handle messages dispatched with objc_msgSend_fpret.
The question is what to do about objc_msgSend_stret. Writing a
separate IMP for every possible struct return type is impractical, for
two reasons: First, because even if I did so only for struct types
that are known at compile-time, that's an absurd number of functions.
And second, because we're talking about a framework that can be linked against any arbitrary Objective-C & Perl code, we don't know all the potential struct types when the framework is being compiled.
What I hope to do is write a single IMP that can handle any return
type that's dispatched via objc_msgSend_stret. Could I write it as
returning void, and taking a pointer argument to a return buffer, like
the old objc_msgSend_stret was declared? Even if that happened to
work for now, could I rely on it continuing to work in the future?
Thanks for any advice - I've been racking my brain on this one. :-)
Update:
Here's the advice I received from one of Apple's runtime engineers, on their objc-language mailing list:
You must write assembly code to handle
this case.
Your suggestion fails on some
architectures, where ABI for "function
returning void with a pointer to a
struct as the first argument" differs
from "function returning a struct".
(On i386, the struct address is popped
from the stack by the caller in one
case and by the callee in the other
case.) That's why the prototype for
objc_msgSend_stret was changed.
The assembly code would capture the
struct return address, smuggle it into
non-struct-return C function call
without disturbing the rest of the
parameters, and then do the right
ABI-specific cleanup on exit (ret $4
on i386). Alternatively, the assembly
code can capture all of the
parameters. The forwarding machinery
does something like this. That code
might be in open-source CoreFoundation
if you want to see what the techniques
look like.
I'll leave this question open, in case someone brainstorms a better idea, but with this coming directly from Apple's own "runtime wrangler," I figure it's probably as authoritative an answer as I'm likely to get. Time to dust off the x86 reference manuals and knock the rust off my assembler-fu, I guess...
It seems that the Apple engineer is right: the only to way to go is assembly code. Here are some usefull pointers to getting started:
From the Objective-C runtime code: The i386 and x86_64 hand-crafted messenger assmbly stubs for the various messaging methods.
An SO answer that provides an overview of the dispatching.
A in-depth review of the dispatching mecanism with a line-by-line analysis of the assembly code
Hope it helps.
I'm trying to understand the concept of blocks. What I've read so far seems to be conceptually similar to anonymous functions in JavaScript. Is this correct?
Yes, for the largest part. Blocks are kind-of C functions treated kind-of like objects which can capture variables from the surrounding scope. Anonymous functions are equivalent to blocks, but certainly not identical due to the rather complicated behind-the-scene machinery of blocks.
For example, if you plan to use a block after/outside the function/method which defines the block isn't active anymore—it's the case if you set the block as a property somewhere or use in GCD (a multi-core operation queueing library), you need to copy it with Block_copy() (or [aBlock copy]). I won't go into the details, but this is certainly not something you do with JS (anonymous) functions. It has to do with the fact that block literals are allocated on the stack (and not somewhere in the code) and you need to copy it to the heap if you want it to persist.
It can get quite complicated (but rather beautiful in its design), but for most use cases it's rather easy and you can treat it like anonymous JS functions. ;-)
Yes. Blocks in Objective-C are closures.