Re: [nu] The cblock Macro Does Not Work (#31)

70 views
Skip to first unread message

Philip White

unread,
Jan 11, 2012, 11:55:59 AM1/11/12
to ksjogo, Programming Nu
Hi,

I've been looking into this and while I'm not sure what the problem is, I am going to rewrite part of the code to use some relevant run-time functions which became available in Lion. These functions allow for the graceful creation of blocks from functions and I hope will eliminate the iOS problem.

More to come,
Philip

On Jan 11, 2012, at 10:50 AM, ksjogo wrote:

> iOS has some cBlock issue at the moment too: http://groups.google.com/group/programming-nu/browse_thread/thread/b819d3e56cef2949
>
> ---
> Reply to this email directly or view it on GitHub:
> https://github.com/timburks/nu/issues/31#issuecomment-3449515

Philip White

unread,
Jan 11, 2012, 1:21:30 PM1/11/12
to Sorin Ionescu, Programming Nu
It looks like MacRuby uses BridgeSupport to determine the signatures of blocks passed as arguments to Cocoa methods. So I suppose that could be done so the programmer doesn't have to manually input the signature.

Making NuBlock a subclass of a obj-c block class (presumably NSMallocBlock) sounds a little hairy. Is that what MacRuby does?. Alternately, when Nu finds that the user is passing an object to a method expecting a block, it could see if the object implements a method (say -cBlock) and, if so, call that method and pass the return value instead of the original object.

Along with this, the (do ...) syntax could be extended to allow the user to input type information. If information is not included for any argument, id can be assumed, similar to declaring instance and class methods in nu. This info would then be used if the NuBlock were passed to a method expecting an obj-c block. That would avoid the complexity of using BridgeSupport while eliminating the separate cblock macro. To my mind, that seems the best solution.

Does MacRuby allow objc-blocks to be used as Ruby blocks? I don't see a lot of utility in this, though perhaps it could be useful. Are there any Cocoa or GCD methods that return objc-blocks?

-Philip


On Jan 11, 2012, at 11:41 AM, Sorin Ionescu wrote:

> Objective-C blocks are implemented through NSGlobalBlock, NSStackBlock, and NSMallocBlock. So why not have NuBlock extend the Objective-C block classes? Instead of bridging, you can just downcast and upcast between a NuBlock and an Objective-C block automatically.


>
> ---
> Reply to this email directly or view it on GitHub:

> https://github.com/timburks/nu/issues/31#issuecomment-3450354

jogo

unread,
Feb 20, 2012, 5:42:27 AM2/20/12
to Programming Nu
The automatic conversion with type info in do sounds great.
Any success with the lion apis?

Philip White

unread,
Feb 20, 2012, 8:30:48 AM2/20/12
to program...@googlegroups.com
Hi,
Sorry, I haven't had a chance to delve into this too deeply. It turns out that the API functions I had found didn't do exactly what I was hoping. They were for generating functions from blocks, not the other way around, which is what would have been useful in the Nu. If you have a chance, could you send me a little Xcode project that demonstrates the nu blocks crashing on the iPhone? I'm guessing the problem has to do with how the block objects are laid out in memory on the ARM architecture.
I don't have an iOS developer license yet, but I will be getting one very soon, and that should enable me to work on this problem a little better.

Thanks,
Philip

On Feb 20, 2012, at 4:42 AM, jogo wrote:

> The automatic conversion with type info in do sounds great.
> Any success with the lion apis?
>

> --
> You received this message because you are subscribed to the Google Groups "Programming Nu" group.
> To post to this group, send email to program...@googlegroups.com.
> To unsubscribe from this group, send email to programming-n...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/programming-nu?hl=en.
>

jogo

unread,
Feb 20, 2012, 9:34:18 AM2/20/12
to Programming Nu
No problem:
https://github.com/ksjogo/NuBlockCrash
I just took the default "Empty application template" and added Nu.[hm]
and ffi.[cHs] to it and called the block in AppDelegate.
The strange thing is, that it works in Simulator and on Device while
debugging with lldb/gdb.

ksjogo

unread,
Apr 7, 2012, 6:28:57 PM4/7/12
to program...@googlegroups.com
HI, I further digged around a bit but sadly I am not all into libffi and trying to apply things from the following sources did not work out for me:
Here Mike Ash is talking a lot about creating blocks on the run:
http://www.mikeash.com/pyblog/friday-qa-2011-05-06-a-tour-of-mablockclosure.html

Closure Allocation
libffi has changed how it deals with closures over time. Originally, closures had to be allocated by the calling code. This chunk of memory was then passed to libffi which did its thing. Afterwards, the client had to mark that code as executable. The version of libffi which ships with Mac OS X works this way. Newer versions of libffi encapsulate all of this in calls to allocate, prepare, and deallocate closures. This is what you'll get if you build libffi from source, and it's what you can get on iOS.
It looks like Nu is using the old style, perhaps the closure allocation from libffi would help.

Further he states here:
https://github.com/mikeash/MABlockClosure

Due to iOS not supporting the creation of executable data, standard libffi closures don't work there. Landon Fuller has developed a fork of libffi that uses some crazy dirty tricks to work around this, and MABlockClosure works with this fork. This requires building a custom libffi, but iOS doesn't even offer libffi anyway, so this would be required either way.

Note that libffi closures on iOS are highly experimental and you should tread with caution. They have worked well in limited testing so far, but be prepared for trouble.

Interesting post too:
http://landonf.bikemonkey.org/code/objc/imp_implementationWithBlock.20110413.html

Philip White

unread,
Apr 7, 2012, 6:39:39 PM4/7/12
to Programming Nu
Well that certainly explains why the block bridge isn't working on iOS. Maybe just using that fork of libffi is all that's needed to solve the problem. 

-Philip

--
You received this message because you are subscribed to the Google Groups "Programming Nu" group.
To view this discussion on the web visit https://groups.google.com/d/msg/programming-nu/-/hlO_1PXRN7sJ.

ksjogo

unread,
Apr 8, 2012, 7:00:30 AM4/8/12
to program...@googlegroups.com
Somehow the universe wants to get this fixed, yesterday working iOS 5.1 has been pulled into the "official" libffi.
https://github.com/atgreen/libffi/issues/7#issuecomment-5003785
https://github.com/atgreen/libffi/pull/15

My steps for the new libffi so far:
git clone https://github.com/atgreen/libffi.git libffi
cd libffi
chmod +x generate-ios-source-and-headers.py
./generate-ios-source-and-headers.py
import the .xcodeproj into a iOS window template project with Nu.hm added 
add a header search path for libffi/ios/include
It will compile fine for iOS and Simulator.
But for some reason running instanceMethods will cause an error on free(method_list).
Uncommenting free will result in a working NuInit and cBlock call in Simulator.
On Device it will EXC_BAD_ACCESS at ffi_prep_closure(closure, cif, objc_calling_nu_block_handler, userdata), maybe we need to port these calls to the ffi alloc closure as stated here: http://www.mikeash.com/pyblog/friday-qa-2011-05-06-a-tour-of-mablockclosure.html

ksjogo

unread,
Apr 8, 2012, 8:01:23 AM4/8/12
to program...@googlegroups.com
Yeah, finally I got them working on iOS,
this is the new code of construct_block_handler aufter ffi_prep_cif:

void* funcPtr;
ffi_closure* closure =    ffi_closure_alloc(sizeof(ffi_closure), &funcPtr);
ffi_prep_closure_loc(closure, cif, objc_calling_nu_block_handler, userdata, funcPtr);
return funcPtr;

Works great so far.
Now I have to clean up my mess, add some error checking and find a way to package it nicely into Nu.

ksjogo

unread,
Apr 8, 2012, 9:23:53 AM4/8/12
to program...@googlegroups.com
FFI-Update integreated into NuApp:
https://github.com/ksjogo/nu/tree/ffi-update
I decided to keep the ffi files for the moment in their own project and created a static NuTouch Library Target for inclusion in other project.
Maybe ffi could get amalgamated too.
The new ffi closures are #ifdef for iOS only because the Mac framework does not support them.
I am going to add some more cBlock tests this evening.
Maybe creating a static Mac Library too.
Is there any reason we do not have statics yet?
Reply all
Reply to author
Forward
0 new messages