[macruby-changes] [1202] MacRuby/branches/experimental
source_changes at macosforge.org
source_changes at macosforge.org
Fri Mar 27 01:16:51 PDT 2009
Revision: 1202
http://trac.macosforge.org/projects/ruby/changeset/1202
Author: lsansonetti at apple.com
Date: 2009-03-27 01:16:51 -0700 (Fri, 27 Mar 2009)
Log Message:
-----------
implemented NODE_OP_ASGN2 (o.foo||=42)
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-27 04:53:14 UTC (rev 1201)
+++ MacRuby/branches/experimental/roxor.cpp 2009-03-27 08:16:51 UTC (rev 1202)
@@ -2681,12 +2681,13 @@
break;
case NODE_OP_ASGN1:
+ case NODE_OP_ASGN2:
{
assert(node->nd_recv != NULL);
Value *recv = compile_node(node->nd_recv);
- assert(node->nd_mid >= 0);
- ID mid = node->nd_mid;
+ long type = nd_type(node) == NODE_OP_ASGN1
+ ? node->nd_mid : node->nd_next->nd_mid;
// a=[0] += 42
//
@@ -2696,28 +2697,40 @@
assert(node->nd_args != NULL);
assert(node->nd_args->nd_head != NULL);
- assert(node->nd_args->nd_body != NULL);
// tmp = a.send(:[], 0)
std::vector<Value *> params;
- void *cache = GET_VM()->method_cache_get(selAREF, false);
+ SEL sel;
+ if (nd_type(node) == NODE_OP_ASGN1) {
+ sel = selAREF;
+ }
+ else {
+ assert(node->nd_next->nd_vid > 0);
+ sel = mid_to_sel(node->nd_next->nd_vid, 0);
+ }
+ void *cache = GET_VM()->method_cache_get(sel, false);
params.push_back(compile_const_pointer(cache));
params.push_back(recv);
- params.push_back(compile_const_pointer((void *)selAREF));
+ params.push_back(compile_const_pointer((void *)sel));
params.push_back(compile_const_pointer(NULL));
params.push_back(ConstantInt::get(Type::Int8Ty, 0));
+ int argc = 0;
std::vector<Value *> arguments;
- int argc;
- compile_dispatch_arguments(node->nd_args->nd_body, arguments, &argc);
+ if (nd_type(node) == NODE_OP_ASGN1) {
+ assert(node->nd_args->nd_body != NULL);
+ compile_dispatch_arguments(node->nd_args->nd_body,
+ arguments,
+ &argc);
+ }
params.push_back(ConstantInt::get(Type::Int32Ty, argc));
for (std::vector<Value *>::iterator i = arguments.begin();
- i != arguments.end(); ++i) {
+ i != arguments.end(); ++i) {
params.push_back(*i);
}
- Value *tmp = compile_optimized_dispatch_call(selAREF, argc, params);
+ Value *tmp = compile_optimized_dispatch_call(sel, argc, params);
if (tmp == NULL) {
tmp = compile_dispatch_call(params);
}
@@ -2728,7 +2741,10 @@
BasicBlock *touchedBB = NULL;
BasicBlock *untouchedBB = NULL;
Value *tmp2;
- if (mid == 0 || mid == 1) {
+ NODE *value = nd_type(node) == NODE_OP_ASGN1
+ ? node->nd_args->nd_head : node->nd_value;
+ assert(value != NULL);
+ if (type == 0 || type == 1) {
// 0 means OR, 1 means AND
Function *f = bb->getParent();
@@ -2736,7 +2752,7 @@
untouchedBB = BasicBlock::Create("", f);
mergeBB = BasicBlock::Create("merge", f);
- if (mid == 0) {
+ if (type == 0) {
compile_boolean_test(tmp, untouchedBB, touchedBB);
}
else {
@@ -2746,10 +2762,12 @@
BranchInst::Create(mergeBB, untouchedBB);
bb = touchedBB;
- tmp2 = compile_node(node->nd_args->nd_head);
+ tmp2 = compile_node(value);
}
else {
- const SEL sel = mid_to_sel(mid, 1);
+ ID mid = nd_type(node) == NODE_OP_ASGN1
+ ? node->nd_mid : node->nd_next->nd_mid;
+ sel = mid_to_sel(mid, 1);
cache = GET_VM()->method_cache_get(sel, false);
params.clear();
params.push_back(compile_const_pointer(cache));
@@ -2758,7 +2776,7 @@
params.push_back(compile_const_pointer(NULL));
params.push_back(ConstantInt::get(Type::Int8Ty, 0));
params.push_back(ConstantInt::get(Type::Int32Ty, 1));
- params.push_back(compile_node(node->nd_args->nd_head));
+ params.push_back(compile_node(value));
tmp2 = compile_optimized_dispatch_call(sel, 1, params);
if (tmp2 == NULL) {
@@ -2767,12 +2785,19 @@
}
// a.send(:[]=, 0, tmp)
-
- cache = GET_VM()->method_cache_get(selASET, false);
+
+ if (nd_type(node) == NODE_OP_ASGN1) {
+ sel = selASET;
+ }
+ else {
+ assert(node->nd_next->nd_aid > 0);
+ sel = mid_to_sel(node->nd_next->nd_aid, 1);
+ }
+ cache = GET_VM()->method_cache_get(sel, false);
params.clear();
params.push_back(compile_const_pointer(cache));
params.push_back(recv);
- params.push_back(compile_const_pointer((void *)selASET));
+ params.push_back(compile_const_pointer((void *)sel));
params.push_back(compile_const_pointer(NULL));
params.push_back(ConstantInt::get(Type::Int8Ty, 0));
argc++;
@@ -2783,7 +2808,7 @@
}
params.push_back(tmp2);
- Value *ret = compile_optimized_dispatch_call(selASET, argc, params);
+ Value *ret = compile_optimized_dispatch_call(sel, argc, params);
if (ret == NULL) {
ret = compile_dispatch_call(params);
}
Modified: MacRuby/branches/experimental/test_roxor.rb
===================================================================
--- MacRuby/branches/experimental/test_roxor.rb 2009-03-27 04:53:14 UTC (rev 1201)
+++ MacRuby/branches/experimental/test_roxor.rb 2009-03-27 08:16:51 UTC (rev 1202)
@@ -333,6 +333,20 @@
assert '42', "a=[123]; a[0] &&= 42; p a[0]"
assert 'nil', "a=[]; a[0] &&= 123; p a[0]"
+ assert '42', %q{
+ class Foo; attr_accessor :x; end
+ o = Foo.new
+ o.x ||= 42
+ p o.x
+ }
+ assert '42', %q{
+ class Foo; attr_accessor :x; end
+ o = Foo.new
+ o.x = 2
+ o.x += 40
+ p o.x
+ }
+
assert '42', "a ||= 42; p a"
assert '42', "a = nil; a ||= 42; p a"
assert '42', "a = false; a ||= 42; p a"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090327/0f39ac1b/attachment-0001.html>
More information about the macruby-changes
mailing list