Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions crates/perry-abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,9 +572,46 @@ pub const SETTER_SITE_ADDRESS_MASK: u64 = 0x0000_FFFF_FFFF_FFFF;
pub const SETTER_SITE_RECV_SHAPE_OFFSET: usize = 0;
pub const SETTER_SITE_HOLDER_SHAPE_OFFSET: usize = 4;
pub const SETTER_SITE_HOLDER_OFFSET: usize = 8;
pub const SETTER_SITE_SLOT_OFFSET: usize = 16;
pub const SETTER_SITE_PAIR_OFFSET: usize = 24;
pub const SETTER_SITE_CODE_OFFSET: usize = 32;

/// Byte offsets of the entry's pointer-sized fields and the u32 slot, for a
/// target whose pointers are `ptr_bytes` wide (8 on LP64, 4 on ILP32 such as
/// wasm32). The entry is `#[repr(C)]` with `usize` address fields, so the
/// offsets after the two u32 ShapeIds follow the target's pointer width; the
/// runtime asserts the `SETTER_SITE_*_OFFSET` constants (this crate's own
/// target width) against `offset_of!`, and codegen asks for the width of the
/// target it emits for.
pub const fn setter_site_layout(ptr_bytes: usize) -> SetterSiteLayout {
let slot = SETTER_SITE_HOLDER_OFFSET + ptr_bytes;
let pair = (slot + 4).next_multiple_of(ptr_bytes);
SetterSiteLayout {
holder: SETTER_SITE_HOLDER_OFFSET,
slot,
pair,
code: pair + ptr_bytes,
}
}

/// See [`setter_site_layout`].
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct SetterSiteLayout {
pub holder: usize,
pub slot: usize,
pub pair: usize,
pub code: usize,
}

const SETTER_SITE_NATIVE: SetterSiteLayout = setter_site_layout(core::mem::size_of::<usize>());
pub const SETTER_SITE_SLOT_OFFSET: usize = SETTER_SITE_NATIVE.slot;
pub const SETTER_SITE_PAIR_OFFSET: usize = SETTER_SITE_NATIVE.pair;
pub const SETTER_SITE_CODE_OFFSET: usize = SETTER_SITE_NATIVE.code;
const _: () = assert!(
setter_site_layout(8).slot == 16
&& setter_site_layout(8).pair == 24
&& setter_site_layout(8).code == 32
&& setter_site_layout(4).slot == 12
&& setter_site_layout(4).pair == 16
&& setter_site_layout(4).code == 20
);
/// The site's holder state word, and its bit for a LATCHED site: one that
/// refused, or whose non-own receivers took several shapes. Its misses ask the
/// inherited-read hook, as a never-primed site's do.
Expand Down
21 changes: 17 additions & 4 deletions crates/perry-codegen/src/expr/put_value_store_ic/setter_arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,25 @@ pub(super) fn emit_setter_arm(
blk.cond_br(&tagged, &recv_l, next_label);
addr
};
// The entry's address fields are `usize`: 4 bytes on an ILP32 target, whose
// layout differs from the host's (`abi::setter_site_layout`).
let ilp32 = crate::target_layout::target_is_ilp32(ctx.target_triple);
let layout = abi::setter_site_layout(if ilp32 { 4 } else { 8 });
let field = |ctx: &mut FnCtx<'_>, offset: usize, ty| -> String {
let blk = ctx.block();
let a = blk.add(I64, &entry, &offset.to_string());
let p = blk.inttoptr(I64, &a);
blk.load(ty, &p)
};
// A pointer-sized field, widened to i64.
let addr_field = |ctx: &mut FnCtx<'_>, offset: usize| -> String {
if ilp32 {
let narrow = field(ctx, offset, I32);
ctx.block().zext(I32, &narrow, I64)
} else {
field(ctx, offset, I64)
}
};

ctx.current_block = recv_idx;
let recv_shape = field(ctx, abi::SETTER_SITE_RECV_SHAPE_OFFSET, I32);
Expand All @@ -123,7 +136,7 @@ pub(super) fn emit_setter_arm(
}

ctx.current_block = holder_idx;
let holder = field(ctx, abi::SETTER_SITE_HOLDER_OFFSET, I64);
let holder = addr_field(ctx, layout.holder);
let holder_shape = field(ctx, abi::SETTER_SITE_HOLDER_SHAPE_OFFSET, I32);
{
let blk = ctx.block();
Expand All @@ -135,9 +148,9 @@ pub(super) fn emit_setter_arm(
}

ctx.current_block = lane_idx;
let slot = field(ctx, abi::SETTER_SITE_SLOT_OFFSET, I32);
let pair = field(ctx, abi::SETTER_SITE_PAIR_OFFSET, I64);
let code = field(ctx, abi::SETTER_SITE_CODE_OFFSET, I64);
let slot = field(ctx, layout.slot, I32);
let pair = addr_field(ctx, layout.pair);
let code = addr_field(ctx, layout.code);
{
let blk = ctx.block();
let slot64 = blk.zext(I32, &slot, I64);
Expand Down
3 changes: 3 additions & 0 deletions crates/perry-codegen/src/wasm32/runtime_abi.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -1977,6 +1977,7 @@ js_native_call_method f64 f64,ptr,usize,ptr,usize
js_native_call_method_apply f64 f64,ptr,usize,i64
js_native_call_method_apply_by_id f64 f64,i64,i64
js_native_call_method_by_id f64 f64,i64,ptr,usize
js_native_call_method_by_id_learn f64 f64,i64,ptr,usize,ptr,i32u
js_native_call_method_nullsafe f64 f64,ptr,usize,ptr,usize
js_native_call_method_patched_proto f64 f64,ptr,usize,ptr,usize
js_native_call_method_patched_proto_apply f64 f64,ptr,usize,i64
Expand Down Expand Up @@ -2594,6 +2595,7 @@ js_object_get_field_ic_overflow_load f64 ptr,ptr,i32s,ptr
js_object_get_field_ic_slow f64 i64,ptr,ptr,ptr
js_object_get_index_polymorphic f64 i64,f64
js_object_get_own_field_or_undef f64 f64,ptr,usize
js_object_get_own_field_or_undef_learn f64 f64,ptr,usize,ptr
js_object_get_own_property_descriptor f64 f64,f64
js_object_get_own_property_descriptors f64 f64
js_object_get_own_property_names f64 f64
Expand Down Expand Up @@ -3908,6 +3910,7 @@ js_typed_feedback_native_call_method_by_id f64 i64,f64,i64,ptr,usize
js_typed_feedback_numeric_array_index_get_guard i32s i64,f64,i32s,i32s
js_typed_feedback_numeric_array_index_set_guard i32s i64,f64,i32s,f64,i32s
js_typed_feedback_numeric_array_push_guard i32s i64,f64,f64
js_typed_feedback_object_get_field_by_key_f64 f64 i64,ptr,f64,f64
js_typed_feedback_object_get_field_by_name_f64 f64 i64,ptr,ptr
js_typed_feedback_object_get_field_by_value_f64 f64 i64,ptr,f64
js_typed_feedback_object_set_field_by_name void i64,ptr,ptr,f64
Expand Down
Loading