summaryrefslogtreecommitdiffhomepage
path: root/src/dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dump.c')
-rw-r--r--src/dump.c697
1 files changed, 697 insertions, 0 deletions
diff --git a/src/dump.c b/src/dump.c
new file mode 100644
index 000000000..ba2a9ab7a
--- /dev/null
+++ b/src/dump.c
@@ -0,0 +1,697 @@
+#include <string.h>
+#include "dump.h"
+
+#include "mruby/string.h"
+#ifdef INCLUDE_REGEXP
+#include "re.h"
+#endif
+#include "irep.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,
+};
+
+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*,mrb_irep*,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(unsigned char bin, char *hex, int type)
+{
+ if (type == DUMP_TYPE_BIN) {
+ *hex = bin;
+ } else {
+ *hex++ = bin2hex[(bin >> 4) & 0x0f];
+ *hex = bin2hex[bin & 0x0f];
+ }
+ return DUMP_SIZE(sizeof(char), type);
+}
+
+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);
+ }
+}
+
+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);
+ }
+}
+
+static char*
+str_dump(char *str, char *hex, uint16_t len, int type)
+{
+ if (type == DUMP_TYPE_BIN)
+ memcpy(hex, str, len);
+ else {
+ char *src, *dst;
+
+ 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 0x22:/* " */ /* fall through */
+ case 0x27:/* ' */ /* fall through */
+ // case 0x3F:/* ? */ /* fall through */
+ case 0x5C:/* \ */ /* fall through */
+ default: *dst = *src; break;
+ }
+ }
+ }
+
+ return hex;
+}
+
+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 */
+ dump_len += 2;
+ break;
+
+ case 0x22:/* " */ /* fall through */
+ case 0x27:/* ' */ /* fall through */
+ // case 0x3F:/* ? */ /* fall through */
+ case 0x5C:/* \ */ /* fall through */
+ default:
+ dump_len++; break;
+ }
+ }
+ }
+
+ return dump_len;
+}
+
+static uint32_t
+get_irep_header_size(mrb_state *mrb, mrb_irep *irep, int type)
+{
+ uint32_t size = 0;
+
+ size += sizeof(char) * 2;
+ size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type) * 4;
+
+ return size;
+}
+
+static uint32_t
+get_iseq_block_size(mrb_state *mrb, mrb_irep *irep, int type)
+{
+ uint32_t size = 0;
+
+ size += MRB_DUMP_SIZE_OF_LONG; /* ilen */
+ size += irep->ilen * MRB_DUMP_SIZE_OF_LONG; /* iseq(n) */
+ size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
+
+ return DUMP_SIZE(size, type);
+}
+
+static uint32_t
+get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type)
+{
+ uint32_t size = 0;
+ int pool_no;
+ mrb_value str;
+ char buf[32];
+
+ size += MRB_DUMP_SIZE_OF_LONG; /* plen */
+ size += irep->plen * sizeof(char); /* tt(n) */
+ size += irep->plen * MRB_DUMP_SIZE_OF_SHORT; /* len(n) */
+ size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
+ size = DUMP_SIZE(size, type);
+
+ for (pool_no = 0; pool_no < irep->plen; pool_no++) {
+ uint16_t nlen =0;
+
+ switch (irep->pool[pool_no].tt) {
+ case MRB_TT_FIXNUM:
+ sprintf( buf, "%d", irep->pool[pool_no].value.i);
+ size += strlen(buf);
+ break;
+ case MRB_TT_FLOAT:
+ sprintf( buf, "%.16e", irep->pool[pool_no].value.f);
+ size += strlen(buf);
+ 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;
+ break;
+#ifdef INCLUDE_REGEXP
+ case MRB_TT_REGEX:
+ str = mrb_reg_to_s(mrb, irep->pool[pool_no]);
+ nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
+ size += nlen;
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+
+ 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) {
+ name = mrb_sym2name(mrb, irep->syms[sym_no]);
+ nlen = str_dump_len((char*)name, strlen(name), 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, irep, 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)
+{
+ 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;
+
+ buf_size = MRB_DUMP_DEFAULT_STR_LEN;
+ if ((char_buf = mrb_malloc(mrb, buf_size)) == 0)
+ goto error_exit;
+
+ buf += uint32_dump((uint32_t)irep->plen, buf, type); /* number of pool */
+
+ for (pool_no = 0; pool_no < irep->plen; pool_no++) {
+ uint16_t nlen =0;
+
+ buf += uint8_dump(irep->pool[pool_no].tt, buf, type); /* data type */
+ memset(char_buf, 0, buf_size);
+
+ switch (irep->pool[pool_no].tt) {
+ case MRB_TT_FIXNUM:
+ sprintf(char_buf, "%d", irep->pool[pool_no].value.i);
+ break;
+
+ case MRB_TT_FLOAT:
+ sprintf(char_buf, "%.16e", irep->pool[pool_no].value.f);
+ 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);
+ if ( nlen > buf_size - 1) {
+ buf_size = nlen + 1;
+ if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
+ goto error_exit;
+ memset(char_buf, 0, buf_size);
+ }
+ str_dump(RSTRING_PTR(str), char_buf, RSTRING_LEN(str), type);
+ break;
+
+#ifdef INCLUDE_REGEXP
+ case MRB_TT_REGEX:
+ str = mrb_reg_to_s(mrb, irep->pool[pool_no]);
+ nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
+ if ( nlen > buf_size - 1) {
+ buf_size = nlen + 1;
+ if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
+ goto error_exit;
+ memset(char_buf, 0, buf_size);
+ }
+ str_dump(RSTRING_PTR(str), char_buf, RSTRING_LEN(str), type);
+ break;
+#endif
+
+ default:
+ buf += uint16_dump(0, buf, type); /* data length = 0 */
+ continue;
+ }
+
+ buf += uint16_dump((uint16_t)strlen(char_buf), buf, type); /* data length */
+
+ memcpy(buf, char_buf, strlen(char_buf));
+ buf += strlen(char_buf);
+ }
+
+error_exit:
+ if (char_buf)
+ mrb_free(mrb, char_buf);
+ return (int)(buf - buf_top);
+}
+
+static int
+write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
+{
+ int sym_no;
+ char *buf_top = buf;
+ char *char_buf;
+ uint16_t buf_size =0;
+
+ buf_size = MRB_DUMP_DEFAULT_STR_LEN;
+ if ((char_buf = mrb_malloc(mrb, buf_size)) == 0)
+ goto error_exit;
+
+ buf += uint32_dump((uint32_t)irep->slen, buf, type); /* 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) {
+ name = mrb_sym2name(mrb, irep->syms[sym_no]);
+ nlen = str_dump_len((char*)name, strlen(name), type);
+ if ( nlen > buf_size - 1) {
+ buf_size = nlen + 1;
+ if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
+ goto error_exit;
+ }
+ memset(char_buf, 0, buf_size);
+ str_dump((char*)name, char_buf, strlen(name), type);
+
+ buf += uint16_dump(nlen, buf, type); /* length of symbol name */
+ memcpy(buf, char_buf, nlen); /* symbol name */
+ buf += nlen;
+ }
+ else {
+ buf += uint16_dump(MRB_DUMP_NULL_SYM_LEN, buf, type); /* length of symbol name */
+ }
+ }
+
+error_exit:
+ if (char_buf)
+ mrb_free(mrb, char_buf);
+ return (int)(buf - buf_top);
+}
+
+static int
+calc_crc_section(mrb_state *mrb, mrb_irep *irep, uint16_t *crc, int section)
+{
+ char *buf, *buf_top;
+ uint32_t buf_size;
+ int type = DUMP_TYPE_BIN;
+
+ switch (section) {
+ case DUMP_IREP_HEADER: buf_size = get_irep_header_size(mrb, irep, 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;
+ }
+
+ if ((buf = mrb_malloc(mrb, buf_size)) == 0)
+ return MRB_DUMP_GENERAL_FAILURE;
+
+ buf_top = buf;
+ memset(buf, 0, buf_size);
+
+ switch (section) {
+ case DUMP_IREP_HEADER: buf += write_irep_header(mrb, irep, buf, type); break;
+ case DUMP_ISEQ_BLOCK: buf += write_iseq_block(mrb, irep, buf, type); break;
+ case DUMP_POOL_BLOCK: buf += write_pool_block(mrb, irep, buf, type); break;
+ case DUMP_SYMS_BLOCK: buf += write_syms_block(mrb, irep, buf, type); break;
+ default: break;
+ }
+
+ *crc = calc_crc_16_ccitt((unsigned char *)buf_top, (int)(buf - buf_top));
+
+ mrb_free(mrb, buf_top);
+
+ return MRB_DUMP_OK;
+}
+
+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;
+
+ binary_header = (rite_binary_header *)bin;
+
+ memcpy( binary_header, def_rite_binary_header, sizeof(*binary_header));
+
+ 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);
+
+ crc = calc_crc_16_ccitt((unsigned char *)binary_header, sizeof(*binary_header));
+ bin += sizeof(*binary_header);
+ uint16_dump(crc, bin, type);
+
+ return MRB_DUMP_OK;
+}
+
+static int
+dump_rite_header(mrb_state *mrb, int top, FILE* fp, uint32_t rbds)
+{
+ rite_binary_header binary_header;
+ rite_file_header file_header;
+ uint16_t crc;
+ int type;
+
+ if (fseek(fp, 0, SEEK_SET) != 0)
+ return MRB_DUMP_GENERAL_FAILURE;
+
+ /* calc crc */
+ memcpy( &binary_header, def_rite_binary_header, sizeof(binary_header));
+
+ type = DUMP_TYPE_BIN;
+ 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);
+
+ crc = calc_crc_16_ccitt((unsigned char *)&binary_header, sizeof(binary_header));
+
+ /* dump rbc header */
+ memcpy( &file_header, def_rite_file_header, sizeof(file_header));
+
+ 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);
+
+ if (fwrite(&file_header, sizeof(file_header), 1, fp) != 1)
+ return MRB_DUMP_WRITE_FAULT;
+
+ return MRB_DUMP_OK;
+}
+
+static int
+write_irep_record(mrb_state *mrb, int irep_no, char* bin, uint32_t *rlen, int type)
+{
+ uint32_t irep_record_size;
+ mrb_irep *irep = mrb->irep[irep_no];
+ int section;
+
+ if (irep == 0)
+ return MRB_DUMP_INVALID_IREP;
+
+ /* buf alloc */
+ irep_record_size = get_irep_record_size(mrb, irep_no, type);
+ if (irep_record_size == 0)
+ 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;
+ }
+
+ if ((rc = calc_crc_section(mrb, irep, &crc, section)) != 0)
+ 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 == 0)
+ return MRB_DUMP_INVALID_IREP;
+
+ /* 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;
+
+ if ((buf = mrb_malloc(mrb, irep_record_size)) == 0)
+ return MRB_DUMP_GENERAL_FAILURE;
+
+ memset( buf, 0, irep_record_size);
+
+ if ((rc = write_irep_record(mrb, irep_no, buf, rlen, DUMP_TYPE_HEX)) != MRB_DUMP_OK)
+ goto error_exit;
+
+
+ if (fwrite(buf, irep_record_size, 1, fp) != 1)
+ rc = MRB_DUMP_WRITE_FAULT;
+
+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 == 0 || top < 0 || top >= mrb->irep_len || bin == 0)
+ 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++) {
+ if ((rc = write_irep_record(mrb, irep_no, bin, &rlen, DUMP_TYPE_BIN)) != 0)
+ return rc;
+
+ bin += (rlen + DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, DUMP_TYPE_BIN));
+ }
+
+ 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;
+}
+
+int
+mrb_dump_irep(mrb_state *mrb, int top, FILE* fp)
+{
+ int rc;
+ uint32_t rbds=0; /* size of Rite Binary Data */
+ uint32_t rlen=0; /* size of irep record */
+ int irep_no;
+
+ if (mrb == 0 || top < 0 || top >= mrb->irep_len || fp == 0)
+ 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++) {
+ if ((rc = dump_irep_record(mrb, irep_no, fp, &rlen)) != 0)
+ 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)
+
+ return rc;
+}
+
+int
+mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname)
+{
+ int rc;
+ int irep_no;
+ char *buf;
+ int buf_size = 0;
+ int buf_idx = 0;
+
+ if (mrb == 0 || n < 0 || n >= mrb->irep_len || f == 0 || initname == 0)
+ return -1;
+
+ 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 */
+
+ if ((buf = mrb_malloc(mrb, buf_size)) == 0)
+ 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++]);
+ }
+ fputs("\n};\n", f);
+ }
+
+ mrb_free(mrb, buf);
+
+ return rc;
+}