[macruby-changes] [1078] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Sun Mar 22 20:32:00 PDT 2009


Revision: 1078
          http://trac.macosforge.org/projects/ruby/changeset/1078
Author:   lsansonetti at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090322/cb0eb46d/attachment-0001.html>


More information about the macruby-changes mailing list