[macruby-changes] [3474] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Tue Feb 9 22:38:40 PST 2010
Revision: 3474
http://trac.macosforge.org/projects/ruby/changeset/3474
Author: lsansonetti at 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)
{
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100209/c78dd4b9/attachment-0001.html>
More information about the macruby-changes
mailing list