allocation related primitives

This commit is contained in:
2026-07-08 20:29:25 +02:00
parent 5e18df9bc1
commit 2cda024614
11 changed files with 617 additions and 98 deletions
+13 -3
View File
@@ -1114,7 +1114,7 @@ emit_instruction_stream :: proc(
}
container := instructions[instruction.a]
item, ok := types.container(container.type, &emitter.module.types)
if !ok || (item.kind != .Array && item.kind != .Slice) {
if !ok || (item.kind != .Array && item.kind != .Slice && item.kind != .Pointer) {
emit_recovery_value(emitter, instruction_index, instruction, "invalid slice container")
continue
}
@@ -1132,6 +1132,12 @@ emit_instruction_stream :: proc(
fmt.sbprintf(&emitter.builder, " %%slice_len%d = extractvalue %s %%v%d, 1\n", instruction_index, llvm_type(container.type, &emitter.module.types), instruction.a)
pointer_name = fmt.tprintf("%%slice_ptr%d", instruction_index)
length_name = fmt.tprintf("%%slice_len%d", instruction_index)
} else if item.kind == .Pointer {
if len(instruction.args) <= 1 || instruction.args[1] == ir.INVALID_INSTRUCTION {
emit_recovery_value(emitter, instruction_index, instruction, "invalid many-item pointer slice")
continue
}
length_name = "0"
}
fmt.sbprintf(&emitter.builder, " %%slice_bound_start%d = add i64 0, ", instruction_index)
if len(instruction.args) > 0 && instruction.args[0] != ir.INVALID_INSTRUCTION {
@@ -1150,8 +1156,12 @@ emit_instruction_stream :: proc(
start_name := fmt.tprintf("%%slice_bound_start%d", instruction_index)
end_name := fmt.tprintf("%%slice_bound_end%d", instruction_index)
fmt.sbprintf(&emitter.builder, " %%slice_order%d = icmp ule i64 %s, %s\n", instruction_index, start_name, end_name)
fmt.sbprintf(&emitter.builder, " %%slice_end_ok%d = icmp ule i64 %s, %s\n", instruction_index, end_name, length_name)
fmt.sbprintf(&emitter.builder, " %%slice_ok%d = and i1 %%slice_order%d, %%slice_end_ok%d\n", instruction_index, instruction_index, instruction_index)
if item.kind == .Pointer {
fmt.sbprintf(&emitter.builder, " %%slice_ok%d = or i1 false, %%slice_order%d\n", instruction_index, instruction_index)
} else {
fmt.sbprintf(&emitter.builder, " %%slice_end_ok%d = icmp ule i64 %s, %s\n", instruction_index, end_name, length_name)
fmt.sbprintf(&emitter.builder, " %%slice_ok%d = and i1 %%slice_order%d, %%slice_end_ok%d\n", instruction_index, instruction_index, instruction_index)
}
fmt.sbprintf(&emitter.builder, " br i1 %%slice_ok%d, label %%slice_continue%d, label %%slice_trap%d\nslice_trap%d:\n", instruction_index, instruction_index, instruction_index, instruction_index)
message := diagnostic_message(emitter, source.INVALID_DIAGNOSTIC, instruction.span, "slice bounds out of range")
emit_trap_call(emitter, message)