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:
parent
fd639a4c3b
commit
467830e867
3 changed files with 91 additions and 122 deletions
|
@ -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.
|
||||
|
|
86
compile.c
86
compile.c
|
@ -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
122
iseq.c
|
@ -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:
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue