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

source_changes at macosforge.org source_changes at macosforge.org
Tue Mar 17 22:57:28 PDT 2009


Revision: 981
          http://trac.macosforge.org/projects/ruby/changeset/981
Author:   lsansonetti at apple.com
Date:     2009-03-17 22:57:27 -0700 (Tue, 17 Mar 2009)
Log Message:
-----------
implemented singleton class opening (class << self)

Modified Paths:
--------------
    MacRuby/branches/experimental/roxor.cpp
    MacRuby/branches/experimental/test_roxor.rb

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-03-18 04:09:13 UTC (rev 980)
+++ MacRuby/branches/experimental/roxor.cpp	2009-03-18 05:57:27 UTC (rev 981)
@@ -223,6 +223,7 @@
 	Function *getConstFunc;
 	Function *setConstFunc;
 	Function *prepareMethodFunc;
+	Function *singletonClassFunc;
 	Function *defineClassFunc;
 	Function *prepareIvarSlotFunc;
 	Function *getIvarFunc;
@@ -540,6 +541,7 @@
     getConstFunc = NULL;
     setConstFunc = NULL;
     prepareMethodFunc = NULL;
+    singletonClassFunc = NULL;
     defineClassFunc = NULL;
     prepareIvarSlotFunc = NULL;
     getIvarFunc = NULL;
@@ -2754,33 +2756,47 @@
 	    break;
 
 	case NODE_CLASS:
+	case NODE_SCLASS:
 	case NODE_MODULE:
 	    {
 		assert(node->nd_cpath != NULL);
-		assert(node->nd_cpath->nd_mid > 0);
-		ID path = node->nd_cpath->nd_mid;
 
-		NODE *super = node->nd_super;
+		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));
+		    }
 
-		if (defineClassFunc == NULL) {
-		    // VALUE rb_vm_define_class(ID path, VALUE outer, VALUE super, unsigned char is_module);
-		    std::vector<const Type *> types;
-		    types.push_back(IntTy);
-		    types.push_back(RubyObjTy);
-		    types.push_back(RubyObjTy);
-		    types.push_back(Type::Int8Ty);
-		    FunctionType *ft = FunctionType::get(RubyObjTy, types, false);
-		    defineClassFunc = cast<Function>(module->getOrInsertFunction("rb_vm_define_class", ft));
+		    std::vector<Value *> params;
+
+		    params.push_back(compile_current_class());
+
+		    classVal = CallInst::Create(singletonClassFunc, params.begin(), params.end(), "", bb);
 		}
+		else {
+		    assert(node->nd_cpath->nd_mid > 0);
+		    ID path = node->nd_cpath->nd_mid;
 
-		std::vector<Value *> params;
+		    NODE *super = node->nd_super;
 
-		params.push_back(ConstantInt::get(IntTy, (long)path));
-		params.push_back(compile_current_class());
-		params.push_back(super == NULL ? zeroVal : compile_node(super));
-		params.push_back(ConstantInt::get(Type::Int8Ty, nd_type(node) == NODE_MODULE ? 1 : 0));
-		Value *classVal = CallInst::Create(defineClassFunc, params.begin(), params.end(), "", bb);
+		    if (defineClassFunc == NULL) {
+			// VALUE rb_vm_define_class(ID path, VALUE outer, VALUE super, unsigned char is_module);
+			defineClassFunc = cast<Function>(module->getOrInsertFunction("rb_vm_define_class",
+				RubyObjTy, IntTy, RubyObjTy, RubyObjTy, Type::Int8Ty, NULL));
+		    }
 
+		    std::vector<Value *> params;
+
+		    params.push_back(ConstantInt::get(IntTy, (long)path));
+		    params.push_back(compile_current_class());
+		    params.push_back(super == NULL ? zeroVal : compile_node(super));
+		    params.push_back(ConstantInt::get(Type::Int8Ty, nd_type(node) == NODE_MODULE ? 1 : 0));
+
+		    classVal = CallInst::Create(defineClassFunc, params.begin(), params.end(), "", bb);
+		}
+
 		NODE *body = node->nd_body;
 		if (body != NULL) {
 		    assert(nd_type(body) == NODE_SCOPE);

Modified: MacRuby/branches/experimental/test_roxor.rb
===================================================================
--- MacRuby/branches/experimental/test_roxor.rb	2009-03-18 04:09:13 UTC (rev 980)
+++ MacRuby/branches/experimental/test_roxor.rb	2009-03-18 05:57:27 UTC (rev 981)
@@ -463,6 +463,15 @@
     o.foo
   }
 
+  assert "42", %q{
+    class X
+      class << self
+        def foo; 42; end
+      end
+    end
+    p X.foo
+  }
+
 end
 
 test "module" do
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090317/384f83b1/attachment-0001.html>


More information about the macruby-changes mailing list