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

source_changes at macosforge.org source_changes at macosforge.org
Sun Aug 2 20:50:22 PDT 2009


Revision: 2154
          http://trac.macosforge.org/projects/ruby/changeset/2154
Author:   lsansonetti at apple.com
Date:     2009-08-02 20:50:22 -0700 (Sun, 02 Aug 2009)
Log Message:
-----------
added support for @@foo||=42, a lot of changes for a very stupid functionality, unfortunately used in crap projects such as minitest

Modified Paths:
--------------
    MacRuby/branches/experimental/compiler.cpp
    MacRuby/branches/experimental/compiler.h
    MacRuby/branches/experimental/include/ruby/intern.h
    MacRuby/branches/experimental/variable.c
    MacRuby/branches/experimental/vm.cpp

Modified: MacRuby/branches/experimental/compiler.cpp
===================================================================
--- MacRuby/branches/experimental/compiler.cpp	2009-08-02 19:16:53 UTC (rev 2153)
+++ MacRuby/branches/experimental/compiler.cpp	2009-08-03 03:50:22 UTC (rev 2154)
@@ -1072,6 +1072,25 @@
 }
 
 Value *
+RoxorCompiler::compile_cvar_get(ID id, bool check)
+{
+    if (cvarGetFunc == NULL) {
+	// VALUE rb_vm_cvar_get(VALUE klass, ID id, unsigned char check);
+	cvarGetFunc = cast<Function>(module->getOrInsertFunction(
+		    "rb_vm_cvar_get", 
+		    RubyObjTy, RubyObjTy, IntTy, Type::Int8Ty, NULL));
+    }
+
+    std::vector<Value *> params;
+
+    params.push_back(compile_current_class());
+    params.push_back(compile_id(id));
+    params.push_back(ConstantInt::get(Type::Int8Ty, check ? 1 : 0));
+
+    return compile_protected_call(cvarGetFunc, params);
+}
+
+Value *
 RoxorCompiler::compile_cvar_assignment(ID name, Value *val)
 {
     if (cvarSetFunc == NULL) {
@@ -3054,25 +3073,9 @@
 	    break;
 
 	case NODE_CVAR:
-	    {
-		assert(node->nd_vid > 0);
+	    assert(node->nd_vid > 0);
+	    return compile_cvar_get(node->nd_vid, true);
 
-		if (cvarGetFunc == NULL) {
-		    // VALUE rb_vm_cvar_get(VALUE klass, ID id);
-		    cvarGetFunc = cast<Function>(module->getOrInsertFunction(
-				"rb_vm_cvar_get", 
-				RubyObjTy, RubyObjTy, IntTy, NULL));
-		}
-
-		std::vector<Value *> params;
-
-		params.push_back(compile_current_class());
-		params.push_back(compile_id(node->nd_vid));
-
-		return compile_protected_call(cvarGetFunc, params);
-	    }
-	    break;
-
 	case NODE_CVASGN:
 	    assert(node->nd_vid > 0);
 	    assert(node->nd_value != NULL);
@@ -3108,9 +3111,21 @@
 	    {
 		assert(node->nd_recv != NULL);
 		assert(node->nd_value != NULL);
-		
-		Value *recvVal = compile_node(node->nd_recv);
 
+		Value *recvVal;
+		if (nd_type(node->nd_recv) == NODE_CVAR) {
+		    // @@foo ||= 42
+		    // We need to compile the class variable retrieve to not
+		    // raise an exception in case the variable has never been
+		    // defined yet.
+		    assert(node->nd_recv->nd_vid > 0);
+		    recvVal = compile_cvar_get(node->nd_recv->nd_vid, false);
+		}
+		else {
+		    recvVal = compile_node(node->nd_recv);
+		}
+
+
 		Value *falseCond = new ICmpInst(ICmpInst::ICMP_EQ, recvVal, falseVal, "", bb);
 
 		Function *f = bb->getParent();

Modified: MacRuby/branches/experimental/compiler.h
===================================================================
--- MacRuby/branches/experimental/compiler.h	2009-08-02 19:16:53 UTC (rev 2153)
+++ MacRuby/branches/experimental/compiler.h	2009-08-03 03:50:22 UTC (rev 2154)
@@ -224,6 +224,7 @@
 	Value *compile_ivar_read(ID vid);
 	Value *compile_ivar_assignment(ID vid, Value *val);
 	Value *compile_cvar_assignment(ID vid, Value *val);
+	Value *compile_cvar_get(ID vid, bool check);
 	Value *compile_gvar_assignment(NODE *node, Value *val);
 	Value *compile_constant_declaration(NODE *node, Value *val);
 	Value *compile_multiple_assignment(NODE *node, Value *val);

Modified: MacRuby/branches/experimental/include/ruby/intern.h
===================================================================
--- MacRuby/branches/experimental/include/ruby/intern.h	2009-08-02 19:16:53 UTC (rev 2153)
+++ MacRuby/branches/experimental/include/ruby/intern.h	2009-08-03 03:50:22 UTC (rev 2154)
@@ -652,6 +652,7 @@
 VALUE rb_cvar_defined(VALUE, ID);
 void rb_cvar_set(VALUE, ID, VALUE);
 VALUE rb_cvar_get(VALUE, ID);
+VALUE rb_cvar_get2(VALUE klass, ID id, bool check);
 void rb_cv_set(VALUE, const char*, VALUE);
 VALUE rb_cv_get(VALUE, const char*);
 void rb_define_class_variable(VALUE, const char*, VALUE);

Modified: MacRuby/branches/experimental/variable.c
===================================================================
--- MacRuby/branches/experimental/variable.c	2009-08-02 19:16:53 UTC (rev 2153)
+++ MacRuby/branches/experimental/variable.c	2009-08-03 03:50:22 UTC (rev 2154)
@@ -1945,7 +1945,7 @@
 }
 
 VALUE
-rb_cvar_get(VALUE klass, ID id)
+rb_cvar_get2(VALUE klass, ID id, bool check)
 {
     VALUE value, tmp, front = 0, target = 0;
     CFMutableDictionaryRef iv_dict;
@@ -1956,8 +1956,13 @@
     }
     CVAR_LOOKUP(&value, {if (!front) front = klass; target = klass;});
     if (!target) {
-	rb_name_error(id,"uninitialized class variable %s in %s",
-		      rb_id2name(id), rb_class2name(tmp));
+	if (check) {
+	    rb_name_error(id,"uninitialized class variable %s in %s",
+		    rb_id2name(id), rb_class2name(tmp));
+	}
+	else {
+	    return Qnil;
+	}
     }
     if (front && target != front) {
 	ID did = id;
@@ -1975,6 +1980,12 @@
 }
 
 VALUE
+rb_cvar_get(VALUE klass, ID id)
+{
+    return rb_cvar_get2(klass, id, true);
+}
+
+VALUE
 rb_cvar_defined(VALUE klass, ID id)
 {
     CFMutableDictionaryRef iv_dict;

Modified: MacRuby/branches/experimental/vm.cpp
===================================================================
--- MacRuby/branches/experimental/vm.cpp	2009-08-02 19:16:53 UTC (rev 2153)
+++ MacRuby/branches/experimental/vm.cpp	2009-08-03 03:50:22 UTC (rev 2154)
@@ -1006,13 +1006,13 @@
 
 extern "C"
 VALUE
-rb_vm_cvar_get(VALUE klass, ID id)
+rb_vm_cvar_get(VALUE klass, ID id, unsigned char check)
 {
     Class k = GET_VM()->get_current_class();
     if (k != NULL) {
 	klass = (VALUE)k;
     }
-    return rb_cvar_get(klass, id);
+    return rb_cvar_get2(klass, id, check);
 }
 
 extern "C"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090802/65de878c/attachment-0001.html>


More information about the macruby-changes mailing list