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
4 changes: 3 additions & 1 deletion meld-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,9 @@ impl Fuser {
if !matches!(imp.kind, parser::ImportKind::Function(_)) {
continue;
}
if imp.name == site.import_name || imp.module == site.import_name {
if (imp.name == site.import_name || imp.module == site.import_name)
&& (imp.module == site.import_module || imp.name == site.import_module)
{
merged
.function_index_map
.insert((comp_idx, mod_idx, import_func_idx), adapter_merged_idx);
Expand Down
1 change: 1 addition & 0 deletions meld-core/src/merger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,7 @@ impl Merger {
site.from_component == comp_idx
&& site.from_module == mod_idx
&& (imp.name == site.import_name || imp.module == site.import_name)
&& (imp.module == site.import_module || imp.name == site.import_module)
});
if let Some(site) = resolved {
if let Some(&target_idx) = merged.function_index_map.get(&(
Expand Down
59 changes: 55 additions & 4 deletions meld-core/src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,11 @@ pub struct AdapterSite {
pub from_component: usize,
/// Source module index within component
pub from_module: usize,
/// Import being resolved
/// Import being resolved (bare function name, e.g., "roundtrip-u8")
pub import_name: String,
/// Caller's core import module name (e.g., "test:dep/test@0.1.0").
/// Used to disambiguate when multiple interfaces export the same function name.
pub import_module: String,
/// Caller's import function type index (module-local) in from_module's type section.
/// Used so the adapter's declared type matches what the caller expects to call.
pub import_func_type_idx: Option<u32>,
Expand Down Expand Up @@ -1169,6 +1172,7 @@ impl Resolver {
from_component: unresolved.component_idx,
from_module: unresolved.module_idx,
import_name: unresolved.field_name.clone(),
import_module: unresolved.module_name.clone(),
import_func_type_idx: None,
to_component: target_comp,
to_module: target_mod,
Expand Down Expand Up @@ -1915,6 +1919,7 @@ impl Resolver {
from_component: *from_comp,
from_module: from_mod_idx,
import_name: (*func_name).to_string(),
import_module: import_name.clone(),
import_func_type_idx: caller_import_type_idx,
to_component: *to_comp,
to_module: to_mod_idx,
Expand Down Expand Up @@ -1975,20 +1980,64 @@ impl Resolver {
let mut requirements = AdapterRequirements::default();

// Callee side: use provenance-based lookup for correct
// component-level core func index.
let callee_lift_map = to_component.lift_options_by_core_func();
// component-level core func index, including type index
// for layout/resource detection.
let callee_lift_map = to_component.lift_info_by_core_func();
let fb_export_to_core = build_module_export_to_core_func(to_component);
let fb_core_to_local = build_core_func_to_module_local(to_component);
let fb_comp_core_idx =
fb_export_to_core.get(&(to_mod_idx, export_name.clone()));
if let Some(lift_opts) =
if let Some((comp_type_idx, lift_opts)) =
fb_comp_core_idx.and_then(|idx| callee_lift_map.get(idx))
{
requirements.callee_encoding = Some(lift_opts.string_encoding);
requirements.callee_post_return = lift_opts
.post_return
.and_then(|pr_idx| fb_core_to_local.get(&pr_idx).copied());
requirements.callee_realloc = lift_opts.realloc;

// Populate layout and resource info from component
// function type (mirrors per-function path).
if let Some(ct) = to_component.get_type_definition(*comp_type_idx)
&& let ComponentTypeKind::Function {
params: comp_params,
results,
} = &ct.kind
{
let size = to_component.return_area_byte_size(results);
if size > 4 {
requirements.return_area_byte_size = Some(size);
}
requirements.pointer_pair_positions =
to_component.pointer_pair_param_positions(comp_params);
requirements.result_pointer_pair_offsets =
to_component.pointer_pair_result_offsets(results);
requirements.param_copy_layouts =
collect_param_copy_layouts(to_component, comp_params);
requirements.result_copy_layouts =
collect_result_copy_layouts(to_component, results);
requirements.conditional_pointer_pairs = to_component
.conditional_pointer_pair_positions(comp_params);
requirements.conditional_result_pointer_pairs = to_component
.conditional_pointer_pair_result_positions(results);
requirements.conditional_result_flat_pairs = to_component
.conditional_pointer_pair_result_flat_positions(results);
requirements.return_area_slots =
to_component.return_area_slots(results);

let callee_resource_map =
build_resource_type_to_import(to_component);
requirements.resource_params = resolve_resource_positions(
&callee_resource_map,
&to_component.resource_param_positions(comp_params),
"[resource-rep]",
);
requirements.resource_results = resolve_resource_positions(
&callee_resource_map,
&to_component.resource_result_positions(results),
"[resource-new]",
);
}
}

// Caller side: look up lower options by import func index.
Expand Down Expand Up @@ -2052,6 +2101,7 @@ impl Resolver {
from_component: *from_comp,
from_module: from_mod_idx,
import_name: import_name.clone(),
import_module: import_name.clone(),
import_func_type_idx: fallback_import_type_idx,
to_component: *to_comp,
to_module: to_mod_idx,
Expand Down Expand Up @@ -2245,6 +2295,7 @@ impl Resolver {
from_component: res.component_idx,
from_module: res.from_module,
import_name: res.import_name.clone(),
import_module: res.import_name.clone(),
import_func_type_idx: None,
to_component: res.component_idx, // same component
to_module: res.to_module,
Expand Down
16 changes: 6 additions & 10 deletions meld-core/tests/wit_bindgen_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,21 +635,18 @@ runtime_test!(
test_runtime_wit_bindgen_owned_resource_deref_mut,
"owned-resource-deref-mut"
);
// with-and-resources: adapter codegen produces empty stack (same as resource_alias)
fuse_only_test!(
test_fuse_wit_bindgen_with_and_resources,
runtime_test!(
test_runtime_wit_bindgen_with_and_resources,
"with-and-resources"
);
runtime_test!(test_runtime_wit_bindgen_resource_alias, "resource_alias");

// Resource fixtures — known failures (graceful degradation)
// resource_alias: adapter codegen produces empty stack (type mismatch)
// resource_aggregates: own<T> handle leak (handle != 0 assertion)
// resource_floats: borrow handle not converted in 3-component chain (align 8)
// resource_floats: 3-component resource chain — wrong resource table for [resource-rep]
// resource_borrow_in_record: borrow<T> inside record not detected as flat param
// resource_with_lists: data corruption in resource+list combination
// ownership: resource ownership transfer issue
// xcrate: resource handle lookup failure in 3-component chain
fuse_only_test!(test_fuse_wit_bindgen_resource_alias, "resource_alias");
fuse_only_test!(
test_fuse_wit_bindgen_resource_aggregates,
"resource_aggregates"
Expand All @@ -664,7 +661,7 @@ fuse_only_test!(
"resource_with_lists"
);
fuse_only_test!(test_fuse_wit_bindgen_ownership, "ownership");
fuse_only_test!(test_fuse_wit_bindgen_xcrate, "xcrate");
runtime_test!(test_runtime_wit_bindgen_xcrate, "xcrate");

// resource-import-and-export: core fusion works, P2 wrapping fails on toplevel-import
fuse_only_test!(
Expand All @@ -685,8 +682,7 @@ runtime_test!(
"package-with-version"
);

// versions: wrong function dispatched across versioned interfaces
fuse_only_test!(test_fuse_wit_bindgen_versions, "versions");
runtime_test!(test_runtime_wit_bindgen_versions, "versions");

// Rust binding-specific fixtures (still valid fusion targets)
runtime_test!(
Expand Down
Loading