Initial setup for results for wasm
This commit is contained in:
parent
eb68977290
commit
0d3d5bcbe7
|
@ -573,6 +573,11 @@ impl ScriptContainer {
|
||||||
&self.script
|
&self.script
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether or not the script is set.
|
||||||
|
pub fn is_any(&self) -> bool {
|
||||||
|
self.script.read().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the underlying script as the downcasted value.
|
/// Get the underlying script as the downcasted value.
|
||||||
pub fn get_as<T: 'static>(&self) -> Result<MappedRwLockReadGuard<T>> {
|
pub fn get_as<T: 'static>(&self) -> Result<MappedRwLockReadGuard<T>> {
|
||||||
let r = RwLockReadGuard::try_map(self.script.read(), |a| unsafe {
|
let r = RwLockReadGuard::try_map(self.script.read(), |a| unsafe {
|
||||||
|
|
|
@ -23,7 +23,7 @@ extern "C" fn script_resolver_drop(ptr: OwnedPtr<Box<dyn ScriptResolver>>) {
|
||||||
#[cfg(feature = "wasm")]
|
#[cfg(feature = "wasm")]
|
||||||
mod web_assembly_script_resolver {
|
mod web_assembly_script_resolver {
|
||||||
use crate::dynamic_data::ScriptResolver;
|
use crate::dynamic_data::ScriptResolver;
|
||||||
use crate::ffi::{ExternPointer, IdentifiablePointer};
|
use crate::ffi::{ExternPointer, IdentifiablePointer, NativeResult};
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyScriptResolver;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyScriptResolver;
|
||||||
|
|
||||||
/// Instantiates a new WebAssemblyScriptResolver.
|
/// Instantiates a new WebAssemblyScriptResolver.
|
||||||
|
@ -41,13 +41,19 @@ mod web_assembly_script_resolver {
|
||||||
mut ptr: ExternPointer<Box<WebAssemblyScriptResolver>>,
|
mut ptr: ExternPointer<Box<WebAssemblyScriptResolver>>,
|
||||||
arr: *const u8,
|
arr: *const u8,
|
||||||
len: usize,
|
len: usize,
|
||||||
) {
|
) -> NativeResult<()> {
|
||||||
unsafe { ptr.as_mut().load_wasm_from_bytes(std::slice::from_raw_parts(arr, len)) }
|
unsafe {
|
||||||
|
ptr.as_mut()
|
||||||
|
.load_wasm_from_bytes(std::slice::from_raw_parts(arr, len))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tells the script resolver we're done loading wasm modules, and to finalize the resolver.
|
/// Tells the script resolver we're done loading wasm modules, and to finalize the resolver.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn webassembly_script_resolver_finalize(mut ptr: ExternPointer<Box<WebAssemblyScriptResolver>>) {
|
extern "C" fn webassembly_script_resolver_finalize(
|
||||||
ptr.as_mut().finalize();
|
mut ptr: ExternPointer<Box<WebAssemblyScriptResolver>>,
|
||||||
|
) -> NativeResult<()> {
|
||||||
|
ptr.as_mut().finalize().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#![feature(unboxed_closures)]
|
#![feature(unboxed_closures)]
|
||||||
#![feature(trait_upcasting)]
|
#![feature(trait_upcasting)]
|
||||||
#![feature(lazy_cell)]
|
#![feature(lazy_cell)]
|
||||||
|
#![feature(try_trait_v2)]
|
||||||
|
|
||||||
//! PkmnLib
|
//! PkmnLib
|
||||||
//! PkmnLib is a full featured implementation of Pokemon. while currently focused on implementing
|
//! PkmnLib is a full featured implementation of Pokemon. while currently focused on implementing
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
/// The WASM module handles loading dynamic scripts through WebAssembly.
|
/// The WASM module handles loading dynamic scripts through WebAssembly.
|
||||||
#[cfg(feature = "wasm")]
|
#[cfg(feature = "wasm")]
|
||||||
// FIXME: allow these for now until we have a good result interface defined.
|
|
||||||
#[allow(clippy::unwrap_used)]
|
|
||||||
#[allow(clippy::expect_used)]
|
|
||||||
#[allow(clippy::indexing_slicing)]
|
|
||||||
#[allow(clippy::string_slice)]
|
|
||||||
#[allow(clippy::exit)]
|
|
||||||
#[allow(clippy::panic)]
|
|
||||||
pub mod wasm;
|
pub mod wasm;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::dynamic_data::{
|
use crate::dynamic_data::{
|
||||||
Battle, BattleParty, BattleRandom, BattleResult, BattleSide, ChoiceQueue, DynamicLibrary, Pokemon, PokemonParty,
|
Battle, BattleParty, BattleRandom, BattleResult, BattleSide, ChoiceQueue, DynamicLibrary, Pokemon, PokemonParty,
|
||||||
};
|
};
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::StringKey;
|
use crate::StringKey;
|
||||||
|
@ -11,141 +11,141 @@ register! {
|
||||||
fn battle_get_pokemon_per_side(
|
fn battle_get_pokemon_per_side(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
battle.value_func(&env).unwrap().pokemon_per_side()
|
Ok(battle.value_func(&env)?.pokemon_per_side()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_parties(
|
fn battle_get_parties(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> VecExternRef<BattleParty> {
|
) -> WasmResult<VecExternRef<BattleParty>> {
|
||||||
VecExternRef::new(env.data().data().as_ref(), battle.value_func(&env).unwrap().parties())
|
Ok(VecExternRef::new(env.data().data().as_ref(), battle.value_func(&env)?.parties())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_choice_queue(
|
fn battle_get_choice_queue(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> ExternRef<ChoiceQueue> {
|
) -> WasmResult<ExternRef<ChoiceQueue>> {
|
||||||
let queue = battle.value_func(&env).unwrap().current_turn_queue().read();
|
let queue = battle.value_func(&env)?.current_turn_queue().read();
|
||||||
if let Some(queue) = queue.as_ref() {
|
Ok(if let Some(queue) = queue.as_ref() {
|
||||||
ExternRef::func_new(&env, queue)
|
ExternRef::func_new(&env, queue)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_library(
|
fn battle_get_library(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> ExternRef<dyn DynamicLibrary> {
|
) -> WasmResult<ExternRef<dyn DynamicLibrary>> {
|
||||||
ExternRef::func_new(&env, &battle.value_func_arc(&env).unwrap().library().clone())
|
Ok(ExternRef::func_new(&env, &battle.value_func(&env)?.library().clone())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_sides(
|
fn battle_get_sides(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> VecExternRef<BattleSide> {
|
) -> WasmResult<VecExternRef<BattleSide>> {
|
||||||
VecExternRef::new(env.data().data().as_ref(), battle.value_func(&env).unwrap().sides())
|
Ok(VecExternRef::new(env.data().data().as_ref(), battle.value_func(&env)?.sides())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_random(
|
fn battle_get_random(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> ExternRef<BattleRandom> {
|
) -> WasmResult<ExternRef<BattleRandom>> {
|
||||||
ExternRef::func_new(&env, battle.value_func(&env).unwrap().random())
|
Ok(ExternRef::func_new(&env, battle.value_func(&env)?.random())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_weather_name(
|
fn battle_get_weather_name(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> ExternRef<StringKey> {
|
) -> WasmResult<ExternRef<StringKey>> {
|
||||||
let weather = battle.value_func(&env).unwrap().weather_name().unwrap();
|
let weather = battle.value_func(&env)?.weather_name()?;
|
||||||
if let Some(weather) = weather {
|
Ok(if let Some(weather) = weather {
|
||||||
ExternRef::func_new(&env, &weather)
|
ExternRef::func_new(&env, &weather)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_find_party_for_pokemon(
|
fn battle_find_party_for_pokemon(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
pokemon: ExternRef<Pokemon>
|
pokemon: ExternRef<Pokemon>
|
||||||
) -> ExternRef<BattleParty> {
|
) -> WasmResult<ExternRef<BattleParty>> {
|
||||||
let battle = battle.value_func(&env).unwrap();
|
let battle = battle.value_func(&env)?;
|
||||||
let pokemon = pokemon.value_func(&env).unwrap();
|
let pokemon = pokemon.value_func(&env)?;
|
||||||
for party in battle.parties() {
|
for party in battle.parties() {
|
||||||
if party.party().has_pokemon(pokemon) {
|
if party.party().has_pokemon(pokemon) {
|
||||||
return ExternRef::func_new(&env, party);
|
return Ok(ExternRef::func_new(&env, party)).into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExternRef::null()
|
Ok(ExternRef::null()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_pokemon(
|
fn battle_get_pokemon(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
side: u8, index: u8
|
side: u8, index: u8
|
||||||
) -> ExternRef<Pokemon> {
|
) -> WasmResult<ExternRef<Pokemon>> {
|
||||||
let battle = battle.value_func(&env).unwrap();
|
let battle = battle.value_func(&env)?;
|
||||||
let pokemon = battle.get_pokemon(side, index);
|
let pokemon = battle.get_pokemon(side, index);
|
||||||
if let Some(pokemon) = pokemon {
|
Ok(if let Some(pokemon) = pokemon {
|
||||||
ExternRef::func_new(&env, &pokemon)
|
ExternRef::func_new(&env, &pokemon)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_can_flee(
|
fn battle_get_can_flee(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if battle.value_func(&env).unwrap().can_flee() { 1 } else { 0 }
|
Ok(if battle.value_func(&env)?.can_flee() { 1 } else { 0 }).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_number_of_sides(
|
fn battle_get_number_of_sides(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
battle.value_func(&env).unwrap().number_of_sides()
|
Ok(battle.value_func(&env)?.number_of_sides()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_has_ended(
|
fn battle_get_has_ended(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if battle.value_func(&env).unwrap().has_ended() { 1 } else { 0 }
|
Ok(if battle.value_func(&env)?.has_ended() { 1 } else { 0 }).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_has_ended_conclusively(
|
fn battle_get_has_ended_conclusively(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if battle.value_func(&env).unwrap().result().is_conclusive() { 1 } else { 0 }
|
Ok(if battle.value_func(&env)?.result().is_conclusive() { 1 } else { 0 }).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_winning_side(
|
fn battle_get_winning_side(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if let BattleResult::Conclusive(result) = battle.value_func(&env).unwrap().result() {
|
Ok(if let BattleResult::Conclusive(result) = battle.value_func(&env)?.result() {
|
||||||
result
|
result
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_current_turn(
|
fn battle_get_current_turn(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
battle.value_func(&env).unwrap().current_turn()
|
Ok(battle.value_func(&env)?.current_turn()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_party_get_party(
|
fn battle_party_get_party(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle_party: ExternRef<BattleParty>,
|
battle_party: ExternRef<BattleParty>,
|
||||||
) -> ExternRef<PokemonParty> {
|
) -> WasmResult<ExternRef<PokemonParty>> {
|
||||||
ExternRef::func_new(&env, battle_party.value_func(&env).unwrap().party().as_ref())
|
Ok(ExternRef::func_new(&env, battle_party.value_func(&env)?.party().as_ref())).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::dynamic_data::BattleRandom;
|
use crate::dynamic_data::BattleRandom;
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
|
@ -9,22 +9,22 @@ register! {
|
||||||
fn battle_random_get(
|
fn battle_random_get(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle_random: ExternRef<BattleRandom>,
|
battle_random: ExternRef<BattleRandom>,
|
||||||
) -> i32 {
|
) -> WasmResult<i32> {
|
||||||
battle_random.value_func(&env).unwrap().get().unwrap()
|
battle_random.value_func(&env)?.get().into()
|
||||||
}
|
}
|
||||||
fn battle_random_get_max(
|
fn battle_random_get_max(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle_random: ExternRef<BattleRandom>,
|
battle_random: ExternRef<BattleRandom>,
|
||||||
max: i32
|
max: i32
|
||||||
) -> i32 {
|
) -> WasmResult<i32> {
|
||||||
battle_random.value_func(&env).unwrap().get_max(max).unwrap()
|
battle_random.value_func(&env)?.get_max(max).into()
|
||||||
}
|
}
|
||||||
fn battle_random_get_between(
|
fn battle_random_get_between(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle_random: ExternRef<BattleRandom>,
|
battle_random: ExternRef<BattleRandom>,
|
||||||
min: i32,
|
min: i32,
|
||||||
max: i32
|
max: i32
|
||||||
) -> i32 {
|
) -> WasmResult<i32> {
|
||||||
battle_random.value_func(&env).unwrap().get_between(min, max).unwrap()
|
battle_random.value_func(&env)?.get_between(min, max).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use crate::dynamic_data::{Battle, BattleSide, Pokemon, VolatileScriptsOwner};
|
use crate::dynamic_data::{Battle, BattleSide, Pokemon, VolatileScriptsOwner};
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::ScriptCategory;
|
use crate::ScriptCategory;
|
||||||
|
use anyhow::anyhow;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
|
@ -11,78 +12,78 @@ register! {
|
||||||
fn battleside_has_fled_battle(
|
fn battleside_has_fled_battle(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
u8::from(side.value_func(&env).unwrap().has_fled_battle())
|
Ok(u8::from(side.value_func(&env)?.has_fled_battle())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_is_defeated(
|
fn battleside_is_defeated(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
u8::from(side.value_func(&env).unwrap().is_defeated())
|
Ok(u8::from(side.value_func(&env)?.is_defeated())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_get_side_index(
|
fn battleside_get_side_index(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
side.value_func(&env).unwrap().index()
|
Ok(side.value_func(&env)?.index()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_get_pokemon_per_side(
|
fn battleside_get_pokemon_per_side(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
side.value_func(&env).unwrap().pokemon_per_side()
|
Ok(side.value_func(&env)?.pokemon_per_side()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_get_battle(
|
fn battleside_get_battle(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> ExternRef<Battle> {
|
) -> WasmResult<ExternRef<Battle>> {
|
||||||
ExternRef::func_new(&env, side.value_func(&env).unwrap().battle().unwrap())
|
Ok(ExternRef::func_new(&env, side.value_func(&env)?.battle()?)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_get_pokemon(
|
fn battleside_get_pokemon(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
index: u32
|
index: u32
|
||||||
) -> ExternRef<Pokemon> {
|
) -> WasmResult<ExternRef<Pokemon>> {
|
||||||
if let Some(Some(p)) = side.value_func(&env).unwrap().pokemon().get(index as usize) {
|
Ok(if let Some(Some(p)) = side.value_func(&env)?.pokemon().get(index as usize) {
|
||||||
ExternRef::func_new(&env, p.as_ref())
|
ExternRef::func_new(&env, p.as_ref())
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_side_get_has_fled_battle(
|
fn battle_side_get_has_fled_battle(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if side.value_func(&env).unwrap().has_fled_battle() { 1 } else { 0 }
|
Ok(if side.value_func(&env)?.has_fled_battle() { 1 } else { 0 }).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_side_get_is_defeated(
|
fn battle_side_get_is_defeated(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if side.value_func(&env).unwrap().is_defeated() { 1 } else { 0 }
|
Ok(if side.value_func(&env)?.is_defeated() { 1 } else { 0 }).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_add_volatile_by_name(
|
fn battleside_add_volatile_by_name(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
let script = side.value_func(&env).unwrap().add_volatile_script(&c_name.as_ref().into()).unwrap();
|
let script = side.value_func(&env)?.add_volatile_script(&c_name.as_ref().into())?;
|
||||||
if let Some(script) = script {
|
Ok(if let Some(script) = script {
|
||||||
let script = script.get_as::<WebAssemblyScript>().unwrap();
|
let script = script.get_as::<WebAssemblyScript>()?;
|
||||||
script.get_wasm_pointer()
|
script.get_wasm_pointer()
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,22 +91,28 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
script_ptr: u32
|
script_ptr: u32
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
let side : &BattleSide = side.value_func(&env).unwrap();
|
let side : &BattleSide = side.value_func(&env)?;
|
||||||
unsafe{
|
unsafe {
|
||||||
let env = env.data().data();
|
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();
|
let name_ptr = match env
|
||||||
|
.script_function_cache()
|
||||||
|
.script_get_name(&env)?
|
||||||
|
.call(&mut env.store_mut(), script_ptr) {
|
||||||
|
Ok(name_ptr) => Ok(name_ptr),
|
||||||
|
Err(e) => Err(e.into())
|
||||||
|
}?;
|
||||||
let c_name: &CStr = CStr::from_ptr(env.get_raw_pointer(name_ptr));
|
let c_name: &CStr = CStr::from_ptr(env.get_raw_pointer(name_ptr));
|
||||||
let script = env.setup_script(script_ptr, ScriptCategory::Side, &c_name.as_ref().into(), side.into()).unwrap();
|
let script = env.setup_script(script_ptr, ScriptCategory::Side, &c_name.as_ref().into(), side.into())?;
|
||||||
env.script_function_cache().dealloc_cstring(&env).unwrap().call(&mut env.store_mut(), name_ptr).unwrap();
|
env.script_function_cache().dealloc_cstring(&env, name_ptr)?;
|
||||||
|
|
||||||
if let Some(script) = script {
|
Ok(if let Some(script) = script {
|
||||||
let script = side.add_volatile_script_with_script(script);
|
let script = side.add_volatile_script_with_script(script)?;
|
||||||
let s = script.as_ref().unwrap().as_ref().unwrap().get_as::<WebAssemblyScript>().unwrap();
|
let s = script.as_ref().ok_or(anyhow!("Couldn't get script"))?.get_as::<WebAssemblyScript>()?;
|
||||||
s.get_wasm_pointer()
|
s.get_wasm_pointer()
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,10 +120,10 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
u8::from(side.value_func(&env).unwrap().has_volatile_script(&c_name.as_ref().into()))
|
Ok(u8::from(side.value_func(&env)?.has_volatile_script(&c_name.as_ref().into()))).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,16 +131,16 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
let script = side.value_func(&env).unwrap().get_volatile_script(&c_name.as_ref().into());
|
let script = side.value_func(&env)?.get_volatile_script(&c_name.as_ref().into());
|
||||||
if let Some(script) = script {
|
Ok(if let Some(script) = script {
|
||||||
let script = script.get_as::<WebAssemblyScript>().unwrap();
|
let script = script.get_as::<WebAssemblyScript>()?;
|
||||||
script.get_wasm_pointer()
|
script.get_wasm_pointer()
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,10 +148,10 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) {
|
) -> WasmResult<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
side.value_func(&env).unwrap().remove_volatile_script(&c_name.as_ref().into()).unwrap();
|
side.value_func(&env)?.remove_volatile_script(&c_name.as_ref().into()).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::dynamic_data::{ChoiceQueue, Pokemon};
|
use crate::dynamic_data::{ChoiceQueue, Pokemon};
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
@ -9,7 +9,7 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle_random: ExternRef<ChoiceQueue>,
|
battle_random: ExternRef<ChoiceQueue>,
|
||||||
pokemon: ExternRef<Pokemon>
|
pokemon: ExternRef<Pokemon>
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
u8::from(battle_random.value_func(&env).unwrap().move_pokemon_choice_next(pokemon.value_func(&env).unwrap()).unwrap())
|
Ok(u8::from(battle_random.value_func(&env)?.move_pokemon_choice_next(pokemon.value_func(&env)?)?)).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::dynamic_data::{ExecutingMove, HitData, LearnedMove, Pokemon};
|
use crate::dynamic_data::{ExecutingMove, HitData, LearnedMove, Pokemon};
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
@ -10,29 +10,29 @@ register! {
|
||||||
fn executing_move_get_user(
|
fn executing_move_get_user(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
) -> ExternRef<Pokemon> {
|
) -> WasmResult<ExternRef<Pokemon>> {
|
||||||
ExternRef::func_new(&env, executing_move.value_func(&env).unwrap().user().as_ref())
|
Ok(ExternRef::func_new(&env, executing_move.value_func(&env)?.user().as_ref())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executing_move_get_use_move(
|
fn executing_move_get_use_move(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
) -> ExternRef<dyn MoveData> {
|
) -> WasmResult<ExternRef<dyn MoveData>> {
|
||||||
ExternRef::func_new(&env, executing_move.value_func(&env).unwrap().use_move())
|
Ok(ExternRef::func_new(&env, executing_move.value_func(&env)?.use_move())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executing_move_get_chosen_move(
|
fn executing_move_get_chosen_move(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
) -> ExternRef<LearnedMove> {
|
) -> WasmResult<ExternRef<LearnedMove>> {
|
||||||
ExternRef::func_new(&env, executing_move.value_func_arc(&env).unwrap().chosen_move().as_ref())
|
Ok(ExternRef::func_new(&env, executing_move.value_func(&env)?.chosen_move().as_ref())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executing_move_get_number_of_hits(
|
fn executing_move_get_number_of_hits(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
executing_move.value_func(&env).unwrap().number_of_hits()
|
Ok(executing_move.value_func(&env)?.number_of_hits()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executing_move_get_hit_data(
|
fn executing_move_get_hit_data(
|
||||||
|
@ -40,24 +40,24 @@ register! {
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<Pokemon>,
|
||||||
hit: u8
|
hit: u8
|
||||||
) -> ExternRef<HitData> {
|
) -> WasmResult<ExternRef<HitData>> {
|
||||||
ExternRef::func_new(&env, executing_move.value_func(&env).unwrap().get_hit_data(target.value_func(&env).unwrap(), hit).unwrap())
|
Ok(ExternRef::func_new(&env, executing_move.value_func(&env)?.get_hit_data(target.value_func(&env)?, hit)?)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executing_move_get_number_of_targets(
|
fn executing_move_get_number_of_targets(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
executing_move.value_func(&env).unwrap().target_count() as u32
|
Ok(executing_move.value_func(&env)?.target_count() as u32).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executing_move_is_pokemon_target(
|
fn executing_move_is_pokemon_target(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
pokemon: ExternRef<Pokemon>
|
pokemon: ExternRef<Pokemon>
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
let pokemon = pokemon.value_func_arc(&env).unwrap();
|
let pokemon = pokemon.value_func_arc(&env)?;
|
||||||
if executing_move.value_func(&env).unwrap().is_pokemon_target(&pokemon) { 1 } else { 0 }
|
Ok(if executing_move.value_func(&env)?.is_pokemon_target(&pokemon) { 1 } else { 0 }).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,16 +65,14 @@ register! {
|
||||||
fn executing_move_get_script(
|
fn executing_move_get_script(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
) -> (u32 , u32) {
|
) -> WasmResult<(u32 , u32)> {
|
||||||
let executing_move = executing_move.value_func(&env).unwrap();
|
let executing_move = executing_move.value_func(&env)?;
|
||||||
if let Some(script) = executing_move.script().get() {
|
let script = executing_move.script();
|
||||||
let read_lock = script.read();
|
if script.is_any() {
|
||||||
if let Some(script) = read_lock.as_ref() {
|
let s = script.get_as::<WebAssemblyScript>()?.get_wasm_pointer();
|
||||||
let s = script.as_any().downcast_ref::<WebAssemblyScript>().unwrap().get_wasm_pointer();
|
return Ok((s, s + 4)).into()
|
||||||
return (s, s + 4)
|
|
||||||
}
|
}
|
||||||
}
|
Ok((0, 0)).into()
|
||||||
(0, 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,14 @@ use std::mem::transmute;
|
||||||
|
|
||||||
use crate::defines::LevelInt;
|
use crate::defines::LevelInt;
|
||||||
use crate::dynamic_data::{Battle, DynamicLibrary, LearnedMove, Pokemon, VolatileScriptsOwner};
|
use crate::dynamic_data::{Battle, DynamicLibrary, LearnedMove, Pokemon, VolatileScriptsOwner};
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::{Ability, ClampedStatisticSet, Form, Nature, Species};
|
use crate::static_data::{Ability, ClampedStatisticSet, Form, Nature, Species};
|
||||||
use crate::static_data::{Item, StatisticSet};
|
use crate::static_data::{Item, StatisticSet};
|
||||||
use crate::ScriptCategory;
|
use crate::{ScriptCategory, VecExt};
|
||||||
|
use anyhow::anyhow;
|
||||||
use std::ffi::{c_char, CStr, CString};
|
use std::ffi::{c_char, CStr, CString};
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
|
@ -16,88 +17,89 @@ register! {
|
||||||
fn pokemon_get_library(
|
fn pokemon_get_library(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<dyn DynamicLibrary> {
|
) -> WasmResult<ExternRef<dyn DynamicLibrary>> {
|
||||||
let lib = pokemon.value_func(&env).unwrap().library().clone();
|
let lib = pokemon.value_func(&env)?.library().clone();
|
||||||
ExternRef::func_new(&env, &lib)
|
Ok(ExternRef::func_new(&env, &lib)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_boosted_stats(
|
fn pokemon_get_boosted_stats(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<StatisticSet<u32>> {
|
) -> WasmResult<ExternRef<StatisticSet<u32>>> {
|
||||||
let statistic_set = pokemon.value_func(&env).unwrap().boosted_stats();
|
let statistic_set = pokemon.value_func(&env)?.boosted_stats();
|
||||||
ExternRef::func_new(&env, statistic_set)
|
Ok(ExternRef::func_new(&env, statistic_set)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_flat_stats(
|
fn pokemon_get_flat_stats(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<StatisticSet<u32>> {
|
) -> WasmResult<ExternRef<StatisticSet<u32>>> {
|
||||||
let statistic_set = pokemon.value_func(&env).unwrap().flat_stats();
|
let statistic_set = pokemon.value_func(&env)?.flat_stats();
|
||||||
ExternRef::func_new(&env, statistic_set)
|
Ok(ExternRef::func_new(&env, statistic_set)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_stat_boosts(
|
fn pokemon_get_stat_boosts(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<ClampedStatisticSet<i8, -6, 6>> {
|
) -> WasmResult<ExternRef<ClampedStatisticSet<i8, -6, 6>>> {
|
||||||
let statistic_set = pokemon.value_func(&env).unwrap().stat_boosts();
|
let statistic_set = pokemon.value_func(&env)?.stat_boosts();
|
||||||
ExternRef::func_new(&env, statistic_set)
|
Ok(ExternRef::func_new(&env, statistic_set)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_individual_values(
|
fn pokemon_get_individual_values(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<ClampedStatisticSet<u8, 0, 31>> {
|
) -> WasmResult<ExternRef<ClampedStatisticSet<u8, 0, 31>>> {
|
||||||
let statistic_set = pokemon.value_func(&env).unwrap().individual_values();
|
let statistic_set = pokemon.value_func(&env)?.individual_values();
|
||||||
ExternRef::func_new(&env, statistic_set)
|
Ok(ExternRef::func_new(&env, statistic_set)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_effort_values(
|
fn pokemon_get_effort_values(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<ClampedStatisticSet<u8, 0, 252>> {
|
) -> WasmResult<ExternRef<ClampedStatisticSet<u8, 0, 252>>> {
|
||||||
let statistic_set = pokemon.value_func(&env).unwrap().effort_values();
|
let statistic_set = pokemon.value_func(&env)?.effort_values();
|
||||||
ExternRef::func_new(&env, statistic_set)
|
Ok(ExternRef::func_new(&env, statistic_set)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_species(
|
fn pokemon_get_species(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<dyn Species> {
|
) -> WasmResult<ExternRef<dyn Species>> {
|
||||||
let species = pokemon.value_func(&env).unwrap().species();
|
let species = pokemon.value_func(&env)?.species();
|
||||||
ExternRef::func_new(&env, &species)
|
Ok(ExternRef::func_new(&env, &species)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_weight(
|
fn pokemon_get_weight(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> f32 {
|
) -> WasmResult<f32> {
|
||||||
pokemon.value_func(&env).unwrap().weight()
|
Ok(pokemon.value_func(&env)?.weight()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_set_weight(
|
fn pokemon_set_weight(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
weight: f32,
|
weight: f32,
|
||||||
) {
|
) -> WasmResult<()> {
|
||||||
pokemon.value_func(&env).unwrap().set_weight(weight)
|
pokemon.value_func(&env)?.set_weight(weight);
|
||||||
|
Ok(()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn pokemon_get_height(
|
fn pokemon_get_height(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> f32 {
|
) -> WasmResult<f32> {
|
||||||
pokemon.value_func(&env).unwrap().height()
|
Ok(pokemon.value_func(&env)?.height()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_gender(
|
fn pokemon_get_gender(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
unsafe {
|
unsafe {
|
||||||
transmute(pokemon.value_func(&env).unwrap().gender())
|
Ok(transmute(pokemon.value_func(&env)?.gender())).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,9 +108,10 @@ register! {
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
damage: u32,
|
damage: u32,
|
||||||
source: u8
|
source: u8
|
||||||
) {
|
) -> WasmResult<()> {
|
||||||
unsafe{
|
unsafe{
|
||||||
pokemon.value_func(&env).unwrap().damage(damage, transmute(source)).unwrap();
|
pokemon.value_func(&env)?.damage(damage, transmute(source))?;
|
||||||
|
WasmResult::ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,15 +119,15 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
index: u32
|
index: u32
|
||||||
) -> ExternRef<LearnedMove> {
|
) -> WasmResult<ExternRef<LearnedMove>> {
|
||||||
let read_lock = pokemon.value_func(&env).unwrap().learned_moves().read();
|
let read_lock = pokemon.value_func(&env)?.learned_moves().read();
|
||||||
let mv = read_lock.get(index as usize);
|
let mv = read_lock.get(index as usize);
|
||||||
if let Some(Some(mv)) = mv {
|
Ok(if let Some(Some(mv)) = mv {
|
||||||
ExternRef::func_new(&env, mv)
|
ExternRef::func_new(&env, mv)
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_change_stat_boost(
|
fn pokemon_change_stat_boost(
|
||||||
|
@ -133,65 +136,65 @@ register! {
|
||||||
stat: u8,
|
stat: u8,
|
||||||
amount: i8,
|
amount: i8,
|
||||||
self_inflicted: u8
|
self_inflicted: u8
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
unsafe{
|
unsafe{
|
||||||
u8::from(pokemon.value_func(&env).unwrap().change_stat_boost(transmute(stat), amount, self_inflicted == 1).unwrap())
|
Ok(u8::from(pokemon.value_func(&env)?.change_stat_boost(transmute(stat), amount, self_inflicted == 1)?)).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_battle(
|
fn pokemon_get_battle(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<Battle> {
|
) -> WasmResult<ExternRef<Battle>> {
|
||||||
if let Some(battle) = pokemon.value_func(&env).unwrap().get_battle() {
|
Ok(if let Some(battle) = pokemon.value_func(&env)?.get_battle() {
|
||||||
ExternRef::func_new(&env, battle)
|
ExternRef::func_new(&env, battle)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_battle_index(
|
fn pokemon_get_battle_index(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if let Some(i) = pokemon.value_func(&env).unwrap().get_battle_index() {
|
Ok(if let Some(i) = pokemon.value_func(&env)?.get_battle_index() {
|
||||||
i
|
i
|
||||||
} else {
|
} else {
|
||||||
255
|
255
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_battle_side_index(
|
fn pokemon_get_battle_side_index(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if let Some(i) = pokemon.value_func(&env).unwrap().get_battle_side_index() {
|
Ok(if let Some(i) = pokemon.value_func(&env)?.get_battle_side_index() {
|
||||||
i
|
i
|
||||||
} else {
|
} else {
|
||||||
255
|
255
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_held_item(
|
fn pokemon_get_held_item(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<dyn Item> {
|
) -> WasmResult<ExternRef<dyn Item>> {
|
||||||
let read_lock = pokemon.value_func(&env).unwrap().held_item().read();
|
let read_lock = pokemon.value_func(&env)?.held_item().read();
|
||||||
if let Some(item) = read_lock.as_ref() {
|
Ok(if let Some(item) = read_lock.as_ref() {
|
||||||
ExternRef::func_new(&env, item.as_ref())
|
ExternRef::func_new(&env, item.as_ref())
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_has_held_item(
|
fn pokemon_has_held_item(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
name: u32
|
name: u32
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
let name : *mut c_char = env.data().data().get_raw_pointer(name);
|
let name : *mut c_char = env.data().data().get_raw_pointer(name);
|
||||||
let name = unsafe { CStr::from_ptr(name) };
|
let name = unsafe { CStr::from_ptr(name) };
|
||||||
u8::from(pokemon.value_func(&env).unwrap().has_held_item(&name.into()))
|
Ok(u8::from(pokemon.value_func(&env)?.has_held_item(&name.into()))).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_heal(
|
fn pokemon_heal(
|
||||||
|
@ -199,51 +202,52 @@ register! {
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
amount: u32,
|
amount: u32,
|
||||||
allow_revive: u8
|
allow_revive: u8
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
u8::from(pokemon.value_func(&env).unwrap().heal(amount, allow_revive == 1))
|
Ok(u8::from(pokemon.value_func(&env)?.heal(amount, allow_revive == 1))).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_clear_status(
|
fn pokemon_clear_status(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) {
|
) -> WasmResult<()> {
|
||||||
pokemon.value_func(&env).unwrap().clear_status()
|
pokemon.value_func(&env)?.clear_status();
|
||||||
|
WasmResult::ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_active_ability(
|
fn pokemon_get_active_ability(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<dyn Ability> {
|
) -> WasmResult<ExternRef<dyn Ability>> {
|
||||||
ExternRef::func_new(&env, &pokemon.value_func(&env).unwrap().active_ability())
|
Ok(ExternRef::func_new(&env, &pokemon.value_func(&env)?.active_ability())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_real_ability(
|
fn pokemon_get_real_ability(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> (u8, u8) {
|
) -> WasmResult<(u8, u8)> {
|
||||||
let index = &pokemon.value_func(&env).unwrap().real_ability();
|
let index = &pokemon.value_func(&env)?.real_ability();
|
||||||
(if index.hidden { 1 } else { 0 }, index.index)
|
WasmResult::ok((if index.hidden { 1 } else { 0 }, index.index))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_is_ability_overriden(
|
fn pokemon_get_is_ability_overriden(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if pokemon.value_func(&env).unwrap().is_ability_overriden() { 1 } else { 0 }
|
Ok(if pokemon.value_func(&env)?.is_ability_overriden() { 1 } else { 0 }).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_allowed_experience_gain(
|
fn pokemon_get_allowed_experience_gain(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if pokemon.value_func(&env).unwrap().allowed_experience_gain() { 1 } else { 0 }
|
Ok(if pokemon.value_func(&env)?.allowed_experience_gain() { 1 } else { 0 }).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_is_usable(
|
fn pokemon_get_is_usable(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if pokemon.value_func(&env).unwrap().is_usable() { 1 } else { 0 }
|
Ok(if pokemon.value_func(&env)?.is_usable() { 1 } else { 0 }).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -251,56 +255,56 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
item: ExternRef<dyn Item>
|
item: ExternRef<dyn Item>
|
||||||
) -> ExternRef<dyn Item> {
|
) -> WasmResult<ExternRef<dyn Item>> {
|
||||||
let item = item.value_func_arc(&env).unwrap();
|
let item = item.value_func_arc(&env)?;
|
||||||
let old_item = pokemon.value_func(&env).unwrap().set_held_item(&item);
|
let old_item = pokemon.value_func(&env)?.set_held_item(&item);
|
||||||
if let Some(old_item) = old_item {
|
Ok(if let Some(old_item) = old_item {
|
||||||
ExternRef::func_new(&env, &old_item)
|
ExternRef::func_new(&env, &old_item)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_remove_held_item(
|
fn pokemon_remove_held_item(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<dyn Item> {
|
) -> WasmResult<ExternRef<dyn Item>> {
|
||||||
let old_item = pokemon.value_func(&env).unwrap().remove_held_item();
|
let old_item = pokemon.value_func(&env)?.remove_held_item();
|
||||||
if let Some(old_item) = old_item {
|
Ok(if let Some(old_item) = old_item {
|
||||||
ExternRef::func_new(&env, &old_item)
|
ExternRef::func_new(&env, &old_item)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_consume_held_item(
|
fn pokemon_consume_held_item(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if pokemon.value_func(&env).unwrap().consume_held_item().unwrap() { 1 } else { 0 }
|
Ok(if pokemon.value_func(&env)?.consume_held_item()? { 1 } else { 0 }).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_types_length(
|
fn pokemon_get_types_length(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>
|
pokemon: ExternRef<Pokemon>
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
pokemon.value_func(&env).unwrap().types().len() as u32
|
Ok(pokemon.value_func(&env)?.types().len() as u32).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_type(
|
fn pokemon_get_type(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
index: u32
|
index: u32
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
(*pokemon.value_func(&env).unwrap().types().get(index as usize).unwrap()).into()
|
Ok((*pokemon.value_func(&env)?.types().get_res(index as usize)?).into()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_has_type(
|
fn pokemon_has_type(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
t: u8
|
t: u8
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if pokemon.value_func(&env).unwrap().types().contains(&t.into()) { 1 } else { 0 }
|
Ok(if pokemon.value_func(&env)?.types().contains(&t.into()) { 1 } else { 0 }).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_change_species(
|
fn pokemon_change_species(
|
||||||
|
@ -308,97 +312,102 @@ register! {
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
species: ExternRef<dyn Species>,
|
species: ExternRef<dyn Species>,
|
||||||
form: ExternRef<dyn Form>,
|
form: ExternRef<dyn Form>,
|
||||||
) {
|
) -> WasmResult<()> {
|
||||||
pokemon.value_func(&env).unwrap().change_species(
|
pokemon.value_func(&env)?.change_species(
|
||||||
species.value_func_arc(&env).unwrap(),
|
species.value_func_arc(&env)?,
|
||||||
form.value_func_arc(&env).unwrap(),
|
form.value_func_arc(&env)?,
|
||||||
).unwrap();
|
)?;
|
||||||
|
WasmResult::ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_change_form(
|
fn pokemon_change_form(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
form: ExternRef<dyn Form>,
|
form: ExternRef<dyn Form>,
|
||||||
) {
|
) -> WasmResult<()> {
|
||||||
pokemon.value_func(&env).unwrap().change_form(
|
pokemon.value_func(&env)?.change_form(
|
||||||
&form.value_func_arc(&env).unwrap(),
|
&form.value_func_arc(&env)?,
|
||||||
).unwrap();
|
)?;
|
||||||
|
WasmResult::ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_current_health(
|
fn pokemon_get_current_health(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
pokemon.value_func(&env).unwrap().current_health()
|
Ok(pokemon.value_func(&env)?.current_health()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_nature(
|
fn pokemon_get_nature(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<dyn Nature> {
|
) -> WasmResult<ExternRef<dyn Nature>> {
|
||||||
ExternRef::func_new(&env, pokemon.value_func(&env).unwrap().nature())
|
Ok(ExternRef::func_new(&env, pokemon.value_func(&env)?.nature())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_form(
|
fn pokemon_get_form(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<dyn Form> {
|
) -> WasmResult<ExternRef<dyn Form>> {
|
||||||
ExternRef::func_new(&env, &pokemon.value_func(&env).unwrap().form())
|
Ok(ExternRef::func_new(&env, &pokemon.value_func(&env)?.form())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_display_species(
|
fn pokemon_get_display_species(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<dyn Species> {
|
) -> WasmResult<ExternRef<dyn Species>> {
|
||||||
ExternRef::func_new(&env, &pokemon.value_func(&env).unwrap().display_species())
|
Ok(ExternRef::func_new(&env, &pokemon.value_func(&env)?.display_species())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_display_form(
|
fn pokemon_get_display_form(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<dyn Form> {
|
) -> WasmResult<ExternRef<dyn Form>> {
|
||||||
ExternRef::func_new(&env, &pokemon.value_func(&env).unwrap().display_form())
|
Ok(ExternRef::func_new(&env, &pokemon.value_func(&env)?.display_form())).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_level(
|
fn pokemon_get_level(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> LevelInt {
|
) -> WasmResult<LevelInt> {
|
||||||
pokemon.value_func(&env).unwrap().level()
|
Ok(pokemon.value_func(&env)?.level()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_experience(
|
fn pokemon_get_experience(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
pokemon.value_func(&env).unwrap().experience()
|
Ok(pokemon.value_func(&env)?.experience()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_unique_identifier(
|
fn pokemon_get_unique_identifier(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
pokemon.value_func(&env).unwrap().unique_identifier()
|
Ok(pokemon.value_func(&env)?.unique_identifier()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_coloring(
|
fn pokemon_get_coloring(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
pokemon.value_func(&env).unwrap().coloring()
|
Ok(pokemon.value_func(&env)?.coloring()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_nickname(
|
fn pokemon_get_nickname(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
let pokemon = pokemon.value_func(&env).unwrap();
|
let pokemon = pokemon.value_func(&env)?;
|
||||||
let nickname = pokemon.nickname();
|
let nickname = pokemon.nickname();
|
||||||
if let Some(nickname) = nickname {
|
if let Some(nickname) = nickname {
|
||||||
let nickname: CString = CString::new(nickname.as_str()).unwrap();
|
let nickname: CString = match CString::new(nickname.as_str()) {
|
||||||
env.data().data().copy_value_vec_to_wasm(nickname.as_bytes())
|
Ok(nickname) => nickname,
|
||||||
|
Err(e) => return WasmResult::err(e.into()),
|
||||||
|
};
|
||||||
|
env.data().data().copy_value_vec_to_wasm(nickname.as_bytes()).into()
|
||||||
} else {
|
} else {
|
||||||
0
|
Ok(0).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,15 +417,15 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
let script = pokemon.value_func(&env).unwrap().add_volatile_script(&c_name.as_ref().into()).unwrap();
|
let script = pokemon.value_func(&env)?.add_volatile_script(&c_name.as_ref().into())?;
|
||||||
if let Some(script) = script {
|
if let Some(script) = script {
|
||||||
let script = script.get_as::<WebAssemblyScript>().unwrap();
|
let script = script.get_as::<WebAssemblyScript>()?;
|
||||||
script.get_wasm_pointer()
|
Ok(script.get_wasm_pointer()).into()
|
||||||
} else {
|
} else {
|
||||||
0
|
Ok(0).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -425,21 +434,24 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
script_ptr: u32
|
script_ptr: u32
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
let pokemon : &Pokemon = pokemon.value_func(&env).unwrap();
|
let pokemon : &Pokemon = pokemon.value_func(&env)?;
|
||||||
unsafe{
|
unsafe{
|
||||||
let env = env.data().data();
|
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();
|
let name_ptr = match env.script_function_cache().script_get_name(&env)?.call(&mut env.store_mut(), script_ptr){
|
||||||
|
Ok(name_ptr) => name_ptr,
|
||||||
|
Err(e) => return WasmResult::err(e.into())
|
||||||
|
};
|
||||||
let c_name: &CStr = CStr::from_ptr(env.get_raw_pointer(name_ptr));
|
let c_name: &CStr = CStr::from_ptr(env.get_raw_pointer(name_ptr));
|
||||||
let script = env.setup_script(script_ptr, ScriptCategory::Pokemon, &c_name.as_ref().into(), pokemon.into()).unwrap();
|
let script = env.setup_script(script_ptr, ScriptCategory::Pokemon, &c_name.as_ref().into(), pokemon.into())?;
|
||||||
env.script_function_cache().dealloc_cstring(&env).unwrap().call(&mut env.store_mut(), name_ptr).unwrap();
|
env.script_function_cache().dealloc_cstring(&env, name_ptr)?;
|
||||||
|
|
||||||
if let Some(script) = script {
|
if let Some(script) = script {
|
||||||
let script = pokemon.add_volatile_script_with_script(script);
|
let script = pokemon.add_volatile_script_with_script(script)?;
|
||||||
let s = script.as_ref().unwrap().as_ref().unwrap().get_as::<WebAssemblyScript>().unwrap();
|
let s = script.as_ref().ok_or(anyhow!("Unable to get script"))?.get_as::<WebAssemblyScript>()?;
|
||||||
s.get_wasm_pointer()
|
WasmResult::ok(s.get_wasm_pointer())
|
||||||
} else {
|
} else {
|
||||||
0
|
WasmResult::ok(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,10 +460,10 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
u8::from(pokemon.value_func(&env).unwrap().has_volatile_script(&c_name.as_ref().into()))
|
Ok(u8::from(pokemon.value_func(&env)?.has_volatile_script(&c_name.as_ref().into()))).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,16 +471,16 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
let script = pokemon.value_func(&env).unwrap().get_volatile_script(&c_name.as_ref().into());
|
let script = pokemon.value_func(&env)?.get_volatile_script(&c_name.as_ref().into());
|
||||||
if let Some(script) = script {
|
Ok(if let Some(script) = script {
|
||||||
let script = script.get_as::<WebAssemblyScript>().unwrap();
|
let script = script.get_as::<WebAssemblyScript>()?;
|
||||||
script.get_wasm_pointer()
|
script.get_wasm_pointer()
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,25 +488,24 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) {
|
) -> WasmResult<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
pokemon.value_func(&env).unwrap().remove_volatile_script(&c_name.as_ref().into()).unwrap();
|
pokemon.value_func(&env)?.remove_volatile_script(&c_name.as_ref().into())?;
|
||||||
|
WasmResult::ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_ability_script(
|
fn pokemon_get_ability_script(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
let pokemon = pokemon.value_func(&env).unwrap();
|
let pokemon = pokemon.value_func(&env)?;
|
||||||
if let Some(script) = pokemon.ability_script().get() {
|
let script = pokemon.ability_script();
|
||||||
let read_lock = script.read();
|
if script.is_any() {
|
||||||
if let Some(script) = read_lock.as_ref() {
|
return Ok(script.get_as::<WebAssemblyScript>()?.get_wasm_pointer()).into();
|
||||||
return script.as_any().downcast_ref::<WebAssemblyScript>().unwrap().get_wasm_pointer()
|
|
||||||
}
|
}
|
||||||
}
|
WasmResult::ok(0)
|
||||||
0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
|
use anyhow_ext::anyhow;
|
||||||
|
use anyhow_ext::Result;
|
||||||
|
use num_traits::{NumCast, PrimInt};
|
||||||
use std::ffi::{c_char, CStr, CString};
|
use std::ffi::{c_char, CStr, CString};
|
||||||
use std::mem::{align_of, forget};
|
use std::mem::{align_of, forget};
|
||||||
|
use std::ops::{ControlFlow, FromResidual, Try};
|
||||||
|
|
||||||
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
use wasmer::{FromToNativeWasmType, FunctionEnv, FunctionEnvMut, Imports, NativeWasmTypeInto, StoreMut};
|
||||||
|
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
@ -108,80 +112,147 @@ fn _error(env: FunctionEnvMut<WebAssemblyEnv>, message: u32, file: u32, line: u3
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a single item from an earlier passed VecExternRef
|
/// Get a single item from an earlier passed VecExternRef
|
||||||
fn _vec_extern_ref_get_value(env: FunctionEnvMut<WebAssemblyEnv>, reference: u32, index: u32) -> u32 {
|
fn _vec_extern_ref_get_value(env: FunctionEnvMut<WebAssemblyEnv>, reference: u32, index: u32) -> WasmResult<u32> {
|
||||||
env.data()
|
let res = env
|
||||||
.data()
|
.data()
|
||||||
.get_extern_vec_ref_extern_ref(reference as usize, index as usize) as u32
|
.data()
|
||||||
|
.get_extern_vec_ref_extern_ref(reference as usize, index as usize)?;
|
||||||
|
Ok(res as u32).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the hash value of a StringKey.
|
/// Gets the hash value of a StringKey.
|
||||||
fn string_key_get_hash(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> u32 {
|
fn string_key_get_hash(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> WasmResult<u32> {
|
||||||
string_key.value_func(&env).unwrap().hash()
|
Ok(string_key.value_func(&env)?.hash()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a null-terminated C string from a StringKey. Note that this involves a copy into WASM
|
/// Get a null-terminated C string from a StringKey. Note that this involves a copy into WASM
|
||||||
/// memory, so this is relatively heavy.
|
/// memory, so this is relatively heavy.
|
||||||
fn string_key_get_str(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> u32 {
|
fn string_key_get_str(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> WasmResult<u32> {
|
||||||
let string_key = string_key.value_func(&env).unwrap().str();
|
let string_key = string_key.value_func(&env)?.str();
|
||||||
let wasm_string_ptr = env
|
let wasm_string_ptr = env
|
||||||
.data()
|
.data()
|
||||||
.data()
|
.data()
|
||||||
.allocate_mem((string_key.len() + 1) as u32, align_of::<CString>() as u32);
|
.allocate_mem((string_key.len() + 1) as u32, align_of::<CString>() as u32)?;
|
||||||
let mut wasm_string: Vec<u8> =
|
let mut wasm_string: Vec<u8> =
|
||||||
unsafe { Vec::from_raw_parts(wasm_string_ptr.0, string_key.len() + 1, string_key.len() + 1) };
|
unsafe { Vec::from_raw_parts(wasm_string_ptr.0, string_key.len() + 1, string_key.len() + 1) };
|
||||||
wasm_string.resize(string_key.len() + 1, 0);
|
wasm_string.resize(string_key.len() + 1, 0);
|
||||||
string_key.as_bytes().clone_into(&mut wasm_string);
|
string_key.as_bytes().clone_into(&mut wasm_string);
|
||||||
wasm_string.insert(string_key.len(), 0_u8);
|
wasm_string.insert(string_key.len(), 0_u8);
|
||||||
forget(wasm_string);
|
forget(wasm_string);
|
||||||
wasm_string_ptr.1
|
Ok(wasm_string_ptr.1).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the type of an EffectParameter
|
/// Gets the type of an EffectParameter
|
||||||
fn effect_parameter_get_type(env: FunctionEnvMut<WebAssemblyEnv>, parameter: ExternRef<EffectParameter>) -> u8 {
|
fn effect_parameter_get_type(
|
||||||
let v = parameter.value_func(&env).unwrap();
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
match v {
|
parameter: ExternRef<EffectParameter>,
|
||||||
|
) -> WasmResult<u8> {
|
||||||
|
let v = parameter.value_func(&env)?;
|
||||||
|
Ok(match v {
|
||||||
EffectParameter::Bool(_, _) => 1,
|
EffectParameter::Bool(_, _) => 1,
|
||||||
EffectParameter::Int(_, _) => 2,
|
EffectParameter::Int(_, _) => 2,
|
||||||
EffectParameter::Float(_, _) => 3,
|
EffectParameter::Float(_, _) => 3,
|
||||||
EffectParameter::String(_, _) => 4,
|
EffectParameter::String(_, _) => 4,
|
||||||
}
|
})
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inner bool data of an EffectParameter. Panics if it's not a bool.
|
/// Gets the inner bool data of an EffectParameter. Panics if it's not a bool.
|
||||||
fn effect_parameter_as_bool(env: FunctionEnvMut<WebAssemblyEnv>, parameter: ExternRef<EffectParameter>) -> u8 {
|
fn effect_parameter_as_bool(
|
||||||
let v = parameter.value_func(&env).unwrap();
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
|
parameter: ExternRef<EffectParameter>,
|
||||||
|
) -> WasmResult<u8> {
|
||||||
|
let v = parameter.value_func(&env)?;
|
||||||
match v {
|
match v {
|
||||||
EffectParameter::Bool(_, b) => u8::from(*b),
|
EffectParameter::Bool(_, b) => Ok(<u8 as From<bool>>::from(*b)),
|
||||||
_ => panic!("Unexpected parameter type!"),
|
_ => Err(anyhow!("Unexpected parameter type. Expected bool, got {}", v)),
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inner int data of an EffectParameter. Panics if it's not an int.
|
/// Gets the inner int data of an EffectParameter. Panics if it's not an int.
|
||||||
fn effect_parameter_as_int(env: FunctionEnvMut<WebAssemblyEnv>, parameter: ExternRef<EffectParameter>) -> i64 {
|
fn effect_parameter_as_int(
|
||||||
let v = parameter.value_func(&env).unwrap();
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
|
parameter: ExternRef<EffectParameter>,
|
||||||
|
) -> WasmResult<i64> {
|
||||||
|
let v = parameter.value_func(&env)?;
|
||||||
match v {
|
match v {
|
||||||
EffectParameter::Int(_, i) => *i,
|
EffectParameter::Int(_, i) => Ok(*i),
|
||||||
_ => panic!("Unexpected parameter type!"),
|
_ => Err(anyhow!("Unexpected parameter type. Expected int, got {}", v)),
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inner float data of an EffectParameter. Panics if it's not a float.
|
/// Gets the inner float data of an EffectParameter. Panics if it's not a float.
|
||||||
fn effect_parameter_as_float(env: FunctionEnvMut<WebAssemblyEnv>, parameter: ExternRef<EffectParameter>) -> f32 {
|
fn effect_parameter_as_float(
|
||||||
let v = parameter.value_func(&env).unwrap();
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
|
parameter: ExternRef<EffectParameter>,
|
||||||
|
) -> WasmResult<f32> {
|
||||||
|
let v = parameter.value_func(&env)?;
|
||||||
match v {
|
match v {
|
||||||
EffectParameter::Float(_, f) => *f,
|
EffectParameter::Float(_, f) => Ok(*f),
|
||||||
_ => panic!("Unexpected parameter type!"),
|
_ => Err(anyhow!("Unexpected parameter type. Expected float, got {}", v)),
|
||||||
}
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inner string data of an EffectParameter. Panics if it's not a string.
|
/// Gets the inner string data of an EffectParameter. Panics if it's not a string.
|
||||||
fn effect_parameter_as_string(
|
fn effect_parameter_as_string(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
parameter: ExternRef<EffectParameter>,
|
parameter: ExternRef<EffectParameter>,
|
||||||
) -> ExternRef<StringKey> {
|
) -> WasmResult<ExternRef<StringKey>> {
|
||||||
let v = parameter.value_func(&env).unwrap();
|
let v = parameter.value_func(&env)?;
|
||||||
match v {
|
match v {
|
||||||
EffectParameter::String(_, s) => ExternRef::func_new(&env, s),
|
EffectParameter::String(_, s) => Ok(ExternRef::func_new(&env, s)),
|
||||||
_ => panic!("Unexpected parameter type!"),
|
_ => Err(anyhow!("Unexpected parameter type. Expected string, got {}", v)),
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A result type that can be given to, or returned from WASM.
|
||||||
|
struct WasmResult<T>(Result<T>);
|
||||||
|
|
||||||
|
impl<T> WasmResult<T> {
|
||||||
|
/// Create a new WasmResult with an OK value.
|
||||||
|
pub fn ok(value: T) -> Self {
|
||||||
|
Self(Ok(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new WasmResult with an Err value.
|
||||||
|
pub fn err(value: anyhow_ext::Error) -> Self {
|
||||||
|
Self(Err(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<Result<T>> for WasmResult<T> {
|
||||||
|
fn from(value: Result<T>) -> Self {
|
||||||
|
Self(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> FromResidual for WasmResult<T> {
|
||||||
|
fn from_residual(residual: <Self as Try>::Residual) -> Self {
|
||||||
|
match residual {
|
||||||
|
Ok(_) => {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
Err(e) => WasmResult(Err(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Try for WasmResult<T> {
|
||||||
|
type Output = T;
|
||||||
|
type Residual = <Result<T> as Try>::Residual;
|
||||||
|
|
||||||
|
fn from_output(output: Self::Output) -> Self {
|
||||||
|
Self(Ok(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
|
||||||
|
match self.0 {
|
||||||
|
Ok(v) => ControlFlow::Continue(v),
|
||||||
|
Err(e) => ControlFlow::Break(Err(e)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
|
||||||
use crate::script_implementations::wasm::export_registry::FunctionEnvMut;
|
use crate::script_implementations::wasm::export_registry::FunctionEnvMut;
|
||||||
|
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::{Form, StatisticSet};
|
use crate::static_data::{Form, StatisticSet};
|
||||||
|
@ -18,11 +18,11 @@ fn form_get_name(
|
||||||
fn form_get_types(
|
fn form_get_types(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
form: ExternRef<dyn Form>
|
form: ExternRef<dyn Form>
|
||||||
) -> (u32, u32) {
|
) -> WasmResult<(u32, u32)> {
|
||||||
let form = form.value_func_arc(&env).unwrap();
|
let form = form.value_func_arc(&env).unwrap();
|
||||||
let vec = form.types();
|
let vec = form.types();
|
||||||
let wasm_ptr = env.data().data().copy_value_vec_to_wasm(vec);
|
let wasm_ptr = env.data().data().copy_value_vec_to_wasm(vec)?;
|
||||||
(wasm_ptr, vec.len() as u32)
|
Ok((wasm_ptr, vec.len() as u32)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn form_get_height(
|
fn form_get_height(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::ValueIdentifiable;
|
use crate::{PkmnError, ValueIdentifiable};
|
||||||
|
use anyhow_ext::Result;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
|
@ -68,25 +69,26 @@ impl<T: ValueIdentifiable + ?Sized> ExternRef<T> {
|
||||||
|
|
||||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
/// 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.
|
/// value when it was passed before. If these types do not match, this will panic.
|
||||||
pub fn value_func<'a>(&self, env: &'a FunctionEnvMut<WebAssemblyEnv>) -> Option<&'a T>
|
pub fn value_func<'a>(&self, env: &'a FunctionEnvMut<WebAssemblyEnv>) -> Result<&'a T>
|
||||||
where
|
where
|
||||||
T: Sized + 'static,
|
T: Sized + 'static,
|
||||||
{
|
{
|
||||||
self.value(&env.data().data())
|
self.value(&env.data().data())?.ok_or(PkmnError::NullReference.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
/// 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.
|
/// value when it was passed before. If these types do not match, this will panic.
|
||||||
pub fn value_func_arc(&self, env: &FunctionEnvMut<WebAssemblyEnv>) -> Option<Arc<T>>
|
pub fn value_func_arc(&self, env: &FunctionEnvMut<WebAssemblyEnv>) -> Result<Arc<T>>
|
||||||
where
|
where
|
||||||
T: 'static,
|
T: 'static,
|
||||||
{
|
{
|
||||||
self.value_arc(&env.data().data())
|
self.value_arc(&env.data().data())?
|
||||||
|
.ok_or(PkmnError::NullReference.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
/// 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.
|
/// value when it was passed before. If these types do not match, this will panic.
|
||||||
pub fn value_func_box(&self, env: &FunctionEnvMut<WebAssemblyEnv>) -> Option<&Box<T>>
|
pub fn value_func_box(&self, env: &FunctionEnvMut<WebAssemblyEnv>) -> Result<&Box<T>>
|
||||||
where
|
where
|
||||||
T: 'static,
|
T: 'static,
|
||||||
{
|
{
|
||||||
|
@ -95,31 +97,34 @@ impl<T: ValueIdentifiable + ?Sized> ExternRef<T> {
|
||||||
|
|
||||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
/// 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.
|
/// value when it was passed before. If these types do not match, this will panic.
|
||||||
pub fn value<'a>(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Option<&'a T>
|
pub fn value<'a>(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Result<Option<&'a T>>
|
||||||
where
|
where
|
||||||
T: Sized + 'static,
|
T: Sized + 'static,
|
||||||
{
|
{
|
||||||
env.get_extern_ref_value::<T>(self.index).downcast_ref::<T>()
|
Ok(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
|
/// 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.
|
/// 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>>
|
pub fn value_arc(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Result<Option<Arc<T>>>
|
||||||
where
|
where
|
||||||
T: 'static,
|
T: 'static,
|
||||||
{
|
{
|
||||||
env.get_extern_ref_value::<T>(self.index)
|
Ok(env
|
||||||
|
.get_extern_ref_value::<T>(self.index)?
|
||||||
.downcast_ref::<Arc<T>>()
|
.downcast_ref::<Arc<T>>()
|
||||||
.cloned()
|
.cloned())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
/// 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.
|
/// value when it was passed before. If these types do not match, this will panic.
|
||||||
pub fn value_box(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Option<&Box<T>>
|
pub fn value_box(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Result<&Box<T>>
|
||||||
where
|
where
|
||||||
T: 'static,
|
T: 'static,
|
||||||
{
|
{
|
||||||
env.get_extern_ref_value::<T>(self.index).downcast_ref::<Box<T>>()
|
env.get_extern_ref_value::<T>(self.index)?
|
||||||
|
.downcast_ref::<Box<T>>()
|
||||||
|
.ok_or(PkmnError::NullReference.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use anyhow_ext::Result;
|
use anyhow_ext::{anyhow, Result};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicUsize};
|
use std::sync::atomic::{AtomicBool, AtomicUsize};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -189,7 +189,11 @@ impl Script for WebAssemblyScript {
|
||||||
let move_ref = ex_ref!(env, move_name);
|
let move_ref = ex_ref!(env, move_name);
|
||||||
let ptr = env.allocate_temp::<ExternRef<StringKey>>(move_ref);
|
let ptr = env.allocate_temp::<ExternRef<StringKey>>(move_ref);
|
||||||
call_func!(func, env, self, ex_ref!(env, choice), ptr.wasm_ptr);
|
call_func!(func, env, self, ex_ref!(env, choice), ptr.wasm_ptr);
|
||||||
*move_name = ptr.value().value(env).unwrap().clone();
|
*move_name = ptr
|
||||||
|
.value()
|
||||||
|
.value(env)?
|
||||||
|
.ok_or(anyhow!("Unable to get move name"))?
|
||||||
|
.clone();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
use anyhow::anyhow;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use anyhow_ext::Result;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
|
|
||||||
|
@ -177,40 +179,50 @@ script_function_cache! {
|
||||||
|
|
||||||
impl ScriptFunctionCache {
|
impl ScriptFunctionCache {
|
||||||
/// Get the name of a script.
|
/// Get the name of a script.
|
||||||
pub(crate) fn script_get_name(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Option<TypedFunction<u32, u32>> {
|
pub(crate) fn script_get_name(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Result<TypedFunction<u32, u32>> {
|
||||||
{
|
{
|
||||||
let read_lock = self.script_get_name.read();
|
let read_lock = self.script_get_name.read();
|
||||||
if let Some(f) = read_lock.as_ref() {
|
if let Some(f) = read_lock.as_ref() {
|
||||||
return Some(f.clone());
|
return Ok(f.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let exported = env.exported_functions();
|
let exported = env.exported_functions();
|
||||||
let f = exported.get::<StringKey>(&"script_get_name".into());
|
let f = exported.get::<StringKey>(&"script_get_name".into());
|
||||||
if let Some(f) = f {
|
if let Some(f) = f {
|
||||||
let func: TypedFunction<u32, u32> = f.typed(&env.store_ref()).unwrap();
|
let func: TypedFunction<u32, u32> = f.typed(&env.store_ref())?;
|
||||||
let _ = self.script_get_name.write().insert(func);
|
let _ = self.script_get_name.write().insert(func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.script_get_name.read().as_ref().cloned()
|
Ok(self
|
||||||
|
.script_get_name
|
||||||
|
.read()
|
||||||
|
.as_ref()
|
||||||
|
.ok_or(anyhow!("Couldn't find script function `script_get_name`"))?
|
||||||
|
.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drop the memory of a CString inside the WASM memory.
|
/// Drop the memory of a CString inside the WASM memory.
|
||||||
pub(crate) fn dealloc_cstring(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Option<TypedFunction<u32, ()>> {
|
pub(crate) fn dealloc_cstring(&self, env: &Arc<WebAssemblyEnvironmentData>, ptr: u32) -> Result<()> {
|
||||||
{
|
{
|
||||||
let read_lock = self.dealloc_cstring.read();
|
let read_lock = self.dealloc_cstring.read();
|
||||||
if let Some(f) = read_lock.as_ref() {
|
if read_lock.is_none() {
|
||||||
return Some(f.clone());
|
drop(read_lock);
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
let exported = env.exported_functions();
|
let exported = env.exported_functions();
|
||||||
let f = exported.get::<StringKey>(&"dealloc_cstring".into());
|
let f = exported.get::<StringKey>(&"dealloc_cstring".into());
|
||||||
if let Some(f) = f {
|
if let Some(f) = f {
|
||||||
let func: TypedFunction<u32, ()> = f.typed(&env.store_ref()).unwrap();
|
let func: TypedFunction<u32, ()> = f.typed(&env.store_ref())?;
|
||||||
let _ = self.dealloc_cstring.write().insert(func);
|
let _ = self.dealloc_cstring.write().insert(func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.dealloc_cstring.read().as_ref().cloned()
|
};
|
||||||
|
let func = self
|
||||||
|
.dealloc_cstring
|
||||||
|
.read()
|
||||||
|
.as_ref()
|
||||||
|
.ok_or(anyhow!("Couldn't find script function `dealloc_cstring`"))?
|
||||||
|
.clone();
|
||||||
|
func.call(&mut env.store_mut(), ptr)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ use crate::script_implementations::wasm::script_function_cache::ScriptFunctionCa
|
||||||
use crate::script_implementations::wasm::temp_wasm_allocator::{AllocatedObject, TempWasmAllocator};
|
use crate::script_implementations::wasm::temp_wasm_allocator::{AllocatedObject, TempWasmAllocator};
|
||||||
use crate::script_implementations::wasm::WebAssemblyScriptCapabilities;
|
use crate::script_implementations::wasm::WebAssemblyScriptCapabilities;
|
||||||
use crate::static_data::Item;
|
use crate::static_data::Item;
|
||||||
use crate::{ScriptCategory, StringKey, ValueIdentifiable, ValueIdentifier};
|
use crate::{ScriptCategory, StringKey, ValueIdentifiable, ValueIdentifier, VecExt};
|
||||||
|
|
||||||
/// A WebAssembly script resolver implements the dynamic scripts functionality with WebAssembly.
|
/// A WebAssembly script resolver implements the dynamic scripts functionality with WebAssembly.
|
||||||
pub struct WebAssemblyScriptResolver {
|
pub struct WebAssemblyScriptResolver {
|
||||||
|
@ -80,23 +80,30 @@ impl WebAssemblyScriptResolver {
|
||||||
|
|
||||||
/// Get an immutable reference to the current WASM Store.
|
/// Get an immutable reference to the current WASM Store.
|
||||||
fn store_ref(&self) -> StoreRef<'_> {
|
fn store_ref(&self) -> StoreRef<'_> {
|
||||||
unsafe { self._store.as_ref().unwrap().as_store_ref() }
|
#[allow(clippy::unwrap_used)] // We know this is valid.
|
||||||
|
unsafe {
|
||||||
|
self._store.as_ref().unwrap().as_store_ref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a mutable reference to the current WASM Store.
|
/// Get a mutable reference to the current WASM Store.
|
||||||
fn store_mut(&self) -> StoreMut<'_> {
|
fn store_mut(&self) -> StoreMut<'_> {
|
||||||
unsafe { self._store.as_mut().unwrap().as_store_mut() }
|
#[allow(clippy::unwrap_used)] // We know this is valid.
|
||||||
|
unsafe {
|
||||||
|
self._store.as_mut().unwrap().as_store_mut()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a compiled WASM module.
|
/// Load a compiled WASM module.
|
||||||
pub fn load_wasm_from_bytes(&mut self, bytes: &[u8]) {
|
pub fn load_wasm_from_bytes(&mut self, bytes: &[u8]) -> Result<()> {
|
||||||
// FIXME: Error handling
|
// FIXME: Error handling
|
||||||
let module = Module::new(&self.store_ref(), bytes).unwrap();
|
let module = Module::new(&self.store_ref(), bytes)?;
|
||||||
self.modules.push(module);
|
self.modules.push(module);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tells the script resolver we're done loading wasm modules, and to finalize the resolver.
|
/// Tells the script resolver we're done loading wasm modules, and to finalize the resolver.
|
||||||
pub fn finalize(&mut self) {
|
pub fn finalize(&mut self) -> Result<()> {
|
||||||
let mut imports = Imports::new();
|
let mut imports = Imports::new();
|
||||||
|
|
||||||
let env = FunctionEnv::new(
|
let env = FunctionEnv::new(
|
||||||
|
@ -115,12 +122,12 @@ impl WebAssemblyScriptResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let instance = Instance::new(&mut self.store_mut(), module, &imports).unwrap();
|
let instance = Instance::new(&mut self.store_mut(), module, &imports)?;
|
||||||
let exports = &instance.exports;
|
let exports = &instance.exports;
|
||||||
|
|
||||||
let init_fn = exports.get_extern("_init");
|
let init_fn = exports.get_extern("_init");
|
||||||
if let Some(Extern::Function(init_fn)) = init_fn {
|
if let Some(Extern::Function(init_fn)) = init_fn {
|
||||||
init_fn.call(&mut self.store_mut(), &[]).unwrap();
|
init_fn.call(&mut self.store_mut(), &[])?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut exported_functions = self.environment_data.exported_functions.write();
|
let mut exported_functions = self.environment_data.exported_functions.write();
|
||||||
|
@ -136,19 +143,19 @@ impl WebAssemblyScriptResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(m) = &self.environment_data.memory.read().as_ref() {
|
if let Some(m) = &self.environment_data.memory.read().as_ref() {
|
||||||
m.grow(&mut self.store_mut(), 32).unwrap();
|
m.grow(&mut self.store_mut(), 32)?;
|
||||||
}
|
}
|
||||||
if let Some(f) = exported_functions.get::<StringKey>(&"load_script".into()) {
|
if let Some(f) = exported_functions.get::<StringKey>(&"load_script".into()) {
|
||||||
self.load_script_fn = Some(f.typed(&self.store_ref()).unwrap())
|
self.load_script_fn = Some(f.typed(&self.store_ref())?)
|
||||||
}
|
}
|
||||||
if let Some(f) = exported_functions.get::<StringKey>(&"allocate_mem".into()) {
|
if let Some(f) = exported_functions.get::<StringKey>(&"allocate_mem".into()) {
|
||||||
let _ = self
|
let _ = self
|
||||||
.environment_data
|
.environment_data
|
||||||
.allocate_mem_fn
|
.allocate_mem_fn
|
||||||
.write()
|
.write()
|
||||||
.insert(f.typed(&self.store_ref()).unwrap());
|
.insert(f.typed(&self.store_ref())?);
|
||||||
|
|
||||||
let temp_memory_slab = self.environment_data.allocate_mem(128, 1);
|
let temp_memory_slab = self.environment_data.allocate_mem(128, 1)?;
|
||||||
let _ = self
|
let _ = self
|
||||||
.environment_data
|
.environment_data
|
||||||
.temp_allocator
|
.temp_allocator
|
||||||
|
@ -157,6 +164,7 @@ impl WebAssemblyScriptResolver {
|
||||||
}
|
}
|
||||||
self.instances.push(instance);
|
self.instances.push(instance);
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the data passed to every function as environment data.
|
/// Gets the data passed to every function as environment data.
|
||||||
|
@ -289,11 +297,13 @@ impl WebAssemblyEnvironmentData {
|
||||||
|
|
||||||
/// This returns the memory of the WASM container.
|
/// This returns the memory of the WASM container.
|
||||||
pub fn memory(&self) -> *mut u8 {
|
pub fn memory(&self) -> *mut u8 {
|
||||||
|
#[allow(clippy::unwrap_used)] // We know this is valid.
|
||||||
self.memory.read().as_ref().unwrap().view(&self.store_ref()).data_ptr()
|
self.memory.read().as_ref().unwrap().view(&self.store_ref()).data_ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a pointer to something inside the WASM memory.
|
/// Return a pointer to something inside the WASM memory.
|
||||||
pub fn get_raw_pointer<T>(&self, offset: u32) -> *mut T {
|
pub fn get_raw_pointer<T>(&self, offset: u32) -> *mut T {
|
||||||
|
#[allow(clippy::unwrap_used)] // We know this is valid.
|
||||||
unsafe {
|
unsafe {
|
||||||
self.memory
|
self.memory
|
||||||
.read()
|
.read()
|
||||||
|
@ -319,57 +329,55 @@ impl WebAssemblyEnvironmentData {
|
||||||
/// owned by WASM, and is how we can pass memory references that the host allocated to WASM.
|
/// owned by WASM, and is how we can pass memory references that the host allocated to WASM.
|
||||||
/// The return is a tuple containing both the actual pointer to the memory (usable by the host),
|
/// The return is a tuple containing both the actual pointer to the memory (usable by the host),
|
||||||
/// and the WASM offset to the memory (usable by the client).
|
/// and the WASM offset to the memory (usable by the client).
|
||||||
pub fn allocate_mem(&self, size: u32, align: u32) -> (*mut u8, u32) {
|
pub fn allocate_mem(&self, size: u32, align: u32) -> Result<(*mut u8, u32)> {
|
||||||
let wasm_ptr = self
|
let wasm_ptr = self
|
||||||
.allocate_mem_fn
|
.allocate_mem_fn
|
||||||
.read()
|
.read()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.ok_or(anyhow!("allocate_mem_fn not set"))?
|
||||||
.call(&mut self.store_mut(), size, align)
|
.call(&mut self.store_mut(), size, align)?;
|
||||||
.unwrap();
|
unsafe { Ok((self.memory().offset(wasm_ptr as isize), wasm_ptr)) }
|
||||||
unsafe { (self.memory().offset(wasm_ptr as isize), wasm_ptr) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocates memory inside the WASM container with a given size and alignment. This memory is
|
/// Allocates memory inside the WASM container with a given size and alignment. This memory is
|
||||||
/// owned by WASM, and is how we can pass memory references that the host allocated to WASM.
|
/// owned by WASM, and is how we can pass memory references that the host allocated to WASM.
|
||||||
/// The return is a tuple containing both the actual pointer to the memory (usable by the host),
|
/// The return is a tuple containing both the actual pointer to the memory (usable by the host),
|
||||||
/// and the WASM offset to the memory (usable by the client).
|
/// and the WASM offset to the memory (usable by the client).
|
||||||
pub fn allocate_mem_typed<T>(&self) -> (*mut u8, u32) {
|
pub fn allocate_mem_typed<T>(&self) -> Result<(*mut u8, u32)> {
|
||||||
let wasm_ptr = self
|
let wasm_ptr = self
|
||||||
.allocate_mem_fn
|
.allocate_mem_fn
|
||||||
.read()
|
.read()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.ok_or(anyhow!("allocate_mem_fn not set"))?
|
||||||
.call(&mut self.store_mut(), size_of::<T>() as u32, align_of::<T>() as u32)
|
.call(&mut self.store_mut(), size_of::<T>() as u32, align_of::<T>() as u32)?;
|
||||||
.unwrap();
|
unsafe { Ok((self.memory().offset(wasm_ptr as isize), wasm_ptr)) }
|
||||||
unsafe { (self.memory().offset(wasm_ptr as isize), wasm_ptr) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocates a raw array in wasm, and copy the values from a given slice to it. Returns the
|
/// Allocates a raw array in wasm, and copy the values from a given slice to it. Returns the
|
||||||
/// pointer in wasm memory.
|
/// pointer in wasm memory.
|
||||||
pub fn copy_value_vec_to_wasm<T>(&self, v: &[T]) -> u32 {
|
pub fn copy_value_vec_to_wasm<T>(&self, v: &[T]) -> Result<u32> {
|
||||||
let wasm_ptr = self
|
let wasm_ptr = self
|
||||||
.allocate_mem_fn
|
.allocate_mem_fn
|
||||||
.read()
|
.read()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.ok_or(anyhow!("allocate_mem_fn not set"))?
|
||||||
.call(
|
.call(
|
||||||
&mut self.store_mut(),
|
&mut self.store_mut(),
|
||||||
(std::mem::size_of_val(v)) as u32,
|
(std::mem::size_of_val(v)) as u32,
|
||||||
align_of::<T>() as u32,
|
align_of::<T>() as u32,
|
||||||
)
|
)?;
|
||||||
.unwrap();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let raw = self.memory().offset(wasm_ptr as isize) as *mut T;
|
let raw = self.memory().offset(wasm_ptr as isize) as *mut T;
|
||||||
v.as_ptr().copy_to(raw, v.len());
|
v.as_ptr().copy_to(raw, v.len());
|
||||||
}
|
}
|
||||||
wasm_ptr
|
Ok(wasm_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate a piece of memory inside WASM with a very short lifespan. This is mainly used for
|
/// Allocate a piece of memory inside WASM with a very short lifespan. This is mainly used for
|
||||||
/// rapid allocation of script function parameters, where WASM needs to write to a specific
|
/// rapid allocation of script function parameters, where WASM needs to write to a specific
|
||||||
/// pointer.
|
/// pointer.
|
||||||
pub(super) fn allocate_temp<T>(&self, value: T) -> AllocatedObject<T> {
|
pub(super) fn allocate_temp<T>(&self, value: T) -> AllocatedObject<T> {
|
||||||
|
#[allow(clippy::unwrap_used)] // We know this is valid.
|
||||||
self.temp_allocator.read().as_ref().unwrap().alloc::<T>(value)
|
self.temp_allocator.read().as_ref().unwrap().alloc::<T>(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,10 +409,10 @@ impl WebAssemblyEnvironmentData {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an extern ref belonging to a vector we have passed to WASM.
|
/// 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: usize, index: usize) -> usize {
|
pub fn get_extern_vec_ref_extern_ref(&self, extern_vec_ref: usize, index: usize) -> Result<usize> {
|
||||||
let r = self.extern_vec_ref_lookup.read();
|
let r = self.extern_vec_ref_lookup.read();
|
||||||
let v = r.get(&extern_vec_ref).unwrap();
|
let v = r.get(&extern_vec_ref).ok_or(anyhow!("Invalid extern vec ref"))?;
|
||||||
v[index]
|
Ok(*v.get_res(index)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the extern ref index belonging to a specific pointer. If none exists, this will create
|
/// Gets the extern ref index belonging to a specific pointer. If none exists, this will create
|
||||||
|
@ -438,9 +446,9 @@ impl WebAssemblyEnvironmentData {
|
||||||
|
|
||||||
/// Gets a value from the extern ref lookup. This turns an earlier registered index back into
|
/// 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.
|
/// its proper value, validates its type, and returns the value.
|
||||||
pub fn get_extern_ref_value<'a, T: ?Sized>(&self, index: usize) -> &'a dyn Any {
|
pub fn get_extern_ref_value<'a, T: ?Sized>(&self, index: usize) -> Result<&'a dyn Any> {
|
||||||
let read_guard = self.extern_ref_pointers.read();
|
let read_guard = self.extern_ref_pointers.read();
|
||||||
let ptr = read_guard.get(index - 1).unwrap();
|
let ptr = read_guard.get_res(index - 1)?;
|
||||||
if self
|
if self
|
||||||
.extern_ref_type_lookup
|
.extern_ref_type_lookup
|
||||||
.read()
|
.read()
|
||||||
|
@ -449,14 +457,17 @@ impl WebAssemblyEnvironmentData {
|
||||||
is_vec: false,
|
is_vec: false,
|
||||||
})
|
})
|
||||||
.is_none()
|
.is_none()
|
||||||
|
{
|
||||||
|
#[allow(clippy::panic)] // Allow panic here, as this is a security error.
|
||||||
{
|
{
|
||||||
panic!(
|
panic!(
|
||||||
"Extern ref was accessed with wrong type. Requested type {}, but this was not the type the extern ref was stored with.",
|
"Extern ref was accessed with wrong type. Requested type {}, but this was not the type the extern ref was stored with.",
|
||||||
std::any::type_name::<T>()
|
std::any::type_name::<T>()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe { ptr.as_ref().unwrap() }
|
unsafe { Ok(ptr.as_ref().unwrap()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The WASM store.
|
/// The WASM store.
|
||||||
|
|
|
@ -75,6 +75,7 @@ impl<T> AllocatedObject<T> {
|
||||||
|
|
||||||
impl<T> Drop for AllocatedObject<T> {
|
impl<T> Drop for AllocatedObject<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
#[allow(clippy::unwrap_used)] // We know this is valid.
|
||||||
unsafe {
|
unsafe {
|
||||||
self.allocator.as_ref().unwrap().drop::<T>();
|
self.allocator.as_ref().unwrap().drop::<T>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,8 +364,8 @@ fn load_script_resolver(path: &String) -> Box<dyn ScriptResolver> {
|
||||||
let mut reader = BufReader::new(file);
|
let mut reader = BufReader::new(file);
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
reader.read_to_end(&mut buffer).unwrap();
|
reader.read_to_end(&mut buffer).unwrap();
|
||||||
resolver.load_wasm_from_bytes(&buffer);
|
resolver.load_wasm_from_bytes(&buffer).unwrap();
|
||||||
resolver.finalize();
|
resolver.finalize().unwrap();
|
||||||
resolver
|
resolver
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue