summaryrefslogtreecommitdiffhomepage
path: root/src/dump.c
diff options
context:
space:
mode:
authortake_cheeze <[email protected]>2013-09-01 22:43:17 +0900
committertake_cheeze <[email protected]>2013-09-02 00:48:06 +0900
commit3d1fffbd6bce3a6f9a77af3116078574ce8d5fe9 (patch)
tree35d6c58a23442ca055671c3b9e34f736153bc4ec /src/dump.c
parentbc131350d416409220fd3294d2ffcea3ae73027d (diff)
downloadmruby-3d1fffbd6bce3a6f9a77af3116078574ce8d5fe9.tar.gz
mruby-3d1fffbd6bce3a6f9a77af3116078574ce8d5fe9.zip
support multiple filename in irep
Diffstat (limited to 'src/dump.c')
-rw-r--r--src/dump.c221
1 files changed, 206 insertions, 15 deletions
diff --git a/src/dump.c b/src/dump.c
index 72ca9e0c3..92b1b011a 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -11,6 +11,8 @@
#include "mruby/string.h"
#include "mruby/irep.h"
#include "mruby/numeric.h"
+#include "mruby/debug.h"
+#include "mruby/array.h"
static size_t get_irep_record_size(mrb_state *mrb, mrb_irep *irep);
@@ -257,7 +259,7 @@ 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)
-{
+{
struct rite_section_irep_header *header = (struct rite_section_irep_header*)bin;
memcpy(header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(header->section_identify));
@@ -300,7 +302,7 @@ mrb_write_section_irep(mrb_state *mrb, size_t start_index, uint8_t *bin)
static int
mrb_write_section_lineno_header(mrb_state *mrb, uint32_t section_size, uint16_t nirep, uint16_t sirep, uint8_t *bin)
-{
+{
struct rite_section_lineno_header *header = (struct rite_section_lineno_header*)bin;
// TODO
@@ -313,7 +315,7 @@ mrb_write_section_lineno_header(mrb_state *mrb, uint32_t section_size, uint16_t
}
static size_t
-get_debug_record_size(mrb_state *mrb, mrb_irep *irep)
+get_lineno_record_size(mrb_state *mrb, mrb_irep *irep)
{
size_t size = 0;
@@ -388,9 +390,152 @@ mrb_write_section_lineno(mrb_state *mrb, size_t start_index, uint8_t *bin)
return MRB_DUMP_OK;
}
+static size_t
+get_debug_record_size(mrb_state* mrb, mrb_irep *irep) {
+ (void)mrb;
+ size_t ret = 0;
+
+ ret += sizeof(uint32_t); // record size
+ ret += sizeof(uint16_t); // file count
+
+ for(uint32_t 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
+ ret += sizeof(uint16_t); // filename index
+
+ // lines
+ ret += sizeof(uint32_t); // entry count
+ ret += sizeof(uint8_t); // line type
+ switch(file->line_type) {
+ case mrb_debug_line_ary:
+ ret += sizeof(uint16_t) * file->line_entry_count;
+ break;
+
+ case mrb_debug_line_flat_map:
+ ret += (sizeof(uint32_t) + sizeof(uint16_t)) * file->line_entry_count;
+ break;
+
+ default: mrb_assert(0); break;
+ }
+ }
+
+ return ret;
+}
+
+static int
+find_filename_index(mrb_value const ary, mrb_sym s) {
+ for(mrb_int i = 0; i < RARRAY_LEN(ary); ++i) {
+ mrb_assert(mrb_symbol_p(RARRAY_PTR(ary)[i]));
+ if(mrb_symbol(RARRAY_PTR(ary)[i]) == s) { return i; }
+ }
+ return -1;
+}
+
+static int
+write_debug_record(mrb_state* mrb, mrb_irep *irep, uint8_t * const bin, mrb_value filenames)
+{
+ uint8_t *cur = bin + sizeof(uint32_t); // skip record size
+
+ cur += uint16_to_bin(irep->debug_info->flen, cur); // file count
+ for(uint32_t f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) {
+ mrb_irep_debug_info_file const* file = irep->debug_info->files[f_idx];
+
+ // position
+ cur += uint32_to_bin(file->start_pos, cur);
+
+ // filename index
+ int const filename_idx = find_filename_index(filenames, 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: {
+ for(size_t l = 0; l < file->line_entry_count; ++l) {
+ cur += uint16_to_bin(file->line_ary[l], cur);
+ }
+ } break;
+
+ case mrb_debug_line_flat_map:
+ for(uint32_t 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;
+ }
+ }
+
+ size_t const ret = cur - bin;
+ uint32_to_bin(ret, bin);
+
+ mrb_assert((cur - bin) == (int)get_debug_record_size(mrb, irep));
+
+ return ret;
+}
+
+static int
+mrb_write_section_debug(mrb_state* mrb, size_t start_index, uint8_t *cur)
+{
+ uint32_t section_size = 0;
+ uint8_t* const bin = cur;
+
+ if (mrb == NULL || start_index >= mrb->irep_len || cur == NULL) {
+ return MRB_DUMP_INVALID_ARGUMENT;
+ }
+
+ struct rite_section_debug_header* header = (struct rite_section_debug_header*)bin;
+ cur += sizeof(struct rite_section_debug_header);
+ section_size += sizeof(struct rite_section_debug_header);
+
+ // filename table
+ mrb_value const filenames = mrb_ary_new(mrb);
+ uint8_t* const filenames_len = cur;
+ cur += sizeof(uint16_t);
+ section_size += sizeof(uint16_t);
+ for (size_t irep_i = start_index; irep_i < mrb->irep_len; ++irep_i) {
+ mrb_irep_debug_info const* debug_info = mrb->irep[irep_i]->debug_info;
+
+ for(size_t file_i = 0; file_i < debug_info->flen; ++file_i) {
+ mrb_irep_debug_info_file const* file = debug_info->files[file_i];
+ if(find_filename_index(filenames, file->filename_sym) != -1) continue;
+
+ // register filename
+ mrb_ary_push(mrb, filenames, mrb_symbol_value(file->filename_sym));
+
+ // filename
+ uint16_t const fn_len = 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;
+ }
+ }
+ uint16_to_bin(RARRAY_LEN(filenames), filenames_len);
+
+ // records
+ for (size_t i = start_index; i < mrb->irep_len; ++i) {
+ uint32_t rlen = write_debug_record(mrb, mrb->irep[i], cur, filenames);
+ cur += rlen;
+ section_size += rlen;
+ }
+
+ 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);
+
+ return MRB_DUMP_OK;
+}
+
static int
write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t* bin)
-{
+{
struct rite_binary_header *header = (struct rite_binary_header*)bin;
uint16_t crc;
size_t offset;
@@ -400,7 +545,7 @@ write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t* bin)
memcpy(header->compiler_name, RITE_COMPILER_NAME, sizeof(header->compiler_name));
memcpy(header->compiler_version, RITE_COMPILER_VERSION, sizeof(header->compiler_version));
uint32_to_bin(binary_size, header->binary_size);
-
+
offset = (&(header->binary_crc[0]) - bin) + sizeof(uint16_t);
crc = calc_crc_16_ccitt(bin + offset, binary_size - offset, 0);
uint16_to_bin(crc, header->binary_crc);
@@ -408,6 +553,13 @@ 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) {
+ for (size_t i = start_index; i < mrb->irep_len; ++i) {
+ if (!mrb->irep[i]->debug_info) { 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)
{
@@ -418,6 +570,8 @@ mrb_dump_irep(mrb_state *mrb, size_t start_index, int debug_info, uint8_t **bin,
size_t irep_no;
uint8_t *cur = NULL;
+ mrb_bool const debug_info_defined = is_debug_info_defined(mrb, start_index);
+
if (mrb == NULL || start_index >= mrb->irep_len) {
*bin = NULL;
return MRB_DUMP_GENERAL_FAILURE;
@@ -431,11 +585,39 @@ mrb_dump_irep(mrb_state *mrb, size_t start_index, int debug_info, uint8_t **bin,
/* DEBUG section size */
if (debug_info) {
- 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_debug_record_size(mrb, mrb->irep[irep_no]);
+ if (debug_info_defined) {
+ section_lineno_size += sizeof(struct rite_section_debug_header);
+
+ // filename table
+ mrb_value const filenames = mrb_ary_new(mrb);
+ // filename table size
+ section_lineno_size += sizeof(uint16_t);
+ for (size_t irep_i = start_index; irep_i < mrb->irep_len; ++irep_i) {
+ mrb_irep_debug_info const* di = mrb->irep[irep_i]->debug_info;
+
+ for(size_t file_i = 0; file_i < di->flen; ++file_i) {
+ mrb_irep_debug_info_file const* file = di->files[file_i];
+ if(find_filename_index(filenames, file->filename_sym) != -1) continue;
+
+ // register filename
+ mrb_ary_push(mrb, filenames, mrb_symbol_value(file->filename_sym));
+ // filename
+ section_lineno_size += sizeof(uint16_t) + strlen(file->filename);
+ }
+ }
+
+ 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;
+ }
+ 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_size += section_lineno_size;
}
*bin_size += sizeof(struct rite_binary_header) + section_size + sizeof(struct rite_binary_footer);
@@ -450,16 +632,25 @@ mrb_dump_irep(mrb_state *mrb, size_t start_index, int debug_info, uint8_t **bin,
if (result != MRB_DUMP_OK) {
goto error_exit;
}
-
+
cur += section_irep_size;
-
+
/* write DEBUG section */
if (debug_info) {
- result = mrb_write_section_lineno(mrb, start_index, cur);
- if (result != MRB_DUMP_OK) {
- goto error_exit;
+ 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;
+ }
+ else {
+ result = mrb_write_section_lineno(mrb, start_index, cur);
+ if (result != MRB_DUMP_OK) {
+ goto error_exit;
+ }
+ cur += section_lineno_size;
}
- cur += section_lineno_size;
}
mrb_write_eof(mrb, cur);