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
@ -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>
|
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.
|
* 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;
|
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;
|
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:
|
* :nodoc:
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user