allocation related primitives
This commit is contained in:
+13
-3
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user