Repository: wasmerio/wasmer (language: rust)

Issue:
Wasm value kind enum WASM_ANYREF doesn't align with Wasm C API
### Describe the bug

Wasmer does not use Wasm value types as defined by the [Wasm C API](https://github.com/WebAssembly/wasm-c-api).

The Wasm C API defines value types as follows ([source](https://github.com/WebAssembly/wasm-c-api/blob/2ce1367c9d1271c83fb63bef26d896a2f290cd23/include/wasm.h#L180)):

```
typedef uint8_t wasm_valkind_t;
enum wasm_valkind_enum {
  WASM_I32,
  WASM_I64,
  WASM_F32,
  WASM_F64,
  WASM_EXTERNREF = 128,
  WASM_FUNCREF,
};
```

Wasmer uses enum `WASM_ANYREF` instead of `WASM_EXTERNREF` as follows:

```
typedef uint8_t wasm_valkind_t;
enum wasm_valkind_enum {
  WASM_I32,
  WASM_I64,
  WASM_F32,
  WASM_F64,
  WASM_ANYREF = 128,
  WASM_FUNCREF,
};
```

This means that Wasmer can not be swapped in in place of other libraries adhering to the Wasm C API (e.g. Wasmtime). The following error is produced when compiling:

```
error: use of undeclared identifier 'WASM_EXTERNREF'; did you mean 'WASM_ANYREF'?
          if (results->data[i].kind == WASM_EXTERNREF) return ERR_INVALID_DATA;
                                       ^~~~~~~~~~~
                                       WASM_ANYREF
```

### Steps to reproduce

Compile using Wasmer via the Wasm C API. Make use of `WASM_EXTERNREF`.

### Expected behavior

Program compiles using `WASM_EXTERNREF`.

### Actual behavior

The `WASM_EXTERNREF` enum is undefined.

```
error: use of undeclared identifier 'WASM_EXTERNREF'; did you mean 'WASM_ANYREF'?
          if (results->data[i].kind == WASM_EXTERNREF) return ERR_INVALID_DATA;
                                       ^~~~~~~~~~~
                                       WASM_ANYREF
```



Discussion / hints:
This is indeed something to fix. Thanks for reporting @ashtonmeuser

Fix patch:
diff --git a/lib/c-api/src/wasm_c_api/types/value.rs b/lib/c-api/src/wasm_c_api/types/value.rs
index ae2189c3117..96712f369c2 100644
--- a/lib/c-api/src/wasm_c_api/types/value.rs
+++ b/lib/c-api/src/wasm_c_api/types/value.rs
@@ -10,7 +10,7 @@ pub enum wasm_valkind_enum {
     WASM_I64 = 1,
     WASM_F32 = 2,
     WASM_F64 = 3,
-    WASM_ANYREF = 128,
+    WASM_EXTERNREF = 128,
     WASM_FUNCREF = 129,
 }
 
@@ -22,7 +22,7 @@ impl From<Type> for wasm_valkind_enum {
             Type::F32 => Self::WASM_F32,
             Type::F64 => Self::WASM_F64,
             Type::V128 => todo!("no v128 type in Wasm C API yet!"),
-            Type::ExternRef => Self::WASM_ANYREF,
+            Type::ExternRef => Self::WASM_EXTERNREF,
             Type::FuncRef => Self::WASM_FUNCREF,
         }
     }
@@ -36,7 +36,7 @@ impl From<wasm_valkind_enum> for Type {
             WASM_I64 => Type::I64,
             WASM_F32 => Type::F32,
             WASM_F64 => Type::F64,
-            WASM_ANYREF => Type::ExternRef,
+            WASM_EXTERNREF => Type::ExternRef,
             WASM_FUNCREF => Type::FuncRef,
         }
     }
diff --git a/lib/c-api/src/wasm_c_api/value.rs b/lib/c-api/src/wasm_c_api/value.rs
index 737975fa881..3be2f2a340b 100644
--- a/lib/c-api/src/wasm_c_api/value.rs
+++ b/lib/c-api/src/wasm_c_api/value.rs
@@ -9,7 +9,7 @@ use wasmer_api::Value;
 /// * `WASM_I64`, a 64-bit integer,
 /// * `WASM_F32`, a 32-bit float,
 /// * `WASM_F64`, a 64-bit float,
-/// * `WASM_ANYREF`, a WebAssembly reference,
+/// * `WASM_EXTERNREF`, a WebAssembly reference,
 /// * `WASM_FUNCREF`, a WebAssembly reference.
 #[allow(non_camel_case_types)]
 pub type wasm_valkind_t = u8;
@@ -94,7 +94,7 @@ impl std::fmt::Debug for wasm_val_t {
             Ok(wasm_valkind_enum::WASM_F64) => {
                 ds.field("f64", &unsafe { self.of.float64_t });
             }
-            Ok(wasm_valkind_enum::WASM_ANYREF) => {
+            Ok(wasm_valkind_enum::WASM_EXTERNREF) => {
                 ds.field("anyref", &unsafe { self.of.wref });
             }
 
@@ -150,7 +150,7 @@ pub unsafe extern "C" fn wasm_val_copy(
             wasm_valkind_enum::WASM_F64 => wasm_val_inner {
                 float64_t: val.of.float64_t,
             },
-            wasm_valkind_enum::WASM_ANYREF => wasm_val_inner { wref: val.of.wref },
+            wasm_valkind_enum::WASM_EXTERNREF => wasm_val_inner { wref: val.of.wref },
             wasm_valkind_enum::WASM_FUNCREF => wasm_val_inner { wref: val.of.wref },
         }
     }); otherwise ());
@@ -173,7 +173,7 @@ impl TryFrom<wasm_valkind_t> for wasm_valkind_enum {
             1 => wasm_valkind_enum::WASM_I64,
             2 => wasm_valkind_enum::WASM_F32,
             3 => wasm_valkind_enum::WASM_F64,
-            128 => wasm_valkind_enum::WASM_ANYREF,
+            128 => wasm_valkind_enum::WASM_EXTERNREF,
             129 => wasm_valkind_enum::WASM_FUNCREF,
             _ => return Err("valkind value out of bounds"),
         })
@@ -197,7 +197,9 @@ impl TryFrom<&wasm_val_t> for Value {
             wasm_valkind_enum::WASM_I64 => Value::I64(unsafe { item.of.int64_t }),
             wasm_valkind_enum::WASM_F32 => Value::F32(unsafe { item.of.float32_t }),
             wasm_valkind_enum::WASM_F64 => Value::F64(unsafe { item.of.float64_t }),
-            wasm_valkind_enum::WASM_ANYREF => return Err("ANYREF not supported at this time"),
+            wasm_valkind_enum::WASM_EXTERNREF => {
+                return Err("EXTERNREF not supported at this time")
+            }
             wasm_valkind_enum::WASM_FUNCREF => return Err("FUNCREF not supported at this time"),
         })
     }


Test patch:
diff --git a/lib/c-api/tests/wasm-c-api/example/callback.c b/lib/c-api/tests/wasm-c-api/example/callback.c
index 2fddb1634ff..a575397463e 100644
--- a/lib/c-api/tests/wasm-c-api/example/callback.c
+++ b/lib/c-api/tests/wasm-c-api/example/callback.c
@@ -22,7 +22,7 @@ void wasm_val_print(wasm_val_t val) {
     case WASM_F64: {
       printf("%g", val.of.f64);
     } break;
-    case WASM_ANYREF:
+    case WASM_EXTERNREF:
     case WASM_FUNCREF: {
       if (val.of.ref == NULL) {
         printf("null");
diff --git a/lib/c-api/tests/wasm-c-api/example/hostref.c b/lib/c-api/tests/wasm-c-api/example/hostref.c
index 1e787ab1902..ae23584033b 100644
--- a/lib/c-api/tests/wasm-c-api/example/hostref.c
+++ b/lib/c-api/tests/wasm-c-api/example/hostref.c
@@ -159,7 +159,7 @@ int main(int argc, const char* argv[]) {
   // Create external callback function.
   printf("Creating callback...\n");
   own wasm_functype_t* callback_type = wasm_functype_new_1_1(
-    wasm_valtype_new(WASM_ANYREF), wasm_valtype_new(WASM_ANYREF));
+    wasm_valtype_new(WASM_EXTERNREF), wasm_valtype_new(WASM_EXTERNREF));
   own wasm_func_t* callback_func =
     wasm_func_new(store, callback_type, callback);
 
@@ -207,7 +207,7 @@ int main(int argc, const char* argv[]) {
   check(wasm_ref_copy(host2), host2);
 
   own wasm_val_t val;
-  val.kind = WASM_ANYREF;
+  val.kind = WASM_EXTERNREF;
   val.of.ref = wasm_ref_copy(host1);
   check(wasm_ref_copy(val.of.ref), host1);
   own wasm_ref_t* ref = val.of.ref;
@@ -225,13 +225,13 @@ int main(int argc, const char* argv[]) {
   check(call_v_r(global_get), NULL);
 
   wasm_global_get(global, &val);
-  assert(val.kind == WASM_ANYREF);
+  assert(val.kind == WASM_EXTERNREF);
   check(val.of.ref, NULL);
   val.of.ref = host2;
   wasm_global_set(global, &val);
   check(call_v_r(global_get), host2);
   wasm_global_get(global, &val);
-  assert(val.kind == WASM_ANYREF);
+  assert(val.kind == WASM_EXTERNREF);
   check(val.of.ref, host2);
 
   printf("Accessing table...\n");
diff --git a/lib/c-api/tests/wasm-c-api/example/reflect.c b/lib/c-api/tests/wasm-c-api/example/reflect.c
index d4383185ff0..0a7099fe07e 100644
--- a/lib/c-api/tests/wasm-c-api/example/reflect.c
+++ b/lib/c-api/tests/wasm-c-api/example/reflect.c
@@ -25,7 +25,7 @@ void print_valtype(const wasm_valtype_t* type) {
     case WASM_I64: printf("i64"); break;
     case WASM_F32: printf("f32"); break;
     case WASM_F64: printf("f64"); break;
-    case WASM_ANYREF: printf("anyref"); break;
+    case WASM_EXTERNREF: printf("externref"); break;
     case WASM_FUNCREF: printf("funcref"); break;
   }
 }
diff --git a/lib/c-api/tests/wasm-c-api/include/wasm.h b/lib/c-api/tests/wasm-c-api/include/wasm.h
index 7b38fe33e16..58115fa386d 100644
--- a/lib/c-api/tests/wasm-c-api/include/wasm.h
+++ b/lib/c-api/tests/wasm-c-api/include/wasm.h
@@ -186,7 +186,7 @@ enum wasm_valkind_enum {
   WASM_I64,
   WASM_F32,
   WASM_F64,
-  WASM_ANYREF = 128,
+  WASM_EXTERNREF = 128,
   WASM_FUNCREF,
 };
 
@@ -195,10 +195,10 @@ WASM_API_EXTERN own wasm_valtype_t* wasm_valtype_new(wasm_valkind_t);
 WASM_API_EXTERN wasm_valkind_t wasm_valtype_kind(const wasm_valtype_t*);
 
 static inline bool wasm_valkind_is_num(wasm_valkind_t k) {
-  return k < WASM_ANYREF;
+  return k < WASM_EXTERNREF ;
 }
 static inline bool wasm_valkind_is_ref(wasm_valkind_t k) {
-  return k >= WASM_ANYREF;
+  return k >= WASM_EXTERNREF ;
 }
 
 static inline bool wasm_valtype_is_num(const wasm_valtype_t* t) {
@@ -551,8 +551,8 @@ static inline own wasm_valtype_t* wasm_valtype_new_f64() {
   return wasm_valtype_new(WASM_F64);
 }
 
-static inline own wasm_valtype_t* wasm_valtype_new_anyref() {
-  return wasm_valtype_new(WASM_ANYREF);
+static inline own wasm_valtype_t* wasm_valtype_new_externref() {
+  return wasm_valtype_new(WASM_EXTERNREF);
 }
 static inline own wasm_valtype_t* wasm_valtype_new_funcref() {
   return wasm_valtype_new(WASM_FUNCREF);
@@ -712,8 +712,8 @@ static inline void* wasm_val_ptr(const wasm_val_t* val) {
 #define WASM_I64_VAL(i) {.kind = WASM_I64, .of = {.i64 = i}}
 #define WASM_F32_VAL(z) {.kind = WASM_F32, .of = {.f32 = z}}
 #define WASM_F64_VAL(z) {.kind = WASM_F64, .of = {.f64 = z}}
-#define WASM_REF_VAL(r) {.kind = WASM_ANYREF, .of = {.ref = r}}
-#define WASM_INIT_VAL {.kind = WASM_ANYREF, .of = {.ref = NULL}}
+#define WASM_REF_VAL(r) {.kind = WASM_EXTERNREF, .of = {.ref = r}}
+#define WASM_INIT_VAL {.kind = WASM_EXTERNREF, .of = {.ref = NULL}}
 
 
 ///////////////////////////////////////////////////////////////////////////////