mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge branch 'masuidrive-new_mrb_format'
This commit is contained in:
+77
-79
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** mruby/dump.h - mruby binary dumper (Rite binary format)
|
||||
** mruby/dump.h - mruby binary dumper (mrbc binary format)
|
||||
**
|
||||
** See Copyright Notice in mruby.h
|
||||
*/
|
||||
@@ -14,116 +14,104 @@ extern "C" {
|
||||
#include "mruby.h"
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
int mrb_dump_irep(mrb_state*,int,FILE*);
|
||||
int mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname);
|
||||
|
||||
int mrb_read_irep_file(mrb_state*,FILE*);
|
||||
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);
|
||||
int32_t mrb_read_irep_file(mrb_state*, FILE*);
|
||||
#endif
|
||||
int mrb_read_irep(mrb_state*,const char*);
|
||||
int mrb_read_irep(mrb_state*, const uint8_t*);
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
mrb_value mrb_load_irep_file(mrb_state*,FILE*);
|
||||
#endif
|
||||
|
||||
/* dump type */
|
||||
#define DUMP_TYPE_CODE 0
|
||||
#define DUMP_TYPE_BIN 1
|
||||
#define DUMP_TYPE_HEX 2
|
||||
|
||||
/* dump/load error code
|
||||
*
|
||||
* NOTE: MRB_DUMP_GENERAL_FAILURE is caused by
|
||||
* unspecified issues like malloc failed.
|
||||
*/
|
||||
#define MRB_DUMP_OK 0
|
||||
#define MRB_DUMP_GENERAL_FAILURE -1
|
||||
#define MRB_DUMP_WRITE_FAULT -2
|
||||
#define MRB_DUMP_READ_FAULT -3
|
||||
#define MRB_DUMP_CRC_ERROR -4
|
||||
#define MRB_DUMP_INVALID_FILE_HEADER -5
|
||||
#define MRB_DUMP_INVALID_IREP -6
|
||||
#define MRB_DUMP_INVALID_ARGUMENT -7
|
||||
|
||||
/* size of long/int/short value on dump/load */
|
||||
#define MRB_DUMP_SIZE_OF_LONG 4
|
||||
#define MRB_DUMP_SIZE_OF_INT 4
|
||||
#define MRB_DUMP_SIZE_OF_SHORT 2
|
||||
#define MRB_DUMP_SIZE_OF_CHAR 1
|
||||
#define MRB_DUMP_OK 0
|
||||
#define MRB_DUMP_GENERAL_FAILURE -1
|
||||
#define MRB_DUMP_WRITE_FAULT -2
|
||||
#define MRB_DUMP_READ_FAULT -3
|
||||
#define MRB_DUMP_CRC_ERROR -4
|
||||
#define MRB_DUMP_INVALID_FILE_HEADER -5
|
||||
#define MRB_DUMP_INVALID_IREP -6
|
||||
#define MRB_DUMP_INVALID_ARGUMENT -7
|
||||
|
||||
/* null symbol length */
|
||||
#define MRB_DUMP_NULL_SYM_LEN 0xFFFF
|
||||
|
||||
/* Use HEX format string */
|
||||
#define RITE_FILE_IS_HEX
|
||||
|
||||
#ifdef RITE_FILE_IS_HEX
|
||||
#define RITE_FILE_HEX_SIZE 2
|
||||
#else
|
||||
#define RITE_FILE_HEX_SIZE 1
|
||||
#endif
|
||||
#define MRB_DUMP_NULL_SYM_LEN 0xFFFF
|
||||
|
||||
/* Rite Binary File header */
|
||||
#define RITE_FILE_IDENFIFIER "RITE"
|
||||
#define RITE_FILE_FORMAT_VER "00090000"
|
||||
#define RITE_VM_VER "00090000"
|
||||
#define RITE_COMPILER_TYPE "MATZ "
|
||||
#define RITE_COMPILER_VER "00090000"
|
||||
#define RITE_RESERVED " "
|
||||
#define RITE_BINARY_IDENFIFIER "RITE"
|
||||
#define RITE_BINARY_FORMAT_VER "0001"
|
||||
#define RITE_COMPILER_NAME "MATZ"
|
||||
#define RITE_COMPILER_VERSION "0000"
|
||||
|
||||
/* irep header */
|
||||
#define RITE_IREP_IDENFIFIER 'S'
|
||||
#define RITE_IREP_TYPE_CLASS 'C'
|
||||
#define RITE_IREP_TYPE_MODULE 'M'
|
||||
#define RITE_VM_VER "0000"
|
||||
|
||||
#define MRB_DUMP_DEFAULT_STR_LEN 128
|
||||
#define RITE_BINARY_EOF "END\0"
|
||||
#define RITE_SECTION_IREP_IDENTIFIER "IREP"
|
||||
|
||||
//Rite Binary file_header
|
||||
typedef struct {
|
||||
unsigned char rbfi[4]; //Rite Binary File Identify
|
||||
unsigned char rbfv[8]; //Rite Binary File Format Version
|
||||
unsigned char risv[8]; //Rite Instruction Specification Version
|
||||
unsigned char rct[8]; //Rite Compiler Type
|
||||
unsigned char rcv[8]; //Rite Compiler Version
|
||||
unsigned char rbds[4]; //Rite Binary Data Size
|
||||
unsigned char nirep[2]; //Number of ireps
|
||||
unsigned char sirep[2]; //Start index
|
||||
unsigned char rsv[8]; //Reserved
|
||||
} rite_binary_header;
|
||||
#define MRB_DUMP_DEFAULT_STR_LEN 128
|
||||
|
||||
// Rite File file_header
|
||||
typedef struct {
|
||||
unsigned char rbfi[4]; //Rite Binary File Identify
|
||||
unsigned char rbfv[8]; //Rite Binary File Format Version
|
||||
unsigned char risv[8]; //Rite Instruction Specification Version
|
||||
unsigned char rct[8]; //Rite Compiler Type
|
||||
unsigned char rcv[8]; //Rite Compiler Version
|
||||
unsigned char rbds[8]; //Rite Binary Data Size
|
||||
unsigned char nirep[4]; //Number of ireps
|
||||
unsigned char sirep[4]; //Start index
|
||||
unsigned char rsv[8]; //Reserved
|
||||
unsigned char hcrc[4]; //HCRC
|
||||
} rite_file_header;
|
||||
// binary header
|
||||
struct rite_binary_header {
|
||||
uint8_t binary_identify[4]; // Binary Identifier
|
||||
uint8_t binary_version[4]; // Binary Format Version
|
||||
uint8_t binary_crc[2]; // Binary CRC
|
||||
uint8_t binary_size[4]; // Binary Size
|
||||
uint8_t compiler_name[4]; // Compiler name
|
||||
uint8_t compiler_version[4];
|
||||
};
|
||||
|
||||
// section header
|
||||
#define RITE_SECTION_HEADER \
|
||||
uint8_t section_identify[4]; \
|
||||
uint8_t section_size[4];
|
||||
|
||||
struct rite_section_header {
|
||||
RITE_SECTION_HEADER;
|
||||
};
|
||||
|
||||
struct rite_section_irep_header {
|
||||
RITE_SECTION_HEADER;
|
||||
|
||||
uint8_t rite_version[4]; // Rite Instruction Specification Version
|
||||
uint8_t nirep[2]; // Number of ireps
|
||||
uint8_t sirep[2]; // Start index
|
||||
};
|
||||
|
||||
struct rite_binary_footer {
|
||||
RITE_SECTION_HEADER;
|
||||
};
|
||||
|
||||
static inline int
|
||||
uint16_to_bin(uint16_t s, char *bin)
|
||||
uint8_to_bin(uint8_t s, uint8_t *bin)
|
||||
{
|
||||
*bin++ = (s >> 8) & 0xff;
|
||||
*bin = s & 0xff;
|
||||
return (MRB_DUMP_SIZE_OF_SHORT);
|
||||
*bin = s;
|
||||
return sizeof(uint8_t);
|
||||
}
|
||||
|
||||
static inline int
|
||||
uint32_to_bin(uint32_t l, char *bin)
|
||||
uint16_to_bin(uint16_t s, uint8_t *bin)
|
||||
{
|
||||
*bin++ = (s >> 8) & 0xff;
|
||||
*bin = s & 0xff;
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
static inline int
|
||||
uint32_to_bin(uint32_t l, uint8_t *bin)
|
||||
{
|
||||
*bin++ = (l >> 24) & 0xff;
|
||||
*bin++ = (l >> 16) & 0xff;
|
||||
*bin++ = (l >> 8) & 0xff;
|
||||
*bin = l & 0xff;
|
||||
return (MRB_DUMP_SIZE_OF_LONG);
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
bin_to_uint32(unsigned char bin[])
|
||||
bin_to_uint32(const uint8_t *bin)
|
||||
{
|
||||
return (uint32_t)bin[0] << 24 |
|
||||
(uint32_t)bin[1] << 16 |
|
||||
@@ -132,12 +120,22 @@ bin_to_uint32(unsigned char bin[])
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
bin_to_uint16(unsigned char bin[])
|
||||
bin_to_uint16(const uint8_t *bin)
|
||||
{
|
||||
return (uint16_t)bin[0] << 8 |
|
||||
(uint16_t)bin[1];
|
||||
}
|
||||
|
||||
static inline uint8_t
|
||||
bin_to_uint8(const uint8_t *bin)
|
||||
{
|
||||
return (uint8_t)bin[0];
|
||||
}
|
||||
|
||||
/* crc.c */
|
||||
uint32_t
|
||||
calc_crc_16_ccitt(const uint8_t *src, uint32_t nbytes, uint16_t crcwk);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
|
||||
@@ -25,13 +25,13 @@ typedef struct mrb_irep {
|
||||
const char *filename;
|
||||
short *lines;
|
||||
|
||||
int ilen, plen, slen;
|
||||
size_t ilen, plen, slen;
|
||||
} mrb_irep;
|
||||
|
||||
#define MRB_ISEQ_NO_FREE 1
|
||||
|
||||
mrb_irep *mrb_add_irep(mrb_state *mrb);
|
||||
mrb_value mrb_load_irep(mrb_state*,const char*);
|
||||
mrb_value mrb_load_irep(mrb_state*, const uint8_t*);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "mruby/string.h"
|
||||
#include "mruby/proc.h"
|
||||
|
||||
extern const char mrblib_irep[];
|
||||
extern const uint8_t mrblib_irep[];
|
||||
|
||||
void
|
||||
mrb_init_mrblib(mrb_state *mrb)
|
||||
|
||||
+1
-1
@@ -2498,7 +2498,7 @@ codedump(mrb_state *mrb, int n)
|
||||
|
||||
if (!irep) return;
|
||||
printf("irep %d nregs=%d nlocals=%d pools=%d syms=%d\n", n,
|
||||
irep->nregs, irep->nlocals, irep->plen, irep->slen);
|
||||
irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen);
|
||||
for (i=0; i<irep->ilen; i++) {
|
||||
ai = mrb_gc_arena_save(mrb);
|
||||
printf("%03d ", i);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// Calculate CRC (CRC-16-CCITT)
|
||||
//
|
||||
// 0000_0000_0000_0000_0000_0000_0000_0000
|
||||
@@ -16,10 +18,11 @@
|
||||
#define CRC_CARRY_BIT (0x01000000)
|
||||
|
||||
uint16_t
|
||||
calc_crc_16_ccitt(unsigned char *src, int nbytes)
|
||||
calc_crc_16_ccitt(const uint8_t *src, size_t nbytes, uint16_t crc)
|
||||
{
|
||||
uint32_t crcwk = 0ul;
|
||||
int ibyte, ibit;
|
||||
size_t ibyte;
|
||||
uint32_t ibit;
|
||||
uint32_t crcwk = crc << 8;
|
||||
|
||||
for (ibyte = 0; ibyte < nbytes; ibyte++) {
|
||||
crcwk |= *src++;
|
||||
@@ -32,3 +35,4 @@ calc_crc_16_ccitt(unsigned char *src, int nbytes)
|
||||
}
|
||||
return (uint16_t)(crcwk >> 8);
|
||||
}
|
||||
|
||||
|
||||
+270
-573
@@ -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,
|
||||
};
|
||||
|
||||
#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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dump_len;
|
||||
}
|
||||
static size_t
|
||||
get_irep_record_size(mrb_state *mrb, mrb_irep *irep);
|
||||
|
||||
static uint32_t
|
||||
get_irep_header_size(mrb_state *mrb, int type)
|
||||
get_irep_header_size(mrb_state *mrb)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
|
||||
size += 2;
|
||||
size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type) * 4;
|
||||
size += sizeof(uint32_t) * 1;
|
||||
size += sizeof(uint16_t) * 2;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_iseq_block_size(mrb_state *mrb, mrb_irep *irep, int type)
|
||||
static size_t
|
||||
write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
uint8_t *cur = buf;
|
||||
|
||||
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(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_SIZE(size, type);
|
||||
return (cur - buf);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type)
|
||||
get_iseq_block_size(mrb_state *mrb, mrb_irep *irep)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
int pool_no;
|
||||
size += sizeof(uint32_t); /* ilen */
|
||||
size += sizeof(uint32_t) * irep->ilen; /* iseq(n) */
|
||||
return size;
|
||||
}
|
||||
|
||||
static int
|
||||
write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
|
||||
{
|
||||
uint8_t *cur = buf;
|
||||
size_t iseq_no;
|
||||
|
||||
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 (cur - buf);
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
|
||||
{
|
||||
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)
|
||||
write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
|
||||
{
|
||||
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;
|
||||
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 int
|
||||
write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
|
||||
|
||||
static size_t
|
||||
get_syms_block_size(mrb_state *mrb, mrb_irep *irep)
|
||||
{
|
||||
int sym_no;
|
||||
char *buf_top = buf;
|
||||
char *char_buf;
|
||||
uint16_t buf_size =0;
|
||||
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, uint8_t *buf)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
int result;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
buf = (char *)mrb_calloc(mrb, 1, buf_size);
|
||||
if (buf == NULL)
|
||||
return MRB_DUMP_GENERAL_FAILURE;
|
||||
|
||||
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. */
|
||||
}
|
||||
if (result < 0) {
|
||||
goto error_exit;
|
||||
}
|
||||
buf += result;
|
||||
|
||||
*crc = calc_crc_16_ccitt((unsigned char*)buf_top, (int)(buf - buf_top));
|
||||
|
||||
mrb_free(mrb, buf_top);
|
||||
|
||||
result = MRB_DUMP_OK;
|
||||
error_exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
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
|
||||
get_irep_record_size(mrb_state *mrb, mrb_irep *irep)
|
||||
{
|
||||
memcpy( binary_header, def_rite_binary_header, sizeof(*binary_header));
|
||||
uint32_t size = 0;
|
||||
|
||||
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);
|
||||
//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);
|
||||
|
||||
return calc_crc_16_ccitt((unsigned char*)binary_header, sizeof(*binary_header));
|
||||
return size;
|
||||
}
|
||||
|
||||
static int
|
||||
write_rite_header(mrb_state *mrb, int top, char* bin, uint32_t rbds)
|
||||
write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, uint32_t *irep_record_size)
|
||||
{
|
||||
rite_binary_header *binary_header;
|
||||
uint16_t crc;
|
||||
int type = DUMP_TYPE_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);
|
||||
|
||||
return MRB_DUMP_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
calc_rite_file_header(mrb_state *mrb, int top, uint32_t rbds, rite_file_header *file_header)
|
||||
{
|
||||
rite_binary_header *binary_header, b_header;
|
||||
uint16_t crc;
|
||||
int type;
|
||||
|
||||
/* calc crc */
|
||||
type = DUMP_TYPE_BIN;
|
||||
binary_header = &b_header;
|
||||
crc = calc_rite_header_crc(mrb, top, binary_header, rbds, type);
|
||||
|
||||
/* 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);
|
||||
|
||||
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;
|
||||
|
||||
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 == NULL)
|
||||
if (irep == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
rc = calc_crc_section(mrb, irep, &crc, section);
|
||||
if (rc != MRB_DUMP_OK)
|
||||
return rc;
|
||||
|
||||
bin += uint16_dump(crc, bin, type); /* crc */
|
||||
}
|
||||
|
||||
*irep_record_size = get_irep_record_size(mrb, irep);
|
||||
if (*irep_record_size == 0) {
|
||||
return MRB_DUMP_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
memset(bin, 0, *irep_record_size);
|
||||
|
||||
//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);
|
||||
|
||||
return MRB_DUMP_OK;
|
||||
}
|
||||
|
||||
static size_t
|
||||
mrb_write_eof(mrb_state *mrb, uint8_t *bin)
|
||||
{
|
||||
struct rite_binary_footer footer;
|
||||
|
||||
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 sizeof(struct rite_binary_footer);
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
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
|
||||
dump_irep_record(mrb_state *mrb, int irep_no, FILE* fp, uint32_t *rlen)
|
||||
mrb_write_section_irep(mrb_state *mrb, size_t start_index, uint8_t *bin)
|
||||
{
|
||||
int rc = MRB_DUMP_OK;
|
||||
uint32_t irep_record_size;
|
||||
char *buf;
|
||||
mrb_irep *irep = mrb->irep[irep_no];
|
||||
int result;
|
||||
size_t irep_no;
|
||||
uint32_t section_size = 0, rlen = 0; /* size of irep record */
|
||||
uint8_t *cur = bin;
|
||||
|
||||
if (irep == NULL)
|
||||
return MRB_DUMP_INVALID_IREP;
|
||||
if (mrb == NULL || start_index >= mrb->irep_len || bin == NULL) {
|
||||
return MRB_DUMP_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
/* buf alloc */
|
||||
irep_record_size = get_irep_record_size(mrb, irep_no, DUMP_TYPE_HEX);
|
||||
if (irep_record_size == 0)
|
||||
cur += sizeof(struct rite_section_irep_header);
|
||||
section_size += sizeof(struct rite_section_irep_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;
|
||||
}
|
||||
|
||||
mrb_write_section_irep_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;
|
||||
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
|
||||
mrb_dump_irep(mrb_state *mrb, size_t start_index, uint8_t **bin, size_t *bin_size)
|
||||
{
|
||||
int result = MRB_DUMP_GENERAL_FAILURE;
|
||||
size_t section_irep_size;
|
||||
size_t irep_no;
|
||||
uint8_t *cur = NULL;
|
||||
|
||||
if (mrb == NULL || start_index >= mrb->irep_len) {
|
||||
*bin = NULL;
|
||||
return MRB_DUMP_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
buf = (char *)mrb_calloc(mrb, 1, irep_record_size);
|
||||
if (buf == NULL)
|
||||
return MRB_DUMP_GENERAL_FAILURE;
|
||||
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]);
|
||||
}
|
||||
|
||||
rc = write_irep_record(mrb, irep_no, buf, rlen, DUMP_TYPE_HEX);
|
||||
if (rc != MRB_DUMP_OK) {
|
||||
rc = 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;
|
||||
}
|
||||
|
||||
cur += sizeof(struct rite_binary_header);
|
||||
|
||||
if (fwrite(buf, irep_record_size, 1, fp) != 1)
|
||||
rc = MRB_DUMP_WRITE_FAULT;
|
||||
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);
|
||||
|
||||
result = write_rite_binary_header(mrb, *bin_size, *bin);
|
||||
|
||||
error_exit:
|
||||
mrb_free(mrb, buf);
|
||||
|
||||
return rc;
|
||||
if (result != MRB_DUMP_OK) {
|
||||
mrb_free(mrb, *bin);
|
||||
*bin = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
mrb_write_irep(mrb_state *mrb, int top, char *bin)
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
|
||||
int
|
||||
mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, FILE* fp)
|
||||
{
|
||||
int rc;
|
||||
uint32_t rlen=0; /* size of irep record */
|
||||
int irep_no;
|
||||
char *bin_top;
|
||||
uint8_t *bin = NULL;
|
||||
size_t bin_size = 0;
|
||||
int result;
|
||||
|
||||
if (mrb == NULL || top < 0 || top >= mrb->irep_len || bin == NULL)
|
||||
if (fp == 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));
|
||||
}
|
||||
|
||||
bin += uint32_dump(0, bin, DUMP_TYPE_BIN); /* end of file */
|
||||
result = mrb_dump_irep(mrb, start_index, &bin, &bin_size);
|
||||
if (result == MRB_DUMP_OK) {
|
||||
fwrite(bin, bin_size, 1, fp);
|
||||
}
|
||||
|
||||
rc = write_rite_header(mrb, top, bin_top, (bin - bin_top)); //TODO: Remove top(SIREP)
|
||||
|
||||
return rc;
|
||||
mrb_free(mrb, bin);
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
mrb_dump_irep(mrb_state *mrb, int top, FILE* fp)
|
||||
mrb_dump_irep_cfunc(mrb_state *mrb, size_t start_index, FILE *fp, const char *initname)
|
||||
{
|
||||
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, bin_idx = 0;
|
||||
int result;
|
||||
|
||||
if (mrb == NULL || top < 0 || top >= mrb->irep_len || fp == NULL)
|
||||
if (fp == NULL || initname == 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)
|
||||
|
||||
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 == NULL || n < 0 || n >= mrb->irep_len || f == 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 */
|
||||
|
||||
+290
-550
@@ -22,395 +22,69 @@ typedef struct _RiteFILE
|
||||
} RiteFILE;
|
||||
#endif
|
||||
|
||||
const char hex2bin[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //00-0f
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10-1f
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20-2f
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, //30-3f
|
||||
0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40-4f
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //50-5f
|
||||
0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0 //60-6f
|
||||
//70-ff
|
||||
};
|
||||
|
||||
static uint16_t hex_to_bin8(unsigned char*,unsigned char*);
|
||||
static uint16_t hex_to_bin16(unsigned char*,unsigned char*);
|
||||
static uint16_t hex_to_bin32(unsigned char*,unsigned char*);
|
||||
static uint8_t hex_to_uint8(unsigned char*);
|
||||
static uint16_t hex_to_uint16(unsigned char*);
|
||||
static uint32_t hex_to_uint32(unsigned char*);
|
||||
static char* hex_to_str(char*,char*,uint16_t*);
|
||||
uint16_t calc_crc_16_ccitt(unsigned char*,int);
|
||||
#ifdef ENABLE_STDIO
|
||||
static unsigned char rite_fgetcSub(RiteFILE*);
|
||||
static unsigned char rite_fgetc(RiteFILE*,int);
|
||||
static unsigned char* rite_fgets(RiteFILE*,unsigned char*,int,int);
|
||||
static int load_rite_header(FILE*,rite_binary_header*,unsigned char*);
|
||||
static int load_rite_irep_record(mrb_state*, RiteFILE*,unsigned char*,uint32_t*);
|
||||
#ifndef _WIN32
|
||||
# if SIZE_MAX < UINT32_MAX
|
||||
# error "It can't be run this code on this environment (SIZE_MAX < UINT32_MAX)"
|
||||
# endif
|
||||
#endif
|
||||
static int read_rite_header(mrb_state*,unsigned char*,rite_binary_header*);
|
||||
static int read_rite_irep_record(mrb_state*,unsigned char*,uint32_t*);
|
||||
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
static unsigned char
|
||||
rite_fgetcSub(RiteFILE* rfp)
|
||||
static size_t
|
||||
offset_crc_body()
|
||||
{
|
||||
//only first call
|
||||
if (rfp->buf[0] == '\0') {
|
||||
rfp->readlen = fread(rfp->buf, 1, sizeof(rfp->buf), rfp->fp);
|
||||
rfp->cnt = 0;
|
||||
}
|
||||
|
||||
if (rfp->readlen == rfp->cnt) {
|
||||
rfp->readlen = fread(rfp->buf, 1, sizeof(rfp->buf), rfp->fp);
|
||||
rfp->cnt = 0;
|
||||
if (rfp->readlen == 0) {
|
||||
return '\0';
|
||||
}
|
||||
}
|
||||
return rfp->buf[(rfp->cnt)++];
|
||||
struct rite_binary_header header;
|
||||
return ((char *)header.binary_crc - (char *)&header) + sizeof(header.binary_crc);
|
||||
}
|
||||
#endif /* ENABLE_STDIO */
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
static unsigned char
|
||||
rite_fgetc(RiteFILE* rfp, int ignorecomment)
|
||||
{
|
||||
unsigned char tmp;
|
||||
|
||||
for (;;) {
|
||||
tmp = rite_fgetcSub(rfp);
|
||||
if (tmp == '\n' || tmp == '\r') {
|
||||
continue;
|
||||
}
|
||||
else if (ignorecomment && tmp == '#') {
|
||||
while (tmp != '\n' && tmp != '\r' && tmp != '\0')
|
||||
tmp = rite_fgetcSub(rfp);
|
||||
if (tmp == '\0')
|
||||
return '\0';
|
||||
}
|
||||
else {
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_STDIO */
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
static unsigned char*
|
||||
rite_fgets(RiteFILE* rfp, unsigned char* dst, int len, int ignorecomment)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
if ('\0' == (dst[i] = rite_fgetc(rfp, ignorecomment))) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
#endif /* ENABLE_STDIO */
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
static int
|
||||
load_rite_header(FILE* fp, rite_binary_header* bin_header, unsigned char* hcrc)
|
||||
read_rite_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len)
|
||||
{
|
||||
rite_file_header file_header;
|
||||
|
||||
if (fread(&file_header, 1, sizeof(file_header), fp) < sizeof(file_header)) {
|
||||
return MRB_DUMP_READ_FAULT;
|
||||
}
|
||||
memcpy(bin_header->rbfi, file_header.rbfi, sizeof(file_header.rbfi));
|
||||
if (memcmp(bin_header->rbfi, RITE_FILE_IDENFIFIER, sizeof(bin_header->rbfi)) != 0) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER; //File identifier error
|
||||
}
|
||||
memcpy(bin_header->rbfv, file_header.rbfv, sizeof(file_header.rbfv));
|
||||
if (memcmp(bin_header->rbfv, RITE_FILE_FORMAT_VER, sizeof(bin_header->rbfv)) != 0) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER; //File format version error
|
||||
}
|
||||
memcpy(bin_header->risv, file_header.risv, sizeof(file_header.risv));
|
||||
memcpy(bin_header->rct, file_header.rct, sizeof(file_header.rct));
|
||||
memcpy(bin_header->rcv, file_header.rcv, sizeof(file_header.rcv));
|
||||
hex_to_bin32(bin_header->rbds, file_header.rbds);
|
||||
hex_to_bin16(bin_header->nirep, file_header.nirep);
|
||||
hex_to_bin16(bin_header->sirep, file_header.sirep);
|
||||
memcpy(bin_header->rsv, file_header.rsv, sizeof(file_header.rsv));
|
||||
memcpy(hcrc, file_header.hcrc, sizeof(file_header.hcrc));
|
||||
|
||||
return MRB_DUMP_OK;
|
||||
}
|
||||
#endif /* ENABLE_STDIO */
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
static int
|
||||
load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_t* len)
|
||||
{
|
||||
int i;
|
||||
uint32_t blocklen;
|
||||
uint16_t offset, pdl, snl, clen;
|
||||
unsigned char hex2[2] = {0}, hex4[4] = {0}, hex8[8] = {0}, hcrc[4] = {0};
|
||||
unsigned char *pStart;
|
||||
int ret;
|
||||
size_t i;
|
||||
char *char_buf;
|
||||
uint16_t buf_size =0;
|
||||
int result;
|
||||
|
||||
buf_size = MRB_DUMP_DEFAULT_STR_LEN;
|
||||
char_buf = (char *)mrb_malloc(mrb, buf_size);
|
||||
if (char_buf == NULL) {
|
||||
result = MRB_DUMP_GENERAL_FAILURE;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
pStart = dst;
|
||||
|
||||
//IREP HEADER BLOCK
|
||||
*dst = rite_fgetc(rfp, TRUE); //record identifier
|
||||
if (*dst != RITE_IREP_IDENFIFIER) {
|
||||
result = MRB_DUMP_INVALID_IREP;
|
||||
goto error_exit;
|
||||
}
|
||||
dst += sizeof(unsigned char);
|
||||
*dst = rite_fgetc(rfp, TRUE); //class or module
|
||||
dst += sizeof(unsigned char);
|
||||
rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //number of local variable
|
||||
dst += hex_to_bin16(dst, hex4);
|
||||
rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //number of register variable
|
||||
dst += hex_to_bin16(dst, hex4);
|
||||
rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //offset of isec block
|
||||
offset = hex_to_uint16(hex4);
|
||||
rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //header CRC
|
||||
memset( char_buf, '\0', buf_size);
|
||||
rite_fgets(rfp, (unsigned char*)char_buf, (offset - (MRB_DUMP_SIZE_OF_SHORT * RITE_FILE_HEX_SIZE)), TRUE); //class or module name
|
||||
hex_to_str(char_buf, (char*)(dst + MRB_DUMP_SIZE_OF_SHORT + MRB_DUMP_SIZE_OF_SHORT), &clen); //class or module name
|
||||
dst += uint16_to_bin((MRB_DUMP_SIZE_OF_SHORT/*crc*/ + clen), (char*)dst); //offset of isec block
|
||||
dst += hex_to_bin16(dst, hcrc); //header CRC
|
||||
dst += clen;
|
||||
|
||||
//ISEQ BLOCK
|
||||
rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //iseq length
|
||||
dst += hex_to_bin32(dst, hex8);
|
||||
blocklen = hex_to_uint32(hex8);
|
||||
for (i=0; i<blocklen; i++) {
|
||||
rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //iseq
|
||||
dst += hex_to_bin32(dst, hex8);
|
||||
}
|
||||
rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //iseq CRC
|
||||
dst += hex_to_bin16(dst, hcrc);
|
||||
|
||||
//POOL BLOCK
|
||||
rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //pool length
|
||||
dst += hex_to_bin32(dst, hex8);
|
||||
blocklen = hex_to_uint32(hex8);
|
||||
for (i=0; i<blocklen; i++) {
|
||||
rite_fgets(rfp, hex2, sizeof(hex2), TRUE); //TT
|
||||
dst += hex_to_bin8(dst, hex2);
|
||||
rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //pool data length
|
||||
pdl = hex_to_uint16(hex4);
|
||||
|
||||
if ( pdl > buf_size - 1) {
|
||||
buf_size = pdl + 1;
|
||||
char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size);
|
||||
if (char_buf == NULL) {
|
||||
result = MRB_DUMP_GENERAL_FAILURE;
|
||||
goto error_exit;
|
||||
}
|
||||
}
|
||||
memset(char_buf, '\0', buf_size);
|
||||
rite_fgets(rfp, (unsigned char*)char_buf, pdl, FALSE); //pool
|
||||
hex_to_str(char_buf, (char*)(dst + MRB_DUMP_SIZE_OF_SHORT), &clen);
|
||||
dst += uint16_to_bin(clen, (char*)dst);
|
||||
dst += clen;
|
||||
}
|
||||
rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //pool CRC
|
||||
dst += hex_to_bin16(dst, hcrc);
|
||||
|
||||
//SYMS BLOCK
|
||||
rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //syms length
|
||||
dst += hex_to_bin32(dst, hex8);
|
||||
blocklen = hex_to_uint32(hex8);
|
||||
for (i=0; i<blocklen; i++) {
|
||||
rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //symbol name length
|
||||
snl = hex_to_uint16(hex4);
|
||||
|
||||
if (snl == MRB_DUMP_NULL_SYM_LEN) {
|
||||
dst += uint16_to_bin(snl, (char*)dst);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( snl > buf_size - 1) {
|
||||
buf_size = snl + 1;
|
||||
char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size);
|
||||
if (char_buf == NULL) {
|
||||
result = MRB_DUMP_GENERAL_FAILURE;
|
||||
goto error_exit;
|
||||
}
|
||||
}
|
||||
memset(char_buf, '\0', buf_size);
|
||||
rite_fgets(rfp, (unsigned char*)char_buf, snl, FALSE); //symbol name
|
||||
hex_to_str(char_buf, (char*)(dst + MRB_DUMP_SIZE_OF_SHORT), &clen);
|
||||
dst += uint16_to_bin(clen, (char*)dst);
|
||||
dst += clen;
|
||||
}
|
||||
rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //syms CRC
|
||||
dst += hex_to_bin16(dst, hcrc);
|
||||
|
||||
*len = dst - pStart;
|
||||
|
||||
result = MRB_DUMP_OK;
|
||||
error_exit:
|
||||
mrb_free(mrb, char_buf);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif /* ENABLE_STDIO */
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
int
|
||||
mrb_read_irep_file(mrb_state *mrb, FILE* fp)
|
||||
{
|
||||
int ret, i;
|
||||
uint32_t len, rlen = 0;
|
||||
unsigned char hex8[8], hcrc[4];
|
||||
unsigned char *dst, *rite_dst = NULL;
|
||||
rite_binary_header bin_header;
|
||||
RiteFILE ritefp = { 0 };
|
||||
RiteFILE *rfp;
|
||||
|
||||
if ((mrb == NULL) || (fp == NULL)) {
|
||||
return MRB_DUMP_INVALID_ARGUMENT;
|
||||
}
|
||||
ritefp.fp = fp;
|
||||
rfp = &ritefp;
|
||||
|
||||
//Read File Header Section
|
||||
ret = load_rite_header(fp, &bin_header, hcrc);
|
||||
if (ret != MRB_DUMP_OK)
|
||||
return ret;
|
||||
|
||||
len = sizeof(rite_binary_header) + bin_to_uint32(bin_header.rbds);
|
||||
rite_dst = (unsigned char *)mrb_malloc(mrb, len);
|
||||
if (rite_dst == NULL)
|
||||
return MRB_DUMP_GENERAL_FAILURE;
|
||||
|
||||
dst = rite_dst;
|
||||
memset(dst, 0x00, len);
|
||||
*(rite_binary_header *)dst = bin_header;
|
||||
dst += sizeof(rite_binary_header);
|
||||
dst += hex_to_bin16(dst, hcrc);
|
||||
|
||||
//Read Binary Data Section
|
||||
len = bin_to_uint16(bin_header.nirep);
|
||||
for (i=0; i<len; i++) {
|
||||
rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //record len
|
||||
dst += hex_to_bin32(dst, hex8);
|
||||
ret = load_rite_irep_record(mrb, rfp, dst, &rlen);
|
||||
if (ret != MRB_DUMP_OK) //irep info
|
||||
goto error_exit;
|
||||
dst += rlen;
|
||||
}
|
||||
rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //dummy record len
|
||||
hex_to_bin32(dst, hex8); /* dst += hex_to_bin32(dst, hex8); */
|
||||
if (0 != hex_to_uint32(hex8)) {
|
||||
ret = MRB_DUMP_INVALID_IREP;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
if (ret == MRB_DUMP_OK)
|
||||
ret = mrb_read_irep(mrb, (char*)rite_dst);
|
||||
|
||||
error_exit:
|
||||
mrb_free(mrb, rite_dst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* ENABLE_STDIO */
|
||||
|
||||
static int
|
||||
read_rite_header(mrb_state *mrb, unsigned char *bin, rite_binary_header* bin_header)
|
||||
{
|
||||
uint16_t crc;
|
||||
|
||||
*bin_header = *(rite_binary_header *)bin;
|
||||
bin += sizeof(rite_binary_header);
|
||||
if (memcmp(bin_header->rbfi, RITE_FILE_IDENFIFIER, sizeof(bin_header->rbfi)) != 0) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER; //File identifier error
|
||||
}
|
||||
if (memcmp(bin_header->risv, RITE_VM_VER, sizeof(bin_header->risv)) != 0) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER; //Instruction set version check
|
||||
}
|
||||
|
||||
crc = calc_crc_16_ccitt((unsigned char*)bin_header, sizeof(*bin_header)); //Calculate CRC
|
||||
if (crc != bin_to_uint16(bin)) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER; //CRC error
|
||||
}
|
||||
|
||||
return bin_to_uint16(bin_header->nirep);
|
||||
}
|
||||
|
||||
static int
|
||||
read_rite_irep_record(mrb_state *mrb, unsigned char *src, uint32_t* len)
|
||||
{
|
||||
int i, ret = MRB_DUMP_OK;
|
||||
char *buf;
|
||||
unsigned char *recordStart, *pStart;
|
||||
uint16_t crc, tt, pdl, snl, offset, bufsize=MRB_DUMP_DEFAULT_STR_LEN;
|
||||
const uint8_t *src = bin;
|
||||
uint16_t tt, pool_data_len, snl, buf_size = MRB_DUMP_DEFAULT_STR_LEN;
|
||||
mrb_int fix_num;
|
||||
mrb_float f;
|
||||
int plen;
|
||||
size_t plen;
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
mrb_irep *irep = mrb_add_irep(mrb);
|
||||
|
||||
recordStart = src;
|
||||
buf = (char *)mrb_malloc(mrb, bufsize);
|
||||
if (buf == NULL) {
|
||||
char_buf = (char *)mrb_malloc(mrb, buf_size);
|
||||
if (char_buf == NULL) {
|
||||
ret = MRB_DUMP_GENERAL_FAILURE;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
//Header Section
|
||||
pStart = src;
|
||||
if (*src != RITE_IREP_IDENFIFIER)
|
||||
return MRB_DUMP_INVALID_IREP;
|
||||
src += (sizeof(unsigned char) * 2);
|
||||
irep->nlocals = bin_to_uint16(src); //number of local variable
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
irep->nregs = bin_to_uint16(src); //number of register variable
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
offset = bin_to_uint16(src); //offset of isec block
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
crc = calc_crc_16_ccitt(pStart, src - pStart); //Calculate CRC
|
||||
if (crc != bin_to_uint16(src)) //header CRC
|
||||
return MRB_DUMP_INVALID_IREP;
|
||||
src += offset;
|
||||
// skip record size
|
||||
src += sizeof(uint32_t);
|
||||
|
||||
//Binary Data Section
|
||||
//ISEQ BLOCK
|
||||
pStart = src;
|
||||
irep->ilen = bin_to_uint32(src); //iseq length
|
||||
src += MRB_DUMP_SIZE_OF_LONG;
|
||||
// number of local variable
|
||||
irep->nlocals = bin_to_uint16(src);
|
||||
src += sizeof(uint16_t);
|
||||
|
||||
// number of register variable
|
||||
irep->nregs = bin_to_uint16(src);
|
||||
src += sizeof(uint16_t);
|
||||
|
||||
// Binary Data Section
|
||||
// ISEQ BLOCK
|
||||
irep->ilen = bin_to_uint32(src);
|
||||
src += sizeof(uint32_t);
|
||||
if (irep->ilen > 0) {
|
||||
irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen);
|
||||
if (irep->iseq == NULL) {
|
||||
ret = MRB_DUMP_GENERAL_FAILURE;
|
||||
goto error_exit;
|
||||
}
|
||||
for (i=0; i<irep->ilen; i++) {
|
||||
for (i = 0; i < irep->ilen; i++) {
|
||||
irep->iseq[i] = bin_to_uint32(src); //iseq
|
||||
src += MRB_DUMP_SIZE_OF_LONG;
|
||||
src += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
crc = calc_crc_16_ccitt((unsigned char*)pStart, src - pStart); //Calculate CRC
|
||||
if (crc != bin_to_uint16(src)) { //iseq CRC
|
||||
ret = MRB_DUMP_INVALID_IREP;
|
||||
goto error_exit;
|
||||
}
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
|
||||
//POOL BLOCK
|
||||
pStart = src;
|
||||
plen = bin_to_uint32(src); //pool length
|
||||
src += MRB_DUMP_SIZE_OF_LONG;
|
||||
plen = bin_to_uint32(src); /* number of pool */
|
||||
src += sizeof(uint32_t);
|
||||
if (plen > 0) {
|
||||
irep->pool = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value) * plen);
|
||||
if (irep->pool == NULL) {
|
||||
@@ -418,37 +92,35 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, uint32_t* len)
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
for (i=0; i<plen; i++) {
|
||||
tt = *src; //pool TT
|
||||
src += sizeof(unsigned char);
|
||||
pdl = bin_to_uint16(src); //pool data length
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
if (pdl > bufsize - 1) {
|
||||
mrb_free(mrb, buf);
|
||||
bufsize = pdl + 1;
|
||||
buf = (char *)mrb_malloc(mrb, bufsize);
|
||||
if (buf == NULL) {
|
||||
for (i = 0; i < plen; i++) {
|
||||
tt = *src++; //pool TT
|
||||
pool_data_len = bin_to_uint16(src); //pool data length
|
||||
src += sizeof(uint16_t);
|
||||
if (pool_data_len > buf_size - 1) {
|
||||
mrb_free(mrb, char_buf);
|
||||
buf_size = pool_data_len + 1;
|
||||
char_buf = (char *)mrb_malloc(mrb, buf_size);
|
||||
if (char_buf == NULL) {
|
||||
ret = MRB_DUMP_GENERAL_FAILURE;
|
||||
goto error_exit;
|
||||
}
|
||||
}
|
||||
memcpy(buf, src, pdl);
|
||||
src += pdl;
|
||||
buf[pdl] = '\0';
|
||||
|
||||
switch (tt) { //pool data
|
||||
memcpy(char_buf, src, pool_data_len);
|
||||
src += pool_data_len;
|
||||
char_buf[pool_data_len] = '\0';
|
||||
switch (tt) { //pool data
|
||||
case MRB_TT_FIXNUM:
|
||||
fix_num = str_to_mrb_int(buf);
|
||||
fix_num = str_to_mrb_int(char_buf);
|
||||
irep->pool[i] = mrb_fixnum_value(fix_num);
|
||||
break;
|
||||
|
||||
case MRB_TT_FLOAT:
|
||||
f = str_to_mrb_float(buf);
|
||||
f = str_to_mrb_float(char_buf);
|
||||
irep->pool[i] = mrb_float_value(f);
|
||||
break;
|
||||
|
||||
case MRB_TT_STRING:
|
||||
irep->pool[i] = mrb_str_new(mrb, buf, pdl);
|
||||
irep->pool[i] = mrb_str_new(mrb, char_buf, pool_data_len);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -459,17 +131,10 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, uint32_t* len)
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
}
|
||||
}
|
||||
crc = calc_crc_16_ccitt((unsigned char*)pStart, src - pStart); //Calculate CRC
|
||||
if (crc != bin_to_uint16(src)) { //pool CRC
|
||||
ret = MRB_DUMP_INVALID_IREP;
|
||||
goto error_exit;
|
||||
}
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
|
||||
//SYMS BLOCK
|
||||
pStart = src;
|
||||
irep->slen = bin_to_uint32(src); //syms length
|
||||
src += MRB_DUMP_SIZE_OF_LONG;
|
||||
irep->slen = bin_to_uint32(src); //syms length
|
||||
src += sizeof(uint32_t);
|
||||
if (irep->slen > 0) {
|
||||
irep->syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen);
|
||||
if (irep->syms == NULL) {
|
||||
@@ -481,80 +146,67 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, uint32_t* len)
|
||||
static const mrb_sym mrb_sym_zero = { 0 };
|
||||
*irep->syms = mrb_sym_zero;
|
||||
}
|
||||
for (i=0; i<irep->slen; i++) {
|
||||
for (i = 0; i < irep->slen; i++) {
|
||||
snl = bin_to_uint16(src); //symbol name length
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
src += sizeof(uint16_t);
|
||||
|
||||
if (snl == MRB_DUMP_NULL_SYM_LEN) {
|
||||
irep->syms[i] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (snl > bufsize - 1) {
|
||||
mrb_free(mrb, buf);
|
||||
bufsize = snl + 1;
|
||||
buf = (char *)mrb_malloc(mrb, bufsize);
|
||||
if (buf == NULL) {
|
||||
if (snl > buf_size - 1) {
|
||||
mrb_free(mrb, char_buf);
|
||||
buf_size = snl + 1;
|
||||
char_buf = (char *)mrb_malloc(mrb, buf_size);
|
||||
if (char_buf == NULL) {
|
||||
ret = MRB_DUMP_GENERAL_FAILURE;
|
||||
goto error_exit;
|
||||
}
|
||||
}
|
||||
memcpy(buf, src, snl); //symbol name
|
||||
memcpy(char_buf, src, snl); //symbol name
|
||||
src += snl;
|
||||
buf[snl] = '\0';
|
||||
irep->syms[i] = mrb_intern2(mrb, buf, snl);
|
||||
char_buf[snl] = '\0';
|
||||
irep->syms[i] = mrb_intern2(mrb, char_buf, snl);
|
||||
}
|
||||
}
|
||||
crc = calc_crc_16_ccitt((unsigned char*)pStart, src - pStart); //Calculate CRC
|
||||
if (crc != bin_to_uint16(src)) { //syms CRC
|
||||
ret = MRB_DUMP_INVALID_IREP;
|
||||
goto error_exit;
|
||||
}
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
*len = src - bin;
|
||||
|
||||
*len = src - recordStart;
|
||||
ret = MRB_DUMP_OK;
|
||||
error_exit:
|
||||
mrb_free(mrb, buf);
|
||||
|
||||
mrb_free(mrb, char_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
mrb_read_irep(mrb_state *mrb, const char *bin)
|
||||
static int
|
||||
read_rite_section_irep(mrb_state *mrb, const uint8_t *bin)
|
||||
{
|
||||
int ret = MRB_DUMP_OK, i, n, nirep, sirep;
|
||||
uint32_t len = 0;
|
||||
unsigned char *src;
|
||||
rite_binary_header bin_header;
|
||||
int result;
|
||||
size_t sirep;
|
||||
size_t i;
|
||||
uint32_t len;
|
||||
uint16_t nirep;
|
||||
uint16_t n;
|
||||
const struct rite_section_irep_header *header;
|
||||
|
||||
header = (const struct rite_section_irep_header*)bin;
|
||||
bin += sizeof(struct rite_section_irep_header);
|
||||
|
||||
if ((mrb == NULL) || (bin == NULL)) {
|
||||
return MRB_DUMP_INVALID_ARGUMENT;
|
||||
}
|
||||
src = (unsigned char*)bin;
|
||||
sirep = mrb->irep_len;
|
||||
|
||||
//Read File Header Section
|
||||
nirep = read_rite_header(mrb, src, &bin_header);
|
||||
if (nirep < 0)
|
||||
return nirep;
|
||||
|
||||
src += sizeof(bin_header) + MRB_DUMP_SIZE_OF_SHORT; //header + crc
|
||||
nirep = bin_to_uint16(header->nirep);
|
||||
|
||||
//Read Binary Data Section
|
||||
for (n=0,i=sirep; n<nirep; n++,i++) {
|
||||
src += MRB_DUMP_SIZE_OF_LONG; //record ren
|
||||
ret = read_rite_irep_record(mrb, src, &len);
|
||||
if (ret != MRB_DUMP_OK)
|
||||
for (n = 0, i = sirep; n < nirep; n++, i++) {
|
||||
result = read_rite_irep_record(mrb, bin, &len);
|
||||
if (result != MRB_DUMP_OK)
|
||||
goto error_exit;
|
||||
src += len;
|
||||
}
|
||||
if (0 != bin_to_uint32(src)) { //dummy record len
|
||||
ret = MRB_DUMP_GENERAL_FAILURE;
|
||||
bin += len;
|
||||
}
|
||||
|
||||
result = MRB_DUMP_OK;
|
||||
error_exit:
|
||||
if (ret != MRB_DUMP_OK) {
|
||||
for (n=0,i=sirep; i<mrb->irep_len; n++,i++) {
|
||||
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);
|
||||
@@ -568,116 +220,71 @@ error_exit:
|
||||
mrb_free(mrb, mrb->irep[i]);
|
||||
}
|
||||
}
|
||||
// mrb->irep_len = sirep;
|
||||
return ret;
|
||||
return result;
|
||||
}
|
||||
return sirep + hex_to_uint8(bin_header.sirep);
|
||||
return sirep + bin_to_uint16(header->sirep);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
hex_to_bin8(unsigned char *dst, unsigned char *src)
|
||||
static int
|
||||
read_rite_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc)
|
||||
{
|
||||
dst[0] = (hex2bin[src[0]] << 4) | (hex2bin[src[1]]);
|
||||
return 1;
|
||||
}
|
||||
const struct rite_binary_header *header = (const struct rite_binary_header *)bin;
|
||||
|
||||
static uint16_t
|
||||
hex_to_bin16(unsigned char *dst, unsigned char *src)
|
||||
{
|
||||
dst[0] = (hex2bin[src[0]] << 4) | (hex2bin[src[1]]);
|
||||
dst[1] = (hex2bin[src[2]] << 4) | (hex2bin[src[3]]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
hex_to_bin32(unsigned char *dst, unsigned char *src)
|
||||
{
|
||||
dst[0] = (hex2bin[src[0]] << 4) | (hex2bin[src[1]]);
|
||||
dst[1] = (hex2bin[src[2]] << 4) | (hex2bin[src[3]]);
|
||||
dst[2] = (hex2bin[src[4]] << 4) | (hex2bin[src[5]]);
|
||||
dst[3] = (hex2bin[src[6]] << 4) | (hex2bin[src[7]]);
|
||||
return 4;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
hex_to_uint8(unsigned char *hex)
|
||||
{
|
||||
return (unsigned char)hex2bin[hex[0]] << 4 |
|
||||
(unsigned char)hex2bin[hex[1]];
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
hex_to_uint16(unsigned char *hex)
|
||||
{
|
||||
return (uint16_t)hex2bin[hex[0]] << 12 |
|
||||
(uint16_t)hex2bin[hex[1]] << 8 |
|
||||
(uint16_t)hex2bin[hex[2]] << 4 |
|
||||
(uint16_t)hex2bin[hex[3]];
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
hex_to_uint32(unsigned char *hex)
|
||||
{
|
||||
return (uint32_t)hex2bin[hex[0]] << 28 |
|
||||
(uint32_t)hex2bin[hex[1]] << 24 |
|
||||
(uint32_t)hex2bin[hex[2]] << 20 |
|
||||
(uint32_t)hex2bin[hex[3]] << 16 |
|
||||
(uint32_t)hex2bin[hex[4]] << 12 |
|
||||
(uint32_t)hex2bin[hex[5]] << 8 |
|
||||
(uint32_t)hex2bin[hex[6]] << 4 |
|
||||
(uint32_t)hex2bin[hex[7]];
|
||||
}
|
||||
|
||||
static char*
|
||||
hex_to_str(char *hex, char *str, uint16_t *str_len)
|
||||
{
|
||||
char *src, *dst, buf[4];
|
||||
int escape = 0, base = 0;
|
||||
char *err_ptr;
|
||||
|
||||
*str_len = 0;
|
||||
for (src = hex, dst = str; *src != '\0'; src++) {
|
||||
if (escape) {
|
||||
switch(*src) {
|
||||
case 'a': *dst++ = '\a'/* BEL */; break;
|
||||
case 'b': *dst++ = '\b'/* BS */; break;
|
||||
case 't': *dst++ = '\t'/* HT */; break;
|
||||
case 'n': *dst++ = '\n'/* LF */; break;
|
||||
case 'v': *dst++ = '\v'/* VT */; break;
|
||||
case 'f': *dst++ = '\f'/* FF */; break;
|
||||
case 'r': *dst++ = '\r'/* CR */; break;
|
||||
case '\"': /* fall through */
|
||||
case '\'': /* fall through */
|
||||
case '\?': /* fall through */
|
||||
case '\\': *dst++ = *src; break;
|
||||
default:
|
||||
if (*src >= '0' && *src <= '7') {
|
||||
base = 8;
|
||||
strncpy(buf, src, 3);
|
||||
} else if (*src == 'x' || *src == 'X') {
|
||||
base = 16;
|
||||
src++;
|
||||
strncpy(buf, src, 2);
|
||||
}
|
||||
|
||||
*dst++ = (unsigned char) strtol(buf, &err_ptr, base) & 0xff;
|
||||
src += (err_ptr - buf - 1);
|
||||
break;
|
||||
}
|
||||
escape = 0;
|
||||
} else {
|
||||
if (*src == '\\') {
|
||||
escape = 1;
|
||||
} else {
|
||||
escape = 0;
|
||||
*dst++ = *src;
|
||||
}
|
||||
}
|
||||
if (!escape) {
|
||||
(*str_len)++;
|
||||
}
|
||||
if(memcmp(header->binary_identify, RITE_BINARY_IDENFIFIER, sizeof(header->binary_identify)) != 0) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER;
|
||||
}
|
||||
return str;
|
||||
|
||||
if(memcmp(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)) != 0) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER;
|
||||
}
|
||||
|
||||
*crc = bin_to_uint16(header->binary_crc);
|
||||
if (bin_size) {
|
||||
*bin_size = bin_to_uint32(header->binary_size);
|
||||
}
|
||||
|
||||
return MRB_DUMP_OK;
|
||||
}
|
||||
|
||||
int32_t
|
||||
mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
|
||||
{
|
||||
int result;
|
||||
int32_t total_nirep = 0;
|
||||
const struct rite_section_header *section_header;
|
||||
uint16_t crc;
|
||||
size_t bin_size = 0;
|
||||
size_t n;
|
||||
|
||||
if ((mrb == NULL) || (bin == NULL)) {
|
||||
return MRB_DUMP_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
result = read_rite_binary_header(bin, &bin_size, &crc);
|
||||
if(result != MRB_DUMP_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
n = offset_crc_body();
|
||||
if(crc != calc_crc_16_ccitt(bin + n, bin_size - n, 0)) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER;
|
||||
}
|
||||
|
||||
bin += sizeof(struct rite_binary_header);
|
||||
|
||||
do {
|
||||
section_header = (const struct rite_section_header *)bin;
|
||||
if(memcmp(section_header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(section_header->section_identify)) == 0) {
|
||||
result = read_rite_section_irep(mrb, bin);
|
||||
if(result < MRB_DUMP_OK) {
|
||||
return result;
|
||||
}
|
||||
total_nirep += result;
|
||||
}
|
||||
bin += bin_to_uint32(section_header->section_size);
|
||||
} while(memcmp(section_header->section_identify, RITE_BINARY_EOF, sizeof(section_header->section_identify)) != 0);
|
||||
|
||||
return total_nirep;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -687,7 +294,152 @@ irep_error(mrb_state *mrb, int n)
|
||||
mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SCRIPT_ERROR, msg, sizeof(msg) - 1));
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_load_irep(mrb_state *mrb, const uint8_t *bin)
|
||||
{
|
||||
int32_t n;
|
||||
|
||||
n = mrb_read_irep(mrb, bin);
|
||||
if (n < 0) {
|
||||
irep_error(mrb, n);
|
||||
return mrb_nil_value();
|
||||
}
|
||||
return mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_STDIO
|
||||
|
||||
static int32_t
|
||||
read_rite_section_irep_file(mrb_state *mrb, FILE *fp)
|
||||
{
|
||||
int32_t result;
|
||||
size_t sirep;
|
||||
size_t i;
|
||||
uint16_t nirep;
|
||||
uint16_t n;
|
||||
uint32_t len, buf_size;
|
||||
uint8_t *buf = NULL;
|
||||
const size_t record_header_size = 1 + 4;
|
||||
struct rite_section_irep_header header;
|
||||
|
||||
if (fread(&header, sizeof(struct rite_section_irep_header), 1, fp) != sizeof(struct rite_section_irep_header)) {
|
||||
return MRB_DUMP_READ_FAULT;
|
||||
}
|
||||
|
||||
sirep = mrb->irep_len;
|
||||
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++) {
|
||||
if (fread(buf, record_header_size, 1, fp) != record_header_size) {
|
||||
result = MRB_DUMP_READ_FAULT;
|
||||
goto error_exit;
|
||||
}
|
||||
buf_size = bin_to_uint32(&buf[0]);
|
||||
buf = (uint8_t *)mrb_realloc(mrb, buf, buf_size);
|
||||
if (fread(&buf[record_header_size], buf_size - record_header_size, 1, fp) != buf_size - record_header_size) {
|
||||
result = MRB_DUMP_READ_FAULT;
|
||||
goto error_exit;
|
||||
}
|
||||
result = read_rite_irep_record(mrb, buf, &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);
|
||||
}
|
||||
|
||||
int32_t
|
||||
mrb_read_irep_file(mrb_state *mrb, FILE* fp)
|
||||
{
|
||||
int result;
|
||||
int32_t total_nirep = 0;
|
||||
uint8_t *buf;
|
||||
uint16_t crc, crcwk = 0;
|
||||
uint32_t section_size = 0;
|
||||
size_t nbytes;
|
||||
struct rite_section_header section_header;
|
||||
long fpos;
|
||||
const size_t block_size = 1 << 14;
|
||||
const size_t buf_size = sizeof(struct rite_binary_header);
|
||||
|
||||
if ((mrb == NULL) || (fp == NULL)) {
|
||||
return MRB_DUMP_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
buf = mrb_malloc(mrb, buf_size);
|
||||
if (fread(buf, buf_size, 1, fp) != buf_size) {
|
||||
mrb_free(mrb, buf);
|
||||
return MRB_DUMP_READ_FAULT;
|
||||
}
|
||||
result = read_rite_binary_header(buf, NULL, &crc);
|
||||
mrb_free(mrb, buf);
|
||||
if(result != MRB_DUMP_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* verify CRC */
|
||||
fpos = ftell(fp);
|
||||
buf = mrb_malloc(mrb, block_size);
|
||||
fseek(fp, offset_crc_body(), SEEK_SET);
|
||||
while((nbytes = fread(buf, 1, block_size, fp)) > 0) {
|
||||
crcwk = calc_crc_16_ccitt(buf, nbytes, crcwk);
|
||||
}
|
||||
mrb_free(mrb, buf);
|
||||
if (nbytes < 0) {
|
||||
return MRB_DUMP_READ_FAULT;
|
||||
}
|
||||
if(crcwk != crc) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER;
|
||||
}
|
||||
fseek(fp, fpos + section_size, SEEK_SET);
|
||||
|
||||
// read sections
|
||||
do {
|
||||
fpos = ftell(fp);
|
||||
if (fread(§ion_header, sizeof(struct rite_section_header), 1, fp) != sizeof(struct rite_section_header)) {
|
||||
return MRB_DUMP_READ_FAULT;
|
||||
}
|
||||
section_size = bin_to_uint32(section_header.section_size);
|
||||
|
||||
if(memcmp(section_header.section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(section_header.section_identify)) == 0) {
|
||||
fseek(fp, fpos, SEEK_SET);
|
||||
result = read_rite_section_irep_file(mrb, fp);
|
||||
if(result < MRB_DUMP_OK) {
|
||||
return result;
|
||||
}
|
||||
total_nirep += result;
|
||||
}
|
||||
|
||||
fseek(fp, fpos + section_size, SEEK_SET);
|
||||
} while(memcmp(section_header.section_identify, RITE_BINARY_EOF, sizeof(section_header.section_identify)) != 0);
|
||||
|
||||
return total_nirep;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_load_irep_file(mrb_state *mrb, FILE* fp)
|
||||
{
|
||||
@@ -699,16 +451,4 @@ mrb_load_irep_file(mrb_state *mrb, FILE* fp)
|
||||
}
|
||||
return mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
|
||||
}
|
||||
#endif
|
||||
|
||||
mrb_value
|
||||
mrb_load_irep(mrb_state *mrb, const char *bin)
|
||||
{
|
||||
int n = mrb_read_irep(mrb, bin);
|
||||
|
||||
if (n < 0) {
|
||||
irep_error(mrb, n);
|
||||
return mrb_nil_value();
|
||||
}
|
||||
return mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
|
||||
}
|
||||
#endif /* ENABLE_STDIO */
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
#include "mruby/string.h"
|
||||
#include "mruby/proc.h"
|
||||
|
||||
extern const char mrbtest_irep[];
|
||||
extern const uint8_t mrbtest_irep[];
|
||||
|
||||
void mrbgemtest_init(mrb_state* mrb);
|
||||
|
||||
|
||||
+2
-2
@@ -209,10 +209,10 @@ main(int argc, char **argv)
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (args.initname) {
|
||||
n = mrb_bdump_irep(mrb, n, args.wfp, args.initname);
|
||||
n = mrb_dump_irep_cfunc(mrb, n, args.wfp, args.initname);
|
||||
}
|
||||
else {
|
||||
n = mrb_dump_irep(mrb, n, args.wfp);
|
||||
n = mrb_dump_irep_binary(mrb, n, args.wfp);
|
||||
}
|
||||
|
||||
cleanup(mrb, &args);
|
||||
|
||||
Reference in New Issue
Block a user