www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - D/Objective-C 64bit

reply Jacob Carlborg <doob me.com> writes:
I just wanted to let everyone know that I have implemented D/Objective-C 
for 64bit. Everything that worked for 32bit should work, except for 
exceptions, which are not implemented yet.

Objective-C on 64bit uses the modern runtime, which is also the same 
used on iOS. This means D/Objective-C should now be compatible with iOS 
as well, at least in theory.

For those how don't know what D/Objective-C is. It is a language 
extension to D making it ABI compatible with Objective-C. This means 
it's possible to use Objective-C classes, methods, protocols 
(interfaces) and so on, directly just as it's currently possible to do 
with regular C functions.

Here's a recap of what's implemented, both for 32 and 64bit unless 
otherwise noticed:

* Classes
* Subclasses
* Instance and class methods
* Protocols (interfaces)
* Properties
* Exceptions (only 32bit)
* Selectors
* Class references
* String literals
* Casts

Some improvements that are really not part of Objective-C but are very 
convenient to have in D :

* Constructors
* Inheriting selectors
* Automatically generated selectors

On the other hand, here a list of what's not implemented yet:

* Blocks (similar to delegates)
* Categories (class extensions)
* Any form of automatic memory management
* Exceptions (64bit)
* Vtable optimization (64bit)

Objective-C exceptions on 64bit is implemented using the same mechanism 
as C++. I'm wondering if it would be possible for D (not just for this 
extension) to adapt this mechanism as well. This would make D compatible 
with both C++ and Objective-C exceptions on 64bit.

A DIP is available here [1] and the latest implementation is available 
here [2].

[1] http://wiki.dlang.org/DIP43
[2] https://github.com/jacob-carlborg/dmd/tree/d-objc

-- 
/Jacob Carlborg
Mar 11 2014
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/11/14, 11:23 AM, Jacob Carlborg wrote:
 [1] http://wiki.dlang.org/DIP43
 [2] https://github.com/jacob-carlborg/dmd/tree/d-objc
Wow, this is fantastic. Congratulations! Upon a quick scan, the DIP seems tasteful and well put together. Let's see how to merge this into dmd! Andrei
Mar 11 2014
parent reply Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-03-11 20:28:58 +0000, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 On 3/11/14, 11:23 AM, Jacob Carlborg wrote:
 [1] http://wiki.dlang.org/DIP43
 [2] https://github.com/jacob-carlborg/dmd/tree/d-objc
Wow, this is fantastic. Congratulations! Upon a quick scan, the DIP seems tasteful and well put together. Let's see how to merge this into dmd!
Honestly, I don't think it's ready to be part of the official distribution (no memory management being the worse issue). But it doesn't mean it shouldn't be merged. You need to compile it with the D_OBJC define to get a compiler with Objective-C capabilities, which means that those capabilities don't necessarily need to be part of the official distribution even if the changes are merged. So merge ahead. Also, I'll be glad to participate in the review given I wrote most of that code. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Mar 11 2014
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 3/11/2014 4:18 PM, Michel Fortin wrote:
 Also, I'll be glad to participate in the review given I wrote most of that
code.
I'm glad to see this is building on the great groundwork you've already done.
Mar 11 2014
parent "Jacob Carlborg" <doob me.com> writes:
On Wednesday, 12 March 2014 at 01:09:25 UTC, Walter Bright wrote:

 I'm glad to see this is building on the great groundwork you've 
 already done.
Yes, absolutely. Michel has done most of the work, forgot to mention that. I'm just polishing now. -- /Jacob Carlborg
Mar 12 2014
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/11/14, 4:18 PM, Michel Fortin wrote:
 On 2014-03-11 20:28:58 +0000, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:

 On 3/11/14, 11:23 AM, Jacob Carlborg wrote:
 [1] http://wiki.dlang.org/DIP43
 [2] https://github.com/jacob-carlborg/dmd/tree/d-objc
Wow, this is fantastic. Congratulations! Upon a quick scan, the DIP seems tasteful and well put together. Let's see how to merge this into dmd!
Honestly, I don't think it's ready to be part of the official distribution (no memory management being the worse issue). But it doesn't mean it shouldn't be merged. You need to compile it with the D_OBJC define to get a compiler with Objective-C capabilities, which means that those capabilities don't necessarily need to be part of the official distribution even if the changes are merged. So merge ahead. Also, I'll be glad to participate in the review given I wrote most of that code.
Great. Jacob, what's your plan to take this forward? We're very interested in merging this as part of the official D compiler. Andrei
Mar 11 2014
parent reply "Jacob Carlborg" <doob me.com> writes:
On Wednesday, 12 March 2014 at 01:45:38 UTC, Andrei Alexandrescu 
wrote:

 Great. Jacob, what's your plan to take this forward? We're very 
 interested in merging this as part of the official D compiler.
In theory I could create a pull request tonight. It depends on what state we need the language support to be in. As I said exceptions are missing on 64bit. But on the other hand when support for C++ was introduced in D it had very limited support. One idea is to merge the changes but wait with enabling the languages changes. The test machines could run the tests with the changes enabled. -- /Jacob Carlborg
Mar 12 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/12/14, 12:15 AM, Jacob Carlborg wrote:
 On Wednesday, 12 March 2014 at 01:45:38 UTC, Andrei Alexandrescu wrote:

 Great. Jacob, what's your plan to take this forward? We're very
 interested in merging this as part of the official D compiler.
In theory I could create a pull request tonight. It depends on what state we need the language support to be in. As I said exceptions are missing on 64bit. But on the other hand when support for C++ was introduced in D it had very limited support. One idea is to merge the changes but wait with enabling the languages changes. The test machines could run the tests with the changes enabled.
I'll defer to domain experts on this one. Please advise. Andrei
Mar 12 2014
next sibling parent Johannes Pfau <nospam example.com> writes:
Am Wed, 12 Mar 2014 10:53:35 -0700
schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 On 3/12/14, 12:15 AM, Jacob Carlborg wrote:
 On Wednesday, 12 March 2014 at 01:45:38 UTC, Andrei Alexandrescu
 wrote:

 Great. Jacob, what's your plan to take this forward? We're very
 interested in merging this as part of the official D compiler.
In theory I could create a pull request tonight. It depends on what state we need the language support to be in. As I said exceptions are missing on 64bit. But on the other hand when support for C++ was introduced in D it had very limited support. One idea is to merge the changes but wait with enabling the languages changes. The test machines could run the tests with the changes enabled.
I'll defer to domain experts on this one. Please advise. Andrei
We could also start a (better: the first) feature branch. http://wiki.dlang.org/Release_Process#Branching%20model
Mar 12 2014
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-03-12 17:53:35 +0000, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 On 3/12/14, 12:15 AM, Jacob Carlborg wrote:
 On Wednesday, 12 March 2014 at 01:45:38 UTC, Andrei Alexandrescu wrote:
 
 Great. Jacob, what's your plan to take this forward? We're very
 interested in merging this as part of the official D compiler.
In theory I could create a pull request tonight. It depends on what state we need the language support to be in. As I said exceptions are missing on 64bit. But on the other hand when support for C++ was introduced in D it had very limited support. One idea is to merge the changes but wait with enabling the languages changes. The test machines could run the tests with the changes enabled.
I'll defer to domain experts on this one. Please advise.
If the compiler is going to be converted to the D language (how is that progressing?), it'd probably be better to merge before that, otherwise it'll be a lot of work to port all those changes. The first question should about the review process. This patch touches a lot of things, so I wonder if Walter will be confortable reviewing it. Should different people review different parts? Here's a comparison view: DMD: 94 changed files with 8,005 additions and 48 deletions. https://github.com/jacob-carlborg/dmd/compare/d-objc druntime: 10 changed files with 1,263 additions and 0 deletions. https://github.com/jacob-carlborg/druntime/compare/d-objc Most of the changes to the compiler are inside #if DMD_OBJC/#endif blocks. Changes outside of those blocks shouldn't affect the semantics or the binary output of existing code. So I think a review could be done in two steps: 1. Review changes outside of those #if DMD_OBJC blocks. Those are the most critical changes as they'll affect the next version of the compiler that'll ship (I'm assuming Objective-C features won't be turned on until they're more usable). This includes some changes in the lexer, but it shouldn't affect current D code. This review could exclude the two files objc.h/objc.c, since the makefile ignores them without the D_OBJC flag. 2. Maybe review things inside of those #if DMD_OBJC blocks. Those things won't affect the compiler unless compiled with the D_OBJC flag, so it's less critical to review them. Most of them are there to implement Objective-C semantics so you'll need to be somewhat familiar with Objective-C to judge whether they're correct or not. What should be checked is whether an error would make them affect non-Objective-C constructs when they're compiled in. We also need to know what to do about the test suite. I made a separate test suite for D/Objective-C since those tests can only run on OS X and only with the compiler compiled with Objective-C support enabled. It could easily be merged with the main test suite, but the tests should be made conditional to whether the compiler is compiled with Objective-C or not. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Mar 12 2014
next sibling parent Iain Buclaw <ibuclaw gdcproject.org> writes:
On 12 March 2014 19:34, Michel Fortin <michel.fortin michelf.ca> wrote:
 On 2014-03-12 17:53:35 +0000, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:

 On 3/12/14, 12:15 AM, Jacob Carlborg wrote:
 On Wednesday, 12 March 2014 at 01:45:38 UTC, Andrei Alexandrescu wrote:

 Great. Jacob, what's your plan to take this forward? We're very
 interested in merging this as part of the official D compiler.
In theory I could create a pull request tonight. It depends on what state we need the language support to be in. As I said exceptions are missing on 64bit. But on the other hand when support for C++ was introduced in D it had very limited support. One idea is to merge the changes but wait with enabling the languages changes. The test machines could run the tests with the changes enabled.
I'll defer to domain experts on this one. Please advise.
If the compiler is going to be converted to the D language (how is that progressing?), it'd probably be better to merge before that, otherwise it'll be a lot of work to port all those changes.
Daniel's DDMD conversion tool is on github, you could run it through that to get most of the legwork converted over I guess?
Mar 12 2014
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-03-12 20:34, Michel Fortin wrote:

 If the compiler is going to be converted to the D language (how is that
 progressing?), it'd probably be better to merge before that, otherwise
 it'll be a lot of work to port all those changes.
I think Daniel has said he as a working Linux compiler. He just need to create pull requests (and get them merged) for all changes his tool requires. -- /Jacob Carlborg
Mar 12 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Jacob Carlborg"  wrote in message news:lfqf4t$2v1o$1 digitalmars.com...

 I think Daniel has said he as a working Linux compiler. He just need to 
 create pull requests (and get them merged) for all changes his tool 
 requires.
The changes to dmd's source are all done(!), it's now time to start putting the manually ported stuff into the main repo.
Mar 13 2014
parent "Jacob Carlborg" <doob me.com> writes:
On Thursday, 13 March 2014 at 12:02:24 UTC, Daniel Murphy wrote:

 The changes to dmd's source are all done(!), it's now time to 
 start putting the manually ported stuff into the main repo.
That's great :). -- /Jacob Carlborg
Mar 13 2014
prev sibling parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Michel Fortin"  wrote in message news:lfqcs6$2su5$1 digitalmars.com...

 If the compiler is going to be converted to the D language (how is that 
 progressing?), it'd probably be better to merge before that, otherwise 
 it'll be a lot of work to port all those changes.
The converter can convert git master, compile it with git master, and pass the full test suite + phobos on linux32/linux64/win32. If someone wants to give me access to an OSX box I'll get it working there too. The main problem with these patches is their use of #if in places where D's version blocks don't work. These will all need to be fixed before it is merged, as I've done for the rest of the frontend. I'm happy to help anyone set up the converter - contact me here/by email/on github. It should be as simple as 1. Build dmd master 2. git clone git github.com:yebblies/magicport2.git 3. Fix paths if you have a different layout than I do 4. make
Mar 13 2014
prev sibling parent reply "Jacob Carlborg" <doob me.com> writes:
On Wednesday, 12 March 2014 at 17:53:19 UTC, Andrei Alexandrescu 
wrote:

 I'll defer to domain experts on this one. Please advise.
Yeah, we need some comments from Walter, Daniel, Kenji and others of the core DMD developers. Probably good to have comments from David and Iain as well, to get a LDC and GDC perspective. -- /Jacob Carlborg
Mar 13 2014
parent reply Johannes Pfau <nospam example.com> writes:
Am Thu, 13 Mar 2014 14:20:54 +0000
schrieb "Jacob Carlborg" <doob me.com>:

 On Wednesday, 12 March 2014 at 17:53:19 UTC, Andrei Alexandrescu 
 wrote:
 
 I'll defer to domain experts on this one. Please advise.
Yeah, we need some comments from Walter, Daniel, Kenji and others of the core DMD developers. Probably good to have comments from David and Iain as well, to get a LDC and GDC perspective. -- /Jacob Carlborg
Is it possible to split objc.c into two files, one for backend interfacing functions (ObjcSymbols) and one for the generic frontend stuff?
Mar 13 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-03-13 17:16, Johannes Pfau wrote:

 Is it possible to split objc.c into two files, one for backend
 interfacing functions (ObjcSymbols) and one for the generic frontend
 stuff?
I would guess so. I would need to take a look to see how coupled the code in objc.c is. Although, most code is for backend. -- /Jacob Carlborg
Mar 13 2014
parent Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-03-13 18:13:44 +0000, Jacob Carlborg <doob me.com> said:

 On 2014-03-13 17:16, Johannes Pfau wrote:
 
 Is it possible to split objc.c into two files, one for backend
 interfacing functions (ObjcSymbols) and one for the generic frontend
 stuff?
I would guess so. I would need to take a look to see how coupled the code in objc.c is. Although, most code is for backend.
I think that'd be a good idea too. When I wrote that code I wanted everything to be close by as it was easier to experiment, but there's no need for that now. Perhaps, instead of splitting, classes derived from frontend classes (Expression, Declaration, Type) should be moved to their corresponding files and live with other similar classes of the frontend, protected in #if DMD_OBJC blocks. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Mar 13 2014
prev sibling next sibling parent reply "Asman01" <jckj33 gmail.com> writes:
On Tuesday, 11 March 2014 at 18:23:08 UTC, Jacob Carlborg wrote:
 I just wanted to let everyone know that I have implemented 
 D/Objective-C for 64bit. Everything that worked for 32bit 
 should work, except for exceptions, which are not implemented 
 yet.

 Objective-C on 64bit uses the modern runtime, which is also the 
 same used on iOS. This means D/Objective-C should now be 
 compatible with iOS as well, at least in theory.

 For those how don't know what D/Objective-C is. It is a 
 language extension to D making it ABI compatible with 
 Objective-C. This means it's possible to use Objective-C 
 classes, methods, protocols (interfaces) and so on, directly 
 just as it's currently possible to do with regular C functions.

 Here's a recap of what's implemented, both for 32 and 64bit 
 unless otherwise noticed:

 * Classes
 * Subclasses
 * Instance and class methods
 * Protocols (interfaces)
 * Properties
 * Exceptions (only 32bit)
 * Selectors
 * Class references
 * String literals
 * Casts

 Some improvements that are really not part of Objective-C but 
 are very convenient to have in D :

 * Constructors
 * Inheriting selectors
 * Automatically generated selectors

 On the other hand, here a list of what's not implemented yet:

 * Blocks (similar to delegates)
 * Categories (class extensions)
 * Any form of automatic memory management
 * Exceptions (64bit)
 * Vtable optimization (64bit)

 Objective-C exceptions on 64bit is implemented using the same 
 mechanism as C++. I'm wondering if it would be possible for D 
 (not just for this extension) to adapt this mechanism as well. 
 This would make D compatible with both C++ and Objective-C 
 exceptions on 64bit.

 A DIP is available here [1] and the latest implementation is 
 available here [2].

 [1] http://wiki.dlang.org/DIP43
 [2] https://github.com/jacob-carlborg/dmd/tree/d-objc
It's really awesome. Congratulations! If this DIP is actually approved will dmd have "native" integration/support to Objective-C language just like we can do with C? I'm not a Obj-C programmer but I like the idea. We could still improve this add new languages
Mar 11 2014
parent "Jacob Carlborg" <doob me.com> writes:
On Tuesday, 11 March 2014 at 21:48:45 UTC, Asman01 wrote:

 It's really awesome. Congratulations! If this DIP is actually 
 approved will dmd have "native" integration/support to 
 Objective-C language just like we can do with C? I'm not a 
 Obj-C programmer but I like the idea.
Yes. -- /Jacob Carlborg
Mar 12 2014
prev sibling next sibling parent reply "Paolo Invernizzi" <paolo.invernizzi no.address> writes:
On Tuesday, 11 March 2014 at 18:23:08 UTC, Jacob Carlborg wrote:
 I just wanted to let everyone know that I have implemented 
 D/Objective-C for 64bit. Everything that worked for 32bit 
 should work, except for exceptions, which are not implemented 
 yet.
<snip>
 A DIP is available here [1] and the latest implementation is 
 available here [2].

 [1] http://wiki.dlang.org/DIP43
 [2] https://github.com/jacob-carlborg/dmd/tree/d-objc
Thanks Jacob, great work! If someone is trying it like me, I don't know the proper way for doing that, but the compiler must be built with the DMD_OBJC define turned on. - Paolo
Mar 11 2014
next sibling parent "Paolo Invernizzi" <paolo.invernizzi no.address> writes:
On Tuesday, 11 March 2014 at 22:13:07 UTC, Paolo Invernizzi wrote:
 If someone is trying it like me, I don't know the proper way 
 for doing that, but the compiler must be built with the 
 DMD_OBJC define turned on.

 - Paolo
Sorry, I meant D_OBJC ... - Paolo
Mar 11 2014
prev sibling parent "Jacob Carlborg" <doob me.com> writes:
On Tuesday, 11 March 2014 at 22:13:07 UTC, Paolo Invernizzi wrote:

 Thanks Jacob, great work!

 If someone is trying it like me, I don't know the proper way 
 for doing that, but the compiler must be built with the 
 DMD_OBJC define turned on.
Yes, D_OBJC. You need the corresponding changes for druntime [1] as well. It seems I haven't pushed the changes for 64bit, I'll do that tonight. [1] https://github.com/jacob-carlborg/druntime/tree/d-objc -- /Jacob Carlborg
Mar 12 2014
prev sibling next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 11 March 2014 at 18:23:08 UTC, Jacob Carlborg wrote:
 I just wanted to let everyone know that I have implemented 
 D/Objective-C for 64bit. Everything that worked for 32bit 
 should work, except for exceptions, which are not implemented 
 yet.

 Objective-C on 64bit uses the modern runtime, which is also the 
 same used on iOS. This means D/Objective-C should now be 
 compatible with iOS as well, at least in theory.

 For those how don't know what D/Objective-C is. It is a 
 language extension to D making it ABI compatible with 
 Objective-C. This means it's possible to use Objective-C 
 classes, methods, protocols (interfaces) and so on, directly 
 just as it's currently possible to do with regular C functions.

 Here's a recap of what's implemented, both for 32 and 64bit 
 unless otherwise noticed:

 * Classes
 * Subclasses
 * Instance and class methods
 * Protocols (interfaces)
 * Properties
 * Exceptions (only 32bit)
 * Selectors
 * Class references
 * String literals
 * Casts

 Some improvements that are really not part of Objective-C but 
 are very convenient to have in D :

 * Constructors
 * Inheriting selectors
 * Automatically generated selectors

 On the other hand, here a list of what's not implemented yet:

 * Blocks (similar to delegates)
 * Categories (class extensions)
 * Any form of automatic memory management
 * Exceptions (64bit)
 * Vtable optimization (64bit)

 Objective-C exceptions on 64bit is implemented using the same 
 mechanism as C++. I'm wondering if it would be possible for D 
 (not just for this extension) to adapt this mechanism as well. 
 This would make D compatible with both C++ and Objective-C 
 exceptions on 64bit.

 A DIP is available here [1] and the latest implementation is 
 available here [2].

 [1] http://wiki.dlang.org/DIP43
 [2] https://github.com/jacob-carlborg/dmd/tree/d-objc
To what extent will this be portable to ldc/gdc?
Mar 11 2014
parent reply Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-03-11 22:43:58 +0000, "John Colvin" 
<john.loughran.colvin gmail.com> said:

 To what extent will this be portable to ldc/gdc?
The codegen elements in objc.c will need to be changed to bind to the LLVM/GCC backend. Shouldn't be too hard, I guess. [1]: https://github.com/jacob-carlborg/dmd/blob/d-objc/src/objc.c -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Mar 11 2014
next sibling parent Iain Buclaw <ibuclaw gdcproject.org> writes:
On 11 Mar 2014 23:25, "Michel Fortin" <michel.fortin michelf.ca> wrote:
 On 2014-03-11 22:43:58 +0000, "John Colvin" <
john.loughran.colvin gmail.com> said:
 To what extent will this be portable to ldc/gdc?
The codegen elements in objc.c will need to be changed to bind to the
LLVM/GCC backend. Shouldn't be too hard, I guess.
 [1]: https://github.com/jacob-carlborg/dmd/blob/d-objc/src/objc.c
Oh no, not more work...
Mar 11 2014
prev sibling parent reply "Jacob Carlborg" <doob me.com> writes:
On Tuesday, 11 March 2014 at 23:20:23 UTC, Michel Fortin wrote:

 The codegen elements in objc.c will need to be changed to bind 
 to the LLVM/GCC backend. Shouldn't be too hard, I guess.
Yeah, since Objective-C uses the C calling convention it's mostly about outputting symbols and data to the object files. -- /Jacob Carlborg
Mar 12 2014
parent reply Iain Buclaw <ibuclaw gdcproject.org> writes:
On 12 March 2014 07:10, Jacob Carlborg <doob me.com> wrote:
 On Tuesday, 11 March 2014 at 23:20:23 UTC, Michel Fortin wrote:

 The codegen elements in objc.c will need to be changed to bind to the
 LLVM/GCC backend. Shouldn't be too hard, I guess.
Yeah, since Objective-C uses the C calling convention it's mostly about outputting symbols and data to the object files.
In what ABI may I ask? Your choices are: - Traditional (32bit) ABI without properties and Obj-C 2.0 additions - Traditional (32bit) ABI with properties and Obj-C 2.0 additions - Modern (64bit) ABI That can be mixed in with either: - GNU Runtime ABI - NeXT Runtime ABI Each combination being incompatible with each other subtly different ways...
Mar 12 2014
parent reply Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-03-12 09:26:56 +0000, Iain Buclaw <ibuclaw gdcproject.org> said:

 On 12 March 2014 07:10, Jacob Carlborg <doob me.com> wrote:
 Yeah, since Objective-C uses the C calling convention it's mostly about
 outputting symbols and data to the object files.
In what ABI may I ask? Your choices are: - Traditional (32bit) ABI without properties and Obj-C 2.0 additions - Traditional (32bit) ABI with properties and Obj-C 2.0 additions - Modern (64bit) ABI
I made the 32-bit legacy runtime support, Jacob added the 64-bit modern runtime support. There's no support at this time for properties declarations in the ABI, but it doesn't really have much impact. As far as I'm aware, Objective-C 2.0 additions only include property declarations and attributes in the ABI.
 That can be mixed in with either:
 - GNU Runtime ABI
 - NeXT Runtime ABI
It's been tested with the Apple (NeXT) runtime only. In all honesty, I, and probably most people out there, don't care about the GNU runtime. Although probably the GCC guys do. Do you think it'd make it more difficult to merge GCC in the GCC project if it had support for Apple's runtime and not for the GNU one? Also, is there a list of differences between the two runtimes somewhere?
 Each combination being incompatible with each other subtly different ways...
Which is why we have a test suite. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Mar 12 2014
next sibling parent "Paulo Pinto" <pjmlp progtools.org> writes:
On Wednesday, 12 March 2014 at 12:14:23 UTC, Michel Fortin wrote:
 On 2014-03-12 09:26:56 +0000, Iain Buclaw 
 <ibuclaw gdcproject.org> said:

 On 12 March 2014 07:10, Jacob Carlborg <doob me.com> wrote:
 Yeah, since Objective-C uses the C calling convention it's 
 mostly about
 outputting symbols and data to the object files.
In what ABI may I ask? Your choices are: - Traditional (32bit) ABI without properties and Obj-C 2.0 additions - Traditional (32bit) ABI with properties and Obj-C 2.0 additions - Modern (64bit) ABI
I made the 32-bit legacy runtime support, Jacob added the 64-bit modern runtime support. There's no support at this time for properties declarations in the ABI, but it doesn't really have much impact. As far as I'm aware, Objective-C 2.0 additions only include property declarations and attributes in the ABI.
 That can be mixed in with either:
 - GNU Runtime ABI
 - NeXT Runtime ABI
It's been tested with the Apple (NeXT) runtime only. In all honesty, I, and probably most people out there, don't care about the GNU runtime. Although probably the GCC guys do. Do you think it'd make it more difficult to merge GCC in the GCC project if it had support for Apple's runtime and not for the GNU one? Also, is there a list of differences between the two runtimes somewhere?
 Each combination being incompatible with each other subtly 
 different ways...
Which is why we have a test suite.
There is an outdated list here, http://wiki.gnustep.org/index.php/ObjC2_FAQ I wouldn't care for GNUStep support. Objective-C support in gcc is almost dead and GNUStep seems to have hardly changed since I used WindowMaker as my main window manager. Which was around 1999 - 2004! -- Paulo
Mar 12 2014
prev sibling next sibling parent reply Iain Buclaw <ibuclaw gdcproject.org> writes:
On 12 March 2014 12:14, Michel Fortin <michel.fortin michelf.ca> wrote:
 On 2014-03-12 09:26:56 +0000, Iain Buclaw <ibuclaw gdcproject.org> said:

 On 12 March 2014 07:10, Jacob Carlborg <doob me.com> wrote:
 Yeah, since Objective-C uses the C calling convention it's mostly about
 outputting symbols and data to the object files.
In what ABI may I ask? Your choices are: - Traditional (32bit) ABI without properties and Obj-C 2.0 additions - Traditional (32bit) ABI with properties and Obj-C 2.0 additions - Modern (64bit) ABI
I made the 32-bit legacy runtime support, Jacob added the 64-bit modern runtime support. There's no support at this time for properties declarations in the ABI, but it doesn't really have much impact. As far as I'm aware, Objective-C 2.0 additions only include property declarations and attributes in the ABI.
 That can be mixed in with either:
 - GNU Runtime ABI
 - NeXT Runtime ABI
It's been tested with the Apple (NeXT) runtime only. In all honesty, I, and probably most people out there, don't care about the GNU runtime. Although probably the GCC guys do. Do you think it'd make it more difficult to merge GCC in the GCC project if it had support for Apple's runtime and not for the GNU one?
gobjc supports both, there's two ABI's for the NeXT - which I take to mean the difference between the difference between 32bit and 64bit. It seems that (now I read up on it) the GNU runtime came about from decades back when NeXT was not open sourced by Apple. From what I can gather, a move towards the modern ABI is the direction, but not considered production ready.
From my POV, I wouldn't want to support the ABI of a language that GCC
itself doesn't support. So code compiled by GNU ObjC should be compatible with extern(ObjC) code generated by GDC - even if it isn't compatible with Clang ObjC. But then, I'd be surprised if it wasn't compatible.
 Also, is there a list of differences between the two runtimes somewhere?
That's hard to say at an initial glance. There's a handy hook system into each ABI to allow you to switch between versions easily. The common differences I do however see are: NeXT: NSConstantString objc_getClass objc_getMetaClass objc_msgSend objc_msgSendSuper GNU: NXConstantString objc_get_class objc_get_meta_class objc_msg_lookup objc_msg_lookup_super Some which greps for s(n)printf also show: NeXT: ".objc_class_name_%s" ".objc_category_name_%s_%s" GNU: "__objc_class_name_%s" "__objc_category_name_%s_%s" Most others look the same? Maybe you'll be able to find out more with this information.
Mar 12 2014
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-03-12 20:02, Iain Buclaw wrote:

 gobjc supports both, there's two ABI's for the NeXT - which I take to
 mean the difference between the difference between 32bit and 64bit.
You previously listed three ABI's. It's the modern runtime for 64bit and the traditional for 32bit with with properties that are interesting. I don't know how much difference these properties do.
 It seems that (now I read up on it) the GNU runtime came about from
 decades back when NeXT was not open sourced by Apple.  From what I can
 gather, a move towards the modern ABI is the direction, but not
 considered production ready.

From my POV, I wouldn't want to support the ABI of a language that GCC
itself doesn't support. So code compiled by GNU ObjC should be compatible with extern(ObjC) code generated by GDC - even if it isn't compatible with Clang ObjC. But then, I'd be surprised if it wasn't compatible.
I'm not sure I understand. Do you want to support the NeXT or GNU runtime? Clang is at least compatible with the Apple GCC. I don't know about FSF GCC.
 That's hard to say at an initial glance.  There's a handy hook system
 into each ABI to allow you to switch between versions easily.  The
 common differences I do however see are:

 NeXT:
 NSConstantString
 objc_getClass
 objc_getMetaClass
 objc_msgSend
 objc_msgSendSuper

 GNU:
 NXConstantString
 objc_get_class
 objc_get_meta_class
 objc_msg_lookup
 objc_msg_lookup_super

 Some which greps for s(n)printf also show:

 NeXT:
 ".objc_class_name_%s"
 ".objc_category_name_%s_%s"

 GNU:
 "__objc_class_name_%s"
 "__objc_category_name_%s_%s"


 Most others look the same?  Maybe you'll be able to find out more with
 this information.
One basically need to look at each single feature and see what differs. -- /Jacob Carlborg
Mar 12 2014
parent reply Iain Buclaw <ibuclaw gdcproject.org> writes:
On 12 March 2014 19:29, Jacob Carlborg <doob me.com> wrote:
 On 2014-03-12 20:02, Iain Buclaw wrote:

 gobjc supports both, there's two ABI's for the NeXT - which I take to
 mean the difference between the difference between 32bit and 64bit.
You previously listed three ABI's. It's the modern runtime for 64bit and the traditional for 32bit with with properties that are interesting. I don't know how much difference these properties do.
Sorry, some context. The two 32bit ABIs are part of the same source, I'd take them to be identical, with the exception that the second option supports features that are on-by-default in the 64bit ABI.
 I'm not sure I understand. Do you want to support the NeXT or GNU runtime?
As in, if I were to support NeXT. I'd support the same as implemented by GNU ObjC. I'd have to look up if there are incompatibilities between GCC > 4.3 and Clang on the ObjC side...
Mar 12 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-03-12 20:37, Iain Buclaw wrote:

 Sorry, some context.  The two 32bit ABIs are part of the same source,
 I'd take them to be identical, with the exception that the second
 option supports features that are on-by-default in the 64bit ABI.
I see.
 As in, if I were to support NeXT.  I'd support the same as implemented
 by GNU ObjC.  I'd have to look up if there are incompatibilities
 between GCC > 4.3 and Clang on the ObjC side...
Sounds reasonable. -- /Jacob Carlborg
Mar 12 2014
prev sibling parent reply Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-03-12 19:02:10 +0000, Iain Buclaw <ibuclaw gdcproject.org> said:

 From my POV, I wouldn't want to support the ABI of a language that GCC
 itself doesn't support.  So code compiled by GNU ObjC should be
 compatible with extern(ObjC) code generated by GDC - even if it isn't
 compatible with Clang ObjC.  But then, I'd be surprised if it wasn't
 compatible.
It all comes to how you integrate the thing with GCC. My guess is that you have three choices: 1. ignore Objective-C support: don't define DMD_OBJC in the code and the compiler will complain whenever it sees extern(Objective-C) 2. translate the calls to the DMD backend creating the various sections and segments to equivalent calls for creating sections and segments in GCC 3. replace the codegen for Objective-C data structures by what's already implemented in GCC for Objective-C This last option will support whatever ABI GCC has support for. That's probably the way to go if you want to make sure ABIs are compatible. All the Objective-C ABI DMD knows about is implemented in objc.c, so what you have to do is to rewrite objc.c to call the GCC equivalent implementation, probably getting rid of most of the code in there.
 NeXT:
 NSConstantString
 objc_getClass
 objc_getMetaClass
 objc_msgSend
 objc_msgSendSuper
 
 GNU:
 NXConstantString
 objc_get_class
 objc_get_meta_class
 objc_msg_lookup
 objc_msg_lookup_super
 
 Some which greps for s(n)printf also show:
 
 NeXT:
 ".objc_class_name_%s"
 ".objc_category_name_%s_%s"
 
 GNU:
 "__objc_class_name_%s"
 "__objc_category_name_%s_%s"
 
 
 Most others look the same?  Maybe you'll be able to find out more with
 this information.
My understanding is that the differences are pretty trivial. But regardless, we probably don't have to care about them if you can hook directly to the GCC Objective-C codegen. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Mar 12 2014
parent Iain Buclaw <ibuclaw gdcproject.org> writes:
On 12 March 2014 19:36, Michel Fortin <michel.fortin michelf.ca> wrote:
 On 2014-03-12 19:02:10 +0000, Iain Buclaw <ibuclaw gdcproject.org> said:

 From my POV, I wouldn't want to support the ABI of a language that GCC
 itself doesn't support.  So code compiled by GNU ObjC should be
 compatible with extern(ObjC) code generated by GDC - even if it isn't
 compatible with Clang ObjC.  But then, I'd be surprised if it wasn't
 compatible.
It all comes to how you integrate the thing with GCC. My guess is that you have three choices: 1. ignore Objective-C support: don't define DMD_OBJC in the code and the compiler will complain whenever it sees extern(Objective-C) 2. translate the calls to the DMD backend creating the various sections and segments to equivalent calls for creating sections and segments in GCC 3. replace the codegen for Objective-C data structures by what's already implemented in GCC for Objective-C This last option will support whatever ABI GCC has support for. That's probably the way to go if you want to make sure ABIs are compatible. All the Objective-C ABI DMD knows about is implemented in objc.c, so what you have to do is to rewrite objc.c to call the GCC equivalent implementation, probably getting rid of most of the code in there.
 NeXT:
 NSConstantString
 objc_getClass
 objc_getMetaClass
 objc_msgSend
 objc_msgSendSuper

 GNU:
 NXConstantString
 objc_get_class
 objc_get_meta_class
 objc_msg_lookup
 objc_msg_lookup_super

 Some which greps for s(n)printf also show:

 NeXT:
 ".objc_class_name_%s"
 ".objc_category_name_%s_%s"

 GNU:
 "__objc_class_name_%s"
 "__objc_category_name_%s_%s"


 Most others look the same?  Maybe you'll be able to find out more with
 this information.
My understanding is that the differences are pretty trivial. But regardless, we probably don't have to care about them if you can hook directly to the GCC Objective-C codegen.
Hooking to ObjC could be done, but requires patching GCC proper so that ObjC mangling becomes common code, not front-end specific.
Mar 12 2014
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2014-03-12 13:14, Michel Fortin wrote:

 I made the 32-bit legacy runtime support, Jacob added the 64-bit modern
 runtime support.

 There's no support at this time for properties declarations in the ABI,
 but it doesn't really have much impact. As far as I'm aware, Objective-C
 2.0 additions only include property declarations and attributes in the ABI.
It is now :). I added support for properties. But as you say, I don't really know what they add. -- /Jacob Carlborg
Mar 12 2014
prev sibling next sibling parent Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-03-11 18:23:07 +0000, Jacob Carlborg <doob me.com> said:

 I just wanted to let everyone know that I have implemented 
 D/Objective-C for 64bit. Everything that worked for 32bit should work, 
 except for exceptions, which are not implemented yet.
It's nice to see you're taking good care of that thing I started. For Objective-C exceptions to work right DMD will have to change its exception model for D exceptions to match the one used by Apple's C++ compiler. It'll make things better for everyone, and no other solution makes much sense really. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Mar 11 2014
prev sibling next sibling parent reply "w0rp" <devw0rp gmail.com> writes:
This is really awesome work. If you combined ARM support with 
Objective C support, it would mean you could write iOS programs 
in D without much frustration, and that would be a huge step 
forward. Objective C has a good runtime, but lacks templates and 
CTFE. Using CTFE for an iOS program could be very cool.

How do you plan to handle automatic reference counting? I imagine 
that's a hard part. When I was writing Objective C I remember 
having to write bridged casts so I could manually extend or limit 
object lifetime, but I never handled it from within a C library.
Mar 12 2014
next sibling parent Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-03-12 08:06:47 +0000, "w0rp" <devw0rp gmail.com> said:

 This is really awesome work. If you combined ARM support with Objective 
 C support, it would mean you could write iOS programs in D without much 
 frustration, and that would be a huge step forward. Objective C has a 
 good runtime, but lacks templates and CTFE. Using CTFE for an iOS 
 program could be very cool.
 
 How do you plan to handle automatic reference counting? I imagine 
 that's a hard part. When I was writing Objective C I remember having to 
 write bridged casts so I could manually extend or limit object 
 lifetime, but I never handled it from within a C library.
Well, there's three ways. (a) The first one is to implement ARC for Objective-C objects, and to automatically add/remove roots to member variables when constructing/destroying Objective-C objects that were defined in D so the GC can those pointers. (b) The second one is to not implement ARC and implement something in the GC so it can track Objective-C objects: retain them on first sight, release them once no longer connected to a root. (c) The third one is to implement ARC as an alternative memory management scheme for D and bolt Objective-C object support on top of it. I'd tend to go for (a) at first, as it's the simplest thing that can be done. But I fear always adding/removing roots will impact performance in a negative way. There's also the issue in (a) and (b) that if the last reference to an object is released from the GC thread the Objective-C object's destructor will be called in a different thread than what is expected which might cause some bugs. So we might want to implement (c) later on to have something more solid and deterministic. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Mar 12 2014
prev sibling parent Dan Olson <zans.is.for.cans yahoo.com> writes:
"w0rp" <devw0rp gmail.com> writes:

 This is really awesome work. If you combined ARM support with 
 Objective C support, it would mean you could write iOS programs 
 in D without much frustration, and that would be a huge step 
 forward. Objective C has a good runtime, but lacks templates and 
 CTFE. Using CTFE for an iOS program could be very cool.
Just a plug that the LDC iOS work is coming along well. D iOS programming may not be too far in the future. -- Dan
Mar 12 2014
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 3/11/14, Jacob Carlborg <doob me.com> wrote:
 I just wanted to let everyone know that I have implemented D/Objective-C
 for 64bit.
Excellent! One thing that's hard to implement right now in D is drag & drop support on OSX, at least when I tried to do it. The problem is I need to call ObjC functions or provide ObjC callbacks, so I end up having to create a C layer, compile that, and then link that to D. Actual support for interfacing with Objective C would be great. Thanks for all the work to both you and Michel Fortin.
Mar 12 2014
prev sibling next sibling parent reply "Szymon Gatner" <noemail gmail.com> writes:
On Tuesday, 11 March 2014 at 18:23:08 UTC, Jacob Carlborg wrote:
 I just wanted to let everyone know that I have implemented 
 D/Objective-C for 64bit. Everything that worked for 32bit 
 should work, except for exceptions, which are not implemented 
 yet.

 Objective-C on 64bit uses the modern runtime, which is also the 
 same used on iOS. This means D/Objective-C should now be 
 compatible with iOS as well, at least in theory.

 For those how don't know what D/Objective-C is. It is a 
 language extension to D making it ABI compatible with 
 Objective-C. This means it's possible to use Objective-C 
 classes, methods, protocols (interfaces) and so on, directly 
 just as it's currently possible to do with regular C functions.

 Here's a recap of what's implemented, both for 32 and 64bit 
 unless otherwise noticed:

 * Classes
 * Subclasses
 * Instance and class methods
 * Protocols (interfaces)
 * Properties
 * Exceptions (only 32bit)
 * Selectors
 * Class references
 * String literals
 * Casts

 Some improvements that are really not part of Objective-C but 
 are very convenient to have in D :

 * Constructors
 * Inheriting selectors
 * Automatically generated selectors

 On the other hand, here a list of what's not implemented yet:

 * Blocks (similar to delegates)
 * Categories (class extensions)
 * Any form of automatic memory management
 * Exceptions (64bit)
 * Vtable optimization (64bit)

 Objective-C exceptions on 64bit is implemented using the same 
 mechanism as C++. I'm wondering if it would be possible for D 
 (not just for this extension) to adapt this mechanism as well. 
 This would make D compatible with both C++ and Objective-C 
 exceptions on 64bit.

 A DIP is available here [1] and the latest implementation is 
 available here [2].

 [1] http://wiki.dlang.org/DIP43
 [2] https://github.com/jacob-carlborg/dmd/tree/d-objc
Wow, this is fantastic! This and recent progress on iOS/ARM/LDC porting make me so happy :)
Mar 12 2014
parent Dan Olson <zans.is.for.cans yahoo.com> writes:
"Szymon Gatner" <noemail gmail.com> writes:

 Wow, this is fantastic! This and recent progress on iOS/ARM/LDC
 porting make me so happy :)
Yeah, it will be cool to combine this with the LDC iOS work. I haven't posted progress lately. I got Fibers working on an iPhone 4. I found that GDC's thread.d already had ARM Fiber support so used it until it gets pulled into dmd. It's really coming down to just a few fundumental things (cross compiling getting real "real" type, and supporting TLS). -- Dan
Mar 12 2014
prev sibling next sibling parent reply "Christian Schneider" <schneider gerzonic.net> writes:
Can somebody with a greater d-objc knowledge have a look at this 
example project and tell this naive D-noob what he is missing?

https://github.com/DiveFramework/DiveFramework/tree/master/Examples/Tableview

I am pretty sure that it has something to do with memory 
management and ARC. First it all starts up right, but then a 
delegate method get's called in the wild and some memory 
segmentation is occurring calling  objectAtIndex, which is called 
on very different objects on multiple runs, and I cannot get any 
closer to the real issue.

NSMutableArray _applications ;

is the main culprit, in this I am trying to put some NSObject 
subclass objects. I have to admit that my mind is all Objective-C 
and very little D yet, and probably the solution is very simple. 
What I have further found is, that the crash occurs in relation 
to the visible table cells. As soon as a view for an invisible 
cell is requested, the seg fault occurs. I am trying to elaborate 
a TableView example using View based cells.

To compile the program, you only need to execute "dub" in the 
Examples/Tableview directory, of course assuming you have the 
latest d-objc branch dmd installed and dub (and Xcode, I am using 
5.1.1 but 6 should work just as well).

Thanks a lot in advance!
Christian
Oct 27 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-10-27 19:03, Christian Schneider wrote:
 Can somebody with a greater d-objc knowledge have a look at this example
 project and tell this naive D-noob what he is missing?

 https://github.com/DiveFramework/DiveFramework/tree/master/Examples/Tableview


 I am pretty sure that it has something to do with memory management and
 ARC. First it all starts up right, but then a delegate method get's
 called in the wild and some memory segmentation is occurring calling
 objectAtIndex, which is called on very different objects on multiple
 runs, and I cannot get any closer to the real issue.

 NSMutableArray _applications ;

 is the main culprit, in this I am trying to put some NSObject subclass
 objects. I have to admit that my mind is all Objective-C and very little
 D yet, and probably the solution is very simple. What I have further
 found is, that the crash occurs in relation to the visible table cells.
 As soon as a view for an invisible cell is requested, the seg fault
 occurs. I am trying to elaborate a TableView example using View based
 cells.

 To compile the program, you only need to execute "dub" in the
 Examples/Tableview directory, of course assuming you have the latest
 d-objc branch dmd installed and dub (and Xcode, I am using 5.1.1 but 6
 should work just as well).
I tried running your code and could observe the behavior. Although I have not been able to figure you why it behaves like this. In general there are a couple of things to think of and watch out for when interfacing between D and Objective-C : * The D compiler does not support any form of ARC, it's back to using retain/release * When allocating memory with the GC in D and passing it to Objective-C (or C for that matter) you have to make sure there is still a root pointing to the memory. This can either be a variable that is still in scope or by explicitly adding a new root by calling core.GC.addRoot. I don't know if any of the above is the actual problem, but it could be. I would recommend trying to contact Michel Fortin how original implemented D/Objective-C. BTW, There is a tool, DStep [1], that can automatically generate bindings for Objective-C code. [1] https://github.com/jacob-carlborg/dstep -- /Jacob Carlborg
Oct 28 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 I tried running your code and could observe the behavior. 
 Although I have not been able to figure you why it behaves like 
 this. In general there are a couple of things to think of and 
 watch out for when interfacing between D and Objective-C :

 * The D compiler does not support any form of ARC, it's back to 
 using retain/release

 * When allocating memory with the GC in D and passing it to 
 Objective-C (or C for that matter) you have to make sure there 
 is still a root pointing to the memory. This can either be a 
 variable that is still in scope or by explicitly adding a new 
 root by calling core.GC.addRoot.

 I don't know if any of the above is the actual problem, but it 
 could be. I would recommend trying to contact Michel Fortin how 
 original implemented D/Objective-C.

 BTW, There is a tool, DStep [1], that can automatically 
 generate bindings for Objective-C code.
Hey Jacob, thanks very much for your reply! It is of course this NSMutableArray that stores the custom objects containing NSString's and an NSImage, which gets deallocated after some time (still can see some garbage if I make it a static member). I will try to figure out how to use retain and release, I once knew how to do this quite well, but since ARC I quit to worry ;) Thanks for the core.GC.addRoot tip! DStep was not very helpful when I tried it, it wanted to find all the referenced includes, which of course can be quite complicated when trying to get foundation and appkit headers processed. Once this ARC / memory management stuff is resolved, d-objc on OSX will be super awesome!! Thanks to you and Michel for all the work!
Oct 29 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-10-29 16:09, Christian Schneider wrote:

 DStep was not very helpful when I tried it, it wanted to find all the
 referenced includes, which of course can be quite complicated when
 trying to get foundation and appkit headers processed.
How do you mean? That it can't find stdarg.h and other header files? I think that can be solved by passing "-include <umbrella_header.h>" when invoking DStep. The problem is that these header files are not meant to be processed individually, but rather as a whole, i.e a translation unit. In the future I hope to make it possible to use pass a framework to DStep and it will create bindings for the whole framework. -- /Jacob Carlborg
Oct 29 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 In the future I hope to make it possible to use pass a 
 framework to DStep and it will create bindings for the whole 
 framework.
That would be so cool! Btw, fixed the example, thanks for giving me the right clues. Of course, it was just the manual memory management à la Objective-C that was missing! I am really lucky that I spent already days, maybe weeks debugging retain / release / autorelease on many projects, so for me this will be peanuts! I just had a little flashback. I love ARC and am looking forward for D to feature it as well, but for now, manual memory management is really not the thing that will put me off. I have all the tools ready now! I can't believe how this all rocks ;)
Oct 29 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-10-29 22:51, Christian Schneider wrote:

 Btw, fixed the example, thanks for giving me the right clues. Of course,
 it was just the manual memory management à la Objective-C that was
 missing! I am really lucky that I spent already days, maybe weeks
 debugging retain / release / autorelease on many projects, so for me
 this will be peanuts! I just had a little flashback. I love ARC and am
 looking forward for D to feature it as well, but for now, manual memory
 management is really not the thing that will put me off.
I had a look at your fix. I see that you added a call to "release" in the destructor. Just for the record, there's no guarantee that the destructor of a GC allocated object gets run, at all. Or, if this class get instantiated by some Objective-C framework then it will know nothing about the destructor in D. I guess the right solution is to override "dealloc". Hmm, I'm wondering if it's a good idea to lower a destructor to "dealloc", just like a constructor is lowered to "init".
 I have all the tools ready now! I can't believe how this all rocks ;)
Awesome :) -- /Jacob Carlborg
Oct 30 2014
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 30 October 2014 at 07:13:09 UTC, Jacob Carlborg 
wrote:
 On 2014-10-29 22:51, Christian Schneider wrote:

 Btw, fixed the example, thanks for giving me the right clues. 
 Of course,
 it was just the manual memory management à la Objective-C that 
 was
 missing! I am really lucky that I spent already days, maybe 
 weeks
 debugging retain / release / autorelease on many projects, so 
 for me
 this will be peanuts! I just had a little flashback. I love 
 ARC and am
 looking forward for D to feature it as well, but for now, 
 manual memory
 management is really not the thing that will put me off.
I had a look at your fix. I see that you added a call to "release" in the destructor. Just for the record, there's no guarantee that the destructor of a GC allocated object gets run, at all.
Slightly derailing the conversation, but I see this all the time... Isn't the situation actually this: GC allocated objects are not guaranteed to be de-allocated before program termination. If a GC allocated object is deallocated, its destructor *is* guaranteed to be called. Except: Destructors are not called for arrays of objects, whether they are structs or emplaced classes, even when they are de-allocated.
Oct 30 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-10-30 10:23, John Colvin wrote:

 Slightly derailing the conversation, but I see this all the time...

 Isn't the situation actually this:

 GC allocated objects are not guaranteed to be de-allocated before
 program termination.
 If a GC allocated object is deallocated, its destructor *is* guaranteed
 to be called.
 Except:
 Destructors are not called for arrays of objects, whether they are
 structs or emplaced classes, even when they are de-allocated.
Yes, that's the longer explanation :) -- /Jacob Carlborg
Oct 30 2014
prev sibling next sibling parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 I had a look at your fix. I see that you added a call to 
 "release" in the destructor. Just for the record, there's no 
 guarantee that the destructor of a GC allocated object gets 
 run, at all.
Omg, how embarrassing ;) of course I need to put it in dealloc so that it will work with NSMutableArray et al. if I am going Objective-C memory management, then I should do it the intended way indeed!
 Or, if this class get instantiated by some Objective-C 
 framework then it will know nothing about the destructor in D. 
 I guess the right solution is to override "dealloc".
So far, I was not even considering a D library that would be used through Objective-C code, but yeah, that's a good point as well.
 Hmm, I'm wondering if it's a good idea to lower a destructor to 
 "dealloc", just like a constructor is lowered to "init".
We will have to find out, but dealloc definitely is the destructor in Objc.
Oct 30 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-10-30 16:28, Christian Schneider wrote:

 So far, I was not even considering a D library that would be used
 through Objective-C code, but yeah, that's a good point as well.
Isn't that what's usually happens when using something like an app delegate. It will be instantiated by the framework when loading a nib. -- /Jacob Carlborg
Oct 30 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
I have a question regarding selectors. I wanted to set a 
double-click action in the tableview example. Currently i get the 
selector like this:


     objc.runtime.SEL doubleAction = 
cast(objc.runtime.SEL)&AppDelegate.doubleClickAction ;
     demoTableView.setDoubleAction(doubleAction) ;


Is this the recommended/right way to do it?

Then the double-click action looks like this:


     void doubleClickAction(NSObject sender) {

	NSTableView tableView = cast(NSTableView)sender ;

	if (sender is demoTableView) {
	     NSInteger clickedRow = demoTableView.clickedRow() ;
	     Item item = 
cast(Item)_applications.objectAtIndex(clickedRow) ;
	     
NSWorkspace.sharedWorkspace().launchApplication(item.itemDisplayName()) 
;
	}
     }


I would expect to be using an ObjcObject instead of an NSObject 
here, but this does not compile. The signature of the target 
action seems to be irrelevant, it may have no or more parameters. 
I guess this is just ok and the expected behavior. In 
Objective-C, if the action signature does not comply you will get 
warnings or errors.
Nov 03 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-03 09:51, Christian Schneider wrote:
 I have a question regarding selectors. I wanted to set a double-click
 action in the tableview example. Currently i get the selector like this:


      objc.runtime.SEL doubleAction =
 cast(objc.runtime.SEL)&AppDelegate.doubleClickAction ;
      demoTableView.setDoubleAction(doubleAction) ;


 Is this the recommended/right way to do it?
No, have a look at the tests for selectors [1]. I'm not sure if you need to cast it to "SEL". Try just using "auto": auto doubleAction = &AppDelegate.doubleClickAction;
 Then the double-click action looks like this:


      void doubleClickAction(NSObject sender) {

      NSTableView tableView = cast(NSTableView)sender ;

      if (sender is demoTableView) {
           NSInteger clickedRow = demoTableView.clickedRow() ;
           Item item = cast(Item)_applications.objectAtIndex(clickedRow) ;
 NSWorkspace.sharedWorkspace().launchApplication(item.itemDisplayName()) ;
      }
      }


 I would expect to be using an ObjcObject instead of an NSObject here,
 but this does not compile. The signature of the target action seems to
 be irrelevant, it may have no or more parameters. I guess this is just
 ok and the expected behavior.
Hmm, that sounds strange. What exact errors do you get? [1] https://github.com/jacob-carlborg/dmd/blob/d-objc/test/runnable/objc/objc_selector.d -- /Jacob Carlborg
Nov 03 2014
next sibling parent "Christian Schneider" <schneider gerzonic.net> writes:
 I would expect to be using an ObjcObject instead of an 
 NSObject here,
 but this does not compile. The signature of the target action 
 seems to
 be irrelevant, it may have no or more parameters. I guess this 
 is just
 ok and the expected behavior.
Hmm, that sounds strange. What exact errors do you get?
source/appdelegate.d(47): Error: function appkit.tableview.NSTableView.setDoubleAction (objc_selector* aSelector) is not callable using argument types (extern (Objective-C) void __selector(ObjcObject)) Line 46 & 47: auto doubleAction = &AppDelegate.doubleClickAction ; demoTableView.setDoubleAction(doubleAction) ; Line 80: void doubleClickAction(ObjcObject sender) { actually, when line 46 & 47 are like above, it doesn't matter if I change ObjcObject to NSObject, but I guess my problem here is how Map the function in tableview.d: void setDoubleAction(objc.runtime.SEL aSelector) [setDoubleAction:] ;
 [1] 
 https://github.com/jacob-carlborg/dmd/blob/d-objc/test/runnable/objc/objc_selector.d
I know Dip 43 almost by heart now, but I haven't yet discovered the tests you wrote. Nice, this will be extremely helpful. Best!
Nov 04 2014
prev sibling next sibling parent reply "Christian Schneider" <schneider gerzonic.net> writes:
Ok, some more info:

I changed the mapping in tableview.d to:

void setDoubleAction(void __selector(ObjcObject))
[setDoubleAction:] ;

This should be the way to do it. Now in the implementation of the
action:

      void doubleClickAction(ObjcObject sender) {
          NSLog("double click action") ;
          NSLog("the sender: % ", sender) ;
      }

This works fine and prints the log:  2014-11-04 10:01:57.967
tableview[9988:507] the sender: <NSTableView: 0x7f8309f156b0>

But now I would like to do something with this sender, like I do
often in an Objective-C project:

NSTableView tableView = cast(NSTableView)sender ;

I get a  EXC_BAD_ACCESS (SIGSEGV) on this line. Only when I
replace both ObjcObject with NSObject (in tableview.d, the
mapping, and the target action) this cast works. I might be
missing something obvious here.

Thanks again.
Nov 04 2014
next sibling parent reply Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-11-04 09:07:08 +0000, "Christian Schneider" 
<schneider gerzonic.net> said:

 Ok, some more info:
 
 I changed the mapping in tableview.d to:
 
 void setDoubleAction(void __selector(ObjcObject))
 [setDoubleAction:] ;
That's indeed the best way to do it.
 This should be the way to do it. Now in the implementation of the
 action:
 
       void doubleClickAction(ObjcObject sender) {
           NSLog("double click action") ;
           NSLog("the sender: % ", sender) ;
       }
 
 This works fine and prints the log:  2014-11-04 10:01:57.967
 tableview[9988:507] the sender: <NSTableView: 0x7f8309f156b0>
 
 But now I would like to do something with this sender, like I do
 often in an Objective-C project:
 
 NSTableView tableView = cast(NSTableView)sender ;
 
 I get a  EXC_BAD_ACCESS (SIGSEGV) on this line. Only when I
 replace both ObjcObject with NSObject (in tableview.d, the
 mapping, and the target action) this cast works. I might be
 missing something obvious here.
There is no test for interface-to-class casts in the D/Objective-C test suite, which means you're likely the first person to try that. It's probably just an oversight in the compiler code. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Nov 04 2014
parent "Christian Schneider" <schneider gerzonic.net> writes:
 There is no test for interface-to-class casts in the 
 D/Objective-C test suite, which means you're likely the first 
 person to try that. It's probably just an oversight in the 
 compiler code.
Hey Michel, thanks very much for this explanation! That's actually good news. It certainly will be good to have this fixed, as the target action mechanism gets a lot of it's spice that the "sender" only needs to comply to a protocol and can be whatever control or even nil. Best! Christian
Nov 04 2014
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-04 10:07, Christian Schneider wrote:
 Ok, some more info:

 I changed the mapping in tableview.d to:

 void setDoubleAction(void __selector(ObjcObject))
 [setDoubleAction:] ;

 This should be the way to do it. Now in the implementation of the
 action:

       void doubleClickAction(ObjcObject sender) {
           NSLog("double click action") ;
           NSLog("the sender: % ", sender) ;
       }

 This works fine and prints the log:  2014-11-04 10:01:57.967
 tableview[9988:507] the sender: <NSTableView: 0x7f8309f156b0>

 But now I would like to do something with this sender, like I do
 often in an Objective-C project:

 NSTableView tableView = cast(NSTableView)sender ;

 I get a  EXC_BAD_ACCESS (SIGSEGV) on this line. Only when I
 replace both ObjcObject with NSObject (in tableview.d, the
 mapping, and the target action) this cast works. I might be
 missing something obvious here.
This should be fixed now in my forks [1] [2]. Note, I've also replaced the selector syntax, [foo], with a compiler recognized UDA, selector("foo"). [1] https://github.com/jacob-carlborg/dmd/tree/d-objc [2] https://github.com/jacob-carlborg/druntime/tree/d-objc -- /Jacob Carlborg
Dec 16 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 This should be fixed now in my forks [1] [2]. Note, I've also 
 replaced the selector syntax, [foo], with a compiler recognized 
 UDA,  selector("foo").

 [1] https://github.com/jacob-carlborg/dmd/tree/d-objc
 [2] https://github.com/jacob-carlborg/druntime/tree/d-objc
OMG, what did you do? all my beautiful appkit and foundation header files are destroyed! do you plan any other such attacks? lol, i must admit, i was a bit shocked about this sudden surprise. what is the main motivation? i thought the old style looked good because it made visually clear that it was glue into objective-c, as it looked very familiar. with a little scripting / string processing i can adapt to the new style, i guess.
Dec 17 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-12-17 20:51, Christian Schneider wrote:

 OMG, what did you do? all my beautiful appkit and foundation header
 files are destroyed! do you plan any other such attacks?
Hopefully no :)
 lol, i must admit, i was a bit shocked about this sudden surprise. what
 is the main motivation? i thought the old style looked good because it
 made visually clear that it was glue into objective-c, as it looked very
 familiar.
The reason for the change is that the old syntax, [foo:bar:], required language changes wheres the new syntax, selector("foo:bar:"), doesn't. When D/Objective-C was initially created D didn't support UDA's, that's why a new syntax was invented. If D had supported UDA's back then, that would most likely have been used. Hopefully this will also increase the chances of D/Objective-C being merged with upstream DMD.
 with a little scripting / string processing i can adapt to the
 new style, i guess.
I updated all the tests quickly with some global search and replace using regular expression. -- /Jacob Carlborg
Dec 18 2014
next sibling parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 The reason for the change is that the old syntax, [foo:bar:], 
 required language changes wheres the new syntax, 
  selector("foo:bar:"), doesn't. When D/Objective-C was 
 initially created D didn't support UDA's, that's why a new 
 syntax was invented. If D had supported UDA's back then, that 
 would most likely have been used.

 Hopefully this will also increase the chances of D/Objective-C 
 being merged with upstream DMD.
OK! Yes I understand, the merge with upstream DMD is one of the most important things, i totally agree.
 I updated all the tests quickly with some global search and 
 replace using regular expression.
Regex is one of my weaknesses. If you don't mind sharing yours (and if you have them still lying around) please send to schneider at gerzonic.net, this would be greatly appreciated, and would make my life a bit easier. this is all a great and exciting adventure ;)
Dec 18 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-12-18 23:31, Christian Schneider wrote:

 Regex is one of my weaknesses. If you don't mind sharing yours (and if
 you have them still lying around) please send to schneider at
 gerzonic.net, this would be greatly appreciated, and would make my life
 a bit easier.
These are two simple regular expression that you can use: \)\s*\[([\w:]+)\];$ Replace with ) selector("$1"); And \)\s*\[([\w:]+)\]$ Replace with ) selector("$1") They make some assumption about the code. They will match: a closing parenthesis -> zero or more spaces -> opening bracket -> at least one or more of: A-Z, a-z, a colon or 0-9 -> closing bracket -> semicolon -> end of line In the above description the arrow, "->", should be read as "followed by". When replacing the text, $1 will represent what's caught in the first group. In this case what's in between the brackets. The difference between the first and the second regular expression is the trailing semicolon, to handle both extern declarations and methods defined in the D source code. These regular expression assume you only have the selector on the right side of the method declaration, i.e. no UDA's or similar. -- /Jacob Carlborg
Dec 18 2014
parent "Christian Schneider" <schneider gerzonic.net> writes:
awesome, thank you very much!
Dec 21 2014
prev sibling next sibling parent reply "Christian Schneider" <schneider gerzonic.net> writes:
Just for my information: Why is it no longer possible to have 
multiple d methods (or overloaded constructors) to map to the 
same Objective-C implementation?

I though it was quite nice to have overloaded d constructors for 
the various init.. methods.
Dec 25 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-12-25 14:12, Christian Schneider wrote:
 Just for my information: Why is it no longer possible to have multiple d
 methods (or overloaded constructors) to map to the same Objective-C
 implementation?

 I though it was quite nice to have overloaded d constructors for the
 various init.. methods.
Can you give me an example of what's not working? -- /Jacob Carlborg
Dec 26 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
On Friday, 26 December 2014 at 17:47:29 UTC, Jacob Carlborg wrote:
 On 2014-12-25 14:12, Christian Schneider wrote:
 Just for my information: Why is it no longer possible to have 
 multiple d
 methods (or overloaded constructors) to map to the same 
 Objective-C
 implementation?

 I though it was quite nice to have overloaded d constructors 
 for the
 various init.. methods.
Can you give me an example of what's not working?
previously it was possible to have a few D methods "point" to the same Objective-C method like this: NSView initWithFrame(NSRect frameRect) selector("initWithFrame:") ; this(NSRect frameRect) selector("initWithFrame:") ; Now with the latest version I get this error for the above two lines: ../../Interfaces/appkit/view.d(19): Error: constructor appkit.view.NSView.this Objcective-C selector 'initWithFrame:' already in use by function 'initWithFrame'. I thought, it was a nice convenience to make both potential types of programmers happy, those leaning more towards Objective-C / named parameters can use the verbose, first option, while the ones coming more from C/C++ can use the shortcut, the 2nd option. But it's no big deal, I'll just remove the "shortcut". My question was more for understanding why it was a) possible in the past and b) what is the motivation behind the decision that it is no longer possible now.
Dec 29 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-12-29 20:01, Christian Schneider wrote:

 previously it was possible to have a few D methods "point" to the same
 Objective-C method like this:

      NSView initWithFrame(NSRect frameRect)  selector("initWithFrame:")  ;
      this(NSRect frameRect)  selector("initWithFrame:")  ;

 Now with the latest version I get this error for the above two lines:

 ../../Interfaces/appkit/view.d(19): Error: constructor
 appkit.view.NSView.this Objcective-C selector 'initWithFrame:' already
 in use by function 'initWithFrame'.

 I thought, it was a nice convenience to make both potential types of
 programmers happy, those leaning more towards Objective-C / named
 parameters can use the verbose, first option, while the ones coming more
 from C/C++ can use the shortcut, the 2nd option.

 But it's no big deal, I'll just remove the "shortcut".  My question was
 more for understanding why it was a) possible in the past and b) what is
 the motivation behind the decision that it is no longer possible now.
I'm not sure what's happened. Perhaps it's a bug that now have been fixed. I'll add it to my todo list. -- /Jacob Carlborg
Dec 29 2014
prev sibling parent reply "Christian Schneider" <schneider gerzonic.net> writes:
Was just upgrading everything to the latest Github, dmd, druntime 
(the d-objc branch). It does not seem to be able to link into the 
AppKit and Foundation anymore. dmd fails silently with error code 
-11

I uploaded a very stripped down project (containing everything) 
that you might want to have a look at, it just declares a 
NSString and tries to log it:

http://diveframework.com/files/supersimple.zip

dub -v gives really no clue whatsoever is failing. I am really 
sorry that I can not be more specific / helpful for making this 
work.
Dec 25 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-12-25 15:30, Christian Schneider wrote:
 Was just upgrading everything to the latest Github, dmd, druntime (the
 d-objc branch). It does not seem to be able to link into the AppKit and
 Foundation anymore. dmd fails silently with error code -11

 I uploaded a very stripped down project (containing everything) that you
 might want to have a look at, it just declares a NSString and tries to
 log it:

 http://diveframework.com/files/supersimple.zip

 dub -v gives really no clue whatsoever is failing. I am really sorry
 that I can not be more specific / helpful for making this work.
It's the destructor in NSObject that causes the problem. I'll take a look. Remove that and your example will work, after you import the missing "foundation.runtime" in "app". -- /Jacob Carlborg
Dec 26 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 It's the destructor in NSObject that causes the problem. I'll 
 take a look. Remove that and your example will work, after you 
 import the missing "foundation.runtime" in "app".
Once again, thank you very much for your help! It works now with the new selector style, and I would had the biggest problems finding out that it was the destructor making dmd bail out a -11. --- I just report another finding here. It's about properties and NSStrings. So far, it was possible to set the strings of an alert like this (source copied from the Chocolat example): auto alert = new NSAlert ; alert.messageText = "Want Chocolate?" ; alert.informativeText = "Chocolate is sweet." ; This now needs to be written like this: auto alert = new NSAlert ; alert.setMessageText("Want Chocolate?") ; alert.setInformativeText("Chocolate is sweet.") ; In the NSAlert class, the respective code is: extern (Objective-C) class NSAlert : NSObject { property { NSString messageText() ; void setMessageText(NSString text) selector("setMessageText:") ; NSString informativeText() ; void setInformativeText(NSString text) selector("setInformativeText:") ; } } Of course, the property read/write access style is again just a convenience, but for somebody coming from Objective-C, it is "natural" to do it either way.
Dec 29 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-12-29 22:39, Christian Schneider wrote:

 I just report another finding here. It's about properties and NSStrings.
 So far, it was possible to set the strings of an alert like this (source
 copied from the Chocolat example):

 auto alert = new NSAlert ;
 alert.messageText = "Want Chocolate?" ;
 alert.informativeText = "Chocolate is sweet." ;

 This now needs to be written like this:

 auto alert = new NSAlert ;
 alert.setMessageText("Want Chocolate?") ;
 alert.setInformativeText("Chocolate is sweet.") ;

 In the NSAlert class, the respective code is:

 extern (Objective-C)
 class NSAlert : NSObject {
     property {
      NSString messageText() ;
      void setMessageText(NSString text)  selector("setMessageText:")  ;

     NSString informativeText() ;
     void setInformativeText(NSString text)
  selector("setInformativeText:")  ;
    }
 }

 Of course, the property read/write access style is again just a
 convenience, but for somebody coming from Objective-C, it is "natural"
 to do it either way.
It might be some issue with properties. I'll have to look into that as well. D/Objective-C has some special treatment for properties. As a workaround you do one of the following alternatives: * Declare the method as "messageText" instead of "setMessageText" * Add a alias for "setMessageText" to "messageText" * Add a method, "messageText", that forwards to "setMessageText". Any D method that takes one argument can be called like a setter * Add an overload for "messageText" to take an argument as well You might need to drop property for some of these alternatives -- /Jacob Carlborg
Dec 31 2014
prev sibling parent reply "Christian Schneider" <schneider gerzonic.net> writes:
what is funky in this context (see above): even when using
ObjcObject in both the mapping and the action method, the test

if (sender is demoTableView) {
     //
}

does not fail in the action, only a cast to a NSTableView object
fails. Of course, in this setting it's not really a problem, I
can work directly on the demoTableView member and can forget
about the sender, but this is against how I would do it in
Objective-C where I can always cast an id reference to the
expected type.
Nov 04 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-04 13:29, Christian Schneider wrote:
 what is funky in this context (see above): even when using
 ObjcObject in both the mapping and the action method, the test

 if (sender is demoTableView) {
      //
 }

 does not fail in the action
That will just compare the address of the objects.
 , only a cast to a NSTableView object
 fails. Of course, in this setting it's not really a problem, I
 can work directly on the demoTableView member and can forget
 about the sender, but this is against how I would do it in
 Objective-C where I can always cast an id reference to the
 expected type.
See the reply by Michel. It's probably a bug/oversight in the compiler. As a workaround you can, as you said, use NSObject instead of ObjcObject in both places. What happens if you declare "doubleClickAction" like this: void doubleClickAction(NSTableView sender) { ... } That will probably require a cast when passing the selector to "setDoubleAction". -- /Jacob Carlborg
Nov 04 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 What happens if you declare "doubleClickAction" like this:

 void doubleClickAction(NSTableView sender) { ... }

 That will probably require a cast when passing the selector to 
 "setDoubleAction".
Hi Jacob This just "delegates" the "problem" to another place. The target/action paradigm in Cocoa programming gets a lot from the fact that any object can be the sender of an action. In this particular case I'd even prefer the conditional if the sender "is" the local table view member var, which then basically has the same effect as what you suggested above. I think the best thing will be to fix the interface-to-class casts in the compiler, as Michel suggests above. Thanks again Christian
Nov 05 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
Oh, just found out, it seems that currently the extern C 
declarations don't work. This comes from the original Chocolat 
range.d

extern (C) {
nothrow:

	NSRange  	NSUnionRange(NSRange range1, NSRange range2) ;
	NSRange  	NSIntersectionRange(NSRange range1, NSRange range2) ;
	NSString 	NSStringFromRange(NSRange range) ;
	NSRange  	NSRangeFromString(NSString aString) ;

	NSRange 	NSMakeRange(NSUInteger loc, NSUInteger len) ;
	NSUInteger 	NSMaxRange(NSRange range) ;
	bool 		NSEqualRanges(NSRange range1, NSRange range2) ;
}

When trying to use NSMakeRange i get:

Undefined symbols for architecture x86_64:
   "_NSMakeRange", referenced from: ....


Also when I tried to declare / use extern strings like from 
NSApplication.h:

APPKIT_EXTERN NSString *NSApplicationDidHideNotification;

I found no way to get this working. Is this a limitation of the 
current 64 bit port?

Thanks again. Christian
Nov 06 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-06 17:06, Christian Schneider wrote:
 Oh, just found out, it seems that currently the extern C declarations
 don't work. This comes from the original Chocolat range.d

 extern (C) {
 nothrow:

      NSRange      NSUnionRange(NSRange range1, NSRange range2) ;
      NSRange      NSIntersectionRange(NSRange range1, NSRange range2) ;
      NSString     NSStringFromRange(NSRange range) ;
      NSRange      NSRangeFromString(NSString aString) ;

      NSRange     NSMakeRange(NSUInteger loc, NSUInteger len) ;
      NSUInteger     NSMaxRange(NSRange range) ;
      bool         NSEqualRanges(NSRange range1, NSRange range2) ;
 }

 When trying to use NSMakeRange i get:

 Undefined symbols for architecture x86_64:
    "_NSMakeRange", referenced from: ....
I wasn't able to link with the symbol either. But when I tried in Objective-C it worked, but only when I imported Foundation.h, not when I declared NSMakeRange myself. That got me thinking and I had a look in the Foundation NSRange.h header file. "NSMakeRange" and friends are implement directly in the header file to allow inlining. D cannot access inlined functions if they don't exist in a library. In general you need to reimplement these functions in D. In this particular case, with NSMakeRange, you can just do this in D instead: auto range = NSRange(1, 2); The above is a syntax that is allowed for all structs. If you really want to type "NSMakeRange" you need implement the function yourself or make an alias and use the above syntax: alias NSMakeRange = NSRange; The downside with the alias is that it allows to use "NSMakeRange" as a struct as well: NSMakeRange range;
 Also when I tried to declare / use extern strings like from
 NSApplication.h:

 APPKIT_EXTERN NSString *NSApplicationDidHideNotification;

 I found no way to get this working. Is this a limitation of the current
 64 bit port?
I think that should work. How did you declare it? It should be declared like this: extern (C) extern NSString NSApplicationDidHideNotification; I tried with a standard D compiler and void* instead of NSString and that worked. "extern (C)" tells the compiler to use C linkage, the second "extern" tells the compiler this symbols is defined somewhere else, i.e. in some library. -- /Jacob Carlborg
Nov 06 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 Also when I tried to declare / use extern strings like from
 NSApplication.h:

 APPKIT_EXTERN NSString *NSApplicationDidHideNotification;

 I found no way to get this working. Is this a limitation of 
 the current
 64 bit port?
I think that should work. How did you declare it? It should be declared like this: extern (C) extern NSString NSApplicationDidHideNotification; I tried with a standard D compiler and void* instead of NSString and that worked. "extern (C)" tells the compiler to use C linkage, the second "extern" tells the compiler this symbols is defined somewhere else, i.e. in some library.
Jacob, thank you very much for your reply and explanations! I get EXC_BAD_ACCESS (SIGSEGV) for both NSString and void * if I use the declaration you suggested. In the case for notification string constants, when I log it in Objective-C, it just equals to "NSApplicationDidHideNotification", so these could be simply redeclared for such strings, but that's not very stylish and against the basic idea, i guess.
Nov 07 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-07 13:12, Christian Schneider wrote:

 Jacob, thank you very much for your reply and explanations!

 I get EXC_BAD_ACCESS (SIGSEGV) for both NSString and void * if I use the
 declaration you suggested.
What exactly are you doing with the string when you get the EXC_BAD_ACCESS? Also, can you reproduce the issue in an program just printing this variable with NSLog?
 In the case for notification string constants, when I log it in
 Objective-C, it just equals to "NSApplicationDidHideNotification", so
 these could be simply redeclared for such strings, but that's not very
 stylish and against the basic idea, i guess.
Yeah, that's not pretty, it should work like in Objective-C. -- /Jacob Carlborg
Nov 07 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 I get EXC_BAD_ACCESS (SIGSEGV) for both NSString and void * if 
 I use the
 declaration you suggested.
What exactly are you doing with the string when you get the EXC_BAD_ACCESS? Also, can you reproduce the issue in an program just printing this variable with NSLog?
I get the SIGSEGV when i try to NSLog this string constant. I was not looking any further, because if it fails to NSLog, i can't do anything with it ;)
Nov 07 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-07 15:23, Christian Schneider wrote:

 I get the SIGSEGV when i try to NSLog this string constant. I was not
 looking any further, because if it fails to NSLog, i can't do anything
 with it ;)
Now I know what the problem is. In D, module variables are by default in TLS (thread local storage). To make it refer to a global C variable, use __gshared: extern (C) extern __gshared NSString NSApplicationDidHideNotification; Sorry, I completely forgot about that. -- /Jacob Carlborg
Nov 07 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 Now I know what the problem is. In D, module variables are by 
 default in TLS (thread local storage). To make it refer to a 
 global C variable, use __gshared:

 extern (C) extern __gshared NSString 
 NSApplicationDidHideNotification;

 Sorry, I completely forgot about that.
Ha, awesome! It works! I'll add this to a wiki page in the DiveFramework github repos. Thanks again! Oh, and btw, I was briefly looking into the DMD source for trying to fix myself the issue with the protocol to class instance cast (trying to be useful), but I am seriously completely not hardcore enough of digging anything in there, lol. Anyhow, if you got a hint, let me know. It's not just in the example discussed in my other posts, I found it to be an issue in other places as well, as often framework classes return id / ObjcObject instead of a further typed instance. I don't remember where exactly I had a problem, but I remember I used NSObject instead of ObjcObject in these places, which of course is not the way to go. Have a nice weekend!
Nov 07 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-07 17:05, Christian Schneider wrote:

 Ha, awesome! It works! I'll add this to a wiki page in the DiveFramework
 github repos.

 Thanks again!
No problem :). This isn't mention in the DIP since this has nothing to do with Objective-C, it's rather plain C. This is documented here [1].
 Oh, and btw, I was briefly looking into the DMD source for trying to fix
 myself the issue with the protocol to class instance cast (trying to be
 useful), but I am seriously completely not hardcore enough of digging
 anything in there, lol.
I had no idea what I was doing when I started with this :)
 Anyhow, if you got a hint, let me know. It's not
 just in the example discussed in my other posts, I found it to be an
 issue in other places as well, as often framework classes return id /
 ObjcObject instead of a further typed instance. I don't remember where
 exactly I had a problem, but I remember I used NSObject instead of
 ObjcObject in these places, which of course is not the way to go.
I guess you have to live using NSObject for now, until I fixed that. But in practice NSObject is the only root class. So far I've seen one other class, NSProxy, that doesn't inherit from NSObject. Ok, I had a quick look at this issue. It is implemented but it's not working. There is a test but that's only casting from a class to an interface, not the other way around. Either there's an issue in the druntime function "_dobjc_interface_cast" or in the compiler (most likely in the compiler). It looks like the casting is implemented here [2], or at least parts of it. [1] http://dlang.org/interfaceToC.html [2] https://github.com/jacob-carlborg/dmd/blob/d-objc/src/e2ir.c#L3843-L3854 -- /Jacob Carlborg
Nov 07 2014
next sibling parent "Christian Schneider" <schneider gerzonic.net> writes:
 I guess you have to live using NSObject for now, until I fixed 
 that. But in practice NSObject is the only root class. So far 
 I've seen one other class, NSProxy, that doesn't inherit from 
 NSObject.

 Ok, I had a quick look at this issue. It is implemented but 
 it's not working. There is a test but that's only casting from 
 a class to an interface, not the other way around. Either 
 there's an issue in the druntime function 
 "_dobjc_interface_cast" or in the compiler (most likely in the 
 compiler).
OK, I see. I can live with that for now, it's just a bit unfortunate because then I will have to touch the interface headers again once it works. Just stumbled upon this thing once again while trying to use mutableCopy ;)
 It looks like the casting is implemented here [2], or at least 
 parts of it.
 [2] 
 https://github.com/jacob-carlborg/dmd/blob/d-objc/src/e2ir.c#L3843-L3854
whoa, thanks for that look deep into the abyss ;)
Nov 11 2014
prev sibling parent reply "Christian Schneider" <schneider gerzonic.net> writes:
I am just stumbling over adding class objects to an array:

I get an error when trying to add class objects to an NSArray 
because e.g. NSString.class does not conform to ObjcObject. There 
is some functions in the API that require arrays of class 
objects, e.g. in NSPasteboard:

NSPasteboard pb = NSPasteboard.generalPasteboard() ;
NSArray classes = NSArray.arrayWithObjects(NSString.class, 
NSAttributedString.class, null) ;
NSString pbItem = cast(NSString) 
pb.readObjectsForClasses_options(classes, null).lastObject() ;

Sure, there are other functions in NSPasteboard, and 
readObjectsForClasses_options is not the only way to get the 
pasteboard items, but a great convenience in given settings.
Nov 16 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-16 12:16, Christian Schneider wrote:
 I am just stumbling over adding class objects to an array:

 I get an error when trying to add class objects to an NSArray because
 e.g. NSString.class does not conform to ObjcObject. There is some
 functions in the API that require arrays of class objects, e.g. in
 NSPasteboard:

 NSPasteboard pb = NSPasteboard.generalPasteboard() ;
 NSArray classes = NSArray.arrayWithObjects(NSString.class,
 NSAttributedString.class, null) ;
 NSString pbItem = cast(NSString)
 pb.readObjectsForClasses_options(classes, null).lastObject() ;
Do you get a compile time error or runtime error? -- /Jacob Carlborg
Nov 17 2014
next sibling parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 Do you get a compile time error or runtime error?
Compiling using dmd... source/document.d(79): Error: function foundation.array.NSArray.arrayWithObjects (ObjcObject object, ...) is not callable using argument types (Class, Class, typeof(null)) compile time. hmm, a class object is of course not an ObjcObject, how could it be. I think here is a limit to what is possible, this is the darn id of Objective-C that makes all this funky convenience possible. Actually, it's not a big deal, there is other methods to get what you want and the above mentioned function in question is by itself just a convenience.
Nov 18 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-18 09:46, Christian Schneider wrote:

 Compiling using dmd...
 source/document.d(79): Error: function
 foundation.array.NSArray.arrayWithObjects (ObjcObject object, ...) is
 not callable using argument types (Class, Class, typeof(null))

 compile time.

 hmm, a class object is of course not an ObjcObject, how could it be. I
 think here is a limit to what is possible, this is the darn id of
 Objective-C that makes all this funky convenience possible. Actually,
 it's not a big deal, there is other methods to get what you want and the
 above mentioned function in question is by itself just a convenience.
Hmm, I don't know. Can you use a cast to get around the problem? Perhaps use a variadic template to make the API simpler. -- /Jacob Carlborg
Nov 18 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 Compiling using dmd...
 source/document.d(79): Error: function
 foundation.array.NSArray.arrayWithObjects (ObjcObject object, 
 ...) is
 not callable using argument types (Class, Class, typeof(null))
Hmm, I don't know. Can you use a cast to get around the problem? Perhaps use a variadic template to make the API simpler.
Yes, of course, and this is really not an issue! And this convenience function can be rewritten in a few lines of code, if really necessary.
Nov 18 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-11-18 21:46, Christian Schneider wrote:

 Yes, of course, and this is really not an issue! And this convenience
 function can be rewritten in a few lines of code, if really necessary.
Good, I just want to make sure you can continue. Than we can figure out the minor issues later. Anyway, I added it to my todo list. -- /Jacob Carlborg
Nov 18 2014
prev sibling parent reply "Christian Schneider" <schneider gerzonic.net> writes:
I'm wondering how I should deal with overriding "designated 
initailizers". I really have no clue about the part "self = 
[super...]. KeyboardView is a subclass of NSView.

 implementation KeyboardView

- (id)initWithFrame:(NSRect)frame {
     self = [super initWithFrame:frame];
     if (self) {
         // Initialization code here.
     }
     return self;
}
 end


This is what I came up with so far:

override KeyboardView initWithFrame(NSRect frame) 
[initWithFrame:] {
     //my stuff
     return cast(KeyboardView) super.initWithFrame(frame) ;
}

This compiles and does not throw any runtime error, but it's a 
bit against the idea, because in Objective-C the idea is to first 
call the super class, then adapt and override what is necessary. 
When calling super in the very end, this of course is no longer 
guaranteed.
Nov 18 2014
next sibling parent reply "Christian Schneider" <schneider gerzonic.net> writes:
Speaking of drawing, I have a very serious problem wit NSView. I 
cannot call frame() nor bounds() on instances or subclasses and 
get a valid NSRect. (same goes for NSWindow frame()).

I had similar problems when working with NSAttributedString and 
NSRange, because NSRange from Chocolat was still 32 bit. After 
fixing this, it all worked perfectly. The parameter to drawRect, 
which is a NSRect as well contains correct values. So it seems to 
me that the NSRect struct declared as is should work just fine.

I am trying to implement drawRect in an NSView subclass (in the 
Portmidi example, KeyboardView). Everything works fine, 
NSBezierPath drawing methods etc., but I cannot call this.frame() 
nor this.bounds() from within that method without triggering a 
runtime segmentation fault.  Often I see this in the crash log as 
last "message":

misaligned_stack_error_entering_dyld_stub_binder

Sometimes there is other stuff, but always indicating a memory 
corruption.

I have not the slightest idea what could be the problem here, it 
most likely is not a threading issue, as drawRect is anyway 
called on the main thread, and usually one only has crashes if 
one tries to update widgets from background threads, which of 
course is not allowed in Cocoa, as the AppKit is not thread safe.

I just checked back, for any widget it fails. You can easily 
reproduce it by e.g. opening the SimpleWebBrowser example and add 
in applicationDidFinishLaunching (this is a good point, because 
all the UI element should be ready):

NSRect backButtonFrame = backButton.frame() ;
NSLog("frame %f %f %f %f", backButtonFrame.origin.x, 
backButtonFrame.origin.y, backButtonFrame.size.width, 
backButtonFrame.size.height) ;

For custom components, if this won't work, it is almost a deal 
breaker for using Cocoa through D. This is quite a setback, all 
the rest so far encountered is working so beautifully.
Nov 18 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-18 13:47, Christian Schneider wrote:
 Speaking of drawing, I have a very serious problem wit NSView. I cannot
 call frame() nor bounds() on instances or subclasses and get a valid
 NSRect. (same goes for NSWindow frame()).

 I had similar problems when working with NSAttributedString and NSRange,
 because NSRange from Chocolat was still 32 bit. After fixing this, it
 all worked perfectly. The parameter to drawRect, which is a NSRect as
 well contains correct values. So it seems to me that the NSRect struct
 declared as is should work just fine.

 I am trying to implement drawRect in an NSView subclass (in the Portmidi
 example, KeyboardView). Everything works fine, NSBezierPath drawing
 methods etc., but I cannot call this.frame() nor this.bounds() from
 within that method without triggering a runtime segmentation fault.
 Often I see this in the crash log as last "message":

 misaligned_stack_error_entering_dyld_stub_binder

 Sometimes there is other stuff, but always indicating a memory corruption.
Could it be this issue [1]? Can you please see if you can reproduce it using just plain C. https://issues.dlang.org/show_bug.cgi?id=5570 -- /Jacob Carlborg
Nov 18 2014
parent reply "Christian Schneider" <schneider gerzonic.net> writes:
 Could it be this issue [1]? Can you please see if you can 
 reproduce it using just plain C.

 https://issues.dlang.org/show_bug.cgi?id=5570
Uh, oh, that bug looks like a major annoyance in 64bit! I made a few checks, all appkit methods returning a NSRect currently produce a runtime segfault. But this does not apply to NSSize, nor NSPoint, functions returning either NSSize or NSPoint work. What I have found out so far: all the extern C functions in geometry.d work just fine.. e.g. NSRectFromString does what it's supposed to do.
Nov 18 2014
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2014-11-18 21:54, Christian Schneider wrote:

 Uh, oh, that bug looks like a major annoyance in 64bit! I made a few
 checks, all appkit methods returning a NSRect currently produce a
 runtime segfault. But this does not apply to NSSize, nor NSPoint,
 functions returning either NSSize or NSPoint work.

 What I have found out so far: all the extern C functions in geometry.d
 work just fine.. e.g. NSRectFromString does what it's supposed to do.
If this is works for extern(C) functions then it might be a problem with the extern(Objective-C) functions. Perhaps it's not using the correct objc_msgSend functions under the hood. -- /Jacob Carlborg
Nov 18 2014
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-18 21:54, Christian Schneider wrote:

 Uh, oh, that bug looks like a major annoyance in 64bit! I made a few
 checks, all appkit methods returning a NSRect currently produce a
 runtime segfault. But this does not apply to NSSize, nor NSPoint,
 functions returning either NSSize or NSPoint work.

 What I have found out so far: all the extern C functions in geometry.d
 work just fine.. e.g. NSRectFromString does what it's supposed to do.
I forgot to ask, do you have a small test case showing this problem? Without windows or any other fancy stuff. -- /Jacob Carlborg
Nov 19 2014
parent "Christian Schneider" <schneider gerzonic.net> writes:
 I forgot to ask, do you have a small test case showing this 
 problem? Without windows or any other fancy stuff.
Just setup a small temporary repository for this: https://github.com/DiveFramework/FixingNSRect Without an OSX application with windows et al, it won't show you the "send bug report" dialog, this is where I found the other information. If you want to, you can open the most simple example in DiveFramework, e.g. OpenGLView and ask the main window for bounds or the frame. After a good night sleep, I came up with this: no way this can be a deal breaker, if push comes to shove I'll just create a small Framework containing wrapper functions with NSRect pointers for all the methods returning NSRect. Luckily, there are not too many of these. But still, they are extremely vital once you start messing with complicated gui stuff e.g. like darn NSScrollViews or even worse NSSplitViews. Thanks for having a look into this ;)
Nov 19 2014
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-18 10:07, Christian Schneider wrote:
 I'm wondering how I should deal with overriding "designated
 initailizers". I really have no clue about the part "self = [super...].
 KeyboardView is a subclass of NSView.

  implementation KeyboardView

 - (id)initWithFrame:(NSRect)frame {
      self = [super initWithFrame:frame];
      if (self) {
          // Initialization code here.
      }
      return self;
 }
  end


 This is what I came up with so far:

 override KeyboardView initWithFrame(NSRect frame) [initWithFrame:] {
      //my stuff
      return cast(KeyboardView) super.initWithFrame(frame) ;
 }

 This compiles and does not throw any runtime error, but it's a bit
 against the idea, because in Objective-C the idea is to first call the
 super class, then adapt and override what is necessary. When calling
 super in the very end, this of course is no longer guaranteed.
Can't you just call "super" in the beginning of the method and then call return "this" at the end. Something like this: override KeyboardView initWithFrame(NSRect frame) [initWithFrame:] { super.initWithFrame(frame); // my stuff return this; } -- /Jacob Carlborg
Nov 18 2014
parent "Christian Schneider" <schneider gerzonic.net> writes:
 Can't you just call "super" in the beginning of the method and 
 then call return "this" at the end. Something like this:

 override KeyboardView initWithFrame(NSRect frame) 
 [initWithFrame:] {
     super.initWithFrame(frame);
     // my stuff
     return this;
 }
Ups, sorry, my bad! I was trying this and had an exception, but not from the constructor! Of course this works just fine! Excuse me for the noise, I should remove my post (if I only could ;).
Nov 18 2014
prev sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2014-11-18 09:07:10 +0000, Christian Schneider said:

 This is what I came up with so far:
 
 override KeyboardView initWithFrame(NSRect frame) [initWithFrame:] {
      //my stuff
      return cast(KeyboardView) super.initWithFrame(frame) ;
 }
Why not use a constructor and let the compiler manage the boilerplate? this(NSRect frame) [initWithFrame:] { //my stuff super(frame); } This should emit the same code as the function above (but I haven't tested). And then you can write: auto view = new KeyboardView(someFrame); and have proper type safety. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Nov 20 2014
parent "Christian Schneider" <schneider gerzonic.net> writes:
 Why not use a constructor and let the compiler manage the 
 boilerplate?

 	this(NSRect frame) [initWithFrame:] {
 		//my stuff
 		super(frame);
 	}

 This should emit the same code as the function above (but I 
 haven't tested). And then you can write:

 	auto view = new KeyboardView(someFrame);

 and have proper type safety.
Thanks Michel, my question was based on a completely wrong assumption (really sorry, my bad), the code of course works, which is again really cool about the D/Objective-C bridging. When I prepare the framework glue headers I usually add both variations init.. and this(), so the coder who uses it can take the shortcut if he prefers. I try to stay as close as possible to the naming conventions of the Cocoa framework, it facilitates somewhat the documentation lookup in Xcode. Named parameters is probably the feature I like most about Objective-C, it makes the code so much more readable and auto-documents, if one is careful.
Nov 26 2014
prev sibling parent reply Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-10-30 07:13:08 +0000, Jacob Carlborg <doob me.com> said:

 I had a look at your fix. I see that you added a call to "release" in 
 the destructor. Just for the record, there's no guarantee that the 
 destructor of a GC allocated object gets run, at all.
D/Objective-C never allocates Objective-C objects on the GC heap. If an object derives from NSObject it is allocated using the usual Objective-C alloc class method when you use the "new" keyword.
 Or, if this class get instantiated by some Objective-C framework then 
 it will know nothing about the destructor in D. I guess the right 
 solution is to override "dealloc".
Whoever instantiated the object has no bearing on who will deallocate and call its destructor. When you call release() and the counter falls to zero, "dealloc" is called and the memory is then released. Whether that call to release() was made from D or Objective-C code is irrelevant.
 Hmm, I'm wondering if it's a good idea to lower a destructor to 
 "dealloc", just like a constructor is lowered to "init".
I can't remember if this is an oversight or just something that I hadn't got to yet. In my mind this was already done. Anyway, the answer is *yes*: the destructor should be mapped to the "dealloc" selector. It should also implicitly call the destructor for any struct within the object and call it's superclass's destructor (if present), the usual D semantics for a destructor (that part might already work actually). -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Oct 31 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-11-01 01:54, Michel Fortin wrote:

 I can't remember if this is an oversight or just something that I hadn't
 got to yet. In my mind this was already done.
I did a grep for "dealloc" and couldn't find anything related.
 Anyway, the answer is *yes*: the destructor should be mapped to the
 "dealloc" selector. It should also implicitly call the destructor for
 any struct within the object and call it's superclass's destructor (if
 present), the usual D semantics for a destructor (that part might
 already work actually).
-- /Jacob Carlborg
Nov 01 2014
prev sibling parent reply "Martin Nowak" <code dawg.eu> writes:
On Tuesday, 11 March 2014 at 18:23:08 UTC, Jacob Carlborg wrote:
 A DIP is available here [1] and the latest implementation is 
 available here [2].

 [1] http://wiki.dlang.org/DIP43
Instead of adding the selector syntaxsyntax you could reuse pragma mangle. extern (Objective-C) class NSComboBox : NSTextField { private void* _dataSource; pragma(mangle, objcMangle!(NSComboBox, "insertItemWithObjectValue", "atIndex") void insertItem(ObjcObject object, NSInteger value); } Alternatively a compiler recognized UDA would work too. objcSel!("insertItemWithObjectValue", "atIndex") void insertItem(ObjcObject object, NSInteger value); Changing the lexer and parser would affect all D language tools (editors, formatters, linters, other compilers). So now that we do have UDAs I don't see a justification for changing the syntax and grammar of D.
Oct 30 2014
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2014-10-30 10:16, Martin Nowak wrote:

 Instead of adding the selector syntaxsyntax you could reuse pragma mangle.

 extern (Objective-C)
 class NSComboBox : NSTextField
 {
      private void* _dataSource;

      pragma(mangle, objcMangle!(NSComboBox, "insertItemWithObjectValue",
 "atIndex")
      void insertItem(ObjcObject object, NSInteger value);
 }

 Alternatively a compiler recognized UDA would work too.

       objcSel!("insertItemWithObjectValue", "atIndex")
      void insertItem(ObjcObject object, NSInteger value);

 Changing the lexer and parser would affect all D language tools
 (editors, formatters, linters, other compilers). So now that we do have
 UDAs I don't see a justification for changing the syntax and grammar of D.
Seems like a fair point, I guess I could change that. I prefer using a UDA for this. -- /Jacob Carlborg
Oct 30 2014
prev sibling parent reply Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-10-30 09:16:34 +0000, "Martin Nowak" <code dawg.eu> said:

 On Tuesday, 11 March 2014 at 18:23:08 UTC, Jacob Carlborg wrote:
 A DIP is available here [1] and the latest implementation is available 
 here [2].
 
 [1] http://wiki.dlang.org/DIP43
Instead of adding the selector syntaxsyntax you could reuse pragma mangle.
Nooo! Mangling is something different from the selector name. Mangling is the linker symbol for the function. The selector is the name used to find the function pointer for a given a dynamic object (with similar purpose to a vtable offset). The function has both a mangled name and a selector name, and they're always two different names.
 Alternatively a compiler recognized UDA would work too.
 
       objcSel!("insertItemWithObjectValue", "atIndex")
      void insertItem(ObjcObject object, NSInteger value);
Ah, that's better. Except you really should use a single string with colons, otherwise you'll have a problem distinguishing no-parameter selectors from single-parameter selectors.
 Changing the lexer and parser would affect all D language tools 
 (editors, formatters, linters, other compilers). So now that we do have 
 UDAs I don't see a justification for changing the syntax and grammar of 
 D.
Very true. I agree. Now that UDAs exist, it'd be preferable to use them. That said, there are other parts of D/Objective-C that could pose difficulties to existing languages tools, some syntactic (__selector, or "this.class" to get the metaclass), some semantic (overridable static methods having a "this" pointing to the metaclass). I had to bend the rules in some places to make all that work. But it's true that nothing will be more confusing to those tools than the selector declaration currently following a function name. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Oct 31 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-11-01 01:58, Michel Fortin wrote:

 That said, there are other parts of D/Objective-C that could pose
 difficulties to existing languages tools, some syntactic (__selector, or
 "this.class" to get the metaclass)
"this.class" could perhaps be called "this.classof", at least that's valid syntax. Although I don't know what to do about __selector. -- /Jacob Carlborg
Nov 01 2014
parent reply Michel Fortin <michel.fortin michelf.ca> writes:
On 2014-11-01 10:47:54 +0000, Jacob Carlborg <doob me.com> said:

 On 2014-11-01 01:58, Michel Fortin wrote:
 
 That said, there are other parts of D/Objective-C that could pose
 difficulties to existing languages tools, some syntactic (__selector, or
 "this.class" to get the metaclass)
"this.class" could perhaps be called "this.classof", at least that's valid syntax. Although I don't know what to do about __selector.
Once this is merged in DMD, __selector could be documented to be syntactically identical to a delegate (although semantically different) and it could be made syntactically valid for regular D code compiled with no Objective-C support (although it'd remain semantically invalid). That'd allow you to hide it in version blocks and static ifs. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca
Nov 04 2014
parent Jacob Carlborg <doob me.com> writes:
On 2014-11-04 23:46, Michel Fortin wrote:

 Once this is merged in DMD, __selector could be documented to be
 syntactically identical to a delegate (although semantically different)
 and it could be made syntactically valid for regular D code compiled
 with no Objective-C support (although it'd remain semantically invalid).
 That'd allow you to hide it in version blocks and static ifs.
Yeah, that would be preferable. I would like to avoid the mess that the migration from D1 to D2 caused. Where if one wanted to support both some D2 code needed to be in a string mixin guarded with a version block. -- /Jacob Carlborg
Nov 04 2014