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

iseq body local variables

* compile.c, iseq.c: extract body and param.keyword in iseq as
  local variables.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63441 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2018-05-16 01:40:44 +00:00
parent db5765ba54
commit a12bfb3bbd
2 changed files with 180 additions and 161 deletions

317
compile.c
View file

@ -1443,13 +1443,15 @@ get_dyna_var_idx(const rb_iseq_t *iseq, ID id, int *level, int *ls)
static int
iseq_local_block_param_p(const rb_iseq_t *iseq, unsigned int idx, unsigned int level)
{
const struct rb_iseq_constant_body *body;
while (level > 0) {
iseq = iseq->body->parent_iseq;
level--;
}
if (iseq->body->local_iseq == iseq && /* local variables */
iseq->body->param.flags.has_block &&
iseq->body->local_table_size - iseq->body->param.block_start == idx) {
body = iseq->body;
if (body->local_iseq == iseq && /* local variables */
body->param.flags.has_block &&
body->local_table_size - body->param.block_start == idx) {
return TRUE;
}
else {
@ -1499,37 +1501,38 @@ iseq_add_setlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, int line, int idx, in
static void
iseq_calc_param_size(rb_iseq_t *iseq)
{
if (iseq->body->param.flags.has_opt ||
iseq->body->param.flags.has_post ||
iseq->body->param.flags.has_rest ||
iseq->body->param.flags.has_block ||
iseq->body->param.flags.has_kw ||
iseq->body->param.flags.has_kwrest) {
struct rb_iseq_constant_body *const body = iseq->body;
if (body->param.flags.has_opt ||
body->param.flags.has_post ||
body->param.flags.has_rest ||
body->param.flags.has_block ||
body->param.flags.has_kw ||
body->param.flags.has_kwrest) {
if (iseq->body->param.flags.has_block) {
iseq->body->param.size = iseq->body->param.block_start + 1;
if (body->param.flags.has_block) {
body->param.size = body->param.block_start + 1;
}
else if (iseq->body->param.flags.has_kwrest) {
iseq->body->param.size = iseq->body->param.keyword->rest_start + 1;
else if (body->param.flags.has_kwrest) {
body->param.size = body->param.keyword->rest_start + 1;
}
else if (iseq->body->param.flags.has_kw) {
iseq->body->param.size = iseq->body->param.keyword->bits_start + 1;
else if (body->param.flags.has_kw) {
body->param.size = body->param.keyword->bits_start + 1;
}
else if (iseq->body->param.flags.has_post) {
iseq->body->param.size = iseq->body->param.post_start + iseq->body->param.post_num;
else if (body->param.flags.has_post) {
body->param.size = body->param.post_start + body->param.post_num;
}
else if (iseq->body->param.flags.has_rest) {
iseq->body->param.size = iseq->body->param.rest_start + 1;
else if (body->param.flags.has_rest) {
body->param.size = body->param.rest_start + 1;
}
else if (iseq->body->param.flags.has_opt) {
iseq->body->param.size = iseq->body->param.lead_num + iseq->body->param.opt_num;
else if (body->param.flags.has_opt) {
body->param.size = body->param.lead_num + body->param.opt_num;
}
else {
rb_bug("unreachable");
}
}
else {
iseq->body->param.size = iseq->body->param.lead_num;
body->param.size = body->param.lead_num;
}
}
@ -1538,13 +1541,14 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
const struct rb_args_info *args, int arg_size)
{
const NODE *node = args->kw_args;
struct rb_iseq_constant_body *const body = iseq->body;
struct rb_iseq_param_keyword *keyword;
const VALUE default_values = rb_ary_tmp_new(1);
const VALUE complex_mark = rb_str_tmp_new(0);
int kw = 0, rkw = 0, di = 0, i;
iseq->body->param.flags.has_kw = TRUE;
iseq->body->param.keyword = keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
body->param.flags.has_kw = TRUE;
body->param.keyword = keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
while (node) {
kw++;
@ -1592,10 +1596,10 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
if (args->kw_rest_arg->nd_vid != 0) {
keyword->rest_start = arg_size++;
iseq->body->param.flags.has_kwrest = TRUE;
body->param.flags.has_kwrest = TRUE;
}
keyword->required_num = rkw;
keyword->table = &iseq->body->local_table[keyword->bits_start - keyword->num];
keyword->table = &body->local_table[keyword->bits_start - keyword->num];
{
VALUE *dvs = ALLOC_N(VALUE, RARRAY_LEN(default_values));
@ -1620,6 +1624,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons
debugs("iseq_set_arguments: %s\n", node_args ? "" : "0");
if (node_args) {
struct rb_iseq_constant_body *const body = iseq->body;
struct rb_args_info *args = node_args->nd_ainfo;
ID rest_id = 0;
int last_comma = 0;
@ -1628,9 +1633,9 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons
EXPECT_NODE("iseq_set_arguments", node_args, NODE_ARGS, COMPILE_NG);
iseq->body->param.lead_num = arg_size = (int)args->pre_args_num;
if (iseq->body->param.lead_num > 0) iseq->body->param.flags.has_lead = TRUE;
debugs(" - argc: %d\n", iseq->body->param.lead_num);
body->param.lead_num = arg_size = (int)args->pre_args_num;
if (body->param.lead_num > 0) body->param.flags.has_lead = TRUE;
debugs(" - argc: %d\n", body->param.lead_num);
rest_id = args->rest_arg;
if (rest_id == 1) {
@ -1668,26 +1673,26 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons
}
rb_ary_clear(labels);
iseq->body->param.flags.has_opt = TRUE;
iseq->body->param.opt_num = i;
iseq->body->param.opt_table = opt_table;
body->param.flags.has_opt = TRUE;
body->param.opt_num = i;
body->param.opt_table = opt_table;
arg_size += i;
}
if (rest_id) {
iseq->body->param.rest_start = arg_size++;
iseq->body->param.flags.has_rest = TRUE;
assert(iseq->body->param.rest_start != -1);
body->param.rest_start = arg_size++;
body->param.flags.has_rest = TRUE;
assert(body->param.rest_start != -1);
}
if (args->first_post_arg) {
iseq->body->param.post_start = arg_size;
iseq->body->param.post_num = args->post_args_num;
iseq->body->param.flags.has_post = TRUE;
body->param.post_start = arg_size;
body->param.post_num = args->post_args_num;
body->param.flags.has_post = TRUE;
arg_size += args->post_args_num;
if (iseq->body->param.flags.has_rest) { /* TODO: why that? */
iseq->body->param.post_start = iseq->body->param.rest_start + 1;
if (body->param.flags.has_rest) { /* TODO: why that? */
body->param.post_start = body->param.rest_start + 1;
}
}
@ -1697,17 +1702,17 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons
else if (args->kw_rest_arg) {
struct rb_iseq_param_keyword *keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1);
keyword->rest_start = arg_size++;
iseq->body->param.keyword = keyword;
iseq->body->param.flags.has_kwrest = TRUE;
body->param.keyword = keyword;
body->param.flags.has_kwrest = TRUE;
}
if (block_id) {
iseq->body->param.block_start = arg_size++;
iseq->body->param.flags.has_block = TRUE;
body->param.block_start = arg_size++;
body->param.flags.has_block = TRUE;
}
iseq_calc_param_size(iseq);
iseq->body->param.size = arg_size;
body->param.size = arg_size;
if (args->pre_init) { /* m_init */
COMPILE_POPPED(optargs, "init arguments (m)", args->pre_init);
@ -1716,16 +1721,16 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons
COMPILE_POPPED(optargs, "init arguments (p)", args->post_init);
}
if (iseq->body->type == ISEQ_TYPE_BLOCK) {
if (iseq->body->param.flags.has_opt == FALSE &&
iseq->body->param.flags.has_post == FALSE &&
iseq->body->param.flags.has_rest == FALSE &&
iseq->body->param.flags.has_kw == FALSE &&
iseq->body->param.flags.has_kwrest == FALSE) {
if (body->type == ISEQ_TYPE_BLOCK) {
if (body->param.flags.has_opt == FALSE &&
body->param.flags.has_post == FALSE &&
body->param.flags.has_rest == FALSE &&
body->param.flags.has_kw == FALSE &&
body->param.flags.has_kwrest == FALSE) {
if (iseq->body->param.lead_num == 1 && last_comma == 0) {
if (body->param.lead_num == 1 && last_comma == 0) {
/* {|a|} */
iseq->body->param.flags.ambiguous_param0 = TRUE;
body->param.flags.ambiguous_param0 = TRUE;
}
}
}
@ -1978,6 +1983,7 @@ static int
iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
{
struct iseq_insn_info_entry *insns_info;
struct rb_iseq_constant_body *const body = iseq->body;
unsigned int *positions;
LINK_ELEMENT *list;
VALUE *generated_iseq;
@ -2040,11 +2046,11 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
generated_iseq = ALLOC_N(VALUE, code_index);
insns_info = ALLOC_N(struct iseq_insn_info_entry, insn_num);
positions = ALLOC_N(unsigned int, insn_num);
iseq->body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, iseq->body->is_size);
iseq->body->ci_entries = (struct rb_call_info *)ruby_xmalloc(sizeof(struct rb_call_info) * iseq->body->ci_size +
sizeof(struct rb_call_info_with_kwarg) * iseq->body->ci_kw_size);
MEMZERO(iseq->body->ci_entries + iseq->body->ci_size, struct rb_call_info_with_kwarg, iseq->body->ci_kw_size); /* need to clear ci_kw entries */
iseq->body->cc_entries = ZALLOC_N(struct rb_call_cache, iseq->body->ci_size + iseq->body->ci_kw_size);
body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, body->is_size);
body->ci_entries = (struct rb_call_info *)ruby_xmalloc(sizeof(struct rb_call_info) * body->ci_size +
sizeof(struct rb_call_info_with_kwarg) * body->ci_kw_size);
MEMZERO(body->ci_entries + body->ci_size, struct rb_call_info_with_kwarg, body->ci_kw_size); /* need to clear ci_kw entries */
body->cc_entries = ZALLOC_N(struct rb_call_cache, body->ci_size + body->ci_kw_size);
ISEQ_COMPILE_DATA(iseq)->ci_index = ISEQ_COMPILE_DATA(iseq)->ci_kw_index = 0;
@ -2124,9 +2130,9 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
case TS_IC: /* inline cache */
{
unsigned int ic_index = FIX2UINT(operands[j]);
IC ic = (IC)&iseq->body->is_entries[ic_index];
if (UNLIKELY(ic_index >= iseq->body->is_size)) {
rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->body->is_size);
IC ic = (IC)&body->is_entries[ic_index];
if (UNLIKELY(ic_index >= body->is_size)) {
rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, body->is_size);
}
generated_iseq[code_index + 1 + j] = (VALUE)ic;
break;
@ -2134,9 +2140,9 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
case TS_ISE: /* inline storage entry */
{
unsigned int ic_index = FIX2UINT(operands[j]);
IC ic = (IC)&iseq->body->is_entries[ic_index];
if (UNLIKELY(ic_index >= iseq->body->is_size)) {
rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->body->is_size);
IC ic = (IC)&body->is_entries[ic_index];
if (UNLIKELY(ic_index >= body->is_size)) {
rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, body->is_size);
}
generated_iseq[code_index + 1 + j] = (VALUE)ic;
FL_SET(iseq, ISEQ_MARKABLE_ISEQ);
@ -2148,16 +2154,16 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
struct rb_call_info *ci;
if (base_ci->flag & VM_CALL_KWARG) {
struct rb_call_info_with_kwarg *ci_kw_entries = (struct rb_call_info_with_kwarg *)&iseq->body->ci_entries[iseq->body->ci_size];
struct rb_call_info_with_kwarg *ci_kw_entries = (struct rb_call_info_with_kwarg *)&body->ci_entries[body->ci_size];
struct rb_call_info_with_kwarg *ci_kw = &ci_kw_entries[ISEQ_COMPILE_DATA(iseq)->ci_kw_index++];
*ci_kw = *((struct rb_call_info_with_kwarg *)base_ci);
ci = (struct rb_call_info *)ci_kw;
assert(ISEQ_COMPILE_DATA(iseq)->ci_kw_index <= iseq->body->ci_kw_size);
assert(ISEQ_COMPILE_DATA(iseq)->ci_kw_index <= body->ci_kw_size);
}
else {
ci = &iseq->body->ci_entries[ISEQ_COMPILE_DATA(iseq)->ci_index++];
ci = &body->ci_entries[ISEQ_COMPILE_DATA(iseq)->ci_index++];
*ci = *base_ci;
assert(ISEQ_COMPILE_DATA(iseq)->ci_index <= iseq->body->ci_size);
assert(ISEQ_COMPILE_DATA(iseq)->ci_index <= body->ci_size);
}
generated_iseq[code_index + 1 + j] = (VALUE)ci;
@ -2165,7 +2171,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
}
case TS_CALLCACHE:
{
struct rb_call_cache *cc = &iseq->body->cc_entries[ISEQ_COMPILE_DATA(iseq)->ci_index + ISEQ_COMPILE_DATA(iseq)->ci_kw_index - 1];
struct rb_call_cache *cc = &body->cc_entries[ISEQ_COMPILE_DATA(iseq)->ci_index + ISEQ_COMPILE_DATA(iseq)->ci_kw_index - 1];
generated_iseq[code_index + 1 + j] = (VALUE)cc;
break;
}
@ -2243,19 +2249,19 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
list = list->next;
}
iseq->body->iseq_encoded = (void *)generated_iseq;
iseq->body->iseq_size = code_index;
iseq->body->stack_max = stack_max;
body->iseq_encoded = (void *)generated_iseq;
body->iseq_size = code_index;
body->stack_max = stack_max;
/* get rid of memory leak when REALLOC failed */
iseq->body->insns_info.body = insns_info;
iseq->body->insns_info.positions = positions;
body->insns_info.body = insns_info;
body->insns_info.positions = positions;
REALLOC_N(insns_info, struct iseq_insn_info_entry, insns_info_index);
iseq->body->insns_info.body = insns_info;
body->insns_info.body = insns_info;
REALLOC_N(positions, unsigned int, insns_info_index);
iseq->body->insns_info.positions = positions;
iseq->body->insns_info.size = insns_info_index;
body->insns_info.positions = positions;
body->insns_info.size = insns_info_index;
return COMPILE_OK;
}
@ -4833,6 +4839,7 @@ number_literal_p(const NODE *n)
static int
compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped, const enum node_type type)
{
struct rb_iseq_constant_body *const body = iseq->body;
const NODE *const node_body = type == NODE_IF ? node->nd_body : node->nd_else;
const NODE *const node_else = type == NODE_IF ? node->nd_else : node->nd_body;
@ -4858,20 +4865,20 @@ compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int
compile_branch_condition(iseq, cond_seq, node->nd_cond,
then_label, else_label);
ci_size = iseq->body->ci_size;
ci_kw_size = iseq->body->ci_kw_size;
ci_size = body->ci_size;
ci_kw_size = body->ci_kw_size;
CHECK(COMPILE_(then_seq, "then", node_body, popped));
if (!then_label->refcnt) {
iseq->body->ci_size = ci_size;
iseq->body->ci_kw_size = ci_kw_size;
body->ci_size = ci_size;
body->ci_kw_size = ci_kw_size;
}
ci_size = iseq->body->ci_size;
ci_kw_size = iseq->body->ci_kw_size;
ci_size = body->ci_size;
ci_kw_size = body->ci_kw_size;
CHECK(COMPILE_(else_seq, "else", node_else, popped));
if (!else_label->refcnt) {
iseq->body->ci_size = ci_size;
iseq->body->ci_kw_size = ci_kw_size;
body->ci_size = ci_size;
body->ci_kw_size = ci_kw_size;
}
ADD_SEQ(ret, cond_seq);
@ -5776,6 +5783,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
{
const int line = (int)nd_line(node);
const enum node_type type = nd_type(node);
struct rb_iseq_constant_body *const body = iseq->body;
if (ISEQ_COMPILE_DATA(iseq)->last_line == line) {
/* ignore */
@ -5879,7 +5887,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
case NODE_LASGN:{
ID id = node->nd_vid;
int idx = iseq->body->local_iseq->body->local_table_size - get_local_var_idx(iseq, id);
int idx = body->local_iseq->body->local_table_size - get_local_var_idx(iseq, id);
debugs("lvar: %s idx: %d\n", rb_id2name(id), idx);
CHECK(COMPILE(ret, "rvalue", node->nd_value));
@ -6513,46 +6521,48 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
else {
/* NODE_ZSUPER */
int i;
const rb_iseq_t *liseq = iseq->body->local_iseq;
const rb_iseq_t *liseq = body->local_iseq;
const struct rb_iseq_constant_body *const local_body = liseq->body;
const struct rb_iseq_param_keyword *const local_kwd = local_body->param.keyword;
int lvar_level = get_lvar_level(iseq);
argc = liseq->body->param.lead_num;
argc = local_body->param.lead_num;
/* normal arguments */
for (i = 0; i < liseq->body->param.lead_num; i++) {
int idx = liseq->body->local_table_size - i;
for (i = 0; i < local_body->param.lead_num; i++) {
int idx = local_body->local_table_size - i;
ADD_GETLOCAL(args, line, idx, lvar_level);
}
if (liseq->body->param.flags.has_opt) {
if (local_body->param.flags.has_opt) {
/* optional arguments */
int j;
for (j = 0; j < liseq->body->param.opt_num; j++) {
int idx = liseq->body->local_table_size - (i + j);
for (j = 0; j < local_body->param.opt_num; j++) {
int idx = local_body->local_table_size - (i + j);
ADD_GETLOCAL(args, line, idx, lvar_level);
}
i += j;
argc = i;
}
if (liseq->body->param.flags.has_rest) {
if (local_body->param.flags.has_rest) {
/* rest argument */
int idx = liseq->body->local_table_size - liseq->body->param.rest_start;
int idx = local_body->local_table_size - local_body->param.rest_start;
ADD_GETLOCAL(args, line, idx, lvar_level);
ADD_INSN1(args, line, splatarray, Qfalse);
argc = liseq->body->param.rest_start + 1;
argc = local_body->param.rest_start + 1;
flag |= VM_CALL_ARGS_SPLAT;
}
if (liseq->body->param.flags.has_post) {
if (local_body->param.flags.has_post) {
/* post arguments */
int post_len = liseq->body->param.post_num;
int post_start = liseq->body->param.post_start;
int post_len = local_body->param.post_num;
int post_start = local_body->param.post_start;
if (liseq->body->param.flags.has_rest) {
if (local_body->param.flags.has_rest) {
int j;
for (j=0; j<post_len; j++) {
int idx = liseq->body->local_table_size - (post_start + j);
int idx = local_body->local_table_size - (post_start + j);
ADD_GETLOCAL(args, line, idx, lvar_level);
}
ADD_INSN1(args, line, newarray, INT2FIX(j));
@ -6562,46 +6572,46 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
else {
int j;
for (j=0; j<post_len; j++) {
int idx = liseq->body->local_table_size - (post_start + j);
int idx = local_body->local_table_size - (post_start + j);
ADD_GETLOCAL(args, line, idx, lvar_level);
}
argc = post_len + post_start;
}
}
if (liseq->body->param.flags.has_kw) { /* TODO: support keywords */
int local_size = liseq->body->local_table_size;
if (local_body->param.flags.has_kw) { /* TODO: support keywords */
int local_size = local_body->local_table_size;
argc++;
ADD_INSN1(args, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
if (liseq->body->param.flags.has_kwrest) {
int idx = liseq->body->local_table_size - liseq->body->param.keyword->rest_start;
if (local_body->param.flags.has_kwrest) {
int idx = local_body->local_table_size - local_kwd->rest_start;
ADD_GETLOCAL(args, line, idx, lvar_level);
ADD_SEND (args, line, rb_intern("dup"), INT2FIX(0));
}
else {
ADD_INSN1(args, line, newhash, INT2FIX(0));
}
for (i = 0; i < liseq->body->param.keyword->num; ++i) {
ID id = liseq->body->param.keyword->table[i];
for (i = 0; i < local_kwd->num; ++i) {
ID id = local_kwd->table[i];
int idx = local_size - get_local_var_idx(liseq, id);
ADD_INSN1(args, line, putobject, ID2SYM(id));
ADD_GETLOCAL(args, line, idx, lvar_level);
}
ADD_SEND(args, line, id_core_hash_merge_ptr, INT2FIX(i * 2 + 1));
if (liseq->body->param.flags.has_rest) {
if (local_body->param.flags.has_rest) {
ADD_INSN1(args, line, newarray, INT2FIX(1));
ADD_INSN (args, line, concatarray);
--argc;
}
}
else if (liseq->body->param.flags.has_kwrest) {
int idx = liseq->body->local_table_size - liseq->body->param.keyword->rest_start;
else if (local_body->param.flags.has_kwrest) {
int idx = local_body->local_table_size - local_kwd->rest_start;
ADD_GETLOCAL(args, line, idx, lvar_level);
ADD_SEND (args, line, rb_intern("dup"), INT2FIX(0));
if (liseq->body->param.flags.has_rest) {
if (local_body->param.flags.has_rest) {
ADD_INSN1(args, line, newarray, INT2FIX(1));
ADD_INSN (args, line, concatarray);
}
@ -6679,8 +6689,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
struct rb_call_info_kw_arg *keywords = NULL;
INIT_ANCHOR(args);
if (iseq->body->type == ISEQ_TYPE_TOP ||
iseq->body->type == ISEQ_TYPE_MAIN) {
if (body->type == ISEQ_TYPE_TOP ||
body->type == ISEQ_TYPE_MAIN) {
COMPILE_ERROR(ERROR_ARGS "Invalid yield");
goto ng;
}
@ -6704,7 +6714,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
case NODE_LVAR:{
if (!popped) {
ID id = node->nd_vid;
int idx = iseq->body->local_iseq->body->local_table_size - get_local_var_idx(iseq, id);
int idx = body->local_iseq->body->local_table_size - get_local_var_idx(iseq, id);
debugs("id: %s idx: %d\n", rb_id2name(id), idx);
ADD_GETLOCAL(ret, line, idx, get_lvar_level(iseq));
@ -6747,7 +6757,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
LABEL *lend = NEW_LABEL(line);
int ic_index = iseq->body->is_size++;
int ic_index = body->is_size++;
ADD_INSN2(ret, line, getinlinecache, lend, INT2FIX(ic_index));
ADD_INSN1(ret, line, getconstant, ID2SYM(node->nd_vid));
@ -6924,7 +6934,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
break;
}
case NODE_ONCE:{
int ic_index = iseq->body->is_size++;
int ic_index = body->is_size++;
const rb_iseq_t *block_iseq;
block_iseq = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_PLAIN, line);
@ -7097,7 +7107,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
if (rb_is_const_id(node->nd_mid)) {
/* constant */
LABEL *lend = NEW_LABEL(line);
int ic_index = iseq->body->is_size++;
int ic_index = body->is_size++;
DECL_ANCHOR(pref);
DECL_ANCHOR(body);
@ -7138,7 +7148,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
}
case NODE_COLON3:{
LABEL *lend = NEW_LABEL(line);
int ic_index = iseq->body->is_size++;
int ic_index = body->is_size++;
debugi("colon3#nd_mid", node->nd_mid);
@ -7224,7 +7234,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
}
case NODE_ERRINFO:{
if (!popped) {
if (iseq->body->type == ISEQ_TYPE_RESCUE) {
if (body->type == ISEQ_TYPE_RESCUE) {
ADD_GETLOCAL(ret, line, LVAR_ERRINFO, 0);
}
else {
@ -7256,7 +7266,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
/* compiled to:
* ONCE{ rb_mRubyVMFrozenCore::core#set_postexe{ ... } }
*/
int is_index = iseq->body->is_size++;
int is_index = body->is_size++;
const rb_iseq_t *once_iseq =
new_child_iseq_ifunc(iseq, IFUNC_NEW(build_postexe_iseq, node->nd_body, 0),
rb_fstring(make_name_for_block(iseq)), iseq, ISEQ_TYPE_BLOCK, line);
@ -7290,8 +7300,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
* kw = default_value
* end
*/
int kw_bits_idx = iseq->body->local_table_size - iseq->body->param.keyword->bits_start;
int keyword_idx = iseq->body->param.keyword->num;
int kw_bits_idx = body->local_table_size - body->param.keyword->bits_start;
int keyword_idx = body->param.keyword->num;
ADD_INSN2(ret, line, checkkeyword, INT2FIX(kw_bits_idx + VM_ENV_DATA_SIZE - 1), INT2FIX(keyword_idx));
ADD_INSNL(ret, line, branchif, end_label);
@ -8159,20 +8169,22 @@ rb_dvar_defined(ID id, const struct rb_block *base_block)
const rb_iseq_t *iseq;
if (base_block && (iseq = vm_block_iseq(base_block)) != NULL) {
while (iseq->body->type == ISEQ_TYPE_BLOCK ||
iseq->body->type == ISEQ_TYPE_RESCUE ||
iseq->body->type == ISEQ_TYPE_ENSURE ||
iseq->body->type == ISEQ_TYPE_EVAL ||
iseq->body->type == ISEQ_TYPE_MAIN
const struct rb_iseq_constant_body *body = iseq->body;
while (body->type == ISEQ_TYPE_BLOCK ||
body->type == ISEQ_TYPE_RESCUE ||
body->type == ISEQ_TYPE_ENSURE ||
body->type == ISEQ_TYPE_EVAL ||
body->type == ISEQ_TYPE_MAIN
) {
unsigned int i;
for (i = 0; i < iseq->body->local_table_size; i++) {
if (iseq->body->local_table[i] == id) {
for (i = 0; i < body->local_table_size; i++) {
if (body->local_table[i] == id) {
return 1;
}
}
iseq = iseq->body->parent_iseq;
iseq = body->parent_iseq;
body = iseq->body;
}
}
return 0;
@ -8185,10 +8197,10 @@ rb_local_defined(ID id, const struct rb_block *base_block)
if (base_block && (iseq = vm_block_iseq(base_block)) != NULL) {
unsigned int i;
iseq = iseq->body->local_iseq;
const struct rb_iseq_constant_body *const body = iseq->body->local_iseq->body;
for (i=0; i<iseq->body->local_table_size; i++) {
if (iseq->body->local_table[i] == id) {
for (i=0; i<body->local_table_size; i++) {
if (body->local_table[i] == id) {
return 1;
}
}
@ -8242,10 +8254,11 @@ for_self_aref(rb_iseq_t *iseq, LINK_ANCHOR *const ret, VALUE a)
{
const accessor_args *const args = (void *)a;
const int line = args->line;
struct rb_iseq_constant_body *const body = iseq->body;
iseq_set_local_table(iseq, 0);
iseq->body->param.lead_num = 0;
iseq->body->param.size = 0;
body->param.lead_num = 0;
body->param.size = 0;
ADD_INSN1(ret, line, putobject, args->arg);
ADD_INSN1(ret, line, opt_call_c_function, (VALUE)args->func);
@ -8257,11 +8270,12 @@ for_self_aset(rb_iseq_t *iseq, LINK_ANCHOR *const ret, VALUE a)
{
const accessor_args *const args = (void *)a;
const int line = args->line;
struct rb_iseq_constant_body *const body = iseq->body;
static const ID vars[] = {1, idUScore};
iseq_set_local_table(iseq, vars);
iseq->body->param.lead_num = 1;
iseq->body->param.size = 1;
body->param.lead_num = 1;
body->param.size = 1;
ADD_GETLOCAL(ret, line, numberof(vars)-1, 0);
ADD_INSN1(ret, line, putobject, args->arg);
@ -8513,7 +8527,8 @@ ibf_load_gentry(const struct ibf_load *load, const struct rb_global_entry *entry
static VALUE *
ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq)
{
const int iseq_size = iseq->body->iseq_size;
const struct rb_iseq_constant_body *const body = iseq->body;
const int iseq_size = body->iseq_size;
int code_index;
VALUE *code;
const VALUE *orig_code = rb_iseq_original_iseq(iseq);
@ -8541,8 +8556,8 @@ ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq)
case TS_ISE:
{
unsigned int i;
for (i=0; i<iseq->body->is_size; i++) {
if (op == (VALUE)&iseq->body->is_entries[i]) {
for (i=0; i<body->is_size; i++) {
if (op == (VALUE)&body->is_entries[i]) {
break;
}
}
@ -8583,10 +8598,10 @@ ibf_load_code(const struct ibf_load *load, const rb_iseq_t *iseq, const struct r
VALUE *code = IBF_R(body->iseq_encoded, VALUE, iseq_size);
struct rb_iseq_constant_body *load_body = iseq->body;
struct rb_call_info *ci_entries = iseq->body->ci_entries;
struct rb_call_info_with_kwarg *ci_kw_entries = (struct rb_call_info_with_kwarg *)&iseq->body->ci_entries[iseq->body->ci_size];
struct rb_call_cache *cc_entries = iseq->body->cc_entries;
union iseq_inline_storage_entry *is_entries = iseq->body->is_entries;
struct rb_call_info *ci_entries = load_body->ci_entries;
struct rb_call_info_with_kwarg *ci_kw_entries = (struct rb_call_info_with_kwarg *)&load_body->ci_entries[load_body->ci_size];
struct rb_call_cache *cc_entries = load_body->cc_entries;
union iseq_inline_storage_entry *is_entries = load_body->is_entries;
load_body->iseq_encoded = code;
load_body->iseq_size = 0;
@ -8761,12 +8776,13 @@ ibf_load_insns_info_positions(const struct ibf_load *load, const struct rb_iseq_
static ID *
ibf_dump_local_table(struct ibf_dump *dump, const rb_iseq_t *iseq)
{
const int size = iseq->body->local_table_size;
const struct rb_iseq_constant_body *const body = iseq->body;
const int size = body->local_table_size;
ID *table = ALLOCA_N(ID, size);
int i;
for (i=0; i<size; i++) {
table[i] = ibf_dump_id(dump, iseq->body->local_table[i]);
table[i] = ibf_dump_id(dump, body->local_table[i]);
}
return IBF_W(table, ID, size);
@ -8834,9 +8850,10 @@ ibf_load_catch_table(const struct ibf_load *load, const struct rb_iseq_constant_
static struct rb_call_info *
ibf_dump_ci_entries(struct ibf_dump *dump, const rb_iseq_t *iseq)
{
const unsigned int ci_size = iseq->body->ci_size;
const unsigned int ci_kw_size = iseq->body->ci_kw_size;
const struct rb_call_info *ci_entries = iseq->body->ci_entries;
const struct rb_iseq_constant_body *const body = iseq->body;
const unsigned int ci_size = body->ci_size;
const unsigned int ci_kw_size = body->ci_kw_size;
const struct rb_call_info *ci_entries = body->ci_entries;
struct rb_call_info *dump_ci_entries;
struct rb_call_info_with_kwarg *dump_ci_kw_entries;
int byte_size = ci_size * sizeof(struct rb_call_info) +

24
iseq.c
View file

@ -228,12 +228,13 @@ rb_iseq_mark(const rb_iseq_t *iseq)
RUBY_MARK_UNLESS_NULL((VALUE)body->parent_iseq);
if (body->param.flags.has_kw && ISEQ_COMPILE_DATA(iseq) == NULL) {
const struct rb_iseq_param_keyword *const keyword = body->param.keyword;
int i, j;
i = body->param.keyword->required_num;
i = keyword->required_num;
for (j = 0; i < body->param.keyword->num; i++, j++) {
VALUE obj = body->param.keyword->default_values[j];
for (j = 0; i < keyword->num; i++, j++) {
VALUE obj = keyword->default_values[j];
if (!SPECIAL_CONST_P(obj)) {
rb_gc_mark(obj);
}
@ -2706,6 +2707,7 @@ rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
{
int i, r;
const struct rb_iseq_constant_body *const body = iseq->body;
const struct rb_iseq_param_keyword *const keyword = body->param.keyword;
VALUE a, args = rb_ary_new2(body->param.size);
ID req, opt, rest, block, key, keyrest;
#define PARAM_TYPE(type) rb_ary_push(a = rb_ary_new2(2), ID2SYM(type))
@ -2757,29 +2759,29 @@ rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
}
if (body->param.flags.has_kw) {
i = 0;
if (body->param.keyword->required_num > 0) {
if (keyword->required_num > 0) {
ID keyreq;
CONST_ID(keyreq, "keyreq");
for (; i < body->param.keyword->required_num; i++) {
for (; i < keyword->required_num; i++) {
PARAM_TYPE(keyreq);
if (rb_id2str(body->param.keyword->table[i])) {
rb_ary_push(a, ID2SYM(body->param.keyword->table[i]));
if (rb_id2str(keyword->table[i])) {
rb_ary_push(a, ID2SYM(keyword->table[i]));
}
rb_ary_push(args, a);
}
}
CONST_ID(key, "key");
for (; i < body->param.keyword->num; i++) {
for (; i < keyword->num; i++) {
PARAM_TYPE(key);
if (rb_id2str(body->param.keyword->table[i])) {
rb_ary_push(a, ID2SYM(body->param.keyword->table[i]));
if (rb_id2str(keyword->table[i])) {
rb_ary_push(a, ID2SYM(keyword->table[i]));
}
rb_ary_push(args, a);
}
}
if (body->param.flags.has_kwrest) {
CONST_ID(keyrest, "keyrest");
rb_ary_push(args, PARAM(body->param.keyword->rest_start, keyrest));
rb_ary_push(args, PARAM(keyword->rest_start, keyrest));
}
if (body->param.flags.has_block) {
CONST_ID(block, "block");