|
|
|
@@ -10,10 +10,10 @@ add_function proc(
|
|
|
|
|
locals []ir.Type,
|
|
|
|
|
parameter_count usize,
|
|
|
|
|
result ir.Type,
|
|
|
|
|
value_count usize,
|
|
|
|
|
) ir.FunctionId ! mem.AllocError {
|
|
|
|
|
) ir.FunctionId ! (mem.AllocError | diagnostics.CapacityError) {
|
|
|
|
|
function := ir.init_function(module.allocator)
|
|
|
|
|
errdefer {
|
|
|
|
|
transferred := false
|
|
|
|
|
errdefer if (!transferred) {
|
|
|
|
|
arraylist.deinit(&function.parameters)
|
|
|
|
|
arraylist.deinit(&function.locals)
|
|
|
|
|
arraylist.deinit(&function.array_storage)
|
|
|
|
@@ -24,22 +24,24 @@ add_function proc(
|
|
|
|
|
}
|
|
|
|
|
arraylist.deinit(&function.blocks)
|
|
|
|
|
}
|
|
|
|
|
for (locals) |type, index| {
|
|
|
|
|
try arraylist.append(&function.locals, type)
|
|
|
|
|
if (index < parameter_count) try arraylist.append(&function.parameters, type)
|
|
|
|
|
}
|
|
|
|
|
function.result = result
|
|
|
|
|
function.value_count = value_count
|
|
|
|
|
try arraylist.append(&function.blocks, ir.init_block(module.allocator))
|
|
|
|
|
id :: ir.FunctionId(module.functions.items.len)
|
|
|
|
|
try arraylist.append(&module.functions, function)
|
|
|
|
|
transferred = true
|
|
|
|
|
for (locals) |type, index| {
|
|
|
|
|
if (index < parameter_count) {
|
|
|
|
|
_ = try ir.add_parameter(module, id, type, ir.no_array)
|
|
|
|
|
} else {
|
|
|
|
|
_ = try ir.add_local(module, id, type, ir.no_array)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return id
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@hide:file
|
|
|
|
|
emit proc(module @mut ir.Module, function ir.FunctionId, instruction ir.Instruction) void ! mem.AllocError {
|
|
|
|
|
if (instruction.type == .address) module.functions.items[usize(function)].has_addresses = true
|
|
|
|
|
try arraylist.append(&module.functions.items[usize(function)].blocks.items[0].instructions, instruction)
|
|
|
|
|
emit proc(module @mut ir.Module, function ir.FunctionId, instruction ir.Instruction) void ! (mem.AllocError | diagnostics.CapacityError) {
|
|
|
|
|
_ = try ir.emit(module, function, ir.BlockId(0), instruction)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@hide:file
|
|
|
|
@@ -91,15 +93,15 @@ repeated_calls_have_fresh_parameters_locals_and_temporaries test {
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
types [2]ir.Type :: [.int, .int]
|
|
|
|
|
bump :: try add_function(&module, types[..], 1, .int, 4)
|
|
|
|
|
bump :: try add_function(&module, types[..], 1, .int)
|
|
|
|
|
try emit(&module, bump, ir.Instruction{ op = .load_local, type = .int, destination = ir.ValueId(0), slot = 0 })
|
|
|
|
|
try emit(&module, bump, integer(1, 1))
|
|
|
|
|
try emit(&module, bump, ir.Instruction{ op = .add, type = .int, destination = ir.ValueId(2), left = ir.ValueId(0), right = ir.ValueId(1) })
|
|
|
|
|
try emit(&module, bump, ir.Instruction{ op = .store_local, left = ir.ValueId(2), slot = 1 })
|
|
|
|
|
try emit(&module, bump, ir.Instruction{ op = .load_local, type = .int, destination = ir.ValueId(3), slot = 1 })
|
|
|
|
|
return_value(&module, bump, ir.ValueId(3))
|
|
|
|
|
noop :: try add_function(&module, &[], 0, .void, 0)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int, 8)
|
|
|
|
|
noop :: try add_function(&module, &[], 0, .void)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, function_value(0, bump))
|
|
|
|
|
try emit(&module, main, integer(1, 19))
|
|
|
|
@@ -125,8 +127,8 @@ lazy_globals_follow_forward_dependencies_and_reset_between_runs test {
|
|
|
|
|
defer ir.deinit(&module)
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
first :: try add_function(&module, &[], 0, .int, 3)
|
|
|
|
|
second :: try add_function(&module, &[], 0, .int, 1)
|
|
|
|
|
first :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
second :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
try emit(&module, first, ir.Instruction{ op = .load_global, type = .int, destination = ir.ValueId(0), slot = 1 })
|
|
|
|
|
try emit(&module, first, integer(1, 1))
|
|
|
|
|
try emit(&module, first, ir.Instruction{ op = .add, type = .int, destination = ir.ValueId(2), left = ir.ValueId(0), right = ir.ValueId(1) })
|
|
|
|
@@ -135,7 +137,7 @@ lazy_globals_follow_forward_dependencies_and_reset_between_runs test {
|
|
|
|
|
return_value(&module, second, ir.ValueId(0))
|
|
|
|
|
try arraylist.append(&module.globals, ir.Global{ type = .int, initializer = first, span = diagnostics.Span{ start = 0, end = 0 } })
|
|
|
|
|
try arraylist.append(&module.globals, ir.Global{ type = .int, initializer = second, span = diagnostics.Span{ start = 0, end = 0 } })
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int, 3)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .load_global, type = .int, destination = ir.ValueId(0), slot = 0 })
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .load_global, type = .int, destination = ir.ValueId(1), slot = 0 })
|
|
|
|
@@ -164,7 +166,7 @@ function_aliases_and_borrowed_string_values_execute test {
|
|
|
|
|
memcopy!(owned, text)
|
|
|
|
|
try arraylist.append(&module.strings, ir.StringStorage{ allocation = owned, len = text.len })
|
|
|
|
|
transferred = true
|
|
|
|
|
target :: try add_function(&module, &[], 0, .string, 1)
|
|
|
|
|
target :: try add_function(&module, &[], 0, .string)
|
|
|
|
|
try emit(&module, target, ir.Instruction{
|
|
|
|
|
op = .constant,
|
|
|
|
|
type = .string,
|
|
|
|
@@ -172,11 +174,11 @@ function_aliases_and_borrowed_string_values_execute test {
|
|
|
|
|
constant = ir.Value{ type = .string, data = ir.ValueData{ string = ir.StringId(0) } },
|
|
|
|
|
})
|
|
|
|
|
return_value(&module, target, ir.ValueId(0))
|
|
|
|
|
initializer :: try add_function(&module, &[], 0, .function, 1)
|
|
|
|
|
initializer :: try add_function(&module, &[], 0, .function)
|
|
|
|
|
try emit(&module, initializer, function_value(0, target))
|
|
|
|
|
return_value(&module, initializer, ir.ValueId(0))
|
|
|
|
|
try arraylist.append(&module.globals, ir.Global{ type = .function, initializer = initializer, span = diagnostics.Span{ start = 0, end = 0 } })
|
|
|
|
|
main :: try add_function(&module, &[], 0, .string, 2)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .string)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .load_global, type = .function, destination = ir.ValueId(0), slot = 0 })
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .call, type = .string, destination = ir.ValueId(1), left = ir.ValueId(0) })
|
|
|
|
@@ -195,7 +197,7 @@ premature_local_reads_and_global_cycles_report_instruction_spans test {
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
span :: diagnostics.Span{ start = 14, end = 19 }
|
|
|
|
|
types [1]ir.Type :: [.int]
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int, 1)
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .load_local, type = .int, destination = ir.ValueId(0), slot = 0, span = span })
|
|
|
|
|
return_value(&module, main, ir.ValueId(0))
|
|
|
|
@@ -203,8 +205,8 @@ premature_local_reads_and_global_cycles_report_instruction_spans test {
|
|
|
|
|
defer deinit(&premature)
|
|
|
|
|
try expect_trap(premature, &store, .read_before_initialization, span)
|
|
|
|
|
|
|
|
|
|
first :: try add_function(&module, &[], 0, .int, 1)
|
|
|
|
|
second :: try add_function(&module, &[], 0, .int, 1)
|
|
|
|
|
first :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
second :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
cycle_span :: diagnostics.Span{ start = 40, end = 44 }
|
|
|
|
|
try emit(&module, first, ir.Instruction{ op = .load_global, type = .int, destination = ir.ValueId(0), slot = 1 })
|
|
|
|
|
try emit(&module, second, ir.Instruction{ op = .load_global, type = .int, destination = ir.ValueId(0), slot = 0, span = cycle_span })
|
|
|
|
@@ -212,7 +214,10 @@ premature_local_reads_and_global_cycles_report_instruction_spans test {
|
|
|
|
|
return_value(&module, second, ir.ValueId(0))
|
|
|
|
|
try arraylist.append(&module.globals, ir.Global{ type = .int, initializer = first, span = diagnostics.Span{ start = 0, end = 0 } })
|
|
|
|
|
try arraylist.append(&module.globals, ir.Global{ type = .int, initializer = second, span = diagnostics.Span{ start = 0, end = 0 } })
|
|
|
|
|
module.functions.items[usize(main)].blocks.items[0].instructions.items[0] = ir.Instruction{ op = .load_global, type = .int, destination = ir.ValueId(0), slot = 0 }
|
|
|
|
|
cycle_main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
module.entry = cycle_main
|
|
|
|
|
try emit(&module, cycle_main, ir.Instruction{ op = .load_global, type = .int, destination = ir.ValueId(0), slot = 0 })
|
|
|
|
|
return_value(&module, cycle_main, ir.ValueId(0))
|
|
|
|
|
cycle := try run(mem.c_allocator, &module, &store)
|
|
|
|
|
defer deinit(&cycle)
|
|
|
|
|
try expect_trap(cycle, &store, .initialization_cycle, cycle_span)
|
|
|
|
@@ -232,9 +237,9 @@ existing_trap_identity_entry_failures_and_unused_errors_survive test {
|
|
|
|
|
defer deinit(&absent)
|
|
|
|
|
try testing.expect_equal(entry_id, absent.trap?)
|
|
|
|
|
invalid_id :: try diagnostics.add(&store, .unknown_name, diagnostics.Span{ start = 12, end = 17 })
|
|
|
|
|
bad :: try add_function(&module, &[], 0, .invalid, 0)
|
|
|
|
|
bad :: try add_function(&module, &[], 0, .invalid)
|
|
|
|
|
module.functions.items[usize(bad)].blocks.items[0].terminator = ir.Terminator{ kind = .trap, diagnostic = invalid_id }
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int, 2)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, integer(0, 42))
|
|
|
|
|
return_value(&module, main, ir.ValueId(0))
|
|
|
|
@@ -242,8 +247,11 @@ existing_trap_identity_entry_failures_and_unused_errors_survive test {
|
|
|
|
|
defer deinit(&success)
|
|
|
|
|
try testing.expect(success.trap == null)
|
|
|
|
|
try testing.expect_equal(i64(42), success.value.data.integer)
|
|
|
|
|
module.functions.items[usize(main)].blocks.items[0].instructions.items[0] = function_value(0, bad)
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .call, type = .invalid, destination = ir.ValueId(1), left = ir.ValueId(0) })
|
|
|
|
|
trap_main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
module.entry = trap_main
|
|
|
|
|
try emit(&module, trap_main, function_value(0, bad))
|
|
|
|
|
try emit(&module, trap_main, ir.Instruction{ op = .call, type = .invalid, destination = ir.ValueId(1), left = ir.ValueId(0) })
|
|
|
|
|
return_value(&module, trap_main, ir.ValueId(0))
|
|
|
|
|
trapped := try run(mem.c_allocator, &module, &store)
|
|
|
|
|
defer deinit(&trapped)
|
|
|
|
|
try testing.expect_equal(invalid_id, trapped.trap?)
|
|
|
|
@@ -286,7 +294,7 @@ integer_arithmetic_checks_boundaries_before_host_operations test {
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
span :: diagnostics.Span{ start = 8, end = 16 }
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int, 3)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, integer(0, case.left))
|
|
|
|
|
try emit(&module, main, integer(1, case.right))
|
|
|
|
@@ -309,7 +317,7 @@ integer_negation_traps_only_at_minimum test {
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
span :: diagnostics.Span{ start = 21, end = 27 }
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int, 2)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, integer(0, minval!(i64)))
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .negate, type = .int, destination = ir.ValueId(1), left = ir.ValueId(0), span = span })
|
|
|
|
@@ -329,7 +337,7 @@ float_arithmetic_and_ieee_zero_division_execute test {
|
|
|
|
|
defer ir.deinit(&module)
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .float, 7)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .float)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .constant, type = .float, destination = ir.ValueId(0), constant = ir.Value{ type = .float, data = ir.ValueData{ real = 10.5 } } })
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .constant, type = .float, destination = ir.ValueId(1), constant = ir.Value{ type = .float, data = ir.ValueData{ real = 2.0 } } })
|
|
|
|
@@ -413,7 +421,7 @@ recursive_invocations_use_heap_frames_and_free_on_allocation_failure test {
|
|
|
|
|
defer ir.deinit(&module)
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .void, 2)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .void)
|
|
|
|
|
module.entry = main
|
|
|
|
|
recursive_block :: try add_block(&module, main)
|
|
|
|
|
module.functions.items[usize(main)].blocks.items[0].terminator = ir.Terminator{ kind = .jump, target = recursive_block }
|
|
|
|
@@ -440,13 +448,13 @@ frames_and_globals_are_freed_at_every_allocation_boundary_and_trap test {
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
types [1]ir.Type :: [.int]
|
|
|
|
|
initializer :: try add_function(&module, types[..], 0, .int, 1)
|
|
|
|
|
initializer :: try add_function(&module, types[..], 0, .int)
|
|
|
|
|
init_block :: try add_block(&module, initializer)
|
|
|
|
|
module.functions.items[usize(initializer)].blocks.items[0].terminator = ir.Terminator{ kind = .jump, target = init_block }
|
|
|
|
|
try emit_at(&module, initializer, init_block, integer(0, 42))
|
|
|
|
|
module.functions.items[usize(initializer)].blocks.items[usize(init_block)].terminator = ir.Terminator{ value = ir.ValueId(0) }
|
|
|
|
|
try arraylist.append(&module.globals, ir.Global{ type = .int, initializer = initializer, span = diagnostics.Span{ start = 0, end = 0 } })
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int, 1)
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
work :: try add_block(&module, main)
|
|
|
|
|
module.functions.items[usize(main)].blocks.items[0].terminator = ir.Terminator{ kind = .jump, target = work }
|
|
|
|
@@ -490,7 +498,7 @@ runtime_diagnostic_allocation_failure_is_infrastructure_error_and_frees_frames t
|
|
|
|
|
module := ir.init(mem.c_allocator)
|
|
|
|
|
defer ir.deinit(&module)
|
|
|
|
|
types [1]ir.Type :: [.int]
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int, 1)
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .load_local, type = .int, destination = ir.ValueId(0), slot = 0 })
|
|
|
|
|
return_value(&module, main, ir.ValueId(0))
|
|
|
|
@@ -523,9 +531,8 @@ add_block proc(module @mut ir.Module, function ir.FunctionId) ir.BlockId ! mem.A
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@hide:file
|
|
|
|
|
emit_at proc(module @mut ir.Module, function ir.FunctionId, block ir.BlockId, instruction ir.Instruction) void ! mem.AllocError {
|
|
|
|
|
if (instruction.type == .address) module.functions.items[usize(function)].has_addresses = true
|
|
|
|
|
try arraylist.append(&module.functions.items[usize(function)].blocks.items[usize(block)].instructions, instruction)
|
|
|
|
|
emit_at proc(module @mut ir.Module, function ir.FunctionId, block ir.BlockId, instruction ir.Instruction) void ! (mem.AllocError | diagnostics.CapacityError) {
|
|
|
|
|
_ = try ir.emit(module, function, block, instruction)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
branching_recursive_calls_and_lazy_initializers_resume_the_current_block test {
|
|
|
|
@@ -534,7 +541,7 @@ branching_recursive_calls_and_lazy_initializers_resume_the_current_block test {
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
types [1]ir.Type :: [.int]
|
|
|
|
|
count :: try add_function(&module, types[..], 1, .int, 9)
|
|
|
|
|
count :: try add_function(&module, types[..], 1, .int)
|
|
|
|
|
done :: try add_block(&module, count)
|
|
|
|
|
recurse :: try add_block(&module, count)
|
|
|
|
|
try emit(&module, count, ir.Instruction{ op = .load_local, type = .int, destination = ir.ValueId(0), slot = 0 })
|
|
|
|
@@ -552,7 +559,7 @@ branching_recursive_calls_and_lazy_initializers_resume_the_current_block test {
|
|
|
|
|
try emit_at(&module, count, recurse, ir.Instruction{ op = .add, type = .int, destination = ir.ValueId(7), left = ir.ValueId(6), right = ir.ValueId(4) })
|
|
|
|
|
module.functions.items[usize(count)].blocks.items[usize(recurse)].terminator = ir.Terminator{ value = ir.ValueId(7) }
|
|
|
|
|
|
|
|
|
|
initializer :: try add_function(&module, &[], 0, .int, 3)
|
|
|
|
|
initializer :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
init_entry :: try add_block(&module, initializer)
|
|
|
|
|
init_exit :: try add_block(&module, initializer)
|
|
|
|
|
trap_id :: try diagnostics.add(&store, .invalid_escape, diagnostics.Span{ start = 0, end = 0 })
|
|
|
|
@@ -566,7 +573,7 @@ branching_recursive_calls_and_lazy_initializers_resume_the_current_block test {
|
|
|
|
|
module.functions.items[usize(initializer)].blocks.items[usize(init_exit)].terminator = ir.Terminator{ value = ir.ValueId(2) }
|
|
|
|
|
try arraylist.append(&module.globals, ir.Global{ type = .int, initializer = initializer, span = diagnostics.Span{ start = 0, end = 0 } })
|
|
|
|
|
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int, 5)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
main_entry :: try add_block(&module, main)
|
|
|
|
|
main_exit :: try add_block(&module, main)
|
|
|
|
|
module.entry = main
|
|
|
|
@@ -611,7 +618,7 @@ all_numeric_comparisons_dispatch_on_operand_type_not_bool_result_type test {
|
|
|
|
|
defer ir.deinit(&module)
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .bool, 3)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .bool)
|
|
|
|
|
module.entry = main
|
|
|
|
|
left_value := ir.Value{ type = type, data = ir.ValueData{ integer = left } }
|
|
|
|
|
right_value := ir.Value{ type = type, data = ir.ValueData{ integer = right } }
|
|
|
|
@@ -650,7 +657,7 @@ nan_comparisons_obey_ieee_rules_in_either_operand_position test {
|
|
|
|
|
defer ir.deinit(&module)
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .bool, 3)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .bool)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, ir.Instruction{
|
|
|
|
|
op = .constant, type = .float, destination = ir.ValueId(0),
|
|
|
|
@@ -680,7 +687,7 @@ boolean_equality_and_branching_use_boolean_payloads test {
|
|
|
|
|
defer ir.deinit(&module)
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int, 5)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
yes :: try add_block(&module, main)
|
|
|
|
|
no :: try add_block(&module, main)
|
|
|
|
@@ -710,7 +717,7 @@ assign_local_replaces_initialized_values_without_producing_a_result test {
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
types [1]ir.Type :: [.int]
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int, 3)
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, integer(0, 1))
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .store_local, slot = 0, left = ir.ValueId(0) })
|
|
|
|
@@ -735,7 +742,7 @@ reset_local_invalidates_reads_and_assignments_at_the_instruction_span test {
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
types [1]ir.Type :: [.int]
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int, 2)
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
span :: diagnostics.Span{ start = 21, end = 26 }
|
|
|
|
|
try emit(&module, main, integer(0, 42))
|
|
|
|
@@ -758,7 +765,7 @@ premature_assignment_and_reset_traps_release_frames_at_all_allocation_boundaries
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
types [1]ir.Type :: [.int]
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int, 1)
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
span :: diagnostics.Span{ start = 14, end = 19 }
|
|
|
|
|
try emit(&module, main, integer(0, 42))
|
|
|
|
@@ -793,7 +800,7 @@ assignment_diagnostic_allocation_failure_releases_runtime_storage test {
|
|
|
|
|
module := ir.init(mem.c_allocator)
|
|
|
|
|
defer ir.deinit(&module)
|
|
|
|
|
types [1]ir.Type :: [.int]
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int, 1)
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, integer(0, 42))
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .assign_local, slot = 0, left = ir.ValueId(0) })
|
|
|
|
@@ -825,7 +832,7 @@ logical_not_inverts_boolean_payload_and_composes_in_typed_ir test {
|
|
|
|
|
defer ir.deinit(&module)
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .bool, 3)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .bool)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, ir.Instruction{
|
|
|
|
|
op = .constant,
|
|
|
|
@@ -859,27 +866,12 @@ unsigned proc(destination u32, value u64) ir.Instruction {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@hide:file
|
|
|
|
|
add_array proc(module @mut ir.Module, element ir.Type, child ir.ArrayId, len usize) ir.ArrayId ! mem.AllocError {
|
|
|
|
|
width :: if (element == .array) module.arrays.items[usize(child)].cells else 1
|
|
|
|
|
id :: ir.ArrayId(module.arrays.items.len)
|
|
|
|
|
try arraylist.append(&module.arrays, ir.ArrayType{
|
|
|
|
|
element = element, element_array = child, len = len, cells = len * width, mutable = true,
|
|
|
|
|
})
|
|
|
|
|
return id
|
|
|
|
|
add_array proc(module @mut ir.Module, element ir.Type, child ir.ArrayId, len usize) ir.ArrayId ! (mem.AllocError | diagnostics.CapacityError) {
|
|
|
|
|
return try ir.add_array(module, element, child, len, true)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@hide:file
|
|
|
|
|
array_storage proc(module @mut ir.Module, function ir.FunctionId, index u32, shape ir.ArrayId, local bool) void ! mem.AllocError {
|
|
|
|
|
body :: &module.functions.items[usize(function)]
|
|
|
|
|
try arraylist.append(&body.array_storage, ir.ArrayStorage{
|
|
|
|
|
index = index, array_type = shape, offset = body.aggregate_cells, local = local,
|
|
|
|
|
})
|
|
|
|
|
body.aggregate_cells += module.arrays.items[usize(shape)].cells
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@hide:file
|
|
|
|
|
literal proc(module @mut ir.Module, function ir.FunctionId, destination u32, shape ir.ArrayId, elements []u32) void ! mem.AllocError {
|
|
|
|
|
try array_storage(module, function, destination, shape, false)
|
|
|
|
|
literal proc(module @mut ir.Module, function ir.FunctionId, destination u32, shape ir.ArrayId, elements []u32) void ! (mem.AllocError | diagnostics.CapacityError) {
|
|
|
|
|
block :: &module.functions.items[usize(function)].blocks.items[0]
|
|
|
|
|
start :: block.arguments.items.len
|
|
|
|
|
for (elements) |element| try arraylist.append(&block.arguments, ir.ValueId(element))
|
|
|
|
@@ -896,12 +888,12 @@ nested_array_places_and_rvalues_copy_only_their_typed_leaf_segments test {
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
row :: try add_array(&module, .int, ir.no_array, 2)
|
|
|
|
|
matrix :: try add_array(&module, .array, row, 2)
|
|
|
|
|
types [2]ir.Type :: [.array, .array]
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .array, 15)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .array)
|
|
|
|
|
_ = try ir.add_local(&module, main, .array, matrix)
|
|
|
|
|
_ = try ir.add_local(&module, main, .array, matrix)
|
|
|
|
|
module.entry = main
|
|
|
|
|
module.functions.items[usize(main)].result_array_type = matrix
|
|
|
|
|
try array_storage(&module, main, 0, matrix, true)
|
|
|
|
|
try array_storage(&module, main, 1, matrix, true)
|
|
|
|
|
|
|
|
|
|
try emit(&module, main, integer(0, 1))
|
|
|
|
|
try emit(&module, main, integer(1, 2))
|
|
|
|
|
pair [2]u32 :: [0, 1]
|
|
|
|
@@ -909,14 +901,14 @@ nested_array_places_and_rvalues_copy_only_their_typed_leaf_segments test {
|
|
|
|
|
rows [2]u32 :: [2, 2]
|
|
|
|
|
try literal(&module, main, 3, matrix, rows[..])
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .store_local, slot = 0, left = ir.ValueId(3) })
|
|
|
|
|
try array_storage(&module, main, 4, matrix, false)
|
|
|
|
|
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .load_local, type = .array, array_type = matrix, destination = ir.ValueId(4), slot = 0 })
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .store_local, slot = 1, left = ir.ValueId(4) })
|
|
|
|
|
try emit(&module, main, unsigned(5, 0))
|
|
|
|
|
try emit(&module, main, unsigned(6, 1))
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .address_local, type = .address, pointee = .array, array_type = matrix, destination = ir.ValueId(7), slot = 0 })
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .index_address, type = .address, pointee = .array, array_type = row, destination = ir.ValueId(8), left = ir.ValueId(7), right = ir.ValueId(5) })
|
|
|
|
|
try array_storage(&module, main, 9, row, false)
|
|
|
|
|
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .load_address, type = .array, array_type = row, destination = ir.ValueId(9), left = ir.ValueId(8) })
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .index_address, type = .address, pointee = .int, destination = ir.ValueId(10), left = ir.ValueId(8), right = ir.ValueId(6) })
|
|
|
|
|
try emit(&module, main, integer(11, 9))
|
|
|
|
@@ -926,12 +918,12 @@ nested_array_places_and_rvalues_copy_only_their_typed_leaf_segments test {
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .store_address, left = ir.ValueId(10), right = ir.ValueId(11) })
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .index_address, type = .address, pointee = .array, array_type = row, destination = ir.ValueId(8), left = ir.ValueId(7), right = ir.ValueId(6) })
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .store_address, left = ir.ValueId(8), right = ir.ValueId(9) })
|
|
|
|
|
try array_storage(&module, main, 12, matrix, false)
|
|
|
|
|
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .load_local, type = .array, array_type = matrix, destination = ir.ValueId(12), slot = 0 })
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .assign_local, slot = 1, left = ir.ValueId(12) })
|
|
|
|
|
try emit(&module, main, integer(13, 7))
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .store_address, left = ir.ValueId(10), right = ir.ValueId(13) })
|
|
|
|
|
try array_storage(&module, main, 14, matrix, false)
|
|
|
|
|
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .load_local, type = .array, array_type = matrix, destination = ir.ValueId(14), slot = 1 })
|
|
|
|
|
return_value(&module, main, ir.ValueId(14))
|
|
|
|
|
outcome := try run(mem.c_allocator, &module, &store)
|
|
|
|
@@ -949,13 +941,11 @@ array_arguments_and_returns_are_private_values_before_frame_release test {
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
shape :: try add_array(&module, .int, ir.no_array, 1)
|
|
|
|
|
pair_shape :: try add_array(&module, .int, ir.no_array, 2)
|
|
|
|
|
types [2]ir.Type :: [.array, .array]
|
|
|
|
|
callee :: try add_function(&module, types[..], 1, .array, 6)
|
|
|
|
|
callee :: try add_function(&module, &[], 0, .array)
|
|
|
|
|
_ = try ir.add_parameter(&module, callee, .array, shape)
|
|
|
|
|
_ = try ir.add_local(&module, callee, .array, shape)
|
|
|
|
|
module.functions.items[usize(callee)].result_array_type = shape
|
|
|
|
|
try array_storage(&module, callee, 0, shape, true)
|
|
|
|
|
try array_storage(&module, callee, 1, shape, true)
|
|
|
|
|
try array_storage(&module, callee, 0, shape, false)
|
|
|
|
|
try array_storage(&module, callee, 5, shape, false)
|
|
|
|
|
|
|
|
|
|
try emit(&module, callee, ir.Instruction{ op = .load_local, type = .array, array_type = shape, destination = ir.ValueId(0), slot = 0 })
|
|
|
|
|
try emit(&module, callee, ir.Instruction{ op = .store_local, left = ir.ValueId(0), slot = 1 })
|
|
|
|
|
try emit(&module, callee, ir.Instruction{ op = .address_local, type = .address, pointee = .array, array_type = shape, destination = ir.ValueId(1), slot = 1 })
|
|
|
|
@@ -970,14 +960,14 @@ array_arguments_and_returns_are_private_values_before_frame_release test {
|
|
|
|
|
try emit(&module, callee, integer(4, 7))
|
|
|
|
|
try emit(&module, callee, ir.Instruction{ op = .store_address, left = ir.ValueId(3), right = ir.ValueId(4) })
|
|
|
|
|
return_value(&module, callee, ir.ValueId(5))
|
|
|
|
|
main :: try add_function(&module, &[], 0, .array, 8)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .array)
|
|
|
|
|
module.entry = main
|
|
|
|
|
module.functions.items[usize(main)].result_array_type = pair_shape
|
|
|
|
|
try emit(&module, main, integer(0, 42))
|
|
|
|
|
element [1]u32 :: [0]
|
|
|
|
|
try literal(&module, main, 1, shape, element[..])
|
|
|
|
|
try emit(&module, main, function_value(2, callee))
|
|
|
|
|
try array_storage(&module, main, 3, shape, false)
|
|
|
|
|
|
|
|
|
|
try arraylist.append(&module.functions.items[usize(main)].blocks.items[0].arguments, ir.ValueId(1))
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .call, type = .array, array_type = shape, destination = ir.ValueId(3), left = ir.ValueId(2), arguments_start = 1, arguments_count = 1 })
|
|
|
|
|
try emit(&module, main, unsigned(4, 0))
|
|
|
|
@@ -999,11 +989,11 @@ lazy_aggregate_globals_escape_with_owned_results_and_release_at_every_boundary t
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
shape :: try add_array(&module, .int, ir.no_array, 1)
|
|
|
|
|
first :: try add_function(&module, &[], 0, .array, 1)
|
|
|
|
|
second :: try add_function(&module, &[], 0, .array, 2)
|
|
|
|
|
first :: try add_function(&module, &[], 0, .array)
|
|
|
|
|
second :: try add_function(&module, &[], 0, .array)
|
|
|
|
|
module.functions.items[usize(first)].result_array_type = shape
|
|
|
|
|
module.functions.items[usize(second)].result_array_type = shape
|
|
|
|
|
try array_storage(&module, first, 0, shape, false)
|
|
|
|
|
|
|
|
|
|
try emit(&module, first, ir.Instruction{ op = .load_global, type = .array, array_type = shape, destination = ir.ValueId(0), slot = 1 })
|
|
|
|
|
return_value(&module, first, ir.ValueId(0))
|
|
|
|
|
try emit(&module, second, integer(0, 42))
|
|
|
|
@@ -1017,11 +1007,11 @@ lazy_aggregate_globals_escape_with_owned_results_and_release_at_every_boundary t
|
|
|
|
|
span = diagnostics.Span{ start = 0, end = 0 },
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
main :: try add_function(&module, &[], 0, .array, 2)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .array)
|
|
|
|
|
module.entry = main
|
|
|
|
|
module.functions.items[usize(main)].result_array_type = shape
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .address_global, type = .address, pointee = .array, array_type = shape, destination = ir.ValueId(0), slot = 0 })
|
|
|
|
|
try array_storage(&module, main, 1, shape, false)
|
|
|
|
|
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .load_address, type = .array, array_type = shape, destination = ir.ValueId(1), left = ir.ValueId(0) })
|
|
|
|
|
return_value(&module, main, ir.ValueId(1))
|
|
|
|
|
succeeded := false
|
|
|
|
@@ -1049,11 +1039,18 @@ lazy_aggregate_globals_escape_with_owned_results_and_release_at_every_boundary t
|
|
|
|
|
try testing.expect(failures > 0)
|
|
|
|
|
# restarting a run clears global readiness, including address-triggered initialization cycles.
|
|
|
|
|
cycle_span :: diagnostics.Span{ start = 51, end = 59 }
|
|
|
|
|
module.functions.items[usize(second)].has_addresses = true
|
|
|
|
|
module.functions.items[usize(second)].blocks.items[0].instructions.items[0] = ir.Instruction{
|
|
|
|
|
cycle_initializer :: try add_function(&module, &[], 0, .array)
|
|
|
|
|
module.functions.items[usize(cycle_initializer)].result_array_type = shape
|
|
|
|
|
try emit(&module, cycle_initializer, ir.Instruction{
|
|
|
|
|
op = .address_global, type = .address, pointee = .array, array_type = shape,
|
|
|
|
|
destination = ir.ValueId(0), slot = 0, span = cycle_span,
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
try emit(&module, cycle_initializer, ir.Instruction{
|
|
|
|
|
op = .load_address, type = .array, array_type = shape,
|
|
|
|
|
destination = ir.ValueId(1), left = ir.ValueId(0),
|
|
|
|
|
})
|
|
|
|
|
return_value(&module, cycle_initializer, ir.ValueId(1))
|
|
|
|
|
module.globals.items[1].initializer = cycle_initializer
|
|
|
|
|
state := AllocationState{ remaining = 64 }
|
|
|
|
|
allocator :: mem.Allocator{ context = &state, vtable = &limited_vtable }
|
|
|
|
|
cycle := try run(allocator, &module, &store)
|
|
|
|
@@ -1063,7 +1060,7 @@ lazy_aggregate_globals_escape_with_owned_results_and_release_at_every_boundary t
|
|
|
|
|
try testing.expect_equal(usize(0), state.live)
|
|
|
|
|
trap_id :: try diagnostics.add(&store, .invalid_escape, cycle_span)
|
|
|
|
|
module.functions.items[usize(second)].blocks.items[0].terminator = ir.Terminator{ kind = .trap, diagnostic = trap_id }
|
|
|
|
|
module.functions.items[usize(second)].blocks.items[0].instructions.items[0] = integer(0, 42)
|
|
|
|
|
module.globals.items[1].initializer = second
|
|
|
|
|
trapped := try run(allocator, &module, &store)
|
|
|
|
|
defer deinit(&trapped)
|
|
|
|
|
try testing.expect_equal(trap_id, trapped.trap?)
|
|
|
|
@@ -1083,10 +1080,10 @@ array_bounds_check_zero_lengths_and_the_full_unsigned_word_before_addressing tes
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
shape :: try add_array(&module, .int, ir.no_array, length)
|
|
|
|
|
types [1]ir.Type :: [.array]
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int, 5)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
_ = try ir.add_local(&module, main, .array, shape)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try array_storage(&module, main, 0, shape, true)
|
|
|
|
|
|
|
|
|
|
try emit(&module, main, integer(0, 42))
|
|
|
|
|
operands [1]u32 :: [0]
|
|
|
|
|
try literal(&module, main, 1, shape, operands[..length])
|
|
|
|
@@ -1129,7 +1126,7 @@ zero_leaf_nested_arrays_return_a_shape_without_an_owned_allocation test {
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
empty :: try add_array(&module, .bool, ir.no_array, 0)
|
|
|
|
|
rows :: try add_array(&module, .array, empty, 3)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .array, 4)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .array)
|
|
|
|
|
module.entry = main
|
|
|
|
|
module.functions.items[usize(main)].result_array_type = rows
|
|
|
|
|
try literal(&module, main, 0, empty, &[])
|
|
|
|
@@ -1148,7 +1145,7 @@ zero_leaf_nested_arrays_return_a_shape_without_an_owned_allocation test {
|
|
|
|
|
deinit(&outcome)
|
|
|
|
|
try testing.expect_equal(usize(0), state.live)
|
|
|
|
|
try emit(&module, main, unsigned(2, 2))
|
|
|
|
|
try array_storage(&module, main, 3, empty, false)
|
|
|
|
|
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .index, type = .array, array_type = empty, destination = ir.ValueId(3), left = ir.ValueId(1), right = ir.ValueId(2) })
|
|
|
|
|
return_value(&module, main, ir.ValueId(3))
|
|
|
|
|
module.functions.items[usize(main)].result_array_type = empty
|
|
|
|
@@ -1189,7 +1186,7 @@ unsigned_arithmetic_and_comparisons_preserve_all_sixty_four_bits test {
|
|
|
|
|
defer ir.deinit(&module)
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .usize, 3)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .usize)
|
|
|
|
|
module.entry = main
|
|
|
|
|
span :: diagnostics.Span{ start = 7, end = 12 }
|
|
|
|
|
try emit(&module, main, unsigned(0, case.left))
|
|
|
|
@@ -1211,7 +1208,7 @@ unsigned_arithmetic_and_comparisons_preserve_all_sixty_four_bits test {
|
|
|
|
|
defer ir.deinit(&module)
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .bool, 3)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .bool)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, unsigned(0, maxval!(u64)))
|
|
|
|
|
try emit(&module, main, unsigned(1, 1))
|
|
|
|
@@ -1244,11 +1241,11 @@ all_scalar_leaf_families_survive_aggregate_return_and_function_extraction test {
|
|
|
|
|
}
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
target :: try add_function(&module, &[], 0, .int, 1)
|
|
|
|
|
target :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
try emit(&module, target, integer(0, 42))
|
|
|
|
|
return_value(&module, target, ir.ValueId(0))
|
|
|
|
|
shape :: try add_array(&module, scalar.type, ir.no_array, 1)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .array, 5)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .array)
|
|
|
|
|
module.entry = main
|
|
|
|
|
module.functions.items[usize(main)].result_array_type = shape
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .constant, type = scalar.type, destination = ir.ValueId(0), constant = scalar })
|
|
|
|
@@ -1288,10 +1285,10 @@ array_address_initialization_flags_survive_reset_and_diagnostic_allocation_failu
|
|
|
|
|
module := ir.init(mem.c_allocator)
|
|
|
|
|
defer ir.deinit(&module)
|
|
|
|
|
shape :: try add_array(&module, .int, ir.no_array, 1)
|
|
|
|
|
types [1]ir.Type :: [.array]
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int, 5)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
_ = try ir.add_local(&module, main, .array, shape)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try array_storage(&module, main, 0, shape, true)
|
|
|
|
|
|
|
|
|
|
try emit(&module, main, integer(0, 42))
|
|
|
|
|
operand [1]u32 :: [0]
|
|
|
|
|
try literal(&module, main, 1, shape, operand[..])
|
|
|
|
@@ -1301,7 +1298,8 @@ array_address_initialization_flags_survive_reset_and_diagnostic_allocation_failu
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .index_address, type = .address, pointee = .int, destination = ir.ValueId(4), left = ir.ValueId(2), right = ir.ValueId(3) })
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .reset_local, slot = 0 })
|
|
|
|
|
span :: diagnostics.Span{ start = 23, end = 37 }
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = op, type = .int, destination = ir.ValueId(0), left = ir.ValueId(4), right = ir.ValueId(0), span = span })
|
|
|
|
|
destination :: if (op == .load_address) ir.ValueId(0) else ir.no_value
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = op, type = .int, destination = destination, left = ir.ValueId(4), right = ir.ValueId(0), span = span })
|
|
|
|
|
for (usize(0)..usize(2)) |attempt| {
|
|
|
|
|
state := AllocationState{ remaining = 64 }
|
|
|
|
|
allocator :: mem.Allocator{ context = &state, vtable = &limited_vtable }
|
|
|
|
@@ -1332,10 +1330,11 @@ aggregate_loop_places_reuse_storage_without_allocation_per_iteration test {
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
shape :: try add_array(&module, .int, ir.no_array, 1)
|
|
|
|
|
types [2]ir.Type :: [.array, .usize]
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .int, 14)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
_ = try ir.add_local(&module, main, .array, shape)
|
|
|
|
|
_ = try ir.add_local(&module, main, .usize, ir.no_array)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try array_storage(&module, main, 0, shape, true)
|
|
|
|
|
|
|
|
|
|
try emit(&module, main, integer(0, 0))
|
|
|
|
|
operand [1]u32 :: [0]
|
|
|
|
|
try literal(&module, main, 1, shape, operand[..])
|
|
|
|
@@ -1389,9 +1388,10 @@ recursive_array_backings_and_addresses_remain_fresh_across_stack_growth test {
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
shape :: try add_array(&module, .int, ir.no_array, 1)
|
|
|
|
|
types [2]ir.Type :: [.int, .array]
|
|
|
|
|
recursive :: try add_function(&module, types[..], 1, .int, 12)
|
|
|
|
|
try array_storage(&module, recursive, 1, shape, true)
|
|
|
|
|
recursive :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
_ = try ir.add_parameter(&module, recursive, .int, ir.no_array)
|
|
|
|
|
_ = try ir.add_local(&module, recursive, .array, shape)
|
|
|
|
|
|
|
|
|
|
try emit(&module, recursive, ir.Instruction{ op = .load_local, type = .int, destination = ir.ValueId(0), slot = 0 })
|
|
|
|
|
operand [1]u32 :: [0]
|
|
|
|
|
try literal(&module, recursive, 1, shape, operand[..])
|
|
|
|
@@ -1413,7 +1413,7 @@ recursive_array_backings_and_addresses_remain_fresh_across_stack_growth test {
|
|
|
|
|
try emit_at(&module, recursive, recurse, ir.Instruction{ op = .load_address, type = .int, destination = ir.ValueId(10), left = ir.ValueId(4) })
|
|
|
|
|
try emit_at(&module, recursive, recurse, ir.Instruction{ op = .add, type = .int, destination = ir.ValueId(11), left = ir.ValueId(9), right = ir.ValueId(10) })
|
|
|
|
|
module.functions.items[usize(recursive)].blocks.items[usize(recurse)].terminator = ir.Terminator{ value = ir.ValueId(11) }
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int, 3)
|
|
|
|
|
main :: try add_function(&module, &[], 0, .int)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, function_value(0, recursive))
|
|
|
|
|
try emit(&module, main, integer(1, 64))
|
|
|
|
@@ -1432,7 +1432,7 @@ inclusive_unsigned_range_reaches_the_maximum_without_incrementing_past_it test {
|
|
|
|
|
store := diagnostics.init(mem.c_allocator)
|
|
|
|
|
defer diagnostics.deinit(&store)
|
|
|
|
|
types [2]ir.Type :: [.usize, .usize]
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .usize, 9)
|
|
|
|
|
main :: try add_function(&module, types[..], 0, .usize)
|
|
|
|
|
module.entry = main
|
|
|
|
|
try emit(&module, main, unsigned(0, maxval!(u64) - 1))
|
|
|
|
|
try emit(&module, main, ir.Instruction{ op = .store_local, slot = 0, left = ir.ValueId(0) })
|
|
|
|
|