summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYuichiro MASUI <[email protected]>2013-03-27 18:02:48 +0900
committerYuichiro MASUI <[email protected]>2013-03-27 18:21:04 +0900
commitf3ebb89392163afba18f0f05634255adaf527294 (patch)
tree81de5eb967d20d17ba67cdbdfa1aa2cff4b21cde
parentf1e6a4a3b564ac07f0b283af05bc2d7be5a31414 (diff)
downloadmruby-f3ebb89392163afba18f0f05634255adaf527294.tar.gz
mruby-f3ebb89392163afba18f0f05634255adaf527294.zip
Added debug infomation section into .mrb file
-rw-r--r--include/mruby/dump.h12
-rw-r--r--src/dump.c127
-rw-r--r--src/load.c141
-rw-r--r--tools/mrbc/mrbc.c9
4 files changed, 277 insertions, 12 deletions
diff --git a/include/mruby/dump.h b/include/mruby/dump.h
index a9cc93fdc..42427de68 100644
--- a/include/mruby/dump.h
+++ b/include/mruby/dump.h
@@ -14,8 +14,8 @@ extern "C" {
#include "mruby.h"
#ifdef ENABLE_STDIO
-int mrb_dump_irep_binary(mrb_state*, size_t, FILE*);
-int mrb_dump_irep_cfunc(mrb_state *mrb, size_t n, FILE *f, const char *initname);
+int mrb_dump_irep_binary(mrb_state*, size_t, int, FILE*);
+int mrb_dump_irep_cfunc(mrb_state *mrb, size_t n, int, FILE *f, const char *initname);
int32_t mrb_read_irep_file(mrb_state*, FILE*);
#endif
int mrb_read_irep(mrb_state*, const uint8_t*);
@@ -51,6 +51,7 @@ mrb_value mrb_load_irep_file(mrb_state*,FILE*);
#define RITE_BINARY_EOF "END\0"
#define RITE_SECTION_IREP_IDENTIFIER "IREP"
+#define RITE_SECTION_LIENO_IDENTIFIER "LINE"
#define MRB_DUMP_DEFAULT_STR_LEN 128
@@ -81,6 +82,13 @@ struct rite_section_irep_header {
uint8_t sirep[2]; // Start index
};
+struct rite_section_lineno_header {
+ RITE_SECTION_HEADER;
+
+ uint8_t nirep[2]; // Number of ireps
+ uint8_t sirep[2]; // Start index
+};
+
struct rite_binary_footer {
RITE_SECTION_HEADER;
};
diff --git a/src/dump.c b/src/dump.c
index fdb20f68a..d3f6ee62b 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -334,6 +334,97 @@ 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
+ memcpy(header->section_identify, RITE_SECTION_LIENO_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;
+}
+
+static size_t
+get_debug_record_size(mrb_state *mrb, mrb_irep *irep)
+{
+ size_t size = 0;
+
+ size += sizeof(uint32_t); // record size
+ size += sizeof(uint16_t); // filename size
+ if(irep->filename) {
+ size += strlen(irep->filename); // filename
+ }
+ size += sizeof(uint32_t); // niseq
+ 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)
+{
+ uint8_t *cur = bin;
+ size_t filename_len = 0;
+ int iseq_no;
+
+ cur += sizeof(uint32_t); /* record size */
+
+ if(irep->filename) {
+ filename_len = strlen(irep->filename);
+ }
+ cur += uint16_to_bin(filename_len, cur); /* filename size */
+
+ if(filename_len) {
+ memcpy(cur, irep->filename, filename_len);
+ cur += filename_len; /* filename */
+ }
+
+ if(irep->lines) {
+ cur += uint32_to_bin(irep->ilen, cur); /* niseq */
+ for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
+ cur += uint16_to_bin(irep->lines[iseq_no], cur); /* opcode */
+ }
+ }
+ else {
+ cur += uint32_to_bin(0, cur); /* niseq */
+ }
+
+ uint32_to_bin(cur - bin, bin); /* record size */
+
+ return (cur - bin);
+}
+
+static int
+mrb_write_section_lineno(mrb_state *mrb, int start_index, uint8_t *bin)
+{
+ int irep_no;
+ uint32_t section_size = 0, rlen = 0; /* size of irep record */
+ uint8_t *cur = bin;
+
+ if (mrb == NULL || start_index < 0 || start_index >= mrb->irep_len || 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;
+ }
+
+ mrb_write_section_lineno_header(mrb, section_size, mrb->irep_len - start_index, start_index, bin);
+
+ 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;
@@ -354,10 +445,12 @@ write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t* bin)
}
static int
-mrb_dump_irep(mrb_state *mrb, size_t start_index, uint8_t **bin, size_t *bin_size)
+mrb_dump_irep(mrb_state *mrb, size_t start_index, 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;
@@ -370,8 +463,18 @@ mrb_dump_irep(mrb_state *mrb, size_t start_index, uint8_t **bin, size_t *bin_siz
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;
+
+ /* 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]);
+ }
+ section_size += section_lineno_size;
+ }
- *bin_size += sizeof(struct rite_binary_header) + section_irep_size + sizeof(struct rite_binary_footer);
+ *bin_size += sizeof(struct rite_binary_header) + section_size + sizeof(struct rite_binary_footer);
cur = *bin = (uint8_t *)mrb_malloc(mrb, *bin_size);
if(cur == NULL) {
goto error_exit;
@@ -383,8 +486,18 @@ mrb_dump_irep(mrb_state *mrb, size_t start_index, uint8_t **bin, size_t *bin_siz
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;
+ }
+ cur += section_lineno_size;
+ }
+
mrb_write_eof(mrb, cur);
result = write_rite_binary_header(mrb, *bin_size, *bin);
@@ -401,7 +514,7 @@ error_exit:
#ifdef ENABLE_STDIO
int
-mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, FILE* fp)
+mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, int debug_info, FILE* fp)
{
uint8_t *bin = NULL;
size_t bin_size = 0;
@@ -411,7 +524,7 @@ mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, FILE* fp)
return MRB_DUMP_INVALID_ARGUMENT;
}
- result = mrb_dump_irep(mrb, start_index, &bin, &bin_size);
+ result = mrb_dump_irep(mrb, start_index, debug_info, &bin, &bin_size);
if (result == MRB_DUMP_OK) {
fwrite(bin, bin_size, 1, fp);
}
@@ -421,7 +534,7 @@ mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, FILE* fp)
}
int
-mrb_dump_irep_cfunc(mrb_state *mrb, size_t start_index, FILE *fp, const char *initname)
+mrb_dump_irep_cfunc(mrb_state *mrb, size_t start_index, int debug_info, FILE *fp, const char *initname)
{
uint8_t *bin = NULL;
size_t bin_size = 0, bin_idx = 0;
@@ -431,7 +544,7 @@ mrb_dump_irep_cfunc(mrb_state *mrb, size_t start_index, FILE *fp, const char *in
return MRB_DUMP_INVALID_ARGUMENT;
}
- result = mrb_dump_irep(mrb, start_index, &bin, &bin_size);
+ result = mrb_dump_irep(mrb, start_index, debug_info, &bin, &bin_size);
if (result == MRB_DUMP_OK) {
fprintf(fp, "const uint8_t %s[] = {", initname);
while (bin_idx < bin_size) {
diff --git a/src/load.c b/src/load.c
index d0859df27..23b23af5c 100644
--- a/src/load.c
+++ b/src/load.c
@@ -32,7 +32,7 @@ static size_t
offset_crc_body()
{
struct rite_binary_header header;
- return ((char *)header.binary_crc - (char *)&header) + sizeof(header.binary_crc);
+ return ((uint8_t *)header.binary_crc - (uint8_t *)&header) + sizeof(header.binary_crc);
}
static int
@@ -226,6 +226,74 @@ error_exit:
}
static int
+read_rite_lineno_record(mrb_state *mrb, const uint8_t *bin, size_t irepno, uint32_t *len)
+{
+ int ret;
+ size_t i, fname_len, niseq;
+ char *fname;
+ short *lines;
+
+ bin += sizeof(uint32_t); // record size
+ fname_len = bin_to_uint16(bin);
+ bin += sizeof(uint16_t);
+ fname = (char *)mrb_malloc(mrb, fname_len + 1);
+ if (fname == NULL) {
+ ret = MRB_DUMP_GENERAL_FAILURE;
+ goto error_exit;
+ }
+ memcpy(fname, bin, fname_len);
+ fname[fname_len] = '\0';
+ bin += fname_len;
+
+ niseq = bin_to_uint32(bin);
+ bin += sizeof(uint32_t); // niseq
+
+ lines = (short *)mrb_malloc(mrb, niseq * sizeof(short));
+ for (i = 0; i < niseq; i++) {
+ lines[i] = bin_to_uint16(bin);
+ bin += sizeof(short); // niseq
+ }
+
+ mrb->irep[irepno]->filename = fname;
+ mrb->irep[irepno]->lines = lines;
+
+error_exit:
+ return MRB_DUMP_OK;
+}
+
+static int
+read_rite_section_lineno(mrb_state *mrb, const uint8_t *bin, size_t sirep)
+{
+ int result;
+ size_t i;
+ uint32_t len;
+ uint16_t nirep;
+ uint16_t n;
+ const struct rite_section_lineno_header *header;
+
+ header = (const struct rite_section_lineno_header*)bin;
+ bin += sizeof(struct rite_section_lineno_header);
+
+ nirep = bin_to_uint16(header->nirep);
+
+ //Read Binary Data Section
+ for (n = 0, i = sirep; n < nirep; n++, i++) {
+ result = read_rite_lineno_record(mrb, bin, i, &len);
+ if (result != MRB_DUMP_OK)
+ goto error_exit;
+ bin += len;
+ }
+
+ result = MRB_DUMP_OK;
+error_exit:
+ if (result != MRB_DUMP_OK) {
+ return result;
+ }
+ return sirep + bin_to_uint16(header->sirep);
+}
+
+
+static int
read_rite_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc)
{
const struct rite_binary_header *header = (const struct rite_binary_header *)bin;
@@ -255,6 +323,7 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
uint16_t crc;
size_t bin_size = 0;
size_t n;
+ size_t sirep;
if ((mrb == NULL) || (bin == NULL)) {
return MRB_DUMP_INVALID_ARGUMENT;
@@ -271,6 +340,7 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
}
bin += sizeof(struct rite_binary_header);
+ sirep = mrb->irep_len;
do {
section_header = (const struct rite_section_header *)bin;
@@ -281,6 +351,12 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
}
total_nirep += result;
}
+ else if(memcmp(section_header->section_identify, RITE_SECTION_LIENO_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
+ result = read_rite_section_lineno(mrb, bin, sirep);
+ if(result < MRB_DUMP_OK) {
+ return result;
+ }
+ }
bin += bin_to_uint32(section_header->section_size);
} while(memcmp(section_header->section_identify, RITE_BINARY_EOF, sizeof(section_header->section_identify)) != 0);
@@ -310,6 +386,60 @@ mrb_load_irep(mrb_state *mrb, const uint8_t *bin)
#ifdef ENABLE_STDIO
static int32_t
+read_rite_section_lineno_file(mrb_state *mrb, FILE *fp, size_t sirep)
+{
+ int32_t result;
+ size_t i;
+ uint16_t nirep;
+ uint16_t n;
+ uint32_t len, buf_size;
+ uint8_t *buf = NULL;
+ const size_t record_header_size = 4;
+
+ struct rite_section_lineno_header header;
+ fread(&header, sizeof(struct rite_section_lineno_header), 1, fp);
+
+ nirep = bin_to_uint16(header.nirep);
+
+ buf_size = record_header_size;
+ buf = (uint8_t *)mrb_malloc(mrb, buf_size);
+
+ //Read Binary Data Section
+ for (n = 0, i = sirep; n < nirep; n++, i++) {
+ fread(buf, record_header_size, 1, fp);
+ buf_size = bin_to_uint32(&buf[0]);
+ buf = (uint8_t *)mrb_realloc(mrb, buf, buf_size);
+
+ fread(&buf[record_header_size], buf_size - record_header_size, 1, fp);
+ result = read_rite_lineno_record(mrb, buf, i, &len);
+ if (result != MRB_DUMP_OK)
+ goto error_exit;
+ }
+
+ result = MRB_DUMP_OK;
+error_exit:
+ mrb_free(mrb, buf);
+ if (result != MRB_DUMP_OK) {
+ for (i = sirep; i < mrb->irep_len; i++) {
+ if (mrb->irep[i]) {
+ if (mrb->irep[i]->iseq)
+ mrb_free(mrb, mrb->irep[i]->iseq);
+
+ if (mrb->irep[i]->pool)
+ mrb_free(mrb, mrb->irep[i]->pool);
+
+ if (mrb->irep[i]->syms)
+ mrb_free(mrb, mrb->irep[i]->syms);
+
+ mrb_free(mrb, mrb->irep[i]);
+ }
+ }
+ return result;
+ }
+ return sirep + bin_to_uint16(header.sirep);
+}
+
+static int32_t
read_rite_section_irep_file(mrb_state *mrb, FILE *fp)
{
int32_t result;
@@ -381,6 +511,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
uint16_t crc, crcwk = 0;
uint32_t section_size = 0;
size_t nbytes;
+ size_t sirep;
struct rite_section_header section_header;
long fpos;
const size_t block_size = 1 << 14;
@@ -416,6 +547,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
return MRB_DUMP_INVALID_FILE_HEADER;
}
fseek(fp, fpos + section_size, SEEK_SET);
+ sirep = mrb->irep_len;
// read sections
do {
@@ -433,6 +565,13 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
}
total_nirep += result;
}
+ else if(memcmp(section_header.section_identify, RITE_SECTION_LIENO_IDENTIFIER, sizeof(section_header.section_identify)) == 0) {
+ fseek(fp, fpos, SEEK_SET);
+ result = read_rite_section_lineno_file(mrb, fp, sirep);
+ if(result < MRB_DUMP_OK) {
+ return result;
+ }
+ }
fseek(fp, fpos + section_size, SEEK_SET);
} while(memcmp(section_header.section_identify, RITE_BINARY_EOF, sizeof(section_header.section_identify)) != 0);
diff --git a/tools/mrbc/mrbc.c b/tools/mrbc/mrbc.c
index 6535d5636..e217ef30f 100644
--- a/tools/mrbc/mrbc.c
+++ b/tools/mrbc/mrbc.c
@@ -21,6 +21,7 @@ struct _args {
char *ext;
mrb_bool check_syntax : 1;
mrb_bool verbose : 1;
+ mrb_bool debug_info : 1;
};
static void
@@ -31,6 +32,7 @@ usage(const char *name)
"-c check syntax only",
"-o<outfile> place the output into <outfile>",
"-v print version number, then trun on verbose mode",
+ "-g produce debugging information",
"-B<symbol> binary <symbol> output in C language format",
"--verbose run at verbose mode",
"--version print the version",
@@ -107,6 +109,9 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
mrb_show_version(mrb);
args->verbose = 1;
break;
+ case 'g':
+ args->debug_info = 1;
+ break;
case '-':
if (strcmp((*argv) + 2, "version") == 0) {
mrb_show_version(mrb);
@@ -209,10 +214,10 @@ main(int argc, char **argv)
return EXIT_SUCCESS;
}
if (args.initname) {
- n = mrb_dump_irep_cfunc(mrb, n, args.wfp, args.initname);
+ n = mrb_dump_irep_cfunc(mrb, n, args.debug_info, args.wfp, args.initname);
}
else {
- n = mrb_dump_irep_binary(mrb, n, args.wfp);
+ n = mrb_dump_irep_binary(mrb, n, args.debug_info, args.wfp);
}
cleanup(mrb, &args);