static int read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, uint8_t *flags) { const struct rite_binary_header *header = (const struct rite_binary_header *)bin; if (memcmp(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)) == 0) { if (bigendian_p()) *flags |= FLAG_BYTEORDER_NATIVE; else *flags |= FLAG_BYTEORDER_BIG; } else if (memcmp(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident)) == 0) { if (bigendian_p()) *flags |= FLAG_BYTEORDER_LIL; else *flags |= FLAG_BYTEORDER_NATIVE; } else { return MRB_DUMP_INVALID_FILE_HEADER; } if (crc) { *crc = bin_to_uint16(header->binary_crc); } *bin_size = (size_t)bin_to_uint32(header->binary_size); return MRB_DUMP_OK; }
static ptrdiff_t write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags) { uint8_t *cur = buf; uint32_t iseq_no; cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */ cur += write_padding(cur); switch (flags & DUMP_ENDIAN_NAT) { case DUMP_ENDIAN_BIG: if (bigendian_p()) goto native; for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */ } break; case DUMP_ENDIAN_LIL: if (!bigendian_p()) goto native; for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { cur += uint32l_to_bin(irep->iseq[iseq_no], cur); /* opcode */ } break; native: case DUMP_ENDIAN_NAT: memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code)); cur += irep->ilen * sizeof(mrb_code); break; } return cur - buf; }
static int write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8_t flags) { struct rite_binary_header *header = (struct rite_binary_header *)bin; uint16_t crc; uint32_t offset; switch (flags & DUMP_ENDIAN_NAT) { endian_big: case DUMP_ENDIAN_BIG: memcpy(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)); break; endian_little: case DUMP_ENDIAN_LIL: memcpy(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident)); break; case DUMP_ENDIAN_NAT: if (bigendian_p()) goto endian_big; goto endian_little; break; } 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)); mrb_assert(binary_size <= UINT32_MAX); uint32_to_bin((uint32_t)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 mrb_bool dump_bigendian_p(uint8_t flags) { switch (flags & DUMP_ENDIAN_NAT) { case DUMP_ENDIAN_BIG: return TRUE; case DUMP_ENDIAN_LIL: return FALSE; default: case DUMP_ENDIAN_NAT: return bigendian_p(); } }