Repository: bytecodealliance/wasmtime
Pull request #7498 (2023-11-08 15:16:32)

[15.0.0] A few more backports
Backporting two PRs here:

* https://github.com/bytecodealliance/wasmtime/pull/7490 - this changed WITs.
* https://github.com/bytecodealliance/wasmtime/pull/7491 - correctness fix for a backend


Patch:
diff --git a/cranelift/codegen/src/isa/riscv64/lower.isle b/cranelift/codegen/src/isa/riscv64/lower.isle
index 059060476..21dec2bb6 100644
--- a/cranelift/codegen/src/isa/riscv64/lower.isle
+++ b/cranelift/codegen/src/isa/riscv64/lower.isle
@@ -329,111 +329,107 @@
   (if-let imm12_neg (imm12_from_negated_value y))
   (alu_rr_imm12 (select_addi ty) x imm12_neg))
 
-(rule 4 (lower (has_type (ty_int_ref_scalar_64 ty) (isub x y)))
-  (if-let imm12_neg (imm12_from_negated_value x))
-  (alu_rr_imm12 (select_addi ty) y imm12_neg))
-
 ;; SIMD Vectors
-(rule 5 (lower (has_type (ty_vec_fits_in_register ty) (isub x y)))
+(rule 4 (lower (has_type (ty_vec_fits_in_register ty) (isub x y)))
   (rv_vsub_vv x y (unmasked) ty))
 
-(rule 6 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat y))))
+(rule 5 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat y))))
   (rv_vsub_vx x y (unmasked) ty))
 
-(rule 7 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat (sextend y @ (value_type sext_ty))))))
+(rule 6 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat (sextend y @ (value_type sext_ty))))))
   (if-let half_ty (ty_half_width ty))
   (if-let $true (ty_equal (lane_type half_ty) sext_ty))
   (rv_vwsub_wx x y (unmasked) (vstate_mf2 half_ty)))
 
-(rule 7 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat (uextend y @ (value_type uext_ty))))))
+(rule 6 (lower (has_type (ty_vec_fits_in_register ty) (isub x (splat (uextend y @ (value_type uext_ty))))))
   (if-let half_ty (ty_half_width ty))
   (if-let $true (ty_equal (lane_type half_ty) uext_ty))
   (rv_vwsubu_wx x y (unmasked) (vstate_mf2 half_ty)))
 
-(rule 8 (lower (has_type (ty_vec_fits_in_register ty) (isub (splat x) y)))
+(rule 7 (lower (has_type (ty_vec_fits_in_register ty) (isub (splat x) y)))
   (rv_vrsub_vx y x (unmasked) ty))
 
-(rule 9 (lower (has_type (ty_vec_fits_in_register ty) (isub x y)))
+(rule 8 (lower (has_type (ty_vec_fits_in_register ty) (isub x y)))
   (if-let x_imm (replicated_imm5 x))
   (rv_vrsub_vi y x_imm (unmasked) ty))
 
 
 ;; Signed Widening Low Subtractions
 
-(rule 7 (lower (has_type (ty_vec_fits_in_register _) (isub x (swiden_low y @ (value_type in_ty)))))
+(rule 6 (lower (has_type (ty_vec_fits_in_register _) (isub x (swiden_low y @ (value_type in_ty)))))
   (rv_vwsub_wv x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
-(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_low x @ (value_type in_ty))
-                                                            (swiden_low y))))
+(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_low x @ (value_type in_ty))
+                                                           (swiden_low y))))
   (rv_vwsub_vv x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
-(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_low x @ (value_type in_ty))
-                                                            (splat (sextend y @ (value_type sext_ty))))))
+(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_low x @ (value_type in_ty))
+                                                           (splat (sextend y @ (value_type sext_ty))))))
   (if-let $true (ty_equal (lane_type in_ty) sext_ty))
   (rv_vwsub_vx x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
 ;; Signed Widening High Subtractions
 ;; These are the same as the low widenings, but we first slide down the inputs.
 
-(rule 7 (lower (has_type (ty_vec_fits_in_register _) (isub x (swiden_high y @ (value_type in_ty)))))
+(rule 6 (lower (has_type (ty_vec_fits_in_register _) (isub x (swiden_high y @ (value_type in_ty)))))
   (rv_vwsub_wv x (gen_slidedown_half in_ty y) (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
-(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_high x @ (value_type in_ty))
-                                                            (swiden_high y))))
+(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_high x @ (value_type in_ty))
+                                                           (swiden_high y))))
   (rv_vwsub_vv (gen_slidedown_half in_ty x) (gen_slidedown_half in_ty y) (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
-(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_high x @ (value_type in_ty))
-                                                            (splat (sextend y @ (value_type sext_ty))))))
+(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_high x @ (value_type in_ty))
+                                                           (splat (sextend y @ (value_type sext_ty))))))
   (if-let $true (ty_equal (lane_type in_ty) sext_ty))
   (rv_vwsub_vx (gen_slidedown_half in_ty x) y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
 ;; Unsigned Widening Low Subtractions
 
-(rule 7 (lower (has_type (ty_vec_fits_in_register _) (isub x (uwiden_low y @ (value_type in_ty)))))
+(rule 6 (lower (has_type (ty_vec_fits_in_register _) (isub x (uwiden_low y @ (value_type in_ty)))))
   (rv_vwsubu_wv x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
-(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_low x @ (value_type in_ty))
-                                                            (uwiden_low y))))
+(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_low x @ (value_type in_ty))
+                                                           (uwiden_low y))))
   (rv_vwsubu_vv x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
-(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_low x @ (value_type in_ty))
-                                                            (splat (uextend y @ (value_type uext_ty))))))
+(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_low x @ (value_type in_ty))
+                                                           (splat (uextend y @ (value_type uext_ty))))))
   (if-let $true (ty_equal (lane_type in_ty) uext_ty))
   (rv_vwsubu_vx x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
 ;; Unsigned Widening High Subtractions
 ;; These are the same as the low widenings, but we first slide down the inputs.
 
-(rule 7 (lower (has_type (ty_vec_fits_in_register _) (isub x (uwiden_high y @ (value_type in_ty)))))
+(rule 6 (lower (has_type (ty_vec_fits_in_register _) (isub x (uwiden_high y @ (value_type in_ty)))))
   (rv_vwsubu_wv x (gen_slidedown_half in_ty y) (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
-(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_high x @ (value_type in_ty))
-                                                            (uwiden_high y))))
+(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_high x @ (value_type in_ty))
+                                                           (uwiden_high y))))
   (rv_vwsubu_vv (gen_slidedown_half in_ty x) (gen_slidedown_half in_ty y) (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
-(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_high x @ (value_type in_ty))
-                                                            (splat (uextend y @ (value_type uext_ty))))))
+(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_high x @ (value_type in_ty))
+                                                           (splat (uextend y @ (value_type uext_ty))))))
   (if-let $true (ty_equal (lane_type in_ty) uext_ty))
   (rv_vwsubu_vx (gen_slidedown_half in_ty x) y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
 ;; Signed Widening Mixed High/Low Subtractions
 
-(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_low x @ (value_type in_ty))
-                                                            (swiden_high y))))
+(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_low x @ (value_type in_ty))
+                                                           (swiden_high y))))
   (rv_vwsub_vv x (gen_slidedown_half in_ty y) (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
-(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_high x @ (value_type in_ty))
-                                                            (swiden_low y))))
+(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (swiden_high x @ (value_type in_ty))
+                                                           (swiden_low y))))
   (rv_vwsub_vv (gen_slidedown_half in_ty x) y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
 ;; Unsigned Widening Mixed High/Low Subtractions
 
-(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_low x @ (value_type in_ty))
-                                                            (uwiden_high y))))
+(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_low x @ (value_type in_ty))
+                                                           (uwiden_high y))))
   (rv_vwsubu_vv x (gen_slidedown_half in_ty y) (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
-(rule 10 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_high x @ (value_type in_ty))
-                                                            (uwiden_low y))))
+(rule 9 (lower (has_type (ty_vec_fits_in_register _) (isub (uwiden_high x @ (value_type in_ty))
+                                                           (uwiden_low y))))
   (rv_vwsubu_vv (gen_slidedown_half in_ty x) y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))
 
 
diff --git a/crates/wasi-http/src/types_impl.rs b/crates/wasi-http/src/types_impl.rs
index a0531a741..89455e3aa 100644
--- a/crates/wasi-http/src/types_impl.rs
+++ b/crates/wasi-http/src/types_impl.rs
@@ -170,15 +170,23 @@ impl<T: WasiHttpView> crate::bindings::http::types::HostFields for T {
         Ok(Ok(()))
     }
 
-    fn delete(&mut self, fields: Resource<HostFields>, name: String) -> wasmtime::Result<()> {
+    fn delete(
+        &mut self,
+        fields: Resource<HostFields>,
+        name: String,
+    ) -> wasmtime::Result<Result<(), types::HeaderError>> {
         let header = match hyper::header::HeaderName::from_bytes(name.as_bytes()) {
             Ok(header) => header,
-            Err(_) => return Ok(()),
+            Err(_) => return Ok(Err(types::HeaderError::InvalidSyntax)),
         };
 
+        if is_forbidden_header(self, &header) {
+            return Ok(Err(types::HeaderError::Forbidden));
+        }
+
         let m = get_fields_mut(self.table(), &fields)?;
         m.remove(header);
-        Ok(())
+        Ok(Ok(()))
     }
 
     fn append(
diff --git a/crates/wasi-http/wit/deps/http/types.wit b/crates/wasi-http/wit/deps/http/types.wit
index e3c06ae9f..fac47f61e 100644
--- a/crates/wasi-http/wit/deps/http/types.wit
+++ b/crates/wasi-http/wit/deps/http/types.wit
@@ -88,8 +88,9 @@ interface types {
     set: func(name: field-key, value: list<field-value>) -> result<_, header-error>;
 
     /// Delete all values for a key. Does nothing if no values for the key
-    /// exist.
-    delete: func(name: field-key);
+    /// exist. Returns and error if the `field-key` is syntactically invalid, or
+    /// if the `field-key` is forbidden.
+    delete: func(name: field-key) -> result<_, header-error>;
 
     /// Append a value for a key. Does not change or delete any existing
     /// values for that key.
@@ -98,7 +99,6 @@ interface types {
     /// the name is forbidden.
     append: func(name: field-key, value: field-value) -> result<_, header-error>;
 
-
     /// Retrieve the full set of keys and values in the Fields. Like the
     /// constructor, the list represents each key-value pair. 
     ///
diff --git a/crates/wasi/wit/deps/http/types.wit b/crates/wasi/wit/deps/http/types.wit
index e3c06ae9f..fac47f61e 100644
--- a/crates/wasi/wit/deps/http/types.wit
+++ b/crates/wasi/wit/deps/http/types.wit
@@ -88,8 +88,9 @@ interface types {
     set: func(name: field-key, value: list<field-value>) -> result<_, header-error>;
 
     /// Delete all values for a key. Does nothing if no values for the key
-    /// exist.
-    delete: func(name: field-key);
+    /// exist. Returns and error if the `field-key` is syntactically invalid, or
+    /// if the `field-key` is forbidden.
+    delete: func(name: field-key) -> result<_, header-error>;
 
     /// Append a value for a key. Does not change or delete any existing
     /// values for that key.
@@ -98,7 +99,6 @@ interface types {
     /// the name is forbidden.
     append: func(name: field-key, value: field-value) -> result<_, header-error>;
 
-
     /// Retrieve the full set of keys and values in the Fields. Like the
     /// constructor, the list represents each key-value pair. 
     ///


Test patch:
diff --git a/cranelift/filetests/filetests/runtests/arithmetic.clif b/cranelift/filetests/filetests/runtests/arithmetic.clif
index c26f2a41e..5b63c9144 100644
--- a/cranelift/filetests/filetests/runtests/arithmetic.clif
+++ b/cranelift/filetests/filetests/runtests/arithmetic.clif
@@ -127,6 +127,14 @@ block0(v0: i8,v1: i8):
 ; run: %sub_i8(0xAB, 0x0B) == 0xA0
 ; run: %sub_i8(0xC0, 0xDE) == 0xE2
 
+function %isub_const_lhs(i8, i32) -> i32 {
+block0(v0: i8, v1: i32):
+    v376 = iconst.i32 0xffff_fffd
+    v1161 = isub v376, v1
+    return v1161
+}
+
+; run: %isub_const_lhs(68, 4474) == -4477
 
 function %mul_i64(i64, i64) -> i64 {
 block0(v0: i64,v1: i64):
diff --git a/crates/test-programs/src/bin/api_proxy.rs b/crates/test-programs/src/bin/api_proxy.rs
index 2170bdbbc..ff36e2519 100644
--- a/crates/test-programs/src/bin/api_proxy.rs
+++ b/crates/test-programs/src/bin/api_proxy.rs
@@ -15,7 +15,22 @@ use bindings::wasi::http::types::{IncomingRequest, ResponseOutparam};
 struct T;
 
 impl bindings::exports::wasi::http::incoming_handler::Guest for T {
-    fn handle(_request: IncomingRequest, outparam: ResponseOutparam) {
+    fn handle(request: IncomingRequest, outparam: ResponseOutparam) {
+        let header = String::from("custom-forbidden-header");
+        let req_hdrs = request.headers();
+
+        assert!(
+            !req_hdrs.get(&header).is_empty(),
+            "missing `custom-forbidden-header` from request"
+        );
+
+        assert!(req_hdrs.delete(&header).is_err());
+
+        assert!(
+            !req_hdrs.get(&header).is_empty(),
+            "delete of forbidden header succeeded"
+        );
+
         let hdrs = bindings::wasi::http::types::Headers::new();
         let resp = bindings::wasi::http::types::OutgoingResponse::new(hdrs);
         let body = resp.body().expect("outgoing response");
diff --git a/crates/wasi-http/tests/all/main.rs b/crates/wasi-http/tests/all/main.rs
index 7a106f4a3..45094d52e 100644
--- a/crates/wasi-http/tests/all/main.rs
+++ b/crates/wasi-http/tests/all/main.rs
@@ -199,11 +199,18 @@ async fn run_wasi_http(
 
 #[test_log::test(tokio::test)]
 async fn wasi_http_proxy_tests() -> anyhow::Result<()> {
-    let req = hyper::Request::builder()
-        .method(http::Method::GET)
-        .body(body::empty())?;
+    let mut req = hyper::Request::builder().method(http::Method::GET);
 
-    let resp = run_wasi_http(test_programs_artifacts::API_PROXY_COMPONENT, req, None).await?;
+    req.headers_mut()
+        .unwrap()
+        .append("custom-forbidden-header", "yes".parse().unwrap());
+
+    let resp = run_wasi_http(
+        test_programs_artifacts::API_PROXY_COMPONENT,
+        req.body(body::empty())?,
+        None,
+    )
+    .await?;
 
     match resp {
         Ok(resp) => println!("response: {resp:?}"),