Revision: 1078 http://trac.macosforge.org/projects/ruby/changeset/1078 Author: lsansonetti@apple.com Date: 2009-03-22 20:31:59 -0700 (Sun, 22 Mar 2009) Log Message: ----------- fixed bugs in singleton method definition + added tests (one is still failing though) Modified Paths: -------------- MacRuby/branches/experimental/class.c MacRuby/branches/experimental/roxor.cpp MacRuby/branches/experimental/test_roxor.rb Modified: MacRuby/branches/experimental/class.c =================================================================== --- MacRuby/branches/experimental/class.c 2009-03-23 02:53:19 UTC (rev 1077) +++ MacRuby/branches/experimental/class.c 2009-03-23 03:31:59 UTC (rev 1078) @@ -1131,12 +1131,15 @@ rb_bug("unknown immediate %ld", obj); } +#if 0 DEFER_INTS; if (RCLASS_SINGLETON(RBASIC(obj)->klass) && rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) { klass = RBASIC(obj)->klass; } - else { + else +#endif + { switch (TYPE(obj)) { case T_CLASS: case T_MODULE: @@ -1155,8 +1158,10 @@ OBJ_UNTAINT(klass); } #endif - if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); - ALLOW_INTS; + if (OBJ_FROZEN(obj)) { + OBJ_FREEZE(klass); + } +// ALLOW_INTS; return klass; } Modified: MacRuby/branches/experimental/roxor.cpp =================================================================== --- MacRuby/branches/experimental/roxor.cpp 2009-03-23 02:53:19 UTC (rev 1077) +++ MacRuby/branches/experimental/roxor.cpp 2009-03-23 03:31:59 UTC (rev 1078) @@ -281,6 +281,7 @@ Value *compile_ivar_assignment(ID vid, Value *val); Value *compile_current_class(void); Value *compile_const(ID id, Value *outer); + Value *compile_singleton_class(Value *obj); Value *compile_defined_expression(NODE *node); Value *compile_dstr(NODE *node); void compile_dead_branch(void); @@ -1014,6 +1015,22 @@ return compile_protected_call(getConstFunc, params); } +Value * +RoxorCompiler::compile_singleton_class(Value *obj) +{ + if (singletonClassFunc == NULL) { + // VALUE rb_singleton_class(VALUE klass); + singletonClassFunc = cast<Function>(module->getOrInsertFunction( + "rb_singleton_class", + RubyObjTy, RubyObjTy, NULL)); + } + + std::vector<Value *> params; + params.push_back(obj); + + return compile_protected_call(singletonClassFunc, params); +} + #define DEFINED_IVAR 1 #define DEFINED_GVAR 2 #define DEFINED_CVAR 3 @@ -2753,17 +2770,7 @@ Value *classVal; if (nd_type(node) == NODE_SCLASS) { - if (singletonClassFunc == NULL) { - // VALUE rb_singleton_class(VALUE klass); - singletonClassFunc = cast<Function>(module->getOrInsertFunction("rb_singleton_class", - RubyObjTy, RubyObjTy, NULL)); - } - - std::vector<Value *> params; - - params.push_back(compile_current_class()); - - classVal = CallInst::Create(singletonClassFunc, params.begin(), params.end(), "", bb); + classVal = compile_singleton_class(compile_current_class()); } else { assert(node->nd_cpath->nd_mid > 0); @@ -3337,10 +3344,10 @@ NODE *body = node->nd_defn; assert(body != NULL); - const bool class_method = nd_type(node) == NODE_DEFS; + const bool singleton_method = nd_type(node) == NODE_DEFS; current_mid = mid; - current_instance_method = !class_method; + current_instance_method = !singleton_method; DEBUG_LEVEL_INC(); Value *val = compile_node(body); @@ -3351,18 +3358,28 @@ current_mid = 0; current_instance_method = false; + Value *classVal; + if (singleton_method) { + assert(node->nd_recv != NULL); + classVal = compile_singleton_class(compile_node(node->nd_recv)); + } + else { + classVal = compile_current_class(); + } + if (prepareMethodFunc == NULL) { - // void rb_vm_prepare_method(Class klass, SEL sel, Function *f, - // NODE *node, unsigned char class_method) + // void rb_vm_prepare_method(Class klass, SEL sel, + // Function *f, NODE *node); prepareMethodFunc = - cast<Function>(module->getOrInsertFunction("rb_vm_prepare_method", - Type::VoidTy, RubyObjTy, PtrTy, PtrTy, - PtrTy, Type::Int8Ty, NULL)); + cast<Function>(module->getOrInsertFunction( + "rb_vm_prepare_method", + Type::VoidTy, RubyObjTy, PtrTy, PtrTy, + PtrTy, NULL)); } std::vector<Value *> params; - params.push_back(compile_current_class()); + params.push_back(classVal); rb_vm_arity_t arity = rb_vm_node_arity(body); const SEL sel = mid_to_sel(mid, arity.real); @@ -3372,11 +3389,9 @@ rb_objc_retain((void *)body); params.push_back(compile_const_pointer(body)); - val = ConstantInt::get(Type::Int8Ty, class_method ? 1 : 0); - params.push_back(val); + CallInst::Create(prepareMethodFunc, params.begin(), + params.end(), "", bb); - CallInst::Create(prepareMethodFunc, params.begin(), params.end(), "", bb); - return nilVal; } break; @@ -4158,16 +4173,12 @@ extern "C" void -rb_vm_prepare_method(Class klass, SEL sel, Function *func, NODE *node, unsigned char class_method) +rb_vm_prepare_method(Class klass, SEL sel, Function *func, NODE *node) { if (klass == NULL) { klass = GET_VM()->current_opened_class; } - if (class_method) { - klass = *(Class *)klass; - } - IMP imp = GET_VM()->compile(func); rb_vm_define_method(klass, sel, imp, node); Modified: MacRuby/branches/experimental/test_roxor.rb =================================================================== --- MacRuby/branches/experimental/test_roxor.rb 2009-03-23 02:53:19 UTC (rev 1077) +++ MacRuby/branches/experimental/test_roxor.rb 2009-03-23 03:31:59 UTC (rev 1078) @@ -780,6 +780,38 @@ end } + assert '42', %{ + class Foo + def self.foo; 42; end + end + p Foo.foo + } + assert '42', %{ + class Foo + class << self + def foo; 42; end + end + end + p Foo.foo + } + assert '42', %{ + class Foo; end + def Foo.foo; 42; end + p Foo.foo + } + assert '42', %{ + o = Object.new + def o.foo; 42; end + p o.foo + } + assert '42', %{ + o = Object.new + class << o + def foo; 42; end + end + p o.foo + } + end test "blocks" do
participants (1)
-
source_changes@macosforge.org