compact compiler ids and spans to reduce memory usage
This commit is contained in:
+101
-10
@@ -82,6 +82,52 @@ main :: func() void { _ = value }
|
||||
testing.expect_value(t, module.statements[module.functions[0].body[0]].name, sink_symbol)
|
||||
}
|
||||
|
||||
@(test)
|
||||
compact_ids_reserve_invalid_values_and_preserve_layout :: proc(t: ^testing.T) {
|
||||
testing.expect_value(t, size_of(source.Span), 12)
|
||||
testing.expect_value(t, size_of(token.Token), 24)
|
||||
|
||||
source_index, source_ok := source.source_index(source.Source_Id(0), 1)
|
||||
testing.expect_value(t, source_index, 0)
|
||||
testing.expect(t, source_ok)
|
||||
_, source_invalid := source.source_index(source.INVALID_SOURCE, 1)
|
||||
testing.expect(t, !source_invalid)
|
||||
_, source_out_of_bounds := source.source_index(source.Source_Id(1), 1)
|
||||
testing.expect(t, !source_out_of_bounds)
|
||||
diagnostic_index, diagnostic_ok := source.diagnostic_index(source.Diagnostic_Id(0), 1)
|
||||
testing.expect_value(t, diagnostic_index, 0)
|
||||
testing.expect(t, diagnostic_ok)
|
||||
_, diagnostic_invalid := source.diagnostic_index(source.INVALID_DIAGNOSTIC, 1)
|
||||
testing.expect(t, !diagnostic_invalid)
|
||||
|
||||
expr_index, expr_ok := ast.index(ast.Expr_Id(0), ast.INVALID_EXPR, 1)
|
||||
testing.expect_value(t, expr_index, 0)
|
||||
testing.expect(t, expr_ok)
|
||||
_, expr_invalid := ast.index(ast.INVALID_EXPR, ast.INVALID_EXPR, 1)
|
||||
testing.expect(t, !expr_invalid)
|
||||
|
||||
function_index, function_ok := hir.index(hir.Function_Id(0), hir.INVALID_FUNCTION, 1)
|
||||
testing.expect_value(t, function_index, 0)
|
||||
testing.expect(t, function_ok)
|
||||
_, function_invalid := hir.index(hir.INVALID_FUNCTION, hir.INVALID_FUNCTION, 1)
|
||||
testing.expect(t, !function_invalid)
|
||||
|
||||
instruction_index, instruction_ok := ir.index(ir.Instruction_Id(0), ir.INVALID_INSTRUCTION, 1)
|
||||
testing.expect_value(t, instruction_index, 0)
|
||||
testing.expect(t, instruction_ok)
|
||||
_, instruction_invalid := ir.index(ir.INVALID_INSTRUCTION, ir.INVALID_INSTRUCTION, 1)
|
||||
testing.expect(t, !instruction_invalid)
|
||||
|
||||
spec_index, spec_ok := checker.spec_index(checker.Spec_Id(0), 1)
|
||||
testing.expect_value(t, spec_index, 0)
|
||||
testing.expect(t, spec_ok)
|
||||
_, spec_invalid := checker.spec_index(checker.INVALID_SPEC, 1)
|
||||
testing.expect(t, !spec_invalid)
|
||||
|
||||
testing.expect(t, source.fits_source_length(u64(0xffff_ffff)))
|
||||
testing.expect(t, !source.fits_source_length(u64(0x1_0000_0000)))
|
||||
}
|
||||
|
||||
@(test)
|
||||
lexer_preserves_newlines_and_skips_comments :: proc(t: ^testing.T) {
|
||||
source_file := source.Source{path="test.bro", text="# comment\nmain :: func() void {}\n"}
|
||||
@@ -196,7 +242,7 @@ main :: func() void {}
|
||||
|
||||
c_symbol := symbol.intern(&symbols, "c")
|
||||
for tok in stream.items {
|
||||
if tok.span.start < len(text) && text[tok.span.start:tok.span.end] == "c" {
|
||||
if int(tok.span.start) < len(text) && text[int(tok.span.start):int(tok.span.end)] == "c" {
|
||||
testing.expect_value(t, tok.kind, token.Kind.Identifier)
|
||||
testing.expect_value(t, tok.symbol, c_symbol)
|
||||
}
|
||||
@@ -415,8 +461,8 @@ multi_source_diagnostics_report_the_originating_file :: proc(t: ^testing.T) {
|
||||
|
||||
testing.expect(t, loaded)
|
||||
found := false
|
||||
for _, diagnostic_id in diagnostics.items {
|
||||
message := source.format(&diagnostics, diagnostic_id)
|
||||
for _, diagnostic_index in diagnostics.items {
|
||||
message := source.format(&diagnostics, source.diagnostic_id(diagnostic_index))
|
||||
if strings.contains(message, "/b.bro:2:9:") &&
|
||||
strings.contains(message, "unknown package alias 'math'") {
|
||||
found = true
|
||||
@@ -788,7 +834,7 @@ main :: func() void {
|
||||
testing.expect(t, done_id >= 0)
|
||||
testing.expect(t, main_id >= 0)
|
||||
testing.expect_value(t, hir_module.statements[hir_module.functions[done_id].body[0]].kind, hir.Stmt_Kind.Return)
|
||||
testing.expect_value(t, hir_module.statements[hir_module.functions[done_id].body[0]].expr, -1)
|
||||
testing.expect_value(t, hir_module.statements[hir_module.functions[done_id].body[0]].expr, hir.INVALID_EXPR)
|
||||
main := hir_module.functions[main_id]
|
||||
testing.expect_value(t, hir_module.statements[main.body[0]].kind, hir.Stmt_Kind.Expression)
|
||||
testing.expect_value(t, hir_module.statements[main.body[1]].kind, hir.Stmt_Kind.Sink)
|
||||
@@ -1243,14 +1289,59 @@ maximum_signed_i64_literal_parses_exactly :: proc(t: ^testing.T) {
|
||||
testing.expect_value(t, module.exprs[module.globals[0].expr].integer, i64(9223372036854775807))
|
||||
}
|
||||
|
||||
@(test)
|
||||
malformed_hir_references_lower_to_valid_trapped_llvm :: proc(t: ^testing.T) {
|
||||
hir_module := hir.init_module()
|
||||
defer hir.destroy_module(&hir_module)
|
||||
append(&hir_module.exprs, hir.Expr{
|
||||
kind=.Local,
|
||||
type=types.I8,
|
||||
target=hir.local_ref(hir.INVALID_LOCAL),
|
||||
left=hir.INVALID_EXPR,
|
||||
right=hir.INVALID_EXPR,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
append(&hir_module.statements, hir.Stmt{
|
||||
kind=.Expression,
|
||||
expr=hir.Expr_Id(0),
|
||||
local=hir.INVALID_LOCAL,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
body := make([]hir.Stmt_Id, 1)
|
||||
body[0] = hir.Stmt_Id(0)
|
||||
append(&hir_module.functions, hir.Function{
|
||||
name=symbol.INVALID,
|
||||
link_name=strings.clone("main"),
|
||||
calling_convention=.C,
|
||||
implementation=.Definition,
|
||||
linkage=.External,
|
||||
is_main=true,
|
||||
result=types.VOID,
|
||||
body=body,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
ir_module := lower.lower(&hir_module)
|
||||
defer ir.destroy_module(&ir_module)
|
||||
source_file := source.Source{path="test.bro", text=""}
|
||||
diagnostics := source.init_diagnostics(&source_file)
|
||||
defer source.destroy_diagnostics(&diagnostics)
|
||||
symbols := symbol.init_table()
|
||||
defer symbol.destroy_table(&symbols)
|
||||
text := llvm.emit(&ir_module, &diagnostics, &symbols)
|
||||
defer delete(text)
|
||||
|
||||
testing.expect(t, strings.contains(text, "call void @bro.trap"))
|
||||
testing.expect(t, !strings.contains(text, "%v-1"))
|
||||
}
|
||||
|
||||
@(test)
|
||||
malformed_ir_emits_traps_and_typed_sentinels :: proc(t: ^testing.T) {
|
||||
module := ir.init_module()
|
||||
defer ir.destroy_module(&module)
|
||||
instructions := make([]ir.Instruction, 3)
|
||||
instructions[0] = ir.Instruction{op=.Store, type=types.I8, a=-1, b=-1, diagnostic=-1}
|
||||
instructions[1] = ir.Instruction{op=.Add_Checked, type=types.I32, a=-1, b=-1, diagnostic=-1}
|
||||
instructions[2] = ir.Instruction{op=.Return, type=types.I32, a=1, b=-1, diagnostic=-1}
|
||||
instructions[0] = ir.Instruction{op=.Store, type=types.I8, a=ir.INVALID_INSTRUCTION, b=ir.INVALID_INSTRUCTION, diagnostic=source.INVALID_DIAGNOSTIC}
|
||||
instructions[1] = ir.Instruction{op=.Add_Checked, type=types.I32, a=ir.INVALID_INSTRUCTION, b=ir.INVALID_INSTRUCTION, diagnostic=source.INVALID_DIAGNOSTIC}
|
||||
instructions[2] = ir.Instruction{op=.Return, type=types.I32, a=ir.Instruction_Id(1), b=ir.INVALID_INSTRUCTION, diagnostic=source.INVALID_DIAGNOSTIC}
|
||||
append(&module.functions, ir.Function{
|
||||
link_name=strings.clone("main"),
|
||||
calling_convention=.C,
|
||||
@@ -1335,14 +1426,14 @@ deep_global_cycle_detection_uses_iterative_dfs :: proc(t: ^testing.T) {
|
||||
|
||||
for id in 0..<count {
|
||||
append(&ast_module.globals, ast.Global{name=name})
|
||||
dependencies: [dynamic]int
|
||||
dependencies: [dynamic]hir.Global_Id
|
||||
dependencies.allocator = context.allocator
|
||||
append(&dependencies, (id+1)%count)
|
||||
append(&dependencies, hir.global_id((id+1)%count))
|
||||
append(&state.module.globals, hir.Global{name=name, dependencies=dependencies})
|
||||
}
|
||||
states := make([]u8, count)
|
||||
defer delete(states)
|
||||
checker.detect_global_cycles_visit(&state, 0, states)
|
||||
checker.detect_global_cycles_visit(&state, hir.Global_Id(0), states)
|
||||
|
||||
testing.expect_value(t, len(diagnostics.items), 1)
|
||||
for global in state.module.globals {
|
||||
|
||||
Reference in New Issue
Block a user