Repository: bytecodealliance/wasmtime
Pull request #7862 (2024-02-02 18:38:22)

Update and add lots of docs, mostly for components
When I originally implemented the embedding API for the component model I left a lot of `// TODO: say more here` style comments assuming I'd come back around before stabilization. While I didn't quite make it in time for Wasmtime 17 this is my attempt to improve things for the future. This should add substantive documentation for all component-model related things and flesh out some more details here and there. Nowhere near comprehensive but, hey, Rome wasn't built in a day either.

<!--
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/.github/workflows/main.yml b/.github/workflows/main.yml
index 4d6062754..7f385bc00 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -520,6 +520,19 @@ jobs:
       shell: pwsh
       if: matrix.os == 'windows-latest'
 
+    # Since MPK (PKU) is not present on some GitHub runners, we check if it is
+    # available before force-enabling it. This occasional testing is better than
+    # none at all; ideally we would test in a system-mode QEMU VM.
+    - name: Force-run with MPK enabled, if available
+      if: ${{ contains(matrix.name, 'MPK') }}
+      run: |
+        if cargo run --example mpk-available; then
+          echo "::notice::This CI run will force-enable MPK; this ensures tests conditioned with the \`WASMTIME_TEST_FORCE_MPK\` environment variable will run with MPK-protected memory pool stripes."
+          echo WASMTIME_TEST_FORCE_MPK=1 >> $GITHUB_ENV
+        else
+          echo "::warning::This CI run will not test MPK; it has been detected as not available on this machine (\`cargo run --example mpk-available\`)."
+        fi
+
     # Build and test all features
     - run: ./ci/run-tests.sh --locked
       env:
diff --git a/Cargo.lock b/Cargo.lock
index c94c32784..fe8933d14 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -224,7 +224,7 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
 
 [[package]]
 name = "byte-array-literals"
-version = "18.0.0"
+version = "19.0.0"
 
 [[package]]
 name = "byteorder"
@@ -570,7 +570,7 @@ dependencies = [
 
 [[package]]
 name = "cranelift"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "cranelift-codegen",
  "cranelift-frontend",
@@ -578,14 +578,14 @@ dependencies = [
 
 [[package]]
 name = "cranelift-bforest"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "cranelift-entity",
 ]
 
 [[package]]
 name = "cranelift-codegen"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "anyhow",
  "bincode",
@@ -613,25 +613,25 @@ dependencies = [
 
 [[package]]
 name = "cranelift-codegen-meta"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "cranelift-codegen-shared",
 ]
 
 [[package]]
 name = "cranelift-codegen-shared"
-version = "0.105.0"
+version = "0.106.0"
 
 [[package]]
 name = "cranelift-control"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "arbitrary",
 ]
 
 [[package]]
 name = "cranelift-entity"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "serde",
  "serde_derive",
@@ -670,7 +670,7 @@ dependencies = [
 
 [[package]]
 name = "cranelift-frontend"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "cranelift-codegen",
  "hashbrown 0.14.0",
@@ -694,7 +694,7 @@ dependencies = [
 
 [[package]]
 name = "cranelift-interpreter"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "cranelift-codegen",
  "cranelift-entity",
@@ -708,7 +708,7 @@ dependencies = [
 
 [[package]]
 name = "cranelift-isle"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "codespan-reporting",
  "log",
@@ -717,7 +717,7 @@ dependencies = [
 
 [[package]]
 name = "cranelift-jit"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "anyhow",
  "cranelift",
@@ -738,7 +738,7 @@ dependencies = [
 
 [[package]]
 name = "cranelift-module"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -750,7 +750,7 @@ dependencies = [
 
 [[package]]
 name = "cranelift-native"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "cranelift-codegen",
  "libc",
@@ -759,7 +759,7 @@ dependencies = [
 
 [[package]]
 name = "cranelift-object"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -774,7 +774,7 @@ dependencies = [
 
 [[package]]
 name = "cranelift-reader"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -784,7 +784,7 @@ dependencies = [
 
 [[package]]
 name = "cranelift-serde"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "clap",
  "cranelift-codegen",
@@ -831,7 +831,7 @@ dependencies = [
 
 [[package]]
 name = "cranelift-wasm"
-version = "0.105.0"
+version = "0.106.0"
 dependencies = [
  "cranelift-codegen",
  "cranelift-entity",
@@ -2892,7 +2892,7 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
 
 [[package]]
 name = "verify-component-adapter"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "wasmparser 0.121.0",
@@ -2942,7 +2942,7 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
 name = "wasi-cap-std-sync"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "async-trait",
@@ -2964,7 +2964,7 @@ dependencies = [
 
 [[package]]
 name = "wasi-common"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "bitflags 2.4.1",
@@ -2997,7 +2997,7 @@ dependencies = [
 
 [[package]]
 name = "wasi-preview1-component-adapter"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "byte-array-literals",
  "object",
@@ -3008,7 +3008,7 @@ dependencies = [
 
 [[package]]
 name = "wasi-tokio"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "cap-std",
@@ -3220,7 +3220,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "addr2line",
  "anyhow",
@@ -3265,14 +3265,14 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-asm-macros"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "cfg-if",
 ]
 
 [[package]]
 name = "wasmtime-bench-api"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "cap-std",
@@ -3289,14 +3289,14 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-c-api"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "wasmtime-c-api-impl",
 ]
 
 [[package]]
 name = "wasmtime-c-api-impl"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "cap-std",
@@ -3323,7 +3323,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-cache"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "base64",
@@ -3345,7 +3345,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-cli"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "async-trait",
@@ -3401,7 +3401,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-cli-flags"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "clap",
@@ -3414,7 +3414,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-component-macro"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "component-macro-test-helpers",
@@ -3430,11 +3430,11 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-component-util"
-version = "18.0.0"
+version = "19.0.0"
 
 [[package]]
 name = "wasmtime-cranelift"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "cfg-if",
@@ -3457,7 +3457,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-cranelift-shared"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -3471,7 +3471,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-environ"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "bincode",
@@ -3512,7 +3512,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-explorer"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "capstone",
@@ -3526,7 +3526,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-fiber"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "backtrace",
@@ -3595,7 +3595,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-jit-debug"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "object",
  "once_cell",
@@ -3605,7 +3605,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-jit-icache-coherence"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "cfg-if",
  "libc",
@@ -3614,7 +3614,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-runtime"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "cc",
@@ -3645,7 +3645,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-types"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "cranelift-entity",
  "serde",
@@ -3656,7 +3656,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-versioned-export-macros"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3665,7 +3665,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-wasi"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "async-trait",
@@ -3703,7 +3703,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-wasi-http"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "async-trait",
@@ -3729,7 +3729,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-wasi-nn"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "cap-std",
@@ -3745,7 +3745,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-wasi-threads"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "log",
@@ -3757,7 +3757,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-wast"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "log",
@@ -3767,7 +3767,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-winch"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -3782,7 +3782,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-wit-bindgen"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "heck",
@@ -3792,7 +3792,7 @@ dependencies = [
 
 [[package]]
 name = "wasmtime-wmemcheck"
-version = "18.0.0"
+version = "19.0.0"
 
 [[package]]
 name = "wast"
@@ -3854,7 +3854,7 @@ dependencies = [
 
 [[package]]
 name = "wiggle"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "async-trait",
@@ -3871,7 +3871,7 @@ dependencies = [
 
 [[package]]
 name = "wiggle-generate"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "anyhow",
  "heck",
@@ -3884,7 +3884,7 @@ dependencies = [
 
 [[package]]
 name = "wiggle-macro"
-version = "18.0.0"
+version = "19.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3939,7 +3939,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
 name = "winch-codegen"
-version = "0.16.0"
+version = "0.17.0"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
diff --git a/Cargo.toml b/Cargo.toml
index 8f0689c01..52d4d0496 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -130,7 +130,7 @@ exclude = [
 ]
 
 [workspace.package]
-version = "18.0.0"
+version = "19.0.0"
 authors = ["The Wasmtime Project Developers"]
 edition = "2021"
 # Wasmtime's current policy is that this number can be no larger than the
@@ -152,58 +152,58 @@ all = 'allow'
 
 [workspace.dependencies]
 arbitrary = { version = "1.3.1" }
-wasmtime-wmemcheck = { path = "crates/wmemcheck", version = "=18.0.0" }
-wasmtime = { path = "crates/wasmtime", version = "18.0.0", default-features = false }
-wasmtime-cache = { path = "crates/cache", version = "=18.0.0" }
-wasmtime-cli-flags = { path = "crates/cli-flags", version = "=18.0.0" }
-wasmtime-cranelift = { path = "crates/cranelift", version = "=18.0.0" }
-wasmtime-cranelift-shared = { path = "crates/cranelift-shared", version = "=18.0.0" }
-wasmtime-winch = { path = "crates/winch", version = "=18.0.0" }
-wasmtime-environ = { path = "crates/environ", version = "=18.0.0" }
-wasmtime-explorer = { path = "crates/explorer", version = "=18.0.0" }
-wasmtime-fiber = { path = "crates/fiber", version = "=18.0.0" }
-wasmtime-types = { path = "crates/types", version = "18.0.0" }
-wasmtime-jit-debug = { path = "crates/jit-debug", version = "=18.0.0" }
-wasmtime-runtime = { path = "crates/runtime", version = "=18.0.0" }
-wasmtime-wast = { path = "crates/wast", version = "=18.0.0" }
-wasmtime-wasi = { path = "crates/wasi", version = "18.0.0", default-features = false }
-wasmtime-wasi-http = { path = "crates/wasi-http", version = "=18.0.0", default-features = false }
-wasmtime-wasi-nn = { path = "crates/wasi-nn", version = "18.0.0" }
-wasmtime-wasi-threads = { path = "crates/wasi-threads", version = "18.0.0" }
-wasmtime-component-util = { path = "crates/component-util", version = "=18.0.0" }
-wasmtime-component-macro = { path = "crates/component-macro", version = "=18.0.0" }
-wasmtime-asm-macros = { path = "crates/asm-macros", version = "=18.0.0" }
-wasmtime-versioned-export-macros = { path = "crates/versioned-export-macros", version = "=18.0.0" }
+wasmtime-wmemcheck = { path = "crates/wmemcheck", version = "=19.0.0" }
+wasmtime = { path = "crates/wasmtime", version = "19.0.0", default-features = false }
+wasmtime-cache = { path = "crates/cache", version = "=19.0.0" }
+wasmtime-cli-flags = { path = "crates/cli-flags", version = "=19.0.0" }
+wasmtime-cranelift = { path = "crates/cranelift", version = "=19.0.0" }
+wasmtime-cranelift-shared = { path = "crates/cranelift-shared", version = "=19.0.0" }
+wasmtime-winch = { path = "crates/winch", version = "=19.0.0" }
+wasmtime-environ = { path = "crates/environ", version = "=19.0.0" }
+wasmtime-explorer = { path = "crates/explorer", version = "=19.0.0" }
+wasmtime-fiber = { path = "crates/fiber", version = "=19.0.0" }
+wasmtime-types = { path = "crates/types", version = "19.0.0" }
+wasmtime-jit-debug = { path = "crates/jit-debug", version = "=19.0.0" }
+wasmtime-runtime = { path = "crates/runtime", version = "=19.0.0" }
+wasmtime-wast = { path = "crates/wast", version = "=19.0.0" }
+wasmtime-wasi = { path = "crates/wasi", version = "19.0.0", default-features = false }
+wasmtime-wasi-http = { path = "crates/wasi-http", version = "=19.0.0", default-features = false }
+wasmtime-wasi-nn = { path = "crates/wasi-nn", version = "19.0.0" }
+wasmtime-wasi-threads = { path = "crates/wasi-threads", version = "19.0.0" }
+wasmtime-component-util = { path = "crates/component-util", version = "=19.0.0" }
+wasmtime-component-macro = { path = "crates/component-macro", version = "=19.0.0" }
+wasmtime-asm-macros = { path = "crates/asm-macros", version = "=19.0.0" }
+wasmtime-versioned-export-macros = { path = "crates/versioned-export-macros", version = "=19.0.0" }
 component-test-util = { path = "crates/misc/component-test-util" }
 component-fuzz-util = { path = "crates/misc/component-fuzz-util" }
-wiggle = { path = "crates/wiggle", version = "=18.0.0", default-features = false }
-wiggle-macro = { path = "crates/wiggle/macro", version = "=18.0.0" }
-wiggle-generate = { path = "crates/wiggle/generate", version = "=18.0.0" }
-wasi-common = { path = "crates/wasi-common", version = "=18.0.0", default-features = false }
-wasi-tokio = { path = "crates/wasi-common/tokio", version = "=18.0.0" }
-wasi-cap-std-sync = { path = "crates/wasi-common/cap-std-sync", version = "=18.0.0" }
+wiggle = { path = "crates/wiggle", version = "=19.0.0", default-features = false }
+wiggle-macro = { path = "crates/wiggle/macro", version = "=19.0.0" }
+wiggle-generate = { path = "crates/wiggle/generate", version = "=19.0.0" }
+wasi-common = { path = "crates/wasi-common", version = "=19.0.0", default-features = false }
+wasi-tokio = { path = "crates/wasi-common/tokio", version = "=19.0.0" }
+wasi-cap-std-sync = { path = "crates/wasi-common/cap-std-sync", version = "=19.0.0" }
 wasmtime-fuzzing = { path = "crates/fuzzing" }
-wasmtime-jit-icache-coherence = { path = "crates/jit-icache-coherence", version = "=18.0.0" }
-wasmtime-wit-bindgen = { path = "crates/wit-bindgen", version = "=18.0.0" }
+wasmtime-jit-icache-coherence = { path = "crates/jit-icache-coherence", version = "=19.0.0" }
+wasmtime-wit-bindgen = { path = "crates/wit-bindgen", version = "=19.0.0" }
 test-programs-artifacts = { path = 'crates/test-programs/artifacts' }
 
-cranelift-wasm = { path = "cranelift/wasm", version = "0.105.0" }
-cranelift-codegen = { path = "cranelift/codegen", version = "0.105.0", default-features = false, features = ["std", "unwind"] }
-cranelift-frontend = { path = "cranelift/frontend", version = "0.105.0" }
-cranelift-entity = { path = "cranelift/entity", version = "0.105.0" }
-cranelift-native = { path = "cranelift/native", version = "0.105.0" }
-cranelift-module = { path = "cranelift/module", version = "0.105.0" }
-cranelift-interpreter = { path = "cranelift/interpreter", version = "0.105.0" }
-cranelift-reader = { path = "cranelift/reader", version = "0.105.0" }
+cranelift-wasm = { path = "cranelift/wasm", version = "0.106.0" }
+cranelift-codegen = { path = "cranelift/codegen", version = "0.106.0", default-features = false, features = ["std", "unwind"] }
+cranelift-frontend = { path = "cranelift/frontend", version = "0.106.0" }
+cranelift-entity = { path = "cranelift/entity", version = "0.106.0" }
+cranelift-native = { path = "cranelift/native", version = "0.106.0" }
+cranelift-module = { path = "cranelift/module", version = "0.106.0" }
+cranelift-interpreter = { path = "cranelift/interpreter", version = "0.106.0" }
+cranelift-reader = { path = "cranelift/reader", version = "0.106.0" }
 cranelift-filetests = { path = "cranelift/filetests" }
-cranelift-object = { path = "cranelift/object", version = "0.105.0" }
-cranelift-jit = { path = "cranelift/jit", version = "0.105.0" }
+cranelift-object = { path = "cranelift/object", version = "0.106.0" }
+cranelift-jit = { path = "cranelift/jit", version = "0.106.0" }
 cranelift-fuzzgen = { path = "cranelift/fuzzgen" }
-cranelift-bforest = { path = "cranelift/bforest", version = "0.105.0" }
-cranelift-control = { path = "cranelift/control", version = "0.105.0" }
-cranelift = { path = "cranelift/umbrella", version = "0.105.0" }
+cranelift-bforest = { path = "cranelift/bforest", version = "0.106.0" }
+cranelift-control = { path = "cranelift/control", version = "0.106.0" }
+cranelift = { path = "cranelift/umbrella", version = "0.106.0" }
 
-winch-codegen = { path = "winch/codegen", version = "=0.16.0" }
+winch-codegen = { path = "winch/codegen", version = "=0.17.0" }
 winch-filetests = { path = "winch/filetests" }
 winch-test-macros = { path = "winch/test-macros" }
 
diff --git a/RELEASES.md b/RELEASES.md
index 3618765bc..3d67a7c2f 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,5 +1,15 @@
 --------------------------------------------------------------------------------
 
+## 19.0.0
+
+Unreleased.
+
+### Added
+
+### Changed
+
+--------------------------------------------------------------------------------
+
 ## 18.0.0
 
 Unreleased.
diff --git a/cranelift/bforest/Cargo.toml b/cranelift/bforest/Cargo.toml
index df489e8f7..1fa5bcac9 100644
--- a/cranelift/bforest/Cargo.toml
+++ b/cranelift/bforest/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 authors = ["The Cranelift Project Developers"]
 name = "cranelift-bforest"
-version = "0.105.0"
+version = "0.106.0"
 description = "A forest of B+-trees"
 license = "Apache-2.0 WITH LLVM-exception"
 documentation = "https://docs.rs/cranelift-bforest"
diff --git a/cranelift/codegen/Cargo.toml b/cranelift/codegen/Cargo.toml
index ff57921c9..5c99c9faa 100644
--- a/cranelift/codegen/Cargo.toml
+++ b/cranelift/codegen/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 authors = ["The Cranelift Project Developers"]
 name = "cranelift-codegen"
-version = "0.105.0"
+version = "0.106.0"
 description = "Low-level code generator library"
 license = "Apache-2.0 WITH LLVM-exception"
 documentation = "https://docs.rs/cranelift-codegen"
@@ -19,7 +19,7 @@ workspace = true
 anyhow = { workspace = true, optional = true }
 bumpalo = "3"
 capstone = { workspace = true, optional = true }
-cranelift-codegen-shared = { path = "./shared", version = "0.105.0" }
+cranelift-codegen-shared = { path = "./shared", version = "0.106.0" }
 cranelift-entity = { workspace = true }
 cranelift-bforest = { workspace = true }
 cranelift-control = { workspace = true }
@@ -44,8 +44,8 @@ criterion = { version = "0.5.0", features = ["html_reports"] }
 similar = "2.1.0"
 
 [build-dependencies]
-cranelift-codegen-meta = { path = "meta", version = "0.105.0" }
-cranelift-isle = { path = "../isle/isle", version = "=0.105.0" }
+cranelift-codegen-meta = { path = "meta", version = "0.106.0" }
+cranelift-isle = { path = "../isle/isle", version = "=0.106.0" }
 
 [features]
 default = ["std", "unwind", "host-arch", "timing"]
diff --git a/cranelift/codegen/meta/Cargo.toml b/cranelift/codegen/meta/Cargo.toml
index aff2d6973..d0f0ee6bb 100644
--- a/cranelift/codegen/meta/Cargo.toml
+++ b/cranelift/codegen/meta/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "cranelift-codegen-meta"
 authors = ["The Cranelift Project Developers"]
-version = "0.105.0"
+version = "0.106.0"
 description = "Metaprogram for cranelift-codegen code generator library"
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/bytecodealliance/wasmtime"
@@ -15,4 +15,4 @@ workspace = true
 rustdoc-args = [ "--document-private-items" ]
 
 [dependencies]
-cranelift-codegen-shared = { path = "../shared", version = "0.105.0" }
+cranelift-codegen-shared = { path = "../shared", version = "0.106.0" }
diff --git a/cranelift/codegen/shared/Cargo.toml b/cranelift/codegen/shared/Cargo.toml
index d773aa743..59e5e22ec 100644
--- a/cranelift/codegen/shared/Cargo.toml
+++ b/cranelift/codegen/shared/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 authors = ["The Cranelift Project Developers"]
 name = "cranelift-codegen-shared"
-version = "0.105.0"
+version = "0.106.0"
 description = "For code shared between cranelift-codegen-meta and cranelift-codegen"
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/bytecodealliance/wasmtime"
diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle
index 2452966a1..516e3151b 100644
--- a/cranelift/codegen/src/isa/x64/lower.isle
+++ b/cranelift/codegen/src/isa/x64/lower.isle
@@ -4159,35 +4159,33 @@
 
 ;; Rules for `umulhi` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(rule (lower (umulhi a @ (value_type $I16) b))
-      (let ((res ValueRegs (mul_hi $I16 $false a b))
-            (hi Gpr (value_regs_get_gpr res 1)))
-        hi))
-
-(rule (lower (umulhi a @ (value_type $I32) b))
-      (let ((res ValueRegs (mul_hi $I32 $false a b))
-            (hi Gpr (value_regs_get_gpr res 1)))
+;; The umulhi instruction is not available for 8-bit types, so we can extend
+;; the inputs, use the 16-bit multiply and shift the result down.
+(rule 1 (lower (umulhi a @ (value_type $I8) b))
+      (let ((a_ext Gpr (extend_to_gpr a $I16 (ExtendKind.Zero)))
+            (b_ext Gpr (extend_to_gpr b $I16 (ExtendKind.Zero)))
+            (mul Gpr (x64_mul $I16 a_ext b_ext))
+            (hi Gpr (x64_shr $I64 mul (imm8_to_imm8_gpr 8))))
         hi))
 
-(rule (lower (umulhi a @ (value_type $I64) b))
-      (let ((res ValueRegs (mul_hi $I64 $false a b))
+(rule 0 (lower (umulhi a @ (value_type ty) b))
+      (let ((res ValueRegs (mul_hi ty $false a b))
             (hi Gpr (value_regs_get_gpr res 1)))
         hi))
 
 ;; Rules for `smulhi` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(rule (lower (smulhi a @ (value_type $I16) b))
-      (let ((res ValueRegs (mul_hi $I16 $true a b))
-            (hi Gpr (value_regs_get_gpr res 1)))
-        hi))
-
-(rule (lower (smulhi a @ (value_type $I32) b))
-      (let ((res ValueRegs (mul_hi $I32 $true a b))
-            (hi Gpr (value_regs_get_gpr res 1)))
+;; The smulhi instruction is not available for 8-bit types, so we can extend
+;; the inputs, use the 16-bit multiply and shift the result down.
+(rule 1 (lower (smulhi a @ (value_type $I8) b))
+      (let ((a_ext Gpr (extend_to_gpr a $I16 (ExtendKind.Sign)))
+            (b_ext Gpr (extend_to_gpr b $I16 (ExtendKind.Sign)))
+            (mul Gpr (x64_mul $I16 a_ext b_ext))
+            (hi Gpr (x64_sar $I64 mul (imm8_to_imm8_gpr 8))))
         hi))
 
-(rule (lower (smulhi a @ (value_type $I64) b))
-      (let ((res ValueRegs (mul_hi $I64 $true a b))
+(rule 0 (lower (smulhi a @ (value_type ty) b))
+      (let ((res ValueRegs (mul_hi ty $true a b))
             (hi Gpr (value_regs_get_gpr res 1)))
         hi))
 
diff --git a/cranelift/codegen/src/verifier/mod.rs b/cranelift/codegen/src/verifier/mod.rs
index 608d0ac05..d80724570 100644
--- a/cranelift/codegen/src/verifier/mod.rs
+++ b/cranelift/codegen/src/verifier/mod.rs
@@ -157,7 +157,7 @@ where
 
 /// Result of a step in the verification process.
 ///
-/// Functions that return `VerifierStepResult<()>` should also take a
+/// Functions that return `VerifierStepResult` should also take a
 /// mutable reference to `VerifierErrors` as argument in order to report
 /// errors.
 ///
@@ -165,11 +165,11 @@ where
 /// meaning that the verification process may continue. However, other (non-fatal)
 /// errors might have been reported through the previously mentioned `VerifierErrors`
 /// argument.
-pub type VerifierStepResult<T> = Result<T, ()>;
+pub type VerifierStepResult = Result<(), ()>;
 
 /// Result of a verification operation.
 ///
-/// Unlike `VerifierStepResult<()>` which may be `Ok` while still having reported
+/// Unlike `VerifierStepResult` which may be `Ok` while still having reported
 /// errors, this type always returns `Err` if an error (fatal or not) was reported.
 pub type VerifierResult<T> = Result<T, VerifierErrors>;
 
@@ -203,7 +203,7 @@ impl VerifierErrors {
     /// Return a `VerifierStepResult` that is fatal if at least one error was reported,
     /// and non-fatal otherwise.
     #[inline]
-    pub fn as_result(&self) -> VerifierStepResult<()> {
+    pub fn as_result(&self) -> VerifierStepResult {
         if self.is_empty() {
             Ok(())
         } else {
@@ -217,13 +217,13 @@ impl VerifierErrors {
     }
 
     /// Report a fatal error and return `Err`.
-    pub fn fatal(&mut self, error: impl Into<VerifierError>) -> VerifierStepResult<()> {
+    pub fn fatal(&mut self, error: impl Into<VerifierError>) -> VerifierStepResult {
         self.report(error);
         Err(())
     }
 
     /// Report a non-fatal error and return `Ok`.
-    pub fn nonfatal(&mut self, error: impl Into<VerifierError>) -> VerifierStepResult<()> {
+    pub fn nonfatal(&mut self, error: impl Into<VerifierError>) -> VerifierStepResult {
         self.report(error);
         Ok(())
     }
@@ -285,7 +285,7 @@ pub fn verify_context<'a, FOI: Into<FlagsOrIsa<'a>>>(
     domtree: &DominatorTree,
     fisa: FOI,
     errors: &mut VerifierErrors,
-) -> VerifierStepResult<()> {
+) -> VerifierStepResult {
     let _tt = timing::verifier();
     let verifier = Verifier::new(func, fisa.into());
     if cfg.is_valid() {
@@ -325,7 +325,7 @@ impl<'a> Verifier<'a> {
     // Check for:
     //  - cycles in the global value declarations.
     //  - use of 'vmctx' when no special parameter declares it.
-    fn verify_global_values(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+    fn verify_global_values(&self, errors: &mut VerifierErrors) -> VerifierStepResult {
         let mut cycle_seen = false;
         let mut seen = SparseSet::new();
 
@@ -410,7 +410,7 @@ impl<'a> Verifier<'a> {
         Ok(())
     }
 
-    fn verify_memory_types(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+    fn verify_memory_types(&self, errors: &mut VerifierErrors) -> VerifierStepResult {
         // Verify that all fields are statically-sized and lie within
         // the struct, do not overlap, and are in offset order
         for (mt, mt_data) in &self.func.memory_types {
@@ -457,7 +457,7 @@ impl<'a> Verifier<'a> {
         Ok(())
     }
 
-    fn verify_tables(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+    fn verify_tables(&self, errors: &mut VerifierErrors) -> VerifierStepResult {
         if let Some(isa) = self.isa {
             for (table, table_data) in &self.func.tables {
                 let base = table_data.base_gv;
@@ -502,7 +502,7 @@ impl<'a> Verifier<'a> {
 
     /// Check that the given block can be encoded as a BB, by checking that only
     /// branching instructions are ending the block.
-    fn encodable_as_bb(&self, block: Block, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+    fn encodable_as_bb(&self, block: Block, errors: &mut VerifierErrors) -> VerifierStepResult {
         match self.func.is_block_basic(block) {
             Ok(()) => Ok(()),
             Err((inst, message)) => errors.fatal((inst, self.context(inst), message)),
@@ -514,7 +514,7 @@ impl<'a> Verifier<'a> {
         block: Block,
         inst: Inst,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         let is_terminator = self.func.dfg.insts[inst].opcode().is_terminator();
         let is_last_inst = self.func.layout.last_inst(block) == Some(inst);
 
@@ -560,11 +560,7 @@ impl<'a> Verifier<'a> {
         Ok(())
     }
 
-    fn instruction_integrity(
-        &self,
-        inst: Inst,
-        errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    fn instruction_integrity(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult {
         let inst_data = &self.func.dfg.insts[inst];
         let dfg = &self.func.dfg;
 
@@ -596,7 +592,7 @@ impl<'a> Verifier<'a> {
         &self,
         inst: Inst,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         use crate::ir::instructions::InstructionData::*;
 
         for arg in self.func.dfg.inst_values(inst) {
@@ -763,7 +759,7 @@ impl<'a> Verifier<'a> {
         loc: impl Into<AnyEntity>,
         e: Block,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         if !self.func.dfg.block_is_valid(e) || !self.func.layout.is_block_inserted(e) {
             return errors.fatal((loc, format!("invalid block reference {}", e)));
         }
@@ -780,7 +776,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         s: SigRef,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         if !self.func.dfg.signatures.is_valid(s) {
             errors.fatal((
                 inst,
@@ -797,7 +793,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         f: FuncRef,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         if !self.func.dfg.ext_funcs.is_valid(f) {
             errors.nonfatal((
                 inst,
@@ -814,7 +810,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         ss: StackSlot,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         if !self.func.sized_stack_slots.is_valid(ss) {
             errors.nonfatal((
                 inst,
@@ -831,7 +827,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         ss: DynamicStackSlot,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         if !self.func.dynamic_stack_slots.is_valid(ss) {
             errors.nonfatal((
                 inst,
@@ -848,7 +844,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         gv: GlobalValue,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         if !self.func.global_values.is_valid(gv) {
             errors.nonfatal((
                 inst,
@@ -865,7 +861,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         table: ir::Table,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         if !self.func.tables.is_valid(table) {
             errors.nonfatal((inst, self.context(inst), format!("invalid table {}", table)))
         } else {
@@ -878,7 +874,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         l: &ValueList,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         if !l.is_valid(&self.func.dfg.value_lists) {
             errors.nonfatal((
                 inst,
@@ -895,7 +891,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         j: JumpTable,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         if !self.func.stencil.dfg.jump_tables.is_valid(j) {
             errors.nonfatal((
                 inst,
@@ -916,7 +912,7 @@ impl<'a> Verifier<'a> {
         loc_inst: Inst,
         v: Value,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         let dfg = &self.func.dfg;
         if !dfg.value_is_valid(v) {
             errors.nonfatal((
@@ -934,7 +930,7 @@ impl<'a> Verifier<'a> {
         loc_inst: Inst,
         v: Value,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         self.verify_value(loc_inst, v, errors)?;
 
         let dfg = &self.func.dfg;
@@ -1028,7 +1024,7 @@ impl<'a> Verifier<'a> {
         loc_inst: Inst,
         v: Value,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         self.verify_value(loc_inst, v, errors)?;
 
         match self.func.dfg.value_def(v) {
@@ -1062,7 +1058,7 @@ impl<'a> Verifier<'a> {
         flags: MemFlags,
         arg: Value,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         let typ = self.func.dfg.ctrl_typevar(inst);
         let value_type = self.func.dfg.value_type(arg);
 
@@ -1099,7 +1095,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         constant: Constant,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         let type_size = self.func.dfg.ctrl_typevar(inst).bytes() as usize;
         let constant_size = self.func.dfg.constants.get(constant).len();
         if type_size != constant_size {
@@ -1119,7 +1115,7 @@ impl<'a> Verifier<'a> {
         &self,
         domtree: &DominatorTree,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         // We consider two `DominatorTree`s to be equal if they return the same immediate
         // dominator for each block. Therefore the current domtree is valid if it matches the freshly
         // computed one.
@@ -1174,7 +1170,7 @@ impl<'a> Verifier<'a> {
         Ok(())
     }
 
-    fn typecheck_entry_block_params(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+    fn typecheck_entry_block_params(&self, errors: &mut VerifierErrors) -> VerifierStepResult {
         if let Some(block) = self.func.layout.entry_block() {
             let expected_types = &self.func.signature.params;
             let block_param_count = self.func.dfg.num_block_params(block);
@@ -1207,7 +1203,7 @@ impl<'a> Verifier<'a> {
         errors.as_result()
     }
 
-    fn check_entry_not_cold(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+    fn check_entry_not_cold(&self, errors: &mut VerifierErrors) -> VerifierStepResult {
         if let Some(entry_block) = self.func.layout.entry_block() {
             if self.func.layout.is_cold(entry_block) {
                 return errors
@@ -1217,7 +1213,7 @@ impl<'a> Verifier<'a> {
         errors.as_result()
     }
 
-    fn typecheck(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+    fn typecheck(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult {
         let inst_data = &self.func.dfg.insts[inst];
         let constraints = inst_data.opcode().constraints();
 
@@ -1258,7 +1254,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         ctrl_type: Type,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         let mut i = 0;
         for &result in self.func.dfg.inst_results(inst) {
             let result_type = self.func.dfg.value_type(result);
@@ -1300,7 +1296,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         ctrl_type: Type,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         let constraints = self.func.dfg.insts[inst].opcode().constraints();
 
         for (i, &arg) in self.func.dfg.inst_fixed_args(inst).iter().enumerate() {
@@ -1341,7 +1337,7 @@ impl<'a> Verifier<'a> {
         &self,
         inst: Inst,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         match &self.func.dfg.insts[inst] {
             ir::InstructionData::Jump { destination, .. } => {
                 self.typecheck_block_call(inst, destination, errors)?;
@@ -1387,7 +1383,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         block: &ir::BlockCall,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         let pool = &self.func.dfg.value_lists;
         let iter = self
             .func
@@ -1405,7 +1401,7 @@ impl<'a> Verifier<'a> {
         iter: I,
         variable_args: &[Value],
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         let mut i = 0;
 
         for expected_type in iter {
@@ -1443,7 +1439,7 @@ impl<'a> Verifier<'a> {
         Ok(())
     }
 
-    fn typecheck_return(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+    fn typecheck_return(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult {
         match self.func.dfg.insts[inst] {
             ir::InstructionData::MultiAry {
                 opcode: Opcode::Return,
@@ -1485,7 +1481,7 @@ impl<'a> Verifier<'a> {
         inst: Inst,
         sig_ref: SigRef,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         let signature = &self.func.dfg.signatures[sig_ref];
         let cc = signature.call_conv;
         if !cc.supports_tail_calls() {
@@ -1513,7 +1509,7 @@ impl<'a> Verifier<'a> {
         actual_types: impl ExactSizeIterator<Item = Type>,
         errors: &mut VerifierErrors,
         message: &str,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         let expected_types = &self.func.signature.returns;
         if actual_types.len() != expected_types.len() {
             return errors.nonfatal((inst, self.context(inst), message));
@@ -1535,7 +1531,7 @@ impl<'a> Verifier<'a> {
 
     // Check special-purpose type constraints that can't be expressed in the normal opcode
     // constraints.
-    fn typecheck_special(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+    fn typecheck_special(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult {
         match self.func.dfg.insts[inst] {
             ir::InstructionData::TableAddr { table, arg, .. } => {
                 let index_type = self.func.dfg.value_type(arg);
@@ -1575,7 +1571,7 @@ impl<'a> Verifier<'a> {
         &self,
         cfg: &ControlFlowGraph,
         errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    ) -> VerifierStepResult {
         let mut expected_succs = BTreeSet::<Block>::new();
         let mut got_succs = BTreeSet::<Block>::new();
         let mut expected_preds = BTreeSet::<Inst>::new();
@@ -1643,11 +1639,7 @@ impl<'a> Verifier<'a> {
         errors.as_result()
     }
 
-    fn immediate_constraints(
-        &self,
-        inst: Inst,
-        errors: &mut VerifierErrors,
-    ) -> VerifierStepResult<()> {
+    fn immediate_constraints(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult {
         let inst_data = &self.func.dfg.insts[inst];
 
         match *inst_data {
@@ -1713,7 +1705,7 @@ impl<'a> Verifier<'a> {
         }
     }
 
-    fn iconst_bounds(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+    fn iconst_bounds(&self, inst: Inst, errors: &mut VerifierErrors) -> VerifierStepResult {
         use crate::ir::instructions::InstructionData::UnaryImm;
 
         let inst_data = &self.func.dfg.insts[inst];
@@ -1746,7 +1738,7 @@ impl<'a> Verifier<'a> {
         }
     }
 
-    fn typecheck_function_signature(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+    fn typecheck_function_signature(&self, errors: &mut VerifierErrors) -> VerifierStepResult {
         let params = self
             .func
             .signature
@@ -1806,7 +1798,7 @@ impl<'a> Verifier<'a> {
         }
     }
 
-    pub fn run(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+    pub fn run(&self, errors: &mut VerifierErrors) -> VerifierStepResult {
         self.verify_global_values(errors)?;
         self.verify_memory_types(errors)?;
         self.verify_tables(errors)?;
diff --git a/cranelift/control/Cargo.toml b/cranelift/control/Cargo.toml
index b0492844d..64a6bf7dc 100644
--- a/cranelift/control/Cargo.toml
+++ b/cranelift/control/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 authors = ["The Cranelift Project Developers"]
 name = "cranelift-control"
-version = "0.105.0"
+version = "0.106.0"
 description = "White-box fuzz testing framework"
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/bytecodealliance/wasmtime"
diff --git a/cranelift/entity/Cargo.toml b/cranelift/entity/Cargo.toml
index 3533274f7..4b16b6a0a 100644
--- a/cranelift/entity/Cargo.toml
+++ b/cranelift/entity/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 authors = ["The Cranelift Project Developers"]
 name = "cranelift-entity"
-version = "0.105.0"
+version = "0.106.0"
 description = "Data structures using entity references as mapping keys"
 license = "Apache-2.0 WITH LLVM-exception"
 documentation = "https://docs.rs/cranelift-entity"
diff --git a/cranelift/frontend/Cargo.toml b/cranelift/frontend/Cargo.toml
index ae84dee24..896168e36 100644
--- a/cranelift/frontend/Cargo.toml
+++ b/cranelift/frontend/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 authors = ["The Cranelift Project Developers"]
 name = "cranelift-frontend"
-version = "0.105.0"
+version = "0.106.0"
 description = "Cranelift IR builder helper"
 license = "Apache-2.0 WITH LLVM-exception"
 documentation = "https://docs.rs/cranelift-frontend"
diff --git a/cranelift/fuzzgen/src/function_generator.rs b/cranelift/fuzzgen/src/function_generator.rs
index 743a6a5d6..6ed5d8412 100644
--- a/cranelift/fuzzgen/src/function_generator.rs
+++ b/cranelift/fuzzgen/src/function_generator.rs
@@ -523,8 +523,6 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
                 rets,
                 (Opcode::UmulOverflow | Opcode::SmulOverflow, &[I128, I128]),
                 (Opcode::Imul, &[I8X16, I8X16]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5468
-                (Opcode::Smulhi | Opcode::Umulhi, &[I8, I8]),
                 // https://github.com/bytecodealliance/wasmtime/issues/4756
                 (Opcode::Udiv | Opcode::Sdiv, &[I128, I128]),
                 // https://github.com/bytecodealliance/wasmtime/issues/5474
diff --git a/cranelift/interpreter/Cargo.toml b/cranelift/interpreter/Cargo.toml
index a2e0f703e..e59b31040 100644
--- a/cranelift/interpreter/Cargo.toml
+++ b/cranelift/interpreter/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cranelift-interpreter"
-version = "0.105.0"
+version = "0.106.0"
 authors = ["The Cranelift Project Developers"]
 description = "Interpret Cranelift IR"
 repository = "https://github.com/bytecodealliance/wasmtime"
diff --git a/cranelift/isle/isle/Cargo.toml b/cranelift/isle/isle/Cargo.toml
index 2394662fa..08fa18a2b 100644
--- a/cranelift/isle/isle/Cargo.toml
+++ b/cranelift/isle/isle/Cargo.toml
@@ -6,7 +6,7 @@ license = "Apache-2.0 WITH LLVM-exception"
 name = "cranelift-isle"
 readme = "../README.md"
 repository = "https://github.com/bytecodealliance/wasmtime/tree/main/cranelift/isle"
-version = "0.105.0"
+version = "0.106.0"
 
 [lints]
 workspace = true
diff --git a/cranelift/jit/Cargo.toml b/cranelift/jit/Cargo.toml
index df9b94416..c06898fc9 100644
--- a/cranelift/jit/Cargo.toml
+++ b/cranelift/jit/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cranelift-jit"
-version = "0.105.0"
+version = "0.106.0"
 authors = ["The Cranelift Project Developers"]
 description = "A JIT library backed by Cranelift"
 repository = "https://github.com/bytecodealliance/wasmtime"
diff --git a/cranelift/module/Cargo.toml b/cranelift/module/Cargo.toml
index 238fd3ba5..66ec7e2fe 100644
--- a/cranelift/module/Cargo.toml
+++ b/cranelift/module/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cranelift-module"
-version = "0.105.0"
+version = "0.106.0"
 authors = ["The Cranelift Project Developers"]
 description = "Support for linking functions and data with Cranelift"
 repository = "https://github.com/bytecodealliance/wasmtime"
diff --git a/cranelift/native/Cargo.toml b/cranelift/native/Cargo.toml
index e57577b8b..be8c2a5e5 100644
--- a/cranelift/native/Cargo.toml
+++ b/cranelift/native/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cranelift-native"
-version = "0.105.0"
+version = "0.106.0"
 authors = ["The Cranelift Project Developers"]
 description = "Support for targeting the host with Cranelift"
 documentation = "https://docs.rs/cranelift-native"
diff --git a/cranelift/object/Cargo.toml b/cranelift/object/Cargo.toml
index 4f2d29154..1086055a6 100644
--- a/cranelift/object/Cargo.toml
+++ b/cranelift/object/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cranelift-object"
-version = "0.105.0"
+version = "0.106.0"
 authors = ["The Cranelift Project Developers"]
 description = "Emit Cranelift output to native object files with `object`"
 repository = "https://github.com/bytecodealliance/wasmtime"
diff --git a/cranelift/reader/Cargo.toml b/cranelift/reader/Cargo.toml
index 50a1f15d2..efbd15335 100644
--- a/cranelift/reader/Cargo.toml
+++ b/cranelift/reader/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 authors = ["The Cranelift Project Developers"]
 name = "cranelift-reader"
-version = "0.105.0"
+version = "0.106.0"
 description = "Cranelift textual IR reader"
 license = "Apache-2.0 WITH LLVM-exception"
 documentation = "https://docs.rs/cranelift-reader"
diff --git a/cranelift/serde/Cargo.toml b/cranelift/serde/Cargo.toml
index 626eb20ff..8577674ea 100644
--- a/cranelift/serde/Cargo.toml
+++ b/cranelift/serde/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cranelift-serde"
-version = "0.105.0"
+version = "0.106.0"
 authors = ["The Cranelift Project Developers"]
 description = "Serializer/Deserializer for Cranelift IR"
 repository = "https://github.com/bytecodealliance/wasmtime"
diff --git a/cranelift/umbrella/Cargo.toml b/cranelift/umbrella/Cargo.toml
index c1da2f66f..83b6d8536 100644
--- a/cranelift/umbrella/Cargo.toml
+++ b/cranelift/umbrella/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 authors = ["The Cranelift Project Developers"]
 name = "cranelift"
-version = "0.105.0"
+version = "0.106.0"
 description = "Umbrella for commonly-used cranelift crates"
 license = "Apache-2.0 WITH LLVM-exception"
 documentation = "https://docs.rs/cranelift"
diff --git a/cranelift/wasm/Cargo.toml b/cranelift/wasm/Cargo.toml
index 9a5d249f7..6913d4d32 100644
--- a/cranelift/wasm/Cargo.toml
+++ b/cranelift/wasm/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cranelift-wasm"
-version = "0.105.0"
+version = "0.106.0"
 authors = ["The Cranelift Project Developers"]
 description = "Translator from WebAssembly to Cranelift IR"
 documentation = "https://docs.rs/cranelift-wasm"
diff --git a/crates/c-api/include/wasmtime.h b/crates/c-api/include/wasmtime.h
index 65b7b4157..6ba3e76b8 100644
--- a/crates/c-api/include/wasmtime.h
+++ b/crates/c-api/include/wasmtime.h
@@ -194,6 +194,7 @@
 #include <wasmtime/linker.h>
 #include <wasmtime/memory.h>
 #include <wasmtime/module.h>
+#include <wasmtime/profiling.h>
 #include <wasmtime/store.h>
 #include <wasmtime/table.h>
 #include <wasmtime/trap.h>
@@ -205,11 +206,11 @@
 /**
  * \brief Wasmtime version string.
  */
-#define WASMTIME_VERSION "18.0.0"
+#define WASMTIME_VERSION "19.0.0"
 /**
  * \brief Wasmtime major version number.
  */
-#define WASMTIME_VERSION_MAJOR 18
+#define WASMTIME_VERSION_MAJOR 19
 /**
  * \brief Wasmtime minor version number.
  */
diff --git a/crates/c-api/include/wasmtime/profiling.h b/crates/c-api/include/wasmtime/profiling.h
new file mode 100644
index 000000000..df3a68966
--- /dev/null
+++ b/crates/c-api/include/wasmtime/profiling.h
@@ -0,0 +1,113 @@
+/**
+ * \file wasmtime/profiling.h
+ *
+ * \brief API for Wasmtime guest profiler
+ */
+
+#ifndef WASMTIME_PROFILING_H
+#define WASMTIME_PROFILING_H
+
+#include <wasm.h>
+#include <wasmtime/error.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Collects basic profiling data for a single WebAssembly guest.
+ *
+ * To use this, you’ll need to arrange to call #wasmtime_guestprofiler_sample at
+ * regular intervals while the guest is on the stack. The most straightforward
+ * way to do that is to call it from a callback registered with
+ * #wasmtime_store_epoch_deadline_callback.
+ *
+ * For more information see the Rust documentation at:
+ * https://docs.wasmtime.dev/api/wasmtime/struct.GuestProfiler.html
+ */
+typedef struct wasmtime_guestprofiler wasmtime_guestprofiler_t;
+
+/**
+ * \brief Deletes profiler without finishing it.
+ *
+ * \param guestprofiler profiler that is being deleted
+ */
+WASM_API_EXTERN void wasmtime_guestprofiler_delete(
+    /* own */ wasmtime_guestprofiler_t *guestprofiler);
+
+/**
+ * \typedef wasmtime_guestprofiler_modules_t
+ * \brief Alias to #wasmtime_guestprofiler_modules
+ *
+ * \struct #wasmtime_guestprofiler_modules
+ * \brief Tuple of name and module for passing into #wasmtime_guestprofiler_new.
+ */
+typedef struct wasmtime_guestprofiler_modules {
+  const wasm_name_t *name; //!< Name recorded in the profile.
+  const wasmtime_module_t
+      *mod; //!< Module that is being allowed to appear in captured stack trace.
+} wasmtime_guestprofiler_modules_t;
+
+/**
+ * \brief Begin profiling a new guest.
+ *
+ * \param module_name    name recorded in the profile
+ * \param interval_nanos intended sampling interval in nanoseconds recorded in
+ *                       the profile
+ * \param modules        modules and associated names that will appear in
+ *                       captured stack traces, pointer to the first element
+ * \param modules_len    count of elements in `modules`
+ *
+ * \return Created profiler that is owned by the caller.
+ *
+ * This function does not take ownership of the arguments.
+ *
+ * For more information see the Rust documentation at:
+ * https://docs.wasmtime.dev/api/wasmtime/struct.GuestProfiler.html#method.new
+ */
+WASM_API_EXTERN /* own */ wasmtime_guestprofiler_t *wasmtime_guestprofiler_new(
+    const wasm_name_t *module_name, uint64_t interval_nanos,
+    const wasmtime_guestprofiler_modules_t *modules, size_t modules_len);
+
+/**
+ * \brief Add a sample to the profile.
+ *
+ * \param guestprofiler the profiler the sample is being added to
+ * \param store         store that is being used to collect the backtraces
+ *
+ * This function does not take ownership of the arguments.
+ *
+ * For more information see the Rust documentation at:
+ * https://docs.wasmtime.dev/api/wasmtime/struct.GuestProfiler.html#method.sample
+ */
+WASM_API_EXTERN void
+wasmtime_guestprofiler_sample(wasmtime_guestprofiler_t *guestprofiler,
+                              const wasmtime_store_t *store);
+
+/**
+ * \brief Writes out the captured profile.
+ *
+ * \param guestprofiler the profiler which is being finished and deleted
+ * \param out           pointer to where #wasm_byte_vec_t containing generated
+ *                      file will be written
+ *
+ * \return Returns #wasmtime_error_t owned by the caller in case of error,
+ * `NULL` otherwise.
+ *
+ * This function takes ownership of `guestprofiler`, even when error is
+ * returned.
+ * Only when returning without error `out` is filled with #wasm_byte_vec_t owned
+ * by the caller.
+ *
+ * For more information see the Rust documentation at:
+ * https://docs.wasmtime.dev/api/wasmtime/struct.GuestProfiler.html#method.finish
+ */
+WASM_API_EXTERN /* own */ wasmtime_error_t *
+wasmtime_guestprofiler_finish(/* own */ wasmtime_guestprofiler_t *guestprofiler,
+                              /* own */ wasm_byte_vec_t *out);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // WASMTIME_PROFILING_H
diff --git a/crates/c-api/src/lib.rs b/crates/c-api/src/lib.rs
index fb686427e..42f617196 100644
--- a/crates/c-api/src/lib.rs
+++ b/crates/c-api/src/lib.rs
@@ -23,6 +23,8 @@ mod instance;
 mod linker;
 mod memory;
 mod module;
+#[cfg(feature = "profiling")]
+mod profiling;
 mod r#ref;
 mod store;
 mod table;
diff --git a/crates/c-api/src/profiling.rs b/crates/c-api/src/profiling.rs
new file mode 100644
index 000000000..25fa32ed7
--- /dev/null
+++ b/crates/c-api/src/profiling.rs
@@ -0,0 +1,64 @@
+use crate::{wasm_byte_vec_t, wasm_name_t, wasmtime_error_t, wasmtime_module_t, wasmtime_store_t};
+use std::slice;
+use std::str::from_utf8;
+use std::time::Duration;
+use wasmtime::GuestProfiler;
+
+pub struct wasmtime_guestprofiler_t {
+    guest_profiler: GuestProfiler,
+}
+
+wasmtime_c_api_macros::declare_own!(wasmtime_guestprofiler_t);
+
+#[repr(C)]
+pub struct wasmtime_guestprofiler_modules_t<'a> {
+    name: &'a wasm_name_t,
+    module: &'a wasmtime_module_t,
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn wasmtime_guestprofiler_new(
+    module_name: &wasm_name_t,
+    interval_nanos: u64,
+    modules: *const wasmtime_guestprofiler_modules_t,
+    modules_len: usize,
+) -> Box<wasmtime_guestprofiler_t> {
+    let module_name = from_utf8(&module_name.as_slice()).expect("not valid utf-8");
+    let list = slice::from_raw_parts(modules, modules_len)
+        .iter()
+        .map(|entry| {
+            (
+                from_utf8(entry.name.as_slice())
+                    .expect("not valid utf-8")
+                    .to_owned(),
+                entry.module.module.clone(),
+            )
+        })
+        .collect();
+    Box::new(wasmtime_guestprofiler_t {
+        guest_profiler: GuestProfiler::new(module_name, Duration::from_nanos(interval_nanos), list),
+    })
+}
+
+#[no_mangle]
+pub extern "C" fn wasmtime_guestprofiler_sample(
+    guestprofiler: &mut wasmtime_guestprofiler_t,
+    store: &wasmtime_store_t,
+) {
+    guestprofiler.guest_profiler.sample(&store.store);
+}
+
+#[no_mangle]
+pub extern "C" fn wasmtime_guestprofiler_finish(
+    guestprofiler: Box<wasmtime_guestprofiler_t>,
+    out: &mut wasm_byte_vec_t,
+) -> Option<Box<wasmtime_error_t>> {
+    let mut buf = vec![];
+    match guestprofiler.guest_profiler.finish(&mut buf) {
+        Ok(()) => {
+            out.set_buffer(buf);
+            None
+        }
+        Err(e) => Some(Box::new(e.into())),
+    }
+}
diff --git a/crates/cranelift/src/debug/transform/attr.rs b/crates/cranelift/src/debug/transform/attr.rs
index 13bf62e9f..354bcdace 100644
--- a/crates/cranelift/src/debug/transform/attr.rs
+++ b/crates/cranelift/src/debug/transform/attr.rs
@@ -95,7 +95,7 @@ where
                 let addr = addr_tr.translate(u).unwrap_or(write::Address::Constant(0));
                 write::AttributeValue::Address(addr)
             }
-            AttributeValue::Block(d) => write::AttributeValue::Block(d.to_slice()?.to_vec()),
+            AttributeValue::Block(d) => write::AttributeValue::Block(d.to_slice()?.into_owned()),
             AttributeValue::Udata(u) => write::AttributeValue::Udata(u),
             AttributeValue::Data1(d) => write::AttributeValue::Data1(d),
             AttributeValue::Data2(d) => write::AttributeValue::Data2(d),
@@ -295,6 +295,7 @@ where
                 pending_di_refs.insert(current_scope_id, attr.name(), offset);
                 continue;
             }
+            AttributeValue::String(d) => write::AttributeValue::String(d.to_slice()?.into_owned()),
             a => bail!("Unexpected attribute: {:?}", a),
         };
         let current_scope = out_unit.get_mut(current_scope_id);
diff --git a/crates/wasi-common/Cargo.toml b/crates/wasi-common/Cargo.toml
index c0479b9be..8b4898c80 100644
--- a/crates/wasi-common/Cargo.toml
+++ b/crates/wasi-common/Cargo.toml
@@ -63,4 +63,4 @@ trace_log = [ "wiggle/tracing_log", "tracing/log" ]
 # crate if they want the snapshots to have metadata available.
 wiggle_metadata = ["wiggle/wiggle_metadata"]
 # This feature enables integration with wasmtime.
-wasmtime = ["dep:wasmtime", "wiggle/wasmtime"]
\ No newline at end of file
+wasmtime = ["dep:wasmtime", "wiggle/wasmtime"]
diff --git a/crates/wasmtime/src/config.rs b/crates/wasmtime/src/config.rs
index 944afd255..ff98cc3c4 100644
--- a/crates/wasmtime/src/config.rs
+++ b/crates/wasmtime/src/config.rs
@@ -28,7 +28,9 @@ use wasmtime_fiber::RuntimeFiberStackCreator;
 
 pub use wasmtime_environ::CacheStore;
 #[cfg(feature = "pooling-allocator")]
-pub use wasmtime_runtime::{mpk, MpkEnabled};
+use wasmtime_runtime::mpk;
+#[cfg(feature = "pooling-allocator")]
+pub use wasmtime_runtime::MpkEnabled;
 
 /// Represents the module instance allocation strategy to use.
 #[derive(Clone)]
diff --git a/crates/wasmtime/src/lib.rs b/crates/wasmtime/src/lib.rs
index e4278148c..5f3010477 100644
--- a/crates/wasmtime/src/lib.rs
+++ b/crates/wasmtime/src/lib.rs
@@ -1,37 +1,52 @@
-//! Wasmtime's embedding API
+//! # Wasmtime's embedding API
 //!
 //! Wasmtime is a WebAssembly engine for JIT-compiled or ahead-of-time compiled
-//! WebAssembly modules. More information about the Wasmtime project as a whole
-//! can be found [in the documentation book](https://docs.wasmtime.dev) whereas
-//! this documentation mostly focuses on the API reference of the `wasmtime`
-//! crate itself.
-//!
-//! This crate contains an API used to interact with WebAssembly modules. For
-//! example you can compile modules, instantiate them, call them, etc. As an
-//! embedder of WebAssembly you can also provide WebAssembly modules
-//! functionality from the host by creating host-defined functions, memories,
-//! globals, etc, which can do things that WebAssembly cannot (such as print to
-//! the screen).
-//!
-//! The `wasmtime` crate has similar concepts to the
-//! the [JS WebAssembly
-//! API](https://developer.mozilla.org/en-US/docs/WebAssembly) as well as the
-//! [proposed C API](https://github.com/webassembly/wasm-c-api), but the Rust
-//! API is designed for efficiency, ergonomics, and expressivity in Rust. As
-//! with all other Rust code you're guaranteed that programs will be safe (not
-//! have undefined behavior or segfault) so long as you don't use `unsafe` in
-//! your own program. With `wasmtime` you can easily and conveniently embed a
-//! WebAssembly runtime with confidence that the WebAssembly is safely
-//! sandboxed.
-//!
-//! An example of using Wasmtime looks like:
+//! WebAssembly modules and components. More information about the Wasmtime
+//! project as a whole can be found [in the documentation
+//! book](https://docs.wasmtime.dev) whereas this documentation mostly focuses
+//! on the API reference of the `wasmtime` crate itself.
+//!
+//! This crate contains an API used to interact with [WebAssembly modules] or
+//! [WebAssembly components]. For example you can compile WebAssembly, create
+//! instances, call functions, etc. As an embedder of WebAssembly you can also
+//! provide guests functionality from the host by creating host-defined
+//! functions, memories, globals, etc, which can do things that WebAssembly
+//! cannot (such as print to the screen).
+//!
+//! [WebAssembly modules]: https://webassembly.github.io/spec
+//! [WebAssembly components]: https://component-model.bytecodealliance.org
+//!
+//! The `wasmtime` crate is designed to be safe, efficient, and ergonomic.
+//! This enables executing WebAssembly without the embedder needing to use
+//! `unsafe` code, meaning that you're guaranteed there is no undefined behavior
+//! or segfaults in either the WebAssembly guest or the host itself.
+//!
+//! The `wasmtime` crate can roughly be thought of as being split into two
+//! halves:
+//!
+//! * One half of the crate is similar to the [JS WebAssembly
+//!   API](https://developer.mozilla.org/en-US/docs/WebAssembly) as well as the
+//!   [proposed C API](https://github.com/webassembly/wasm-c-api) and is
+//!   intended for working with [WebAssembly modules]. This API resides in the
+//!   root of the `wasmtime` crate's namespace, for example
+//!   [`wasmtime::Module`](`Module`).
+//!
+//! * The second half of the crate is for use with the [WebAssembly Component
+//!   Model]. The implementation of the component model is present in
+//!   [`wasmtime::component`](`component`) and roughly mirrors the structure for
+//!   core WebAssembly, for example [`component::Func`] mirrors [`Func`].
+//!
+//! [WebAssembly Component Model]: https://component-model.bytecodealliance.org
+//!
+//! An example of using Wasmtime to run a core WebAssembly module looks like:
 //!
 //! ```
 //! use wasmtime::*;
 //!
 //! fn main() -> wasmtime::Result<()> {
-//!     // Modules can be compiled through either the text or binary format
 //!     let engine = Engine::default();
+//!
+//!     // Modules can be compiled through either the text or binary format
 //!     let wat = r#"
 //!         (module
 //!             (import "host" "host_func" (func $host_hello (param i32)))
@@ -43,19 +58,23 @@
 //!     "#;
 //!     let module = Module::new(&engine, wat)?;
 //!
+//!     // Host functionality can be arbitrary Rust functions and is provided
+//!     // to guests through a `Linker`.
+//!     let mut linker = Linker::new(&engine);
+//!     linker.func_wrap("host", "host_func", |caller: Caller<'_, u32>, param: i32| {
+//!         println!("Got {} from WebAssembly", param);
+//!         println!("my host state is: {}", caller.data());
+//!     })?;
+//!
 //!     // All wasm objects operate within the context of a "store". Each
 //!     // `Store` has a type parameter to store host-specific data, which in
 //!     // this case we're using `4` for.
-//!     let mut store = Store::new(&engine, 4);
-//!     let host_func = Func::wrap(&mut store, |caller: Caller<'_, u32>, param: i32| {
-//!         println!("Got {} from WebAssembly", param);
-//!         println!("my host state is: {}", caller.data());
-//!     });
+//!     let mut store: Store<u32> = Store::new(&engine, 4);
 //!
 //!     // Instantiation of a module requires specifying its imports and then
 //!     // afterwards we can fetch exports by name, as well as asserting the
 //!     // type signature of the function with `get_typed_func`.
-//!     let instance = Instance::new(&mut store, &module, &[host_func.into()])?;
+//!     let instance = linker.instantiate(&mut store, &module)?;
 //!     let hello = instance.get_typed_func::<(), ()>(&mut store, "hello")?;
 //!
 //!     // And finally we can call the wasm!
@@ -70,19 +89,13 @@
 //! There are a number of core types and concepts that are important to be aware
 //! of when using the `wasmtime` crate:
 //!
-//! * [`Engine`] - a global compilation environment for WebAssembly. An
-//!   [`Engine`] is an object that can be shared concurrently across threads and
-//!   is created with a [`Config`] to tweak various settings. Compilation of any
-//!   WebAssembly requires first configuring and creating an [`Engine`].
-//!
-//! * [`Module`] - a compiled WebAssembly module. This structure represents
-//!   in-memory JIT code which is ready to execute after being instantiated.
-//!   It's often important to cache instances of a [`Module`] because creation
-//!   (compilation) can be expensive. Note that [`Module`] is safe to share
-//!   across threads, and can be created from a WebAssembly binary and an
-//!   [`Engine`] with [`Module::new`]. Caching can either happen with
-//!   [`Engine::precompile_module`] or [`Module::serialize`], feeding those
-//!   bytes back into [`Module::deserialize`].
+//! * [`Engine`] - a global compilation and runtime environment for WebAssembly.
+//!   An [`Engine`] is an object that can be shared concurrently across threads
+//!   and is created with a [`Config`] with many knobs for configuring
+//!   behavior. Compiling or executing any WebAssembly requires first
+//!   configuring and creating an [`Engine`]. All [`Module`]s and
+//!   [`Component`](component::Component)s belong to an [`Engine`], and
+//!   typically there's one [`Engine`] per process.
 //!
 //! * [`Store`] - container for all information related to WebAssembly objects
 //!   such as functions, instances, memories, etc. A [`Store<T>`][`Store`]
@@ -92,19 +105,48 @@
 //!   required for all WebAssembly operations, such as calling a wasm function.
 //!   The [`Store`] is passed in as a "context" to methods like [`Func::call`].
 //!   Dropping a [`Store`] will deallocate all memory associated with
-//!   WebAssembly objects within the [`Store`].
-//!
-//! * [`Instance`] - an instantiated WebAssembly module. An instance is where
-//!   you can actually acquire a [`Func`] from, for example, to call.
-//!
-//! * [`Func`] - a WebAssembly (or host) function. This can be acquired as the
-//!   export of an [`Instance`] to call WebAssembly functions, or it can be
-//!   created via functions like [`Func::wrap`] to wrap host-defined
-//!   functionality and give it to WebAssembly.
-//!
-//! * [`Table`], [`Global`], [`Memory`] - other WebAssembly objects which can
-//!   either be defined on the host or in wasm itself (via instances). These all
-//!   have various ways of being interacted with like [`Func`].
+//!   WebAssembly objects within the [`Store`]. A [`Store`] is cheap to create
+//!   and destroy and does not GC objects such as unused instances internally,
+//!   so it's intended to be short-lived (or no longer than the instances it
+//!   contains).
+//!
+//! * [`Linker`] (or [`component::Linker`]) - host functions are defined within
+//!   a linker to provide them a string-based name which can be looked up when
+//!   instantiating a WebAssembly module or component. Linkers are traditionally
+//!   populated at startup and then reused for all future instantiations of all
+//!   instances, assuming the set of host functions does not change over time.
+//!   Host functions are `Fn(..) + Send + Sync` and typically do not close over
+//!   mutable state. Instead it's recommended to store mutable state in the `T`
+//!   of [`Store<T>`] which is accessed through [`Caller<'_,
+//!   T>`](crate::Caller) provided to host functions.
+//!
+//! * [`Module`] (or [`Component`](component::Component)) - a compiled
+//!   WebAssembly module or component. These structures contain compiled
+//!   executable code from a WebAssembly binary which is ready to execute after
+//!   being instantiated. These are expensive to create as they require
+//!   compilation of the input WebAssembly. Modules and components are safe to
+//!   share across threads, however. Modules and components can additionally be
+//!   [serialized into a list of bytes](crate::Module::serialize) to later be
+//!   [deserialized](crate::Module::deserialize) quickly. This enables JIT-style
+//!   compilation through constructors such as [`Module::new`] and AOT-style
+//!   compilation by having the compilation process use [`Module::serialize`]
+//!   and the execution process use [`Module::deserialize`].
+//!
+//! * [`Instance`] (or [`component::Instance`]) - an instantiated WebAssembly
+//!   module or component. An instance is where you can actually acquire a
+//!   [`Func`] (or [`component::Func`]) from, for example, to call.
+//!
+//! * [`Func`] (or [`component::Func`]) - a WebAssembly function. This can be
+//!   acquired as the export of an [`Instance`] to call WebAssembly functions,
+//!   or it can be created via functions like [`Func::wrap`] to wrap
+//!   host-defined functionality and give it to WebAssembly. Functions also have
+//!   typed views as [`TypedFunc`] or [`component::TypedFunc`] for a more
+//!   efficient calling convention.
+//!
+//! * [`Table`], [`Global`], [`Memory`], [`component::Resource`] - other
+//!   WebAssembly objects which can either be defined on the host or in wasm
+//!   itself (via instances). These all have various ways of being interacted
+//!   with like [`Func`].
 //!
 //! All "store-connected" types such as [`Func`], [`Memory`], etc, require the
 //! store to be passed in as a context to each method. Methods in wasmtime
@@ -124,90 +166,6 @@
 //! [`Func`] point within the [`Store`] and require the [`Store`] to be provided
 //! to actually access the internals of the WebAssembly function, for instance.
 //!
-//! ## Linking
-//!
-//! WebAssembly modules almost always require functionality from the host to
-//! perform I/O-like tasks. They might refer to quite a few pieces of host
-//! functionality, WASI, or maybe even a number of other wasm modules. To assist
-//! with managing this a [`Linker`] type is provided to instantiate modules.
-//!
-//! A [`Linker`] performs name-based resolution of the imports of a WebAssembly
-//! module so the [`Linker::instantiate`] method does not take an `imports`
-//! argument like [`Instance::new`] does. Methods like [`Linker::define`] or
-//! [`Linker::func_wrap`] can be used to define names within a [`Linker`] to
-//! later be used for instantiation.
-//!
-//! For example we can reimplement the above example with a `Linker`:
-//!
-//! ```
-//! use wasmtime::*;
-//!
-//! fn main() -> wasmtime::Result<()> {
-//!     let engine = Engine::default();
-//!     let wat = r#"
-//!         (module
-//!             (import "host" "host_func" (func $host_hello (param i32)))
-//!
-//!             (func (export "hello")
-//!                 i32.const 3
-//!                 call $host_hello)
-//!         )
-//!     "#;
-//!     let module = Module::new(&engine, wat)?;
-//!
-//!     // Create a `Linker` and define our host function in it:
-//!     let mut linker = Linker::new(&engine);
-//!     linker.func_wrap("host", "host_func", |caller: Caller<'_, u32>, param: i32| {
-//!         println!("Got {} from WebAssembly", param);
-//!         println!("my host state is: {}", caller.data());
-//!     })?;
-//!
-//!     // Use the `linker` to instantiate the module, which will automatically
-//!     // resolve the imports of the module using name-based resolution.
-//!     let mut store = Store::new(&engine, 0);
-//!     let instance = linker.instantiate(&mut store, &module)?;
-//!     let hello = instance.get_typed_func::<(), ()>(&mut store, "hello")?;
-//!     hello.call(&mut store, ())?;
-//!
-//!     Ok(())
-//! }
-//! ```
-//!
-//! The [`Linker`] type also transparently handles Commands and Reactors
-//! as defined by WASI.
-//!
-//! ## Example Architecture
-//!
-//! To better understand how Wasmtime types interact with each other let's walk
-//! through, at a high-level, an example of how you might use WebAssembly. In
-//! our use case let's say we have a web server where we'd like to run some
-//! custom WebAssembly on each request. To ensure requests are entirely isolated
-//! from each other, though, we'll be creating a new [`Store`] for each
-//! request.
-//!
-//! When the server starts, we'll start off by creating an [`Engine`] (and maybe
-//! tweaking [`Config`] settings if necessary). This [`Engine`] will be the only
-//! engine for the lifetime of the server itself. Next, we can compile our
-//! WebAssembly. You'd create a [`Module`] through the [`Module::new`] API.
-//! This will generate JIT code and perform expensive compilation tasks
-//! up-front. Finally the last step of initialization would be to create a
-//! [`Linker`] which will later be used to instantiate modules, adding
-//! functionality like WASI to the linker too.
-//!
-//! After that setup, the server starts up as usual and is ready to receive
-//! requests. Upon receiving a request you'd then create a [`Store`] with
-//! [`Store::new`] referring to the original [`Engine`]. Using your [`Module`]
-//! and [`Linker`] from before you'd then call [`Linker::instantiate`] to
-//! instantiate our module for the request. Both of these operations are
-//! designed to be as cheap as possible.
-//!
-//! With an [`Instance`] you can then invoke various exports and interact with
-//! the WebAssembly module. Once the request is finished, the [`Store`]
-//! is dropped and everything will be deallocated. Note that if the same
-//! [`Store`] were used for every request then that would have all requests
-//! sharing resources and nothing would ever get deallocated, causing memory
-//! usage to baloon and would achive less isolation between requests.
-//!
 //! ## WASI
 //!
 //! The `wasmtime` crate does not natively provide support for WASI, but you can
@@ -218,36 +176,22 @@
 //!
 //! [`wasmtime-wasi`]: https://crates.io/crates/wasmtime-wasi
 //!
-//! ## Cross-store usage of items
-//!
-//! In `wasmtime` wasm items such as [`Global`] and [`Memory`] "belong" to a
-//! [`Store`]. The store they belong to is the one they were created with
-//! (passed in as a parameter) or instantiated with. This store is the only
-//! store that can be used to interact with wasm items after they're created.
-//!
-//! The `wasmtime` crate will panic if the [`Store`] argument passed in to these
-//! operations is incorrect. In other words it's considered a programmer error
-//! rather than a recoverable error for the wrong [`Store`] to be used when
-//! calling APIs.
-//!
 //! ## Crate Features
 //!
 //! The `wasmtime` crate comes with a number of compile-time features that can
 //! be used to customize what features it supports. Some of these features are
 //! just internal details, but some affect the public API of the `wasmtime`
-//! crate. Be sure to check the API you're using to see if any crate features
-//! are enabled.
+//! crate. Wasmtime APIs gated behind a Cargo feature should be indicated as
+//! such in the documentation.
 //!
 //! * `runtime` - Enabled by default, this feature enables executing
-//!   WebAssembly modules. If modules are only compiled, however, this feature
-//!   can be disabled.
+//!   WebAssembly modules and components. If a compiler is not available (such
+//!   as `cranelift`) then [`Module::deserialize`] must be used, for example, to
+//!   provide an ahead-of-time compiled artifact to execute WebAssembly.
 //!
 //! * `cranelift` - Enabled by default, this features enables using Cranelift at
 //!   runtime to compile a WebAssembly module to native code. This feature is
-//!   required to process and compile new WebAssembly modules. If this feature
-//!   is disabled then the only way to create a [`Module`] is to use the
-//!   [`Module::deserialize`] function with a precompiled artifact (typically
-//!   compiled with the same version of Wasmtime, just somewhere else).
+//!   required to process and compile new WebAssembly modules and components.
 //!
 //! * `cache` - Enabled by default, this feature adds support for wasmtime to
 //!   perform internal caching of modules in a global location. This must still
@@ -255,42 +199,31 @@
 //!   [`Config::cache_config_load_default`].
 //!
 //! * `wat` - Enabled by default, this feature adds support for accepting the
-//!   text format of WebAssembly in [`Module::new`]. The text format will be
+//!   text format of WebAssembly in [`Module::new`] and
+//!   [`Component::new`](component::Component::new). The text format will be
 //!   automatically recognized and translated to binary when compiling a
 //!   module.
 //!
 //! * `parallel-compilation` - Enabled by default, this feature enables support
-//!   for compiling functions of a module in parallel with `rayon`.
+//!   for compiling functions in parallel with `rayon`.
 //!
 //! * `async` - Enabled by default, this feature enables APIs and runtime
 //!   support for defining asynchronous host functions and calling WebAssembly
-//!   asynchronously.
-//!
-//! * `jitdump` - Enabled by default, this feature compiles in support for the
-//!   jitdump runtime profiling format. The profiler can be selected with
-//!   [`Config::profiler`].
+//!   asynchronously. For more information see [`Config::async_support`].
 //!
-//! * `vtune` - Enabled by default, this feature compiles in support for VTune
-//!   profiling of JIT code.
+//! * `profiling` - Enabled by default, this feature compiles in support for
+//!   profiling guest code via a number of possible strategies. See
+//!   [`Config::profiler`] for more information.
 //!
 //! * `all-arch` - Not enabled by default. This feature compiles in support for
 //!   all architectures for both the JIT compiler and the `wasmtime compile` CLI
-//!   command.
+//!   command. This can be combined with [`Config::target`] to precompile
+//!   modules for a different platform than the host.
 //!
 //! * `pooling-allocator` - Enabled by default, this feature adds support for
-//!   the pooling allocation strategy enabled via
-//!   [`Config::allocation_strategy`]. The pooling allocator can enable more
-//!   efficient reuse of resources for high-concurrency and
-//!   high-instantiation-count scenarios.
-//!
-//! * `memory-init-cow` - Enabled by default, this feature builds in support
-//!   for, on supported platforms, initializing wasm linear memories with
-//!   copy-on-write heap mappings. This makes instantiation much faster by
-//!   `mmap`-ing the initial memory image into place instead of copying memory
-//!   into place, allowing sharing pages that end up only getting read. Note
-//!   that this is simply compile-time support and this must also be enabled at
-//!   run-time via [`Config::memory_init_cow`] (which is also enabled by
-//!   default).
+//!   [`PoolingAllocationConfig`] to pass to [`Config::allocation_strategy`].
+//!   The pooling allocator can enable efficient reuse of resources for
+//!   high-concurrency and high-instantiation-count scenarios.
 //!
 //! * `demangle` - Enabled by default, this will affect how backtraces are
 //!   printed and whether symbol names from WebAssembly are attempted to be
@@ -310,98 +243,13 @@
 //!   will enable debugging guest code compiled to WebAssembly. This must also
 //!   be enabled via [`Config::debug_info`] as well for guests.
 //!
+//! * `component-model` - Enabled by default, this enables support for the
+//!   [`wasmtime::component`](component) API for working with components.
+//!
 //! More crate features can be found in the [manifest] of Wasmtime itself for
 //! seeing what can be enabled and disabled.
 //!
 //! [manifest]: https://github.com/bytecodealliance/wasmtime/blob/main/crates/wasmtime/Cargo.toml
-//!
-//! ## Examples
-//!
-//! In addition to the examples below be sure to check out the [online embedding
-//! documentation][rustdocs] as well as the [online list of examples][examples]
-//!
-//! [rustdocs]: https://bytecodealliance.github.io/wasmtime/lang-rust.html
-//! [examples]: https://bytecodealliance.github.io/wasmtime/examples-rust-embed.html
-//!
-//! An example of using WASI looks like:
-//!
-//! ```no_run
-//! # use wasmtime::*;
-//! use wasmtime_wasi::sync::WasiCtxBuilder;
-//!
-//! # fn main() -> wasmtime::Result<()> {
-//! // Compile our module and create a `Linker` which has WASI functions defined
-//! // within it.
-//! let engine = Engine::default();
-//! let module = Module::from_file(&engine, "foo.wasm")?;
-//! let mut linker = Linker::new(&engine);
-//! wasmtime_wasi::add_to_linker(&mut linker, |cx| cx)?;
-//!
-//! // Configure and create a `WasiCtx`, which WASI functions need access to
-//! // through the host state of the store (which in this case is the host state
-//! // of the store)
-//! let wasi_ctx = WasiCtxBuilder::new().inherit_stdio().build();
-//! let mut store = Store::new(&engine, wasi_ctx);
-//!
-//! // Instantiate our module with the imports we've created, and run it.
-//! let instance = linker.instantiate(&mut store, &module)?;
-//! // ...
-//!
-//! # Ok(())
-//! # }
-//! ```
-//!
-//! An example of reading a string from a wasm module:
-//!
-//! ```
-//! use std::str;
-//!
-//! # use wasmtime::*;
-//! # fn main() -> wasmtime::Result<()> {
-//! let mut store = Store::default();
-//! let log_str = Func::wrap(&mut store, |mut caller: Caller<'_, ()>, ptr: i32, len: i32| {
-//!     // Use our `caller` context to learn about the memory export of the
-//!     // module which called this host function.
-//!     let mem = match caller.get_export("memory") {
-//!         Some(Extern::Memory(mem)) => mem,
-//!         _ => anyhow::bail!("failed to find host memory"),
-//!     };
-//!
-//!     // Use the `ptr` and `len` values to get a subslice of the wasm-memory
-//!     // which we'll attempt to interpret as utf-8.
-//!     let data = mem.data(&caller)
-//!         .get(ptr as u32 as usize..)
-//!         .and_then(|arr| arr.get(..len as u32 as usize));
-//!     let string = match data {
-//!         Some(data) => match str::from_utf8(data) {
-//!             Ok(s) => s,
-//!             Err(_) => anyhow::bail!("invalid utf-8"),
-//!         },
-//!         None => anyhow::bail!("pointer/length out of bounds"),
-//!     };
-//!     assert_eq!(string, "Hello, world!");
-//!     println!("{}", string);
-//!     Ok(())
-//! });
-//! let module = Module::new(
-//!     store.engine(),
-//!     r#"
-//!         (module
-//!             (import "" "" (func $log_str (param i32 i32)))
-//!             (func (export "foo")
-//!                 i32.const 4   ;; ptr
-//!                 i32.const 13  ;; len
-//!                 call $log_str)
-//!             (memory (export "memory") 1)
-//!             (data (i32.const 4) "Hello, world!"))
-//!     "#,
-//! )?;
-//! let instance = Instance::new(&mut store, &module, &[log_str.into()])?;
-//! let foo = instance.get_typed_func::<(), ()>(&mut store, "foo")?;
-//! foo.call(&mut store, ())?;
-//! # Ok(())
-//! # }
-//! ```
 
 #![deny(missing_docs)]
 #![doc(test(attr(deny(warnings))))]
@@ -434,6 +282,7 @@ pub use crate::engine::*;
 /// This type can be used to interact with `wasmtimes`'s extensive use
 /// of `anyhow::Error` while still not directly depending on `anyhow`.
 /// This type alias is identical to `anyhow::Result`.
+#[doc(no_inline)]
 pub use anyhow::{Error, Result};
 
 fn _assert_send_and_sync<T: Send + Sync>() {}
diff --git a/crates/wasmtime/src/runtime/component/component.rs b/crates/wasmtime/src/runtime/component/component.rs
index 11280ef2c..9b03c8cc2 100644
--- a/crates/wasmtime/src/runtime/component/component.rs
+++ b/crates/wasmtime/src/runtime/component/component.rs
@@ -20,8 +20,36 @@ use wasmtime_runtime::{
 };
 
 /// A compiled WebAssembly Component.
-//
-// FIXME: need to write more docs here.
+///
+/// This structure represents a compiled component that is ready to be
+/// instantiated. This owns a region of virtual memory which contains executable
+/// code compiled from a WebAssembly binary originally. This is the analog of
+/// [`Module`](crate::Module) in the component embedding API.
+///
+/// A [`Component`] can be turned into an
+/// [`Instance`](crate::component::Instance) through a
+/// [`Linker`](crate::component::Linker). [`Component`]s are safe to share
+/// across threads. The compilation model of a component is the same as that of
+/// [a module](crate::Module) which is to say:
+///
+/// * Compilation happens synchronously during [`Component::new`].
+/// * The result of compilation can be saved into storage with
+///   [`Component::serialize`].
+/// * A previously compiled artifact can be parsed with
+///   [`Component::deserialize`].
+/// * No compilation happens at runtime for a component — everything is done
+///   by the time [`Component::new`] returns.
+///
+/// ## Components and `Clone`
+///
+/// Using `clone` on a `Component` is a cheap operation. It will not create an
+/// entirely new component, but rather just a new reference to the existing
+/// component. In other words it's a shallow copy, not a deep copy.
+///
+/// ## Examples
+///
+/// For example usage see the documentation of [`Module`](crate::Module) as
+/// [`Component`] has the same high-level API.
 #[derive(Clone)]
 pub struct Component {
     inner: Arc<ComponentInner>,
@@ -53,10 +81,64 @@ pub(crate) struct AllCallFuncPointers {
 }
 
 impl Component {
-    /// Compiles a new WebAssembly component from the in-memory wasm image
+    /// Compiles a new WebAssembly component from the in-memory list of bytes
     /// provided.
-    //
-    // FIXME: need to write more docs here.
+    ///
+    /// The `bytes` provided can either be the binary or text format of a
+    /// [WebAssembly component]. Note that the text format requires the `wat`
+    /// feature of this crate to be enabled. This API does not support
+    /// streaming compilation.
+    ///
+    /// This function will synchronously validate the entire component,
+    /// including all core modules, and then compile all components, modules,
+    /// etc., found within the provided bytes.
+    ///
+    /// [WebAssembly component]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md
+    ///
+    /// # Errors
+    ///
+    /// This function may fail and return an error. Errors may include
+    /// situations such as:
+    ///
+    /// * The binary provided could not be decoded because it's not a valid
+    ///   WebAssembly binary
+    /// * The WebAssembly binary may not validate (e.g. contains type errors)
+    /// * Implementation-specific limits were exceeded with a valid binary (for
+    ///   example too many locals)
+    /// * The wasm binary may use features that are not enabled in the
+    ///   configuration of `engine`
+    /// * If the `wat` feature is enabled and the input is text, then it may be
+    ///   rejected if it fails to parse.
+    ///
+    /// The error returned should contain full information about why compilation
+    /// failed.
+    ///
+    /// # Examples
+    ///
+    /// The `new` function can be invoked with a in-memory array of bytes:
+    ///
+    /// ```no_run
+    /// # use wasmtime::*;
+    /// # use wasmtime::component::Component;
+    /// # fn main() -> anyhow::Result<()> {
+    /// # let engine = Engine::default();
+    /// # let wasm_bytes: Vec<u8> = Vec::new();
+    /// let component = Component::new(&engine, &wasm_bytes)?;
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// Or you can also pass in a string to be parsed as the wasm text
+    /// format:
+    ///
+    /// ```
+    /// # use wasmtime::*;
+    /// # use wasmtime::component::Component;
+    /// # fn main() -> anyhow::Result<()> {
+    /// # let engine = Engine::default();
+    /// let component = Component::new(&engine, "(component (core module))")?;
+    /// # Ok(())
+    /// # }
     #[cfg(any(feature = "cranelift", feature = "winch"))]
     #[cfg_attr(nightlydoc, doc(cfg(any(feature = "cranelift", feature = "winch"))))]
     pub fn new(engine: &Engine, bytes: impl AsRef<[u8]>) -> Result<Component> {
@@ -66,10 +148,11 @@ impl Component {
         Component::from_binary(engine, &bytes)
     }
 
-    /// Compiles a new WebAssembly component from a wasm file on disk pointed to
-    /// by `file`.
-    //
-    // FIXME: need to write more docs here.
+    /// Compiles a new WebAssembly component from a wasm file on disk pointed
+    /// to by `file`.
+    ///
+    /// This is a convenience function for reading the contents of `file` on
+    /// disk and then calling [`Component::new`].
     #[cfg(any(feature = "cranelift", feature = "winch"))]
     #[cfg_attr(nightlydoc, doc(cfg(any(feature = "cranelift", feature = "winch"))))]
     pub fn from_file(engine: &Engine, file: impl AsRef<Path>) -> Result<Component> {
@@ -94,8 +177,13 @@ impl Component {
 
     /// Compiles a new WebAssembly component from the in-memory wasm image
     /// provided.
-    //
-    // FIXME: need to write more docs here.
+    ///
+    /// This function is the same as [`Component::new`] except that it does not
+    /// accept the text format of WebAssembly. Even if the `wat` feature
+    /// is enabled an error will be returned here if `binary` is the text
+    /// format.
+    ///
+    /// For more information on semantics and errors see [`Component::new`].
     #[cfg(any(feature = "cranelift", feature = "winch"))]
     #[cfg_attr(nightlydoc, doc(cfg(any(feature = "cranelift", feature = "winch"))))]
     pub fn from_binary(engine: &Engine, binary: &[u8]) -> Result<Component> {
@@ -153,12 +241,17 @@ impl Component {
 
     /// Same as [`Module::deserialize`], but for components.
     ///
-    /// Note that the file referenced here must contain contents previously
+    /// Note that the bytes referenced here must contain contents previously
     /// produced by [`Engine::precompile_component`] or
     /// [`Component::serialize`].
     ///
     /// For more information see the [`Module::deserialize`] method.
     ///
+    /// # Unsafety
+    ///
+    /// The unsafety of this method is the same as that of the
+    /// [`Module::deserialize`] method.
+    ///
     /// [`Module::deserialize`]: crate::Module::deserialize
     pub unsafe fn deserialize(engine: &Engine, bytes: impl AsRef<[u8]>) -> Result<Component> {
         let code = engine.load_code_bytes(bytes.as_ref(), ObjectKind::Component)?;
@@ -167,8 +260,16 @@ impl Component {
 
     /// Same as [`Module::deserialize_file`], but for components.
     ///
-    /// For more information see the [`Component::deserialize`] and
-    /// [`Module::deserialize_file`] methods.
+    /// Note that the file referenced here must contain contents previously
+    /// produced by [`Engine::precompile_component`] or
+    /// [`Component::serialize`].
+    ///
+    /// For more information see the [`Module::deserialize_file`] method.
+    ///
+    /// # Unsafety
+    ///
+    /// The unsafety of this method is the same as that of the
+    /// [`Module::deserialize_file`] method.
     ///
     /// [`Module::deserialize_file`]: crate::Module::deserialize_file
     pub unsafe fn deserialize_file(engine: &Engine, path: impl AsRef<Path>) -> Result<Component> {
diff --git a/crates/wasmtime/src/runtime/component/func.rs b/crates/wasmtime/src/runtime/component/func.rs
index cf4f710f1..3088dec87 100644
--- a/crates/wasmtime/src/runtime/component/func.rs
+++ b/crates/wasmtime/src/runtime/component/func.rs
@@ -85,9 +85,13 @@ union ParamsAndResults<Params: Copy, Return: Copy> {
     ret: Return,
 }
 
-/// A WebAssembly component function.
-//
-// FIXME: write more docs here
+/// A WebAssembly component function which can be called.
+///
+/// This type is the dual of [`wasmtime::Func`](crate::Func) for component
+/// functions. An instance of [`Func`] represents a component function from a
+/// component [`Instance`](crate::component::Instance). Like with
+/// [`wasmtime::Func`](crate::Func) it's possible to call functions either
+/// synchronously or asynchronously and either typed or untyped.
 #[derive(Copy, Clone, Debug)]
 pub struct Func(Stored<FuncData>);
 
@@ -150,8 +154,8 @@ impl Func {
     /// The `Params` type parameter here is a tuple of the parameters to the
     /// function. A function which takes no arguments should use `()`, a
     /// function with one argument should use `(T,)`, etc. Note that all
-    /// `Params` must also implement the [`Lower`] trait since they're going tin
-    /// to wasm.
+    /// `Params` must also implement the [`Lower`] trait since they're going
+    /// into wasm.
     ///
     /// The `Return` type parameter is the return value of this function. A
     /// return value of `()` means that there's no return (similar to a Rust
@@ -164,6 +168,9 @@ impl Func {
     /// primitives, floats, `Option<T>`, `Result<T, E>`, strings, `Vec<T>`, and
     /// more. As parameters you'll be passing native Rust types.
     ///
+    /// See the documentation for [`ComponentType`] for more information about
+    /// supported types.
+    ///
     /// # Errors
     ///
     /// If the function does not actually take `Params` as its parameters or
@@ -284,15 +291,39 @@ impl Func {
 
     /// Invokes this function with the `params` given and returns the result.
     ///
-    /// The `params` here must match the type signature of this `Func`, or this will return an error. If a trap
-    /// occurs while executing this function, then an error will also be returned.
-    // TODO: say more -- most of the docs for `TypedFunc::call` apply here, too
-    //
-    // # Panics
-    //
-    // Panics if this is called on a function in an asyncronous store. This only works
-    // with functions defined within a synchronous store. Also panics if `store`
-    // does not own this function.
+    /// The `params` provided must match the parameters that this function takes
+    /// in terms of their types and the number of parameters. Results will be
+    /// written to the `results` slice provided if the call completes
+    /// successfully. The initial types of the values in `results` are ignored
+    /// and values are overwritten to write the result. It's required that the
+    /// size of `results` exactly matches the number of results that this
+    /// function produces.
+    ///
+    /// Note that after a function is invoked the embedder needs to invoke
+    /// [`Func::post_return`] to execute any final cleanup required by the
+    /// guest. This function call is required to either call the function again
+    /// or to call another function.
+    ///
+    /// For more detailed information see the documentation of
+    /// [`TypedFunc::call`].
+    ///
+    /// # Errors
+    ///
+    /// Returns an error in situations including but not limited to:
+    ///
+    /// * `params` is not the right size or if the values have the wrong type
+    /// * `results` is not the right size
+    /// * A trap occurs while executing the function
+    /// * The function calls a host function which returns an error
+    ///
+    /// See [`TypedFunc::call`] for more information in addition to
+    /// [`wasmtime::Func::call`](crate::Func::call).
+    ///
+    /// # Panics
+    ///
+    /// Panics if this is called on a function in an asyncronous store. This
+    /// only works with functions defined within a synchronous store. Also
+    /// panics if `store` does not own this function.
     pub fn call(
         &self,
         mut store: impl AsContextMut,
@@ -309,11 +340,14 @@ impl Func {
 
     /// Exactly like [`Self::call`] except for use on async stores.
     ///
+    /// Note that after this [`Func::post_return_async`] will be used instead of
+    /// the synchronous version at [`Func::post_return`].
+    ///
     /// # Panics
     ///
-    /// Panics if this is called on a function in a synchronous store. This only works
-    /// with functions defined within an asynchronous store. Also panics if `store`
-    /// does not own this function.
+    /// Panics if this is called on a function in a synchronous store. This
+    /// only works with functions defined within an asynchronous store. Also
+    /// panics if `store` does not own this function.
     #[cfg(feature = "async")]
     #[cfg_attr(nightlydoc, doc(cfg(feature = "async")))]
     pub async fn call_async<T>(
@@ -539,11 +573,9 @@ impl Func {
     /// Invokes the `post-return` canonical ABI option, if specified, after a
     /// [`Func::call`] has finished.
     ///
-    /// For some more information on when to use this function see the
-    /// documentation for post-return in the [`Func::call`] method.
-    /// Otherwise though this function is a required method call after a
-    /// [`Func::call`] completes successfully. After the embedder has
-    /// finished processing the return value then this function must be invoked.
+    /// This function is a required method call after a [`Func::call`] completes
+    /// successfully. After the embedder has finished processing the return
+    /// value then this function must be invoked.
     ///
     /// # Errors
     ///
@@ -598,7 +630,6 @@ impl Func {
         store.on_fiber(|store| self.post_return_impl(store)).await?
     }
 
-    #[inline]
     fn post_return_impl(&self, mut store: impl AsContextMut) -> Result<()> {
         let mut store = store.as_context_mut();
         let data = &mut store.0[self.0];
diff --git a/crates/wasmtime/src/runtime/component/func/typed.rs b/crates/wasmtime/src/runtime/component/func/typed.rs
index a52441899..ba728f685 100644
--- a/crates/wasmtime/src/runtime/component/func/typed.rs
+++ b/crates/wasmtime/src/runtime/component/func/typed.rs
@@ -29,6 +29,8 @@ use wasmtime_runtime::SendSyncPtr;
 /// and usage will panic if used with the wrong store.
 ///
 /// This type is primarily created with the [`Func::typed`] API.
+///
+/// See [`ComponentType`] for more information about supported types.
 pub struct TypedFunc<Params, Return> {
     func: Func,
 
@@ -365,11 +367,47 @@ pub unsafe trait ComponentNamedList: ComponentType {}
 /// with the canonical ABI.
 ///
 /// This trait is implemented for Rust types which can be communicated to
-/// components. This is implemented for Rust types which correspond to
-/// interface types in the component model of WebAssembly. The [`Func::typed`]
-/// and [`TypedFunc`] Rust items are the main consumers of this trait.
+/// components. The [`Func::typed`] and [`TypedFunc`] Rust items are the main
+/// consumers of this trait.
+///
+/// Supported Rust types include:
+///
+/// | Component Model Type              | Rust Type                            |
+/// |-----------------------------------|--------------------------------------|
+/// | `{s,u}{8,16,32,64}`               | `{i,u}{8,16,32,64}`                  |
+/// | `f{32,64}`                        | `f{32,64}`                           |
+/// | `bool`                            | `bool`                               |
+/// | `char`                            | `char`                               |
+/// | `tuple<A, B>`                     | `(A, B)`                             |
+/// | `option<T>`                       | `Option<T>`                          |
+/// | `result`                          | `Result<(), ()>`                     |
+/// | `result<T>`                       | `Result<T, ()>`                      |
+/// | `result<_, E>`                    | `Result<(), E>`                      |
+/// | `result<T, E>`                    | `Result<T, E>`                       |
+/// | `string`                          | `String`, `&str`, or [`WasmStr`]     |
+/// | `list<T>`                         | `Vec<T>`, `&[T]`, or [`WasmList`]    |
+/// | `own<T>`, `borrow<T>`             | [`Resource<T>`] or [`ResourceAny`]   |
+/// | `record`                          | [`#[derive(ComponentType)]`][d-cm]   |
+/// | `variant`                         | [`#[derive(ComponentType)]`][d-cm]   |
+/// | `enum`                            | [`#[derive(ComponentType)]`][d-cm]   |
+/// | `flags`                           | [`flags!`][f-m]                      |
 ///
-/// For more information on this trait see the examples in [`Func::typed`].
+/// [`Resource<T>`]: crate::component::Resource
+/// [`ResourceAny`]: crate::component::ResourceAny
+/// [d-cm]: macro@crate::component::ComponentType
+/// [f-m]: crate::component::flags
+///
+/// Rust standard library pointers such as `&T`, `Box<T>`, `Rc<T>`, and `Arc<T>`
+/// additionally represent whatever type `T` represents in the component model.
+/// Note that types such as `record`, `variant`, `enum`, and `flags` are
+/// generated by the embedder at compile time. These macros derive
+/// implementation of this trait for custom types to map to custom types in the
+/// component model. Note that for `record`, `variant`, `enum`, and `flags`
+/// those types are often generated by the
+/// [`bindgen!`](crate::component::bindgen) macro from WIT definitions.
+///
+/// Types that implement [`ComponentType`] are used for `Params` and `Return`
+/// in [`TypedFunc`] and [`Func::typed`].
 ///
 /// The contents of this trait are hidden as it's intended to be an
 /// implementation detail of Wasmtime. The contents of this trait are not
@@ -454,9 +492,18 @@ pub unsafe trait ComponentVariant: ComponentType {
 /// either as parameters of component exports or returns of component imports.
 /// This trait represents the ability to convert from the native host
 /// representation to the canonical ABI.
-//
-// TODO: #[derive(Lower)]
-// TODO: more docs here
+///
+/// Built-in types to Rust such as `Option<T>` implement this trait as
+/// appropriate. For a mapping of component model to Rust types see
+/// [`ComponentType`].
+///
+/// For user-defined types, for example `record` types mapped to Rust `struct`s,
+/// this crate additionally has
+/// [`#[derive(Lower)]`](macro@crate::component::Lower).
+///
+/// Note that like [`ComponentType`] the definition of this trait is intended to
+/// be an internal implementation detail of Wasmtime at this time. It's
+/// recommended to use the `#[derive(Lower)]` implementation instead.
 pub unsafe trait Lower: ComponentType {
     /// Performs the "lower" function in the canonical ABI.
     ///
@@ -535,9 +582,21 @@ pub unsafe trait Lower: ComponentType {
 }
 
 /// Host types which can be created from the canonical ABI.
-//
-// TODO: #[derive(Lower)]
-// TODO: more docs here
+///
+/// This is the mirror of the [`Lower`] trait where it represents the capability
+/// of acquiring items from WebAssembly and passing them to the host.
+///
+/// Built-in types to Rust such as `Option<T>` implement this trait as
+/// appropriate. For a mapping of component model to Rust types see
+/// [`ComponentType`].
+///
+/// For user-defined types, for example `record` types mapped to Rust `struct`s,
+/// this crate additionally has
+/// [`#[derive(Lift)]`](macro@crate::component::Lift).
+///
+/// Note that like [`ComponentType`] the definition of this trait is intended to
+/// be an internal implementation detail of Wasmtime at this time. It's
+/// recommended to use the `#[derive(Lift)]` implementation instead.
 pub unsafe trait Lift: Sized + ComponentType {
     /// Performs the "lift" operation in the canonical ABI.
     ///
@@ -1178,6 +1237,23 @@ fn lower_string<T>(cx: &mut LowerContext<'_, T>, string: &str) -> Result<(usize,
 /// Representation of a string located in linear memory in a WebAssembly
 /// instance.
 ///
+/// This type can be used in place of `String` and `str` for string-taking APIs
+/// in some situations. The purpose of this type is to represent a range of
+/// validated bytes within a component but does not actually copy the bytes. The
+/// primary method, [`WasmStr::to_str`], attempts to return a reference to the
+/// string directly located in the component's memory, avoiding a copy into the
+/// host if possible.
+///
+/// The downside of this type, however, is that accessing a string requires a
+/// [`Store`](crate::Store) pointer (via [`StoreContext`]). Bindings generated
+/// by [`bindgen!`](crate::component::bindgen), for example, do not have access
+/// to [`StoreContext`] and thus can't use this type.
+///
+/// This is intended for more advanced use cases such as defining functions
+/// directly in a [`Linker`](crate::component::Linker). It's expected that in
+/// the future [`bindgen!`](crate::component::bindgen) will also have a way to
+/// use this type.
+///
 /// This type is used with [`TypedFunc`], for example, when WebAssembly returns
 /// a string. This type cannot be used to give a string to WebAssembly, instead
 /// `&str` should be used for that (since it's coming from the host).
@@ -1185,8 +1261,9 @@ fn lower_string<T>(cx: &mut LowerContext<'_, T>, string: &str) -> Result<(usize,
 /// Note that this type represents an in-bounds string in linear memory, but it
 /// does not represent a valid string (e.g. valid utf-8). Validation happens
 /// when [`WasmStr::to_str`] is called.
-//
-// TODO: should probably expand this with examples
+///
+/// Also note that this type does not implement [`Lower`], it only implements
+/// [`Lift`].
 pub struct WasmStr {
     ptr: usize,
     len: usize,
@@ -1414,6 +1491,11 @@ where
 
 /// Representation of a list of values that are owned by a WebAssembly instance.
 ///
+/// For some more commentary about the rationale for this type see the
+/// documentation of [`WasmStr`]. In summary this type can avoid a copy when
+/// passing data to the host in some situations but is additionally more
+/// cumbersome to use by requiring a [`Store`](crate::Store) to be provided.
+///
 /// This type is used whenever a `(list T)` is returned from a [`TypedFunc`],
 /// for example. This type represents a list of values that are stored in linear
 /// memory which are waiting to be read.
@@ -1421,6 +1503,8 @@ where
 /// Note that this type represents only a valid range of bytes for the list
 /// itself, it does not represent validity of the elements themselves and that's
 /// performed when they're iterated.
+///
+/// Note that this type does not implement the [`Lower`] trait, only [`Lift`].
 pub struct WasmList<T> {
     ptr: usize,
     len: usize,
diff --git a/crates/wasmtime/src/runtime/component/instance.rs b/crates/wasmtime/src/runtime/component/instance.rs
index a3f2a2025..b90aee0bb 100644
--- a/crates/wasmtime/src/runtime/component/instance.rs
+++ b/crates/wasmtime/src/runtime/component/instance.rs
@@ -19,11 +19,18 @@ use wasmtime_runtime::VMFuncRef;
 
 /// An instantiated component.
 ///
-/// This is similar to [`crate::Instance`] except that it represents an
-/// instantiated component instead of an instantiated module. Otherwise though
-/// the two behave similarly.
-//
-// FIXME: need to write more docs here.
+/// This type represents an instantiated [`Component`](super::Component).
+/// Instances have exports which can be accessed through functions such as
+/// [`Instance::get_func`] or [`Instance::exports`]. Instances are owned by a
+/// [`Store`](crate::Store) and all methods require a handle to the store.
+///
+/// Component instances are created through
+/// [`Linker::instantiate`](super::Linker::instantiate) and its family of
+/// methods.
+///
+/// This type is similar to the core wasm version
+/// [`wasmtime::Instance`](crate::Instance) except that it represents an
+/// instantiated component instead of an instantiated module.
 #[derive(Copy, Clone)]
 pub struct Instance(pub(crate) Stored<Option<Box<InstanceData>>>);
 
diff --git a/crates/wasmtime/src/runtime/component/mod.rs b/crates/wasmtime/src/runtime/component/mod.rs
index e820525e2..821ef6259 100644
--- a/crates/wasmtime/src/runtime/component/mod.rs
+++ b/crates/wasmtime/src/runtime/component/mod.rs
@@ -1,7 +1,43 @@
-//! In-progress implementation of the WebAssembly component model
+//! # Embedding API for the Component Model
 //!
-//! This module is a work-in-progress and currently represents an incomplete and
-//! probably buggy implementation of the component model.
+//! This module contains the embedding API for the [Component Model] in
+//! Wasmtime. This module requires the `component-model` feature to be enabled,
+//! which is enabled by default. The embedding API here is mirrored after the
+//! core wasm embedding API at the crate root and is intended to have the same
+//! look-and-feel while handling concepts of the component model.
+//!
+//! [Component Model]: https://component-model.bytecodealliance.org
+//!
+//! The component model is a broad topic which can't be explained here fully, so
+//! it's recommended to read over individual items' documentation to see more
+//! about the capabilities of the embedding API. At a high-level, however,
+//! perhaps the most interesting items in this module are:
+//!
+//! * [`Component`] - a compiled component ready to be instantiated. Similar to
+//!   a [`Module`](crate::Module) for core wasm.
+//!
+//! * [`Linker`] - a component-style location for defining host functions. This
+//!   is not the same as [`wasmtime::Linker`](crate::Linker) for core wasm
+//!   modules.
+//!
+//! * [`bindgen!`] - a macro to generate Rust bindings for a [WIT] [world]. This
+//!   maps all WIT types into Rust automatically and generates traits for
+//!   embedders to implement.
+//!
+//! [WIT]: https://component-model.bytecodealliance.org/design/wit.html
+//! [world]: https://component-model.bytecodealliance.org/design/worlds.html
+//!
+//! Embedders of the component model will typically start by defining their API
+//! in [WIT]. This describes what will be available to guests and what needs to
+//! be provided to the embedder by the guest. This [`world`][world] that was
+//! created is then fed into [`bindgen!`] to generate types and traits for the
+//! embedder to use. The embedder then implements these traits, adds
+//! functionality via the generated `add_to_linker` method (see [`bindgen!`] for
+//! more info), and then instantiates/executes a component.
+//!
+//! It's recommended to read over the [documentation for the Component
+//! Model][Component Model] to get an overview about how to build components
+//! from various languages.
 
 #![cfg_attr(nightlydoc, doc(cfg(feature = "component-model")))]
 
@@ -26,7 +62,6 @@ pub use self::resource_table::{ResourceTable, ResourceTableError};
 pub use self::resources::{Resource, ResourceAny};
 pub use self::types::{ResourceType, Type};
 pub use self::values::{Enum, Flags, List, OptionVal, Record, ResultVal, Tuple, Val, Variant};
-pub use wasmtime_component_macro::{flags, ComponentType, Lift, Lower};
 
 // These items are expected to be used by an eventual
 // `#[derive(ComponentType)]`, they are not part of Wasmtime's API stability
@@ -50,26 +85,26 @@ pub mod __internal {
 
 pub(crate) use self::store::ComponentStoreData;
 
-/// Generate bindings for a WIT package.
+/// Generate bindings for a [WIT world].
+///
+/// [WIT world]: https://component-model.bytecodealliance.org/design/worlds.html
+/// [WIT package]: https://component-model.bytecodealliance.org/design/packages.html
 ///
-/// This macro ingests a [WIT package] and will generate all the necessary
-/// bindings for instantiating and invoking a particular `world` in the
-/// package. A `world` in a WIT package is a description of imports and exports
-/// for a component. This provides a higher-level representation of working with
-/// a component than the raw [`Instance`] type which must be manually-type-check
-/// and manually have its imports provided via the [`Linker`] type.
+/// This macro ingests a [WIT world] and will generate all the necessary
+/// bindings for instantiating components that ascribe to the `world`. This
+/// provides a higher-level representation of working with a component than the
+/// raw [`Instance`] type which must be manually-type-checked and manually have
+/// its imports provided via the [`Linker`] type.
 ///
 /// The most basic usage of this macro is:
 ///
 /// ```rust,ignore
-/// wasmtime::component::bindgen!("my-component");
+/// wasmtime::component::bindgen!();
 /// ```
 ///
-/// This will parse your projects WIT package in a `wit` directory adjacent to
+/// This will parse your projects [WIT package] in a `wit` directory adjacent to
 /// your crate's `Cargo.toml`. All of the `*.wit` files in that directory are
-/// parsed and then the `default world` will be looked up within
-/// `my-component.wit`. This world is then used as the basis for generating
-/// bindings.
+/// parsed and then the single `world` found will be used for bindings.
 ///
 /// For example if your project contained:
 ///
@@ -86,18 +121,29 @@ pub(crate) use self::store::ComponentStoreData;
 ///
 /// Then you can interact with the generated bindings like so:
 ///
-/// ```rust,ignore
+/// ```rust
 /// use wasmtime::component::*;
 /// use wasmtime::{Config, Engine, Store};
 ///
+/// # const _: () = { macro_rules! bindgen { () => () }
 /// bindgen!();
+/// # };
+/// # bindgen!({
+/// #   inline: r#"
+/// #       package my:project;
+/// #       world hello-world {
+/// #           import name: func() -> string;
+/// #           export greet: func();
+/// #       }
+/// #   "#,
+/// # });
 ///
 /// struct MyState {
 ///     name: String,
 /// }
 ///
-/// // Imports into the world, like the `name` import for this world, are satisfied
-/// // through traits.
+/// // Imports into the world, like the `name` import for this world, are
+/// // satisfied through traits.
 /// impl HelloWorldImports for MyState {
 ///     // Note the `Result` return value here where `Ok` is returned back to
 ///     // the component and `Err` will raise a trap.
@@ -107,6 +153,7 @@ pub(crate) use self::store::ComponentStoreData;
 /// }
 ///
 /// fn main() -> wasmtime::Result<()> {
+/// #   if true { return Ok(()) }
 ///     // Configure an `Engine` and compile the `Component` that is being run for
 ///     // the application.
 ///     let mut config = Config::new();
@@ -162,7 +209,7 @@ pub(crate) use self::store::ComponentStoreData;
 ///     sha256: func(bytes: list<u8>) -> string;
 /// }
 ///
-/// default world hello-world {
+/// world hello-world {
 ///     import host;
 ///
 ///     export demo: interface {
@@ -173,12 +220,32 @@ pub(crate) use self::store::ComponentStoreData;
 ///
 /// Then you can interact with the generated bindings like so:
 ///
-/// ```rust,ignore
+/// ```rust
 /// use wasmtime::component::*;
 /// use wasmtime::{Config, Engine, Store};
 /// use my::project::host::Host;
 ///
+/// # const _: () = { macro_rules! bindgen { () => () }
 /// bindgen!();
+/// # };
+/// # bindgen!({
+/// #   inline: r#"
+/// # package my:project;
+/// #
+/// # interface host {
+/// #     gen-random-integer: func() -> u32;
+/// #     sha256: func(bytes: list<u8>) -> string;
+/// # }
+/// #
+/// # world hello-world {
+/// #     import host;
+/// #
+/// #     export demo: interface {
+/// #         run: func();
+/// #     }
+/// # }
+/// #   "#,
+/// # });
 ///
 /// struct MyState {
 ///     // ...
@@ -187,15 +254,19 @@ pub(crate) use self::store::ComponentStoreData;
 /// // Note that the trait here is per-interface and within a submodule now.
 /// impl Host for MyState {
 ///     fn gen_random_integer(&mut self) -> wasmtime::Result<u32> {
+/// #       panic!();
+/// #       #[cfg(FALSE)]
 ///         Ok(rand::thread_rng().gen())
 ///     }
 ///
 ///     fn sha256(&mut self, bytes: Vec<u8>) -> wasmtime::Result<String> {
 ///         // ...
+/// #       panic!()
 ///     }
 /// }
 ///
 /// fn main() -> wasmtime::Result<()> {
+/// #   if true { return Ok(()) }
 ///     let mut config = Config::new();
 ///     config.wasm_component_model(true);
 ///     let engine = Engine::new(&config)?;
@@ -227,12 +298,12 @@ pub(crate) use self::store::ComponentStoreData;
 /// `world` from the parsed package. There are then codegen-specific options to
 /// the bindings themselves which can additionally be specified.
 ///
-/// Basic usage of this macro looks like:
+/// Usage of this macro looks like:
 ///
 /// ```rust,ignore
 /// // Parse the `wit/` folder adjacent to this crate's `Cargo.toml` and look
-/// // for a `default world` in its documents. There must be exactly one
-/// // `default world` for this to succeed.
+/// // for a single `world` in it. There must be exactly one for this to
+/// // succeed.
 /// bindgen!();
 ///
 /// // Parse the `wit/` folder adjacent to this crate's `Cargo.toml` and look
@@ -346,6 +417,260 @@ pub(crate) use self::store::ComponentStoreData;
 ///     },
 /// });
 /// ```
-///
-/// [WIT package]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md
 pub use wasmtime_component_macro::bindgen;
+
+/// Derive macro to generate implementations of the [`ComponentType`] trait.
+///
+/// This derive macro can be applied to `struct` and `enum` definitions and is
+/// used to bind either a `record`, `enum`, or `variant` in the component model.
+///
+/// Note you might be looking for [`bindgen!`] rather than this macro as that
+/// will generate the entire type for you rather than just a trait
+/// implementation.
+///
+/// This macro supports a `#[component]` attribute which is used to customize
+/// how the type is bound to the component model. A top-level `#[component]`
+/// attribute is required to specify either `record`, `enum`, or `variant`.
+///
+/// ## Records
+///
+/// `record`s in the component model correspond to `struct`s in Rust. An example
+/// is:
+///
+/// ```rust
+/// use wasmtime::component::ComponentType;
+///
+/// #[derive(ComponentType)]
+/// #[component(record)]
+/// struct Color {
+///     r: u8,
+///     g: u8,
+///     b: u8,
+/// }
+/// ```
+///
+/// which corresponds to the WIT type:
+///
+/// ```wit
+/// record color {
+///     r: u8,
+///     g: u8,
+///     b: u8,
+/// }
+/// ```
+///
+/// Note that the name `Color` here does not need to match the name in WIT.
+/// That's purely used as a name in Rust of what to refer to. The field names
+/// must match that in WIT, however. Field names can be customized with the
+/// `#[component]` attribute though.
+///
+/// ```rust
+/// use wasmtime::component::ComponentType;
+///
+/// #[derive(ComponentType)]
+/// #[component(record)]
+/// struct VerboseColor {
+///     #[component(name = "r")]
+///     red: u8,
+///     #[component(name = "g")]
+///     green: u8,
+///     #[component(name = "b")]
+///     blue: u8,
+/// }
+/// ```
+///
+/// Also note that field ordering is significant at this time and must match
+/// WIT.
+///
+/// ## Variants
+///
+/// `variant`s in the component model correspond to a subset of shapes of a Rust
+/// `enum`. Variants in the component model have a single optional payload type
+/// which means that not all Rust `enum`s correspond to component model
+/// `variant`s. An example variant is:
+///
+/// ```rust
+/// use wasmtime::component::ComponentType;
+///
+/// #[derive(ComponentType)]
+/// #[component(variant)]
+/// enum Filter {
+///     #[component(name = "none")]
+///     None,
+///     #[component(name = "all")]
+///     All,
+///     #[component(name = "some")]
+///     Some(Vec<String>),
+/// }
+/// ```
+///
+/// which corresponds to the WIT type:
+///
+/// ```wit
+/// variant filter {
+///     none,
+///     all,
+///     some(list<string>),
+/// }
+/// ```
+///
+/// The `variant` style of derive allows an optional payload on Rust `enum`
+/// variants but it must be a single unnamed field. Variants of the form `Foo(T,
+/// U)` or `Foo { name: T }` are not supported at this time.
+///
+/// Note that the order of variants in Rust must match the order of variants in
+/// WIT. Additionally it's likely that `#[component(name = "...")]` is required
+/// on all Rust `enum` variants because the name currently defaults to the Rust
+/// name which is typically UpperCamelCase whereas WIT uses kebab-case.
+///
+/// ## Enums
+///
+/// `enum`s in the component model correspond to C-like `enum`s in Rust. Note
+/// that a component model `enum` does not allow any payloads so the Rust `enum`
+/// must additionally have no payloads.
+///
+/// ```rust
+/// use wasmtime::component::ComponentType;
+///
+/// #[derive(ComponentType)]
+/// #[component(enum)]
+/// enum Setting {
+///     #[component(name = "yes")]
+///     Yes,
+///     #[component(name = "no")]
+///     No,
+///     #[component(name = "auto")]
+///     Auto,
+/// }
+/// ```
+///
+/// which corresponds to the WIT type:
+///
+/// ```wit
+/// enum setting {
+///     yes,
+///     no,
+///     auto,
+/// }
+/// ```
+///
+/// Note that the order of variants in Rust must match the order of variants in
+/// WIT. Additionally it's likely that `#[component(name = "...")]` is required
+/// on all Rust `enum` variants because the name currently defaults to the Rust
+/// name which is typically UpperCamelCase whereas WIT uses kebab-case.
+pub use wasmtime_component_macro::ComponentType;
+
+/// A derive macro for generating implementations of the [`Lift`] trait.
+///
+/// This macro will likely be applied in conjunction with the
+/// [`#[derive(ComponentType)]`](macro@ComponentType) macro along the lines
+/// of `#[derive(ComponentType, Lift)]`. This trait enables reading values from
+/// WebAssembly.
+///
+/// Note you might be looking for [`bindgen!`] rather than this macro as that
+/// will generate the entire type for you rather than just a trait
+/// implementation.
+///
+/// At this time this derive macro has no configuration.
+///
+/// ## Examples
+///
+/// ```rust
+/// use wasmtime::component::{ComponentType, Lift};
+///
+/// #[derive(ComponentType, Lift)]
+/// #[component(record)]
+/// struct Color {
+///     r: u8,
+///     g: u8,
+///     b: u8,
+/// }
+/// ```
+pub use wasmtime_component_macro::Lift;
+
+/// A derive macro for generating implementations of the [`Lower`] trait.
+///
+/// This macro will likely be applied in conjunction with the
+/// [`#[derive(ComponentType)]`](macro@ComponentType) macro along the lines
+/// of `#[derive(ComponentType, Lower)]`. This trait enables passing values to
+/// WebAssembly.
+///
+/// Note you might be looking for [`bindgen!`] rather than this macro as that
+/// will generate the entire type for you rather than just a trait
+/// implementation.
+///
+/// At this time this derive macro has no configuration.
+///
+/// ## Examples
+///
+/// ```rust
+/// use wasmtime::component::{ComponentType, Lower};
+///
+/// #[derive(ComponentType, Lower)]
+/// #[component(record)]
+/// struct Color {
+///     r: u8,
+///     g: u8,
+///     b: u8,
+/// }
+/// ```
+pub use wasmtime_component_macro::Lower;
+
+/// A macro to generate a Rust type corresponding to WIT `flags`
+///
+/// This macro generates a type that implements the [`ComponentType`], [`Lift`],
+/// and [`Lower`] traits. The generated Rust type corresponds to the `flags`
+/// type in WIT.
+///
+/// Example usage of this looks like:
+///
+/// ```rust
+/// use wasmtime::component::flags;
+///
+/// flags! {
+///     Permissions {
+///         #[component(name = "read")]
+///         const READ;
+///         #[component(name = "write")]
+///         const WRITE;
+///         #[component(name = "execute")]
+///         const EXECUTE;
+///     }
+/// }
+///
+/// fn validate_permissions(permissions: &mut Permissions) {
+///     if permissions.contains(Permissions::EXECUTE | Permissions::WRITE) {
+///         panic!("cannot enable both writable and executable at the same time");
+///     }
+///
+///     if permissions.contains(Permissions::READ) {
+///         panic!("permissions must at least contain read");
+///     }
+/// }
+/// ```
+///
+/// which corresponds to the WIT type:
+///
+/// ```wit
+/// flags permissions {
+///     read,
+///     write,
+///     execute,
+/// }
+/// ```
+///
+/// This generates a structure which is similar to/inspired by the [`bitflags`
+/// crate](https://crates.io/crates/bitflags). The `Permissions` structure
+/// generated implements the [`PartialEq`], [`Eq`], [`Debug`], [`BitOr`],
+/// [`BitOrAssign`], [`BitAnd`], [`BitAndAssign`], [`BitXor`], [`BitXorAssign`],
+/// and [`Not`] traits - in addition to the Wasmtime-specific component ones
+/// [`ComponentType`], [`Lift`], and [`Lower`].
+///
+/// [`BitOr`]: std::ops::BitOr
+/// [`BitOrAssign`]: std::ops::BitOrAssign
+/// [`BitAnd`]: std::ops::BitAnd
+/// [`BitAndAssign`]: std::ops::BitAndAssign
+/// [`BitXor`]: std::ops::BitXor
+/// [`BitXorAssign`]: std::ops::BitXorAssign
+/// [`Not`]: std::ops::Not
+pub use wasmtime_component_macro::flags;
diff --git a/crates/wasmtime/src/runtime/component/values.rs b/crates/wasmtime/src/runtime/component/values.rs
index 0775dcf7b..52d08d120 100644
--- a/crates/wasmtime/src/runtime/component/values.rs
+++ b/crates/wasmtime/src/runtime/component/values.rs
@@ -13,7 +13,14 @@ use wasmtime_environ::component::{
     CanonicalAbiInfo, ComponentTypes, InterfaceType, TypeListIndex, VariantInfo,
 };
 
-/// Represents runtime list values
+/// Dynamic representation of `list<T>` in the component model.
+///
+/// This structure is part of the dynamically-typed [`Val`] which represents
+/// all possible values in the component model. This is often used in
+/// conjunction with [`Func::call`](crate::component::Func::call).
+///
+/// Note that `Vec<T>` is also supported for component model lists when
+/// using [`TypedFunc`](crate::component::TypedFunc).
 #[derive(PartialEq, Eq, Clone)]
 pub struct List {
     ty: types::List,
@@ -21,7 +28,12 @@ pub struct List {
 }
 
 impl List {
-    /// Instantiate the specified type with the specified `values`.
+    /// Creates a new list with the specified type with the specified `values`.
+    ///
+    /// # Errors
+    ///
+    /// Returns an error if any value in `values` does not have the element
+    /// type of `ty` specified.
     pub fn new(ty: &types::List, values: Box<[Val]>) -> Result<Self> {
         let element_type = ty.ty();
         for (index, value) in values.iter().enumerate() {
@@ -60,7 +72,15 @@ impl fmt::Debug for List {
     }
 }
 
-/// Represents runtime record values
+/// Dynamic representation of `record` in the component model.
+///
+/// This structure is part of the dynamically-typed [`Val`] which represents
+/// all possible values in the component model. This is often used in
+/// conjunction with [`Func::call`](crate::component::Func::call).
+///
+/// Note that records can also be mapped to Rust `struct`s through the
+/// [`#[derive(ComponentType)]`](macro@crate::component::ComponentType) macro
+/// and using [`TypedFunc`](crate::component::TypedFunc).
 #[derive(PartialEq, Eq, Clone)]
 pub struct Record {
     ty: types::Record,
@@ -68,7 +88,15 @@ pub struct Record {
 }
 
 impl Record {
-    /// Instantiate the specified type with the specified `values`.
+    /// Creates a new record with the specified `ty` and the `values` for fields.
+    ///
+    /// Note that the `values` specified for fields must list fields in the
+    /// same order that the `ty` lists them in.
+    ///
+    /// # Errors
+    ///
+    /// Returns an error if any of the `values` specified are in the wrong order
+    /// field-wise or have the wrong type relative to what's specified in `ty`.
     pub fn new<'a>(
         ty: &types::Record,
         values: impl IntoIterator<Item = (&'a str, Val)>,
@@ -111,8 +139,9 @@ impl Record {
         &self.ty
     }
 
-    /// Gets the value of the specified field `name` from this record.
-    pub fn fields(&self) -> impl Iterator<Item = (&str, &Val)> {
+    /// Returns the list of fields that this struct contains with their name
+    /// and value.
+    pub fn fields(&self) -> impl ExactSizeIterator<Item = (&str, &Val)> {
         assert_eq!(self.values.len(), self.ty.fields().len());
         self.ty
             .fields()
@@ -131,7 +160,14 @@ impl fmt::Debug for Record {
     }
 }
 
-/// Represents runtime tuple values
+/// Dynamic representation of `tuple<...>` in the component model.
+///
+/// This structure is part of the dynamically-typed [`Val`] which represents
+/// all possible values in the component model. This is often used in
+/// conjunction with [`Func::call`](crate::component::Func::call).
+///
+/// Note that tuples are also mapped to Rust tuples when using
+/// [`TypedFunc`](crate::component::TypedFunc).
 #[derive(PartialEq, Eq, Clone)]
 pub struct Tuple {
     ty: types::Tuple,
@@ -139,7 +175,13 @@ pub struct Tuple {
 }
 
 impl Tuple {
-    /// Instantiate the specified type ith the specified `values`.
+    /// Creates a new tuple with the `ty` specified and `values` for each
+    /// entry.
+    ///
+    /// # Errors
+    ///
+    /// Returns an error if `values` does not match the `ty` specified, such as
+    /// if it has the wrong length or if any field has the wrong type.
     pub fn new(ty: &types::Tuple, values: Box<[Val]>) -> Result<Self> {
         if values.len() != ty.types().len() {
             bail!(
@@ -181,7 +223,15 @@ impl fmt::Debug for Tuple {
     }
 }
 
-/// Represents runtime variant values
+/// Dynamic representation of `variant` in the component model.
+///
+/// This structure is part of the dynamically-typed [`Val`] which represents
+/// all possible values in the component model. This is often used in
+/// conjunction with [`Func::call`](crate::component::Func::call).
+///
+/// Note that variants can also be mapped to Rust `enum`s through the
+/// [`#[derive(ComponentType)]`](macro@crate::component::ComponentType) macro
+/// and using [`TypedFunc`](crate::component::TypedFunc).
 #[derive(PartialEq, Eq, Clone)]
 pub struct Variant {
     ty: types::Variant,
@@ -190,7 +240,18 @@ pub struct Variant {
 }
 
 impl Variant {
-    /// Instantiate the specified type with the specified case `name` and `value`.
+    /// Creates a new variant with the specified `ty` and the case `name` and
+    /// `value` provided.
+    ///
+    /// This will create a instance of a variant with the case `name` which has
+    /// the optional payload of `value`.
+    ///
+    /// # Errors
+    ///
+    /// Returns an error if `name` doesn't match any case of `ty` or if
+    /// `value` is of the wrong type. Note that `ty` must match the payload
+    /// type exactly, in that if the case for `name` doesn't have a type then
+    /// `value` must be `None`.
     pub fn new(ty: &types::Variant, name: &str, value: Option<Val>) -> Result<Self> {
         let (discriminant, case_type) = ty
             .cases()
@@ -272,7 +333,15 @@ impl fmt::Debug for Variant {
     }
 }
 
-/// Represents runtime enum values
+/// Dynamic representation of `enum` in the component model.
+///
+/// This structure is part of the dynamically-typed [`Val`] which represents
+/// all possible values in the component model. This is often used in
+/// conjunction with [`Func::call`](crate::component::Func::call).
+///
+/// Note that enums can also be mapped to Rust `enum`s through the
+/// [`#[derive(ComponentType)]`](macro@crate::component::ComponentType) macro
+/// and using [`TypedFunc`](crate::component::TypedFunc).
 #[derive(PartialEq, Eq, Clone)]
 pub struct Enum {
     ty: types::Enum,
@@ -280,7 +349,12 @@ pub struct Enum {
 }
 
 impl Enum {
-    /// Instantiate the specified type with the specified case `name`.
+    /// Creates a new enum value with the `ty` specified selecting the
+    /// specified variant called `name`.
+    ///
+    /// # Errors
+    ///
+    /// Returns an error if `name` isn't listed within `ty`.
     pub fn new(ty: &types::Enum, name: &str) -> Result<Self> {
         let discriminant = u32::try_from(
             ty.names()
@@ -328,7 +402,14 @@ impl fmt::Debug for Enum {
     }
 }
 
-/// Represents runtime option values
+/// Dynamic representation of `option<T>` in the component model.
+///
+/// This structure is part of the dynamically-typed [`Val`] which represents
+/// all possible values in the component model. This is often used in
+/// conjunction with [`Func::call`](crate::component::Func::call).
+///
+/// Note that options are also mapped to Rust `Option<T>` when using
+/// [`TypedFunc`](crate::component::TypedFunc).
 #[derive(PartialEq, Eq, Clone)]
 pub struct OptionVal {
     ty: types::OptionType,
@@ -337,7 +418,12 @@ pub struct OptionVal {
 }
 
 impl OptionVal {
-    /// Instantiate the specified type with the specified `value`.
+    /// Creates a new value with the `ty` specified holding the payload `value`.
+    ///
+    /// # Errors
+    ///
+    /// Returns an error if `value` is `Some` and the payload has the wrong
+    /// type for `ty`.
     pub fn new(ty: &types::OptionType, value: Option<Val>) -> Result<Self> {
         let value = value
             .map(|value| {
@@ -390,7 +476,14 @@ impl fmt::Debug for OptionVal {
     }
 }
 
-/// Represents runtime result values
+/// Dynamic representation of `result<T, E>` in the component model.
+///
+/// This structure is part of the dynamically-typed [`Val`] which represents
+/// all possible values in the component model. This is often used in
+/// conjunction with [`Func::call`](crate::component::Func::call).
+///
+/// Note that tuples are also mapped to Rust's `Result<T, E>` when using
+/// [`TypedFunc`](crate::component::TypedFunc).
 #[derive(PartialEq, Eq, Clone)]
 pub struct ResultVal {
     ty: types::ResultType,
@@ -399,7 +492,14 @@ pub struct ResultVal {
 }
 
 impl ResultVal {
-    /// Instantiate the specified type with the specified `value`.
+    /// Creates a new `Result` from the specified `ty` and `value`.
+    ///
+    /// Note that the `value` uses `Option<Val>` for payloads to map to the
+    /// optional payload value of the component model within each variant.
+    ///
+    /// # Errors
+    ///
+    /// Returns an error if the `value` payload has the wrong type for `ty`.
     pub fn new(ty: &types::ResultType, value: Result<Option<Val>, Option<Val>>) -> Result<Self> {
         Ok(Self {
             ty: ty.clone(),
@@ -459,7 +559,15 @@ impl fmt::Debug for ResultVal {
     }
 }
 
-/// Represents runtime flag values
+/// Dynamic representation of `flags` in the component model.
+///
+/// This structure is part of the dynamically-typed [`Val`] which represents
+/// all possible values in the component model. This is often used in
+/// conjunction with [`Func::call`](crate::component::Func::call).
+///
+/// Note that flags can also be mapped to Rust structures through the
+/// [`flags!`](crate::component::flags) macro and using
+/// [`TypedFunc`](crate::component::TypedFunc).
 #[derive(PartialEq, Eq, Clone)]
 pub struct Flags {
     ty: types::Flags,
@@ -468,7 +576,13 @@ pub struct Flags {
 }
 
 impl Flags {
-    /// Instantiate the specified type with the specified flag `names`.
+    /// Creates a new set of flags with the `ty` specified and the `names` as
+    /// members of the flags.
+    ///
+    /// # Errors
+    ///
+    /// An error is returned if any of `names` aren't present within the `ty`
+    /// specified.
     pub fn new(ty: &types::Flags, names: &[&str]) -> Result<Self> {
         let map = ty
             .names()
diff --git a/crates/wasmtime/src/runtime/func.rs b/crates/wasmtime/src/runtime/func.rs
index b7e9d6617..6a19734cd 100644
--- a/crates/wasmtime/src/runtime/func.rs
+++ b/crates/wasmtime/src/runtime/func.rs
@@ -18,16 +18,15 @@ use wasmtime_runtime::{
 
 /// A WebAssembly function which can be called.
 ///
-/// This type can represent either an exported function from a WebAssembly
-/// module or a host-defined function which can be used to satisfy an import of
-/// a module. [`Func`] and can be used to both instantiate an [`Instance`] as
-/// well as be extracted from an [`Instance`].
+/// This type typically represents an exported function from a WebAssembly
+/// module instance. In this case a [`Func`] belongs to an [`Instance`] and is
+/// loaded from there. A [`Func`] may also represent a host function as well in
+/// some cases, too.
 ///
-/// [`Instance`]: crate::Instance
-///
-/// A [`Func`] "belongs" to the store that it was originally created within.
-/// Operations on a [`Func`] only work with the store it belongs to, and if
-/// another store is passed in by accident then methods will panic.
+/// Functions can be called in a few different ways, either synchronous or async
+/// and either typed or untyped (more on this below). Note that host functions
+/// are normally inserted directly into a [`Linker`](crate::Linker) rather than
+/// using this directly, but both options are available.
 ///
 /// # `Func` and `async`
 ///
diff --git a/crates/wasmtime/src/runtime/module.rs b/crates/wasmtime/src/runtime/module.rs
index 94c9470b6..56bd904b0 100644
--- a/crates/wasmtime/src/runtime/module.rs
+++ b/crates/wasmtime/src/runtime/module.rs
@@ -40,14 +40,25 @@ pub use registry::{
 /// representation. Instead you'll need to create an
 /// [`Instance`](crate::Instance) to interact with the wasm module.
 ///
-/// Creating a `Module` currently involves compiling code, meaning that it can
-/// be an expensive operation. All `Module` instances are compiled according to
-/// the configuration in [`Config`], but typically they're JIT-compiled. If
-/// you'd like to instantiate a module multiple times you can do so with
-/// compiling the original wasm module only once with a single [`Module`]
-/// instance.
+/// A `Module` can be created by compiling WebAssembly code through APIs such as
+/// [`Module::new`]. This would be a JIT-style use case where code is compiled
+/// just before it's used. Alternatively a `Module` can be compiled in one
+/// process and [`Module::serialize`] can be used to save it to storage. A later
+/// call to [`Module::deserialize`] will quickly load the module to execute and
+/// does not need to compile any code, representing a more AOT-style use case.
 ///
-/// The `Module` is thread-safe and safe to share across threads.
+/// Currently a `Module` does not implement any form of tiering or dynamic
+/// optimization of compiled code. Creation of a `Module` via [`Module::new`] or
+/// related APIs will perform the entire compilation step synchronously. When
+/// finished no further compilation will happen at runtime or later during
+/// execution of WebAssembly instances for example.
+///
+/// Compilation of WebAssembly by default goes through Cranelift and is
+/// recommended to be done once-per-module. The same WebAssembly binary need not
+/// be compiled multiple times and can instead used an embedder-cached result of
+/// the first call.
+///
+/// `Module` is thread-safe and safe to share across threads.
 ///
 /// ## Modules and `Clone`
 ///
@@ -98,6 +109,25 @@ pub use registry::{
 /// # }
 /// ```
 ///
+/// Serializing and deserializing a module looks like:
+///
+/// ```no_run
+/// # use wasmtime::*;
+/// # fn main() -> anyhow::Result<()> {
+/// let engine = Engine::default();
+/// # let wasm_bytes: Vec<u8> = Vec::new();
+/// let module = Module::new(&engine, &wasm_bytes)?;
+/// let module_bytes = module.serialize()?;
+///
+/// // ... can save `module_bytes` to disk or other storage ...
+///
+/// // recreate the module from the serialized bytes. For the `unsafe` bits
+/// // see the documentation of `deserialize`.
+/// let module = unsafe { Module::deserialize(&engine, &module_bytes)? };
+/// # Ok(())
+/// # }
+/// ```
+///
 /// [`Config`]: crate::Config
 #[derive(Clone)]
 pub struct Module {
@@ -157,9 +187,8 @@ impl Module {
     /// loaded into memory all at once, this API does not support streaming
     /// compilation of a module.
     ///
-    /// If the module has not been already been compiled, the WebAssembly binary will
-    /// be decoded and validated. It will also be compiled according to the
-    /// configuration of the provided `engine`.
+    /// The WebAssembly binary will be decoded and validated. It will also be
+    /// compiled according to the configuration of the provided `engine`.
     ///
     /// # Errors
     ///
diff --git a/crates/wasmtime/src/runtime/store.rs b/crates/wasmtime/src/runtime/store.rs
index 631f49b3b..513474f8b 100644
--- a/crates/wasmtime/src/runtime/store.rs
+++ b/crates/wasmtime/src/runtime/store.rs
@@ -120,8 +120,8 @@ use func_refs::FuncRefs;
 /// [`Store`] it will not be deallocated until the [`Store`] itself is dropped.
 /// This makes [`Store`] unsuitable for creating an unbounded number of
 /// instances in it because [`Store`] will never release this memory. It's
-/// recommended to have a [`Store`] correspond roughly to the lifetime of a "main
-/// instance" that an embedding is interested in executing.
+/// recommended to have a [`Store`] correspond roughly to the lifetime of a
+/// "main instance" that an embedding is interested in executing.
 ///
 /// ## Type parameter `T`
 ///
@@ -158,6 +158,18 @@ use func_refs::FuncRefs;
 /// You can create a store with default configuration settings using
 /// `Store::default()`. This will create a brand new [`Engine`] with default
 /// configuration (see [`Config`](crate::Config) for more information).
+///
+/// ## Cross-store usage of items
+///
+/// In `wasmtime` wasm items such as [`Global`] and [`Memory`] "belong" to a
+/// [`Store`]. The store they belong to is the one they were created with
+/// (passed in as a parameter) or instantiated with. This store is the only
+/// store that can be used to interact with wasm items after they're created.
+///
+/// The `wasmtime` crate will panic if the [`Store`] argument passed in to these
+/// operations is incorrect. In other words it's considered a programmer error
+/// rather than a recoverable error for the wrong [`Store`] to be used when
+/// calling APIs.
 pub struct Store<T> {
     // for comments about `ManuallyDrop`, see `Store::into_data`
     inner: ManuallyDrop<Box<StoreInner<T>>>,
diff --git a/examples/mpk-available.rs b/examples/mpk-available.rs
new file mode 100644
index 000000000..e48663112
--- /dev/null
+++ b/examples/mpk-available.rs
@@ -0,0 +1,16 @@
+//! This example checks if memory protection keys (MPK) are available on the
+//! current system using the
+//! [`PoolingAllocationConfig::are_memory_protection_keys_available`] API.
+
+use std::process::exit;
+use wasmtime::*;
+
+fn main() {
+    if PoolingAllocationConfig::are_memory_protection_keys_available() {
+        eprintln!("MPK is available");
+        exit(0);
+    } else {
+        eprintln!("MPK is not available");
+        exit(1);
+    }
+}
diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock
index 643372a7a..a89ee8181 100644
--- a/supply-chain/imports.lock
+++ b/supply-chain/imports.lock
@@ -5,190 +5,378 @@
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-bforest]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-bforest]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-codegen]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-codegen]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-codegen-meta]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-codegen-meta]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-codegen-shared]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-codegen-shared]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-control]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-control]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-entity]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-entity]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-frontend]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-frontend]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-interpreter]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-interpreter]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-isle]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-isle]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-jit]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-jit]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-module]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-module]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-native]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-native]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-object]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-object]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-reader]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-reader]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-serde]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-serde]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.cranelift-wasm]]
 version = "0.105.0"
 audited_as = "0.104.0"
 
+[[unpublished.cranelift-wasm]]
+version = "0.106.0"
+audited_as = "0.104.0"
+
 [[unpublished.wasi-cap-std-sync]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasi-cap-std-sync]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasi-common]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasi-common]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasi-tokio]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasi-tokio]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-asm-macros]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-asm-macros]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-cache]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-cache]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-cli]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-cli]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-cli-flags]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-cli-flags]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-component-macro]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-component-macro]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-component-util]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-component-util]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-cranelift]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-cranelift]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-cranelift-shared]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-cranelift-shared]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-environ]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-environ]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-explorer]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-explorer]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-fiber]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-fiber]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-jit-debug]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-jit-debug]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-jit-icache-coherence]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-jit-icache-coherence]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-runtime]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-runtime]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-types]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-types]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-wasi]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-wasi]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-wasi-http]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-wasi-http]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-wasi-nn]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-wasi-nn]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-wasi-threads]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-wasi-threads]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-wast]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-wast]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-winch]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-winch]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-wit-bindgen]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-wit-bindgen]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wasmtime-wmemcheck]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wasmtime-wmemcheck]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wiggle]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wiggle]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wiggle-generate]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wiggle-generate]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wiggle-macro]]
 version = "18.0.0"
 audited_as = "17.0.0"
 
+[[unpublished.wiggle-macro]]
+version = "19.0.0"
+audited_as = "17.0.0"
+
 [[unpublished.wiggle-test]]
 version = "0.0.0"
 audited_as = "0.1.0"
@@ -197,6 +385,10 @@ audited_as = "0.1.0"
 version = "0.16.0"
 audited_as = "0.15.0"
 
+[[unpublished.winch-codegen]]
+version = "0.17.0"
+audited_as = "0.15.0"
+
 [[publisher.aho-corasick]]
 version = "1.0.2"
 when = "2023-06-04"
diff --git a/winch/codegen/Cargo.toml b/winch/codegen/Cargo.toml
index 90c52fa5c..fe7347655 100644
--- a/winch/codegen/Cargo.toml
+++ b/winch/codegen/Cargo.toml
@@ -4,7 +4,7 @@ name = "winch-codegen"
 description = "Winch code generation library"
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/bytecodealliance/wasmtime"
-version = "0.16.0"
+version = "0.17.0"
 edition.workspace = true
 
 [lints]


Test patch:
diff --git a/ci/build-test-matrix.js b/ci/build-test-matrix.js
index 5fee846d6..b5b776fc7 100644
--- a/ci/build-test-matrix.js
+++ b/ci/build-test-matrix.js
@@ -48,6 +48,12 @@ const array = [
     "isa": "x64",
     "rust": "msrv",
   },
+  {
+    "os": "ubuntu-latest",
+    "name": "Test Linux x86_64 with MPK",
+    "filter": "linux-x64",
+    "isa": "x64"
+  },
   {
     "os": "macos-latest",
     "name": "Test macOS x86_64",
diff --git a/cranelift/filetests/filetests/isa/x64/smulhi.clif b/cranelift/filetests/filetests/isa/x64/smulhi.clif
index 25c6db99c..fb8356e4b 100644
--- a/cranelift/filetests/filetests/isa/x64/smulhi.clif
+++ b/cranelift/filetests/filetests/isa/x64/smulhi.clif
@@ -1,6 +1,37 @@
 test compile precise-output
 target x86_64
 
+function %smulhi_i8(i8, i8) -> i8 {
+block0(v0: i8, v1: i8):
+  v2 = smulhi v0, v1
+  return v2
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movsbl  %dil, %eax
+;   movsbl  %sil, %r8d
+;   imull   %eax, %r8d, %eax
+;   sarq    $8, %rax, %rax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movsbl %dil, %eax
+;   movsbl %sil, %r8d
+;   imull %r8d, %eax
+;   sarq $8, %rax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
 function %f1(i16, i16) -> i16 {
 block0(v0: i16, v1: i16):
   v2 = smulhi v0, v1
diff --git a/cranelift/filetests/filetests/isa/x64/umulhi.clif b/cranelift/filetests/filetests/isa/x64/umulhi.clif
index e910de46e..487d2a897 100644
--- a/cranelift/filetests/filetests/isa/x64/umulhi.clif
+++ b/cranelift/filetests/filetests/isa/x64/umulhi.clif
@@ -1,6 +1,37 @@
 test compile precise-output
 target x86_64
 
+function %umulhi_i8(i8, i8) -> i8 {
+block0(v0: i8, v1: i8):
+  v2 = umulhi v0, v1
+  return v2
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movzbl  %dil, %eax
+;   movzbl  %sil, %r8d
+;   imull   %eax, %r8d, %eax
+;   shrq    $8, %rax, %rax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+;
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movzbl %dil, %eax
+;   movzbl %sil, %r8d
+;   imull %r8d, %eax
+;   shrq $8, %rax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
 function %f1(i16, i16) -> i16 {
 block0(v0: i16, v1: i16):
   v2 = umulhi v0, v1
diff --git a/cranelift/filetests/filetests/runtests/smulhi.clif b/cranelift/filetests/filetests/runtests/smulhi.clif
index 52a8d4d0e..df9f13adf 100644
--- a/cranelift/filetests/filetests/runtests/smulhi.clif
+++ b/cranelift/filetests/filetests/runtests/smulhi.clif
@@ -8,6 +8,15 @@ target riscv64
 target riscv64 has_c has_zcb
 
 
+function %smulhi_i8(i8, i8) -> i8 {
+block0(v0: i8, v1: i8):
+    v2 = smulhi v0, v1
+    return v2
+}
+; run: %smulhi_i8(-2, -4) == 0
+; run: %smulhi_i8(2, -4) == -1
+; run: %smulhi_i8(255, 255) == 0
+
 function %smulhi_i16(i16, i16) -> i16 {
 block0(v0: i16, v1: i16):
     v2 = smulhi v0, v1
diff --git a/cranelift/filetests/filetests/runtests/umulhi.clif b/cranelift/filetests/filetests/runtests/umulhi.clif
index 464a2bc67..51d4eee45 100644
--- a/cranelift/filetests/filetests/runtests/umulhi.clif
+++ b/cranelift/filetests/filetests/runtests/umulhi.clif
@@ -6,6 +6,14 @@ target s390x
 target riscv64
 target riscv64 has_c has_zcb
 
+function %umulhi_i8(i8, i8) -> i8 {
+block0(v0: i8, v1: i8):
+    v2 = umulhi v0, v1
+    return v2
+}
+; run: %umulhi_i8(2, 4) == 0
+; run: %umulhi_i8(255, 255) == 254
+
 function %umulhi_i16(i16, i16) -> i16 {
 block0(v0: i16, v1: i16):
     v2 = umulhi v0, v1