Repository: bytecodealliance/wasmtime
Pull request #8030 (2024-02-29 18:33:18)

Cranelift: Add missing `check:` filetest pragma
<!--
Please make sure you include the following information:

- If this work has been discussed elsewhere, please include a link to that
  conversation. If it was discussed in an issue, just mention "issue #...".

- Explain why this change is needed. If the details are in an issue already,
  this can be brief.

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->



Patch:
diff --git a/crates/wasmtime/src/runtime/component/resources.rs b/crates/wasmtime/src/runtime/component/resources.rs
index 09e164cfd..6cc1e8b89 100644
--- a/crates/wasmtime/src/runtime/component/resources.rs
+++ b/crates/wasmtime/src/runtime/component/resources.rs
@@ -12,7 +12,8 @@ use std::marker;
 use std::mem::MaybeUninit;
 use std::sync::atomic::{AtomicU64, Ordering::Relaxed};
 use wasmtime_environ::component::{
-    CanonicalAbiInfo, DefinedResourceIndex, InterfaceType, TypeResourceTableIndex,
+    CanonicalAbiInfo, ComponentTypes, DefinedResourceIndex, InterfaceType, ResourceIndex,
+    TypeResourceTableIndex,
 };
 use wasmtime_runtime::component::{ComponentInstance, InstanceFlags, ResourceTables};
 use wasmtime_runtime::{SendSyncPtr, VMFuncRef, ValRaw};
@@ -69,6 +70,15 @@ impl ResourceType {
             },
         }
     }
+
+    pub(crate) fn uninstantiated(types: &ComponentTypes, index: ResourceIndex) -> ResourceType {
+        ResourceType {
+            kind: ResourceTypeKind::Uninstantiated {
+                component: types as *const _ as usize,
+                index,
+            },
+        }
+    }
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -82,6 +92,14 @@ enum ResourceTypeKind {
         instance: usize,
         id: DefinedResourceIndex,
     },
+    Uninstantiated {
+        // Like `instance` in `Guest` above this is a pointer and is used to
+        // distinguish between two components. Technically susceptible to ABA
+        // issues but the consequence is a nonexistent resource would be equal
+        // to a new resource so there's not really any issue with that.
+        component: usize,
+        index: ResourceIndex,
+    },
 }
 
 /// A host-defined resource in the component model.
diff --git a/crates/wasmtime/src/runtime/component/types.rs b/crates/wasmtime/src/runtime/component/types.rs
index c1536f970..06b29d47e 100644
--- a/crates/wasmtime/src/runtime/component/types.rs
+++ b/crates/wasmtime/src/runtime/component/types.rs
@@ -944,7 +944,18 @@ impl ComponentItem {
                 engine,
                 ty.types[*idx].clone(),
             )),
-            TypeDef::Resource(idx) => Self::Resource(ty.resources[ty.types[*idx].ty]),
+            TypeDef::Resource(idx) => {
+                let resource_index = ty.types[*idx].ty;
+                let ty = match ty.resources.get(resource_index) {
+                    // This resource type was substituted by a linker for
+                    // example so it's replaced here.
+                    Some(ty) => *ty,
+
+                    // This resource type was not substituted.
+                    None => ResourceType::uninstantiated(&ty.types, resource_index),
+                };
+                Self::Resource(ty)
+            }
         }
     }
 }


Test patch:
diff --git a/cranelift/filetests/filetests/egraph/issue-7999.clif b/cranelift/filetests/filetests/egraph/issue-7999.clif
index 7cacb533f..2903d2a33 100644
--- a/cranelift/filetests/filetests/egraph/issue-7999.clif
+++ b/cranelift/filetests/filetests/egraph/issue-7999.clif
@@ -8,5 +8,8 @@ block0(v0: i8):
     v2 = imul_imm v1, 256
     v3 = ireduce.i8 v2
     return v3
-    ; return v10  ; v10 = 0
+
+    ;; This function should get optimized down to simply returning zero:
+
+    ; check: return v10  ; v10 = 0
 }
diff --git a/tests/all/component_model/linker.rs b/tests/all/component_model/linker.rs
index fbff6fe92..73030cacf 100644
--- a/tests/all/component_model/linker.rs
+++ b/tests/all/component_model/linker.rs
@@ -1,4 +1,5 @@
 use anyhow::Result;
+use wasmtime::component::types::ComponentItem;
 use wasmtime::component::{Component, Linker, ResourceType};
 use wasmtime::{Engine, Store};
 
@@ -103,3 +104,44 @@ fn missing_import_selects_max() -> Result<()> {
 
     Ok(())
 }
+
+#[test]
+fn linker_substituting_types_issue_8003() -> Result<()> {
+    let engine = Engine::default();
+    let linker = Linker::<()>::new(&engine);
+    let component = Component::new(
+        &engine,
+        r#"
+            (component
+              (component $foo
+                (type $_myres (resource (rep i32)))
+                (export $myres "myres" (type $_myres))
+
+                (core module $m
+                  (func (export "make") (result i32) unreachable)
+                )
+                (core instance $m (instantiate $m))
+
+                (func (export "make") (result (own $myres))
+                  (canon lift (core func $m "make")))
+              )
+              (instance $foo (instantiate $foo))
+              (export "foo" (instance $foo))
+            )
+        "#,
+    )?;
+
+    let component_ty = linker.substituted_component_type(&component)?;
+    let exports = component_ty.exports(&engine);
+    for (_name, item) in exports {
+        match item {
+            ComponentItem::ComponentInstance(instance) => {
+                for _ in instance.exports(&engine) {
+                    // ..
+                }
+            }
+            _ => {}
+        }
+    }
+    Ok(())
+}