зеркало из https://github.com/github/ruby.git
* vm.c, internal.h: remove RubyVM::Env class and all of env objects
are imemo objects (imemo_env). * NEWS: describe this change. I believe nobody touch these objects because there are no method defined. * vm_core.h: remove the following definitions. * rb_cEnv decl. * GetEnvPtr() because Env is no longer T_DATA object. * vm_core.h (rb_env_t): fix layout for imemo values. * vm_core.h (vm_assert_env): added. * vm_core.h (vm_env_new): added. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55768 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
c3ceb1bff2
Коммит
e06698d257
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
||||||
|
Fri Jul 29 03:49:04 2016 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* vm.c, internal.h: remove RubyVM::Env class and all of env objects
|
||||||
|
are imemo objects (imemo_env).
|
||||||
|
|
||||||
|
* NEWS: describe this change. I believe nobody touch these objects
|
||||||
|
because there are no method defined.
|
||||||
|
|
||||||
|
* vm_core.h: remove the following definitions.
|
||||||
|
* rb_cEnv decl.
|
||||||
|
* GetEnvPtr() because Env is no longer T_DATA object.
|
||||||
|
|
||||||
|
* vm_core.h (rb_env_t): fix layout for imemo values.
|
||||||
|
|
||||||
|
* vm_core.h (vm_assert_env): added.
|
||||||
|
|
||||||
|
* vm_core.h (vm_env_new): added.
|
||||||
|
|
||||||
Thu Jul 28 19:53:21 2016 Koichi Sasada <ko1@atdot.net>
|
Thu Jul 28 19:53:21 2016 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* vm_core.h: revisit the structure of frame, block and env.
|
* vm_core.h: revisit the structure of frame, block and env.
|
||||||
|
|
4
NEWS
4
NEWS
|
@ -66,6 +66,10 @@ with all sufficient information, see the ChangeLog file or Redmine
|
||||||
* Regexp#match? [Feature #8110]
|
* Regexp#match? [Feature #8110]
|
||||||
This returns bool and doesn't save backref.
|
This returns bool and doesn't save backref.
|
||||||
|
|
||||||
|
* RubyVM::Env
|
||||||
|
|
||||||
|
* RubyVM::Env was removed.
|
||||||
|
|
||||||
* String
|
* String
|
||||||
|
|
||||||
* String#upcase, String#downcase, String#capitalize, String#swapcase and
|
* String#upcase, String#downcase, String#capitalize, String#swapcase and
|
||||||
|
|
125
gc.c
125
gc.c
|
@ -421,6 +421,7 @@ typedef struct RVALUE {
|
||||||
struct MEMO memo;
|
struct MEMO memo;
|
||||||
struct rb_method_entry_struct ment;
|
struct rb_method_entry_struct ment;
|
||||||
const rb_iseq_t iseq;
|
const rb_iseq_t iseq;
|
||||||
|
rb_env_t env;
|
||||||
} imemo;
|
} imemo;
|
||||||
struct {
|
struct {
|
||||||
struct RBasic basic;
|
struct RBasic basic;
|
||||||
|
@ -2272,17 +2273,19 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_IMEMO:
|
case T_IMEMO:
|
||||||
{
|
switch (imemo_type(obj)) {
|
||||||
switch (imemo_type(obj)) {
|
case imemo_ment:
|
||||||
case imemo_ment:
|
rb_free_method_entry(&RANY(obj)->as.imemo.ment);
|
||||||
rb_free_method_entry(&RANY(obj)->as.imemo.ment);
|
break;
|
||||||
break;
|
case imemo_iseq:
|
||||||
case imemo_iseq:
|
rb_iseq_free(&RANY(obj)->as.imemo.iseq);
|
||||||
rb_iseq_free(&RANY(obj)->as.imemo.iseq);
|
break;
|
||||||
break;
|
case imemo_env:
|
||||||
default:
|
VM_ASSERT(VM_ENV_ESCAPED_P(RANY(obj)->as.imemo.env.ep));
|
||||||
break;
|
xfree((VALUE *)RANY(obj)->as.imemo.env.env);
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -3988,10 +3991,9 @@ rb_gc_mark_locations(const VALUE *start, const VALUE *end)
|
||||||
gc_mark_locations(&rb_objspace, start, end);
|
gc_mark_locations(&rb_objspace, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
rb_gc_mark_values(long n, const VALUE *values)
|
gc_mark_values(rb_objspace_t *objspace, long n, const VALUE *values)
|
||||||
{
|
{
|
||||||
rb_objspace_t *objspace = &rb_objspace;
|
|
||||||
long i;
|
long i;
|
||||||
|
|
||||||
for (i=0; i<n; i++) {
|
for (i=0; i<n; i++) {
|
||||||
|
@ -3999,6 +4001,13 @@ rb_gc_mark_values(long n, const VALUE *values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_gc_mark_values(long n, const VALUE *values)
|
||||||
|
{
|
||||||
|
rb_objspace_t *objspace = &rb_objspace;
|
||||||
|
gc_mark_values(objspace, n, values);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mark_entry(st_data_t key, st_data_t value, st_data_t data)
|
mark_entry(st_data_t key, st_data_t value, st_data_t data)
|
||||||
{
|
{
|
||||||
|
@ -4391,6 +4400,55 @@ gc_mark_set_parent(rb_objspace_t *objspace, VALUE obj)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gc_mark_imemo(rb_objspace_t *objspace, VALUE obj)
|
||||||
|
{
|
||||||
|
switch (imemo_type(obj)) {
|
||||||
|
case imemo_env:
|
||||||
|
{
|
||||||
|
const rb_env_t *env = (const rb_env_t *)obj;
|
||||||
|
VM_ASSERT(VM_ENV_ESCAPED_P(env->ep));
|
||||||
|
gc_mark_values(objspace, (long)env->env_size, env->env);
|
||||||
|
VM_ENV_FLAGS_SET(env->ep, VM_ENV_FLAG_WB_REQUIRED);
|
||||||
|
gc_mark(objspace, (VALUE)rb_vm_env_prev_env(env));
|
||||||
|
gc_mark(objspace, (VALUE)env->iseq);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case imemo_cref:
|
||||||
|
gc_mark(objspace, RANY(obj)->as.imemo.cref.klass);
|
||||||
|
gc_mark(objspace, (VALUE)RANY(obj)->as.imemo.cref.next);
|
||||||
|
gc_mark(objspace, RANY(obj)->as.imemo.cref.refinements);
|
||||||
|
return;
|
||||||
|
case imemo_svar:
|
||||||
|
gc_mark(objspace, RANY(obj)->as.imemo.svar.cref_or_me);
|
||||||
|
gc_mark(objspace, RANY(obj)->as.imemo.svar.lastline);
|
||||||
|
gc_mark(objspace, RANY(obj)->as.imemo.svar.backref);
|
||||||
|
gc_mark(objspace, RANY(obj)->as.imemo.svar.others);
|
||||||
|
return;
|
||||||
|
case imemo_throw_data:
|
||||||
|
gc_mark(objspace, RANY(obj)->as.imemo.throw_data.throw_obj);
|
||||||
|
return;
|
||||||
|
case imemo_ifunc:
|
||||||
|
gc_mark_maybe(objspace, (VALUE)RANY(obj)->as.imemo.ifunc.data);
|
||||||
|
return;
|
||||||
|
case imemo_memo:
|
||||||
|
gc_mark(objspace, RANY(obj)->as.imemo.memo.v1);
|
||||||
|
gc_mark(objspace, RANY(obj)->as.imemo.memo.v2);
|
||||||
|
gc_mark_maybe(objspace, RANY(obj)->as.imemo.memo.u3.value);
|
||||||
|
return;
|
||||||
|
case imemo_ment:
|
||||||
|
mark_method_entry(objspace, &RANY(obj)->as.imemo.ment);
|
||||||
|
return;
|
||||||
|
case imemo_iseq:
|
||||||
|
rb_iseq_mark((rb_iseq_t *)obj);
|
||||||
|
return;
|
||||||
|
#if VM_CHECK_MODE > 0
|
||||||
|
default:
|
||||||
|
VM_UNREACHABLE(gc_mark_imemo);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gc_mark_children(rb_objspace_t *objspace, VALUE obj)
|
gc_mark_children(rb_objspace_t *objspace, VALUE obj)
|
||||||
{
|
{
|
||||||
|
@ -4413,40 +4471,8 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
|
||||||
return; /* no need to mark class. */
|
return; /* no need to mark class. */
|
||||||
|
|
||||||
case T_IMEMO:
|
case T_IMEMO:
|
||||||
switch (imemo_type(obj)) {
|
gc_mark_imemo(objspace, obj);
|
||||||
case imemo_none:
|
return;
|
||||||
rb_bug("unreachable");
|
|
||||||
return;
|
|
||||||
case imemo_cref:
|
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.cref.klass);
|
|
||||||
gc_mark(objspace, (VALUE)RANY(obj)->as.imemo.cref.next);
|
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.cref.refinements);
|
|
||||||
return;
|
|
||||||
case imemo_svar:
|
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.svar.cref_or_me);
|
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.svar.lastline);
|
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.svar.backref);
|
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.svar.others);
|
|
||||||
return;
|
|
||||||
case imemo_throw_data:
|
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.throw_data.throw_obj);
|
|
||||||
return;
|
|
||||||
case imemo_ifunc:
|
|
||||||
gc_mark_maybe(objspace, (VALUE)RANY(obj)->as.imemo.ifunc.data);
|
|
||||||
return;
|
|
||||||
case imemo_memo:
|
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.memo.v1);
|
|
||||||
gc_mark(objspace, RANY(obj)->as.imemo.memo.v2);
|
|
||||||
gc_mark_maybe(objspace, RANY(obj)->as.imemo.memo.u3.value);
|
|
||||||
return;
|
|
||||||
case imemo_ment:
|
|
||||||
mark_method_entry(objspace, &RANY(obj)->as.imemo.ment);
|
|
||||||
return;
|
|
||||||
case imemo_iseq:
|
|
||||||
rb_iseq_mark((rb_iseq_t *)obj);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
rb_bug("T_IMEMO: unreachable");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gc_mark(objspace, any->as.basic.klass);
|
gc_mark(objspace, any->as.basic.klass);
|
||||||
|
@ -9241,7 +9267,7 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
|
||||||
const char *imemo_name;
|
const char *imemo_name;
|
||||||
switch (imemo_type(obj)) {
|
switch (imemo_type(obj)) {
|
||||||
#define IMEMO_NAME(x) case imemo_##x: imemo_name = #x; break;
|
#define IMEMO_NAME(x) case imemo_##x: imemo_name = #x; break;
|
||||||
IMEMO_NAME(none);
|
IMEMO_NAME(env);
|
||||||
IMEMO_NAME(cref);
|
IMEMO_NAME(cref);
|
||||||
IMEMO_NAME(svar);
|
IMEMO_NAME(svar);
|
||||||
IMEMO_NAME(throw_data);
|
IMEMO_NAME(throw_data);
|
||||||
|
@ -9249,7 +9275,6 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
|
||||||
IMEMO_NAME(memo);
|
IMEMO_NAME(memo);
|
||||||
IMEMO_NAME(ment);
|
IMEMO_NAME(ment);
|
||||||
IMEMO_NAME(iseq);
|
IMEMO_NAME(iseq);
|
||||||
default: rb_bug("unknown IMEMO");
|
|
||||||
#undef IMEMO_NAME
|
#undef IMEMO_NAME
|
||||||
}
|
}
|
||||||
snprintf(buff, buff_size, "%s %s", buff, imemo_name);
|
snprintf(buff, buff_size, "%s %s", buff, imemo_name);
|
||||||
|
|
16
internal.h
16
internal.h
|
@ -685,15 +685,15 @@ struct RIMemo {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum imemo_type {
|
enum imemo_type {
|
||||||
imemo_none = 0,
|
imemo_env = 0,
|
||||||
imemo_cref = 1,
|
imemo_cref = 1,
|
||||||
imemo_svar = 2,
|
imemo_svar = 2,
|
||||||
imemo_throw_data = 3,
|
imemo_throw_data = 3,
|
||||||
imemo_ifunc = 4,
|
imemo_ifunc = 4,
|
||||||
imemo_memo = 5,
|
imemo_memo = 5,
|
||||||
imemo_ment = 6,
|
imemo_ment = 6,
|
||||||
imemo_iseq = 7,
|
imemo_iseq = 7,
|
||||||
imemo_mask = 0x07
|
imemo_mask = 0x07
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline enum imemo_type
|
static inline enum imemo_type
|
||||||
|
|
81
proc.c
81
proc.c
|
@ -392,15 +392,12 @@ bind_eval(int argc, VALUE *argv, VALUE bindval)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const VALUE *
|
static const VALUE *
|
||||||
get_local_variable_ptr(VALUE envval, ID lid)
|
get_local_variable_ptr(const rb_env_t *env, ID lid)
|
||||||
{
|
{
|
||||||
rb_env_t *env;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
const rb_iseq_t *iseq;
|
const rb_iseq_t *iseq;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
GetEnvPtr(envval, env);
|
|
||||||
iseq = env->iseq;
|
iseq = env->iseq;
|
||||||
|
|
||||||
if (iseq && RUBY_VM_NORMAL_ISEQ_P(iseq)) {
|
if (iseq && RUBY_VM_NORMAL_ISEQ_P(iseq)) {
|
||||||
|
@ -413,7 +410,7 @@ get_local_variable_ptr(VALUE envval, ID lid)
|
||||||
else {
|
else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} while ((envval = rb_vm_env_prev_envval(env)) != Qfalse);
|
} while ((env = rb_vm_env_prev_env(env)) != NULL);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -470,8 +467,7 @@ bind_local_variables(VALUE bindval)
|
||||||
const rb_env_t *env;
|
const rb_env_t *env;
|
||||||
|
|
||||||
GetBindingPtr(bindval, bind);
|
GetBindingPtr(bindval, bind);
|
||||||
GetEnvPtr(VM_ENV_ENVVAL(vm_block_ep(&bind->block)), env);
|
env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
|
||||||
|
|
||||||
return rb_vm_env_local_variables(env);
|
return rb_vm_env_local_variables(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,7 +499,7 @@ bind_local_variable_get(VALUE bindval, VALUE sym)
|
||||||
|
|
||||||
GetBindingPtr(bindval, bind);
|
GetBindingPtr(bindval, bind);
|
||||||
|
|
||||||
if ((ptr = get_local_variable_ptr(VM_ENV_ENVVAL(vm_block_ep(&bind->block)), lid)) == NULL) {
|
if ((ptr = get_local_variable_ptr(VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block)), lid)) == NULL) {
|
||||||
sym = ID2SYM(lid);
|
sym = ID2SYM(lid);
|
||||||
undefined:
|
undefined:
|
||||||
rb_name_err_raise("local variable `%1$s' not defined for %2$s",
|
rb_name_err_raise("local variable `%1$s' not defined for %2$s",
|
||||||
|
@ -543,19 +539,19 @@ bind_local_variable_set(VALUE bindval, VALUE sym, VALUE val)
|
||||||
ID lid = check_local_id(bindval, &sym);
|
ID lid = check_local_id(bindval, &sym);
|
||||||
rb_binding_t *bind;
|
rb_binding_t *bind;
|
||||||
const VALUE *ptr;
|
const VALUE *ptr;
|
||||||
VALUE envval;
|
const rb_env_t *env;
|
||||||
|
|
||||||
if (!lid) lid = rb_intern_str(sym);
|
if (!lid) lid = rb_intern_str(sym);
|
||||||
|
|
||||||
GetBindingPtr(bindval, bind);
|
GetBindingPtr(bindval, bind);
|
||||||
envval = VM_ENV_ENVVAL(vm_block_ep(&bind->block));
|
env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
|
||||||
if ((ptr = get_local_variable_ptr(envval, lid)) == NULL) {
|
if ((ptr = get_local_variable_ptr(env, lid)) == NULL) {
|
||||||
/* not found. create new env */
|
/* not found. create new env */
|
||||||
ptr = rb_binding_add_dynavars(bind, 1, &lid);
|
ptr = rb_binding_add_dynavars(bind, 1, &lid);
|
||||||
envval = VM_ENV_ENVVAL(vm_block_ep(&bind->block));
|
env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
|
||||||
}
|
}
|
||||||
|
|
||||||
RB_OBJ_WRITE(envval, ptr, val);
|
RB_OBJ_WRITE(env, ptr, val);
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
@ -586,7 +582,7 @@ bind_local_variable_defined_p(VALUE bindval, VALUE sym)
|
||||||
if (!lid) return Qfalse;
|
if (!lid) return Qfalse;
|
||||||
|
|
||||||
GetBindingPtr(bindval, bind);
|
GetBindingPtr(bindval, bind);
|
||||||
return get_local_variable_ptr(VM_ENV_ENVVAL(vm_block_ep(&bind->block)), lid) ? Qtrue : Qfalse;
|
return get_local_variable_ptr(VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block)), lid) ? Qtrue : Qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2705,36 +2701,36 @@ localjump_reason(VALUE exc)
|
||||||
rb_cref_t *rb_vm_cref_new_toplevel(void); /* vm.c */
|
rb_cref_t *rb_vm_cref_new_toplevel(void); /* vm.c */
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
env_write(VALUE env, const VALUE *ep, int index, VALUE v)
|
env_write(VALUE envval, const VALUE *ep, int index, VALUE v)
|
||||||
{
|
{
|
||||||
VM_ASSERT(VM_ENV_ESCAPED_P(ep));
|
VM_ASSERT(VM_ENV_ESCAPED_P(ep));
|
||||||
VM_ASSERT(env == VM_ENV_ENVVAL(ep));
|
VM_ASSERT(envval == VM_ENV_ENVVAL(ep));
|
||||||
VM_ASSERT(vm_env_ep(env) == ep);
|
VM_ASSERT(vm_assert_env(envval));
|
||||||
|
|
||||||
RB_OBJ_WRITE(env, &ep[index], v);
|
RB_OBJ_WRITE(envval, &ep[index], v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static const rb_env_t *
|
||||||
env_clone(VALUE envval, const rb_cref_t *cref)
|
env_clone(const rb_env_t *env, const rb_cref_t *cref)
|
||||||
{
|
{
|
||||||
VALUE newenvval = TypedData_Wrap_Struct(RBASIC_CLASS(envval), RTYPEDDATA_TYPE(envval), 0);
|
VALUE *new_ep;
|
||||||
rb_env_t *env, *newenv;
|
VALUE *new_body;
|
||||||
int envsize;
|
const rb_env_t *new_env;
|
||||||
|
|
||||||
|
VM_ASSERT(env->ep > env->env);
|
||||||
|
VM_ASSERT(VM_ENV_ESCAPED_P(env->ep));
|
||||||
|
|
||||||
if (cref == NULL) {
|
if (cref == NULL) {
|
||||||
cref = rb_vm_cref_new_toplevel();
|
cref = rb_vm_cref_new_toplevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
GetEnvPtr(envval, env);
|
new_body = ALLOC_N(VALUE, env->env_size);
|
||||||
envsize = sizeof(rb_env_t) + (env->env_size - 1) * sizeof(VALUE);
|
MEMCPY(new_body, env->env, VALUE, env->env_size);
|
||||||
newenv = xmalloc(envsize);
|
new_ep = &new_body[env->ep - env->env];
|
||||||
memcpy(newenv, env, envsize);
|
new_env = vm_env_new(new_ep, new_body, env->env_size, env->iseq);
|
||||||
VM_ASSERT(env->ep > env->env);
|
RB_OBJ_WRITE(new_env, &new_ep[VM_ENV_DATA_INDEX_ME_CREF], (VALUE)cref);
|
||||||
newenv->ep = &newenv->env[env->ep - env->env];
|
VM_ASSERT(VM_ENV_ESCAPED_P(new_ep));
|
||||||
VM_FORCE_WRITE(&newenv->ep[VM_ENV_DATA_INDEX_ENV], newenvval);
|
return new_env;
|
||||||
RTYPEDDATA_DATA(newenvval) = newenv;
|
|
||||||
env_write(newenvval, newenv->ep, VM_ENV_DATA_INDEX_ME_CREF, (VALUE)cref);
|
|
||||||
return newenvval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2755,12 +2751,12 @@ env_clone(VALUE envval, const rb_cref_t *cref)
|
||||||
static VALUE
|
static VALUE
|
||||||
proc_binding(VALUE self)
|
proc_binding(VALUE self)
|
||||||
{
|
{
|
||||||
VALUE bindval, envval = Qundef, binding_self = Qundef;
|
VALUE bindval, binding_self = Qundef;
|
||||||
rb_binding_t *bind;
|
rb_binding_t *bind;
|
||||||
const rb_proc_t *proc;
|
const rb_proc_t *proc;
|
||||||
const rb_iseq_t *iseq = NULL;
|
const rb_iseq_t *iseq = NULL;
|
||||||
const struct rb_block *block;
|
const struct rb_block *block;
|
||||||
const rb_env_t *env;
|
const rb_env_t *env = NULL;
|
||||||
|
|
||||||
GetProcPtr(self, proc);
|
GetProcPtr(self, proc);
|
||||||
block = &proc->block;
|
block = &proc->block;
|
||||||
|
@ -2770,7 +2766,7 @@ proc_binding(VALUE self)
|
||||||
case block_type_iseq:
|
case block_type_iseq:
|
||||||
iseq = block->as.captured.code.iseq;
|
iseq = block->as.captured.code.iseq;
|
||||||
binding_self = block->as.captured.self;
|
binding_self = block->as.captured.self;
|
||||||
envval = VM_ENV_ENVVAL(block->as.captured.ep);
|
env = VM_ENV_ENVVAL_PTR(block->as.captured.ep);
|
||||||
break;
|
break;
|
||||||
case block_type_proc:
|
case block_type_proc:
|
||||||
GetProcPtr(block->as.proc, proc);
|
GetProcPtr(block->as.proc, proc);
|
||||||
|
@ -2783,16 +2779,12 @@ proc_binding(VALUE self)
|
||||||
const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
|
const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
|
||||||
if (IS_METHOD_PROC_IFUNC(ifunc)) {
|
if (IS_METHOD_PROC_IFUNC(ifunc)) {
|
||||||
VALUE method = (VALUE)ifunc->data;
|
VALUE method = (VALUE)ifunc->data;
|
||||||
rb_env_t *newenv;
|
|
||||||
|
|
||||||
iseq = rb_method_iseq(method);
|
|
||||||
envval = VM_ENV_ENVVAL(block->as.captured.ep);
|
|
||||||
envval = env_clone(envval, method_cref(method));
|
|
||||||
binding_self = method_receiver(method);
|
binding_self = method_receiver(method);
|
||||||
|
iseq = rb_method_iseq(method);
|
||||||
GetEnvPtr(envval, newenv);
|
env = VM_ENV_ENVVAL_PTR(block->as.captured.ep);
|
||||||
|
env = env_clone(env, method_cref(method));
|
||||||
/* set empty iseq */
|
/* set empty iseq */
|
||||||
newenv->iseq = rb_iseq_new(NULL, rb_str_new2("<empty iseq>"), rb_str_new2("<empty_iseq>"), Qnil, 0, ISEQ_TYPE_TOP);
|
RB_OBJ_WRITE(env, &env->iseq, rb_iseq_new(NULL, rb_str_new2("<empty iseq>"), rb_str_new2("<empty_iseq>"), Qnil, 0, ISEQ_TYPE_TOP));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2805,7 +2797,6 @@ proc_binding(VALUE self)
|
||||||
|
|
||||||
bindval = rb_binding_alloc(rb_cBinding);
|
bindval = rb_binding_alloc(rb_cBinding);
|
||||||
GetBindingPtr(bindval, bind);
|
GetBindingPtr(bindval, bind);
|
||||||
GetEnvPtr(envval, env);
|
|
||||||
|
|
||||||
bind->block.as.captured.self = binding_self;
|
bind->block.as.captured.self = binding_self;
|
||||||
bind->block.as.captured.code.iseq = env->iseq;
|
bind->block.as.captured.code.iseq = env->iseq;
|
||||||
|
|
172
vm.c
172
vm.c
|
@ -98,8 +98,6 @@ VM_CFP_IN_HEAP_P(const rb_thread_t *th, const rb_control_frame_t *cfp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int envval_p(VALUE envval);
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
VM_EP_IN_HEAP_P(const rb_thread_t *th, const VALUE *ep)
|
VM_EP_IN_HEAP_P(const rb_thread_t *th, const VALUE *ep)
|
||||||
{
|
{
|
||||||
|
@ -120,11 +118,10 @@ vm_ep_in_heap_p_(const rb_thread_t *th, const VALUE *ep)
|
||||||
VALUE envval = ep[VM_ENV_DATA_INDEX_ENV]; /* VM_ENV_ENVVAL(ep); */
|
VALUE envval = ep[VM_ENV_DATA_INDEX_ENV]; /* VM_ENV_ENVVAL(ep); */
|
||||||
|
|
||||||
if (envval != Qundef) {
|
if (envval != Qundef) {
|
||||||
rb_env_t *env;
|
const rb_env_t *env = (const rb_env_t *)envval;
|
||||||
|
|
||||||
|
VM_ASSERT(vm_assert_env(envval));
|
||||||
VM_ASSERT(VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED));
|
VM_ASSERT(VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED));
|
||||||
VM_ASSERT(envval_p(envval));
|
|
||||||
GetEnvPtr(envval, env);
|
|
||||||
VM_ASSERT(env->ep == ep);
|
VM_ASSERT(env->ep == ep);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -268,8 +265,7 @@ vm_cref_dump(const char *mesg, const rb_cref_t *cref)
|
||||||
static void
|
static void
|
||||||
vm_bind_update_env(rb_binding_t *bind, VALUE envval)
|
vm_bind_update_env(rb_binding_t *bind, VALUE envval)
|
||||||
{
|
{
|
||||||
rb_env_t *env;
|
const rb_env_t *env = (rb_env_t *)envval;
|
||||||
GetEnvPtr(envval, env);
|
|
||||||
bind->block.as.captured.code.iseq = env->iseq;
|
bind->block.as.captured.code.iseq = env->iseq;
|
||||||
bind->block.as.captured.ep = env->ep;
|
bind->block.as.captured.ep = env->ep;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +305,6 @@ rb_next_class_serial(void)
|
||||||
|
|
||||||
VALUE rb_cRubyVM;
|
VALUE rb_cRubyVM;
|
||||||
VALUE rb_cThread;
|
VALUE rb_cThread;
|
||||||
VALUE rb_cEnv;
|
|
||||||
VALUE rb_mRubyVMFrozenCore;
|
VALUE rb_mRubyVMFrozenCore;
|
||||||
|
|
||||||
#define ruby_vm_redefined_flag GET_VM()->redefined_flag
|
#define ruby_vm_redefined_flag GET_VM()->redefined_flag
|
||||||
|
@ -583,100 +578,29 @@ ruby_vm_run_at_exit_hooks(rb_vm_t *vm)
|
||||||
|
|
||||||
/* Env */
|
/* Env */
|
||||||
|
|
||||||
/*
|
static VALUE check_env_value(const rb_env_t *env);
|
||||||
env{
|
|
||||||
env[0] // special (block or prev env)
|
|
||||||
env[1] // env object
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
env_mark(void * const ptr)
|
|
||||||
{
|
|
||||||
const rb_env_t * const env = ptr;
|
|
||||||
|
|
||||||
/* TODO: should mark more restricted range */
|
|
||||||
RUBY_GC_INFO("env->env\n");
|
|
||||||
VM_ASSERT(VM_ENV_FLAGS(env->ep, VM_ENV_FLAG_ESCAPED));
|
|
||||||
|
|
||||||
rb_gc_mark_values((long)env->env_size, env->env);
|
|
||||||
VM_ENV_FLAGS_SET(env->ep, VM_ENV_FLAG_WB_REQUIRED);
|
|
||||||
|
|
||||||
RUBY_MARK_UNLESS_NULL(rb_vm_env_prev_envval(env));
|
|
||||||
RUBY_MARK_UNLESS_NULL((VALUE)env->iseq);
|
|
||||||
RUBY_MARK_LEAVE("env");
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
env_memsize(const void *ptr)
|
|
||||||
{
|
|
||||||
const rb_env_t * const env = ptr;
|
|
||||||
size_t size = sizeof(rb_env_t);
|
|
||||||
|
|
||||||
size += (env->env_size - 1) * sizeof(VALUE);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if VM_CHECK_MODE > 0
|
|
||||||
static void
|
|
||||||
env_free(void *ptr)
|
|
||||||
{
|
|
||||||
if (ptr) {
|
|
||||||
rb_env_t * const env = ptr;
|
|
||||||
VM_ASSERT(VM_ENV_FLAGS(env->ep, VM_ENV_FLAG_ESCAPED));
|
|
||||||
free(env);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define env_free RUBY_TYPED_DEFAULT_FREE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const rb_data_type_t env_data_type = {
|
|
||||||
"VM/env",
|
|
||||||
{env_mark, env_free, env_memsize,},
|
|
||||||
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
||||||
};
|
|
||||||
|
|
||||||
#if VM_CHECK_MODE > 0
|
|
||||||
static int
|
|
||||||
envval_p(VALUE envval)
|
|
||||||
{
|
|
||||||
if (rb_typeddata_is_kind_of(envval, &env_data_type)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rb_obj_info_dump(envval);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static VALUE check_env_value(VALUE envval);
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_env(rb_env_t * const env)
|
check_env(const rb_env_t *env)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "---\n");
|
fprintf(stderr, "---\n");
|
||||||
fprintf(stderr, "envptr: %p\n", (void *)&env->ep[0]);
|
fprintf(stderr, "envptr: %p\n", (void *)&env->ep[0]);
|
||||||
fprintf(stderr, "envval: %10p ", (void *)env->ep[1]);
|
fprintf(stderr, "envval: %10p ", (void *)env->ep[1]);
|
||||||
dp(env->ep[1]);
|
dp(env->ep[1]);
|
||||||
fprintf(stderr, "ep: %10p\n", (void *)env->ep);
|
fprintf(stderr, "ep: %10p\n", (void *)env->ep);
|
||||||
if (rb_vm_env_prev_envval(env)) {
|
if (rb_vm_env_prev_env(env)) {
|
||||||
fprintf(stderr, ">>\n");
|
fprintf(stderr, ">>\n");
|
||||||
check_env_value(rb_vm_env_prev_envval(env));
|
check_env_value(rb_vm_env_prev_env(env));
|
||||||
fprintf(stderr, "<<\n");
|
fprintf(stderr, "<<\n");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
check_env_value(VALUE envval)
|
check_env_value(const rb_env_t *env)
|
||||||
{
|
{
|
||||||
rb_env_t *env;
|
|
||||||
GetEnvPtr(envval, env);
|
|
||||||
|
|
||||||
if (check_env(env)) {
|
if (check_env(env)) {
|
||||||
return envval;
|
return (VALUE)env;
|
||||||
}
|
}
|
||||||
rb_bug("invalid env");
|
rb_bug("invalid env");
|
||||||
return Qnil; /* unreachable */
|
return Qnil; /* unreachable */
|
||||||
|
@ -703,10 +627,11 @@ vm_block_handler_escape(rb_thread_t *th, VALUE block_handler, VALUE *procvalptr)
|
||||||
static VALUE
|
static VALUE
|
||||||
vm_make_env_each(rb_thread_t *const th, rb_control_frame_t *const cfp)
|
vm_make_env_each(rb_thread_t *const th, rb_control_frame_t *const cfp)
|
||||||
{
|
{
|
||||||
VALUE envval, blockprocval = Qfalse;
|
VALUE blockprocval = Qfalse;
|
||||||
const VALUE * const ep = cfp->ep;
|
const VALUE * const ep = cfp->ep;
|
||||||
rb_env_t *env;
|
const rb_env_t *env;
|
||||||
const VALUE *new_ep;
|
const rb_iseq_t *env_iseq;
|
||||||
|
VALUE *env_body, *env_ep;
|
||||||
int local_size, env_size;
|
int local_size, env_size;
|
||||||
|
|
||||||
if (VM_ENV_ESCAPED_P(ep)) {
|
if (VM_ENV_ESCAPED_P(ep)) {
|
||||||
|
@ -759,12 +684,8 @@ vm_make_env_each(rb_thread_t *const th, rb_control_frame_t *const cfp)
|
||||||
env_size = local_size +
|
env_size = local_size +
|
||||||
1 /* envval */ +
|
1 /* envval */ +
|
||||||
(blockprocval ? 1 : 0) /* blockprocval */;
|
(blockprocval ? 1 : 0) /* blockprocval */;
|
||||||
envval = TypedData_Wrap_Struct(rb_cEnv, &env_data_type, 0);
|
env_body = ALLOC_N(VALUE, env_size);
|
||||||
env = xmalloc(sizeof(rb_env_t) + (env_size - 1 /* rb_env_t::env[1] */) * sizeof(VALUE));
|
MEMCPY(env_body, ep - (local_size - 1 /* specval */), VALUE, local_size);
|
||||||
env->env_size = env_size;
|
|
||||||
|
|
||||||
/* setup env */
|
|
||||||
MEMCPY((VALUE *)env->env, ep - (local_size - 1 /* specval */), VALUE, local_size);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
for (i = 0; i < local_size; i++) {
|
for (i = 0; i < local_size; i++) {
|
||||||
|
@ -775,29 +696,16 @@ vm_make_env_each(rb_thread_t *const th, rb_control_frame_t *const cfp)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* be careful not to trigger GC after this */
|
env_iseq = RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) ? cfp->iseq : NULL;
|
||||||
RTYPEDDATA_DATA(envval) = env;
|
env_ep = &env_body[local_size - 1 /* specval */];
|
||||||
|
|
||||||
new_ep = &env->env[local_size - 1 /* specval */];
|
env = vm_env_new(env_ep, env_body, env_size, env_iseq);
|
||||||
RB_OBJ_WRITE(envval, &new_ep[1], envval);
|
|
||||||
if (blockprocval) RB_OBJ_WRITE(envval, &new_ep[2], blockprocval);
|
|
||||||
VM_ENV_FLAGS_SET(new_ep, VM_ENV_FLAG_ESCAPED | VM_ENV_FLAG_WB_REQUIRED);
|
|
||||||
|
|
||||||
/*
|
if (blockprocval) RB_OBJ_WRITE(env, &env_ep[2], blockprocval);
|
||||||
* must happen after TypedData_Wrap_Struct to ensure penvval is markable
|
cfp->ep = env_ep;
|
||||||
* in case object allocation triggers GC and clobbers penvval.
|
VM_ENV_FLAGS_SET(env_ep, VM_ENV_FLAG_ESCAPED | VM_ENV_FLAG_WB_REQUIRED);
|
||||||
*/
|
VM_STACK_ENV_WRITE(ep, 0, (VALUE)env); /* GC mark */
|
||||||
VM_STACK_ENV_WRITE(ep, 0, envval); /* GC mark */
|
return (VALUE)env;
|
||||||
|
|
||||||
/* setup env object */
|
|
||||||
env->ep = cfp->ep = new_ep;
|
|
||||||
env->iseq = cfp->iseq;
|
|
||||||
|
|
||||||
if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
|
||||||
env->iseq = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return envval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -806,7 +714,7 @@ vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp)
|
||||||
VALUE envval = vm_make_env_each(th, cfp);
|
VALUE envval = vm_make_env_each(th, cfp);
|
||||||
|
|
||||||
if (PROCDEBUG) {
|
if (PROCDEBUG) {
|
||||||
check_env_value(envval);
|
check_env_value((const rb_env_t *)envval);
|
||||||
}
|
}
|
||||||
|
|
||||||
return envval;
|
return envval;
|
||||||
|
@ -822,16 +730,16 @@ rb_vm_stack_to_heap(rb_thread_t *th)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
const rb_env_t *
|
||||||
rb_vm_env_prev_envval(const rb_env_t *env)
|
rb_vm_env_prev_env(const rb_env_t *env)
|
||||||
{
|
{
|
||||||
const VALUE *ep = env->ep;
|
const VALUE *ep = env->ep;
|
||||||
|
|
||||||
if (VM_ENV_LOCAL_P(ep)) {
|
if (VM_ENV_LOCAL_P(ep)) {
|
||||||
return Qfalse;
|
return NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return VM_ENV_ENVVAL(VM_ENV_PREV_EP(ep));
|
return VM_ENV_ENVVAL_PTR(VM_ENV_PREV_EP(ep));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,20 +757,16 @@ collect_local_variables_in_iseq(const rb_iseq_t *iseq, const struct local_var_li
|
||||||
static void
|
static void
|
||||||
collect_local_variables_in_env(const rb_env_t *env, const struct local_var_list *vars)
|
collect_local_variables_in_env(const rb_env_t *env, const struct local_var_list *vars)
|
||||||
{
|
{
|
||||||
VALUE prev_envval;
|
do {
|
||||||
|
collect_local_variables_in_iseq(env->iseq, vars);
|
||||||
while (collect_local_variables_in_iseq(env->iseq, vars), (prev_envval = rb_vm_env_prev_envval(env)) != Qfalse) {
|
} while ((env = rb_vm_env_prev_env(env)) != NULL);
|
||||||
GetEnvPtr(prev_envval, env);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vm_collect_local_variables_in_heap(rb_thread_t *th, const VALUE *ep, const struct local_var_list *vars)
|
vm_collect_local_variables_in_heap(rb_thread_t *th, const VALUE *ep, const struct local_var_list *vars)
|
||||||
{
|
{
|
||||||
if (VM_ENV_ESCAPED_P(ep)) {
|
if (VM_ENV_ESCAPED_P(ep)) {
|
||||||
rb_env_t *env;
|
collect_local_variables_in_env(VM_ENV_ENVVAL_PTR(ep), vars);
|
||||||
GetEnvPtr(VM_ENV_ENVVAL(ep), env);
|
|
||||||
collect_local_variables_in_env(env, vars);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1010,10 +914,9 @@ rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp)
|
||||||
const VALUE *
|
const VALUE *
|
||||||
rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
|
rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
|
||||||
{
|
{
|
||||||
VALUE envval;
|
VALUE envval, path = bind->path;
|
||||||
VALUE path = bind->path;
|
|
||||||
const struct rb_block *base_block;
|
const struct rb_block *base_block;
|
||||||
rb_env_t *env;
|
const rb_env_t *env;
|
||||||
rb_thread_t *th = GET_THREAD();
|
rb_thread_t *th = GET_THREAD();
|
||||||
const rb_iseq_t *base_iseq, *iseq;
|
const rb_iseq_t *base_iseq, *iseq;
|
||||||
NODE *node = 0;
|
NODE *node = 0;
|
||||||
|
@ -1045,7 +948,7 @@ rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
|
||||||
vm_bind_update_env(bind, envval = vm_make_env_object(th, th->cfp));
|
vm_bind_update_env(bind, envval = vm_make_env_object(th, th->cfp));
|
||||||
rb_vm_pop_frame(th);
|
rb_vm_pop_frame(th);
|
||||||
|
|
||||||
GetEnvPtr(envval, env);
|
env = (const rb_env_t *)envval;
|
||||||
return env->env;
|
return env->env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2859,11 +2762,6 @@ Init_VM(void)
|
||||||
rb_gc_register_mark_object(fcore);
|
rb_gc_register_mark_object(fcore);
|
||||||
rb_mRubyVMFrozenCore = fcore;
|
rb_mRubyVMFrozenCore = fcore;
|
||||||
|
|
||||||
/* ::RubyVM::Env */
|
|
||||||
rb_cEnv = rb_define_class_under(rb_cRubyVM, "Env", rb_cObject);
|
|
||||||
rb_undef_alloc_func(rb_cEnv);
|
|
||||||
rb_undef_method(CLASS_OF(rb_cEnv), "new");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Document-class: Thread
|
* Document-class: Thread
|
||||||
*
|
*
|
||||||
|
|
52
vm_core.h
52
vm_core.h
|
@ -858,7 +858,6 @@ VALUE rb_iseq_coverage(const rb_iseq_t *iseq);
|
||||||
|
|
||||||
RUBY_EXTERN VALUE rb_cISeq;
|
RUBY_EXTERN VALUE rb_cISeq;
|
||||||
RUBY_EXTERN VALUE rb_cRubyVM;
|
RUBY_EXTERN VALUE rb_cRubyVM;
|
||||||
RUBY_EXTERN VALUE rb_cEnv;
|
|
||||||
RUBY_EXTERN VALUE rb_mRubyVMFrozenCore;
|
RUBY_EXTERN VALUE rb_mRubyVMFrozenCore;
|
||||||
RUBY_SYMBOL_EXPORT_END
|
RUBY_SYMBOL_EXPORT_END
|
||||||
|
|
||||||
|
@ -872,14 +871,12 @@ typedef struct {
|
||||||
int8_t is_lambda; /* bool */
|
int8_t is_lambda; /* bool */
|
||||||
} rb_proc_t;
|
} rb_proc_t;
|
||||||
|
|
||||||
#define GetEnvPtr(obj, ptr) \
|
|
||||||
GetCoreDataFromValue((obj), rb_env_t, (ptr))
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int env_size;
|
VALUE flags; /* imemo header */
|
||||||
const VALUE *ep;
|
|
||||||
const rb_iseq_t *iseq;
|
const rb_iseq_t *iseq;
|
||||||
const VALUE env[1]; /* flexible array */
|
const VALUE *ep;
|
||||||
|
const VALUE *env;
|
||||||
|
unsigned int env_size;
|
||||||
} rb_env_t;
|
} rb_env_t;
|
||||||
|
|
||||||
extern const rb_data_type_t ruby_binding_data_type;
|
extern const rb_data_type_t ruby_binding_data_type;
|
||||||
|
@ -1070,11 +1067,29 @@ VM_ENV_ESCAPED_P(const VALUE *ep)
|
||||||
return VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED) ? 1 : 0;
|
return VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if VM_CHECK_MODE > 0
|
||||||
|
static inline int
|
||||||
|
vm_assert_env(VALUE obj)
|
||||||
|
{
|
||||||
|
VM_ASSERT(RB_TYPE_P(obj, T_IMEMO));
|
||||||
|
VM_ASSERT(imemo_type(obj) == imemo_env);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline VALUE
|
static inline VALUE
|
||||||
VM_ENV_ENVVAL(const VALUE *ep)
|
VM_ENV_ENVVAL(const VALUE *ep)
|
||||||
{
|
{
|
||||||
|
VALUE envval = ep[VM_ENV_DATA_INDEX_ENV];
|
||||||
VM_ASSERT(VM_ENV_ESCAPED_P(ep));
|
VM_ASSERT(VM_ENV_ESCAPED_P(ep));
|
||||||
return ep[VM_ENV_DATA_INDEX_ENV];
|
VM_ASSERT(vm_assert_env(envval));
|
||||||
|
return envval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const rb_env_t *
|
||||||
|
VM_ENV_ENVVAL_PTR(const VALUE *ep)
|
||||||
|
{
|
||||||
|
return (const rb_env_t *)VM_ENV_ENVVAL(ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline VALUE
|
static inline VALUE
|
||||||
|
@ -1087,6 +1102,15 @@ VM_ENV_PROCVAL(const VALUE *ep)
|
||||||
return ep[VM_ENV_DATA_INDEX_ENV_PROC];
|
return ep[VM_ENV_DATA_INDEX_ENV_PROC];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const rb_env_t *
|
||||||
|
vm_env_new(VALUE *env_ep, VALUE *env_body, unsigned int env_size, const rb_iseq_t *iseq)
|
||||||
|
{
|
||||||
|
rb_env_t *env = (rb_env_t *)rb_imemo_new(imemo_env, (VALUE)env_ep, (VALUE)env_body, 0, (VALUE)iseq);
|
||||||
|
env->env_size = env_size;
|
||||||
|
env_ep[VM_ENV_DATA_INDEX_ENV] = (VALUE)env;
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
VM_FORCE_WRITE(const VALUE *ptr, VALUE v)
|
VM_FORCE_WRITE(const VALUE *ptr, VALUE v)
|
||||||
{
|
{
|
||||||
|
@ -1107,16 +1131,6 @@ VM_STACK_ENV_WRITE(const VALUE *ep, int index, VALUE v)
|
||||||
VM_FORCE_WRITE(&ep[index], v);
|
VM_FORCE_WRITE(&ep[index], v);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if VM_CHECK_MODE > 0
|
|
||||||
static inline const VALUE *
|
|
||||||
vm_env_ep(VALUE envval)
|
|
||||||
{
|
|
||||||
rb_env_t *env;
|
|
||||||
GetEnvPtr(envval, env);
|
|
||||||
return env->ep;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const VALUE *rb_vm_ep_local_ep(const VALUE *ep);
|
const VALUE *rb_vm_ep_local_ep(const VALUE *ep);
|
||||||
VALUE rb_vm_frame_block_handler(const rb_control_frame_t *cfp);
|
VALUE rb_vm_frame_block_handler(const rb_control_frame_t *cfp);
|
||||||
|
|
||||||
|
@ -1381,7 +1395,7 @@ VALUE rb_vm_make_proc_lambda(rb_thread_t *th, const struct rb_captured_block *ca
|
||||||
VALUE rb_vm_make_proc(rb_thread_t *th, const struct rb_captured_block *captured, VALUE klass);
|
VALUE rb_vm_make_proc(rb_thread_t *th, const struct rb_captured_block *captured, VALUE klass);
|
||||||
VALUE rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp);
|
VALUE rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp);
|
||||||
VALUE rb_vm_env_local_variables(const rb_env_t *env);
|
VALUE rb_vm_env_local_variables(const rb_env_t *env);
|
||||||
VALUE rb_vm_env_prev_envval(const rb_env_t *env);
|
const rb_env_t *rb_vm_env_prev_env(const rb_env_t *env);
|
||||||
const VALUE *rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars);
|
const VALUE *rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars);
|
||||||
void rb_vm_inc_const_missing_count(void);
|
void rb_vm_inc_const_missing_count(void);
|
||||||
void rb_vm_gvl_destroy(rb_vm_t *vm);
|
void rb_vm_gvl_destroy(rb_vm_t *vm);
|
||||||
|
|
17
vm_dump.c
17
vm_dump.c
|
@ -182,14 +182,12 @@ rb_vmdebug_stack_dump_raw_current(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_vmdebug_env_dump_raw(rb_env_t *env, const VALUE *ep)
|
rb_vmdebug_env_dump_raw(const rb_env_t *env, const VALUE *ep)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned int i;
|
||||||
fprintf(stderr, "-- env --------------------\n");
|
fprintf(stderr, "-- env --------------------\n");
|
||||||
|
|
||||||
while (env) {
|
while (env) {
|
||||||
VALUE prev_envval;
|
|
||||||
|
|
||||||
fprintf(stderr, "--\n");
|
fprintf(stderr, "--\n");
|
||||||
for (i = 0; i < env->env_size; i++) {
|
for (i = 0; i < env->env_size; i++) {
|
||||||
fprintf(stderr, "%04d: %08"PRIxVALUE" (%p)", i, env->env[i], (void *)&env->env[i]);
|
fprintf(stderr, "%04d: %08"PRIxVALUE" (%p)", i, env->env[i], (void *)&env->env[i]);
|
||||||
|
@ -197,12 +195,7 @@ rb_vmdebug_env_dump_raw(rb_env_t *env, const VALUE *ep)
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prev_envval = rb_vm_env_prev_envval(env)) != Qfalse) {
|
env = rb_vm_env_prev_env(env);
|
||||||
GetEnvPtr(prev_envval, env);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
env = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fprintf(stderr, "---------------------------\n");
|
fprintf(stderr, "---------------------------\n");
|
||||||
}
|
}
|
||||||
|
@ -210,14 +203,14 @@ rb_vmdebug_env_dump_raw(rb_env_t *env, const VALUE *ep)
|
||||||
void
|
void
|
||||||
rb_vmdebug_proc_dump_raw(rb_proc_t *proc)
|
rb_vmdebug_proc_dump_raw(rb_proc_t *proc)
|
||||||
{
|
{
|
||||||
rb_env_t *env;
|
const rb_env_t *env;
|
||||||
char *selfstr;
|
char *selfstr;
|
||||||
VALUE val = rb_inspect(vm_block_self(&proc->block));
|
VALUE val = rb_inspect(vm_block_self(&proc->block));
|
||||||
selfstr = StringValueCStr(val);
|
selfstr = StringValueCStr(val);
|
||||||
|
|
||||||
fprintf(stderr, "-- proc -------------------\n");
|
fprintf(stderr, "-- proc -------------------\n");
|
||||||
fprintf(stderr, "self: %s\n", selfstr);
|
fprintf(stderr, "self: %s\n", selfstr);
|
||||||
GetEnvPtr(VM_ENV_ENVVAL(vm_block_ep(&proc->block)), env);
|
env = VM_ENV_ENVVAL_PTR(vm_block_ep(&proc->block));
|
||||||
rb_vmdebug_env_dump_raw(env, vm_block_ep(&proc->block));
|
rb_vmdebug_env_dump_raw(env, vm_block_ep(&proc->block));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ static void
|
||||||
vm_check_frame_detail(VALUE type, int req_block, int req_me, int req_cref, VALUE specval, VALUE cref_or_me)
|
vm_check_frame_detail(VALUE type, int req_block, int req_me, int req_cref, VALUE specval, VALUE cref_or_me)
|
||||||
{
|
{
|
||||||
unsigned int magic = (unsigned int)(type & VM_FRAME_MAGIC_MASK);
|
unsigned int magic = (unsigned int)(type & VM_FRAME_MAGIC_MASK);
|
||||||
enum imemo_type cref_or_me_type = imemo_none;
|
enum imemo_type cref_or_me_type = imemo_env; /* impossible value */
|
||||||
|
|
||||||
if (RB_TYPE_P(cref_or_me, T_IMEMO)) {
|
if (RB_TYPE_P(cref_or_me, T_IMEMO)) {
|
||||||
cref_or_me_type = imemo_type(cref_or_me);
|
cref_or_me_type = imemo_type(cref_or_me);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче