This is interesting. I will try this in 1.8.0.
Something like this (not fully tested)
diff -u ../ruby/eval.c ruby/eval.c
--- ../ruby/eval.c 2003-01-09 13:51:27.000000000 +0100
+++ ruby/eval.c 2003-01-13 12:45:19.000000000 +0100
@@ -1796,14 +1796,14 @@
# define TMP_ALLOC(n) ALLOCA_N(VALUE,n)
#endif
-#define SETUP_ARGS(anode) do {\
+#define SETUP_ARGS0(anode, alen) do {\
NODE *n = anode;\
if (!n) {\
argc = 0;\
argv = 0;\
}\
else if (nd_type(n) == NODE_ARRAY) {\
- argc=n->nd_alen;\
+ argc=alen;\
if (argc > 0) {\
int i;\
n = anode;\
@@ -1828,6 +1828,16 @@
}\
} while (0)
+#define SETUP_ARGS(anode) do {\
+ if (anode) {\
+ SETUP_ARGS0(anode, anode->nd_alen);\
+ }\
+ else {\
+ argc = 0;\
+ argv = 0;\
+ }\
+} while (0)
···
+
#define BEGIN_CALLARGS do {\
struct BLOCK *tmp_block = ruby_block;\
if (ruby_iter->iter == ITER_PRE) {\
@@ -2854,7 +2864,7 @@
recv = rb_eval(self, node->nd_recv);
rval = node->nd_args->nd_head;
- SETUP_ARGS(node->nd_args->nd_next);
+ SETUP_ARGS0(node->nd_args->nd_next, node->nd_args->nd_alen - 1);
val = rb_funcall2(recv, aref, argc-1, argv);
switch (node->nd_mid) {
case 0: /* OR */
diff -u ../ruby/parse.y ruby/parse.y
--- ../ruby/parse.y 2003-01-09 13:52:01.000000000 +0100
+++ ruby/parse.y 2003-01-13 14:22:19.000000000 +0100
@@ -4498,16 +4498,18 @@
list_append(list, item)
NODE *list, *item;
{
- NODE *last;
-
- if (list == 0) return NEW_LIST(item);
+ NODE *last, *node;
- last = list;
- while (last->nd_next) {
- last = last->nd_next;
+ node = NEW_LIST(item);
+ if (list == 0) return node;
+ if (list->nd_next) {
+ last = list->nd_next->nd_end;
}
-
- last->nd_next = NEW_LIST(item);
+ else {
+ last = list;
+ }
+ last->nd_next = node;
+ list->nd_next->nd_end = node;
list->nd_alen += 1;
return list;
}
@@ -4519,14 +4521,20 @@
{
NODE *last;
- last = head;
- while (last->nd_next) {
- last = last->nd_next;
+ if (head->nd_next) {
+ last = head->nd_next->nd_end;
+ }
+ else {
+ last = head;
}
-
last->nd_next = tail;
head->nd_alen += tail->nd_alen;
-
+ if (tail->nd_next) {
+ head->nd_next->nd_end = tail->nd_next->nd_end;
+ }
+ else {
+ head->nd_next->nd_end = tail;
+ }
return head;
}
@@ -4544,6 +4552,7 @@
if (htype == NODE_EVSTR) {
NODE *node = NEW_DSTR(rb_str_new(0, 0));
node->nd_next = NEW_LIST(head);
+ node->nd_next->nd_end = node->nd_next;
node->nd_alen += 1;
head = node;
}
Guy Decoux