title: How to implement an IMP function that returns a large struct type determined at run-time?
body: <p>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 <code>self</code> &amp; <code>_cmd</code> arguments to find
  which Perl method to call.</p>
  
  <p>This has worked well enough for several years, for messages that were
  dispatched with <code>objc_msgSend</code>. 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 <code>objc_msgSend_fpret</code>.</p>
  
  <p>The question is what to do about <code>objc_msgSend_stret</code>. Writing a
  separate <code>IMP</code> 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 &amp; Perl code, we <em>don't</em> know all the potential struct types when the framework is being compiled.</p>
  
  <p>What I hope to do is write a single <code>IMP</code> that can handle any return
  type that's dispatched via <code>objc_msgSend_stret</code>. Could I write it as
  returning <code>void</code>, and taking a pointer argument to a return buffer, like
  the old <code>objc_msgSend_stret</code> was declared? Even if that happened to
  work for now, could I rely on it continuing to work in the future?</p>
  
  <p>Thanks for any advice - I've been racking my brain on this one. :-)</p>
  
  <p><strong>Update:</strong></p>
  
  <p>Here's the advice I received from one of Apple's runtime engineers, on their objc-language mailing list:</p>
  
  <blockquote>
    <p>You must write assembly code to handle
    this case.</p>
    
    <p>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
    <code>objc_msgSend_stret</code> was changed.</p>
    
    <p>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 (<code>ret $4</code>
    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.</p>
  </blockquote>
  
  <p>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...</p>