From f0291bfdf6548c62b039fa1c3e6771555781ed15 Mon Sep 17 00:00:00 2001 From: Laurent Sansonetti Date: Fri, 29 May 2009 04:32:50 +0000 Subject: [PATCH] define -allocWithZone: and not -alloc on every new Ruby class git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/branches/experimental@1629 23306eb0-4c56-4727-a40e-e92c0eb68959 --- class.c | 31 ++++++++++++++++--------------- id.c | 2 ++ id.h | 2 ++ objc.m | 4 +--- spec/macruby/core/object_spec.rb | 26 ++++++++++++++++++++++++++ spec/macruby/fixtures/object.m | 25 +++++++++++++++++++++++++ spec/macruby/fixtures/object.rb | 6 ++++++ 7 files changed, 78 insertions(+), 18 deletions(-) create mode 100644 spec/macruby/core/object_spec.rb create mode 100644 spec/macruby/fixtures/object.m create mode 100644 spec/macruby/fixtures/object.rb diff --git a/class.c b/class.c index 3d6b6e772..8e0216ec9 100644 --- a/class.c +++ b/class.c @@ -13,9 +13,10 @@ #include "ruby/signal.h" #include "ruby/node.h" #include "ruby/st.h" -#include "id.h" #include +#include "id.h" #include "vm.h" +#include "objc.h" extern st_table *rb_class_tbl; @@ -56,10 +57,10 @@ rb_objc_install_primitives(Class ocklass, Class ocsuper) return false; } -static VALUE -rb_class_allocate_instance(VALUE klass, SEL sel) +static void * +rb_obj_imp_allocWithZone(void *rcv, SEL sel, void *zone) { - return rb_robject_allocate_instance(klass); + return (void *)rb_robject_allocate_instance((VALUE)rcv); } static BOOL @@ -101,21 +102,21 @@ VALUE rb_class_new_instance_imp(VALUE klass, SEL sel, int argc, VALUE *argv); void rb_define_object_special_methods(VALUE klass) { - rb_objc_define_method(*(VALUE *)klass, "alloc", rb_class_allocate_instance, 0); - RCLASS_SET_VERSION(*(VALUE *)klass, (RCLASS_VERSION(*(VALUE *)klass) | RCLASS_HAS_ROBJECT_ALLOC)); - rb_objc_define_method(*(VALUE *)klass, "new", rb_class_new_instance_imp, -1); - rb_objc_define_method(*(VALUE *)klass, "__new__", rb_class_new_instance_imp, -1); + RCLASS_SET_VERSION(*(VALUE *)klass, + (RCLASS_VERSION(*(VALUE *)klass) | RCLASS_HAS_ROBJECT_ALLOC)); + + rb_objc_define_method(*(VALUE *)klass, "new", + rb_class_new_instance_imp, -1); + rb_objc_define_method(*(VALUE *)klass, "__new__", + rb_class_new_instance_imp, -1); rb_objc_define_method(klass, "dup", rb_obj_dup, 0); rb_objc_define_method(klass, "initialize", rb_objc_init, 0); rb_objc_define_method(klass, "initialize_copy", rb_obj_init_copy, 1); - static SEL sel_isEqual = 0; - if (sel_isEqual == 0) { - sel_isEqual = sel_registerName("isEqual:"); - } - class_addMethod((Class)klass, sel_isEqual, (IMP)rb_obj_imp_isEqual, "c@:@"); - - class_addMethod((Class)klass, selInit, (IMP)rb_obj_imp_init, "@@:"); + rb_objc_install_method(*(Class *)klass, selAllocWithZone, + (IMP)rb_obj_imp_allocWithZone); + rb_objc_install_method((Class)klass, selIsEqual, (IMP)rb_obj_imp_isEqual); + rb_objc_install_method((Class)klass, selInit, (IMP)rb_obj_imp_init); } static VALUE diff --git a/id.c b/id.c index 83b764cd4..95f072b49 100644 --- a/id.c +++ b/id.c @@ -61,6 +61,7 @@ Init_id(void) selSucc = sel_registerName("succ"); selNot = sel_registerName("!"); selAlloc = sel_registerName("alloc"); + selAllocWithZone = sel_registerName("allocWithZone:"); selInit = sel_registerName("init"); selInitialize = sel_registerName("initialize"); selInitialize2 = sel_registerName("initialize:"); @@ -89,6 +90,7 @@ Init_id(void) selBackquote = sel_registerName("`:"); selMethodAdded = sel_registerName("method_added:"); selSingletonMethodAdded = sel_registerName("singleton_method_added:"); + selIsEqual = sel_registerName("isEqual:"); cacheEach = rb_vm_get_call_cache(selEach); #endif diff --git a/id.h b/id.h index 249cacdcb..0253fd765 100644 --- a/id.h +++ b/id.h @@ -71,6 +71,7 @@ extern SEL selLength; extern SEL selSucc; extern SEL selNot; extern SEL selAlloc; +extern SEL selAllocWithZone; extern SEL selInit; extern SEL selInitialize; extern SEL selInitialize2; @@ -98,6 +99,7 @@ extern SEL selDup; extern SEL selBackquote; extern SEL selMethodAdded; extern SEL selSingletonMethodAdded; +extern SEL selIsEqual; extern ID idIncludedModules; extern ID idIncludedInClasses; extern ID idAncestors; diff --git a/objc.m b/objc.m index ac4dc2775..8fc5d2f44 100644 --- a/objc.m +++ b/objc.m @@ -417,7 +417,7 @@ - (VMURange)addressRange; } } -static void * +static void rb_objc_kvo_setter_imp(void *recv, SEL sel, void *value) { const char *selname; @@ -432,8 +432,6 @@ - (VMURange)addressRange; rb_ivar_set((VALUE)recv, rb_intern(buf), value == NULL ? Qnil : OC2RB(value)); - - return NULL; /* we explicitely return NULL because otherwise a special constant may stay on the stack and be returned to Objective-C, and do some very nasty crap, especially if called via -[performSelector:]. */ } /* diff --git a/spec/macruby/core/object_spec.rb b/spec/macruby/core/object_spec.rb new file mode 100644 index 000000000..67738864f --- /dev/null +++ b/spec/macruby/core/object_spec.rb @@ -0,0 +1,26 @@ +require File.dirname(__FILE__) + "/../spec_helper" +FixtureCompiler.require! "object" + +require File.join(FIXTURES, 'object') + +describe "A pure MacRuby Class" do +=begin # TODO + it "can be instantiated from Objective-C, using +[new]" do + o = TestObject.testNewObject(TestObjectPureMacRuby) + o.class.should == TestObjectPureMacRuby + o.initialized?.should == true + end +=end + + it "can be instantiated from Objective-C, using +[alloc] and -[init]" do + o = TestObject.testAllocInitObject(TestObjectPureMacRuby) + o.class.should == TestObjectPureMacRuby + o.initialized?.should == true + end + + it "can be instantiated from Objective-C, using +[allocWithZone:] and -[init]" do + o = TestObject.testAllocWithZoneInitObject(TestObjectPureMacRuby) + o.class.should == TestObjectPureMacRuby + o.initialized?.should == true + end +end diff --git a/spec/macruby/fixtures/object.m b/spec/macruby/fixtures/object.m new file mode 100644 index 000000000..0ef30c77f --- /dev/null +++ b/spec/macruby/fixtures/object.m @@ -0,0 +1,25 @@ +#import + +@interface TestObject : NSObject +@end + +@implementation TestObject + ++ (id)testNewObject:(Class)k +{ + return [k new]; +} + ++ (id)testAllocInitObject:(Class)k +{ + return [[k alloc] init]; +} + ++ (id)testAllocWithZoneInitObject:(Class)k +{ + return [[k allocWithZone:NULL] init]; +} + +@end + +void Init_object(void) {} diff --git a/spec/macruby/fixtures/object.rb b/spec/macruby/fixtures/object.rb new file mode 100644 index 000000000..4e7e54a8b --- /dev/null +++ b/spec/macruby/fixtures/object.rb @@ -0,0 +1,6 @@ +class TestObjectPureMacRuby + def initialize + @initialized = true + end + def initialized?; @initialized; end +end