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; i<irep->rlen; i++) { size += get_filename_table_size(mrb, irep->reps[i], fp, lp); } } return size; }
static int 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_lv_record(mrb_state *mrb, const mrb_irep *irep, uint8_t **start, mrb_sym const *syms, uint32_t syms_len) { uint8_t *cur = *start; size_t i; for (i = 0; i + 1 < irep->nlocals; ++i) { if (irep->lv[i].name == 0) { cur += uint16_to_bin(RITE_LV_NULL_MARK, cur); cur += uint16_to_bin(0, cur); } else { int const sym_idx = find_filename_index(syms, syms_len, irep->lv[i].name); mrb_assert(sym_idx != -1); /* local variable name must be in syms */ cur += uint16_to_bin(sym_idx, cur); cur += uint16_to_bin(irep->lv[i].r, cur); } } for (i = 0; i < irep->rlen; ++i) { write_lv_record(mrb, irep->reps[i], &cur, syms, syms_len); } *start = cur; return MRB_DUMP_OK; }
static size_t get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint16_t *lp) { mrb_sym *filenames = *fp; size_t i, size = 0; mrb_irep_debug_info *di = irep->debug_info; mrb_assert(lp); for (i = 0; i < di->flen; ++i) { mrb_irep_debug_info_file *file; mrb_int filename_len; file = di->files[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) + (size_t)filename_len; } } for (i=0; i<irep->rlen; i++) { size += get_filename_table_size(mrb, irep->reps[i], fp, lp); } return size; }
static size_t write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len) { uint8_t *cur; uint16_t f_idx; ptrdiff_t ret; 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) { int filename_idx; const mrb_irep_debug_info_file *file = irep->debug_info->files[f_idx]; /* position */ cur += uint32_to_bin(file->start_pos, cur); /* filename index */ filename_idx = find_filename_index(filenames, filenames_len, file->filename_sym); mrb_assert(filename_idx >= 0); mrb_assert(filename_idx <= UINT16_MAX); cur += uint16_to_bin((uint16_t)filename_idx, cur); /* lines */ cur += uint32_to_bin(file->line_entry_count, cur); cur += uint8_to_bin(file->line_type, cur); switch(file->line_type) { case mrb_debug_line_ary: { uint32_t 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) { cur += uint32_to_bin(file->line_flat_map[line].start_pos, cur); cur += uint16_to_bin(file->line_flat_map[line].line, cur); } } break; default: mrb_assert(0); break; } } ret = cur - bin; mrb_assert(ret >= 0); mrb_assert(ret <= UINT32_MAX); uint32_to_bin(ret, bin); mrb_assert((size_t)ret <= SIZE_MAX); return (size_t)ret; }
static int write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, size_t filenames_len) { uint8_t *cur; uint32_t f_idx; size_t ret; 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) { int filename_idx; const mrb_irep_debug_info_file *file = irep->debug_info->files[f_idx]; // position cur += uint32_to_bin(file->start_pos, cur); // filename index filename_idx = find_filename_index(filenames, filenames_len, file->filename_sym); mrb_assert(filename_idx != -1); cur += uint16_to_bin(filename_idx, cur); // lines cur += uint32_to_bin(file->line_entry_count, cur); cur += uint8_to_bin(file->line_type, cur); switch(file->line_type) { case mrb_debug_line_ary: { size_t 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) { cur += uint32_to_bin(file->line_flat_map[line].start_pos, cur); cur += uint16_to_bin(file->line_flat_map[line].line, cur); } } break; default: mrb_assert(0); break; } } ret = cur - bin; uint32_to_bin(ret, bin); mrb_assert((cur - bin) == (int)get_debug_record_size(mrb, irep)); return ret; }
static void create_lv_sym_table(mrb_state *mrb, const mrb_irep *irep, mrb_sym **syms, uint32_t *syms_len) { size_t i; if (*syms == NULL) { *syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * 1); } for (i = 0; i + 1 < irep->nlocals; ++i) { mrb_sym const name = irep->lv[i].name; if (name == 0) continue; if (find_filename_index(*syms, *syms_len, name) != -1) continue; ++(*syms_len); *syms = (mrb_sym*)mrb_realloc(mrb, *syms, sizeof(mrb_sym) * (*syms_len)); (*syms)[*syms_len - 1] = name; } for (i = 0; i < irep->rlen; ++i) { create_lv_sym_table(mrb, irep->reps[i], syms, syms_len); } }