summaryrefslogtreecommitdiffhomepage
path: root/src/dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dump.c')
-rw-r--r--src/dump.c777
1 files changed, 237 insertions, 540 deletions
diff --git a/src/dump.c b/src/dump.c
index 9666f7562..fdb20f68a 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -1,5 +1,5 @@
/*
-** dump.c - mruby binary dumper (Rite binary format)
+** dump.c - mruby binary dumper (mrbc binary format)
**
** See Copyright Notice in mruby.h
*/
@@ -12,249 +12,86 @@
#include "mruby/irep.h"
#include "mruby/numeric.h"
-static const unsigned char def_rite_binary_header[] =
- RITE_FILE_IDENFIFIER
- RITE_FILE_FORMAT_VER
- RITE_VM_VER
- RITE_COMPILER_TYPE
- RITE_COMPILER_VER
- "0000" //Binary data size
- "00" //Number of ireps
- "00" //Start index
- RITE_RESERVED
-;
-
-static const unsigned char def_rite_file_header[] =
- RITE_FILE_IDENFIFIER
- RITE_FILE_FORMAT_VER
- RITE_VM_VER
- RITE_COMPILER_TYPE
- RITE_COMPILER_VER
- "00000000" //Binary data size
- "0000" //Number of ireps
- "0000" //Start index
- RITE_RESERVED
- "0000" //CRC
-;
-
-const char bin2hex[] = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-};
-
-#define DUMP_SIZE(size, type) ((type == DUMP_TYPE_BIN) ? size : size * RITE_FILE_HEX_SIZE)
-
-enum {
- DUMP_IREP_HEADER = 0,
- DUMP_ISEQ_BLOCK,
- DUMP_POOL_BLOCK,
- DUMP_SYMS_BLOCK,
- DUMP_SECTION_NUM,
-};
+static size_t
+get_irep_record_size(mrb_state *mrb, mrb_irep *irep);
-#ifdef ENABLE_STDIO
-
-uint16_t calc_crc_16_ccitt(unsigned char*,int);
-static inline int uint8_dump(uint8_t,char*,int);
-static inline int uint16_dump(uint16_t,char*,int);
-static inline int uint32_dump(uint32_t,char*,int);
-static char* str_dump(char*,char*,uint16_t,int);
-static uint16_t str_dump_len(char*,uint16_t, int);
-static uint32_t get_irep_header_size(mrb_state*,int);
-static uint32_t get_iseq_block_size(mrb_state*,mrb_irep*,int);
-static uint32_t get_pool_block_size(mrb_state*,mrb_irep*,int);
-static uint32_t get_syms_block_size(mrb_state*,mrb_irep*,int);
-static uint32_t get_irep_record_size(mrb_state*,int,int);
-static int write_irep_header(mrb_state*,mrb_irep*,char*,int);
-static int write_iseq_block(mrb_state*,mrb_irep*,char*,int);
-static int write_pool_block(mrb_state*,mrb_irep*,char*,int);
-static int write_syms_block(mrb_state*,mrb_irep*,char*,int);
-static int calc_crc_section(mrb_state*,mrb_irep*,uint16_t*,int);
-static int write_rite_header(mrb_state*,int,char*,uint32_t);
-static int dump_rite_header(mrb_state*,int,FILE*,uint32_t);
-static int write_irep_record(mrb_state*,int,char*,uint32_t*,int);
-static int dump_irep_record(mrb_state*,int,FILE*,uint32_t*);
-static int mrb_write_irep(mrb_state*,int,char*);
-
-
-static inline int
-uint8_dump(uint8_t bin, char *hex, int type)
+static uint32_t
+get_irep_header_size(mrb_state *mrb)
{
- if (type == DUMP_TYPE_BIN) {
- *hex = bin;
- } else {
- *hex++ = bin2hex[(bin >> 4) & 0x0f];
- *hex = bin2hex[bin & 0x0f];
- }
- return DUMP_SIZE(MRB_DUMP_SIZE_OF_CHAR, type);
-}
+ uint32_t size = 0;
-static inline int
-uint16_dump(uint16_t bin, char *hex, int type)
-{
- if (type == DUMP_TYPE_BIN) {
- return (uint16_to_bin(bin, hex));
- } else {
- *hex++ = bin2hex[(bin >> 12)& 0x0f];
- *hex++ = bin2hex[(bin >> 8) & 0x0f];
- *hex++ = bin2hex[(bin >> 4) & 0x0f];
- *hex = bin2hex[bin & 0x0f];
- return DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type);
- }
-}
+ size += sizeof(uint32_t) * 1;
+ size += sizeof(uint16_t) * 2;
-static inline int
-uint32_dump(uint32_t bin, char *hex, int type)
-{
- if (type == DUMP_TYPE_BIN) {
- return (uint32_to_bin(bin, hex));
- } else {
- *hex++ = bin2hex[(bin >> 28) & 0x0f];
- *hex++ = bin2hex[(bin >> 24) & 0x0f];
- *hex++ = bin2hex[(bin >> 20) & 0x0f];
- *hex++ = bin2hex[(bin >> 16) & 0x0f];
- *hex++ = bin2hex[(bin >> 12) & 0x0f];
- *hex++ = bin2hex[(bin >> 8) & 0x0f];
- *hex++ = bin2hex[(bin >> 4) & 0x0f];
- *hex = bin2hex[bin & 0x0f];
- return DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, type);
- }
+ return size;
}
-#define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */
-
-static char*
-str_dump(char *str, char *hex, uint16_t len, int type)
+static size_t
+write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
{
- if (type == DUMP_TYPE_BIN)
- memcpy(hex, str, len);
- else {
- char *src, *dst, buf[CHAR_ESC_LEN + 1];
- int n;
-
- for (src = str, dst = hex; len > 0; src++, dst++, len--) {
- switch (*src) {
- case 0x07:/* BEL */ *dst++ = '\\'; *dst = 'a'; break;
- case 0x08:/* BS */ *dst++ = '\\'; *dst = 'b'; break;
- case 0x09:/* HT */ *dst++ = '\\'; *dst = 't'; break;
- case 0x0A:/* LF */ *dst++ = '\\'; *dst = 'n'; break;
- case 0x0B:/* VT */ *dst++ = '\\'; *dst = 'v'; break;
- case 0x0C:/* FF */ *dst++ = '\\'; *dst = 'f'; break;
- case 0x0D:/* CR */ *dst++ = '\\'; *dst = 'r'; break;
- case 0x5C:/* \ */ *dst++ = '\\'; *dst = '\\'; break;
- case 0x22:/* " */ /* fall through */
- case 0x27:/* ' */ /* fall through */
- // case 0x3F:/* ? */ /* fall through */
- default:
- if (*src >= ' ' && *src <= '~') {
- *dst = *src;
- } else {
- n = sprintf(buf, "\\%03o", *src & 0377);
- memcpy(dst, buf, n);
- dst += (n-1);
- }
- break;
- }
- }
- }
-
- return hex;
-}
+ uint8_t *cur = buf;
-static uint16_t
-str_dump_len(char *str, uint16_t len, int type)
-{
- uint16_t dump_len = 0;
-
- if (type == DUMP_TYPE_BIN)
- dump_len = len;
- else {
- char *src;
-
- for (src = str; len > 0; src++, len--) {
- switch (*src) {
- case 0x07:/* BEL */ /* fall through */
- case 0x08:/* BS */ /* fall through */
- case 0x09:/* HT */ /* fall through */
- case 0x0A:/* LF */ /* fall through */
- case 0x0B:/* VT */ /* fall through */
- case 0x0C:/* FF */ /* fall through */
- case 0x0D:/* CR */ /* fall through */
- case 0x5C:/* \ */ /* fall through */
- dump_len += 2;
- break;
-
- case 0x22:/* " */ /* fall through */
- case 0x27:/* ' */ /* fall through */
- // case 0x3F:/* ? */ /* fall through */
- default:
- if (*src >= ' ' && *src <= '~') {
- dump_len++;
- } else {
- dump_len += 4; /* octet "\\nnn" */
- }
- break;
- }
- }
- }
+ cur += uint32_to_bin(get_irep_record_size(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 */
- return dump_len;
+ return (cur - buf);
}
+
static uint32_t
-get_irep_header_size(mrb_state *mrb, int type)
+get_iseq_block_size(mrb_state *mrb, mrb_irep *irep)
{
uint32_t size = 0;
-
- size += 2;
- size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type) * 4;
-
+ size += sizeof(uint32_t); /* ilen */
+ size += sizeof(uint32_t) * irep->ilen; /* iseq(n) */
return size;
}
-static uint32_t
-get_iseq_block_size(mrb_state *mrb, mrb_irep *irep, int type)
+static int
+write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
{
- uint32_t size = 0;
+ uint8_t *cur = buf;
+ size_t iseq_no;
- size += MRB_DUMP_SIZE_OF_LONG; /* ilen */
- size += irep->ilen * MRB_DUMP_SIZE_OF_LONG; /* iseq(n) */
- size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
+ cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */
+ for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
+ cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */
+ }
- return DUMP_SIZE(size, type);
+ return (cur - buf);
}
-static uint32_t
-get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type)
+
+static size_t
+get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
{
- uint32_t size = 0;
- int pool_no;
+ size_t size = 0;
+ size_t pool_no;
+ int len;
mrb_value str;
char buf[32];
- size += MRB_DUMP_SIZE_OF_LONG; /* plen */
- size += irep->plen; /* tt(n) */
- size += irep->plen * MRB_DUMP_SIZE_OF_SHORT; /* len(n) */
- size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
- size = DUMP_SIZE(size, type);
+ size += sizeof(uint32_t); /* plen */
+ size += irep->plen * (sizeof(uint8_t) + sizeof(uint16_t)); /* len(n) */
for (pool_no = 0; pool_no < irep->plen; pool_no++) {
- uint16_t nlen =0;
- int len;
-
switch (mrb_type(irep->pool[pool_no])) {
case MRB_TT_FIXNUM:
str = mrb_fix2str(mrb, irep->pool[pool_no], 10);
- size += (uint32_t)RSTRING_LEN(str);
+ size += RSTRING_LEN(str);
break;
+
case MRB_TT_FLOAT:
- len = mrb_float_to_str( buf, mrb_float(irep->pool[pool_no]));
- size += (uint32_t)len;
+ len = mrb_float_to_str(buf, mrb_float(irep->pool[pool_no]));
+ size += len;
break;
+
case MRB_TT_STRING:
- str = mrb_string_value( mrb, &irep->pool[pool_no]);
- nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
- size += nlen;
+ str = mrb_string_value(mrb, &irep->pool[pool_no]);
+ size += RSTRING_LEN(str);
break;
+
default:
break;
}
@@ -263,87 +100,15 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type)
return size;
}
-static uint32_t
-get_syms_block_size(mrb_state *mrb, mrb_irep *irep, int type)
-{
- uint32_t size = 0;
- int sym_no;
-
- size += MRB_DUMP_SIZE_OF_LONG; /* slen */
- size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
- size = DUMP_SIZE(size, type);
-
- for (sym_no = 0; sym_no < irep->slen; sym_no++) {
- const char * name;
- uint16_t nlen =0;
-
- size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type); /* snl(n) */
- if (irep->syms[sym_no] != 0) {
- size_t len;
-
- name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
- nlen = str_dump_len((char*)name, len, type);
- size += nlen; /* sn(n) */
- }
- }
-
- return size;
-}
-
-static uint32_t
-get_irep_record_size(mrb_state *mrb, int irep_no, int type)
-{
- uint32_t size = 0;
- mrb_irep *irep = mrb->irep[irep_no];
-
- size += DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, type); /* rlen */
- size += get_irep_header_size(mrb, type);
- size += get_iseq_block_size(mrb, irep, type);
- size += get_pool_block_size(mrb, irep, type);
- size += get_syms_block_size(mrb, irep, type);
-
- return size;
-}
-
-static int
-write_irep_header(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
-{
- char *buf_top = buf;
-
- *buf++ = RITE_IREP_IDENFIFIER; /* record identifier */
- *buf++ = RITE_IREP_TYPE_CLASS; /* class or module */
- buf += uint16_dump((uint16_t)irep->nlocals, buf, type); /* number of local variable */
- buf += uint16_dump((uint16_t)irep->nregs, buf, type); /* number of register variable */
- buf += uint16_dump(DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type)/* crc */, buf, type); /* offset of isec block */
-
- return (int)(buf - buf_top);
-}
-
static int
-write_iseq_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
+write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
{
- char *buf_top = buf;
- int iseq_no;
-
- buf += uint32_dump((uint32_t)irep->ilen, buf, type); /* number of opcode */
-
- for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
- buf += uint32_dump((uint32_t)irep->iseq[iseq_no], buf, type); /* opcode */
- }
-
- return (int)(buf - buf_top);
-}
-
-static int
-write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
-{
- int pool_no;
- mrb_value str;
- char *buf_top = buf;
- char *char_buf;
- uint16_t buf_size =0;
- uint16_t len =0;
int result;
+ size_t pool_no;
+ uint8_t *cur = buf;
+ size_t buf_size, len;
+ mrb_value str;
+ char *char_buf = NULL;
buf_size = MRB_DUMP_DEFAULT_STR_LEN;
char_buf = (char *)mrb_malloc(mrb, buf_size);
@@ -352,10 +117,10 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
goto error_exit;
}
- buf += uint32_dump((uint32_t)irep->plen, buf, type); /* number of pool */
+ cur += uint32_to_bin(irep->plen, cur); /* number of pool */
for (pool_no = 0; pool_no < irep->plen; pool_no++) {
- buf += uint8_dump(mrb_type(irep->pool[pool_no]), buf, type); /* data type */
+ cur += uint8_to_bin(mrb_type(irep->pool[pool_no]), cur); /* data type */
memset(char_buf, 0, buf_size);
switch (mrb_type(irep->pool[pool_no])) {
@@ -371,7 +136,7 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
case MRB_TT_STRING:
str = irep->pool[pool_no];
- len = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
+ len = RSTRING_LEN(str);
if (len > buf_size - 1) {
buf_size = len + 1;
char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size);
@@ -381,371 +146,303 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
}
memset(char_buf, 0, buf_size);
}
- str_dump(RSTRING_PTR(str), char_buf, RSTRING_LEN(str), type);
+ memcpy(char_buf, RSTRING_PTR(str), RSTRING_LEN(str));
break;
default:
- buf += uint16_dump(0, buf, type); /* data length = 0 */
+ len = 0;
continue;
}
- buf += uint16_dump(len, buf, type); /* data length */
-
- memcpy(buf, char_buf, len);
- buf += len;
+ cur += uint16_to_bin(len, cur); /* data length */
+ memcpy(cur, char_buf, len);
+ cur += len;
}
+ result = (int)(cur - buf);
- result = (int)(buf - buf_top);
error_exit:
mrb_free(mrb, char_buf);
return result;
}
+
+static size_t
+get_syms_block_size(mrb_state *mrb, mrb_irep *irep)
+{
+ size_t size = 0;
+ size_t sym_no;
+ size_t len;
+
+ size += sizeof(uint32_t); /* slen */
+ for (sym_no = 0; sym_no < irep->slen; sym_no++) {
+ size += sizeof(uint16_t); /* snl(n) */
+ if (irep->syms[sym_no] != 0) {
+ mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
+ size += len; /* sn(n) */
+ }
+ }
+
+ return size;
+}
+
static int
-write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
+write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
{
- int sym_no;
- char *buf_top = buf;
- char *char_buf;
- uint16_t buf_size =0;
+ int result;
+ size_t sym_no;
+ size_t buf_size;
+ uint8_t *cur = buf;
+ uint16_t nlen;
+ char *char_buf = NULL;
+ const char *name;
buf_size = MRB_DUMP_DEFAULT_STR_LEN;
char_buf = (char *)mrb_malloc(mrb, buf_size);
- if (char_buf == NULL)
+ if (char_buf == NULL) {
+ result = MRB_DUMP_GENERAL_FAILURE;
goto error_exit;
+ }
- buf += uint32_dump((uint32_t)irep->slen, buf, type); /* number of symbol */
+ cur += uint32_to_bin(irep->slen, cur); /* number of symbol */
for (sym_no = 0; sym_no < irep->slen; sym_no++) {
- const char * name;
- uint16_t nlen =0;
-
if (irep->syms[sym_no] != 0) {
size_t len;
name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
if (len > UINT16_MAX) goto error_exit;
- nlen = str_dump_len((char*)name, len, type);
- if ( nlen > buf_size - 1) {
+ nlen = (uint16_t)len;
+ if (nlen > buf_size - 1) {
buf_size = nlen + 1;
char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size);
- if (char_buf == NULL)
+ if (char_buf == NULL) {
+ result = MRB_DUMP_GENERAL_FAILURE;
goto error_exit;
+ }
}
memset(char_buf, 0, buf_size);
- str_dump((char*)name, char_buf, len, type);
+ memcpy(char_buf, name, len);
- buf += uint16_dump(nlen, buf, type); /* length of symbol name */
- memcpy(buf, char_buf, nlen); /* symbol name */
- buf += nlen;
+ cur += uint16_to_bin(nlen, cur); /* length of symbol name */
+ memcpy(cur, char_buf, nlen); /* symbol name */
+ cur += nlen;
}
else {
- buf += uint16_dump(MRB_DUMP_NULL_SYM_LEN, buf, type); /* length of symbol name */
+ cur += uint16_to_bin(MRB_DUMP_NULL_SYM_LEN, cur); /* length of symbol name */
}
}
+ result = (int)(cur - buf);
error_exit:
mrb_free(mrb, char_buf);
- return (int)(buf - buf_top);
+ return result;
}
-static int
-calc_crc_section(mrb_state *mrb, mrb_irep *irep, uint16_t *crc, int section)
+
+
+static size_t
+get_irep_record_size(mrb_state *mrb, mrb_irep *irep)
{
- char *buf, *buf_top;
- uint32_t buf_size;
- int type = DUMP_TYPE_BIN;
- int result;
+ uint32_t size = 0;
- switch (section) {
- case DUMP_IREP_HEADER: buf_size = get_irep_header_size(mrb, type); break;
- case DUMP_ISEQ_BLOCK: buf_size = get_iseq_block_size(mrb, irep, type); break;
- case DUMP_POOL_BLOCK: buf_size = get_pool_block_size(mrb, irep, type); break;
- case DUMP_SYMS_BLOCK: buf_size = get_syms_block_size(mrb, irep, type); break;
- default: return MRB_DUMP_GENERAL_FAILURE;
- }
+ //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);
- buf = (char *)mrb_calloc(mrb, 1, buf_size);
- if (buf == NULL)
- return MRB_DUMP_GENERAL_FAILURE;
+ return size;
+}
- buf_top = buf;
-
- switch (section) {
- case DUMP_IREP_HEADER:
- result = write_irep_header(mrb, irep, buf, type);
- break;
- case DUMP_ISEQ_BLOCK:
- result = write_iseq_block(mrb, irep, buf, type);
- break;
- case DUMP_POOL_BLOCK:
- result = write_pool_block(mrb, irep, buf, type);
- break;
- case DUMP_SYMS_BLOCK:
- result = write_syms_block(mrb, irep, buf, type);
- break;
- default:
- result = MRB_DUMP_GENERAL_FAILURE;
- break; /* Already checked above. */
+static int
+write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, uint32_t *irep_record_size)
+{
+ if (irep == NULL) {
+ return MRB_DUMP_INVALID_IREP;
}
- if (result < 0) {
- goto error_exit;
+
+ *irep_record_size = get_irep_record_size(mrb, irep);
+ if (*irep_record_size == 0) {
+ return MRB_DUMP_GENERAL_FAILURE;
}
- buf += result;
- *crc = calc_crc_16_ccitt((unsigned char*)buf_top, (int)(buf - buf_top));
+ memset(bin, 0, *irep_record_size);
- mrb_free(mrb, buf_top);
+ //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);
- result = MRB_DUMP_OK;
- error_exit:
- return result;
+ return MRB_DUMP_OK;
}
-static uint16_t
-calc_rite_header_crc(mrb_state *mrb, int top, rite_binary_header *binary_header, uint32_t rbds, int type)
+static size_t
+mrb_write_eof(mrb_state *mrb, uint8_t *bin)
{
- memcpy( binary_header, def_rite_binary_header, sizeof(*binary_header));
+ struct rite_binary_footer footer;
- uint32_dump(rbds, (char*)binary_header->rbds, type);
- uint16_dump((uint16_t)mrb->irep_len, (char*)binary_header->nirep, type);
- uint16_dump((uint16_t)top, (char*)binary_header->sirep, type);
+ memcpy(footer.section_identify, RITE_BINARY_EOF, sizeof(footer.section_identify));
+ uint32_to_bin(sizeof(struct rite_binary_footer), footer.section_size);
+ memcpy(bin, &footer, sizeof(struct rite_binary_footer));
- return calc_crc_16_ccitt((unsigned char*)binary_header, sizeof(*binary_header));
+ return sizeof(struct rite_binary_footer);
}
+
static int
-write_rite_header(mrb_state *mrb, int top, char* bin, uint32_t rbds)
-{
- rite_binary_header *binary_header;
- uint16_t crc;
- int type = DUMP_TYPE_BIN;
+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;
- binary_header = (rite_binary_header*)bin;
- crc = calc_rite_header_crc(mrb, top, binary_header, rbds, type);
- bin += sizeof(*binary_header);
- uint16_dump(crc, bin, type);
+ 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
-calc_rite_file_header(mrb_state *mrb, int top, uint32_t rbds, rite_file_header *file_header)
+mrb_write_section_irep(mrb_state *mrb, size_t start_index, uint8_t *bin)
{
- rite_binary_header *binary_header, b_header;
- uint16_t crc;
- int type;
+ 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) {
+ return MRB_DUMP_INVALID_ARGUMENT;
+ }
- /* calc crc */
- type = DUMP_TYPE_BIN;
- binary_header = &b_header;
- crc = calc_rite_header_crc(mrb, top, binary_header, rbds, type);
+ cur += sizeof(struct rite_section_irep_header);
+ section_size += sizeof(struct rite_section_irep_header);
- /* dump rbc header */
- memcpy( file_header, def_rite_file_header, sizeof(*file_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;
+ }
- type = DUMP_TYPE_HEX;
- uint32_dump(rbds, (char*)file_header->rbds, type);
- uint16_dump((uint16_t)mrb->irep_len, (char*)file_header->nirep, type);
- uint16_dump((uint16_t)top, (char*)file_header->sirep, type);
- uint16_dump(crc, (char*)file_header->hcrc, type);
+ mrb_write_section_irep_header(mrb, section_size, mrb->irep_len - start_index, start_index, bin);
return MRB_DUMP_OK;
}
static int
-dump_rite_header(mrb_state *mrb, int top, FILE* fp, uint32_t rbds)
-{
- int rc = MRB_DUMP_OK;
- rite_file_header file_header;
-
- if (fseek(fp, 0, SEEK_SET) != 0)
- return MRB_DUMP_GENERAL_FAILURE;
-
- rc = calc_rite_file_header(mrb, top, rbds, &file_header);
- if (rc != MRB_DUMP_OK)
- return rc;
-
- if (fwrite(&file_header, sizeof(file_header), 1, fp) != 1)
- return MRB_DUMP_WRITE_FAULT;
+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;
+
+ memcpy(header->binary_identify, RITE_BINARY_IDENFIFIER, sizeof(header->binary_identify));
+ memcpy(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version));
+ 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);
return MRB_DUMP_OK;
}
static int
-write_irep_record(mrb_state *mrb, int irep_no, char* bin, uint32_t *rlen, int type)
+mrb_dump_irep(mrb_state *mrb, size_t start_index, uint8_t **bin, size_t *bin_size)
{
- uint32_t irep_record_size;
- mrb_irep *irep = mrb->irep[irep_no];
- int section;
-
- if (irep == NULL)
- return MRB_DUMP_INVALID_IREP;
+ int result = MRB_DUMP_GENERAL_FAILURE;
+ size_t section_irep_size;
+ size_t irep_no;
+ uint8_t *cur = NULL;
- /* buf alloc */
- irep_record_size = get_irep_record_size(mrb, irep_no, type);
- if (irep_record_size == 0)
+ if (mrb == NULL || start_index >= mrb->irep_len) {
+ *bin = NULL;
return MRB_DUMP_GENERAL_FAILURE;
-
- memset( bin, 0, irep_record_size);
-
- /* rlen */
- *rlen = irep_record_size - DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, type);
-
- bin += uint32_dump(*rlen, bin, type);
-
- for (section = 0; section < DUMP_SECTION_NUM; section++) {
- int rc;
- uint16_t crc;
-
- switch (section) {
- case DUMP_IREP_HEADER: bin += write_irep_header(mrb, irep, bin, type); break;
- case DUMP_ISEQ_BLOCK: bin += write_iseq_block(mrb, irep, bin, type); break;
- case DUMP_POOL_BLOCK: bin += write_pool_block(mrb, irep, bin, type); break;
- case DUMP_SYMS_BLOCK: bin += write_syms_block(mrb, irep, bin, type); break;
- default: break;
- }
-
- rc = calc_crc_section(mrb, irep, &crc, section);
- if (rc != MRB_DUMP_OK)
- return rc;
-
- bin += uint16_dump(crc, bin, type); /* crc */
}
- return MRB_DUMP_OK;
-}
-
-static int
-dump_irep_record(mrb_state *mrb, int irep_no, FILE* fp, uint32_t *rlen)
-{
- int rc = MRB_DUMP_OK;
- uint32_t irep_record_size;
- char *buf;
- mrb_irep *irep = mrb->irep[irep_no];
-
- if (irep == NULL)
- return MRB_DUMP_INVALID_IREP;
+ 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]);
+ }
- /* buf alloc */
- irep_record_size = get_irep_record_size(mrb, irep_no, DUMP_TYPE_HEX);
- if (irep_record_size == 0)
- return MRB_DUMP_GENERAL_FAILURE;
+ *bin_size += sizeof(struct rite_binary_header) + section_irep_size + sizeof(struct rite_binary_footer);
+ cur = *bin = (uint8_t *)mrb_malloc(mrb, *bin_size);
+ if(cur == NULL) {
+ goto error_exit;
+ }
- buf = (char *)mrb_calloc(mrb, 1, irep_record_size);
- if (buf == NULL)
- return MRB_DUMP_GENERAL_FAILURE;
+ cur += sizeof(struct rite_binary_header);
- rc = write_irep_record(mrb, irep_no, buf, rlen, DUMP_TYPE_HEX);
- if (rc != MRB_DUMP_OK) {
- rc = MRB_DUMP_GENERAL_FAILURE;
+ result = mrb_write_section_irep(mrb, start_index, cur);
+ if (result != MRB_DUMP_OK) {
goto error_exit;
}
+ cur += section_irep_size;
+ mrb_write_eof(mrb, cur);
- if (fwrite(buf, irep_record_size, 1, fp) != 1)
- rc = MRB_DUMP_WRITE_FAULT;
+ result = write_rite_binary_header(mrb, *bin_size, *bin);
error_exit:
- mrb_free(mrb, buf);
-
- return rc;
-}
-
-static int
-mrb_write_irep(mrb_state *mrb, int top, char *bin)
-{
- int rc;
- uint32_t rlen=0; /* size of irep record */
- int irep_no;
- char *bin_top;
-
- if (mrb == NULL || top < 0 || top >= mrb->irep_len || bin == NULL)
- return MRB_DUMP_INVALID_ARGUMENT;
-
- bin_top = bin;
- bin += sizeof(rite_binary_header) + MRB_DUMP_SIZE_OF_SHORT/* crc */;
-
- for (irep_no=top; irep_no<mrb->irep_len; irep_no++) {
- rc = write_irep_record(mrb, irep_no, bin, &rlen, DUMP_TYPE_BIN);
- if (rc != MRB_DUMP_OK)
- return rc;
-
- bin += (rlen + DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, DUMP_TYPE_BIN));
+ if (result != MRB_DUMP_OK) {
+ mrb_free(mrb, *bin);
+ *bin = NULL;
}
+ return result;
+}
- bin += uint32_dump(0, bin, DUMP_TYPE_BIN); /* end of file */
-
- rc = write_rite_header(mrb, top, bin_top, (bin - bin_top)); //TODO: Remove top(SIREP)
- return rc;
-}
+#ifdef ENABLE_STDIO
int
-mrb_dump_irep(mrb_state *mrb, int top, FILE* fp)
+mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, FILE* fp)
{
- int rc;
- uint32_t rbds=0; /* size of Rite Binary Data */
- uint32_t rlen=0; /* size of irep record */
- int irep_no;
+ uint8_t *bin = NULL;
+ size_t bin_size = 0;
+ int result;
- if (mrb == NULL || top < 0 || top >= mrb->irep_len || fp == NULL)
+ if (fp == NULL) {
return MRB_DUMP_INVALID_ARGUMENT;
-
- if (fwrite(&def_rite_file_header, sizeof(rite_file_header), 1, fp) != 1) /* dummy write */
- return MRB_DUMP_WRITE_FAULT;
-
- for (irep_no=top; irep_no<mrb->irep_len; irep_no++) {
- rc = dump_irep_record(mrb, irep_no, fp, &rlen);
- if (rc != MRB_DUMP_OK)
- return rc;
-
- rbds += rlen;
}
- if (fwrite("00000000"/* end of file */, 8, 1, fp) != 1)
- return MRB_DUMP_WRITE_FAULT;
-
- rc = dump_rite_header(mrb, top, fp, rbds); //TODO: Remove top(SIREP)
+ result = mrb_dump_irep(mrb, start_index, &bin, &bin_size);
+ if (result == MRB_DUMP_OK) {
+ fwrite(bin, bin_size, 1, fp);
+ }
- return rc;
+ mrb_free(mrb, bin);
+ return result;
}
int
-mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname)
+mrb_dump_irep_cfunc(mrb_state *mrb, size_t start_index, FILE *fp, const char *initname)
{
- int rc;
- int irep_no;
- char *buf;
- int buf_size = 0;
- int buf_idx = 0;
+ uint8_t *bin = NULL;
+ size_t bin_size = 0, bin_idx = 0;
+ int result;
- if (mrb == NULL || n < 0 || n >= mrb->irep_len || f == NULL || initname == NULL)
+ if (fp == NULL || initname == NULL) {
return MRB_DUMP_INVALID_ARGUMENT;
+ }
- buf_size = sizeof(rite_binary_header) + MRB_DUMP_SIZE_OF_SHORT/* crc */;
- for (irep_no=n; irep_no<mrb->irep_len; irep_no++)
- buf_size += get_irep_record_size(mrb, irep_no, DUMP_TYPE_BIN);
- buf_size += MRB_DUMP_SIZE_OF_LONG; /* end of file */
-
- buf = (char *)mrb_malloc(mrb, buf_size);
- if (buf == NULL)
- return MRB_DUMP_GENERAL_FAILURE;
-
- rc = mrb_write_irep(mrb, n, buf);
-
- if (rc == MRB_DUMP_OK) {
- fprintf(f, "const char %s[] = {", initname);
- while (buf_idx < buf_size ) {
- if (buf_idx % 16 == 0 ) fputs("\n", f);
- fprintf(f, "0x%02x,", (unsigned char)buf[buf_idx++]);
+ result = mrb_dump_irep(mrb, start_index, &bin, &bin_size);
+ if (result == MRB_DUMP_OK) {
+ fprintf(fp, "const uint8_t %s[] = {", initname);
+ while (bin_idx < bin_size) {
+ if (bin_idx % 16 == 0 ) fputs("\n", fp);
+ fprintf(fp, "0x%02x,", bin[bin_idx++]);
}
- fputs("\n};\n", f);
+ fputs("\n};\n", fp);
}
- mrb_free(mrb, buf);
-
- return rc;
+ mrb_free(mrb, bin);
+ return result;
}
#endif /* ENABLE_STDIO */