1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* vm.c, eval_intern.h (PASS_PASSED_BLOCK):

set a VM_FRAME_FLAG_PASSED flag to skip this frame when
  searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp.  if there is
  no valid ruby-level-cfp, cause RuntimeError exception.
  [ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
  insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2008-06-10 21:46:43 +00:00
parent e6697a6405
commit 9e324fdd3e
17 changed files with 242 additions and 191 deletions

View file

@ -1,3 +1,18 @@
Wed Jun 11 05:53:20 2008 Koichi Sasada <ko1@atdot.net>
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
Wed Jun 11 05:55:31 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
* ext/tk/tcltklib.c: SEGV when tcltk-stubs is enabled.

View file

@ -29,49 +29,6 @@ assert_equal 'ok', %q{
C.new.foo
}, '[ruby-core:14813]'
assert_equal 'ok', %q{
a = lambda {|x, y, &b| b }
b = a.curry[1]
if b.call(2){} == nil
:ng
else
:ok
end
}, '[ruby-core:15551]'
assert_normal_exit %q{
g = Module.enum_for(:new)
loop { g.next }
}, '[ruby-dev:34128]'
assert_normal_exit %q{
Fiber.new(&Object.method(:class_eval)).resume("foo")
}, '[ruby-dev:34128]'
assert_normal_exit %q{
Thread.new("foo", &Object.method(:class_eval)).join
}, '[ruby-dev:34128]'
assert_normal_exit %q{
g = enum_for(:local_variables)
loop { g.next }
}, '[ruby-dev:34128]'
assert_normal_exit %q{
g = enum_for(:block_given?)
loop { g.next }
}, '[ruby-dev:34128]'
assert_normal_exit %q{
g = enum_for(:binding)
loop { g.next }
}, '[ruby-dev:34128]'
assert_normal_exit %q{
g = "abc".enum_for(:scan, /./)
loop { g.next }
}, '[ruby-dev:34128]'
assert_equal %q{[:bar, :foo]}, %q{
def foo
klass = Class.new do
@ -84,24 +41,3 @@ assert_equal %q{[:bar, :foo]}, %q{
foo
}, "[ ruby-Bugs-19304 ]"
assert_equal 'ok', %q{
lambda {
break :ok
:ng
}.call
}, '[ruby-dev:34646]'
assert_normal_exit %q{
eval("", method(:proc).call {}.binding)
}
assert_normal_exit %q{
a = []
100.times {|i| a << i << nil << nil }
p a.compact!
}
assert_equal 'ok', %q{
a = [false]
(a[0] &&= true) == false ? :ok : :ng
}, '[ruby-dev:34679]'

View file

@ -282,3 +282,7 @@ assert_equal 'ok', %q{
:ok
end
}, '[ruby-core:16796]'
assert_normal_exit %q{
eval("", method(:proc).call {}.binding)
}

View file

@ -259,3 +259,20 @@ assert_equal %Q{ok\n}, %q{
GC.start
block.call
}, '[ruby-core:14885]'
assert_equal 'ok', %q{
a = lambda {|x, y, &b| b }
b = a.curry[1]
if b.call(2){} == nil
:ng
else
:ok
end
}, '[ruby-core:15551]'
assert_equal 'ok', %q{
lambda {
break :ok
:ng
}.call
}, '[ruby-dev:34646]'

View file

@ -817,3 +817,14 @@ assert_equal 'ok', %q{
end
}, '[ruby-core:14537]'
assert_equal 'ok', %q{
a = [false]
(a[0] &&= true) == false ? :ok : :ng
}, '[ruby-dev:34679]'
assert_normal_exit %q{
a = []
100.times {|i| a << i << nil << nil }
p a.compact!
}

View file

@ -1,3 +1,5 @@
# Thread and Fiber
assert_equal %q{ok}, %q{
Thread.new{
}.join
@ -268,3 +270,35 @@ assert_normal_exit %q{
at_exit { Fiber.new{}.resume }
}
assert_normal_exit %q{
g = enum_for(:local_variables)
loop { g.next }
}, '[ruby-dev:34128]'
assert_normal_exit %q{
g = enum_for(:block_given?)
loop { g.next }
}, '[ruby-dev:34128]'
assert_normal_exit %q{
g = enum_for(:binding)
loop { g.next }
}, '[ruby-dev:34128]'
assert_normal_exit %q{
g = "abc".enum_for(:scan, /./)
loop { g.next }
}, '[ruby-dev:34128]'
assert_normal_exit %q{
g = Module.enum_for(:new)
loop { g.next }
}, '[ruby-dev:34128]'
assert_normal_exit %q{
Fiber.new(&Object.method(:class_eval)).resume("foo")
}, '[ruby-dev:34128]'
assert_normal_exit %q{
Thread.new("foo", &Object.method(:class_eval)).join
}, '[ruby-dev:34128]'

10
eval.c
View file

@ -17,8 +17,6 @@ VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE);
VALUE rb_binding_new(void);
NORETURN(void rb_raise_jump(VALUE));
VALUE rb_f_block_given_p(void);
ID rb_frame_callee(void);
VALUE rb_eLocalJumpError;
VALUE rb_eSysStackError;
@ -586,9 +584,9 @@ rb_f_block_given_p(void)
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = th->cfp;
cfp = vm_get_ruby_level_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
if (GC_GUARDED_PTR_REF(cfp->lfp[0])) {
if (cfp != 0 && GC_GUARDED_PTR_REF(cfp->lfp[0])) {
return Qtrue;
}
else {
@ -1089,10 +1087,10 @@ rb_f_local_variables(void)
VALUE ary = rb_ary_new();
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp =
vm_get_ruby_level_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp));
vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp));
int i;
while (1) {
while (cfp) {
if (cfp->iseq) {
for (i = 0; i < cfp->iseq->local_table_size; i++) {
ID lid = cfp->iseq->local_table[i];

View file

@ -2,9 +2,15 @@
#ifndef RUBY_EVAL_INTERN_H
#define RUBY_EVAL_INTERN_H
#define PASS_PASSED_BLOCK() \
(GET_THREAD()->passed_block = \
GC_GUARDED_PTR_REF((rb_block_t *)GET_THREAD()->cfp->lfp[0]))
#define PASS_PASSED_BLOCK_TH(th) do { \
(th)->passed_block = GC_GUARDED_PTR_REF((rb_block_t *)(th)->cfp->lfp[0]); \
(th)->cfp->flag |= VM_FRAME_FLAG_PASSED; \
} while (0)
#define PASS_PASSED_BLOCK() do { \
rb_thread_t * const __th__ = GET_THREAD(); \
PASS_PASSED_BLOCK_TH(__th__); \
} while (0)
#include "ruby/ruby.h"
#include "ruby/node.h"
@ -219,7 +225,7 @@ NORETURN(void vm_jump_tag_but_local_jump(int, VALUE));
VALUE vm_make_jump_tag_but_local_jump(int state, VALUE val);
NODE *vm_cref(void);
rb_control_frame_t *vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp);
rb_control_frame_t *vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp);
VALUE rb_obj_is_proc(VALUE);
VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, const rb_block_t *blockptr, VALUE filename);
void rb_thread_terminate_all(void);

View file

@ -996,7 +996,7 @@ defineclass
/* enter scope */
vm_push_frame(th, class_iseq,
FRAME_MAGIC_CLASS, klass, (VALUE) GET_DFP() | 0x02,
VM_FRAME_MAGIC_CLASS, klass, (VALUE) GET_DFP() | 0x02,
class_iseq->iseq_encoded, GET_SP(), 0,
class_iseq->local_size);
RESTORE_REGS();

11
proc.c
View file

@ -275,10 +275,14 @@ VALUE
rb_binding_new(void)
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->cfp);
VALUE bindval = binding_alloc(rb_cBinding);
rb_binding_t *bind;
if (cfp == 0) {
rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber.");
}
GetBindingPtr(bindval, bind);
bind->env = vm_make_env_object(th, cfp);
return bindval;
@ -1187,11 +1191,12 @@ rb_method_call(int argc, VALUE *argv, VALUE method)
}
}
if ((state = EXEC_TAG()) == 0) {
rb_thread_t *th = GET_THREAD();
VALUE rb_vm_call(rb_thread_t * th, VALUE klass, VALUE recv, VALUE id, ID oid,
int argc, const VALUE *argv, const NODE *body, int nosuper);
PASS_PASSED_BLOCK();
result = rb_vm_call(GET_THREAD(), data->oclass, data->recv, data->id, data->oid,
PASS_PASSED_BLOCK_TH(th);
result = rb_vm_call(th, data->oclass, data->recv, data->id, data->oid,
argc, argv, data->body, 0);
}
POP_TAG();

97
vm.c
View file

@ -52,7 +52,7 @@ rb_vm_change_state(void)
static inline VALUE
rb_vm_set_finish_env(rb_thread_t * th)
{
vm_push_frame(th, 0, FRAME_MAGIC_FINISH,
vm_push_frame(th, 0, VM_FRAME_MAGIC_FINISH,
Qnil, th->cfp->lfp[0], 0,
th->cfp->sp, 0, 1);
th->cfp->pc = (VALUE *)&finish_insn_seq[0];
@ -72,7 +72,7 @@ vm_set_top_stack(rb_thread_t * th, VALUE iseqval)
/* for return */
rb_vm_set_finish_env(th);
vm_push_frame(th, iseq, FRAME_MAGIC_TOP,
vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP,
th->top_self, 0, iseq->iseq_encoded,
th->cfp->sp, 0, iseq->local_size);
}
@ -86,7 +86,7 @@ vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref)
/* for return */
rb_vm_set_finish_env(th);
vm_push_frame(th, iseq, FRAME_MAGIC_EVAL, block->self,
vm_push_frame(th, iseq, VM_FRAME_MAGIC_EVAL, block->self,
GC_GUARDED_PTR(block->dfp), iseq->iseq_encoded,
th->cfp->sp, block->lfp, iseq->local_size);
@ -95,8 +95,8 @@ vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref)
}
}
rb_control_frame_t *
vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
static rb_control_frame_t *
vm_get_ruby_level_next_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
{
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
@ -107,6 +107,28 @@ vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
return 0;
}
rb_control_frame_t *
vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
{
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
return cfp;
}
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
return cfp;
}
if ((cfp->flag & VM_FRAME_FLAG_PASSED) == 0) {
break;
}
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
return 0;
}
/* Env */
static void
@ -322,7 +344,7 @@ vm_make_env_object(rb_thread_t * th, rb_control_frame_t *cfp)
{
VALUE envval;
if (VM_FRAME_FLAG(cfp->flag) == FRAME_MAGIC_FINISH) {
if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_FINISH) {
/* for method_missing */
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
@ -340,7 +362,7 @@ void
vm_stack_to_heap(rb_thread_t * const th)
{
rb_control_frame_t *cfp = th->cfp;
while ((cfp = vm_get_ruby_level_cfp(th, cfp)) != 0) {
while ((cfp = vm_get_ruby_level_next_cfp(th, cfp)) != 0) {
vm_make_env_object(th, cfp);
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
@ -423,7 +445,8 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
const rb_iseq_t *iseq = block->iseq;
const rb_control_frame_t *cfp = th->cfp;
int i, opt_pc, arg_size = iseq->arg_size;
int type = block_proc_is_lambda(block->proc) ? FRAME_MAGIC_LAMBDA : FRAME_MAGIC_BLOCK;
int type = block_proc_is_lambda(block->proc) ?
VM_FRAME_MAGIC_LAMBDA : VM_FRAME_MAGIC_BLOCK;
rb_vm_set_finish_env(th);
@ -434,7 +457,7 @@ invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
}
opt_pc = vm_yield_setup_args(th, iseq, argc, cfp->sp, blockptr,
type == FRAME_MAGIC_LAMBDA);
type == VM_FRAME_MAGIC_LAMBDA);
vm_push_frame(th, iseq, type,
self, GC_GUARDED_PTR(block->dfp),
@ -521,22 +544,30 @@ vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
/* special variable */
static rb_control_frame_t *
vm_normal_frame(rb_thread_t *th, rb_control_frame_t *cfp)
{
while (cfp->pc == 0) {
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
return 0;
}
}
return cfp;
}
static VALUE
vm_cfp_svar_get(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key)
{
while (cfp->pc == 0) {
cfp++;
}
return lfp_svar_get(th, cfp->lfp, key);
cfp = vm_normal_frame(th, cfp);
return lfp_svar_get(th, cfp ? cfp->lfp : 0, key);
}
static void
vm_cfp_svar_set(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key, const VALUE val)
{
while (cfp->pc == 0) {
cfp++;
}
lfp_svar_set(th, cfp->lfp, key, val);
cfp = vm_normal_frame(th, cfp);
lfp_svar_set(th, cfp ? cfp->lfp : 0, key, val);
}
static VALUE
@ -663,7 +694,7 @@ const char *
rb_sourcefile(void)
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
rb_control_frame_t *cfp = vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp) {
return RSTRING_PTR(cfp->iseq->filename);
@ -677,7 +708,7 @@ int
rb_sourceline(void)
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
rb_control_frame_t *cfp = vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp) {
return vm_get_sourceline(cfp);
@ -691,7 +722,7 @@ NODE *
vm_cref(void)
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
rb_control_frame_t *cfp = vm_get_ruby_level_next_cfp(th, th->cfp);
return vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
}
@ -710,12 +741,15 @@ debug_cref(NODE *cref)
static NODE *
vm_cref_push(rb_thread_t *th, VALUE klass, int noex)
{
rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->cfp);
NODE *cref = NEW_BLOCK(klass);
rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
cref->nd_file = 0;
cref->nd_next = vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
cref->nd_visi = noex;
if (cfp) {
cref->nd_next = vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
}
return cref;
}
@ -739,7 +773,8 @@ VALUE
rb_vm_cbase(void)
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
rb_control_frame_t *cfp = vm_get_ruby_level_next_cfp(th, th->cfp);
return vm_get_cbase(cfp->iseq, cfp->lfp, cfp->dfp);
}
@ -1183,7 +1218,7 @@ vm_eval_body(rb_thread_t *th)
/* push block frame */
cfp->sp[0] = err;
vm_push_frame(th, catch_iseq, FRAME_MAGIC_BLOCK,
vm_push_frame(th, catch_iseq, VM_FRAME_MAGIC_BLOCK,
cfp->self, (VALUE)cfp->dfp, catch_iseq->iseq_encoded,
cfp->sp + 1 /* push value */, cfp->lfp, catch_iseq->local_size - 1);
@ -1297,7 +1332,7 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
volatile VALUE iseqval = rb_iseq_new(0, filename, filename, 0, ISEQ_TYPE_TOP);
VALUE val;
vm_push_frame(th, DATA_PTR(iseqval), FRAME_MAGIC_TOP,
vm_push_frame(th, DATA_PTR(iseqval), VM_FRAME_MAGIC_TOP,
recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
val = (*func)(arg);
@ -1306,14 +1341,6 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
return val;
}
int
rb_vm_cfunc_funcall_p(const rb_control_frame_t *cfp)
{
if (vm_cfunc_flags(cfp) & (VM_CALL_FCALL_BIT | VM_CALL_VCALL_BIT))
return Qtrue;
return Qfalse;
}
/* vm */
static void
@ -1548,7 +1575,7 @@ th_init2(rb_thread_t *th)
th->cfp = (void *)(th->stack + th->stack_size);
vm_push_frame(th, 0, FRAME_MAGIC_TOP, Qnil, 0, 0,
vm_push_frame(th, 0, VM_FRAME_MAGIC_TOP, Qnil, 0, 0,
th->stack, 0, 1);
th->status = THREAD_RUNNABLE;

21
vm.h
View file

@ -219,27 +219,6 @@ default: \
(!((th)->stack < (env) && (env) < ((th)->stack + (th)->stack_size)))
#define ENV_VAL(env) ((env)[1])
#define FRAME_MAGIC_METHOD 0x11
#define FRAME_MAGIC_BLOCK 0x21
#define FRAME_MAGIC_CLASS 0x31
#define FRAME_MAGIC_TOP 0x41
#define FRAME_MAGIC_FINISH 0x51
#define FRAME_MAGIC_CFUNC 0x61
#define FRAME_MAGIC_PROC 0x71
#define FRAME_MAGIC_IFUNC 0x81
#define FRAME_MAGIC_EVAL 0x91
#define FRAME_MAGIC_LAMBDA 0xa1
#define FRAME_MAGIC_MASK_BITS 8
#define FRAME_MAGIC_MASK (~(~0<<FRAME_MAGIC_MASK_BITS))
#define VM_FRAME_FLAG(type) ((VALUE)((type) & FRAME_MAGIC_MASK))
#define VM_FRAME_TYPE(cfp) \
((cfp)->flag & FRAME_MAGIC_MASK)
#define RUBYVM_CFUNC_FRAME_P(cfp) \
(VM_FRAME_TYPE(cfp) == FRAME_MAGIC_CFUNC)
#if OPT_CALL_THREADED_CODE
#define THROW_EXCEPTION(exc) do { \
th->errinfo = (VALUE)(exc); \

View file

@ -539,6 +539,29 @@ typedef struct {
#define VM_CALL_SUPER_BIT (0x01 << 7)
#define VM_CALL_SEND_BIT (0x01 << 8)
#define VM_FRAME_MAGIC_METHOD 0x11
#define VM_FRAME_MAGIC_BLOCK 0x21
#define VM_FRAME_MAGIC_CLASS 0x31
#define VM_FRAME_MAGIC_TOP 0x41
#define VM_FRAME_MAGIC_FINISH 0x51
#define VM_FRAME_MAGIC_CFUNC 0x61
#define VM_FRAME_MAGIC_PROC 0x71
#define VM_FRAME_MAGIC_IFUNC 0x81
#define VM_FRAME_MAGIC_EVAL 0x91
#define VM_FRAME_MAGIC_LAMBDA 0xa1
#define VM_FRAME_MAGIC_MASK_BITS 8
#define VM_FRAME_MAGIC_MASK (~(~0<<VM_FRAME_MAGIC_MASK_BITS))
#define VM_FRAME_TYPE(cfp) ((cfp)->flag & VM_FRAME_MAGIC_MASK)
/* other frame flag */
#define VM_FRAME_FLAG_PASSED 0x0100
#define RUBYVM_CFUNC_FRAME_P(cfp) \
(VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC)
/* inline (method|const) cache */
#define NEW_INLINE_CACHE_ENTRY() NEW_WHILE(Qundef, 0, 0)
#define ic_class u1.value

View file

@ -46,34 +46,34 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
}
switch (VM_FRAME_TYPE(cfp)) {
case FRAME_MAGIC_TOP:
case VM_FRAME_MAGIC_TOP:
magic = "TOP";
break;
case FRAME_MAGIC_METHOD:
case VM_FRAME_MAGIC_METHOD:
magic = "METHOD";
break;
case FRAME_MAGIC_CLASS:
case VM_FRAME_MAGIC_CLASS:
magic = "CLASS";
break;
case FRAME_MAGIC_BLOCK:
case VM_FRAME_MAGIC_BLOCK:
magic = "BLOCK";
break;
case FRAME_MAGIC_FINISH:
case VM_FRAME_MAGIC_FINISH:
magic = "FINISH";
break;
case FRAME_MAGIC_CFUNC:
case VM_FRAME_MAGIC_CFUNC:
magic = "CFUNC";
break;
case FRAME_MAGIC_PROC:
case VM_FRAME_MAGIC_PROC:
magic = "PROC";
break;
case FRAME_MAGIC_LAMBDA:
case VM_FRAME_MAGIC_LAMBDA:
magic = "LAMBDA";
break;
case FRAME_MAGIC_IFUNC:
case VM_FRAME_MAGIC_IFUNC:
magic = "IFUNC";
break;
case FRAME_MAGIC_EVAL:
case VM_FRAME_MAGIC_EVAL:
magic = "EVAL";
break;
case 0:
@ -271,15 +271,15 @@ stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
/* stack trace header */
if (VM_FRAME_TYPE(cfp) == FRAME_MAGIC_METHOD ||
VM_FRAME_TYPE(cfp) == FRAME_MAGIC_TOP ||
VM_FRAME_TYPE(cfp) == FRAME_MAGIC_BLOCK ||
VM_FRAME_TYPE(cfp) == FRAME_MAGIC_CLASS ||
VM_FRAME_TYPE(cfp) == FRAME_MAGIC_PROC ||
VM_FRAME_TYPE(cfp) == FRAME_MAGIC_LAMBDA ||
VM_FRAME_TYPE(cfp) == FRAME_MAGIC_CFUNC ||
VM_FRAME_TYPE(cfp) == FRAME_MAGIC_IFUNC ||
VM_FRAME_TYPE(cfp) == FRAME_MAGIC_EVAL) {
if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_METHOD ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_TOP ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_BLOCK ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CLASS ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_PROC ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_IFUNC ||
VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_EVAL) {
VALUE *ptr = dfp - local_size;
@ -312,7 +312,7 @@ stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
ptr - th->stack);
}
}
else if (VM_FRAME_TYPE(cfp) == FRAME_MAGIC_FINISH) {
else if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_FINISH) {
if ((th)->stack + (th)->stack_size > (VALUE *)(cfp + 2)) {
stack_dump_each(th, cfp + 1);
}
@ -362,7 +362,7 @@ debug_print_pre(rb_thread_t *th, rb_control_frame_t *cfp)
{
rb_iseq_t *iseq = cfp->iseq;
if (iseq != 0 && VM_FRAME_TYPE(cfp) != FRAME_MAGIC_FINISH) {
if (iseq != 0 && VM_FRAME_TYPE(cfp) != VM_FRAME_MAGIC_FINISH) {
VALUE *seq = iseq->iseq;
int pc = cfp->pc - iseq->iseq_encoded;

View file

@ -66,7 +66,7 @@ vm_call0(rb_thread_t * th, VALUE klass, VALUE recv, VALUE id, ID oid,
{
rb_control_frame_t *reg_cfp = th->cfp;
rb_control_frame_t *cfp =
vm_push_frame(th, 0, FRAME_MAGIC_CFUNC,
vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
cfp->method_id = id;
@ -412,13 +412,15 @@ send_internal(int argc, VALUE *argv, VALUE recv, int scope)
{
VALUE vid;
VALUE self = RUBY_VM_PREVIOUS_CONTROL_FRAME(GET_THREAD()->cfp)->self;
rb_thread_t *th = GET_THREAD();
if (argc == 0) {
rb_raise(rb_eArgError, "no method name given");
}
vid = *argv++; argc--;
PASS_PASSED_BLOCK();
PASS_PASSED_BLOCK_TH(th);
return rb_call0(CLASS_OF(recv), recv, rb_to_id(vid), argc, argv, scope, self);
}
@ -687,11 +689,17 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char
th->base_block = &env->block;
}
else {
rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
th->base_block = &block;
th->base_block->self = self;
th->base_block->iseq = cfp->iseq; /* TODO */
rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->cfp);
if (cfp != 0) {
block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
th->base_block = &block;
th->base_block->self = self;
th->base_block->iseq = cfp->iseq; /* TODO */
}
else {
rb_raise(rb_eRuntimeError, "Can't eval on top of Fiber or Thread");
}
}
/* make eval iseq */

View file

@ -131,7 +131,7 @@ vm_eval(rb_thread_t *th, VALUE initial)
}
}
if (VM_FRAME_TYPE(th->cfp) != FRAME_MAGIC_FINISH) {
if (VM_FRAME_TYPE(th->cfp) != VM_FRAME_MAGIC_FINISH) {
rb_bug("cfp consistency error");
}

View file

@ -367,7 +367,7 @@ vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp,
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, id, klass);
{
rb_control_frame_t *cfp =
vm_push_frame(th, 0, FRAME_MAGIC_CFUNC | (flag << FRAME_MAGIC_MASK_BITS),
vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
recv, (VALUE) blockptr, 0, reg_cfp->sp, 0, 1);
cfp->method_id = id;
@ -380,6 +380,7 @@ vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp,
if (reg_cfp != th->cfp + 1) {
rb_bug("cfp consistency error - send");
}
vm_pop_frame(th);
}
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, id, klass);
@ -387,14 +388,6 @@ vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp,
return val;
}
static inline int
vm_cfunc_flags(const rb_control_frame_t *cfp)
{
if (RUBYVM_CFUNC_FRAME_P(cfp))
return cfp->flag >> FRAME_MAGIC_MASK_BITS;
return 0;
}
static inline VALUE
vm_call_bmethod(rb_thread_t *th, ID id, VALUE procval, VALUE recv,
VALUE klass, int argc, VALUE *argv, rb_block_t *blockptr)
@ -455,7 +448,7 @@ vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp,
}
vm_push_frame(th, iseq,
FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
VM_FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
iseq->iseq_encoded + opt_pc, sp, 0, 0);
cfp->sp = rsp - 1 /* recv */;
@ -478,7 +471,7 @@ vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp,
}
vm_push_frame(th, iseq,
FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
VM_FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
iseq->iseq_encoded + opt_pc, sp, 0, 0);
}
}
@ -675,7 +668,7 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block,
blockarg = Qnil;
}
vm_push_frame(th, 0, FRAME_MAGIC_IFUNC,
vm_push_frame(th, 0, VM_FRAME_MAGIC_IFUNC,
self, (VALUE)block->dfp,
0, th->cfp->sp, block->lfp, 1);
@ -831,7 +824,7 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_n
block_proc_is_lambda(block->proc));
vm_push_frame(th, iseq,
FRAME_MAGIC_BLOCK, block->self, (VALUE) block->dfp,
VM_FRAME_MAGIC_BLOCK, block->self, (VALUE) block->dfp,
iseq->iseq_encoded + opt_pc, rsp + arg_size, block->lfp,
iseq->local_size - arg_size);
@ -849,23 +842,18 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_n
static inline NODE *
lfp_svar_place(rb_thread_t *th, VALUE *lfp)
{
NODE *svar;
VALUE *svar;
if (th->local_lfp != lfp) {
svar = (NODE *)lfp[-1];
if ((VALUE)svar == Qnil) {
svar = NEW_IF(Qnil, Qnil, Qnil);
lfp[-1] = (VALUE)svar;
}
if (lfp && th->local_lfp != lfp) {
svar = &lfp[-1];
}
else {
svar = (NODE *)th->local_svar;
if ((VALUE)svar == Qnil) {
svar = NEW_IF(Qnil, Qnil, Qnil);
th->local_svar = (VALUE)svar;
}
svar = &th->local_svar;
}
return svar;
if (NIL_P(*svar)) {
*svar = (VALUE)NEW_IF(Qnil, Qnil, Qnil);
}
return (NODE *)*svar;
}
static VALUE
@ -1238,7 +1226,7 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
rb_bug("VM (throw): can't find break base.");
}
if (VM_FRAME_TYPE(cfp) == FRAME_MAGIC_LAMBDA) {
if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
/* lambda{... break ...} */
is_orphan = 0;
pt = GET_LFP();
@ -1297,7 +1285,7 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp,
*/
while ((VALUE *) cfp < th->stack + th->stack_size) {
if (GET_DFP() == dfp) {
if (VM_FRAME_TYPE(cfp) == FRAME_MAGIC_LAMBDA) {
if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
/* in lambda */
is_orphan = 0;
break;