Skip to content

Commit 99c6840

Browse files
authored
Merge pull request #17 from jmecom/jm/more-examples
Jm/more examples
2 parents b899288 + 87070de commit 99c6840

4 files changed

Lines changed: 1206 additions & 1169 deletions

File tree

‎capc/src/codegen/emit.rs‎

Lines changed: 81 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ use super::{
2121
use super::layout::{align_to, resolve_struct_layout, type_layout_for_abi};
2222
use super::sig_to_clif;
2323

24+
#[derive(Copy, Clone, Debug)]
25+
struct ResultStringSlots {
26+
slot_ptr: ir::StackSlot,
27+
slot_len: ir::StackSlot,
28+
slot_err: ir::StackSlot,
29+
ptr_align: u32,
30+
len_align: u32,
31+
err_align: u32,
32+
}
33+
2434

2535
/// Emit a single HIR statement.
2636
pub(super) fn emit_hir_stmt(
@@ -607,39 +617,15 @@ fn emit_hir_expr_inner(
607617
}
608618

609619
// Handle result out-parameters (same logic as AST version)
610-
let mut out_slots = None;
620+
let mut out_slots: Option<ResultStringSlots> = None;
611621
let mut result_out = None;
612622
let abi_sig = info.abi_sig.as_ref().unwrap_or(&info.sig);
613623

614624
if abi_sig.ret == AbiType::ResultString {
615625
let ptr_ty = module.isa().pointer_type();
616-
let ptr_align = ptr_ty.bytes() as u32;
617-
let len_bytes = result_string_len_bytes();
618-
let len_align = len_bytes;
619-
let err_align = 4u32;
620-
621-
let slot_ptr = builder.create_sized_stack_slot(ir::StackSlotData::new(
622-
ir::StackSlotKind::ExplicitSlot,
623-
aligned_slot_size(ptr_ty.bytes() as u32, ptr_align),
624-
));
625-
let slot_len = builder.create_sized_stack_slot(ir::StackSlotData::new(
626-
ir::StackSlotKind::ExplicitSlot,
627-
aligned_slot_size(len_bytes, len_align),
628-
));
629-
let slot_err = builder.create_sized_stack_slot(ir::StackSlotData::new(
630-
ir::StackSlotKind::ExplicitSlot,
631-
aligned_slot_size(4, err_align),
632-
));
633-
634-
let ptr_ptr = aligned_stack_addr(builder, slot_ptr, ptr_align, ptr_ty);
635-
let len_ptr = aligned_stack_addr(builder, slot_len, len_align, ptr_ty);
636-
let err_ptr = aligned_stack_addr(builder, slot_err, err_align, ptr_ty);
637-
638-
args.push(ptr_ptr);
639-
args.push(len_ptr);
640-
args.push(err_ptr);
641-
642-
out_slots = Some((slot_ptr, slot_len, slot_err));
626+
let slots = result_string_slots(builder, ptr_ty);
627+
push_result_string_out_params(builder, ptr_ty, &slots, &mut args);
628+
out_slots = Some(slots);
643629
}
644630

645631
if let AbiType::ResultOut(ok_ty, err_ty) = &abi_sig.ret {
@@ -698,25 +684,10 @@ fn emit_hir_expr_inner(
698684
let tag = results
699685
.get(0)
700686
.ok_or_else(|| CodegenError::Codegen("missing result tag".to_string()))?;
701-
let (slot_ptr, slot_len, slot_err) =
687+
let slots =
702688
out_slots.ok_or_else(|| CodegenError::Codegen("missing slots".to_string()))?;
703689
let ptr_ty = module.isa().pointer_type();
704-
let ptr_align = ptr_ty.bytes() as u32;
705-
let len_align = result_string_len_bytes();
706-
let err_align = 4u32;
707-
let ptr_addr = aligned_stack_addr(builder, slot_ptr, ptr_align, ptr_ty);
708-
let len_addr = aligned_stack_addr(builder, slot_len, len_align, ptr_ty);
709-
let err_addr = aligned_stack_addr(builder, slot_err, err_align, ptr_ty);
710-
let ptr =
711-
builder
712-
.ins()
713-
.load(module.isa().pointer_type(), MemFlags::new(), ptr_addr, 0);
714-
let len = builder
715-
.ins()
716-
.load(ir::types::I64, MemFlags::new(), len_addr, 0);
717-
let err = builder
718-
.ins()
719-
.load(ir::types::I32, MemFlags::new(), err_addr, 0);
690+
let (ptr, len, err) = read_result_string_slots(builder, ptr_ty, &slots);
720691
match &info.sig.ret {
721692
AbiType::Result(ok_ty, err_ty) => {
722693
if **ok_ty != AbiType::String || **err_ty != AbiType::I32 {
@@ -1495,6 +1466,65 @@ fn result_string_len_bytes() -> u32 {
14951466
8
14961467
}
14971468

1469+
fn result_string_slots(builder: &mut FunctionBuilder, ptr_ty: Type) -> ResultStringSlots {
1470+
let ptr_align = ptr_ty.bytes() as u32;
1471+
let len_bytes = result_string_len_bytes();
1472+
let len_align = len_bytes;
1473+
let err_align = 4u32;
1474+
let slot_ptr = builder.create_sized_stack_slot(ir::StackSlotData::new(
1475+
ir::StackSlotKind::ExplicitSlot,
1476+
aligned_slot_size(ptr_ty.bytes() as u32, ptr_align),
1477+
));
1478+
let slot_len = builder.create_sized_stack_slot(ir::StackSlotData::new(
1479+
ir::StackSlotKind::ExplicitSlot,
1480+
aligned_slot_size(len_bytes, len_align),
1481+
));
1482+
let slot_err = builder.create_sized_stack_slot(ir::StackSlotData::new(
1483+
ir::StackSlotKind::ExplicitSlot,
1484+
aligned_slot_size(4, err_align),
1485+
));
1486+
ResultStringSlots {
1487+
slot_ptr,
1488+
slot_len,
1489+
slot_err,
1490+
ptr_align,
1491+
len_align,
1492+
err_align,
1493+
}
1494+
}
1495+
1496+
fn push_result_string_out_params(
1497+
builder: &mut FunctionBuilder,
1498+
ptr_ty: Type,
1499+
slots: &ResultStringSlots,
1500+
args: &mut Vec<Value>,
1501+
) {
1502+
let ptr_ptr = aligned_stack_addr(builder, slots.slot_ptr, slots.ptr_align, ptr_ty);
1503+
let len_ptr = aligned_stack_addr(builder, slots.slot_len, slots.len_align, ptr_ty);
1504+
let err_ptr = aligned_stack_addr(builder, slots.slot_err, slots.err_align, ptr_ty);
1505+
args.push(ptr_ptr);
1506+
args.push(len_ptr);
1507+
args.push(err_ptr);
1508+
}
1509+
1510+
fn read_result_string_slots(
1511+
builder: &mut FunctionBuilder,
1512+
ptr_ty: Type,
1513+
slots: &ResultStringSlots,
1514+
) -> (Value, Value, Value) {
1515+
let ptr_addr = aligned_stack_addr(builder, slots.slot_ptr, slots.ptr_align, ptr_ty);
1516+
let len_addr = aligned_stack_addr(builder, slots.slot_len, slots.len_align, ptr_ty);
1517+
let err_addr = aligned_stack_addr(builder, slots.slot_err, slots.err_align, ptr_ty);
1518+
let ptr = builder.ins().load(ptr_ty, MemFlags::new(), ptr_addr, 0);
1519+
let len = builder
1520+
.ins()
1521+
.load(ir::types::I64, MemFlags::new(), len_addr, 0);
1522+
let err = builder
1523+
.ins()
1524+
.load(ir::types::I32, MemFlags::new(), err_addr, 0);
1525+
(ptr, len, err)
1526+
}
1527+
14981528
/// Compute pointer/len offsets for the string layout.
14991529
fn string_offsets(ptr_ty: Type) -> (u32, u32) {
15001530
let ptr_size = ptr_ty.bytes() as u32;
@@ -2293,37 +2323,14 @@ pub(super) fn emit_runtime_wrapper_call(
22932323
) -> Result<ValueRepr, CodegenError> {
22942324
ensure_abi_sig_handled(info)?;
22952325
let abi_sig = info.abi_sig.as_ref().unwrap_or(&info.sig);
2296-
let mut out_slots = None;
2326+
let mut out_slots: Option<ResultStringSlots> = None;
22972327
let mut result_out = None;
22982328

22992329
if abi_sig.ret == AbiType::ResultString {
23002330
let ptr_ty = module.isa().pointer_type();
2301-
let ptr_align = ptr_ty.bytes() as u32;
2302-
let len_bytes = result_string_len_bytes();
2303-
let len_align = len_bytes;
2304-
let err_align = 4u32;
2305-
let slot_ptr = builder.create_sized_stack_slot(ir::StackSlotData::new(
2306-
ir::StackSlotKind::ExplicitSlot,
2307-
aligned_slot_size(ptr_ty.bytes(), ptr_align),
2308-
));
2309-
let slot_len = builder.create_sized_stack_slot(ir::StackSlotData::new(
2310-
ir::StackSlotKind::ExplicitSlot,
2311-
aligned_slot_size(len_bytes, len_align),
2312-
));
2313-
let slot_err = builder.create_sized_stack_slot(ir::StackSlotData::new(
2314-
ir::StackSlotKind::ExplicitSlot,
2315-
aligned_slot_size(4, err_align),
2316-
));
2317-
2318-
let ptr_ptr = aligned_stack_addr(builder, slot_ptr, ptr_align, ptr_ty);
2319-
let len_ptr = aligned_stack_addr(builder, slot_len, len_align, ptr_ty);
2320-
let err_ptr = aligned_stack_addr(builder, slot_err, err_align, ptr_ty);
2321-
2322-
args.push(ptr_ptr);
2323-
args.push(len_ptr);
2324-
args.push(err_ptr);
2325-
2326-
out_slots = Some((slot_ptr, slot_len, slot_err));
2331+
let slots = result_string_slots(builder, ptr_ty);
2332+
push_result_string_out_params(builder, ptr_ty, &slots, &mut args);
2333+
out_slots = Some(slots);
23272334
}
23282335

23292336
if let AbiType::ResultOut(ok_ty, err_ty) = &abi_sig.ret {
@@ -2375,24 +2382,9 @@ pub(super) fn emit_runtime_wrapper_call(
23752382
let tag = results
23762383
.get(0)
23772384
.ok_or_else(|| CodegenError::Codegen("missing result tag".to_string()))?;
2378-
let (slot_ptr, slot_len, slot_err) =
2379-
out_slots.ok_or_else(|| CodegenError::Codegen("missing slots".to_string()))?;
2385+
let slots = out_slots.ok_or_else(|| CodegenError::Codegen("missing slots".to_string()))?;
23802386
let ptr_ty = module.isa().pointer_type();
2381-
let ptr_align = ptr_ty.bytes() as u32;
2382-
let len_align = result_string_len_bytes();
2383-
let err_align = 4u32;
2384-
let ptr_addr = aligned_stack_addr(builder, slot_ptr, ptr_align, ptr_ty);
2385-
let len_addr = aligned_stack_addr(builder, slot_len, len_align, ptr_ty);
2386-
let err_addr = aligned_stack_addr(builder, slot_err, err_align, ptr_ty);
2387-
let ptr = builder
2388-
.ins()
2389-
.load(module.isa().pointer_type(), MemFlags::new(), ptr_addr, 0);
2390-
let len = builder
2391-
.ins()
2392-
.load(ir::types::I64, MemFlags::new(), len_addr, 0);
2393-
let err = builder
2394-
.ins()
2395-
.load(ir::types::I32, MemFlags::new(), err_addr, 0);
2387+
let (ptr, len, err) = read_result_string_slots(builder, ptr_ty, &slots);
23962388
match &info.sig.ret {
23972389
AbiType::Result(ok_ty, err_ty) => {
23982390
if **ok_ty != AbiType::String || **err_ty != AbiType::I32 {

0 commit comments

Comments
 (0)