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

compile.c: struct accessors

* compile.c (rb_method_for_self_aref, rb_method_for_self_aset):
  move from iseq.c to build from node instead of arrays.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48876 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2014-12-17 03:20:58 +00:00
parent fd639a4c3b
commit 467830e867
3 changed files with 91 additions and 122 deletions

View file

@ -1,3 +1,8 @@
Wed Dec 17 12:20:56 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* compile.c (rb_method_for_self_aref, rb_method_for_self_aset):
move from iseq.c to build from node instead of arrays.
Wed Dec 17 10:50:09 2014 SHIBATA Hiroshi <shibata.hiroshi@gmail.com>
* test/gdbm/test_gdbm.rb: Added test for each_key called without a block.

View file

@ -6234,3 +6234,89 @@ rb_parse_in_main(void)
{
return GET_THREAD()->parse_in_eval < 0;
}
static int
caller_location(VALUE *path, VALUE *absolute_path)
{
const rb_thread_t *const th = GET_THREAD();
const rb_control_frame_t *const cfp =
rb_vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp) {
int line = rb_vm_get_sourceline(cfp);
*path = cfp->iseq->location.path;
*absolute_path = cfp->iseq->location.absolute_path;
return line;
}
else {
*path = rb_str_new2("<compiled>");
*absolute_path = *path;
return 1;
}
}
typedef struct {
VALUE arg;
rb_insn_func_t func;
int line;
} accessor_args;
static VALUE
method_for_self(VALUE name, VALUE arg, rb_insn_func_t func,
VALUE (*build)(rb_iseq_t *, LINK_ANCHOR *, VALUE))
{
VALUE path, absolute_path;
accessor_args acc;
acc.arg = arg;
acc.func = func;
acc.line = caller_location(&path, &absolute_path);
return rb_iseq_new_with_opt(NEW_IFUNC(build, (VALUE)&acc),
rb_sym2str(name), path, absolute_path,
INT2FIX(acc.line), 0, ISEQ_TYPE_METHOD, 0);
}
static VALUE
for_self_aref(rb_iseq_t *iseq, LINK_ANCHOR *ret, VALUE a)
{
const accessor_args *const args = (void *)a;
const int line = args->line;
iseq_set_local_table(iseq, 0);
iseq->param.lead_num = 0;
iseq->param.size = 0;
ADD_INSN1(ret, line, putobject, args->arg);
ADD_INSN1(ret, line, opt_call_c_function, (VALUE)args->func);
return Qnil;
}
static VALUE
for_self_aset(rb_iseq_t *iseq, LINK_ANCHOR *ret, VALUE a)
{
const accessor_args *const args = (void *)a;
const int line = args->line;
static const ID vars[] = {1, idUScore};
iseq_set_local_table(iseq, vars);
iseq->param.lead_num = 1;
iseq->param.size = 1;
ADD_INSN2(ret, line, getlocal, INT2FIX(numberof(vars)-0), INT2FIX(0));
ADD_INSN1(ret, line, putobject, args->arg);
ADD_INSN1(ret, line, opt_call_c_function, (VALUE)args->func);
ADD_INSN(ret, line, pop);
return Qnil;
}
VALUE
rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func)
{
return method_for_self(name, arg, func, for_self_aref);
}
VALUE
rb_method_for_self_aset(VALUE name, VALUE arg, rb_insn_func_t func)
{
return method_for_self(name, arg, func, for_self_aset);
}

122
iseq.c
View file

@ -553,128 +553,6 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt)
return iseqval;
}
static VALUE
caller_location(VALUE *path, VALUE *absolute_path)
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp) {
int line = rb_vm_get_sourceline(cfp);
*path = cfp->iseq->location.path;
*absolute_path = cfp->iseq->location.absolute_path;
return INT2FIX(line);
}
else {
*path = rb_str_new2("<compiled>");
*absolute_path = *path;
return INT2FIX(1);
}
}
VALUE
rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func)
{
VALUE iseqval = iseq_alloc(rb_cISeq);
rb_iseq_t *iseq;
VALUE path, absolute_path;
VALUE lineno = caller_location(&path, &absolute_path);
VALUE parent = 0;
VALUE misc, locals, params, exception, body, send_arg;
GetISeqPtr(iseqval, iseq);
iseq->self = iseqval;
iseq->local_iseq = iseq;
prepare_iseq_build(iseq, rb_sym2str(name), path, absolute_path,
lineno, parent,
ISEQ_TYPE_METHOD, &COMPILE_OPTION_DEFAULT);
misc = params = rb_hash_new(); /* empty */
locals = exception = rb_ary_tmp_new(0); /* empty */
body = rb_ary_tmp_new(5);
#define S(s) ID2SYM(rb_intern(#s))
#define ADD(a) rb_ary_push(body, rb_obj_hide(a))
/* def name; self[arg]; end */
ADD(lineno);
ADD(rb_ary_new3(2, S(putobject), arg));
#if SIZEOF_VALUE <= SIZEOF_LONG
send_arg = LONG2NUM((SIGNED_VALUE)func);
#else
send_arg = LL2NUM((SIGNED_VALUE)func);
#endif
send_arg = rb_ary_new3(2, S(opt_call_c_function), send_arg);
ADD(send_arg);
ADD(rb_ary_new3(1, S(leave)));
#undef S
#undef ADD
rb_iseq_build_from_ary(iseq, misc, locals, params, exception, body);
cleanup_iseq_build(iseq);
rb_ary_clear(body);
rb_ary_clear(send_arg);
return iseqval;
}
VALUE
rb_method_for_self_aset(VALUE name, VALUE arg, rb_insn_func_t func)
{
VALUE iseqval = iseq_alloc(rb_cISeq);
rb_iseq_t *iseq;
VALUE path, absolute_path;
VALUE lineno = caller_location(&path, &absolute_path);
VALUE parent = 0;
VALUE misc, locals, params, exception, body, send_arg;
GetISeqPtr(iseqval, iseq);
iseq->self = iseqval;
iseq->local_iseq = iseq;
prepare_iseq_build(iseq, rb_sym2str(name), path, absolute_path,
lineno, parent,
ISEQ_TYPE_METHOD, &COMPILE_OPTION_DEFAULT);
/* def name=(val); self[arg] = val; end */
#define S(s) ID2SYM(rb_intern(#s))
#define ADD(a) rb_ary_push(body, rb_obj_hide(a))
misc = rb_hash_new(); /* empty */
locals = rb_obj_hide(rb_ary_new3(1, S(val)));
params = rb_hash_new();
exception = rb_ary_tmp_new(0); /* empty */
body = rb_ary_tmp_new(6);
rb_hash_aset(params, S(lead_num), INT2FIX(1));
ADD(lineno);
ADD(rb_ary_new3(3, S(getlocal), INT2FIX(2), INT2FIX(0)));
ADD(rb_ary_new3(2, S(putobject), arg));
#if SIZEOF_VALUE <= SIZEOF_LONG
send_arg = LONG2NUM((SIGNED_VALUE)func);
#else
send_arg = LL2NUM((SIGNED_VALUE)func);
#endif
send_arg = rb_ary_new3(2, S(opt_call_c_function), send_arg);
ADD(send_arg);
ADD(rb_ary_new3(1, S(pop)));
ADD(rb_ary_new3(1, S(leave)));
#undef S
#undef ADD
rb_iseq_build_from_ary(iseq, misc, locals, params, exception, body);
cleanup_iseq_build(iseq);
rb_ary_clear(body);
rb_ary_clear(send_arg);
return iseqval;
}
/*
* :nodoc:
*/