[MacRuby-devel] experimental branch: status update
Laurent Sansonetti
lsansonetti at apple.com
Sat Jul 11 22:25:01 PDT 2009
Another update on the experimental branch!
Highlights are:
- A much better AOT (ahead-of-time) compiler, now available as a
separate command line executable, macrubyc. It can compile some
MacRuby sample code. Details at the very end of this message.
- IB support is back! Once you install experimental IB can show the
classes and their outlets/actions that you defined in your Ruby code,
inside Xcode, as previously. It still uses the same command line tool
based on Ripper.
- More Ruby and Cocoa compatibility.
Detailed changes:
- AOT compiler: added support for compilation of NSObject, IDs,
blocks, dynamic variables, instance variables, cleanup exception
handler, global variables, literal symbols & immediates,
- RubySpec was updated from upstream.
- Fixed a bug in the way we compile literal strings, before the same
instance was reused which was bad since strings are mutable.
- Implemented END{} blocks.
- Fixed a bug in IO.copy_stream, IO#print, implemented
IO#initialize_copy.
- Fixed lexical constant lookup inside classes defined within a
builtin class.
- The Ripper C extension is now supported again. It is built and
installed as part of the normal build process. First C extension on
experimental!
- Fixed a bug in the instance variable slot logic where it was only
called for T_OBJECT types.
- Added a workaround for missing 64-bit informal protocol annotations
in BridgeSupport.
- Installed a cleanup exception handler in macruby_main().
- Optimized dummy calls to <=>: inside the code base.
- Mark thread block locals as used. This fixes a bug where a thread's
block was using a local variable right after the method exited.
- Implemented the internal rb_rescue() and rb_ensure() APIs.
- Implemented ThreadGroup.
- Re-implemented return-from-block to use a specialized C++ exception
instead of SjLj. This is to make sure ensure blocks are honored, to
conform to the Ruby specs.
- Force the installation of the static .a library within
MacRuby.framework (for AOT compiler).
- Fixed the setting of $? post a popen-based expression.
- Removed the --compile command line argument from the macruby
executable, added the --emit-llvm argument which dumps the LLVM
bitcode. This is only for internal use, users should use the new
macrubyc executable instead.
- Introducing macrubyc, a command line tool interface to the AOT
compiler.
macrubyc allows you to compile a given Ruby file into a Mach-O object
file and/or produce a final executable.
Produced Mach-O objects are true object files. They can be used to
form a MacRuby executable or you can also use them into your Objective-
C project that uses the MacRuby Objective-C API.
Produced executables embed all the compiled Ruby code as well as
MacRuby, statically. It can be distributed as is and does not depend
on anything MacRuby or LLVM at runtime. The Ruby source code is
compiled into native machine code (same process as we do at runtime
with the JIT compiler), so it's also a good way to obfuscate the
source code. The final binary looks like an Objective-C binary (except
that it's larger).
macrubyc behaves like gcc.
An example:
$ echo 'p 123' > t1.rb
$ echo 'p 456' > t2.rb
$ macrubyc -c t1.rb -o t1.o
$ macrubyc -c t2.rb -o t2.o
$ macrubyc t1.o t2.o -o t
$ ./t
123
456
Which can be rewritten in a shorter form:
$ macrubyc t1.rb t2.rb -o t
$ ./t
123
456
Ruby files are loaded using the link order.
You can also provide any .o file during link time. Example:
$ cat t.m
#import <Foundation/Foundation.h>
@interface Foo : NSObject
@end
@implementation Foo
+ (void)foo { NSLog(@"foo"); }
@end
$ gcc -c t.m -o t.o -fobjc-gc
$ cat t2.rb
Foo.foo
$ macrubyc t.o t2.rb -o t
$ ./t
2009-07-11 22:04:37.229 t[12964:903] foo
Here, we link a Ruby source file with a pure Objective-C source file
and it works.
macrubyc is still very preliminary but it can compile a few samples
that we ship, like DotView or PathDemo (I did not try all of them yet).
We will provide an Xcode target to automatize the compilation of a
MacRuby Xcode project, but in the meantime you can try the command
line. An example for PathDemo:
$ cd build/Release/PathDemo.app/Contents/Resources/
$ cat prelude.rb
framework 'Cocoa'
$ cat main.rb
NSApplicationMain(0, nil)
$ macrubyc prelude.rb DemoView.rb PathDemoController.rb main.rb -o ../
MacOS/PathDemo
$ rm *.o *.rb
As you can see, here we created 2 additional files, prelude.rb and
main.rb. prelude.rb loads the Cocoa framework and is passed as the 1st
object, which means it will be executed at the very first time. This
is needed since you want the framework to be loaded before executing
code that would use it. main.rb just calls the Cocoa run loop, we pass
it at the very end since this is a blocking call.
Current issues:
- It is very preliminary. Lots of bugs and only a portion of the Ruby
AST is supported. The goal is to provide 2 modes: normal and full.
Only the normal mode is being implemented right now.
The normal mode will support the entire Ruby specification, compile
input source files into machine code, and still use LLVM at runtime to
generate stubs. This will be the preferred way to compile desktop
applications. Startup time will be very good (almost like Objective-C)
and the entire source code will be compiled.
The full mode will compile everything statically and will not generate
any code at runtime. Only a subset of the Ruby specification will be
supported, and the final binary will not contain LLVM. This can be
used when you want a very light application and/or if the environment
does not support runtime code generation.
- It can only produce 64-bit binaries for now. Universal binary
support will come in the future.
- It heavily depends on the linker ordering in order to initialize
things. macrubyc might expose a way to call a "main" method that you
would define in Ruby, after doing all the initializations.
If you have any comment, criticism or suggestion please do not
hesitate. This is all shiny and we have the time to iterate on it :-)
Laurent
More information about the MacRuby-devel
mailing list