[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