Files

62 lines
2.9 KiB
Plaintext

import "@std/mem"
import "@std/arraylist"
import "@std/testing"
shape_and_segment_limits_preserve_zero_leaf_arrays_and_allow_retry test {
module := init(mem.c_allocator)
defer deinit(&module)
limit :: divtrunc!(maxval!(usize), sizeof!(Value))
rejected := false
_ = add_array(&module, .int, no_array, limit + 1, false) catch |error| {
rejected = error == .storage_limit_reached
yield no_array
}
try testing.expect(rejected)
pair :: try add_array(&module, .int, no_array, 2, false)
rejected = false
_ = add_array(&module, .array, pair, maxval!(usize), false) catch |error| {
rejected = error == .storage_limit_reached
yield no_array
}
try testing.expect(rejected)
full :: try add_array(&module, .int, no_array, limit - 2, false)
empty :: try add_array(&module, .bool, no_array, 0, false)
zero_rows :: try add_array(&module, .array, empty, maxval!(usize), false)
try arraylist.append(&module.functions, init_function(module.allocator))
function :: FunctionId(0)
try arraylist.append(&module.functions.items[0].blocks, init_block(module.allocator))
try testing.expect_equal(LocalId(0), try add_parameter(&module, function, .array, full))
element :: try emit(&module, function, BlockId(0), Instruction{
op = .constant, type = .int, constant = Value{ type = .int, data = ValueData{ integer = 42 } },
})
try arraylist.append(&module.functions.items[0].blocks.items[0].arguments, element)
try arraylist.append(&module.functions.items[0].blocks.items[0].arguments, element)
result :: try emit(&module, function, BlockId(0), Instruction{
op = .array_literal, type = .array, array_type = pair, arguments_count = 2,
})
# redefining an array result reuses backing even when no further cells fit.
_ = try emit(&module, function, BlockId(0), Instruction{
op = .array_literal, type = .array, array_type = pair, arguments_count = 2, destination = result,
})
rejected = false
_ = add_parameter(&module, function, .array, pair) catch |error| {
rejected = error == .storage_limit_reached
yield LocalId(0)
}
try testing.expect(rejected)
# a rejected parameter consumes neither a parameter/local identity nor aggregate storage.
try testing.expect_equal(LocalId(1), try add_parameter(&module, function, .array, zero_rows))
rejected = false
_ = emit(&module, function, BlockId(0), Instruction{
op = .array_literal, type = .array, array_type = pair, arguments_count = 2,
}) catch |error| {
rejected = error == .storage_limit_reached
yield no_value
}
try testing.expect(rejected)
# a rejected result consumes no temporary; zero-leaf shapes still fit a full segment layout.
try testing.expect_equal(ValueId(2), try emit(&module, function, BlockId(0), Instruction{
op = .load_local, type = .array, array_type = zero_rows, slot = 1,
}))
}