8000 Introduce the memory_base field in the BM file metadata by redoste · Pull Request #486 · tsoding/bm · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Introduce the memory_base field in the BM file metadata #486

8000 New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bang/src/bang_compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,7 @@ void bang_prepare_var_stack(Bang *bang, Basm *basm, size_t stack_size)
assert(sizeof(stack_start_addr) == ptr_def.size);

bang->stack_frame_var_addr = basm_push_buffer_to_memory(basm, (uint8_t*) &stack_start_addr, ptr_def.size).as_u64;
basm->memory_base = stack_size;
}

void compile_var_def_into_basm(Bang *bang, Basm *basm, Bang_Var_Def var_def, Bang_Var_Storage storage)
Expand Down
23 changes: 21 additions & 2 deletions basm/src/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,8 @@ void basm_save_to_file_as_bm(Basm *basm, const char *file_path)
.version = BM_FILE_VERSION,
.entry = basm->entry,
.program_size = basm->program_size,
.memory_size = basm->memory_size,
.memory_base = basm->memory_base,
.memory_size = basm->memory_size - basm->memory_base,
.memory_capacity = basm->memory_capacity,
.externals_size = basm->external_natives_size,
};
Expand All @@ -327,7 +328,7 @@ void basm_save_to_file_as_bm(Basm *basm, const char *file_path)
exit(1);
}

fwrite(basm->memory, sizeof(basm->memory[0]), basm->memory_size, f);
fwrite(basm->memory + basm->memory_base, sizeof(basm->memory[0]), basm->memory_size - basm->memory_base, f);
if (ferror(f)) {
fprintf(stderr, "ERROR: Could not write to file `%s`: %s\n",
file_path, strerror(errno));
Expand Down Expand Up @@ -403,6 +404,10 @@ void basm_translate_block_statement(Basm *basm, Block_Statement *block)
basm_translate_macrodef_statement(basm, statement.value.as_macrodef, statement.location);
break;

case STATEMENT_KIND_BASE:
basm_translate_base_statement(basm, statement.value.as_base, statement.location);
break;

case STATEMENT_KIND_MACROCALL:
case STATEMENT_KIND_FUNCDEF:
case STATEMENT_KIND_FOR:
Expand Down Expand Up @@ -470,6 +475,7 @@ void basm_translate_block_statement(Basm *basm, Block_Statement *block)
case STATEMENT_KIND_ASSERT:
case STATEMENT_KIND_INCLUDE:
case STATEMENT_KIND_CONST:
case STATEMENT_KIND_BASE:
// NOTE: ignored at the second pass
break;

Expand Down Expand Up @@ -1288,6 +1294,19 @@ Macrodef *basm_resolve_macrodef(Basm *basm, String_View name)
return NULL;
}


void basm_translate_base_statement(Basm *basm, Base_Statement base_statement, File_Location location)
{
if (basm->memory_size != 0 || 10000 basm->memory_base != 0) {
fprintf(stderr, FL_Fmt": ERROR: %%base should precede every memory related statements\n",
FL_Arg(location));
exit(1);
}

basm_push_byte_array_to_memory(basm, base_statement.size, 0);
basm->memory_base = basm->memory_size;
}

Native_ID basm_push_external_native(Basm *basm, String_View native_name)
{
assert(basm->external_natives_size < BM_EXTERNAL_NATIVES_CAPACITY);
Expand Down
2 changes: 2 additions & 0 deletions basm/src/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ typedef struct {
size_t string_lengths_size;

uint8_t memory[BM_MEMORY_CAPACITY];
size_t memory_base;
size_t memory_size;
size_t memory_capacity;

Expand Down Expand Up @@ -179,6 +180,7 @@ bool basm_resolve_include_file_path(Basm *basm,
Macrodef *basm_resolve_macrodef(Basm *basm, String_View name);
void basm_translate_macrocall_statement(Basm *basm, Macrocall_Statement macrocall, File_Location location);
void basm_translate_macrodef_statement(Basm *basm, Macrodef_Statement macrodef, File_Location location);
void basm_translate_base_statement(Basm *basm, Base_Statement base_statement, File_Location location);
void basm_translate_block_statement(Basm *basm, Block_Statement *block);
void basm_translate_const_statement(Basm *basm, Const_Statement konst, File_Location location);
void basm_translate_native_statement(Basm *basm, Native_Statement native, File_Location location);
Expand Down
39 changes: 39 additions & 0 deletions basm/src/statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ void dump_statement(FILE *stream, Statement statement, int level)
exit(1);
}
break;

case STATEMENT_KIND_BASE: {
uint64_t size = statement.value.as_base.size;

fprintf(stream, "%*sBase:\n", level * 2, "");
fprintf(stream, "%*s%"PRIu64"\n", (level + 1) * 2, "", size);
}
break;
}
}

Expand Down Expand Up @@ -426,6 +434,20 @@ int dump_statement_as_dot_edges(FILE *stream, Statement statement, int *counter)
}
break;

case STATEMENT_KIND_BASE: {
int id = (*counter)++;
int child_id = (*counter)++;

uint64_t size = statement.value.as_base.size;

fprintf(stream, "Expr_%d [shape=diamond label=\"%%base\"]\n", id);
fprintf(stream, "Expr_%d [shape=circle label=\"%"PRIu64"\"]\n",
child_id, size);
fprintf(stream, "Expr_%d -> Expr_%d [style=dotted]\n", id, child_id);
return id;
}
break;

default: {
assert(false && "dump_statement_as_dot_edges: unreachable");
exit(1);
Expand Down Expand Up @@ -732,6 +754,23 @@ void parse_directive_from_line(Arena *arena, Linizer *linizer, Block_List *outpu
exit(1);
}

block_list_push(arena, output, statement);
} else if (sv_eq(name, sv_from_cstr("base"))) {
Statement statement = {0};
statement.location = location;
statement.kind = STATEMENT_KIND_BASE;

Tokenizer tokenizer = tokenizer_from_sv(body);
Expr base_size = parse_expr_from_tokens(arena, &tokenizer, location);
if (base_size.kind != EXPR_KIND_LIT_INT) {
fprintf(stderr, FL_Fmt": ERROR: expected memory base for %%base\n",
FL_Arg(location));
exit(1);
}

statement.value.as_base.size = base_size.value.as_lit_int;
expect_no_tokens(&tokenizer, location);

block_list_push(arena, output, statement);
} else {
Tokenizer tokenizer = tokenizer_from_sv(body);
Expand Down
8 changes: 7 additions & 1 deletion basm/src/statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ typedef enum {
STATEMENT_KIND_FOR,
STATEMENT_KIND_FUNCDEF,
STATEMENT_KIND_MACROCALL,
STATEMENT_KIND_MACRODEF
STATEMENT_KIND_MACRODEF,
STATEMENT_KIND_BASE
} Statement_Kind;

typedef struct {
Expand Down Expand Up @@ -92,6 +93,10 @@ typedef struct {
Block_Statement *body;
} Macrodef_Statement;

typedef struct {
uint64_t size;
} Base_Statement;

typedef union {
Emit_Inst_Statement as_emit_inst;
Label_Statement as_label;
Expand All @@ -108,6 +113,7 @@ typedef union {
Fundef_Statement as_fundef;
Macrocall_Statement as_macrocall;
Macrodef_Statement as_macrodef;
Base_Statement as_base;
} Statement_Value;

struct Statement {
F438 Expand Down
7 changes: 4 additions & 3 deletions bm/src/bm.c
Original file line number Diff line number Diff line change
Expand Up @@ -891,11 +891,11 @@ void bm_load_program_from_file(Bm *bm, const char *file_path)
exit(1);
}

if (meta.memory_size > meta.memory_capacity) {
if (meta.memory_base + meta.memory_size > meta.memory_capacity) {
fprintf(stderr,
"ERROR: %s: memory size %"PRIu64" is greater than declared memory capacity %"PRIu64"\n",
file_path,
meta.memory_size,
meta.memory_base + meta.memory_size,
meta.memory_capacity);
exit(1);
}
Expand All @@ -919,8 +919,9 @@ void bm_load_program_from_file(Bm *bm, const char *file_path)
exit(1);
}

n = fread(bm->memory, sizeof(bm->memory[0]), meta.memory_size, f);
n = fread(bm->memory + meta.memory_base, sizeof(bm->memory[0]), meta.memory_size, f);
bm->expected_memory_size = meta.memory_size;
bm->memory_base = meta.memory_base;

if (n != meta.memory_size) {
fprintf(stderr, "ERROR: %s: read %zd bytes of memory section, but expected %"PRIu64" bytes.\n",
Expand Down
4 changes: 3 additions & 1 deletion bm/src/bm.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ struct Bm {
// The program is allowed to access memory beyond the `expected_memory_size`.
// This variable is needed for debasm to reliably recover the source code.
size_t expected_memory_size;
size_t memory_base;

bool halt;
};
Expand All @@ -199,13 +200,14 @@ void bm_dump_stack(FILE *stream, const Bm *bm);
void bm_load_program_from_file(Bm *bm, const char *file_path);

#define BM_FILE_MAGIC 0xa4016d62
#define BM_FILE_VERSION 7
#define BM_FILE_VERSION 8

PACK(struct Bm_File_Meta {
uint32_t magic;
uint16_t version;
uint64_t program_size;
uint64_t entry;
uint64_t memory_base;
uint64_t memory_size;
uint64_t memory_capacity;
uint64_t externals_size;
Expand Down
5 changes: 3 additions & 2 deletions debasm/src/debasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ int main(int argc, char *argv[])
printf("%%native %s\n", bm.externals[i].name);
}

printf("%%base %zu\n", bm.memory_base);
printf("%%const MEMORY = \"");
for (size_t i = 0; i < bm.expected_memory_size; ++i) {
for (size_t i = bm.memory_base; i < bm.expected_memory_size + bm.memory_base; ++i) {
if (32 <= bm.memory[i] && bm.memory[i] < 127) {
printf("%c", bm.memory[i]);
} else {
printf("\\x%02x", bm.memory[i]);
}
}
printf("\"\n");
printf("%%assert MEMORY == 0\n");
printf("%%assert MEMORY == %zu\n", bm.memory_base);

for (Inst_Addr i = 0; i < bm.program_size; ++i) {
if (i == bm.ip) {
Expand Down
0