From: ts Date: 2003-01-14T00:04:31+09:00 Subject: Re: Ruby: politics & performance [long] >>>>> "Y" == Yukihiro Matsumoto writes: Y> 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