Revision: 3474 http://trac.macosforge.org/projects/ruby/changeset/3474 Author: lsansonetti@apple.com Date: 2010-02-09 22:38:36 -0800 (Tue, 09 Feb 2010) Log Message: ----------- cleaning a bit public headers, added support for methods defined for the MRI ABI (using rb_define_method & friends), removed unused code Modified Paths: -------------- MacRuby/trunk/MacRuby.m MacRuby/trunk/class.c MacRuby/trunk/compiler.cpp MacRuby/trunk/compiler.h MacRuby/trunk/dir.c MacRuby/trunk/gc.c MacRuby/trunk/include/ruby/intern.h MacRuby/trunk/include/ruby/node.h MacRuby/trunk/include/ruby/ruby.h MacRuby/trunk/marshal.c MacRuby/trunk/objc.h MacRuby/trunk/proc.c MacRuby/trunk/spec/macruby/spec_helper.rb MacRuby/trunk/variable.c MacRuby/trunk/vm.cpp MacRuby/trunk/vm_method.c Added Paths: ----------- MacRuby/trunk/spec/macruby/core/mri_abi_spec.rb MacRuby/trunk/spec/macruby/fixtures/mri_abi.m Modified: MacRuby/trunk/MacRuby.m =================================================================== --- MacRuby/trunk/MacRuby.m 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/MacRuby.m 2010-02-10 06:38:36 UTC (rev 3474) @@ -1,8 +1,18 @@ +/* + * MacRuby Objective-C API. + * + * This file is covered by the Ruby license. See COPYING for more details. + * + * Copyright (C) 2009-2010, Apple Inc. All rights reserved. + */ + #import <Foundation/Foundation.h> + #include "ruby/ruby.h" #include "ruby/node.h" #include "ruby/objc.h" #include "vm.h" +#include "objc.h" @implementation MacRuby Modified: MacRuby/trunk/class.c =================================================================== --- MacRuby/trunk/class.c 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/class.c 2010-02-10 06:38:36 UTC (rev 3474) @@ -1033,13 +1033,31 @@ } NODE *body = rb_vm_cfunc_node_from_imp((Class)klass, arity, (IMP)imp, noex); - rb_objc_retain(body); + GC_RETAIN(body); rb_vm_define_method((Class)klass, name_to_sel(name, arity), (IMP)imp, body, direct); } +void *rb_vm_generate_mri_stub(void *imp, const int arity); + +static void +rb_add_mri_method(VALUE klass, const char *name, void *imp, const int arity, + const int noex) +{ + imp = rb_vm_generate_mri_stub(imp, arity); + rb_objc_add_method(klass, name, imp, arity, noex, false); +} + void +rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE)) +{ + Check_Type(klass, T_CLASS); + rb_add_mri_method(rb_singleton_class(klass), "alloc", func, 0, + NOEX_PUBLIC); +} + +void rb_objc_define_direct_method(VALUE klass, const char *name, void *imp, const int arity) { @@ -1068,27 +1086,40 @@ } void +rb_undef_alloc_func(VALUE klass) +{ + // TODO +#if 0 + Check_Type(klass, T_CLASS); + rb_add_mri_method(rb_singleton_class(klass), ID_ALLOCATOR, 0, NOEX_UNDEF); +#endif +} + +void rb_define_method_id(VALUE klass, ID name, VALUE (*func)(ANYARGS), int argc) { - rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC); + rb_add_mri_method(klass, rb_id2name(name), func, argc, NOEX_PUBLIC); } void -rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) +rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), + int argc) { - rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PUBLIC); + rb_add_mri_method(klass, name, func, argc, NOEX_PUBLIC); } void -rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) +rb_define_protected_method(VALUE klass, const char *name, + VALUE (*func)(ANYARGS), int argc) { - rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PROTECTED); + rb_add_mri_method(klass, name, func, argc, NOEX_PROTECTED); } void -rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) +rb_define_private_method(VALUE klass, const char *name, + VALUE (*func)(ANYARGS), int argc) { - rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE); + rb_add_mri_method(klass, name, func, argc, NOEX_PRIVATE); } void @@ -1162,13 +1193,15 @@ } void -rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc) +rb_define_singleton_method(VALUE obj, const char *name, + VALUE (*func)(ANYARGS), int argc) { rb_define_method(rb_singleton_class(obj), name, func, argc); } void -rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc) +rb_define_module_function(VALUE module, const char *name, + VALUE (*func)(ANYARGS), int argc) { rb_define_private_method(module, name, func, argc); rb_define_singleton_method(module, name, func, argc); Modified: MacRuby/trunk/compiler.cpp =================================================================== --- MacRuby/trunk/compiler.cpp 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/compiler.cpp 2010-02-10 06:38:36 UTC (rev 3474) @@ -7321,6 +7321,82 @@ } Function * +RoxorCompiler::compile_mri_stub(void *imp, const int arity) +{ + if (arity == 0) { + // ABI matches if arity is 0. + // MacRuby: VALUE foo(VALUE rcv, SEL sel); + // MRI: VALUE foo(VALUE rcv); + return NULL; + } + + // Prepare function type for the stub. + std::vector<const Type *> stub_types; + stub_types.push_back(RubyObjTy); // self + stub_types.push_back(PtrTy); // SEL + if (arity == -2) { + stub_types.push_back(RubyObjTy); // ary + } + else if (arity == -1) { + stub_types.push_back(Int32Ty); // argc + stub_types.push_back(RubyObjPtrTy); // argv + } + else { + assert(arity > 0); + for (int i = 0; i < arity; i++) { + stub_types.push_back(RubyObjTy); // arg... + } + } + + // Create the stub. + FunctionType *ft = FunctionType::get(RubyObjTy, stub_types, false); + Function *f = cast<Function>(module->getOrInsertFunction("", ft)); + bb = BasicBlock::Create(context, "EntryBlock", f); + Function::arg_iterator arg = f->arg_begin(); + Value *rcv = arg++; + arg++; // skip SEL + + // Prepare function types for the MRI implementation and arguments. + std::vector<const Type *> imp_types; + std::vector<Value *> params; + if (arity == -2) { + imp_types.push_back(RubyObjTy); // self + imp_types.push_back(RubyObjTy); // ary + params.push_back(rcv); + params.push_back(arg++); + } + else if (arity == -1) { + imp_types.push_back(Int32Ty); // argc + imp_types.push_back(RubyObjPtrTy); // argv + imp_types.push_back(RubyObjTy); // self + params.push_back(arg++); + params.push_back(arg++); + params.push_back(rcv); + } + else { + assert(arity > 0); + imp_types.push_back(RubyObjTy); // self + params.push_back(rcv); + for (int i = 0; i < arity; i++) { + imp_types.push_back(RubyObjTy); // arg... + params.push_back(arg++); + } + } + + // Cast the given MRI implementation. + FunctionType *imp_ft = FunctionType::get(RubyObjTy, imp_types, false); + Value *imp_val = new BitCastInst(compile_const_pointer(imp), + PointerType::getUnqual(imp_ft), "", bb); + + // Call the MRI implementation and return its value. + CallInst *imp_call = CallInst::Create(imp_val, params.begin(), + params.end(), "", bb); + ReturnInst::Create(context, imp_call, bb); + + return f; +} + +Function * RoxorCompiler::compile_to_rval_convertor(const char *type) { // VALUE foo(void *ocval); Modified: MacRuby/trunk/compiler.h =================================================================== --- MacRuby/trunk/compiler.h 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/compiler.h 2010-02-10 06:38:36 UTC (rev 3474) @@ -57,6 +57,7 @@ Function *compile_objc_stub(Function *ruby_func, IMP ruby_imp, const rb_vm_arity_t &arity, const char *types); Function *compile_block_caller(rb_vm_block_t *block); + Function *compile_mri_stub(void *imp, const int arity); const Type *convert_type(const char *type); Modified: MacRuby/trunk/dir.c =================================================================== --- MacRuby/trunk/dir.c 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/dir.c 2010-02-10 06:38:36 UTC (rev 3474) @@ -675,7 +675,7 @@ // chdir_thread = Qnil; dir_chdir(args->old_path); } - rb_objc_release((const void *)args->old_path); + GC_RELEASE(args->old_path); return Qnil; } @@ -747,7 +747,7 @@ VALUE cwd = my_getcwd(); args.old_path = cwd; - rb_objc_retain((const void *)args.old_path); + GC_RETAIN(args.old_path); args.new_path = path; args.done = Qfalse; return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args); Modified: MacRuby/trunk/gc.c =================================================================== --- MacRuby/trunk/gc.c 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/gc.c 2010-02-10 06:38:36 UTC (rev 3474) @@ -295,13 +295,13 @@ const void * rb_objc_retain_ni(const void *addr) { - return rb_objc_retain(addr); + return rb_objc_retain((void *)addr); } const void * rb_objc_release_ni(const void *addr) { - return rb_objc_release(addr); + return rb_objc_release((void *)addr); } void Modified: MacRuby/trunk/include/ruby/intern.h =================================================================== --- MacRuby/trunk/include/ruby/intern.h 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/include/ruby/intern.h 2010-02-10 06:38:36 UTC (rev 3474) @@ -259,12 +259,10 @@ typedef VALUE (*rb_alloc_func_t)(VALUE); void rb_define_alloc_func(VALUE, rb_alloc_func_t); void rb_undef_alloc_func(VALUE); -rb_alloc_func_t rb_get_alloc_func(VALUE); void rb_clear_cache(void); void rb_clear_cache_by_class(VALUE); void rb_alias(VALUE, ID, ID); void rb_attr(VALUE,ID,int,int,int); -int rb_method_boundp(VALUE, ID, int); VALUE rb_eval_cmd(VALUE, VALUE, int); bool rb_obj_respond_to(VALUE, ID, bool); bool rb_respond_to(VALUE, ID); @@ -286,8 +284,6 @@ int rb_proc_arity(VALUE); VALUE rb_binding_new(void); VALUE rb_method_call(VALUE, SEL, int, VALUE*); -int rb_mod_method_arity(VALUE, ID); -int rb_obj_method_arity(VALUE, ID); VALUE rb_protect(VALUE (*)(VALUE), VALUE, int*); void rb_mark_end_proc(void); void rb_exec_end_proc(void); @@ -335,8 +331,6 @@ void rb_objc_gc_unregister_thread(void); void rb_objc_set_associative_ref(void *, void *, void *); void *rb_objc_get_associative_ref(void *, void *); -const void *rb_objc_retain(const void *); -const void *rb_objc_release(const void *); # define rb_gc_mark_locations(x,y) # define rb_mark_tbl(x) # define rb_mark_set(x) Modified: MacRuby/trunk/include/ruby/node.h =================================================================== --- MacRuby/trunk/include/ruby/node.h 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/include/ruby/node.h 2010-02-10 06:38:36 UTC (rev 3474) @@ -503,17 +503,8 @@ NODE *rb_compile_string(const char*, VALUE, int); NODE *rb_compile_file(const char*, VALUE, int); -void rb_add_method(VALUE, ID, NODE *, int); -void rb_add_method_direct(VALUE, ID, NODE *); -#if WITH_OBJC -void rb_objc_register_ruby_method(VALUE, ID, NODE *); -NODE *rb_objc_method_node(VALUE, ID, IMP *, SEL *); -NODE *rb_objc_method_node2(VALUE, SEL, IMP *); -NODE *rb_objc_method_node3(IMP); -#endif NODE *rb_node_newnode(enum node_type,VALUE,VALUE,VALUE); -NODE* rb_method_node(VALUE klass, ID id); int rb_node_arity(NODE* node); struct global_entry *rb_global_entry(ID); Modified: MacRuby/trunk/include/ruby/ruby.h =================================================================== --- MacRuby/trunk/include/ruby/ruby.h 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/include/ruby/ruby.h 2010-02-10 06:38:36 UTC (rev 3474) @@ -1194,73 +1194,7 @@ return k != NULL && (RCLASS_VERSION(k) & RCLASS_IS_OBJECT_SUBCLASS) != RCLASS_IS_OBJECT_SUBCLASS; } #define NATIVE(obj) (rb_is_native((VALUE)obj)) - -VALUE rb_box_fixnum(VALUE); -VALUE rb_box_fixfloat(VALUE); - -static inline id -rb_rval_to_ocid(VALUE obj) -{ - if (SPECIAL_CONST_P(obj)) { - if (obj == Qtrue) { - return (id)kCFBooleanTrue; - } - if (obj == Qfalse) { - return (id)kCFBooleanFalse; - } - if (obj == Qnil) { - return (id)kCFNull; - } - if (FIXNUM_P(obj)) { - return (id)rb_box_fixnum(obj); - } - if (FIXFLOAT_P(obj)) { - return (id)rb_box_fixfloat(obj); - } - } - return (id)obj; -} - -static inline VALUE -rb_ocid_to_rval(id obj) -{ - if (obj == (id)kCFBooleanTrue) { - return Qtrue; - } - if (obj == (id)kCFBooleanFalse) { - return Qfalse; - } - if (obj == (id)kCFNull || obj == nil) { - return Qnil; - } - if (*(Class *)obj == (Class)rb_cFixnum) { - return LONG2FIX(RFIXNUM(obj)->value); - } -#if 0 // XXX this does not seem to be needed - if (*(Class *)obj == (Class)rb_cFloat) { - extern VALUE rb_float_new(double); - return rb_float_new(RFLOAT(obj)->float_value); - } #endif - if (*(Class *)obj == (Class)rb_cCFNumber) { - /* TODO NSNumber should implement the Numeric primitive methods */ - if (CFNumberIsFloatType((CFNumberRef)obj)) { - double v; - assert(CFNumberGetValue((CFNumberRef)obj, kCFNumberDoubleType, &v)); - extern VALUE rb_float_new(double); - return rb_float_new(v); - } - else { - long v; - assert(CFNumberGetValue((CFNumberRef)obj, kCFNumberLongType, &v)); - return LONG2FIX(v); - } - } - return (VALUE)obj; -} -#define RB2OC(obj) (rb_rval_to_ocid((VALUE)obj)) -#define OC2RB(obj) (rb_ocid_to_rval((id)obj)) -#endif static force_inline VALUE rb_class_of(VALUE obj) @@ -1368,22 +1302,21 @@ CLASS_OF(INT2FIX(0)); } -static inline int +static inline bool rb_special_const_p(VALUE obj) { - if (SPECIAL_CONST_P(obj)) return Qtrue; - return Qfalse; + return SPECIAL_CONST_P(obj) ? Qtrue : Qfalse; } #if !defined(__AUTO_ZONE__) -# include <malloc/malloc.h> -typedef void *auto_zone_t; -boolean_t auto_zone_set_write_barrier(auto_zone_t *zone, const void *dest, const void *new_value); -void auto_zone_add_root(auto_zone_t *zone, void *address_of_root_ptr, void *value); -void auto_zone_retain(auto_zone_t *zone, void *ptr); -unsigned int auto_zone_release(auto_zone_t *zone, void *ptr); -#endif +boolean_t auto_zone_set_write_barrier(void *zone, const void *dest, const void *new_value); +void auto_zone_add_root(void *zone, void *address_of_root_ptr, void *value); +void auto_zone_retain(void *zone, void *ptr); +unsigned int auto_zone_release(void *zone, void *ptr); +extern void *__auto_zone; +#else extern auto_zone_t *__auto_zone; +#endif #define GC_WB(dst, newval) \ do { \ @@ -1407,25 +1340,25 @@ } #define GC_ROOT(addr) (rb_objc_root((void *)addr)) -static inline const void * -rb_objc_retain(const void *addr) +static inline void * +rb_objc_retain(void *addr) { if (addr != NULL && !SPECIAL_CONST_P(addr)) { - auto_zone_retain(__auto_zone, (void *)addr); + auto_zone_retain(__auto_zone, addr); } return addr; } -#define GC_RETAIN(obj) (rb_objc_retain((const void *)obj)) +#define GC_RETAIN(obj) (rb_objc_retain((void *)obj)) -static inline const void * -rb_objc_release(const void *addr) +static inline void * +rb_objc_release(void *addr) { if (addr != NULL && !SPECIAL_CONST_P(addr)) { - auto_zone_release(__auto_zone, (void *)addr); + auto_zone_release(__auto_zone, addr); } return addr; } -#define GC_RELEASE(obj) (rb_objc_release((const void *)obj)) +#define GC_RELEASE(obj) (rb_objc_release((void *)obj)) #if RUBY_INCLUDED_AS_FRAMEWORK #include <MacRuby/ruby/missing.h> Modified: MacRuby/trunk/marshal.c =================================================================== --- MacRuby/trunk/marshal.c 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/marshal.c 2010-02-10 06:38:36 UTC (rev 3474) @@ -113,6 +113,13 @@ st_foreach(tbl, mark_marshal_compat_i, 0); } +static rb_alloc_func_t +rb_get_alloc_func(VALUE klass) +{ + // TODO... or is this really needed... + return NULL; +} + void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE), VALUE (*loader)(VALUE, VALUE)) { Modified: MacRuby/trunk/objc.h =================================================================== --- MacRuby/trunk/objc.h 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/objc.h 2010-02-10 06:38:36 UTC (rev 3474) @@ -15,22 +15,10 @@ #include "bs.h" -struct rb_objc_method_sig { - const char *types; - unsigned int argc; -}; - bool rb_objc_get_types(VALUE recv, Class klass, SEL sel, Method m, bs_element_method_t *bs_method, char *buf, size_t buflen); -VALUE rb_objc_call(VALUE recv, SEL sel, int argc, VALUE *argv); - -VALUE rb_objc_call2(VALUE recv, VALUE klass, SEL sel, IMP imp, - struct rb_objc_method_sig *sig, bs_element_method_t *bs_method, - int argc, VALUE *argv); - void rb_objc_define_kvo_setter(VALUE klass, ID mid); -void rb_objc_change_ruby_method_signature(VALUE mod, ID mid, VALUE sig); static inline IMP rb_objc_install_method(Class klass, SEL sel, IMP imp) @@ -179,6 +167,73 @@ return arity; } +VALUE rb_box_fixnum(VALUE); +VALUE rb_box_fixfloat(VALUE); + +static inline id +rb_rval_to_ocid(VALUE obj) +{ + if (SPECIAL_CONST_P(obj)) { + if (obj == Qtrue) { + return (id)kCFBooleanTrue; + } + if (obj == Qfalse) { + return (id)kCFBooleanFalse; + } + if (obj == Qnil) { + return (id)kCFNull; + } + if (FIXNUM_P(obj)) { + return (id)rb_box_fixnum(obj); + } + if (FIXFLOAT_P(obj)) { + return (id)rb_box_fixfloat(obj); + } + } + return (id)obj; +} + +static inline VALUE +rb_ocid_to_rval(id obj) +{ + if (obj == (id)kCFBooleanTrue) { + return Qtrue; + } + if (obj == (id)kCFBooleanFalse) { + return Qfalse; + } + if (obj == (id)kCFNull || obj == nil) { + return Qnil; + } + if (*(Class *)obj == (Class)rb_cFixnum) { + return LONG2FIX(RFIXNUM(obj)->value); + } +#if 0 // XXX this does not seem to be needed + if (*(Class *)obj == (Class)rb_cFloat) { + extern VALUE rb_float_new(double); + return rb_float_new(RFLOAT(obj)->float_value); + } +#endif + if (*(Class *)obj == (Class)rb_cCFNumber) { + /* TODO NSNumber should implement the Numeric primitive methods */ + if (CFNumberIsFloatType((CFNumberRef)obj)) { + double v; + assert(CFNumberGetValue((CFNumberRef)obj, kCFNumberDoubleType, &v)); + extern VALUE rb_float_new(double); + return rb_float_new(v); + } + else { + long v; + assert(CFNumberGetValue((CFNumberRef)obj, kCFNumberLongType, &v)); + return LONG2FIX(v); + } + } + return (VALUE)obj; +} + +#define RB2OC(obj) (rb_rval_to_ocid((VALUE)obj)) +#define OC2RB(obj) (rb_ocid_to_rval((id)obj)) + #if defined(__cplusplus) } #endif Modified: MacRuby/trunk/proc.c =================================================================== --- MacRuby/trunk/proc.c 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/proc.c 2010-02-10 06:38:36 UTC (rev 3474) @@ -1233,19 +1233,6 @@ return INT2FIX(n); } -int -rb_mod_method_arity(VALUE mod, ID id) -{ - NODE *node = rb_method_node(mod, id); - return rb_node_arity(node); -} - -int -rb_obj_method_arity(VALUE obj, ID id) -{ - return rb_mod_method_arity(CLASS_OF(obj), id); -} - /* * call-seq: * meth.to_s => string Added: MacRuby/trunk/spec/macruby/core/mri_abi_spec.rb =================================================================== --- MacRuby/trunk/spec/macruby/core/mri_abi_spec.rb (rev 0) +++ MacRuby/trunk/spec/macruby/core/mri_abi_spec.rb 2010-02-10 06:38:36 UTC (rev 3474) @@ -0,0 +1,76 @@ +require File.dirname(__FILE__) + "/../spec_helper" +FixtureCompiler.require! "mri_abi" + +describe "A method written for the MRI ABI" do + before :each do + @o = MRI_ABI_TEST.new + @helper = proc { |*a| a.map { |x| x.object_id.to_s }.join('') } + end + + it "with arity 0 can be called" do + @o.test_arity0.should == @helper[@o] + end + + it "with arity 1 can be called" do + arg1 = Object.new + @o.test_arity1(arg1).should == @helper[@o, arg1] + end + + it "with arity 2 can be called" do + arg1 = Object.new + arg2 = Object.new + @o.test_arity2(arg1, arg2).should == @helper[@o, arg1, arg2] + end + + it "with arity 3 can be called" do + arg1 = Object.new + arg2 = Object.new + arg3 = Object.new + @o.test_arity3(arg1, arg2, arg3).should == @helper[@o, arg1, arg2, arg3] + end + + it "with arity 4 can be called" do + arg1 = Object.new + arg2 = Object.new + arg3 = Object.new + arg4 = Object.new + @o.test_arity4(arg1, arg2, arg3, arg4).should == @helper[@o, arg1, arg2, arg3, arg4] + end + + it "with arity 5 can be called" do + arg1 = Object.new + arg2 = Object.new + arg3 = Object.new + arg4 = Object.new + arg5 = Object.new + @o.test_arity5(arg1, arg2, arg3, arg4, arg5).should == @helper[@o, arg1, arg2, arg3, arg4, arg5] + end + + it "with arity -1 can be called" do + arg1 = Object.new + arg2 = Object.new + arg3 = Object.new + arg4 = Object.new + arg5 = Object.new + @o.test_arity_m1.should == @helper[@o] + @o.test_arity_m1(arg1).should == @helper[@o, arg1] + @o.test_arity_m1(arg1, arg2).should == @helper[@o, arg1, arg2] + @o.test_arity_m1(arg1, arg2, arg3).should == @helper[@o, arg1, arg2, arg3] + @o.test_arity_m1(arg1, arg2, arg3, arg4).should == @helper[@o, arg1, arg2, arg3, arg4] + @o.test_arity_m1(arg1, arg2, arg3, arg4, arg5).should == @helper[@o, arg1, arg2, arg3, arg4, arg5] + end + + it "with arity -2 can be called" do + arg1 = Object.new + arg2 = Object.new + arg3 = Object.new + arg4 = Object.new + arg5 = Object.new + @o.test_arity_m2.should == @helper[@o] + @o.test_arity_m2(arg1).should == @helper[@o, arg1] + @o.test_arity_m2(arg1, arg2).should == @helper[@o, arg1, arg2] + @o.test_arity_m2(arg1, arg2, arg3).should == @helper[@o, arg1, arg2, arg3] + @o.test_arity_m2(arg1, arg2, arg3, arg4).should == @helper[@o, arg1, arg2, arg3, arg4] + @o.test_arity_m2(arg1, arg2, arg3, arg4, arg5).should == @helper[@o, arg1, arg2, arg3, arg4, arg5] + end +end Added: MacRuby/trunk/spec/macruby/fixtures/mri_abi.m =================================================================== --- MacRuby/trunk/spec/macruby/fixtures/mri_abi.m (rev 0) +++ MacRuby/trunk/spec/macruby/fixtures/mri_abi.m 2010-02-10 06:38:36 UTC (rev 3474) @@ -0,0 +1,101 @@ +#import <MacRuby/MacRuby.h> + +static VALUE +ocid_str(VALUE obj) +{ + char buf[64]; + snprintf(buf, sizeof buf, "%ld", obj); + return rb_str_new2(buf); +} + +static VALUE +test_arity0(VALUE rcv) +{ + return ocid_str(rcv); +} + +static VALUE +test_arity1(VALUE rcv, VALUE arg1) +{ + VALUE str = ocid_str(rcv); + rb_str_concat(str, ocid_str(arg1)); + return str; +} + +static VALUE +test_arity2(VALUE rcv, VALUE arg1, VALUE arg2) +{ + VALUE str = ocid_str(rcv); + rb_str_concat(str, ocid_str(arg1)); + rb_str_concat(str, ocid_str(arg2)); + return str; +} + +static VALUE +test_arity3(VALUE rcv, VALUE arg1, VALUE arg2, VALUE arg3) +{ + VALUE str = ocid_str(rcv); + rb_str_concat(str, ocid_str(arg1)); + rb_str_concat(str, ocid_str(arg2)); + rb_str_concat(str, ocid_str(arg3)); + return str; +} + +static VALUE +test_arity4(VALUE rcv, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4) +{ + VALUE str = ocid_str(rcv); + rb_str_concat(str, ocid_str(arg1)); + rb_str_concat(str, ocid_str(arg2)); + rb_str_concat(str, ocid_str(arg3)); + rb_str_concat(str, ocid_str(arg4)); + return str; +} + +static VALUE +test_arity5(VALUE rcv, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5) +{ + VALUE str = ocid_str(rcv); + rb_str_concat(str, ocid_str(arg1)); + rb_str_concat(str, ocid_str(arg2)); + rb_str_concat(str, ocid_str(arg3)); + rb_str_concat(str, ocid_str(arg4)); + rb_str_concat(str, ocid_str(arg5)); + return str; +} + +static VALUE +test_arity_m1(int argc, VALUE *argv, VALUE rcv) +{ + VALUE str = ocid_str(rcv); + int i; + for (i = 0; i < argc; i++) { + rb_str_concat(str, ocid_str(argv[i])); + } + return str; +} + +static VALUE +test_arity_m2(VALUE rcv, VALUE argv) +{ + VALUE str = ocid_str(rcv); + int i; + for (i = 0; i < RARRAY_LEN(argv); i++) { + rb_str_concat(str, ocid_str(rb_ary_entry(argv, i))); + } + return str; +} + +void +Init_mri_abi(void) +{ + VALUE klass = rb_define_class("MRI_ABI_TEST", rb_cObject); + rb_define_method(klass, "test_arity0", test_arity0, 0); + rb_define_method(klass, "test_arity1", test_arity1, 1); + rb_define_method(klass, "test_arity2", test_arity2, 2); + rb_define_method(klass, "test_arity3", test_arity3, 3); + rb_define_method(klass, "test_arity4", test_arity4, 4); + rb_define_method(klass, "test_arity5", test_arity5, 5); + rb_define_method(klass, "test_arity_m1", test_arity_m1, -1); + rb_define_method(klass, "test_arity_m2", test_arity_m2, -2); +} Modified: MacRuby/trunk/spec/macruby/spec_helper.rb =================================================================== --- MacRuby/trunk/spec/macruby/spec_helper.rb 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/spec/macruby/spec_helper.rb 2010-02-10 06:38:36 UTC (rev 3474) @@ -9,8 +9,8 @@ end FRAMEWORKS = %w{ Foundation } - ARCHS = %w{ i386 x86_64 ppc } - OPTIONS = %w{ -g -dynamiclib -fobjc-gc } + ARCHS = %w{ i386 x86_64 } + OPTIONS = %w{ -g -dynamiclib -fobjc-gc -Wl,-undefined,dynamic_lookup } GCC = "/usr/bin/gcc" attr_reader :gcc, :frameworks, :archs, :options Modified: MacRuby/trunk/variable.c =================================================================== --- MacRuby/trunk/variable.c 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/variable.c 2010-02-10 06:38:36 UTC (rev 3474) @@ -20,14 +20,14 @@ static const void * retain_cb(CFAllocatorRef allocator, const void *v) { - rb_objc_retain(v); + GC_RETAIN(v); return v; } static void release_cb(CFAllocatorRef allocator, const void *v) { - rb_objc_release(v); + GC_RELEASE(v); } static void Modified: MacRuby/trunk/vm.cpp =================================================================== --- MacRuby/trunk/vm.cpp 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/vm.cpp 2010-02-10 06:38:36 UTC (rev 3474) @@ -2226,10 +2226,6 @@ flags, true); } -static rb_vm_method_node_t * __rb_vm_define_method(Class klass, SEL sel, - IMP objc_imp, IMP ruby_imp, const rb_vm_arity_t &arity, int flags, - bool direct); - #define VISI(x) ((x)&NOEX_MASK) #define VISI_CHECK(x,f) (VISI(x) == (f)) @@ -2654,6 +2650,18 @@ rb_vm_define_method(klass, sel, imp, body, false); } +extern "C" +void * +rb_vm_generate_mri_stub(void *imp, const int arity) +{ + Function *func = RoxorCompiler::shared->compile_mri_stub(imp, arity); + if (func == NULL) { + // Not needed! + return imp; + } + return (void *)GET_CORE()->compile(func); +} + void RoxorCore::undef_method(Class klass, SEL sel) { Modified: MacRuby/trunk/vm_method.c =================================================================== --- MacRuby/trunk/vm_method.c 2010-02-10 02:35:37 UTC (rev 3473) +++ MacRuby/trunk/vm_method.c 2010-02-10 06:38:36 UTC (rev 3474) @@ -8,109 +8,6 @@ static ID eqq, each, aref, aset, match, missing; static ID added, singleton_added; -void -rb_add_method(VALUE klass, ID mid, NODE * node, int noex) -{ - // TODO - return; -} - -void -rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE)) -{ - // TODO -#if 0 - Check_Type(klass, T_CLASS); - rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, NEW_CFUNC(func, 0), - NOEX_PUBLIC); -#endif -} - -void -rb_undef_alloc_func(VALUE klass) -{ - // TODO -#if 0 - Check_Type(klass, T_CLASS); - rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, 0, NOEX_UNDEF); -#endif -} - -rb_alloc_func_t -rb_get_alloc_func(VALUE klass) -{ - NODE *n; - Check_Type(klass, T_CLASS); - n = rb_method_node(CLASS_OF(klass), ID_ALLOCATOR); - if (!n) return 0; - if (nd_type(n) != NODE_METHOD) return 0; - n = n->nd_body; - if (nd_type(n) != NODE_CFUNC) return 0; - return (rb_alloc_func_t)n->nd_cfnc; -} - -static NODE * -search_method(VALUE klass, ID id, VALUE *klassp) -{ - NODE *node; - if (klass == 0) { - return NULL; - } - node = rb_method_node(klass, id); - if (node != NULL) { - if (klassp != NULL) { /* TODO honour klassp */ - *klassp = klass; - } - } - return node; -} - -/* - * search method body (NODE_METHOD) - * with : klass and id - * without : method cache - * - * if you need method node with method cache, use - * rb_method_node() - */ -NODE * -rb_get_method_body(VALUE klass, ID id, ID *idp) -{ - return search_method(klass, id, NULL); -} - -NODE * -rb_method_node(VALUE klass, ID id) -{ - return NULL; -#if 0 // TODO - NODE *node = rb_objc_method_node(klass, id, NULL, NULL); - if (node == NULL && id != ID_ALLOCATOR) { - const char *id_str = rb_id2name(id); - size_t slen = strlen(id_str); - - if (strcmp(id_str, "retain") == 0 - || strcmp(id_str, "release") == 0 - || strcmp(id_str, "zone") == 0) { - char buf[100]; - snprintf(buf, sizeof buf, "__rb_%s__", id_str); - return rb_method_node(klass, rb_intern(buf)); - } - else { - if (id_str[slen - 1] == ':') { - return NULL; - } - else { - char buf[100]; - snprintf(buf, sizeof buf, "%s:", id_str); - return rb_method_node(klass, rb_intern(buf)); - } - } - } - return node; -#endif -} - static void remove_method(VALUE klass, ID mid) { @@ -231,20 +128,6 @@ node->flags |= flags; } -int -rb_method_boundp(VALUE klass, ID id, int ex) -{ - NODE *method; - - if ((method = rb_method_node(klass, id)) != 0) { - if (ex && (method->nd_noex & NOEX_PRIVATE)) { - return Qfalse; - } - return Qtrue; - } - return Qfalse; -} - void rb_attr(VALUE klass, ID id, int read, int write, int ex) {
participants (1)
-
source_changes@macosforge.org