Custom calling conventions

Michel Fortin michel.fortin at michelf.com
Tue Feb 21 11:30:31 PST 2012


On 2012-02-21 17:03:56 +0000, Manu <turkeyman at gmail.com> said:

> What was the primary cause of the bloat? I can't imagine my proposal
> causing any more bloat than the explicit jni call (or equivalent) woudl
> have otherwise.

I had one D class for every corresponding Objective-C class, each 
method wrapped in both direction, each wrapper doing automatic mapping 
of D and Objective-C wrapper objects and translating exceptions. I 
could actually override a method in a derived class of the D wrapper 
and it'd effectively override the method on the Objective-C side. But 
with all those D classes having virtual tables referring to all these 
wrapper functions, even if you use only 1% of all the bindings nothing 
can be stripped of the final executable.

Quoting from a blog post of mine:
"""
But the real show stopper is the size of the generated code for the 
bindings. The system I created needs to generate a lot of code for each 
and every one of the functions and classes you define bindings for. 
This makes the final executable awfully big (and might also explain in 
part the slowness while compiling). The small test application included 
with the bridge takes about 60 Mb of code, thats for something that’d 
be only a few kilobytes when written in Objective-C.

This wasn’t the case at first. This bloat appeared as I added bindings 
for more and more classes in Cocoa. It is a real problem because no one 
in his right mind will want to ship a 60 Mb application that contains 
so much binding code that stay unused most of the time. A solution 
could be that everyone would have to write bindings that only contains 
the classes and methods he needs, but this is of rather limited 
interest.
"""

>> Maybe you'll have more luck, but for me wrappers just couldn't work. So I
>> decided making the compiler understand the Objective-C runtime and object
>> model was a much better solution. It was fun to do and wasn't that hard
>> actually. Here's the result: 
>> <http://michelf.com/projects/**d-objc/<http://michelf.com/projects/d-objc/>>.
Unfortunately 
>> 
>> I don't have much time to work on it anymore.
> 
> That sounds appropriate for Obj-C, but I don't think it applies to VM based
> languages however you slice it, since there's not actually a direct binary
> linkage. There's no way to know about the Java/.NET/Lua/etc object model
> internally, the VM owns that entirely, so you're forced to marshal through
> API's.

That's not actually very different from what I'm doing for Objective-C. 
Call to Objective-C methods are all done through low-level API 
functions in the Objective-C runtime. Class definitions are static 
data, but could be done dynamically through API calls in module 
constructors.

The most interesting bit however is that class *declarations* require 
nothing to be compiled, the compiler will just emit the right code when 
calling a method, using objc_msgSend(). This has a major impact on 
compilation time if you have thousands of such functions.


> That's okay though, you have to do it anyway. I'm proposing a way to
> unify the concept of calling functions without obscuring the actual call
> with junk, and still allowing the D language to annotate and optimise to
> its fullest extent.

The goal is certainly worthwhile. I think your proposal has merit if 
you goal is just to call functions and not define function or classes, 
although I'm skeptical overloading extern() is the right way to do that 
(perhaps a pragma?). But I'd suggest you define your goals more 
throughly before deciding on an implementation.

Some questions you should try to have an answer for regarding OO: if 
you're interacting with classes, how should it work in an ideal world? 
Then, do you need to define new classes that'd be available in the 
foreign language? Do you need to override functions on existing 
classes? How do you want code using foreign objects to look? Then ask 
yourself what would be an acceptable compromise, and start implementing 
it.

For my part, I came to the conclusion that you couldn't really use 
Objective-C APIs in a meaningful way without the ability to create 
subclasses and override functions… which led me to the current design 
where you can use Objective-C classes as if they were D classes.


-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/



More information about the Digitalmars-d mailing list