This commit is contained in:
@@ -77,7 +77,7 @@ register! {
|
||||
side: ExternRef<BattleSide>,
|
||||
script_ptr: u32
|
||||
) -> u32 {
|
||||
let side = side.value_func(&env).unwrap();
|
||||
let side : &BattleSide = side.value_func(&env).unwrap();
|
||||
unsafe{
|
||||
let env = env.data().data();
|
||||
let name_ptr = env.script_function_cache().script_get_name(&env).unwrap().call(&mut env.store_mut(), script_ptr).unwrap();
|
||||
|
||||
@@ -44,9 +44,9 @@ register! {
|
||||
let script = env.data().data().get_loaded_script(script);
|
||||
if let Some(script) = script {
|
||||
match script.get_owner() {
|
||||
ScriptOwnerData::Pokemon(p) => env.data().data().get_extern_ref_index(p.load(Ordering::Relaxed).as_ref().unwrap()),
|
||||
ScriptOwnerData::BattleSide(p) => env.data().data().get_extern_ref_index(p.load(Ordering::Relaxed).as_ref().unwrap()),
|
||||
ScriptOwnerData::Battle(p) => env.data().data().get_extern_ref_index(p.load(Ordering::Relaxed).as_ref().unwrap()),
|
||||
ScriptOwnerData::Pokemon(p) => env.data().data().get_extern_ref_index::<crate::dynamic_data::Pokemon>(p.load(Ordering::Relaxed).as_ref().unwrap()) as u32,
|
||||
ScriptOwnerData::BattleSide(p) => env.data().data().get_extern_ref_index::<crate::dynamic_data::BattleSide>(p.load(Ordering::Relaxed).as_ref().unwrap()) as u32,
|
||||
ScriptOwnerData::Battle(p) => env.data().data().get_extern_ref_index::<crate::dynamic_data::Battle>(p.load(Ordering::Relaxed).as_ref().unwrap()) as u32,
|
||||
ScriptOwnerData::None => 0,
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -16,7 +16,7 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> ExternRef<DynamicLibrary> {
|
||||
let lib = pokemon.value_func(&env).unwrap().library();
|
||||
let lib = pokemon.value_func(&env).unwrap().library().as_ref();
|
||||
ExternRef::func_new(&env, lib)
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ register! {
|
||||
fn pokemon_get_held_item(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> ExternRef<Item> {
|
||||
) -> ExternRef<dyn Item> {
|
||||
let read_lock = pokemon.value_func(&env).unwrap().held_item().read();
|
||||
if let Some(item) = read_lock.as_ref() {
|
||||
ExternRef::func_new(&env, item.as_ref())
|
||||
@@ -231,7 +231,7 @@ register! {
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
script_ptr: u32
|
||||
) -> u32 {
|
||||
let pokemon = pokemon.value_func(&env).unwrap();
|
||||
let pokemon : &Pokemon = pokemon.value_func(&env).unwrap();
|
||||
unsafe{
|
||||
let env = env.data().data();
|
||||
let name_ptr = env.script_function_cache().script_get_name(&env).unwrap().call(&mut env.store_mut(), script_ptr).unwrap();
|
||||
|
||||
@@ -109,7 +109,9 @@ fn _error(env: FunctionEnvMut<WebAssemblyEnv>, message: u32, file: u32, line: u3
|
||||
|
||||
/// Get a single item from an earlier passed VecExternRef
|
||||
fn _vec_extern_ref_get_value(env: FunctionEnvMut<WebAssemblyEnv>, reference: u32, index: u32) -> u32 {
|
||||
env.data().data().get_extern_vec_ref_extern_ref(reference, index)
|
||||
env.data()
|
||||
.data()
|
||||
.get_extern_vec_ref_extern_ref(reference as usize, index as usize) as u32
|
||||
}
|
||||
|
||||
/// Gets the hash value of a StringKey.
|
||||
|
||||
@@ -1,38 +1,62 @@
|
||||
use crate::script_implementations::wasm::export_registry::register;
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::static_data::Item;
|
||||
use crate::static_data::{DataLibrary, Item, ItemLibrary};
|
||||
use crate::StringKey;
|
||||
use std::mem::transmute;
|
||||
use wasmer::FunctionEnvMut;
|
||||
|
||||
register! {
|
||||
fn item_library_get_item(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
lib: ExternRef<ItemLibrary>,
|
||||
string_key: ExternRef<StringKey>,
|
||||
) -> ExternRef<dyn Item> {
|
||||
let lib = lib.value_func(&env).unwrap();
|
||||
let m = lib.get(string_key.value_func(&env).unwrap());
|
||||
if let Some(v) = m {
|
||||
ExternRef::func_new(&env, v)
|
||||
} else {
|
||||
ExternRef::null()
|
||||
}
|
||||
}
|
||||
|
||||
fn item_library_get_item_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, lib: ExternRef<ItemLibrary>, hash: u32) -> ExternRef<dyn Item> {
|
||||
let lib = lib.value_func(&env).unwrap();
|
||||
let m = lib.get_by_hash(hash);
|
||||
if let Some(v) = m {
|
||||
ExternRef::func_new(&env, v)
|
||||
} else {
|
||||
ExternRef::null()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn item_get_price(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
item: ExternRef<Item>,
|
||||
item: ExternRef<dyn Item>,
|
||||
) -> i32 {
|
||||
item.value_func(&env).unwrap().price()
|
||||
item.value_func_arc(&env).unwrap().price()
|
||||
}
|
||||
|
||||
fn item_get_name(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
item: ExternRef<Item>,
|
||||
item: ExternRef<dyn Item>,
|
||||
) -> ExternRef<StringKey> {
|
||||
ExternRef::func_new(&env, item.value_func(&env).unwrap().name())
|
||||
ExternRef::func_new(&env, item.value_func_arc(&env).unwrap().name())
|
||||
}
|
||||
|
||||
fn item_get_category(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
item: ExternRef<Item>,
|
||||
item: ExternRef<dyn Item>,
|
||||
) -> u8 {
|
||||
unsafe { transmute(item.value_func(&env).unwrap().category()) }
|
||||
|
||||
unsafe { transmute(item.value_func_arc(&env).unwrap().category()) }
|
||||
}
|
||||
|
||||
fn item_get_battle_category(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
item: ExternRef<Item>,
|
||||
item: ExternRef<dyn Item>,
|
||||
) -> u8 {
|
||||
unsafe { transmute(item.value_func(&env).unwrap().battle_category()) }
|
||||
unsafe { transmute(item.value_func_arc(&env).unwrap().battle_category()) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use crate::ValueIdentifiable;
|
||||
use std::any::Any;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::transmute;
|
||||
use std::sync::Arc;
|
||||
@@ -5,7 +7,6 @@ use std::sync::Arc;
|
||||
use crate::script_implementations::wasm::script_resolver::{
|
||||
WebAssemblyEnv, WebAssemblyEnvironmentData, WebAssemblyScriptResolver,
|
||||
};
|
||||
use unique_type_id::UniqueTypeId;
|
||||
use wasmer::FromToNativeWasmType;
|
||||
use wasmer::FunctionEnvMut;
|
||||
|
||||
@@ -13,36 +14,36 @@ use wasmer::FunctionEnvMut;
|
||||
/// requiring us to make copies. Instead, we pass a simple increment index, that we can then use
|
||||
/// to find the relevant data.
|
||||
#[derive(Copy, Clone)]
|
||||
pub(crate) struct ExternRef<T: UniqueTypeId<u64>> {
|
||||
pub(crate) struct ExternRef<T: ?Sized> {
|
||||
/// The lookup index we can use to find the data.
|
||||
index: u32,
|
||||
index: usize,
|
||||
/// Phantom data so we can get a type generic.
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: UniqueTypeId<u64>> ExternRef<T> {
|
||||
impl<T: ValueIdentifiable + ?Sized> ExternRef<T> {
|
||||
/// Instantiates a new ExternRef for a bit of data. If we already have made an Extern Ref for
|
||||
/// this data and type, we use that instead.
|
||||
pub fn new(env: &WebAssemblyEnvironmentData, value: &T) -> Self {
|
||||
pub fn new(env: &WebAssemblyEnvironmentData, value: &dyn Any) -> Self {
|
||||
Self {
|
||||
index: env.get_extern_ref_index(value),
|
||||
index: env.get_extern_ref_index::<T>(value),
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Instantiates a new ExternRef for a bit of data using the function environment. If we already
|
||||
/// have made an Extern Ref for this data and type, we use that instead.
|
||||
pub fn func_new(env: &FunctionEnvMut<WebAssemblyEnv>, value: &T) -> Self {
|
||||
pub fn func_new(env: &FunctionEnvMut<WebAssemblyEnv>, value: &dyn Any) -> Self {
|
||||
Self {
|
||||
index: env.data().data().get_extern_ref_index(value),
|
||||
index: env.data().data().get_extern_ref_index::<T>(value),
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an ExternRef with a given resolver. This can be used in cases where we do not have an environment variable.
|
||||
pub(crate) fn new_with_resolver(resolver: &WebAssemblyScriptResolver, value: &T) -> Self {
|
||||
pub(crate) fn new_with_resolver(resolver: &WebAssemblyScriptResolver, value: &dyn Any) -> Self {
|
||||
Self {
|
||||
index: resolver.environment_data().get_extern_ref_index(value),
|
||||
index: resolver.environment_data().get_extern_ref_index::<T>(value),
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
@@ -57,24 +58,49 @@ impl<T: UniqueTypeId<u64>> ExternRef<T> {
|
||||
|
||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||
/// value when it was passed before. If these types do not match, this will panic.
|
||||
pub fn value_func<'a, 'b>(&'a self, env: &'b FunctionEnvMut<WebAssemblyEnv>) -> Option<&'b T> {
|
||||
pub fn value_func<'a, 'b>(&'a self, env: &'b FunctionEnvMut<WebAssemblyEnv>) -> Option<&'b T>
|
||||
where
|
||||
T: Sized + 'static,
|
||||
{
|
||||
self.value(&env.data().data())
|
||||
}
|
||||
|
||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||
/// value when it was passed before. If these types do not match, this will panic.
|
||||
pub fn value<'a, 'b, 'c>(&'a self, env: &'b Arc<WebAssemblyEnvironmentData>) -> Option<&'c T> {
|
||||
let ptr = env.get_extern_ref_value(self.index) as *const T;
|
||||
unsafe { ptr.as_ref() }
|
||||
pub fn value_func_arc(&self, env: &FunctionEnvMut<WebAssemblyEnv>) -> Option<Arc<T>>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
self.value_arc(&env.data().data())
|
||||
}
|
||||
|
||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||
/// value when it was passed before. If these types do not match, this will panic.
|
||||
pub fn value<'a, 'b, 'c>(&'a self, env: &'b Arc<WebAssemblyEnvironmentData>) -> Option<&'c T>
|
||||
where
|
||||
T: Sized + 'static,
|
||||
{
|
||||
env.get_extern_ref_value::<T>(self.index).downcast_ref::<T>()
|
||||
}
|
||||
|
||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||
/// value when it was passed before. If these types do not match, this will panic.
|
||||
pub fn value_arc(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Option<Arc<T>>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
env.get_extern_ref_value::<T>(self.index)
|
||||
.downcast_ref::<Arc<T>>()
|
||||
.cloned()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: UniqueTypeId<u64>> FromToNativeWasmType for ExternRef<T> {
|
||||
unsafe impl<T: ?Sized> FromToNativeWasmType for ExternRef<T> {
|
||||
type Native = i32;
|
||||
|
||||
fn from_native(native: Self::Native) -> Self {
|
||||
Self {
|
||||
index: native as u32,
|
||||
index: native as usize,
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
@@ -88,16 +114,16 @@ unsafe impl<T: UniqueTypeId<u64>> FromToNativeWasmType for ExternRef<T> {
|
||||
/// actually passing raw memory, or requiring us to make copies.
|
||||
pub(crate) struct VecExternRef<T> {
|
||||
/// The lookup index we can use to find the data.
|
||||
index: u32,
|
||||
index: usize,
|
||||
/// The number of items in the vec.
|
||||
size: u32,
|
||||
/// Phantom data so we can get a type generic.
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: UniqueTypeId<u64>> VecExternRef<T> {
|
||||
impl<T: 'static> VecExternRef<T> {
|
||||
/// Instantiates a new VecExternRef for a given slice.
|
||||
pub fn new(env: &WebAssemblyEnvironmentData, value: &[T]) -> Self {
|
||||
pub fn new(env: &WebAssemblyEnvironmentData, value: &Vec<T>) -> Self {
|
||||
Self {
|
||||
index: env.get_extern_vec_ref_index(value),
|
||||
size: value.len() as u32,
|
||||
@@ -106,20 +132,20 @@ impl<T: UniqueTypeId<u64>> VecExternRef<T> {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: UniqueTypeId<u64>> FromToNativeWasmType for VecExternRef<T> {
|
||||
unsafe impl<T> FromToNativeWasmType for VecExternRef<T> {
|
||||
type Native = i64;
|
||||
|
||||
fn from_native(native: Self::Native) -> Self {
|
||||
let split: (u32, u32) = unsafe { transmute(native) };
|
||||
Self {
|
||||
index: split.0,
|
||||
index: split.0 as usize,
|
||||
size: split.1,
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn to_native(self) -> Self::Native {
|
||||
let v: i64 = unsafe { transmute((self.index, self.size)) };
|
||||
let v: i64 = unsafe { transmute((self.index as u32, self.size)) };
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,14 +125,14 @@ impl Script for WebAssemblyScript {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_initialize(&self, library: &DynamicLibrary, pars: &[EffectParameter]) {
|
||||
fn on_initialize(&self, library: &DynamicLibrary, pars: Vec<EffectParameter>) {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::Initialize) {
|
||||
return;
|
||||
}
|
||||
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().on_initialize(env) {
|
||||
call_func!(func, env, self, ex_ref!(env, library), vec_ex_ref!(env, pars));
|
||||
call_func!(func, env, self, ex_ref!(env, library), vec_ex_ref!(env, &pars));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -757,7 +757,7 @@ impl Script for WebAssemblyScript {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_after_held_item_consume(&self, pokemon: &Pokemon, item: &Item) {
|
||||
fn on_after_held_item_consume(&self, pokemon: &Pokemon, item: &dyn Item) {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::OnAfterHeldItemConsume) {
|
||||
return;
|
||||
}
|
||||
@@ -807,7 +807,7 @@ impl Script for WebAssemblyScript {
|
||||
}
|
||||
}
|
||||
|
||||
fn change_capture_rate_bonus(&self, target: &Pokemon, pokeball: &Item, modifier: &mut u8) {
|
||||
fn change_capture_rate_bonus(&self, target: &Pokemon, pokeball: &dyn Item, modifier: &mut u8) {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangeCaptureRate) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -165,11 +165,11 @@ script_function_cache! {
|
||||
on_damage(ExternRef<Pokemon>, u8, u32, u32)
|
||||
on_faint(ExternRef<Pokemon>, u8)
|
||||
on_switch_in(ExternRef<Pokemon>)
|
||||
on_after_held_item_consume(ExternRef<Pokemon>, ExternRef<Item>)
|
||||
on_after_held_item_consume(ExternRef<Pokemon>, ExternRef<dyn Item>)
|
||||
change_experience_gained(ExternRef<Pokemon>, ExternRef<Pokemon>, WasmPtr<u32>)
|
||||
share_experience(ExternRef<Pokemon>, ExternRef<Pokemon>, WasmPtr<bool>)
|
||||
block_weather(ExternRef<Battle>, WasmPtr<bool>)
|
||||
change_capture_rate_bonus(ExternRef<Pokemon>, ExternRef<Item>, WasmPtr<u8>)
|
||||
change_capture_rate_bonus(ExternRef<Pokemon>, ExternRef<dyn Item>, WasmPtr<u8>)
|
||||
}
|
||||
|
||||
impl ScriptFunctionCache {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::any::Any;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::mem::{align_of, forget, size_of};
|
||||
use std::sync::{Arc, Weak};
|
||||
@@ -5,7 +6,6 @@ use std::sync::{Arc, Weak};
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use parking_lot::lock_api::RwLockReadGuard;
|
||||
use parking_lot::{RawRwLock, RwLock};
|
||||
use unique_type_id::UniqueTypeId;
|
||||
use wasmer::{
|
||||
AsStoreMut, AsStoreRef, Cranelift, EngineBuilder, Extern, Features, Function, FunctionEnv, Imports, Instance,
|
||||
Memory, Module, Store, StoreMut, StoreRef, TypedFunction, Value,
|
||||
@@ -189,7 +189,7 @@ impl ScriptResolver for WebAssemblyScriptResolver {
|
||||
self.environment_data.setup_script(script, category, script_key, owner)
|
||||
}
|
||||
|
||||
fn load_item_script(&self, _key: &Item) -> PkmnResult<Option<Arc<dyn ItemScript>>> {
|
||||
fn load_item_script(&self, _key: &dyn Item) -> PkmnResult<Option<Arc<dyn ItemScript>>> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@@ -215,17 +215,17 @@ pub struct WebAssemblyEnvironmentData {
|
||||
/// we instead keep track of all the data we've sent to WASM, and pass the ID of that data to WASM. This allows us
|
||||
/// to only operate on data we know WASM owns. We currently store this data in this continuous Vec, and give the index
|
||||
/// of the data as the ID.
|
||||
extern_ref_pointers: RwLock<Vec<*const u8>>,
|
||||
extern_ref_pointers: RwLock<Vec<*const dyn Any>>,
|
||||
/// To make sure we send the same identifier to WASM when we send the same piece of data multiple times, we have a
|
||||
/// backwards lookup on extern_ref_pointers. This allows us to get the index for a given piece of data.
|
||||
extern_ref_pointers_lookup: RwLock<HashMap<ExternRefLookupKey, u32>>,
|
||||
extern_ref_pointers_lookup: RwLock<HashMap<ExternRefLookupKey, usize>>,
|
||||
/// As an added security measure on our extern refs, we keep track of the types of the extern ref data we've sent.
|
||||
/// This prevents illegal arbitrary memory operations, where we expect type X, but the actual type is Y, which would
|
||||
/// allow for modifying memory we might not want to. If we get a type mismatch, we will panic, preventing this.
|
||||
extern_ref_type_lookup: RwLock<HashSet<ExternRefLookupKey>>,
|
||||
|
||||
/// Additional security for data slices passed to WASM.
|
||||
extern_vec_ref_lookup: RwLock<HashMap<u32, Vec<u32>>>,
|
||||
extern_vec_ref_lookup: RwLock<HashMap<usize, Vec<usize>>>,
|
||||
|
||||
/// The memory inside of the WASM container.
|
||||
memory: RwLock<Option<Memory>>,
|
||||
@@ -257,14 +257,13 @@ pub struct WebAssemblyEnvironmentData {
|
||||
}
|
||||
|
||||
/// A quick lookup so we can find the extern ref of the value.
|
||||
#[allow(clippy::vtable_address_comparisons)]
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
struct ExternRefLookupKey {
|
||||
/// The raw pointer to the data
|
||||
pub ptr: *const u8,
|
||||
pub ptr: *const dyn Any,
|
||||
/// Whether or not the reference is a Vec
|
||||
pub is_vec: bool,
|
||||
/// The unique identifier of the type.
|
||||
pub t: u64,
|
||||
}
|
||||
|
||||
impl WebAssemblyEnvironmentData {
|
||||
@@ -359,8 +358,8 @@ impl WebAssemblyEnvironmentData {
|
||||
/// when extern refs get actually properly implemented at compile time we might want to get rid
|
||||
/// of this code.
|
||||
#[inline(always)]
|
||||
pub fn get_extern_ref_index<T: UniqueTypeId<u64> + ?Sized>(&self, value: &T) -> u32 {
|
||||
self.get_extern_ref_from_ptr(value as *const T as *const u8, T::id().0, false)
|
||||
pub fn get_extern_ref_index<T: ?Sized>(&self, value: &dyn Any) -> usize {
|
||||
self.get_extern_ref_from_identifier::<T>(value, false)
|
||||
}
|
||||
|
||||
/// Get a numeric value from any given value. This is not a true Extern Ref from WASM, as this
|
||||
@@ -369,18 +368,18 @@ impl WebAssemblyEnvironmentData {
|
||||
/// access can be touched through this, and we ensure the value is the correct type. In the future,
|
||||
/// when extern refs get actually properly implemented at compile time we might want to get rid
|
||||
/// of this code.
|
||||
pub fn get_extern_vec_ref_index<T: UniqueTypeId<u64>>(&self, value: &[T]) -> u32 {
|
||||
pub fn get_extern_vec_ref_index<T: 'static>(&self, value: &Vec<T>) -> usize {
|
||||
let mut vec = Vec::with_capacity(value.len());
|
||||
for v in value {
|
||||
vec.push(self.get_extern_ref_index(v));
|
||||
vec.push(self.get_extern_ref_index::<T>(v));
|
||||
}
|
||||
let p = self.get_extern_ref_from_ptr(value as *const [T] as *const u8, T::id().0, true);
|
||||
let p = self.get_extern_ref_from_identifier::<Vec<T>>(value, true);
|
||||
self.extern_vec_ref_lookup.write().insert(p, vec);
|
||||
p
|
||||
}
|
||||
|
||||
/// Get an extern ref belonging to a vector we have passed to WASM.
|
||||
pub fn get_extern_vec_ref_extern_ref(&self, extern_vec_ref: u32, index: u32) -> u32 {
|
||||
pub fn get_extern_vec_ref_extern_ref(&self, extern_vec_ref: usize, index: usize) -> usize {
|
||||
let r = self.extern_vec_ref_lookup.read();
|
||||
let v = r.get(&extern_vec_ref).unwrap();
|
||||
v[index as usize]
|
||||
@@ -389,47 +388,43 @@ impl WebAssemblyEnvironmentData {
|
||||
/// Gets the extern ref index belonging to a specific pointer. If none exists, this will create
|
||||
/// a new one.
|
||||
#[inline(always)]
|
||||
fn get_extern_ref_from_ptr(&self, ptr: *const u8, type_id: u64, is_vec: bool) -> u32 {
|
||||
fn get_extern_ref_from_identifier<T: ?Sized>(&self, value: &dyn Any, is_vec: bool) -> usize {
|
||||
if let Some(v) = self.extern_ref_pointers_lookup.read().get(&ExternRefLookupKey {
|
||||
ptr,
|
||||
ptr: value as *const dyn Any,
|
||||
is_vec,
|
||||
t: type_id,
|
||||
}) {
|
||||
return *v as u32;
|
||||
return *v as usize;
|
||||
}
|
||||
let index = {
|
||||
let mut extern_ref_guard = self.extern_ref_pointers.write();
|
||||
extern_ref_guard.push(ptr);
|
||||
extern_ref_guard.len() as u32
|
||||
extern_ref_guard.push(value as *const dyn Any);
|
||||
extern_ref_guard.len()
|
||||
};
|
||||
self.extern_ref_pointers_lookup.write().insert(
|
||||
ExternRefLookupKey {
|
||||
ptr,
|
||||
ptr: value as *const dyn Any,
|
||||
is_vec,
|
||||
t: type_id,
|
||||
},
|
||||
index,
|
||||
);
|
||||
self.extern_ref_type_lookup.write().insert(ExternRefLookupKey {
|
||||
ptr,
|
||||
ptr: value as *const dyn Any,
|
||||
is_vec,
|
||||
t: type_id,
|
||||
});
|
||||
index
|
||||
}
|
||||
|
||||
/// Gets a value from the extern ref lookup. This turns an earlier registered index back into
|
||||
/// its proper value, validates its type, and returns the value.
|
||||
pub fn get_extern_ref_value<T: UniqueTypeId<u64>>(&self, index: u32) -> &T {
|
||||
pub fn get_extern_ref_value<'a, 'b, T: ?Sized>(&'a self, index: usize) -> &'b dyn Any {
|
||||
let read_guard = self.extern_ref_pointers.read();
|
||||
let ptr = read_guard.get((index - 1) as usize).unwrap();
|
||||
let ptr = read_guard.get(index - 1).unwrap();
|
||||
if self
|
||||
.extern_ref_type_lookup
|
||||
.read()
|
||||
.get(&ExternRefLookupKey {
|
||||
ptr: *ptr,
|
||||
is_vec: false,
|
||||
t: T::id().0,
|
||||
})
|
||||
.is_none()
|
||||
{
|
||||
@@ -439,7 +434,7 @@ impl WebAssemblyEnvironmentData {
|
||||
);
|
||||
}
|
||||
|
||||
unsafe { (*ptr as *const T).as_ref().unwrap() }
|
||||
unsafe { ptr.as_ref().unwrap() }
|
||||
}
|
||||
|
||||
/// The WASM store.
|
||||
|
||||
Reference in New Issue
Block a user