summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c74
1 files changed, 57 insertions, 17 deletions
diff --git a/eval.c b/eval.c
index 41124c2887..57aa51171d 100644
--- a/eval.c
+++ b/eval.c
@@ -1969,6 +1969,10 @@ rb_eval(self, node)
}
break;
+ case NODE_COLON3:
+ result = rb_const_get_at(cObject, node->nd_mid);
+ break;
+
case NODE_NTH_REF:
result = reg_nth_match(node->nd_nth, MATCH_DATA);
break;
@@ -3378,19 +3382,12 @@ f_send(argc, argv, recv)
VALUE recv;
{
VALUE vid;
- ID mid;
if (argc == 0) ArgError("no method name given");
- vid = argv[0]; argc--; argv++;
- if (TYPE(vid) == T_STRING) {
- mid = rb_intern(RSTRING(vid)->ptr);
- }
- else {
- mid = NUM2INT(vid);
- }
+ vid = *argv++; argc--;
PUSH_ITER(iterator_p()?ITER_PRE:ITER_NOT);
- vid = rb_call(CLASS_OF(recv), recv, mid, argc, argv, 1);
+ vid = rb_call(CLASS_OF(recv), recv, rb_to_id(vid), argc, argv, 1);
POP_ITER();
return vid;
@@ -3410,7 +3407,7 @@ f_pass_block(argc, argv, recv)
if (!f_iterator_p())
ArgError("pass_block called out of iterator");
- vid = argv[0]; argc--; argv++;
+ vid = *argv++; argc--;
PUSH_ITER(ITER_PRE);
vid = rb_call(CLASS_OF(recv), recv, rb_to_id(vid), argc, argv, 1);
POP_ITER();
@@ -4349,19 +4346,45 @@ static void
blk_mark(data)
struct BLOCK *data;
{
- gc_mark_frame(&data->frame);
- gc_mark(data->scope);
- gc_mark(data->var);
- gc_mark(data->body);
- gc_mark(data->self);
- gc_mark(data->d_vars);
+ while (data) {
+ gc_mark_frame(&data->frame);
+ gc_mark(data->scope);
+ gc_mark(data->var);
+ gc_mark(data->body);
+ gc_mark(data->self);
+ gc_mark(data->d_vars);
+ data = data->prev;
+ }
}
static void
blk_free(data)
struct BLOCK *data;
{
- free(data->frame.argv);
+ struct BLOCK *tmp;
+
+ while (data) {
+ free(data->frame.argv);
+ tmp = data;
+ data = data->prev;
+ free(tmp);
+ }
+}
+
+static void
+blk_copy_prev(block)
+ struct BLOCK *block;
+{
+ struct BLOCK *tmp;
+
+ while (block->prev) {
+ tmp = ALLOC_N(struct BLOCK, 1);
+ MEMCPY(tmp, block->prev, struct BLOCK, 1);
+ tmp->frame.argv = ALLOC_N(VALUE, tmp->frame.argc);
+ MEMCPY(tmp->frame.argv, block->frame.argv, VALUE, tmp->frame.argc);
+ block->prev = tmp;
+ block = tmp;
+ }
}
static VALUE
@@ -4375,11 +4398,21 @@ f_binding(self)
bind = Data_Make_Struct(cData, struct BLOCK, blk_mark, blk_free, data);
MEMCPY(data, the_block, struct BLOCK, 1);
+#ifdef THREAD
+ data->orig_thread = thread_current();
+#endif
data->iter = f_iterator_p();
data->frame.last_func = 0;
data->frame.argv = ALLOC_N(VALUE, data->frame.argc);
MEMCPY(data->frame.argv, the_block->frame.argv, VALUE, data->frame.argc);
+ if (data->iter) {
+ blk_copy_prev(data);
+ }
+ else {
+ data->prev = 0;
+ }
+
scope_dup(data->scope);
POP_BLOCK();
@@ -4412,6 +4445,12 @@ proc_s_new(klass)
data->iter = f_iterator_p();
data->frame.argv = ALLOC_N(VALUE, data->frame.argc);
MEMCPY(data->frame.argv, the_block->frame.argv, VALUE, data->frame.argc);
+ if (data->iter) {
+ blk_copy_prev(data);
+ }
+ else {
+ data->prev = 0;
+ }
scope_dup(data->scope);
if (safe_level >= 3) {
@@ -4794,6 +4833,7 @@ thread_free(th)
{
if (th->stk_ptr) free(th->stk_ptr);
th->stk_ptr = 0;
+ free(th);
}
static thread_t