Skip to content

Commit

Permalink
define -allocWithZone: and not -alloc on every new Ruby class
Browse files Browse the repository at this point in the history
  • Loading branch information
lrz committed May 29, 2009
1 parent 1d49107 commit f0291bf
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 18 deletions.
31 changes: 16 additions & 15 deletions class.c
Expand Up @@ -13,9 +13,10 @@
#include "ruby/signal.h"
#include "ruby/node.h"
#include "ruby/st.h"
#include "id.h"
#include <ctype.h>
#include "id.h"
#include "vm.h"
#include "objc.h"

extern st_table *rb_class_tbl;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions id.c
Expand Up @@ -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:");
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions id.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 1 addition & 3 deletions objc.m
Expand Up @@ -417,7 +417,7 @@ - (VMURange)addressRange;
}
}

static void *
static void
rb_objc_kvo_setter_imp(void *recv, SEL sel, void *value)
{
const char *selname;
Expand All @@ -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:]. */
}

/*
Expand Down
26 changes: 26 additions & 0 deletions 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
25 changes: 25 additions & 0 deletions spec/macruby/fixtures/object.m
@@ -0,0 +1,25 @@
#import <Foundation/Foundation.h>

@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) {}
6 changes: 6 additions & 0 deletions spec/macruby/fixtures/object.rb
@@ -0,0 +1,6 @@
class TestObjectPureMacRuby
def initialize
@initialized = true
end
def initialized?; @initialized; end
end

0 comments on commit f0291bf

Please sign in to comment.