Feature #10030 » iseq_catch_table_flex.patch
compile.c | ||
---|---|---|
tlen = (int)RARRAY_LEN(iseq->compile_data->catch_table_ary);
|
||
tptr = RARRAY_CONST_PTR(iseq->compile_data->catch_table_ary);
|
||
iseq->catch_table = tlen ? ALLOC_N(struct iseq_catch_table_entry, tlen) : 0;
|
||
iseq->catch_table_size = tlen;
|
||
iseq->_catch_table = 0;
|
||
if (tlen > 0) {
|
||
iseq->_catch_table = xmalloc(iseq_catch_table_bytes(tlen));
|
||
iseq->_catch_table->size = tlen;
|
||
}
|
||
for (i = 0; i < tlen; i++) {
|
||
iseq_catch_table_each(iseq, i, entry) {
|
||
ptr = RARRAY_CONST_PTR(tptr[i]);
|
||
entry = &iseq->catch_table[i];
|
||
entry->type = (enum catch_type)(ptr[0] & 0xffff);
|
||
entry->start = label_get_position((LABEL *)(ptr[1] & ~1));
|
||
entry->end = label_get_position((LABEL *)(ptr[2] & ~1));
|
iseq.c | ||
---|---|---|
RUBY_FREE_UNLESS_NULL(iseq->local_table);
|
||
RUBY_FREE_UNLESS_NULL(iseq->is_entries);
|
||
RUBY_FREE_UNLESS_NULL(iseq->callinfo_entries);
|
||
RUBY_FREE_UNLESS_NULL(iseq->catch_table);
|
||
RUBY_FREE_UNLESS_NULL(iseq->_catch_table);
|
||
RUBY_FREE_UNLESS_NULL(iseq->arg_opt_table);
|
||
RUBY_FREE_UNLESS_NULL(iseq->arg_keyword_table);
|
||
compile_data_free(iseq->compile_data);
|
||
... | ... | |
size += iseq->iseq_size * sizeof(VALUE);
|
||
size += iseq->line_info_size * sizeof(struct iseq_line_info_entry);
|
||
size += iseq->local_table_size * sizeof(ID);
|
||
size += iseq->catch_table_size * sizeof(struct iseq_catch_table_entry);
|
||
if (iseq->_catch_table) {
|
||
size += iseq_catch_table_bytes(iseq->_catch_table->size);
|
||
}
|
||
size += iseq->arg_opts * sizeof(VALUE);
|
||
size += iseq->is_size * sizeof(union iseq_inline_storage_entry);
|
||
size += iseq->callinfo_size * sizeof(rb_call_info_t);
|
||
... | ... | |
ID *tbl;
|
||
size_t n;
|
||
enum {header_minlen = 72};
|
||
struct iseq_catch_table_entry *entry;
|
||
rb_secure(1);
|
||
... | ... | |
rb_str_cat2(str, "\n");
|
||
/* show catch table information */
|
||
if (iseqdat->catch_table_size != 0) {
|
||
if (iseqdat->_catch_table) {
|
||
rb_str_cat2(str, "== catch table\n");
|
||
}
|
||
for (i = 0; i < iseqdat->catch_table_size; i++) {
|
||
struct iseq_catch_table_entry *entry = &iseqdat->catch_table[i];
|
||
iseq_catch_table_each(iseqdat, i, entry) {
|
||
rb_str_catf(str,
|
||
"| catch type: %-6s st: %04d ed: %04d sp: %04d cont: %04d\n",
|
||
catch_type((int)entry->type), (int)entry->start,
|
||
... | ... | |
rb_str_concat(str, rb_iseq_disasm(entry->iseq));
|
||
}
|
||
}
|
||
if (iseqdat->catch_table_size != 0) {
|
||
if (iseqdat->_catch_table) {
|
||
rb_str_cat2(str, "|-------------------------------------"
|
||
"-----------------------------------\n");
|
||
}
|
||
... | ... | |
static VALUE insn_syms[VM_INSTRUCTION_SIZE];
|
||
struct st_table *labels_table = st_init_numtable();
|
||
struct iseq_catch_table_entry *entry;
|
||
DECL_SYMBOL(top);
|
||
DECL_SYMBOL(method);
|
||
... | ... | |
nbody = body;
|
||
/* exception */
|
||
for (i=0; i<iseq->catch_table_size; i++) {
|
||
iseq_catch_table_each(iseq, i, entry) {
|
||
VALUE ary = rb_ary_new();
|
||
struct iseq_catch_table_entry *entry = &iseq->catch_table[i];
|
||
rb_ary_push(ary, exception_type2symbol(entry->type));
|
||
if (entry->iseq) {
|
||
rb_iseq_t *eiseq;
|
||
... | ... | |
ALLOC_AND_COPY(iseq->line_info_table, line_info_table,
|
||
struct iseq_line_info_entry, iseq->line_info_size);
|
||
ALLOC_AND_COPY(iseq->catch_table, catch_table,
|
||
struct iseq_catch_table_entry, iseq->catch_table_size);
|
||
/*
|
||
* FIXME: probably broken, but this function is probably unused
|
||
* and should be removed
|
||
*/
|
||
if (iseq->_catch_table) {
|
||
MEMCPY(&iseq->_catch_table->entries, catch_table,
|
||
struct iseq_catch_table_entry, iseq->_catch_table->size);
|
||
}
|
||
ALLOC_AND_COPY(iseq->arg_opt_table, arg_opt_table,
|
||
VALUE, iseq->arg_opts);
|
iseq.h | ||
---|---|---|
unsigned long sp;
|
||
};
|
||
PACKED_STRUCT_UNALIGNED(struct iseq_catch_table {
|
||
int size;
|
||
struct iseq_catch_table_entry entries[1]; /* flexible array */
|
||
});
|
||
#define iseq_catch_table_bytes(n) \
|
||
(sizeof(struct iseq_catch_table) + \
|
||
((n)-1) * sizeof(struct iseq_catch_table_entry))
|
||
#define iseq_catch_table_each(iseq,i,entry) \
|
||
for (i = 0; \
|
||
iseq->_catch_table && \
|
||
(i < iseq->_catch_table->size) && \
|
||
(entry = &iseq->_catch_table->entries[i]); \
|
||
i++)
|
||
#define INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE (512)
|
||
struct iseq_compile_data_storage {
|
vm.c | ||
---|---|---|
SET_THROWOBJ_STATE(err, state = TAG_BREAK);
|
||
}
|
||
else {
|
||
for (i = 0; i < cfp->iseq->catch_table_size; i++) {
|
||
entry = &cfp->iseq->catch_table[i];
|
||
iseq_catch_table_each(cfp->iseq, i, entry) {
|
||
if (entry->start < epc && entry->end >= epc) {
|
||
if (entry->type == CATCH_TYPE_ENSURE) {
|
||
catch_iseqval = entry->iseq;
|
||
... | ... | |
}
|
||
if (state == TAG_RAISE) {
|
||
for (i = 0; i < cfp->iseq->catch_table_size; i++) {
|
||
entry = &cfp->iseq->catch_table[i];
|
||
iseq_catch_table_each(cfp->iseq, i, entry) {
|
||
if (entry->start < epc && entry->end >= epc) {
|
||
if (entry->type == CATCH_TYPE_RESCUE ||
|
||
... | ... | |
}
|
||
}
|
||
else if (state == TAG_RETRY) {
|
||
for (i = 0; i < cfp->iseq->catch_table_size; i++) {
|
||
entry = &cfp->iseq->catch_table[i];
|
||
iseq_catch_table_each(cfp->iseq, i, entry) {
|
||
if (entry->start < epc && entry->end >= epc) {
|
||
if (entry->type == CATCH_TYPE_ENSURE) {
|
||
... | ... | |
type = CATCH_TYPE_BREAK;
|
||
search_restart_point:
|
||
for (i = 0; i < cfp->iseq->catch_table_size; i++) {
|
||
entry = &cfp->iseq->catch_table[i];
|
||
iseq_catch_table_each(cfp->iseq, i, entry) {
|
||
if (entry->start < epc && entry->end >= epc) {
|
||
if (entry->type == CATCH_TYPE_ENSURE) {
|
||
catch_iseqval = entry->iseq;
|
||
... | ... | |
goto search_restart_point;
|
||
}
|
||
else {
|
||
for (i = 0; i < cfp->iseq->catch_table_size; i++) {
|
||
entry = &cfp->iseq->catch_table[i];
|
||
iseq_catch_table_each(cfp->iseq, i, entry) {
|
||
if (entry->start < epc && entry->end >= epc) {
|
||
if (entry->type == CATCH_TYPE_ENSURE) {
|
vm_core.h | ||
---|---|---|
ID *arg_keyword_table;
|
||
/* catch table */
|
||
struct iseq_catch_table_entry *catch_table;
|
||
int catch_table_size;
|
||
struct iseq_catch_table *_catch_table;
|
||
/* for child iseq */
|
||
struct rb_iseq_struct *parent_iseq;
|
vm_insnhelper.c | ||
---|---|---|
VALUE epc = cfp->pc - cfp->iseq->iseq_encoded;
|
||
rb_iseq_t *iseq = cfp->iseq;
|
||
int i;
|
||
struct iseq_catch_table_entry *entry;
|
||
for (i=0; i<iseq->catch_table_size; i++) {
|
||
struct iseq_catch_table_entry *entry = &iseq->catch_table[i];
|
||
iseq_catch_table_each(iseq, i, entry) {
|
||
if (entry->type == CATCH_TYPE_BREAK &&
|
||
entry->start < epc && entry->end >= epc) {
|
||
if (entry->cont == epc) {
|
||
-
|