From e92d4e2680716d3e16a264e46394cb6e458699f9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 7 Nov 2013 03:54:22 +0900 Subject: modified to use irep->reps to reference child ireps. preparation for removing irep array from mrb_state. note that instructions OP_LAMBDA, OP_EXEC and OP_EPUSH are incompatible, and dumped mrb format has changed. --- src/dump.c | 342 ++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 189 insertions(+), 153 deletions(-) (limited to 'src/dump.c') diff --git a/src/dump.c b/src/dump.c index 73c3ed553..65b60b17c 100644 --- a/src/dump.c +++ b/src/dump.c @@ -13,7 +13,7 @@ #include "mruby/numeric.h" #include "mruby/debug.h" -static size_t get_irep_record_size(mrb_state *mrb, mrb_irep *irep); +static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep); static uint32_t get_irep_header_size(mrb_state *mrb) @@ -21,7 +21,7 @@ get_irep_header_size(mrb_state *mrb) uint32_t size = 0; size += sizeof(uint32_t) * 1; - size += sizeof(uint16_t) * 2; + size += sizeof(uint16_t) * 3; return size; } @@ -31,9 +31,10 @@ write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { uint8_t *cur = buf; - cur += uint32_to_bin(get_irep_record_size(mrb, irep), cur); /* record size */ + cur += uint32_to_bin(get_irep_record_size_1(mrb, irep), cur); /* record size */ cur += uint16_to_bin((uint16_t)irep->nlocals, cur); /* number of local variable */ cur += uint16_to_bin((uint16_t)irep->nregs, cur); /* number of register variable */ + cur += uint16_to_bin((uint16_t)irep->rlen, cur); /* number of child irep */ return (cur - buf); } @@ -204,47 +205,68 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) return (int)(cur - buf); } - - static size_t -get_irep_record_size(mrb_state *mrb, mrb_irep *irep) +get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep) { uint32_t size = 0; - //size += sizeof(uint16_t); /* rlen */ size += get_irep_header_size(mrb); size += get_iseq_block_size(mrb, irep); size += get_pool_block_size(mrb, irep); size += get_syms_block_size(mrb, irep); + return size; +} +static size_t +get_irep_record_size(mrb_state *mrb, mrb_irep *irep) +{ + uint32_t size = 0; + size_t irep_no; + + size = get_irep_record_size_1(mrb, irep); + for (irep_no = 0; irep_no < irep->rlen; irep_no++) { + size += get_irep_record_size(mrb, irep->reps[irep_no]); + } return size; } static int write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, uint32_t *irep_record_size) { + size_t i; + if (irep == NULL) { return MRB_DUMP_INVALID_IREP; } - *irep_record_size = get_irep_record_size(mrb, irep); + *irep_record_size = get_irep_record_size_1(mrb, irep); if (*irep_record_size == 0) { return MRB_DUMP_GENERAL_FAILURE; } memset(bin, 0, *irep_record_size); - //bin += uint16_to_bin(*irep_record_size, bin); bin += write_irep_header(mrb, irep, bin); bin += write_iseq_block(mrb, irep, bin); bin += write_pool_block(mrb, irep, bin); bin += write_syms_block(mrb, irep, bin); + for (i = 0; i < irep->rlen; i++) { + int result; + uint32_t rlen; + + result = write_irep_record(mrb, irep->reps[i], bin, &rlen); + if (result != MRB_DUMP_OK) { + return result; + } + *irep_record_size += rlen; + bin += rlen; + } return MRB_DUMP_OK; } static size_t -mrb_write_eof(mrb_state *mrb, uint8_t *bin) +write_footer(mrb_state *mrb, uint8_t *bin) { struct rite_binary_footer footer; @@ -257,58 +279,50 @@ mrb_write_eof(mrb_state *mrb, uint8_t *bin) static int -mrb_write_section_irep_header(mrb_state *mrb, uint32_t section_size, uint16_t nirep, uint16_t sirep, uint8_t *bin) +write_section_irep_header(mrb_state *mrb, uint32_t section_size, uint8_t *bin) { struct rite_section_irep_header *header = (struct rite_section_irep_header*)bin; memcpy(header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(header->section_identify)); uint32_to_bin(section_size, header->section_size); memcpy(header->rite_version, RITE_VM_VER, sizeof(header->rite_version)); - uint16_to_bin(nirep, header->nirep); - uint16_to_bin(sirep, header->sirep); return MRB_DUMP_OK; } static int -mrb_write_section_irep(mrb_state *mrb, size_t start_index, uint8_t *bin) +write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) { int result; - size_t irep_no; uint32_t section_size = 0, rlen = 0; /* size of irep record */ uint8_t *cur = bin; - if (mrb == NULL || start_index >= mrb->irep_len || bin == NULL) { + if (mrb == NULL || bin == NULL) { return MRB_DUMP_INVALID_ARGUMENT; } cur += sizeof(struct rite_section_irep_header); section_size += sizeof(struct rite_section_irep_header); - for (irep_no = start_index; irep_no < mrb->irep_len; irep_no++) { - result = write_irep_record(mrb, mrb->irep[irep_no], cur, &rlen); - if (result != MRB_DUMP_OK) { - return result; - } - cur += rlen; - section_size += rlen; + result = write_irep_record(mrb, irep, cur, &rlen); + if (result != MRB_DUMP_OK) { + return result; } - - mrb_write_section_irep_header(mrb, section_size, mrb->irep_len - start_index, start_index, bin); + cur += rlen; + section_size += rlen; + write_section_irep_header(mrb, section_size, bin); return MRB_DUMP_OK; } static int -mrb_write_section_lineno_header(mrb_state *mrb, uint32_t section_size, uint16_t nirep, uint16_t sirep, uint8_t *bin) +write_section_lineno_header(mrb_state *mrb, uint32_t section_size, uint8_t *bin) { struct rite_section_lineno_header *header = (struct rite_section_lineno_header*)bin; // TODO memcpy(header->section_identify, RITE_SECTION_LINENO_IDENTIFIER, sizeof(header->section_identify)); uint32_to_bin(section_size, header->section_size); - uint16_to_bin(nirep, header->nirep); - uint16_to_bin(sirep, header->sirep); return MRB_DUMP_OK; } @@ -327,12 +341,11 @@ get_lineno_record_size(mrb_state *mrb, mrb_irep *irep) if (irep->lines) { size += sizeof(uint16_t) * irep->ilen; // lineno } - return size; } static int -write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) +write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) { uint8_t *cur = bin; size_t filename_len = 0, iseq_no; @@ -365,26 +378,40 @@ write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) } static int -mrb_write_section_lineno(mrb_state *mrb, size_t start_index, uint8_t *bin) +write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) +{ + size_t i; + uint32_t rlen, size = 0; + + rlen = write_lineno_record_1(mrb, irep, bin); + bin += rlen; + size += rlen; + for (i=0; irlen; i++) { + rlen = write_lineno_record_1(mrb, irep, bin); + bin += rlen; + size += rlen; + } + return size; +} + +static int +write_section_lineno(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) { - size_t irep_no; uint32_t section_size = 0, rlen = 0; /* size of irep record */ uint8_t *cur = bin; - if (mrb == NULL || start_index >= mrb->irep_len || bin == NULL) { + if (mrb == NULL || bin == NULL) { return MRB_DUMP_INVALID_ARGUMENT; } cur += sizeof(struct rite_section_lineno_header); section_size += sizeof(struct rite_section_lineno_header); - for (irep_no = start_index; irep_no < mrb->irep_len; irep_no++) { - rlen = write_lineno_record(mrb, mrb->irep[irep_no], cur); - cur += rlen; - section_size += rlen; - } + rlen = write_lineno_record(mrb, irep, cur); + cur += rlen; + section_size += rlen; - mrb_write_section_lineno_header(mrb, section_size, mrb->irep_len - start_index, start_index, bin); + write_section_lineno_header(mrb, section_size, bin); return MRB_DUMP_OK; } @@ -394,11 +421,12 @@ get_debug_record_size(mrb_state *mrb, mrb_irep *irep) { size_t ret = 0; uint32_t f_idx; + size_t i; ret += sizeof(uint32_t); // record size ret += sizeof(uint16_t); // file count - for(f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { + for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { mrb_irep_debug_info_file const* file = irep->debug_info->files[f_idx]; ret += sizeof(uint32_t); // position @@ -419,6 +447,9 @@ get_debug_record_size(mrb_state *mrb, mrb_irep *irep) default: mrb_assert(0); break; } } + for (i=0; irlen; i++) { + ret += get_debug_record_size(mrb, irep->reps[i]); + } return ret; } @@ -428,12 +459,47 @@ find_filename_index(const mrb_sym *ary, size_t ary_len, mrb_sym s) { size_t i; - for(i = 0; i < ary_len; ++i) { - if(ary[i] == s) { return i; } + for (i = 0; i < ary_len; ++i) { + if (ary[i] == s) { return i; } } return -1; } +static size_t +get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, size_t *lp) +{ + mrb_sym *filenames = *fp; + size_t tsize = 0; + size_t file_i; + size_t size = 0; + mrb_irep_debug_info *di = irep->debug_info; + + if (lp == NULL) { + lp = &tsize; + } + for (file_i = 0; file_i < di->flen; ++file_i) { + mrb_irep_debug_info_file *file; + size_t filename_len; + size_t i; + + file = di->files[file_i]; + if (find_filename_index(filenames, *lp, file->filename_sym) == -1) { + // register filename + *lp += 1; + *fp = filenames = (mrb_sym *)mrb_realloc(mrb, filenames, sizeof(mrb_sym*) * (*lp)); + filenames[*lp - 1] = file->filename_sym; + + // filename + mrb_sym2name_len(mrb, file->filename_sym, &filename_len); + size += sizeof(uint16_t) + filename_len; + } + for (i=0; irlen; i++) { + size += get_filename_table_size(mrb, irep->reps[i], fp, lp); + } + } + return size; +} + static int write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, size_t filenames_len) { @@ -444,7 +510,7 @@ write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* cur = bin + sizeof(uint32_t); // skip record size cur += uint16_to_bin(irep->debug_info->flen, cur); // file count - for(f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { + for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { int filename_idx; const mrb_irep_debug_info_file *file = irep->debug_info->files[f_idx]; @@ -453,7 +519,7 @@ write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* // filename index filename_idx = find_filename_index(filenames, filenames_len, - file->filename_sym); + file->filename_sym); mrb_assert(filename_idx != -1); cur += uint16_to_bin(filename_idx, cur); @@ -463,14 +529,14 @@ write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* switch(file->line_type) { case mrb_debug_line_ary: { size_t l; - for(l = 0; l < file->line_entry_count; ++l) { + for (l = 0; l < file->line_entry_count; ++l) { cur += uint16_to_bin(file->line_ary[l], cur); } } break; case mrb_debug_line_flat_map: { uint32_t line; - for(line = 0; line < file->line_entry_count; ++line) { + for (line = 0; line < file->line_entry_count; ++line) { cur += uint32_to_bin(file->line_flat_map[line].start_pos, cur); cur += uint16_to_bin(file->line_flat_map[line].line, cur); } @@ -489,20 +555,48 @@ write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* } static int -mrb_write_section_debug(mrb_state *mrb, size_t start_index, uint8_t *cur) +write_filename_table(mrb_state *mrb, mrb_irep *irep, uint8_t **cp, mrb_sym **fp, size_t *lp) +{ + uint8_t *cur = *cp; + mrb_sym *filenames = *fp; + size_t file_i; + uint16_t fn_len; + size_t size = 0; + mrb_irep_debug_info *debug_info = irep->debug_info; + + for (file_i = 0; file_i < debug_info->flen; ++file_i) { + mrb_irep_debug_info_file *file = debug_info->files[file_i]; + if (find_filename_index(filenames, *lp, file->filename_sym) != -1) continue; + + // register filename + *lp += 1; + *fp = filenames = (mrb_sym*)mrb_realloc(mrb, filenames, sizeof(mrb_sym*) * (*lp)); + filenames[*lp - 1] = file->filename_sym; + + // filename + fn_len = (uint16_t)strlen(file->filename); + cur += uint16_to_bin(fn_len, cur); + memcpy(cur, file->filename, fn_len); + cur += fn_len; + + size += sizeof(uint16_t) + fn_len; + } + *cp = cur; + return size; +} + +static int +write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur) { uint32_t section_size = 0; const uint8_t *bin = cur; struct rite_section_debug_header *header; mrb_sym *filenames; - size_t filenames_len; + size_t filenames_len, i; uint8_t *filenames_len_out; - size_t irep_i; - size_t file_i; - uint16_t fn_len; - size_t i; + uint32_t dlen; - if (mrb == NULL || start_index >= mrb->irep_len || cur == NULL) { + if (mrb == NULL || cur == NULL) { return MRB_DUMP_INVALID_ARGUMENT; } @@ -512,45 +606,23 @@ mrb_write_section_debug(mrb_state *mrb, size_t start_index, uint8_t *cur) // filename table filenames = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym *) * 1); - filenames_len = 0; filenames_len_out = cur; cur += sizeof(uint16_t); section_size += sizeof(uint16_t); - for (irep_i = start_index; irep_i < mrb->irep_len; ++irep_i) { - mrb_irep_debug_info *debug_info = mrb->irep[irep_i]->debug_info; - - for(file_i = 0; file_i < debug_info->flen; ++file_i) { - mrb_irep_debug_info_file *file = debug_info->files[file_i]; - if(find_filename_index(filenames, filenames_len, file->filename_sym) != -1) continue; - - // register filename - filenames = (mrb_sym*)mrb_realloc(mrb, filenames, sizeof(mrb_sym*) * ++filenames_len); - filenames[filenames_len - 1] = file->filename_sym; - - // filename - fn_len = (uint16_t)strlen(file->filename); - cur += uint16_to_bin(fn_len, cur); - memcpy(cur, file->filename, fn_len); - cur += fn_len; - - section_size += sizeof(uint16_t) + fn_len; - } + section_size += write_filename_table(mrb, irep, &cur, &filenames, &filenames_len); + for (i=0; irlen; i++) { + section_size += write_filename_table(mrb, irep->reps[i], &cur, &filenames, &filenames_len); } + mrb_free(mrb, filenames); uint16_to_bin(filenames_len, filenames_len_out); - // records - for (i = start_index; i < mrb->irep_len; ++i) { - uint32_t rlen = write_debug_record(mrb, mrb->irep[i], cur, filenames, filenames_len); - cur += rlen; - section_size += rlen; - } + // debug records + dlen = write_debug_record(mrb, irep, cur, filenames, filenames_len); + cur += dlen; + section_size += dlen; memcpy(header->section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(header->section_identify)); uint32_to_bin(section_size, header->section_size); - uint16_to_bin(mrb->irep_len - start_index, header->nirep); - uint16_to_bin(start_index, header->sirep); - - mrb_free(mrb, filenames); return MRB_DUMP_OK; } @@ -575,124 +647,88 @@ write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin) return MRB_DUMP_OK; } -mrb_bool is_debug_info_defined(mrb_state *mrb, size_t const start_index) +static mrb_bool +is_debug_info_defined(mrb_irep *irep) { size_t i; - for (i = start_index; i < mrb->irep_len; ++i) { - if (!mrb->irep[i]->debug_info) { return 0; } + + if (!irep->debug_info) return 0; + for (i=0; irlen; i++) { + if (!is_debug_info_defined(irep->reps[i])) return 0; } return 1; } static int -mrb_dump_irep(mrb_state *mrb, size_t start_index, int debug_info, uint8_t **bin, size_t *bin_size) +dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size) { int result = MRB_DUMP_GENERAL_FAILURE; - size_t section_size = 0; size_t section_irep_size; size_t section_lineno_size = 0; - size_t irep_no; uint8_t *cur = NULL; + mrb_bool const debug_info_defined = is_debug_info_defined(irep); - mrb_bool const debug_info_defined = is_debug_info_defined(mrb, start_index); - - if (mrb == NULL || start_index >= mrb->irep_len) { + if (mrb == NULL) { *bin = NULL; return MRB_DUMP_GENERAL_FAILURE; } section_irep_size = sizeof(struct rite_section_irep_header); - for (irep_no = start_index; irep_no < mrb->irep_len; irep_no++) { - section_irep_size += get_irep_record_size(mrb, mrb->irep[irep_no]); - } - section_size += section_irep_size; + section_irep_size += get_irep_record_size(mrb, irep); /* DEBUG section size */ if (debug_info) { if (debug_info_defined) { mrb_sym *filenames; - size_t filenames_len; - size_t irep_i; - size_t file_i; section_lineno_size += sizeof(struct rite_section_debug_header); - // filename table - filenames = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym *) + 1); - filenames_len = 0; + filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym *) + 1); + // filename table size section_lineno_size += sizeof(uint16_t); - for (irep_i = start_index; irep_i < mrb->irep_len; ++irep_i) { - mrb_irep_debug_info *di = mrb->irep[irep_i]->debug_info; - - for(file_i = 0; file_i < di->flen; ++file_i) { - mrb_irep_debug_info_file *file; - size_t filename_len; - - file = di->files[file_i]; - if(find_filename_index(filenames, filenames_len, file->filename_sym) != -1) continue; - - // register filename - filenames = (mrb_sym *)mrb_realloc(mrb, filenames, sizeof(mrb_sym*) * ++filenames_len); - filenames[filenames_len - 1] = file->filename_sym; - - // filename - mrb_sym2name_len(mrb, file->filename_sym, &filename_len); - section_lineno_size += sizeof(uint16_t) + filename_len; - } - } + section_lineno_size += get_filename_table_size(mrb, irep, &filenames, NULL); mrb_free(mrb, filenames); - for(irep_no = start_index; irep_no < mrb->irep_len; ++irep_no) { - section_lineno_size += get_debug_record_size(mrb, mrb->irep[irep_no]); - } - section_size += section_lineno_size; + section_lineno_size += get_debug_record_size(mrb, irep); } else { section_lineno_size += sizeof(struct rite_section_lineno_header); - for (irep_no = start_index; irep_no < mrb->irep_len; irep_no++) { - section_lineno_size += get_lineno_record_size(mrb, mrb->irep[irep_no]); - } - section_size += section_lineno_size; + section_lineno_size += get_lineno_record_size(mrb, irep); } } - *bin_size += sizeof(struct rite_binary_header) + section_size + sizeof(struct rite_binary_footer); - cur = *bin = (uint8_t *)mrb_malloc(mrb, *bin_size); + *bin_size = sizeof(struct rite_binary_header) + + section_irep_size + section_lineno_size + + sizeof(struct rite_binary_footer); + cur = *bin = (uint8_t*)mrb_malloc(mrb, *bin_size); if (cur == NULL) { goto error_exit; } - cur += sizeof(struct rite_binary_header); - result = mrb_write_section_irep(mrb, start_index, cur); + result = write_section_irep(mrb, irep, cur); if (result != MRB_DUMP_OK) { goto error_exit; } - cur += section_irep_size; /* write DEBUG section */ if (debug_info) { - if(debug_info_defined) { - result = mrb_write_section_debug(mrb, start_index, cur); - if(result != MRB_DUMP_OK) { - goto error_exit; - } - cur += section_lineno_size; + if (debug_info_defined) { + result = write_section_debug(mrb, irep, cur); } else { - result = mrb_write_section_lineno(mrb, start_index, cur); - if (result != MRB_DUMP_OK) { - goto error_exit; - } - cur += section_lineno_size; + result = write_section_lineno(mrb, irep, cur); } + if (result != MRB_DUMP_OK) { + goto error_exit; + } + cur += section_lineno_size; } - mrb_write_eof(mrb, cur); - - result = write_rite_binary_header(mrb, *bin_size, *bin); + write_footer(mrb, cur); + write_rite_binary_header(mrb, *bin_size, *bin); error_exit: if (result != MRB_DUMP_OK) { @@ -706,7 +742,7 @@ error_exit: #ifdef ENABLE_STDIO int -mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, int debug_info, FILE* fp) +mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp) { uint8_t *bin = NULL; size_t bin_size = 0; @@ -716,7 +752,7 @@ mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, int debug_info, FILE* f return MRB_DUMP_INVALID_ARGUMENT; } - result = mrb_dump_irep(mrb, start_index, debug_info, &bin, &bin_size); + result = dump_irep(mrb, irep, debug_info, &bin, &bin_size); if (result == MRB_DUMP_OK) { fwrite(bin, bin_size, 1, fp); } @@ -742,7 +778,7 @@ is_valid_c_symbol_name(const char *name) } int -mrb_dump_irep_cfunc(mrb_state *mrb, size_t start_index, int debug_info, FILE *fp, const char *initname) +mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE *fp, const char *initname) { uint8_t *bin = NULL; size_t bin_size = 0, bin_idx = 0; @@ -752,12 +788,12 @@ mrb_dump_irep_cfunc(mrb_state *mrb, size_t start_index, int debug_info, FILE *fp return MRB_DUMP_INVALID_ARGUMENT; } - result = mrb_dump_irep(mrb, start_index, debug_info, &bin, &bin_size); + result = dump_irep(mrb, irep, debug_info, &bin, &bin_size); if (result == MRB_DUMP_OK) { fprintf(fp, "#include \n"); // for uint8_t under at least Darwin fprintf(fp, "const uint8_t %s[] = {", initname); while (bin_idx < bin_size) { - if (bin_idx % 16 == 0 ) fputs("\n", fp); + if (bin_idx % 16 == 0) fputs("\n", fp); fprintf(fp, "0x%02x,", bin[bin_idx++]); } fputs("\n};\n", fp); -- cgit v1.2.3