Skip to content

Commit

Permalink
Deduplicate WasmTy implementations for GC-managed types (bytecodeal…
Browse files Browse the repository at this point in the history
  • Loading branch information
fitzgen authored Jul 12, 2024
1 parent 9f66134 commit 9459cf5
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 191 deletions.
76 changes: 13 additions & 63 deletions crates/wasmtime/src/runtime/gc/enabled/anyref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::runtime::vm::VMGcRef;
use crate::{
store::{AutoAssertNoGc, StoreOpaque},
ArrayType, AsContext, AsContextMut, GcRefImpl, GcRootIndex, HeapType, ManuallyRooted, RefType,
Result, RootSet, Rooted, StructRef, StructType, ValRaw, ValType, WasmTy, I31,
Result, Rooted, StructRef, StructType, ValRaw, ValType, WasmTy, I31,
};
use core::mem;
use core::mem::MaybeUninit;
Expand Down Expand Up @@ -458,23 +458,11 @@ unsafe impl WasmTy for Rooted<AnyRef> {
}

fn store(self, store: &mut AutoAssertNoGc<'_>, ptr: &mut MaybeUninit<ValRaw>) -> Result<()> {
let gc_ref = self.inner.try_clone_gc_ref(store)?;
let r64 = gc_ref.as_r64();
store.gc_store_mut()?.expose_gc_ref_to_wasm(gc_ref);
debug_assert_ne!(r64, 0);
let anyref = u32::try_from(r64).unwrap();
ptr.write(ValRaw::anyref(anyref));
Ok(())
self.wasm_ty_store(store, ptr, ValRaw::anyref)
}

unsafe fn load(store: &mut AutoAssertNoGc<'_>, ptr: &ValRaw) -> Self {
let raw = ptr.get_anyref();
debug_assert_ne!(raw, 0);
let gc_ref = VMGcRef::from_r64(raw.into())
.expect("valid r64")
.expect("non-null");
let gc_ref = store.unwrap_gc_store_mut().clone_gc_ref(&gc_ref);
AnyRef::from_cloned_gc_ref(store, gc_ref)
Self::wasm_ty_load(store, ptr.get_anyref(), AnyRef::from_cloned_gc_ref)
}
}

Expand Down Expand Up @@ -514,19 +502,11 @@ unsafe impl WasmTy for Option<Rooted<AnyRef>> {
}

fn store(self, store: &mut AutoAssertNoGc<'_>, ptr: &mut MaybeUninit<ValRaw>) -> Result<()> {
match self {
Some(r) => r.store(store, ptr),
None => {
ptr.write(ValRaw::anyref(0));
Ok(())
}
}
<Rooted<AnyRef>>::wasm_ty_option_store(self, store, ptr, ValRaw::anyref)
}

unsafe fn load(store: &mut AutoAssertNoGc<'_>, ptr: &ValRaw) -> Self {
let gc_ref = VMGcRef::from_r64(ptr.get_anyref().into()).expect("valid r64")?;
let gc_ref = store.unwrap_gc_store_mut().clone_gc_ref(&gc_ref);
Some(AnyRef::from_cloned_gc_ref(store, gc_ref))
<Rooted<AnyRef>>::wasm_ty_option_load(store, ptr.get_anyref(), AnyRef::from_cloned_gc_ref)
}
}

Expand All @@ -552,28 +532,11 @@ unsafe impl WasmTy for ManuallyRooted<AnyRef> {
}

fn store(self, store: &mut AutoAssertNoGc<'_>, ptr: &mut MaybeUninit<ValRaw>) -> Result<()> {
let gc_ref = self.inner.try_clone_gc_ref(store)?;
let r64 = gc_ref.as_r64();
store.gc_store_mut()?.expose_gc_ref_to_wasm(gc_ref);
debug_assert_ne!(r64, 0);
let anyref = u32::try_from(r64).unwrap();
ptr.write(ValRaw::anyref(anyref));
Ok(())
self.wasm_ty_store(store, ptr, ValRaw::anyref)
}

unsafe fn load(store: &mut AutoAssertNoGc<'_>, ptr: &ValRaw) -> Self {
let raw = ptr.get_anyref();
debug_assert_ne!(raw, 0);
let gc_ref = VMGcRef::from_r64(raw.into())
.expect("valid r64")
.expect("non-null");
let gc_ref = store.unwrap_gc_store_mut().clone_gc_ref(&gc_ref);
RootSet::with_lifo_scope(store, |store| {
let rooted = AnyRef::from_cloned_gc_ref(store, gc_ref);
rooted
._to_manually_rooted(store)
.expect("rooted is in scope")
})
Self::wasm_ty_load(store, ptr.get_anyref(), AnyRef::from_cloned_gc_ref)
}
}

Expand Down Expand Up @@ -614,27 +577,14 @@ unsafe impl WasmTy for Option<ManuallyRooted<AnyRef>> {
}

fn store(self, store: &mut AutoAssertNoGc<'_>, ptr: &mut MaybeUninit<ValRaw>) -> Result<()> {
match self {
Some(r) => r.store(store, ptr),
None => {
ptr.write(ValRaw::anyref(0));
Ok(())
}
}
<ManuallyRooted<AnyRef>>::wasm_ty_option_store(self, store, ptr, ValRaw::anyref)
}

unsafe fn load(store: &mut AutoAssertNoGc<'_>, ptr: &ValRaw) -> Self {
let raw = ptr.get_anyref();
debug_assert_ne!(raw, 0);
let gc_ref = VMGcRef::from_r64(raw.into()).expect("valid r64")?;
let gc_ref = store.unwrap_gc_store_mut().clone_gc_ref(&gc_ref);
RootSet::with_lifo_scope(store, |store| {
let rooted = AnyRef::from_cloned_gc_ref(store, gc_ref);
Some(
rooted
._to_manually_rooted(store)
.expect("rooted is in scope"),
)
})
<ManuallyRooted<AnyRef>>::wasm_ty_option_load(
store,
ptr.get_anyref(),
AnyRef::from_cloned_gc_ref,
)
}
}
80 changes: 17 additions & 63 deletions crates/wasmtime/src/runtime/gc/enabled/externref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::runtime::vm::VMGcRef;
use crate::{
store::{AutoAssertNoGc, StoreOpaque},
AsContextMut, GcHeapOutOfMemory, GcRefImpl, GcRootIndex, HeapType, ManuallyRooted, RefType,
Result, RootSet, Rooted, StoreContext, StoreContextMut, ValRaw, ValType, WasmTy,
Result, Rooted, StoreContext, StoreContextMut, ValRaw, ValType, WasmTy,
};
use core::any::Any;
use core::mem;
Expand Down Expand Up @@ -446,23 +446,11 @@ unsafe impl WasmTy for Rooted<ExternRef> {
}

fn store(self, store: &mut AutoAssertNoGc<'_>, ptr: &mut MaybeUninit<ValRaw>) -> Result<()> {
let gc_ref = self.inner.try_clone_gc_ref(store)?;
let r64 = gc_ref.as_r64();
store.gc_store_mut()?.expose_gc_ref_to_wasm(gc_ref);
debug_assert_ne!(r64, 0);
let externref = u32::try_from(r64).unwrap();
ptr.write(ValRaw::externref(externref));
Ok(())
self.wasm_ty_store(store, ptr, ValRaw::externref)
}

unsafe fn load(store: &mut AutoAssertNoGc<'_>, ptr: &ValRaw) -> Self {
let raw = ptr.get_externref();
debug_assert_ne!(raw, 0);
let gc_ref = VMGcRef::from_r64(raw.into())
.expect("valid r64")
.expect("non-null");
let gc_ref = store.unwrap_gc_store_mut().clone_gc_ref(&gc_ref);
ExternRef::from_cloned_gc_ref(store, gc_ref)
Self::wasm_ty_load(store, ptr.get_externref(), ExternRef::from_cloned_gc_ref)
}
}

Expand All @@ -488,19 +476,15 @@ unsafe impl WasmTy for Option<Rooted<ExternRef>> {
}

fn store(self, store: &mut AutoAssertNoGc<'_>, ptr: &mut MaybeUninit<ValRaw>) -> Result<()> {
match self {
Some(r) => r.store(store, ptr),
None => {
ptr.write(ValRaw::externref(0));
Ok(())
}
}
<Rooted<ExternRef>>::wasm_ty_option_store(self, store, ptr, ValRaw::externref)
}

unsafe fn load(store: &mut AutoAssertNoGc<'_>, ptr: &ValRaw) -> Self {
let gc_ref = VMGcRef::from_r64(ptr.get_externref().into()).expect("valid r64")?;
let gc_ref = store.unwrap_gc_store_mut().clone_gc_ref(&gc_ref);
Some(ExternRef::from_cloned_gc_ref(store, gc_ref))
<Rooted<ExternRef>>::wasm_ty_option_load(
store,
ptr.get_externref(),
ExternRef::from_cloned_gc_ref,
)
}
}

Expand All @@ -526,28 +510,11 @@ unsafe impl WasmTy for ManuallyRooted<ExternRef> {
}

fn store(self, store: &mut AutoAssertNoGc<'_>, ptr: &mut MaybeUninit<ValRaw>) -> Result<()> {
let gc_ref = self.inner.try_clone_gc_ref(store)?;
let r64 = gc_ref.as_r64();
store.gc_store_mut()?.expose_gc_ref_to_wasm(gc_ref);
debug_assert_ne!(r64, 0);
let externref = u32::try_from(r64).unwrap();
ptr.write(ValRaw::externref(externref));
Ok(())
self.wasm_ty_store(store, ptr, ValRaw::externref)
}

unsafe fn load(store: &mut AutoAssertNoGc<'_>, ptr: &ValRaw) -> Self {
let raw = ptr.get_externref();
debug_assert_ne!(raw, 0);
let gc_ref = VMGcRef::from_r64(raw.into())
.expect("valid r64")
.expect("non-null");
let gc_ref = store.unwrap_gc_store_mut().clone_gc_ref(&gc_ref);
RootSet::with_lifo_scope(store, |store| {
let rooted = ExternRef::from_cloned_gc_ref(store, gc_ref);
rooted
._to_manually_rooted(store)
.expect("rooted is in scope")
})
Self::wasm_ty_load(store, ptr.get_externref(), ExternRef::from_cloned_gc_ref)
}
}

Expand All @@ -574,27 +541,14 @@ unsafe impl WasmTy for Option<ManuallyRooted<ExternRef>> {
}

fn store(self, store: &mut AutoAssertNoGc<'_>, ptr: &mut MaybeUninit<ValRaw>) -> Result<()> {
match self {
Some(r) => r.store(store, ptr),
None => {
ptr.write(ValRaw::externref(0));
Ok(())
}
}
<ManuallyRooted<ExternRef>>::wasm_ty_option_store(self, store, ptr, ValRaw::externref)
}

unsafe fn load(store: &mut AutoAssertNoGc<'_>, ptr: &ValRaw) -> Self {
let raw = ptr.get_externref();
debug_assert_ne!(raw, 0);
let gc_ref = VMGcRef::from_r64(raw.into()).expect("valid r64")?;
let gc_ref = store.unwrap_gc_store_mut().clone_gc_ref(&gc_ref);
RootSet::with_lifo_scope(store, |store| {
let rooted = ExternRef::from_cloned_gc_ref(store, gc_ref);
Some(
rooted
._to_manually_rooted(store)
.expect("rooted is in scope"),
)
})
<ManuallyRooted<ExternRef>>::wasm_ty_option_load(
store,
ptr.get_externref(),
ExternRef::from_cloned_gc_ref,
)
}
}
Loading

0 comments on commit 9459cf5

Please sign in to comment.