Fix problems with running programs due to mismatched endian
Basically ensure we're converting to big endian when writing bytecode and converting from big endian when reading bytecode.
This commit is contained in:
54
lib/inst.c
54
lib/inst.c
@@ -326,12 +326,14 @@ void inst_write_bytecode(inst_t inst, darr_t *darr)
|
|||||||
darr_append_byte(darr, inst.operand.as_byte);
|
darr_append_byte(darr, inst.operand.as_byte);
|
||||||
break;
|
break;
|
||||||
case DATA_TYPE_HWORD:
|
case DATA_TYPE_HWORD:
|
||||||
// TODO: Enforce endian here
|
darr_ensure_capacity(darr, HWORD_SIZE);
|
||||||
darr_append_bytes(darr, (byte *)&inst.operand.as_hword, HWORD_SIZE);
|
convert_hword_to_bytes(inst.operand.as_hword, darr->data + darr->used);
|
||||||
|
darr->used += HWORD_SIZE;
|
||||||
break;
|
break;
|
||||||
case DATA_TYPE_WORD:
|
case DATA_TYPE_WORD:
|
||||||
// TODO: Enforce endian here
|
darr_ensure_capacity(darr, WORD_SIZE);
|
||||||
darr_append_bytes(darr, (byte *)&inst.operand.as_word, WORD_SIZE);
|
convert_word_to_bytes(inst.operand.as_word, darr->data + darr->used);
|
||||||
|
darr->used += WORD_SIZE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -355,22 +357,18 @@ data_t read_type_from_darr(darr_t *darr, data_type_t type)
|
|||||||
return DBYTE(darr->data[darr->used++]);
|
return DBYTE(darr->data[darr->used++]);
|
||||||
break;
|
break;
|
||||||
case DATA_TYPE_HWORD:
|
case DATA_TYPE_HWORD:
|
||||||
// TODO: Enforce endian here
|
|
||||||
if (darr->used + HWORD_SIZE > darr->available)
|
if (darr->used + HWORD_SIZE > darr->available)
|
||||||
// TODO: Error (darr has no space left)
|
// TODO: Error (darr has no space left)
|
||||||
return DWORD(0);
|
return DWORD(0);
|
||||||
hword u = 0;
|
hword u = convert_bytes_to_hword(darr->data + darr->used);
|
||||||
memcpy(&u, darr->data + darr->used, HWORD_SIZE);
|
|
||||||
darr->used += HWORD_SIZE;
|
darr->used += HWORD_SIZE;
|
||||||
return DHWORD(u);
|
return DHWORD(u);
|
||||||
break;
|
break;
|
||||||
case DATA_TYPE_WORD:
|
case DATA_TYPE_WORD:
|
||||||
// TODO: Enforce endian here
|
|
||||||
if (darr->used + WORD_SIZE > darr->available)
|
if (darr->used + WORD_SIZE > darr->available)
|
||||||
// TODO: Error (darr has no space left)
|
// TODO: Error (darr has no space left)
|
||||||
return DWORD(0);
|
return DWORD(0);
|
||||||
word w = 0;
|
word w = convert_bytes_to_word(darr->data + darr->used);
|
||||||
memcpy(&w, darr->data + darr->used, WORD_SIZE);
|
|
||||||
darr->used += WORD_SIZE;
|
darr->used += WORD_SIZE;
|
||||||
return DWORD(w);
|
return DWORD(w);
|
||||||
break;
|
break;
|
||||||
@@ -421,6 +419,14 @@ inst_t *insts_read_bytecode(darr_t *bytes, size_t *ret_size)
|
|||||||
return (inst_t *)instructions.data;
|
return (inst_t *)instructions.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inst_t *insts_read_bytecode_file(FILE *fp, size_t *ret)
|
||||||
|
{
|
||||||
|
darr_t darr = darr_read_file(fp);
|
||||||
|
inst_t *instructions = insts_read_bytecode(&darr, ret);
|
||||||
|
free(darr.data);
|
||||||
|
return instructions;
|
||||||
|
}
|
||||||
|
|
||||||
void insts_write_bytecode_file(inst_t *instructions, size_t size, FILE *fp)
|
void insts_write_bytecode_file(inst_t *instructions, size_t size, FILE *fp)
|
||||||
{
|
{
|
||||||
darr_t darr = {0};
|
darr_t darr = {0};
|
||||||
@@ -430,20 +436,19 @@ void insts_write_bytecode_file(inst_t *instructions, size_t size, FILE *fp)
|
|||||||
free(darr.data);
|
free(darr.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inst_t *insts_read_bytecode_file(FILE *fp, size_t *ret)
|
void prog_header_write_bytecode(prog_header_t header, darr_t *buffer)
|
||||||
{
|
{
|
||||||
darr_t darr = darr_read_file(fp);
|
word start = htobe64(header.start_address);
|
||||||
inst_t *instructions = insts_read_bytecode(&darr, ret);
|
darr_append_bytes(buffer, (byte *)&start, sizeof(start));
|
||||||
free(darr.data);
|
|
||||||
return instructions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void prog_write_bytecode(prog_t *program, darr_t *buffer)
|
void prog_write_bytecode(prog_t *program, darr_t *buffer)
|
||||||
{
|
{
|
||||||
// Write program header
|
// Write program header
|
||||||
darr_append_bytes(buffer, (byte *)&program->header, sizeof(program->header));
|
prog_header_write_bytecode(program->header, buffer);
|
||||||
// Write instruction count
|
// Write instruction count
|
||||||
darr_append_bytes(buffer, (byte *)&program->count, sizeof(program->count));
|
word pcount = htobe64(program->count);
|
||||||
|
darr_append_bytes(buffer, (byte *)&pcount, sizeof(pcount));
|
||||||
// Write instructions
|
// Write instructions
|
||||||
insts_write_bytecode(program->instructions, program->count, buffer);
|
insts_write_bytecode(program->instructions, program->count, buffer);
|
||||||
}
|
}
|
||||||
@@ -453,22 +458,29 @@ void prog_append_bytecode(prog_t *program, darr_t *buffer)
|
|||||||
insts_write_bytecode(program->instructions, program->count, buffer);
|
insts_write_bytecode(program->instructions, program->count, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prog_header_t prog_header_read_bytecode(darr_t *buffer)
|
||||||
|
{
|
||||||
|
prog_header_t header = {0};
|
||||||
|
header.start_address = convert_bytes_to_word(buffer->data + buffer->used);
|
||||||
|
buffer->used += sizeof(header.start_address);
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
prog_t *prog_read_bytecode(darr_t *buffer)
|
prog_t *prog_read_bytecode(darr_t *buffer)
|
||||||
{
|
{
|
||||||
// TODO: Error (not enough space for program header)
|
// TODO: Error (not enough space for program header)
|
||||||
if ((buffer->available - buffer->used) < sizeof(prog_header_t))
|
if ((buffer->available - buffer->used) < sizeof(prog_header_t))
|
||||||
return NULL;
|
return NULL;
|
||||||
// Read program header
|
// Read program header
|
||||||
prog_header_t header = {0};
|
prog_header_t header = prog_header_read_bytecode(buffer);
|
||||||
memcpy(&header, buffer->data + buffer->used, sizeof(header));
|
|
||||||
buffer->used += sizeof(prog_header_t);
|
|
||||||
// TODO: Error (not enough space for program instruction count)
|
// TODO: Error (not enough space for program instruction count)
|
||||||
if ((buffer->available - buffer->used) < WORD_SIZE)
|
if ((buffer->available - buffer->used) < WORD_SIZE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Read instruction count
|
// Read instruction count
|
||||||
word count = convert_bytes_to_word(buffer->data + buffer->used);
|
word count = convert_bytes_to_word(buffer->data + buffer->used);
|
||||||
buffer->used += WORD_SIZE;
|
buffer->used += sizeof(count);
|
||||||
|
|
||||||
prog_t *program = malloc(sizeof(*program) + (sizeof(inst_t) * count));
|
prog_t *program = malloc(sizeof(*program) + (sizeof(inst_t) * count));
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < count && (buffer->used < buffer->available); ++i)
|
for (i = 0; i < count && (buffer->used < buffer->available); ++i)
|
||||||
|
|||||||
Reference in New Issue
Block a user