Major rework of extern ref system for WASM, fixes most possible panics in WASM handling
All checks were successful
continuous-integration/drone Build is passing
All checks were successful
continuous-integration/drone Build is passing
This commit is contained in:
@@ -5,10 +5,9 @@ use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||
get_value, get_value_arc, get_value_call_getter, try_wasm,
|
||||
};
|
||||
use crate::script_implementations::wasm::export_registry::{register, wasm_ok, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::StringKey;
|
||||
use anyhow_ext::Context;
|
||||
use wasmer::FunctionEnvMut;
|
||||
|
||||
register! {
|
||||
@@ -23,19 +22,27 @@ register! {
|
||||
fn battle_get_parties(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
battle: ExternRef<Battle>,
|
||||
) -> WasmResult<VecExternRef<BattleParty>> {
|
||||
let parties = get_value_call_getter!(battle.parties(), env);
|
||||
wasm_ok(VecExternRef::new(env.data().data().as_ref(), parties))
|
||||
) -> WasmResult<u64> {
|
||||
let battle = get_value!(battle, env);
|
||||
let parties = battle.parties();
|
||||
let mut vec : Vec<u32> = Vec::with_capacity(parties.len());
|
||||
for party in parties {
|
||||
vec.push(ExternRef::<BattleParty>::func_new(&env, party.into()).index() as u32);
|
||||
}
|
||||
let wasm_ptr = try_wasm!(env.data().data().copy_value_vec_to_wasm(&vec), env);
|
||||
let r: u64 = unsafe { std::mem::transmute((wasm_ptr, vec.len() as u32)) };
|
||||
wasm_ok(r)
|
||||
}
|
||||
|
||||
fn battle_get_choice_queue(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
battle: ExternRef<Battle>,
|
||||
) -> WasmResult<ExternRef<ChoiceQueue>> {
|
||||
let value = get_value_call_getter!(battle.current_turn_queue(), env);
|
||||
let battle = get_value!(battle, env);
|
||||
let value = battle.current_turn_queue();
|
||||
let queue = value.read();
|
||||
wasm_ok(if let Some(queue) = queue.as_ref() {
|
||||
ExternRef::<ChoiceQueue>::func_new(&env, queue)
|
||||
ExternRef::<ChoiceQueue>::func_new(&env, queue.into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
})
|
||||
@@ -45,24 +52,34 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
battle: ExternRef<Battle>,
|
||||
) -> WasmResult<ExternRef<dyn DynamicLibrary>> {
|
||||
let value = get_value_call_getter!(battle.library(), env);
|
||||
wasm_ok(ExternRef::<dyn DynamicLibrary>::func_new(&env, &value.clone()))
|
||||
let battle = get_value!(battle, env);
|
||||
let value = battle.library();
|
||||
wasm_ok(ExternRef::func_new(&env, value.into()))
|
||||
}
|
||||
|
||||
fn battle_get_sides(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
battle: ExternRef<Battle>,
|
||||
) -> WasmResult<VecExternRef<BattleSide>> {
|
||||
let value = get_value_arc!(battle, env);
|
||||
wasm_ok(VecExternRef::new(env.data().data().as_ref(), value.sides()))
|
||||
) -> WasmResult<u64> {
|
||||
let value = get_value!(battle, env);
|
||||
let sides = value.sides();
|
||||
let mut vec : Vec<u32> = Vec::with_capacity(sides.len());
|
||||
for side in sides {
|
||||
vec.push(ExternRef::<BattleSide>::func_new(&env, side.into()).index() as u32);
|
||||
}
|
||||
let wasm_ptr = try_wasm!(env.data().data().copy_value_vec_to_wasm(&vec), env);
|
||||
let r: u64 = unsafe { std::mem::transmute((wasm_ptr, vec.len() as u32)) };
|
||||
wasm_ok(r)
|
||||
|
||||
}
|
||||
|
||||
fn battle_get_random(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
battle: ExternRef<Battle>,
|
||||
) -> WasmResult<ExternRef<BattleRandom>> {
|
||||
let random = get_value_call_getter!(battle.random(), env);
|
||||
wasm_ok(ExternRef::<BattleRandom>::func_new(&env, random))
|
||||
let battle = get_value!(battle, env);
|
||||
let random = battle.random();
|
||||
wasm_ok(ExternRef::<BattleRandom>::func_new(&env, random.into()))
|
||||
}
|
||||
|
||||
fn battle_get_weather_name(
|
||||
@@ -72,7 +89,7 @@ register! {
|
||||
let weather = get_value_call_getter!(battle.weather_name(), env);
|
||||
let weather = try_wasm!(weather, env);
|
||||
wasm_ok(if let Some(weather) = weather {
|
||||
ExternRef::<StringKey>::func_new(&env, &weather)
|
||||
ExternRef::<StringKey>::func_new(&env, weather.into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
})
|
||||
@@ -86,8 +103,8 @@ register! {
|
||||
let battle = get_value!(battle, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
for party in battle.parties() {
|
||||
if party.party().has_pokemon(pokemon) {
|
||||
return wasm_ok(ExternRef::<BattleParty>::func_new(&env, party));
|
||||
if party.party().has_pokemon(&pokemon) {
|
||||
return wasm_ok(ExternRef::<BattleParty>::func_new(&env, party.into()));
|
||||
}
|
||||
}
|
||||
wasm_ok(ExternRef::<BattleParty>::null())
|
||||
@@ -101,7 +118,7 @@ register! {
|
||||
let battle = get_value!(battle, env);
|
||||
let pokemon = battle.get_pokemon(side, index);
|
||||
wasm_ok(if let Some(pokemon) = pokemon {
|
||||
ExternRef::<Pokemon>::func_new(&env, &pokemon)
|
||||
ExternRef::<Pokemon>::func_new(&env, (&pokemon).into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
})
|
||||
@@ -159,7 +176,7 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
battle_party: ExternRef<BattleParty>,
|
||||
) -> WasmResult<ExternRef<PokemonParty>> {
|
||||
let value = get_value_call_getter!(battle_party.party(), env);
|
||||
wasm_ok(ExternRef::<PokemonParty>::func_new(&env, value.as_ref()))
|
||||
let battle_party = get_value_arc!(battle_party, env);
|
||||
wasm_ok(ExternRef::<PokemonParty>::func_new(&env, battle_party.party().into()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
use crate::dynamic_data::BattleRandom;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||
get_value, get_value_call_getter, try_wasm, wasm_ok,
|
||||
};
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{get_value_arc, try_wasm, wasm_ok};
|
||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use wasmer::FunctionEnvMut;
|
||||
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use anyhow_ext::Context;
|
||||
|
||||
register! {
|
||||
fn battle_random_get(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
battle_random: ExternRef<BattleRandom>,
|
||||
) -> WasmResult<i32> {
|
||||
let v = get_value_call_getter!(battle_random.get(), env);
|
||||
let v = try_wasm!(v, env);
|
||||
let v = get_value_arc!(battle_random, env);
|
||||
let v = try_wasm!(v.get(), env);
|
||||
wasm_ok(v)
|
||||
}
|
||||
fn battle_random_get_max(
|
||||
@@ -23,7 +20,7 @@ register! {
|
||||
battle_random: ExternRef<BattleRandom>,
|
||||
max: i32
|
||||
) -> WasmResult<i32> {
|
||||
let battle_random = get_value!(battle_random, env);
|
||||
let battle_random = get_value_arc!(battle_random, env);
|
||||
let v = try_wasm!(battle_random.get_max(max), env);
|
||||
wasm_ok(v)
|
||||
}
|
||||
@@ -33,7 +30,7 @@ register! {
|
||||
min: i32,
|
||||
max: i32
|
||||
) -> WasmResult<i32> {
|
||||
let battle_random = get_value!(battle_random, env);
|
||||
let battle_random = get_value_arc!(battle_random, env);
|
||||
let v = try_wasm!(battle_random.get_between(min, max), env);
|
||||
wasm_ok(v)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use anyhow::anyhow;
|
||||
use anyhow_ext::Context;
|
||||
use std::ffi::CStr;
|
||||
use wasmer::FunctionEnvMut;
|
||||
|
||||
@@ -46,7 +45,7 @@ register! {
|
||||
) -> WasmResult<ExternRef<Battle>> {
|
||||
let value = get_value_call_getter!(side.battle(), env);
|
||||
let value = try_wasm!(value, env);
|
||||
wasm_ok(ExternRef::func_new(&env, &value))
|
||||
wasm_ok(ExternRef::func_new(&env, (&value).into()))
|
||||
}
|
||||
|
||||
fn battleside_get_pokemon(
|
||||
@@ -55,11 +54,11 @@ register! {
|
||||
index: u32
|
||||
) -> WasmResult<ExternRef<Pokemon>> {
|
||||
let side = get_value!(side, env);
|
||||
wasm_ok(if let Some(Some(p)) = side.pokemon().get(index as usize) {
|
||||
ExternRef::<Pokemon>::func_new(&env, p.as_ref())
|
||||
let x = wasm_ok(if let Some(Some(p)) = side.pokemon().get(index as usize) {
|
||||
ExternRef::<Pokemon>::func_new(&env, p.into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
})
|
||||
}); x
|
||||
}
|
||||
|
||||
fn battle_side_get_has_fled_battle(
|
||||
@@ -99,13 +98,13 @@ register! {
|
||||
side: ExternRef<BattleSide>,
|
||||
script_ptr: u32
|
||||
) -> WasmResult<u32> {
|
||||
let side : &BattleSide = get_value!(side, env);
|
||||
let side = get_value!(side, env);
|
||||
unsafe {
|
||||
let e = env.data().data();
|
||||
let name_func = try_wasm!(e.script_function_cache().script_get_name(&e), env);
|
||||
let name_ptr = try_wasm!(name_func.call(&mut e.store_mut(), script_ptr), env);
|
||||
let c_name: &CStr = CStr::from_ptr(e.get_raw_pointer(name_ptr));
|
||||
let script = try_wasm!(e.setup_script(script_ptr, ScriptCategory::Side, &c_name.as_ref().into(), side.into()), env);
|
||||
let script = try_wasm!(e.setup_script(script_ptr, ScriptCategory::Side, &c_name.as_ref().into(), (&side).into()), env);
|
||||
try_wasm!(e.script_function_cache().dealloc_cstring(&e, name_ptr), env);
|
||||
|
||||
if let Some(script) = script {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::dynamic_data::{ChoiceQueue, Pokemon};
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::get_value_arc;
|
||||
use crate::script_implementations::wasm::export_registry::{get_value, register, try_wasm, wasm_ok, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use anyhow_ext::Context;
|
||||
use wasmer::FunctionEnvMut;
|
||||
|
||||
register! {
|
||||
@@ -11,9 +11,9 @@ register! {
|
||||
battle_random: ExternRef<ChoiceQueue>,
|
||||
pokemon: ExternRef<Pokemon>
|
||||
) -> WasmResult<u8> {
|
||||
let battle_random = get_value!(battle_random, env);
|
||||
let battle_random = get_value_arc!(battle_random, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let res = try_wasm!(battle_random.move_pokemon_choice_next(pokemon), env);
|
||||
let res = try_wasm!(battle_random.move_pokemon_choice_next(&pokemon), env);
|
||||
wasm_ok(u8::from(res))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
use crate::dynamic_data::{ExecutingMove, HitData, LearnedMove, Pokemon};
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::get_value_arc;
|
||||
use crate::script_implementations::wasm::export_registry::{
|
||||
get_value, get_value_call_getter, register, try_wasm, wasm_ok, WasmResult,
|
||||
};
|
||||
use crate::script_implementations::wasm::export_registry::{get_value, register, try_wasm, wasm_ok, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::static_data::MoveData;
|
||||
use anyhow_ext::Context;
|
||||
use wasmer::FunctionEnvMut;
|
||||
|
||||
register! {
|
||||
@@ -15,31 +12,32 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
executing_move: ExternRef<ExecutingMove>,
|
||||
) -> WasmResult<ExternRef<Pokemon>> {
|
||||
let user = get_value_call_getter!(executing_move.user(), env);
|
||||
wasm_ok(ExternRef::<Pokemon>::func_new(&env, user.as_ref()))
|
||||
let executing_move = get_value_arc!(executing_move, env);
|
||||
wasm_ok(ExternRef::<Pokemon>::func_new(&env, executing_move.user().into()))
|
||||
}
|
||||
|
||||
fn executing_move_get_use_move(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
executing_move: ExternRef<ExecutingMove>,
|
||||
) -> WasmResult<ExternRef<dyn MoveData>> {
|
||||
let use_move = get_value_call_getter!(executing_move.use_move(), env);
|
||||
wasm_ok(ExternRef::<dyn MoveData>::func_new(&env, use_move))
|
||||
let executing_move = get_value_arc!(executing_move, env);
|
||||
wasm_ok(ExternRef::<dyn MoveData>::func_new(&env, executing_move.use_move().into()))
|
||||
}
|
||||
|
||||
fn executing_move_get_chosen_move(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
executing_move: ExternRef<ExecutingMove>,
|
||||
) -> WasmResult<ExternRef<LearnedMove>> {
|
||||
let chosen_move = get_value_call_getter!(executing_move.chosen_move(), env);
|
||||
wasm_ok(ExternRef::<LearnedMove>::func_new(&env, chosen_move.as_ref()))
|
||||
let executing_move = get_value_arc!(executing_move, env);
|
||||
wasm_ok(ExternRef::<LearnedMove>::func_new(&env, executing_move.chosen_move().into()))
|
||||
}
|
||||
|
||||
fn executing_move_get_number_of_hits(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
executing_move: ExternRef<ExecutingMove>,
|
||||
) -> WasmResult<u8> {
|
||||
wasm_ok(get_value_call_getter!(executing_move.number_of_hits(), env))
|
||||
let executing_move = get_value_arc!(executing_move, env);
|
||||
wasm_ok(executing_move.number_of_hits())
|
||||
}
|
||||
|
||||
fn executing_move_get_hit_data(
|
||||
@@ -48,17 +46,18 @@ register! {
|
||||
target: ExternRef<Pokemon>,
|
||||
hit: u8
|
||||
) -> WasmResult<ExternRef<HitData>> {
|
||||
let executing_move = get_value!(executing_move, env);
|
||||
let target = get_value_arc!(target, env);
|
||||
let executing_move = get_value_arc!(executing_move, env);
|
||||
let target = get_value!(target, env);
|
||||
let hit_data = try_wasm!(executing_move.get_hit_data(&target, hit), env);
|
||||
wasm_ok(ExternRef::<HitData>::func_new(&env, hit_data))
|
||||
wasm_ok(ExternRef::<HitData>::func_new(&env, hit_data.into()))
|
||||
}
|
||||
|
||||
fn executing_move_get_number_of_targets(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
executing_move: ExternRef<ExecutingMove>,
|
||||
) -> WasmResult<u32> {
|
||||
wasm_ok(get_value_call_getter!(executing_move.target_count(), env) as u32)
|
||||
let executing_move = get_value_arc!(executing_move, env);
|
||||
wasm_ok(executing_move.target_count() as u32)
|
||||
}
|
||||
|
||||
fn executing_move_is_pokemon_target(
|
||||
@@ -66,8 +65,8 @@ register! {
|
||||
executing_move: ExternRef<ExecutingMove>,
|
||||
pokemon: ExternRef<Pokemon>
|
||||
) -> WasmResult<u8> {
|
||||
let executing_move = get_value!(executing_move, env);
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let executing_move = get_value_arc!(executing_move, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
wasm_ok(if executing_move.is_pokemon_target(&pokemon) { 1 } else { 0 })
|
||||
}
|
||||
|
||||
@@ -77,7 +76,7 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
executing_move: ExternRef<ExecutingMove>,
|
||||
) -> WasmResult<u32> {
|
||||
let executing_move = get_value!(executing_move, env);
|
||||
let executing_move = get_value_arc!(executing_move, env);
|
||||
let script = executing_move.script();
|
||||
if script.is_any() {
|
||||
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use crate::dynamic_data::HitData;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||
get_value_call_getter, get_value_void, wasm_ok, WasmVoidResultExtension,
|
||||
get_value_arc, get_value_arc_void, wasm_ok, WasmVoidResultExtension,
|
||||
};
|
||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult, WasmVoidResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use anyhow_ext::Context;
|
||||
use wasmer::FunctionEnvMut;
|
||||
|
||||
register! {
|
||||
@@ -13,22 +12,23 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
hit: ExternRef<HitData>,
|
||||
) -> WasmResult<u32> {
|
||||
wasm_ok(get_value_call_getter!(hit.damage(), env))
|
||||
let hit = get_value_arc!(hit, env);
|
||||
wasm_ok(hit.damage())
|
||||
}
|
||||
|
||||
fn hit_data_is_critical(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
hit: ExternRef<HitData>,
|
||||
) -> WasmResult<u8> {
|
||||
let is_critical = get_value_call_getter!(hit.is_critical(), env);
|
||||
wasm_ok(u8::from(is_critical))
|
||||
let hit = get_value_arc!(hit, env);
|
||||
wasm_ok(u8::from(hit.is_critical()))
|
||||
}
|
||||
|
||||
fn hit_data_fail(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
hit: ExternRef<HitData>,
|
||||
) -> WasmVoidResult {
|
||||
let hit = get_value_void!(hit, env);
|
||||
let hit = get_value_arc_void!(hit, env);
|
||||
hit.fail();
|
||||
WasmVoidResult::ok()
|
||||
}
|
||||
@@ -37,21 +37,24 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
hit: ExternRef<HitData>,
|
||||
) -> WasmResult<u8> {
|
||||
wasm_ok(get_value_call_getter!(hit.base_power(), env))
|
||||
let hit = get_value_arc!(hit, env);
|
||||
wasm_ok(hit.base_power())
|
||||
}
|
||||
|
||||
fn hit_data_get_effectiveness(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
hit: ExternRef<HitData>,
|
||||
) -> WasmResult<f32> {
|
||||
wasm_ok(get_value_call_getter!(hit.effectiveness(), env))
|
||||
let hit = get_value_arc!(hit, env);
|
||||
wasm_ok(hit.effectiveness())
|
||||
}
|
||||
|
||||
fn hit_data_get_move_type(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
hit: ExternRef<HitData>,
|
||||
) -> WasmResult<u8> {
|
||||
wasm_ok(get_value_call_getter!(hit.move_type(), env).into())
|
||||
let hit = get_value_arc!(hit, env);
|
||||
wasm_ok(hit.move_type().into())
|
||||
}
|
||||
|
||||
fn hit_data_set_critical(
|
||||
@@ -59,7 +62,7 @@ register! {
|
||||
hit: ExternRef<HitData>,
|
||||
value: u8
|
||||
) -> WasmVoidResult {
|
||||
let hit = get_value_void!(hit, env);
|
||||
let hit = get_value_arc_void!(hit, env);
|
||||
hit.set_critical(value == 1);
|
||||
WasmVoidResult::ok()
|
||||
}
|
||||
@@ -69,7 +72,7 @@ register! {
|
||||
hit: ExternRef<HitData>,
|
||||
effectiveness: f32
|
||||
) -> WasmVoidResult {
|
||||
let hit = get_value_void!(hit, env);
|
||||
let hit = get_value_arc_void!(hit, env);
|
||||
hit.set_effectiveness(effectiveness);
|
||||
WasmVoidResult::ok()
|
||||
}
|
||||
@@ -79,7 +82,7 @@ register! {
|
||||
hit: ExternRef<HitData>,
|
||||
damage: u32
|
||||
) -> WasmVoidResult {
|
||||
let hit = get_value_void!(hit, env);
|
||||
let hit = get_value_arc_void!(hit, env);
|
||||
hit.set_damage(damage);
|
||||
WasmVoidResult::ok()
|
||||
}
|
||||
@@ -89,7 +92,7 @@ register! {
|
||||
hit: ExternRef<HitData>,
|
||||
move_type: u8
|
||||
) -> WasmVoidResult {
|
||||
let hit = get_value_void!(hit, env);
|
||||
let hit = get_value_arc_void!(hit, env);
|
||||
hit.set_move_type(move_type.into());
|
||||
WasmVoidResult::ok()
|
||||
}
|
||||
|
||||
@@ -2,13 +2,12 @@ use std::intrinsics::transmute;
|
||||
|
||||
use crate::dynamic_data::{LearnedMove, MoveLearnMethod};
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||
get_value_call_getter, get_value_void, wasm_ok, WasmVoidResult, WasmVoidResultExtension,
|
||||
get_value_arc, get_value_arc_void, wasm_ok, WasmVoidResult, WasmVoidResultExtension,
|
||||
};
|
||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::static_data::MoveData;
|
||||
use anyhow_ext::Context;
|
||||
use wasmer::FunctionEnvMut;
|
||||
|
||||
register! {
|
||||
@@ -17,8 +16,8 @@ register! {
|
||||
turn_choice: ExternRef<LearnedMove>,
|
||||
) -> WasmResult<u8> {
|
||||
unsafe {
|
||||
let learn_method = get_value_call_getter!(turn_choice.learn_method(), &env);
|
||||
wasm_ok(transmute::<MoveLearnMethod, u8>(learn_method))
|
||||
let learned_move = get_value_arc!(turn_choice, env);
|
||||
wasm_ok(transmute::<MoveLearnMethod, u8>(learned_move.learn_method()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,15 +25,15 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
turn_choice: ExternRef<LearnedMove>,
|
||||
) -> WasmResult<ExternRef<dyn MoveData>> {
|
||||
let move_data = get_value_call_getter!(turn_choice.move_data(), &env);
|
||||
wasm_ok(ExternRef::<dyn MoveData>::func_new(&env, move_data))
|
||||
let turn_choice = get_value_arc!(turn_choice, env);
|
||||
wasm_ok(ExternRef::func_new(&env, turn_choice.move_data().into()))
|
||||
}
|
||||
|
||||
fn learned_move_restore_all_uses(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
turn_choice: ExternRef<LearnedMove>,
|
||||
) -> WasmVoidResult {
|
||||
let turn_choice = get_value_void!(turn_choice, env);
|
||||
let turn_choice = get_value_arc_void!(turn_choice, env);
|
||||
turn_choice.restore_all_uses();
|
||||
WasmVoidResult::ok()
|
||||
}
|
||||
@@ -44,7 +43,7 @@ register! {
|
||||
turn_choice: ExternRef<LearnedMove>,
|
||||
amount: u8,
|
||||
) -> WasmVoidResult {
|
||||
let turn_choice = get_value_void!(turn_choice, env);
|
||||
let turn_choice = get_value_arc_void!(turn_choice, env);
|
||||
turn_choice.restore_uses(amount);
|
||||
WasmVoidResult::ok()
|
||||
}
|
||||
|
||||
@@ -2,12 +2,10 @@ use crate::dynamic_data::{DynamicLibrary, ScriptOwnerData};
|
||||
use crate::script_implementations::wasm::export_registry::register;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{try_wasm, wasm_ok, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use std::sync::atomic::Ordering;
|
||||
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
||||
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::static_data::StaticData;
|
||||
use anyhow_ext::Context;
|
||||
|
||||
/// The battle registration
|
||||
mod battle;
|
||||
@@ -37,25 +35,23 @@ register! {
|
||||
) -> WasmResult<ExternRef<dyn StaticData>> {
|
||||
let dynamic_lib = try_wasm!(dynamic_lib.value_func_arc(&env), env);
|
||||
let static_data = dynamic_lib.static_data();
|
||||
wasm_ok(ExternRef::<dyn StaticData>::func_new(&env, static_data))
|
||||
wasm_ok(ExternRef::<dyn StaticData>::func_new(&env, static_data.into()))
|
||||
}
|
||||
|
||||
fn script_get_owner(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
script: u32,
|
||||
) -> u32 {
|
||||
unsafe {
|
||||
let script = env.data().data().get_loaded_script(script);
|
||||
if let Some(script) = script {
|
||||
match script.get_owner() {
|
||||
ScriptOwnerData::Pokemon(p) => env.data().data().get_extern_ref_index::<crate::dynamic_data::Pokemon>(p.load(Ordering::Relaxed).as_ref().unwrap()) as u32,
|
||||
ScriptOwnerData::BattleSide(p) => env.data().data().get_extern_ref_index::<crate::dynamic_data::BattleSide>(p.load(Ordering::Relaxed).as_ref().unwrap()) as u32,
|
||||
ScriptOwnerData::Battle(p) => env.data().data().get_extern_ref_index::<crate::dynamic_data::Battle>(p.load(Ordering::Relaxed).as_ref().unwrap()) as u32,
|
||||
ScriptOwnerData::None => 0,
|
||||
}
|
||||
} else {
|
||||
0
|
||||
let script = env.data().data().get_loaded_script(script);
|
||||
if let Some(script) = script {
|
||||
match script.get_owner() {
|
||||
ScriptOwnerData::Pokemon(p) => env.data().data().get_extern_ref_index(p.into()) as u32,
|
||||
ScriptOwnerData::BattleSide(p) => env.data().data().get_extern_ref_index(p.into()) as u32,
|
||||
ScriptOwnerData::Battle(p) => env.data().data().get_extern_ref_index(p.into()) as u32,
|
||||
ScriptOwnerData::None => 0,
|
||||
}
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use crate::dynamic_data::{Pokemon, PokemonParty};
|
||||
use crate::script_implementations::wasm::export_registry::register;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{get_value, wasm_ok, WasmResult};
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{get_value_arc, wasm_ok, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use anyhow_ext::Context;
|
||||
use wasmer::FunctionEnvMut;
|
||||
|
||||
register! {
|
||||
@@ -12,20 +11,20 @@ register! {
|
||||
party: ExternRef<PokemonParty>,
|
||||
index: u32
|
||||
) -> WasmResult<ExternRef<Pokemon>> {
|
||||
let party = get_value!(party, env);
|
||||
wasm_ok(
|
||||
let party = get_value_arc!(party, env);
|
||||
let x = wasm_ok(
|
||||
if let Some(Some(v)) = &party.pokemon().get(index as usize) {
|
||||
ExternRef::func_new(&env, v.as_ref())
|
||||
ExternRef::func_new(&env, v.into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
})
|
||||
}); x
|
||||
}
|
||||
|
||||
fn party_get_length(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
party: ExternRef<PokemonParty>,
|
||||
) -> WasmResult<u32> {
|
||||
let party = get_value!(party, env);
|
||||
let party = get_value_arc!(party, env);
|
||||
wasm_ok(party.length() as u32)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ use std::mem::transmute;
|
||||
use crate::defines::LevelInt;
|
||||
use crate::dynamic_data::{Battle, DynamicLibrary, LearnedMove, Pokemon, VolatileScriptsOwner};
|
||||
use crate::script_implementations::wasm::export_registry::{
|
||||
get_value_arc, get_value_arc_void, get_value_call_getter, get_value_void, register, try_wasm, wasm_err, wasm_ok,
|
||||
WasmResult, WasmVoidResult, WasmVoidResultExtension,
|
||||
get_value, get_value_arc, get_value_arc_void, get_value_call_getter, get_value_void, register, try_wasm, wasm_err,
|
||||
wasm_ok, WasmResult, WasmVoidResult, WasmVoidResultExtension,
|
||||
};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||
@@ -13,7 +13,6 @@ use crate::static_data::{Ability, ClampedStatisticSet, Form, Nature, Species};
|
||||
use crate::static_data::{Item, StatisticSet};
|
||||
use crate::{ScriptCategory, VecExt};
|
||||
use anyhow::anyhow;
|
||||
use anyhow_ext::Context;
|
||||
use std::ffi::{c_char, CStr, CString};
|
||||
use wasmer::FunctionEnvMut;
|
||||
|
||||
@@ -22,56 +21,62 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<dyn DynamicLibrary>> {
|
||||
let lib = get_value_call_getter!(pokemon.library(), env).clone();
|
||||
wasm_ok(ExternRef::<dyn DynamicLibrary>::func_new(&env, &lib))
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let lib = pokemon.library();
|
||||
wasm_ok(ExternRef::<dyn DynamicLibrary>::func_new(&env, lib.into()))
|
||||
}
|
||||
|
||||
fn pokemon_get_boosted_stats(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<StatisticSet<u32>>> {
|
||||
let statistic_set = get_value_call_getter!(pokemon.boosted_stats(), env).clone();
|
||||
wasm_ok(ExternRef::<StatisticSet<u32>>::func_new(&env, statistic_set))
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let statistic_set = pokemon.boosted_stats();
|
||||
wasm_ok(ExternRef::<StatisticSet<u32>>::func_new(&env, statistic_set.into()))
|
||||
}
|
||||
|
||||
fn pokemon_get_flat_stats(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<StatisticSet<u32>>> {
|
||||
let statistic_set = get_value_call_getter!(pokemon.flat_stats(), env).clone();
|
||||
wasm_ok(ExternRef::<StatisticSet<u32>>::func_new(&env, statistic_set))
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let statistic_set = pokemon.flat_stats();
|
||||
wasm_ok(ExternRef::<StatisticSet<u32>>::func_new(&env, statistic_set.into()))
|
||||
}
|
||||
|
||||
fn pokemon_get_stat_boosts(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<ClampedStatisticSet<i8, -6, 6>>> {
|
||||
let statistic_set = get_value_call_getter!(pokemon.stat_boosts(), env).clone();
|
||||
wasm_ok(ExternRef::<ClampedStatisticSet<i8, -6, 6>>::func_new(&env, statistic_set))
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let statistic_set = pokemon.stat_boosts();
|
||||
wasm_ok(ExternRef::<ClampedStatisticSet<i8, -6, 6>>::func_new(&env, statistic_set.into()))
|
||||
}
|
||||
|
||||
fn pokemon_get_individual_values(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<ClampedStatisticSet<u8, 0, 31>>> {
|
||||
let statistic_set = get_value_call_getter!(pokemon.individual_values(), env).clone();
|
||||
wasm_ok(ExternRef::<ClampedStatisticSet<u8, 0, 31>>::func_new(&env, statistic_set))
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let statistic_set = pokemon.individual_values();
|
||||
wasm_ok(ExternRef::<ClampedStatisticSet<u8, 0, 31>>::func_new(&env, statistic_set.into()))
|
||||
}
|
||||
|
||||
fn pokemon_get_effort_values(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<ClampedStatisticSet<u8, 0, 252>>> {
|
||||
let statistic_set = get_value_call_getter!(pokemon.effort_values(), env).clone();
|
||||
wasm_ok(ExternRef::<ClampedStatisticSet<u8, 0, 252>>::func_new(&env, statistic_set))
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let statistic_set = pokemon.effort_values();
|
||||
wasm_ok(ExternRef::<ClampedStatisticSet<u8, 0, 252>>::func_new(&env, statistic_set.into()))
|
||||
}
|
||||
|
||||
fn pokemon_get_species(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<dyn Species>> {
|
||||
let species = get_value_call_getter!(pokemon.species(), env).clone();
|
||||
wasm_ok(ExternRef::<dyn Species>::func_new(&env, &species))
|
||||
let species = get_value_call_getter!(pokemon.species(), env);
|
||||
wasm_ok(ExternRef::<dyn Species>::func_new(&env, (&species).into()))
|
||||
}
|
||||
|
||||
fn pokemon_get_weight(
|
||||
@@ -134,11 +139,11 @@ register! {
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
index: u32
|
||||
) -> WasmResult<ExternRef<LearnedMove>> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let read_lock = pokemon.learned_moves().read();
|
||||
let mv = read_lock.get(index as usize);
|
||||
wasm_ok(if let Some(Some(mv)) = mv {
|
||||
ExternRef::<LearnedMove>::func_new(&env, mv)
|
||||
ExternRef::<LearnedMove>::func_new(&env, mv.into())
|
||||
}
|
||||
else{
|
||||
ExternRef::<LearnedMove>::null()
|
||||
@@ -153,7 +158,7 @@ register! {
|
||||
self_inflicted: u8
|
||||
) -> WasmResult<u8> {
|
||||
unsafe{
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let res = try_wasm!(pokemon.change_stat_boost(transmute(stat), amount, self_inflicted == 1), env);
|
||||
wasm_ok(u8::from(res))
|
||||
}
|
||||
@@ -163,11 +168,9 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<Battle>> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
wasm_ok(if let Some(battle) = pokemon.get_battle() {
|
||||
let r = ExternRef::func_new(&env, &battle);
|
||||
std::mem::forget(battle);
|
||||
r
|
||||
ExternRef::func_new(&env, (&battle).into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
})
|
||||
@@ -177,7 +180,7 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<u8> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
wasm_ok(if let Some(i) = pokemon.get_battle_index() {
|
||||
i
|
||||
} else {
|
||||
@@ -189,7 +192,7 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<u8> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
wasm_ok(if let Some(i) = pokemon.get_battle_side_index() {
|
||||
i
|
||||
} else {
|
||||
@@ -201,10 +204,10 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<dyn Item>> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let read_lock = pokemon.held_item().read();
|
||||
wasm_ok(if let Some(item) = read_lock.as_ref() {
|
||||
ExternRef::<dyn Item>::func_new(&env, item.as_ref())
|
||||
ExternRef::<dyn Item>::func_new(&env, item.into())
|
||||
} else {
|
||||
ExternRef::<dyn Item>::null()
|
||||
})
|
||||
@@ -217,7 +220,7 @@ register! {
|
||||
) -> WasmResult<u8> {
|
||||
let name : *mut c_char = env.data().data().get_raw_pointer(name);
|
||||
let name = unsafe { CStr::from_ptr(name) };
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
wasm_ok(u8::from(pokemon.has_held_item(&name.into())))
|
||||
}
|
||||
|
||||
@@ -227,7 +230,7 @@ register! {
|
||||
amount: u32,
|
||||
allow_revive: u8
|
||||
) -> WasmResult<u8> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
wasm_ok(u8::from(pokemon.heal(amount, allow_revive == 1)))
|
||||
}
|
||||
|
||||
@@ -248,14 +251,16 @@ register! {
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<dyn Ability>> {
|
||||
let active_ability = get_value_call_getter!(pokemon.active_ability(), env);
|
||||
wasm_ok(ExternRef::<dyn Ability>::func_new(&env, &active_ability))
|
||||
let active_ability = try_wasm!(active_ability, env);
|
||||
wasm_ok(ExternRef::<dyn Ability>::func_new(&env, (&active_ability).into()))
|
||||
}
|
||||
|
||||
fn pokemon_get_real_ability(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<u16> {
|
||||
let index = get_value_call_getter!(pokemon.real_ability(), env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let index = pokemon.real_ability();
|
||||
let t: (u8, u8) = (if index.hidden { 1 } else { 0 }, index.index);
|
||||
let r: u16 = unsafe { transmute(t) };
|
||||
wasm_ok(r)
|
||||
@@ -265,7 +270,7 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<u8> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
wasm_ok(if pokemon.is_ability_overriden() { 1 } else { 0 })
|
||||
}
|
||||
|
||||
@@ -273,7 +278,7 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<u8> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
wasm_ok(if pokemon.allowed_experience_gain() { 1 } else { 0 })
|
||||
}
|
||||
|
||||
@@ -281,7 +286,7 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<u8> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
wasm_ok(if pokemon.is_usable() { 1 } else { 0 })
|
||||
}
|
||||
|
||||
@@ -292,10 +297,10 @@ register! {
|
||||
item: ExternRef<dyn Item>
|
||||
) -> WasmResult<ExternRef<dyn Item>> {
|
||||
let item = get_value_arc!(item, env);
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let old_item = pokemon.set_held_item(&item);
|
||||
wasm_ok(if let Some(old_item) = old_item {
|
||||
ExternRef::<dyn Item>::func_new(&env, &old_item)
|
||||
ExternRef::<dyn Item>::func_new(&env, (&old_item).into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
})
|
||||
@@ -305,10 +310,10 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<dyn Item>> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let old_item = pokemon.remove_held_item();
|
||||
wasm_ok(if let Some(old_item) = old_item {
|
||||
ExternRef::<dyn Item>::func_new(&env, &old_item)
|
||||
ExternRef::<dyn Item>::func_new(&env, (&old_item).into())
|
||||
} else {
|
||||
ExternRef::<dyn Item>::null()
|
||||
})
|
||||
@@ -318,7 +323,7 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<u8> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let res = try_wasm!(pokemon.consume_held_item(), env);
|
||||
wasm_ok(if res { 1 } else { 0 })
|
||||
}
|
||||
@@ -327,7 +332,7 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>
|
||||
) -> WasmResult<u32> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let len = pokemon.types().len();
|
||||
wasm_ok(len as u32)
|
||||
}
|
||||
@@ -337,7 +342,7 @@ register! {
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
index: u32
|
||||
) -> WasmResult<u8> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let types = pokemon.types();
|
||||
let type_v = types.get_res(index as usize);
|
||||
match type_v {
|
||||
@@ -351,7 +356,7 @@ register! {
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
t: u8
|
||||
) -> WasmResult<u8> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
wasm_ok(if pokemon.types().contains(&t.into()) { 1 } else { 0 })
|
||||
}
|
||||
|
||||
@@ -398,8 +403,9 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<dyn Nature>> {
|
||||
let nature = get_value_call_getter!(pokemon.nature(), env);
|
||||
wasm_ok(ExternRef::<dyn Nature>::func_new(&env, nature))
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let nature = pokemon.nature();
|
||||
wasm_ok(ExternRef::<dyn Nature>::func_new(&env, nature.into()))
|
||||
}
|
||||
|
||||
fn pokemon_get_form(
|
||||
@@ -407,7 +413,7 @@ register! {
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<dyn Form>> {
|
||||
let form = get_value_call_getter!(pokemon.form(), env);
|
||||
wasm_ok(ExternRef::<dyn Form>::func_new(&env, &form))
|
||||
wasm_ok(ExternRef::<dyn Form>::func_new(&env, (&form).into()))
|
||||
}
|
||||
|
||||
fn pokemon_get_display_species(
|
||||
@@ -415,7 +421,7 @@ register! {
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<dyn Species>> {
|
||||
let display_species = get_value_call_getter!(pokemon.display_species(), env);
|
||||
wasm_ok(ExternRef::<dyn Species>::func_new(&env, &display_species))
|
||||
wasm_ok(ExternRef::<dyn Species>::func_new(&env, (&display_species).into()))
|
||||
}
|
||||
|
||||
fn pokemon_get_display_form(
|
||||
@@ -423,7 +429,7 @@ register! {
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<ExternRef<dyn Form>> {
|
||||
let display_form = get_value_call_getter!(pokemon.display_form(), env);
|
||||
wasm_ok(ExternRef::<dyn Form>::func_new(&env, &display_form))
|
||||
wasm_ok(ExternRef::<dyn Form>::func_new(&env, (&display_form).into()))
|
||||
}
|
||||
|
||||
fn pokemon_get_level(
|
||||
@@ -458,7 +464,7 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<u32> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let nickname = pokemon.nickname();
|
||||
if let Some(nickname) = nickname {
|
||||
let nickname: CString = match CString::new(nickname.as_str()) {
|
||||
@@ -482,7 +488,7 @@ register! {
|
||||
name_ptr: u32
|
||||
) -> WasmResult<u32> {
|
||||
unsafe {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||
let script = try_wasm!(pokemon.add_volatile_script(&c_name.as_ref().into()), env);
|
||||
if let Some(script) = script {
|
||||
@@ -499,7 +505,7 @@ register! {
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
script_ptr: u32
|
||||
) -> WasmResult<u32> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
unsafe{
|
||||
let env_data = env.data().data();
|
||||
let name_ptr = match try_wasm!(env_data.script_function_cache().script_get_name(&env_data), env).call(&mut env_data.store_mut(), script_ptr){
|
||||
@@ -507,14 +513,14 @@ register! {
|
||||
Err(e) => return wasm_err::<u32>(e.into(), &env)
|
||||
};
|
||||
let c_name: &CStr = CStr::from_ptr(env_data.get_raw_pointer(name_ptr));
|
||||
let script = try_wasm!(env_data.setup_script(script_ptr, ScriptCategory::Pokemon, &c_name.as_ref().into(), pokemon.as_ref().into()), env);
|
||||
let script = try_wasm!(env_data.setup_script(script_ptr, ScriptCategory::Pokemon, &c_name.as_ref().into(), (&pokemon).into()), env);
|
||||
try_wasm!(env_data.script_function_cache().dealloc_cstring(&env_data, name_ptr), env);
|
||||
|
||||
if let Some(script) = script {
|
||||
let script = try_wasm!(pokemon.add_volatile_script_with_script(script), env);
|
||||
let s = match script.as_ref() {
|
||||
Some(s) => s,
|
||||
None => return wasm_err::<u32>(anyhow!("Unable to get script").into(), &env)
|
||||
None => return wasm_err::<u32>(anyhow!("Unable to get script"), &env)
|
||||
};
|
||||
let s = try_wasm!(s.get_as::<WebAssemblyScript>(), env);
|
||||
wasm_ok(s.get_wasm_pointer())
|
||||
@@ -531,7 +537,7 @@ register! {
|
||||
) -> WasmResult<u8> {
|
||||
unsafe {
|
||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
wasm_ok(u8::from(pokemon.has_volatile_script(&c_name.as_ref().into())))
|
||||
}
|
||||
}
|
||||
@@ -543,7 +549,7 @@ register! {
|
||||
) -> WasmResult<u32> {
|
||||
unsafe {
|
||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let script = pokemon.get_volatile_script(&c_name.as_ref().into());
|
||||
wasm_ok(if let Some(script) = script {
|
||||
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
||||
@@ -564,7 +570,7 @@ register! {
|
||||
let pokemon = get_value_void!(pokemon, env);
|
||||
match pokemon.remove_volatile_script(&c_name.as_ref().into()) {
|
||||
Ok(_) => WasmVoidResult::ok(),
|
||||
Err(e) => WasmVoidResult::err(e.into(), &env)
|
||||
Err(e) => WasmVoidResult::err(e, &env)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -573,7 +579,7 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> WasmResult<u32> {
|
||||
let pokemon = get_value_arc!(pokemon, env);
|
||||
let pokemon = get_value!(pokemon, env);
|
||||
let script = pokemon.ability_script();
|
||||
if script.is_any() {
|
||||
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
use crate::dynamic_data::{LearnedMove, Pokemon, TurnChoice};
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||
get_value, get_value_call_getter, get_value_void, wasm_err,
|
||||
};
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{get_value_arc, get_value_arc_void, wasm_err};
|
||||
use crate::script_implementations::wasm::export_registry::{
|
||||
register, wasm_ok, WasmResult, WasmVoidResult, WasmVoidResultExtension,
|
||||
};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use anyhow_ext::Context;
|
||||
use std::ops::Deref;
|
||||
use wasmer::FunctionEnvMut;
|
||||
|
||||
register! {
|
||||
@@ -17,16 +15,16 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
turn_choice: ExternRef<TurnChoice>,
|
||||
) -> WasmResult<ExternRef<Pokemon>> {
|
||||
let user = get_value_call_getter!(turn_choice.user(), &env);
|
||||
wasm_ok(ExternRef::func_new(&env, user))
|
||||
let turn_choice = get_value_arc!(turn_choice, env);
|
||||
wasm_ok(ExternRef::func_new(&env, turn_choice.user().into()))
|
||||
}
|
||||
|
||||
fn turn_choice_get_kind(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
turn_choice: ExternRef<TurnChoice>,
|
||||
) -> WasmResult<u8> {
|
||||
let turn_choice = get_value!(turn_choice, env);
|
||||
wasm_ok(match turn_choice {
|
||||
let turn_choice = get_value_arc!(turn_choice, env);
|
||||
wasm_ok(match turn_choice.deref() {
|
||||
TurnChoice::Move(_) => 0,
|
||||
TurnChoice::Item(_) => 1,
|
||||
TurnChoice::Switch(_) => 2,
|
||||
@@ -39,21 +37,23 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
turn_choice: ExternRef<TurnChoice>,
|
||||
) -> WasmResult<u32> {
|
||||
wasm_ok(get_value_call_getter!(turn_choice.speed(), &env))
|
||||
let turn_choice = get_value_arc!(turn_choice, env);
|
||||
wasm_ok(turn_choice.speed())
|
||||
}
|
||||
|
||||
fn turn_choice_has_failed(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
turn_choice: ExternRef<TurnChoice>,
|
||||
) -> WasmResult<u8> {
|
||||
wasm_ok(if get_value_call_getter!(turn_choice.has_failed(), &env) { 1 } else { 0 })
|
||||
let turn_choice = get_value_arc!(turn_choice, env);
|
||||
wasm_ok(if turn_choice.has_failed() { 1 } else { 0 })
|
||||
}
|
||||
|
||||
fn turn_choice_fail(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
turn_choice: ExternRef<TurnChoice>,
|
||||
) -> WasmVoidResult {
|
||||
let turn_choice = get_value_void!(turn_choice, env);
|
||||
let turn_choice = get_value_arc_void!(turn_choice, env);
|
||||
turn_choice.fail();
|
||||
WasmVoidResult::ok()
|
||||
}
|
||||
@@ -63,9 +63,9 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
turn_choice: ExternRef<TurnChoice>,
|
||||
) -> WasmResult<i8> {
|
||||
return match turn_choice.value_func(&env) {
|
||||
return match turn_choice.value_func_arc(&env) {
|
||||
Ok(v) => {
|
||||
match v {
|
||||
match v.deref() {
|
||||
TurnChoice::Move(m) => wasm_ok(m.priority()),
|
||||
_ => wasm_err::<i8>(anyhow_ext::anyhow!("Invalid turn choice"), &env)
|
||||
}
|
||||
@@ -78,10 +78,10 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
turn_choice: ExternRef<TurnChoice>,
|
||||
) -> WasmResult<ExternRef<LearnedMove>> {
|
||||
return match turn_choice.value_func(&env) {
|
||||
return match turn_choice.value_func_arc(&env) {
|
||||
Ok(v) => {
|
||||
match v {
|
||||
TurnChoice::Move(m) => wasm_ok(ExternRef::<LearnedMove>::func_new(&env, m.used_move())),
|
||||
match v.deref() {
|
||||
TurnChoice::Move(m) => wasm_ok(ExternRef::func_new(&env, m.used_move().into())),
|
||||
_ => wasm_err::<ExternRef<LearnedMove>>(anyhow_ext::anyhow!("Invalid turn choice"), &env)
|
||||
}
|
||||
},
|
||||
@@ -93,9 +93,9 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
turn_choice: ExternRef<TurnChoice>,
|
||||
) -> WasmResult<u8> {
|
||||
return match turn_choice.value_func(&env) {
|
||||
return match turn_choice.value_func_arc(&env) {
|
||||
Ok(v) => {
|
||||
match v {
|
||||
match v.deref() {
|
||||
TurnChoice::Move(m) => wasm_ok(m.target_side()),
|
||||
_ => wasm_err::<u8>(anyhow_ext::anyhow!("Invalid turn choice"), &env)
|
||||
}
|
||||
@@ -108,9 +108,9 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
turn_choice: ExternRef<TurnChoice>,
|
||||
) -> WasmResult<u8> {
|
||||
return match turn_choice.value_func(&env) {
|
||||
return match turn_choice.value_func_arc(&env) {
|
||||
Ok(v) => {
|
||||
match v {
|
||||
match v.deref() {
|
||||
TurnChoice::Move(m) => wasm_ok(m.target_index()),
|
||||
_ => wasm_err::<u8>(anyhow_ext::anyhow!("Invalid turn choice"), &env)
|
||||
}
|
||||
@@ -123,9 +123,9 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
turn_choice: ExternRef<TurnChoice>,
|
||||
) -> WasmResult<u32> {
|
||||
return match turn_choice.value_func(&env) {
|
||||
return match turn_choice.value_func_arc(&env) {
|
||||
Ok(v) => {
|
||||
match v {
|
||||
match v.deref() {
|
||||
TurnChoice::Move(d) => {
|
||||
if let Some(script) = d.script().get() {
|
||||
let read_lock = script.read();
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
use anyhow_ext::anyhow;
|
||||
use std::ffi::{c_char, CStr, CString};
|
||||
use std::mem::{align_of, forget};
|
||||
use std::ops::Deref;
|
||||
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
||||
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::static_data::EffectParameter;
|
||||
use crate::StringKey;
|
||||
use anyhow_ext::Context;
|
||||
|
||||
/// Dynamic data registration
|
||||
mod dynamic_data;
|
||||
/// Static data registration
|
||||
mod static_data;
|
||||
/// Handling for opaque handles passed to WASM
|
||||
mod wasm_object;
|
||||
/// Result types for WASM
|
||||
mod wasm_result;
|
||||
|
||||
#[doc(inline)]
|
||||
pub(super) use wasm_object::*;
|
||||
#[doc(inline)]
|
||||
pub use wasm_result::*;
|
||||
|
||||
@@ -71,7 +75,6 @@ pub(crate) fn register_webassembly_funcs(
|
||||
) {
|
||||
register_func_with_env!(imports, store, _print, env);
|
||||
register_func_with_env!(imports, store, _error, env);
|
||||
register_func_with_env!(imports, store, _vec_extern_ref_get_value, env);
|
||||
|
||||
static_data::register(imports, store, env);
|
||||
dynamic_data::register(imports, store, env);
|
||||
@@ -90,7 +93,9 @@ fn _print(env: FunctionEnvMut<WebAssemblyEnv>, p: u32) {
|
||||
unsafe {
|
||||
let mem: *mut c_char = env.data().data().get_raw_pointer(p);
|
||||
let s = CStr::from_ptr(mem);
|
||||
println!("{}", s.to_str().unwrap());
|
||||
if let Ok(v) = s.to_str() {
|
||||
println!("{}", v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,21 +105,13 @@ fn _error(env: FunctionEnvMut<WebAssemblyEnv>, message: u32) {
|
||||
unsafe {
|
||||
let mem: *const c_char = env.data().data().get_raw_pointer(message);
|
||||
let message_str = CStr::from_ptr(mem);
|
||||
panic!("WASM Error: {}", message_str.to_str().unwrap());
|
||||
#[allow(clippy::panic)]
|
||||
if let Ok(v) = message_str.to_str() {
|
||||
panic!("WASM Error: {}", v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a single item from an earlier passed VecExternRef
|
||||
fn _vec_extern_ref_get_value(env: FunctionEnvMut<WebAssemblyEnv>, reference: u32, index: u32) -> WasmResult<u32> {
|
||||
let res = try_wasm!(
|
||||
env.data()
|
||||
.data()
|
||||
.get_extern_vec_ref_extern_ref(reference as usize, index as usize),
|
||||
env
|
||||
);
|
||||
wasm_ok(res as u32)
|
||||
}
|
||||
|
||||
/// Gets the hash value of a StringKey.
|
||||
fn string_key_get_hash(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> WasmResult<u32> {
|
||||
let value = get_value!(string_key, env);
|
||||
@@ -123,7 +120,7 @@ fn string_key_get_hash(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRe
|
||||
|
||||
/// Get a null-terminated C string from a StringKey. Note that this involves a copy into WASM
|
||||
/// memory, so this is relatively heavy.
|
||||
fn string_key_get_str(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> (u32, u32) {
|
||||
fn string_key_get_str(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> WasmResult<u32> {
|
||||
let value = get_value!(string_key, env);
|
||||
let string_key = value.str();
|
||||
let wasm_string_ptr = try_wasm!(
|
||||
@@ -147,8 +144,8 @@ fn effect_parameter_get_type(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
parameter: ExternRef<EffectParameter>,
|
||||
) -> WasmResult<u8> {
|
||||
let value = get_value!(parameter, env);
|
||||
wasm_ok(match value {
|
||||
let value = get_value_arc!(parameter, env);
|
||||
wasm_ok(match value.deref() {
|
||||
EffectParameter::Bool(_, _) => 1,
|
||||
EffectParameter::Int(_, _) => 2,
|
||||
EffectParameter::Float(_, _) => 3,
|
||||
@@ -161,8 +158,8 @@ fn effect_parameter_as_bool(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
parameter: ExternRef<EffectParameter>,
|
||||
) -> WasmResult<u8> {
|
||||
let value = get_value!(parameter, env);
|
||||
match value {
|
||||
let value = get_value_arc!(parameter, env);
|
||||
match value.deref() {
|
||||
EffectParameter::Bool(_, b) => wasm_ok(<u8 as From<bool>>::from(*b)),
|
||||
_ => wasm_err::<u8>(anyhow!("Unexpected parameter type. Expected bool, got {}", value), &env),
|
||||
}
|
||||
@@ -173,8 +170,8 @@ fn effect_parameter_as_int(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
parameter: ExternRef<EffectParameter>,
|
||||
) -> WasmResult<i64> {
|
||||
let value = get_value!(parameter, env);
|
||||
match value {
|
||||
let value = get_value_arc!(parameter, env);
|
||||
match value.deref() {
|
||||
EffectParameter::Int(_, i) => wasm_ok(*i),
|
||||
_ => wasm_err::<i64>(anyhow!("Unexpected parameter type. Expected int, got {}", value), &env),
|
||||
}
|
||||
@@ -185,8 +182,8 @@ fn effect_parameter_as_float(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
parameter: ExternRef<EffectParameter>,
|
||||
) -> WasmResult<f32> {
|
||||
let value = get_value!(parameter, env);
|
||||
match value {
|
||||
let value = get_value_arc!(parameter, env);
|
||||
match value.deref() {
|
||||
EffectParameter::Float(_, f) => wasm_ok(*f),
|
||||
_ => wasm_err::<f32>(
|
||||
anyhow!("Unexpected parameter type. Expected float, got {}", value),
|
||||
@@ -200,9 +197,9 @@ fn effect_parameter_as_string(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
parameter: ExternRef<EffectParameter>,
|
||||
) -> WasmResult<ExternRef<StringKey>> {
|
||||
let value = get_value!(parameter, env);
|
||||
match value {
|
||||
EffectParameter::Float(_, s) => wasm_ok(ExternRef::<StringKey>::func_new(&env, s)),
|
||||
let value = get_value_arc!(parameter, env);
|
||||
match value.deref() {
|
||||
EffectParameter::String(_, s) => wasm_ok(ExternRef::<StringKey>::func_new(&env, s.clone().into())),
|
||||
_ => wasm_err::<ExternRef<StringKey>>(
|
||||
anyhow!("Unexpected parameter type. Expected string, got {}", value),
|
||||
&env,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::script_implementations::wasm::export_registry::register;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::get_value_arc;
|
||||
use crate::script_implementations::wasm::export_registry::FunctionEnvMut;
|
||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||
use crate::script_implementations::wasm::export_registry::{register, try_wasm, wasm_ok, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::static_data::{Ability, EffectParameter};
|
||||
use crate::StringKey;
|
||||
@@ -10,25 +11,32 @@ register! {
|
||||
fn ability_get_name(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
ability: ExternRef<dyn Ability>
|
||||
) -> ExternRef<StringKey> {
|
||||
let ability = ability.value_func_arc(&env).unwrap();
|
||||
ExternRef::func_new(&env, ability.name())
|
||||
) -> WasmResult<ExternRef<StringKey>> {
|
||||
let ability = get_value_arc!(ability, env);
|
||||
wasm_ok(ExternRef::func_new(&env, ability.name().clone().into()))
|
||||
}
|
||||
|
||||
fn ability_get_effect(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
ability: ExternRef<dyn Ability>
|
||||
) -> ExternRef<StringKey> {
|
||||
let ability = ability.value_func_arc(&env).unwrap();
|
||||
ExternRef::func_new(&env, ability.effect())
|
||||
) -> WasmResult<ExternRef<StringKey>> {
|
||||
let ability = get_value_arc!(ability, env);
|
||||
wasm_ok(ExternRef::func_new(&env, ability.effect().clone().into()))
|
||||
}
|
||||
|
||||
fn ability_get_parameters(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
ability: ExternRef<dyn Ability>
|
||||
) -> VecExternRef<EffectParameter> {
|
||||
let ability = ability.value_func_arc(&env).unwrap();
|
||||
VecExternRef::new(env.data().data().as_ref(), ability.parameters())
|
||||
) -> WasmResult<u64> {
|
||||
let ability = get_value_arc!(ability, env);
|
||||
let parameters = ability.parameters();
|
||||
let mut vec : Vec<u32> = Vec::with_capacity(parameters.len());
|
||||
for parameter in parameters {
|
||||
vec.push(ExternRef::<EffectParameter>::func_new(&env, parameter.into()).index() as u32);
|
||||
}
|
||||
let wasm_ptr = try_wasm!(env.data().data().copy_value_vec_to_wasm(&vec), env);
|
||||
let r: u64 = unsafe { std::mem::transmute((wasm_ptr, vec.len() as u32)) };
|
||||
wasm_ok(r)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::try_wasm;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{get_value_arc, try_wasm};
|
||||
use crate::script_implementations::wasm::export_registry::{register, wasm_ok, FunctionEnvMut, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::static_data::{Form, StatisticSet};
|
||||
use crate::StringKey;
|
||||
use anyhow_ext::Context;
|
||||
|
||||
register! {
|
||||
|
||||
fn form_get_name(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
form: ExternRef<dyn Form>
|
||||
) -> ExternRef<StringKey> {
|
||||
let form = form.value_func_arc(&env).unwrap();
|
||||
ExternRef::func_new(&env, form.name())
|
||||
) -> WasmResult<ExternRef<StringKey>> {
|
||||
let form = get_value_arc!(form, env);
|
||||
wasm_ok(ExternRef::func_new(&env, form.name().clone().into()))
|
||||
}
|
||||
|
||||
fn form_get_types(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
form: ExternRef<dyn Form>
|
||||
) -> WasmResult<u64> {
|
||||
let form = form.value_func_arc(&env).unwrap();
|
||||
let form = get_value_arc!(form, env);
|
||||
let vec = form.types();
|
||||
let wasm_ptr = try_wasm!(env.data().data().copy_value_vec_to_wasm(vec), env);
|
||||
let r: u64 = unsafe { std::mem::transmute((wasm_ptr, vec.len() as u32)) };
|
||||
@@ -30,54 +29,69 @@ fn form_get_types(
|
||||
fn form_get_height(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
form: ExternRef<dyn Form>
|
||||
) -> f32 {
|
||||
form.value_func_arc(&env).unwrap().height()
|
||||
) -> WasmResult<f32> {
|
||||
wasm_ok(get_value_arc!(form, env).height())
|
||||
}
|
||||
|
||||
fn form_get_weight(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
form: ExternRef<dyn Form>
|
||||
) -> f32 {
|
||||
form.value_func_arc(&env).unwrap().weight()
|
||||
) -> WasmResult<f32> {
|
||||
wasm_ok(get_value_arc!(form, env).weight())
|
||||
}
|
||||
|
||||
fn form_get_base_experience(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
form: ExternRef<dyn Form>
|
||||
) -> u32 {
|
||||
form.value_func_arc(&env).unwrap().base_experience()
|
||||
) -> WasmResult<u32> {
|
||||
wasm_ok(get_value_arc!(form, env).base_experience())
|
||||
}
|
||||
|
||||
fn form_get_base_stats(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
form: ExternRef<dyn Form>
|
||||
) -> ExternRef<StatisticSet<u16>> {
|
||||
let form = form.value_func_arc(&env).unwrap();
|
||||
ExternRef::func_new(&env, form.base_stats())
|
||||
) -> WasmResult<ExternRef<StatisticSet<u16>>> {
|
||||
let form = get_value_arc!(form, env);
|
||||
wasm_ok(ExternRef::func_new(&env, form.base_stats().into()))
|
||||
}
|
||||
|
||||
fn form_get_abilities(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
form: ExternRef<dyn Form>
|
||||
) -> VecExternRef<StringKey> {
|
||||
let form = form.value_func_arc(&env).unwrap();
|
||||
VecExternRef::new(env.data().data().as_ref(), form.abilities())
|
||||
) -> WasmResult<u64> {
|
||||
let form = get_value_arc!(form, env);
|
||||
let abilities = form.abilities();
|
||||
let mut ability_refs : Vec<u32> = Vec::with_capacity(abilities.len());
|
||||
for ability in abilities {
|
||||
ability_refs.push(ExternRef::<StringKey>::func_new(&env, ability.clone().into()).index() as u32);
|
||||
}
|
||||
let wasm_ptr = try_wasm!(env.data().data().copy_value_vec_to_wasm(&ability_refs), env);
|
||||
let r: u64 = unsafe { std::mem::transmute((wasm_ptr, ability_refs.len() as u32)) };
|
||||
wasm_ok(r)
|
||||
}
|
||||
|
||||
fn form_get_hidden_abilities(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
form: ExternRef<dyn Form>
|
||||
) -> VecExternRef<StringKey> {
|
||||
let form = form.value_func_arc(&env).unwrap();
|
||||
VecExternRef::new(env.data().data().as_ref(), form.hidden_abilities())
|
||||
) -> WasmResult<u64> {
|
||||
let form = get_value_arc!(form, env);
|
||||
let abilities = form.hidden_abilities();
|
||||
let mut ability_refs : Vec<u32> = Vec::with_capacity(abilities.len());
|
||||
for ability in abilities {
|
||||
ability_refs.push(ExternRef::<StringKey>::func_new(&env, ability.clone().into()).index() as u32);
|
||||
}
|
||||
let wasm_ptr = try_wasm!(env.data().data().copy_value_vec_to_wasm(&ability_refs), env);
|
||||
let r: u64 = unsafe { std::mem::transmute((wasm_ptr, ability_refs.len() as u32)) };
|
||||
wasm_ok(r)
|
||||
}
|
||||
|
||||
fn form_has_flag_by_hash(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
form: ExternRef<dyn Form>,
|
||||
flag_hash: u32,
|
||||
) -> u8 {
|
||||
if form.value_func_arc(&env).unwrap().has_flag_by_hash(flag_hash) { 1 } else { 0 }
|
||||
) -> WasmResult<u8> {
|
||||
let form = get_value_arc!(form, env);
|
||||
wasm_ok(if form.has_flag_by_hash(flag_hash) { 1 } else { 0 })
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::script_implementations::wasm::export_registry::register;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{get_value, get_value_arc, wasm_ok};
|
||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::static_data::Item;
|
||||
@@ -12,60 +13,67 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
lib: ExternRef<dyn ItemLibrary>,
|
||||
string_key: ExternRef<StringKey>,
|
||||
) -> ExternRef<dyn Item> {
|
||||
let lib = lib.value_func_box(&env).unwrap();
|
||||
let m = lib.get(string_key.value_func(&env).unwrap());
|
||||
if let Some(v) = m {
|
||||
ExternRef::func_new(&env, &v)
|
||||
) -> WasmResult<ExternRef<dyn Item>> {
|
||||
let lib = get_value_arc!(lib, env);
|
||||
let string_key = get_value!(string_key, env);
|
||||
let m = lib.get(&string_key);
|
||||
wasm_ok(if let Some(v) = m {
|
||||
ExternRef::func_new(&env, (&v).into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn item_library_get_item_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, lib: ExternRef<dyn ItemLibrary>, hash: u32) -> ExternRef<dyn Item> {
|
||||
let lib = lib.value_func_box(&env).unwrap();
|
||||
fn item_library_get_item_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, lib: ExternRef<dyn ItemLibrary>, hash: u32) -> WasmResult<ExternRef<dyn Item>> {
|
||||
let lib = get_value_arc!(lib, env);
|
||||
let m = lib.get_by_hash(hash);
|
||||
if let Some(v) = m {
|
||||
ExternRef::func_new(&env, &v)
|
||||
wasm_ok(if let Some(v) = m {
|
||||
ExternRef::func_new(&env, (&v).into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn item_get_price(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
item: ExternRef<dyn Item>,
|
||||
) -> i32 {
|
||||
item.value_func_arc(&env).unwrap().price()
|
||||
) -> WasmResult<i32> {
|
||||
let item = get_value_arc!(item, env);
|
||||
wasm_ok(item.price())
|
||||
}
|
||||
|
||||
fn item_get_name(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
item: ExternRef<dyn Item>,
|
||||
) -> ExternRef<StringKey> {
|
||||
ExternRef::func_new(&env, item.value_func_arc(&env).unwrap().name())
|
||||
) -> WasmResult<ExternRef<StringKey>> {
|
||||
let item = get_value_arc!(item, env);
|
||||
wasm_ok(ExternRef::func_new(&env, item.name().clone().into()))
|
||||
}
|
||||
|
||||
fn item_get_category(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
item: ExternRef<dyn Item>,
|
||||
) -> u8 {
|
||||
unsafe { transmute(item.value_func_arc(&env).unwrap().category()) }
|
||||
) -> WasmResult<u8> {
|
||||
let item = get_value_arc!(item, env);
|
||||
unsafe { wasm_ok(transmute(item.category())) }
|
||||
}
|
||||
|
||||
fn item_get_battle_category(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
item: ExternRef<dyn Item>,
|
||||
) -> u8 {
|
||||
unsafe { transmute(item.value_func_arc(&env).unwrap().battle_category()) }
|
||||
) -> WasmResult<u8> {
|
||||
let item = get_value_arc!(item, env);
|
||||
unsafe { wasm_ok(transmute(item.battle_category())) }
|
||||
}
|
||||
|
||||
fn item_has_flag(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
item: ExternRef<dyn Item>,
|
||||
key: ExternRef<StringKey>
|
||||
) -> u8 {
|
||||
if item.value_func_arc(&env).unwrap().has_flag(key.value_func(&env).unwrap()) { 1 } else { 0 }
|
||||
) -> WasmResult<u8> {
|
||||
let item = get_value_arc!(item, env);
|
||||
let key = get_value!(key, env);
|
||||
wasm_ok(if item.has_flag(&key) { 1 } else { 0 })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
||||
|
||||
use crate::defines::LevelInt;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||
get_value, get_value_void, wasm_ok, WasmResult,
|
||||
get_value_arc, get_value_arc_void, wasm_ok, WasmResult,
|
||||
};
|
||||
use crate::script_implementations::wasm::export_registry::{register, WasmVoidResult, WasmVoidResultExtension};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
@@ -12,7 +12,6 @@ use crate::static_data::{
|
||||
ItemLibrary, LibrarySettings, MoveLibrary, SpeciesLibrary, StaticData, StaticStatisticSet, StatisticSet,
|
||||
TypeLibrary,
|
||||
};
|
||||
use anyhow_ext::Context;
|
||||
|
||||
/// Ability data registration
|
||||
mod ability;
|
||||
@@ -30,52 +29,59 @@ mod species;
|
||||
mod types;
|
||||
|
||||
register! {
|
||||
fn static_data_get_move_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<dyn StaticData>) -> ExternRef<dyn MoveLibrary> {
|
||||
ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().moves())
|
||||
fn static_data_get_move_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<dyn StaticData>) -> WasmResult<ExternRef<dyn MoveLibrary>> {
|
||||
let data_library = get_value_arc!(data_library, env);
|
||||
wasm_ok(ExternRef::func_new(&env, data_library.moves().into()))
|
||||
}
|
||||
|
||||
fn static_data_get_species_library(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
data_library: ExternRef<dyn StaticData>,
|
||||
) -> ExternRef<dyn SpeciesLibrary> {
|
||||
ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().species())
|
||||
) -> WasmResult<ExternRef<dyn SpeciesLibrary>> {
|
||||
let data_library = get_value_arc!(data_library, env);
|
||||
wasm_ok(ExternRef::func_new(&env, data_library.species().into()))
|
||||
}
|
||||
|
||||
fn static_data_get_item_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<dyn StaticData>) -> ExternRef<dyn ItemLibrary> {
|
||||
ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().items())
|
||||
fn static_data_get_item_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<dyn StaticData>) -> WasmResult<ExternRef<dyn ItemLibrary>> {
|
||||
let data_library = get_value_arc!(data_library, env);
|
||||
wasm_ok(ExternRef::func_new(&env, data_library.items().into()))
|
||||
}
|
||||
|
||||
fn static_data_get_type_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<dyn StaticData>) -> ExternRef<dyn TypeLibrary> {
|
||||
ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().types())
|
||||
fn static_data_get_type_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<dyn StaticData>) -> WasmResult<ExternRef<dyn TypeLibrary>> {
|
||||
let data_library = get_value_arc!(data_library, env);
|
||||
wasm_ok(ExternRef::func_new(&env, data_library.types().into()))
|
||||
}
|
||||
|
||||
fn static_data_get_library_settings(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
data_library: ExternRef<dyn StaticData>,
|
||||
) -> ExternRef<dyn LibrarySettings> {
|
||||
ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().settings())
|
||||
) -> WasmResult<ExternRef<dyn LibrarySettings>> {
|
||||
let data_library = get_value_arc!(data_library, env);
|
||||
wasm_ok(ExternRef::func_new(&env, data_library.settings().into()))
|
||||
}
|
||||
|
||||
fn library_settings_get_maximum_level(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<dyn LibrarySettings>) -> LevelInt {
|
||||
data_library.value_func_box(&env).unwrap().maximum_level()
|
||||
fn library_settings_get_maximum_level(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<dyn LibrarySettings>) -> WasmResult<LevelInt> {
|
||||
let data_library = get_value_arc!(data_library, env);
|
||||
wasm_ok(data_library.maximum_level())
|
||||
}
|
||||
|
||||
fn static_statistics_set_get_stat(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StaticStatisticSet<u16>>, stat: u8) -> u32 {
|
||||
fn static_statistics_set_get_stat(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StaticStatisticSet<u16>>, stat: u8) -> WasmResult<u32> {
|
||||
unsafe {
|
||||
statistics_set.value_func(&env).unwrap().get_stat(transmute(stat)) as u32
|
||||
let statistics_set = get_value_arc!(statistics_set, env);
|
||||
wasm_ok(statistics_set.get_stat(transmute(stat)) as u32)
|
||||
}
|
||||
}
|
||||
|
||||
fn statistic_set_get(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8) -> WasmResult<i64> {
|
||||
unsafe {
|
||||
let statistics_set = get_value!(statistics_set, env);
|
||||
let statistics_set = get_value_arc!(statistics_set, env);
|
||||
wasm_ok(statistics_set.get_stat(transmute(stat)) as i64)
|
||||
}
|
||||
}
|
||||
|
||||
fn statistic_set_set(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8, value: u64) -> WasmVoidResult {
|
||||
unsafe {
|
||||
let statistics_set = get_value_void!(statistics_set, env);
|
||||
let statistics_set = get_value_arc_void!(statistics_set, env);
|
||||
statistics_set.set_stat(transmute(stat), value as u32);
|
||||
WasmVoidResult::ok()
|
||||
}
|
||||
@@ -83,7 +89,7 @@ register! {
|
||||
|
||||
fn statistic_set_increase_stat(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8, value: u64) -> WasmVoidResult {
|
||||
unsafe {
|
||||
let statistics_set = get_value_void!(statistics_set, env);
|
||||
let statistics_set = get_value_arc_void!(statistics_set, env);
|
||||
statistics_set.increase_stat(transmute(stat), value as u32);
|
||||
WasmVoidResult::ok()
|
||||
}
|
||||
@@ -91,7 +97,7 @@ register! {
|
||||
|
||||
fn statistic_set_decrease_stat(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8, value: u64) -> WasmVoidResult {
|
||||
unsafe {
|
||||
let statistics_set = get_value_void!(statistics_set, env);
|
||||
let statistics_set = get_value_arc_void!(statistics_set, env);
|
||||
statistics_set.decrease_stat(transmute(stat), value as u32);
|
||||
WasmVoidResult::ok()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::script_implementations::wasm::export_registry::register;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{get_value, get_value_arc, wasm_ok};
|
||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::static_data::{MoveData, MoveLibrary};
|
||||
@@ -10,55 +11,67 @@ fn move_library_get_move(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
lib: ExternRef<dyn MoveLibrary>,
|
||||
string_key: ExternRef<StringKey>,
|
||||
) -> ExternRef<dyn MoveData> {
|
||||
let lib = lib.value_func_box(&env).unwrap();
|
||||
let m = lib.get(string_key.value_func(&env).unwrap());
|
||||
if let Some(v) = m {
|
||||
ExternRef::func_new(&env, &v)
|
||||
) -> WasmResult<ExternRef<dyn MoveData>> {
|
||||
let lib = get_value_arc!(lib, env);
|
||||
let string_key = get_value!(string_key, env);
|
||||
let m = lib.get(&string_key);
|
||||
wasm_ok(if let Some(v) = m {
|
||||
ExternRef::func_new(&env, (&v).into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn move_library_get_move_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, lib: ExternRef<dyn MoveLibrary>, hash: u32) -> ExternRef<dyn MoveData> {
|
||||
let lib = lib.value_func_box(&env).unwrap();
|
||||
fn move_library_get_move_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, lib: ExternRef<dyn MoveLibrary>, hash: u32) -> WasmResult<ExternRef<dyn MoveData>> {
|
||||
let lib = get_value_arc!(lib, env);
|
||||
let m = lib.get_by_hash(hash);
|
||||
if let Some(v) = m {
|
||||
ExternRef::func_new(&env, &v)
|
||||
wasm_ok(if let Some(v) = m {
|
||||
ExternRef::func_new(&env, (&v).into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn move_data_get_name(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> ExternRef<StringKey> {
|
||||
ExternRef::func_new(&env, move_data.value_func_arc(&env).unwrap().name())
|
||||
fn move_data_get_name(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) ->WasmResult<ExternRef<StringKey>> {
|
||||
let move_data = get_value_arc!(move_data, env);
|
||||
wasm_ok(ExternRef::func_new(&env, move_data.name().clone().into()))
|
||||
}
|
||||
|
||||
fn move_data_get_type(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> u8 {
|
||||
move_data.value_func_arc(&env).unwrap().move_type().into()
|
||||
fn move_data_get_type(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> WasmResult<u8> {
|
||||
let move_data = get_value_arc!(move_data, env);
|
||||
wasm_ok(move_data.move_type().into())
|
||||
}
|
||||
fn move_data_get_category(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> u8 {
|
||||
move_data.value_func_arc(&env).unwrap().category() as u8
|
||||
fn move_data_get_category(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> WasmResult<u8> {
|
||||
let move_data = get_value_arc!(move_data, env);
|
||||
wasm_ok(move_data.category() as u8)
|
||||
}
|
||||
fn move_data_get_base_power(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> u8 {
|
||||
move_data.value_func_arc(&env).unwrap().base_power()
|
||||
fn move_data_get_base_power(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> WasmResult<u8> {
|
||||
let move_data = get_value_arc!(move_data, env);
|
||||
wasm_ok(move_data.base_power())
|
||||
}
|
||||
fn move_data_get_accuracy(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> u8 {
|
||||
move_data.value_func_arc(&env).unwrap().accuracy()
|
||||
fn move_data_get_accuracy(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> WasmResult<u8> {
|
||||
let move_data = get_value_arc!(move_data, env);
|
||||
wasm_ok(move_data.accuracy())
|
||||
}
|
||||
fn move_data_get_base_usages(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> u8 {
|
||||
move_data.value_func_arc(&env).unwrap().base_usages()
|
||||
fn move_data_get_base_usages(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> WasmResult<u8> {
|
||||
let move_data = get_value_arc!(move_data, env);
|
||||
wasm_ok(move_data.base_usages())
|
||||
}
|
||||
fn move_data_get_target(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> u8 {
|
||||
move_data.value_func_arc(&env).unwrap().target() as u8
|
||||
fn move_data_get_target(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> WasmResult<u8> {
|
||||
let move_data = get_value_arc!(move_data, env);
|
||||
wasm_ok(move_data.target() as u8)
|
||||
}
|
||||
fn move_data_get_priority(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> i8 {
|
||||
move_data.value_func_arc(&env).unwrap().priority()
|
||||
fn move_data_get_priority(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>) -> WasmResult<i8> {
|
||||
let move_data = get_value_arc!(move_data, env);
|
||||
wasm_ok(move_data.priority())
|
||||
}
|
||||
fn move_data_has_flag(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>, flag: ExternRef<StringKey>) -> u8 {
|
||||
u8::from(move_data.value_func_arc(&env).unwrap().has_flag(flag.value_func(&env).unwrap()))
|
||||
fn move_data_has_flag(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>, flag: ExternRef<StringKey>) -> WasmResult<u8> {
|
||||
let move_data = get_value_arc!(move_data, env);
|
||||
let flag = get_value!(flag, env);
|
||||
wasm_ok(u8::from(move_data.has_flag(&flag)))
|
||||
}
|
||||
fn move_data_has_flag_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>, flag_hash: u32) -> u8 {
|
||||
u8::from(move_data.value_func_arc(&env).unwrap().has_flag_by_hash(flag_hash))
|
||||
fn move_data_has_flag_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<dyn MoveData>, flag_hash: u32) -> WasmResult<u8> {
|
||||
let move_data = get_value_arc!(move_data, env);
|
||||
wasm_ok(u8::from(move_data.has_flag_by_hash(flag_hash)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::script_implementations::wasm::export_registry::register;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{get_value_arc, wasm_ok};
|
||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::static_data::Nature;
|
||||
@@ -9,25 +10,29 @@ register! {
|
||||
fn nature_get_increase_stat(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
nature: ExternRef<dyn Nature>
|
||||
) -> u8 {
|
||||
unsafe { transmute(nature.value_func_box(&env).unwrap().increased_stat()) }
|
||||
) -> WasmResult<u8> {
|
||||
let nature = get_value_arc!(nature, env);
|
||||
wasm_ok(unsafe { transmute(nature.increased_stat()) })
|
||||
}
|
||||
fn nature_get_decrease_stat(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
nature: ExternRef<dyn Nature>
|
||||
) -> u8 {
|
||||
unsafe { transmute(nature.value_func_box(&env).unwrap().decreased_stat()) }
|
||||
) -> WasmResult<u8> {
|
||||
let nature = get_value_arc!(nature, env);
|
||||
wasm_ok(unsafe { transmute(nature.decreased_stat()) })
|
||||
}
|
||||
fn nature_get_increase_modifier(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
nature: ExternRef<dyn Nature>
|
||||
) -> f32 {
|
||||
nature.value_func_box(&env).unwrap().increased_modifier()
|
||||
) -> WasmResult<f32> {
|
||||
let nature = get_value_arc!(nature, env);
|
||||
wasm_ok(nature.increased_modifier())
|
||||
}
|
||||
fn nature_get_decrease_modifier(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
nature: ExternRef<dyn Nature>
|
||||
) -> f32 {
|
||||
nature.value_func_box(&env).unwrap().decreased_modifier()
|
||||
) -> WasmResult<f32> {
|
||||
let nature = get_value_arc!(nature, env);
|
||||
wasm_ok(nature.decreased_modifier())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::script_implementations::wasm::export_registry::register;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{get_value, get_value_arc, wasm_ok};
|
||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
use crate::static_data::SpeciesLibrary;
|
||||
@@ -12,73 +13,78 @@ fn species_library_get_species(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
lib: ExternRef<dyn SpeciesLibrary>,
|
||||
string_key: ExternRef<StringKey>,
|
||||
) -> ExternRef<dyn Species> {
|
||||
let lib = lib.value_func_box(&env).unwrap();
|
||||
let m = lib.get(string_key.value_func(&env).unwrap());
|
||||
if let Some(v) = m {
|
||||
ExternRef::func_new(&env, &v)
|
||||
) -> WasmResult<ExternRef<dyn Species>> {
|
||||
let lib = get_value_arc!(lib, env);
|
||||
let string_key = get_value!(string_key, env);
|
||||
let m = lib.get(&string_key);
|
||||
wasm_ok(if let Some(v) = m {
|
||||
ExternRef::func_new(&env, (&v).into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn species_get_capture_rate(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
species: ExternRef<dyn Species>,
|
||||
) -> u8 {
|
||||
species.value_func_arc(&env).unwrap().capture_rate()
|
||||
) -> WasmResult<u8> {
|
||||
let species = get_value_arc!(species, env);
|
||||
wasm_ok(species.capture_rate())
|
||||
}
|
||||
|
||||
fn species_get_growth_rate(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
species: ExternRef<dyn Species>,
|
||||
) -> ExternRef<StringKey> {
|
||||
let species = species.value_func_arc(&env).unwrap();
|
||||
ExternRef::func_new(&env, species.growth_rate())
|
||||
) -> WasmResult<ExternRef<StringKey>> {
|
||||
let species = get_value_arc!(species, env);
|
||||
wasm_ok(ExternRef::func_new(&env, species.growth_rate().clone().into()))
|
||||
}
|
||||
|
||||
fn species_get_gender_rate(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
species: ExternRef<dyn Species>,
|
||||
) -> f32 {
|
||||
species.value_func_arc(&env).unwrap().gender_rate()
|
||||
) -> WasmResult<f32> {
|
||||
let species = get_value_arc!(species, env);
|
||||
wasm_ok(species.gender_rate())
|
||||
}
|
||||
|
||||
fn species_get_name(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
species: ExternRef<dyn Species>,
|
||||
) -> ExternRef<StringKey> {
|
||||
let species = species.value_func_arc(&env).unwrap();
|
||||
ExternRef::func_new(&env, species.name())
|
||||
) -> WasmResult<ExternRef<StringKey>> {
|
||||
let species = get_value_arc!(species, env);
|
||||
wasm_ok(ExternRef::func_new(&env, species.name().clone().into()))
|
||||
}
|
||||
|
||||
fn species_get_id(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
species: ExternRef<dyn Species>,
|
||||
) -> u16 {
|
||||
species.value_func_arc(&env).unwrap().id()
|
||||
) -> WasmResult<u16> {
|
||||
let species = get_value_arc!(species, env);
|
||||
wasm_ok(species.id())
|
||||
}
|
||||
|
||||
fn species_get_form_by_hash(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
species: ExternRef<dyn Species>,
|
||||
form_hash: u32
|
||||
) -> ExternRef<dyn Form> {
|
||||
let species = species.value_func_arc(&env).unwrap();
|
||||
let form = species.get_form_by_hash(form_hash);
|
||||
if let Some(form) = form {
|
||||
ExternRef::func_new(&env, &form)
|
||||
} else {
|
||||
ExternRef::null()
|
||||
}
|
||||
) -> WasmResult<ExternRef<dyn Form>> {
|
||||
let species = get_value_arc!(species, env);
|
||||
let form = species.get_form_by_hash(form_hash);
|
||||
wasm_ok(if let Some(form) = form {
|
||||
ExternRef::func_new(&env, (&form).into())
|
||||
} else {
|
||||
ExternRef::null()
|
||||
})
|
||||
}
|
||||
|
||||
fn species_has_flag_by_hash(
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
species: ExternRef<dyn Species>,
|
||||
flag_hash: u32
|
||||
) -> u8 {
|
||||
if species.value_func_arc(&env).unwrap().has_flag_by_hash(flag_hash) { 1 } else { 0 }
|
||||
) -> WasmResult<u8> {
|
||||
let species = get_value_arc!(species, env);
|
||||
wasm_ok(if species.has_flag_by_hash(flag_hash) { 1 } else { 0 })
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use crate::script_implementations::wasm::export_registry::register;
|
||||
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||
get_value, get_value_arc, try_wasm, wasm_ok, WasmResult,
|
||||
};
|
||||
use crate::script_implementations::wasm::export_registry::FunctionEnvMut;
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||
@@ -11,15 +14,15 @@ register! {
|
||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||
lib: ExternRef<dyn TypeLibrary>,
|
||||
name: ExternRef<StringKey>
|
||||
) -> u8 {
|
||||
let lib = lib.value_func_arc(&env).unwrap();
|
||||
let name = name.value_func(&env).unwrap();
|
||||
let type_id = lib.get_type_id(name);
|
||||
if let Some(type_id) = type_id {
|
||||
) -> WasmResult<u8> {
|
||||
let lib = get_value_arc!(lib, env);
|
||||
let name = get_value!(name, env);
|
||||
let type_id = lib.get_type_id(&name);
|
||||
wasm_ok(if let Some(type_id) = type_id {
|
||||
type_id.into()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn type_library_get_single_effectiveness(
|
||||
@@ -27,9 +30,10 @@ register! {
|
||||
lib: ExternRef<dyn TypeLibrary>,
|
||||
attacking: u8,
|
||||
defending: u8
|
||||
) -> f32 {
|
||||
let lib = lib.value_func_arc(&env).unwrap();
|
||||
lib.get_single_effectiveness(attacking.into(), defending.into()).unwrap()
|
||||
) -> WasmResult<f32> {
|
||||
let lib = get_value_arc!(lib, env);
|
||||
let effectiveness = try_wasm!(lib.get_single_effectiveness(attacking.into(), defending.into()), env);
|
||||
wasm_ok(effectiveness)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1 +1,449 @@
|
||||
use crate::dynamic_data::{Battle, Pokemon, WeakBattleReference, WeakBattleSideReference, WeakPokemonReference};
|
||||
use anyhow::anyhow;
|
||||
use anyhow_ext::Result;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
#[derive(Clone)]
|
||||
#[allow(clippy::missing_docs_in_private_items)]
|
||||
pub(crate) enum WasmObject {
|
||||
// Static data
|
||||
StringKey(crate::StringKey),
|
||||
EffectParameter(Weak<crate::static_data::EffectParameter>),
|
||||
|
||||
MoveData(Weak<dyn crate::static_data::MoveData>),
|
||||
Species(Weak<dyn crate::static_data::Species>),
|
||||
Form(Weak<dyn crate::static_data::Form>),
|
||||
Item(Weak<dyn crate::static_data::Item>),
|
||||
Ability(Weak<dyn crate::static_data::Ability>),
|
||||
Nature(Weak<dyn crate::static_data::Nature>),
|
||||
|
||||
StaticStatisticSetU16(Weak<crate::static_data::StaticStatisticSet<u16>>),
|
||||
StatisticSetU32(Weak<crate::static_data::StatisticSet<u32>>),
|
||||
StatChangeStatisticSet(Weak<crate::static_data::ClampedStatisticSet<i8, -6, 6>>),
|
||||
EVStatisticSet(Weak<crate::static_data::ClampedStatisticSet<u8, 0, 252>>),
|
||||
IVStatisticSet(Weak<crate::static_data::ClampedStatisticSet<u8, 0, 31>>),
|
||||
|
||||
// Static data libraries
|
||||
MoveLibrary(Weak<dyn crate::static_data::MoveLibrary>),
|
||||
SpeciesLibrary(Weak<dyn crate::static_data::SpeciesLibrary>),
|
||||
ItemLibrary(Weak<dyn crate::static_data::ItemLibrary>),
|
||||
TypeLibrary(Weak<dyn crate::static_data::TypeLibrary>),
|
||||
LibrarySettings(Weak<dyn crate::static_data::LibrarySettings>),
|
||||
AbilityLibrary(Weak<dyn crate::static_data::AbilityLibrary>),
|
||||
StaticData(Weak<dyn crate::static_data::StaticData>),
|
||||
|
||||
// Dynamic data
|
||||
Pokemon(WeakPokemonReference),
|
||||
PokemonParty(Weak<crate::dynamic_data::PokemonParty>),
|
||||
LearnedMove(Weak<crate::dynamic_data::LearnedMove>),
|
||||
|
||||
// Dynamic data libraries
|
||||
DynamicLibrary(Weak<dyn crate::dynamic_data::DynamicLibrary>),
|
||||
|
||||
// Battle data
|
||||
Battle(WeakBattleReference),
|
||||
ChoiceQueue(Weak<crate::dynamic_data::ChoiceQueue>),
|
||||
BattleRandom(Weak<crate::dynamic_data::BattleRandom>),
|
||||
BattleSide(WeakBattleSideReference),
|
||||
BattleParty(Weak<crate::dynamic_data::BattleParty>),
|
||||
TurnChoice(Weak<crate::dynamic_data::TurnChoice>),
|
||||
ExecutingMove(Weak<crate::dynamic_data::ExecutingMove>),
|
||||
HitData(Weak<crate::dynamic_data::HitData>),
|
||||
}
|
||||
|
||||
/// Trait for converting from a [`WasmObject`] to a Rust object.
|
||||
pub(crate) trait FromWasmObj
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
/// Converts from a [`WasmObject`] to a Rust object.
|
||||
fn from_wasm_obj(obj: WasmObject) -> Result<Self>;
|
||||
}
|
||||
|
||||
impl PartialEq for WasmObject {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(WasmObject::StringKey(s1), WasmObject::StringKey(s2)) => s1 == s2,
|
||||
(WasmObject::EffectParameter(s1), WasmObject::EffectParameter(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::MoveData(s1), WasmObject::MoveData(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::Species(s1), WasmObject::Species(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::Form(s1), WasmObject::Form(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::Item(s1), WasmObject::Item(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::Ability(s1), WasmObject::Ability(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::Nature(s1), WasmObject::Nature(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::StaticStatisticSetU16(s1), WasmObject::StaticStatisticSetU16(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::StatisticSetU32(s1), WasmObject::StatisticSetU32(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::StatChangeStatisticSet(s1), WasmObject::StatChangeStatisticSet(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::EVStatisticSet(s1), WasmObject::EVStatisticSet(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::IVStatisticSet(s1), WasmObject::IVStatisticSet(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::MoveLibrary(s1), WasmObject::MoveLibrary(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::SpeciesLibrary(s1), WasmObject::SpeciesLibrary(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::ItemLibrary(s1), WasmObject::ItemLibrary(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::TypeLibrary(s1), WasmObject::TypeLibrary(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::LibrarySettings(s1), WasmObject::LibrarySettings(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::AbilityLibrary(s1), WasmObject::AbilityLibrary(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::StaticData(s1), WasmObject::StaticData(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::Pokemon(s1), WasmObject::Pokemon(s2)) => WeakPokemonReference::eq(s1, s2),
|
||||
(WasmObject::PokemonParty(s1), WasmObject::PokemonParty(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::LearnedMove(s1), WasmObject::LearnedMove(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::DynamicLibrary(s1), WasmObject::DynamicLibrary(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::Battle(s1), WasmObject::Battle(s2)) => WeakBattleReference::eq(s1, s2),
|
||||
(WasmObject::ChoiceQueue(s1), WasmObject::ChoiceQueue(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::BattleRandom(s1), WasmObject::BattleRandom(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::BattleSide(s1), WasmObject::BattleSide(s2)) => WeakBattleSideReference::eq(s1, s2),
|
||||
(WasmObject::BattleParty(s1), WasmObject::BattleParty(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::TurnChoice(s1), WasmObject::TurnChoice(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::ExecutingMove(s1), WasmObject::ExecutingMove(s2)) => Weak::ptr_eq(s1, s2),
|
||||
(WasmObject::HitData(s1), WasmObject::HitData(s2)) => Weak::ptr_eq(s1, s2),
|
||||
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for WasmObject {}
|
||||
|
||||
impl Hash for WasmObject {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
match self {
|
||||
WasmObject::StringKey(s) => state.write_u32(s.hash()),
|
||||
WasmObject::EffectParameter(m) => m.as_ptr().hash(state),
|
||||
WasmObject::MoveData(m) => m.as_ptr().hash(state),
|
||||
WasmObject::Species(m) => m.as_ptr().hash(state),
|
||||
WasmObject::Form(m) => m.as_ptr().hash(state),
|
||||
WasmObject::Item(m) => m.as_ptr().hash(state),
|
||||
WasmObject::Ability(m) => m.as_ptr().hash(state),
|
||||
WasmObject::Nature(m) => m.as_ptr().hash(state),
|
||||
WasmObject::StaticStatisticSetU16(m) => m.as_ptr().hash(state),
|
||||
WasmObject::StatisticSetU32(m) => m.as_ptr().hash(state),
|
||||
WasmObject::StatChangeStatisticSet(m) => m.as_ptr().hash(state),
|
||||
WasmObject::EVStatisticSet(m) => m.as_ptr().hash(state),
|
||||
WasmObject::IVStatisticSet(m) => m.as_ptr().hash(state),
|
||||
WasmObject::MoveLibrary(m) => m.as_ptr().hash(state),
|
||||
WasmObject::SpeciesLibrary(m) => m.as_ptr().hash(state),
|
||||
WasmObject::ItemLibrary(m) => m.as_ptr().hash(state),
|
||||
WasmObject::TypeLibrary(m) => m.as_ptr().hash(state),
|
||||
WasmObject::LibrarySettings(m) => m.as_ptr().hash(state),
|
||||
WasmObject::AbilityLibrary(m) => m.as_ptr().hash(state),
|
||||
WasmObject::StaticData(m) => m.as_ptr().hash(state),
|
||||
WasmObject::Pokemon(m) => m.as_ptr().hash(state),
|
||||
WasmObject::PokemonParty(m) => m.as_ptr().hash(state),
|
||||
WasmObject::LearnedMove(m) => m.as_ptr().hash(state),
|
||||
WasmObject::DynamicLibrary(m) => m.as_ptr().hash(state),
|
||||
WasmObject::Battle(m) => m.as_ptr().hash(state),
|
||||
WasmObject::ChoiceQueue(m) => m.as_ptr().hash(state),
|
||||
WasmObject::BattleRandom(m) => m.as_ptr().hash(state),
|
||||
WasmObject::BattleSide(m) => m.as_ptr().hash(state),
|
||||
WasmObject::BattleParty(m) => m.as_ptr().hash(state),
|
||||
WasmObject::TurnChoice(m) => m.as_ptr().hash(state),
|
||||
WasmObject::ExecutingMove(m) => m.as_ptr().hash(state),
|
||||
WasmObject::HitData(m) => m.as_ptr().hash(state),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Macro to convert a `WasmObject` into a `Result` of the specified type.
|
||||
macro_rules! get_from_wasm_obj {
|
||||
($variant:ident, $obj:expr) => {
|
||||
match $obj {
|
||||
WasmObject::$variant(b) => b.upgrade().ok_or(anyhow!("$variant was dropped")),
|
||||
_ => Err(anyhow!("Expected $variant")),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro to implement `FromWasmObj` for a type.
|
||||
macro_rules! impl_from_wasm_obj {
|
||||
($variant:ident, $ty:ty) => {
|
||||
impl FromWasmObj for $ty {
|
||||
fn from_wasm_obj(obj: WasmObject) -> Result<Self> {
|
||||
get_from_wasm_obj!($variant, obj)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl From<crate::StringKey> for WasmObject {
|
||||
fn from(value: crate::StringKey) -> Self {
|
||||
Self::StringKey(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWasmObj for crate::StringKey {
|
||||
fn from_wasm_obj(obj: WasmObject) -> Result<Self> {
|
||||
match obj {
|
||||
WasmObject::StringKey(b) => Ok(b),
|
||||
_ => Err(anyhow!("Expected StringKey")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Arc<crate::static_data::EffectParameter>> for WasmObject {
|
||||
fn from(value: &Arc<crate::static_data::EffectParameter>) -> Self {
|
||||
Self::EffectParameter(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(EffectParameter, Arc<crate::static_data::EffectParameter>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::MoveData>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::MoveData>) -> Self {
|
||||
Self::MoveData(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(MoveData, Arc<dyn crate::static_data::MoveData>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::Species>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::Species>) -> Self {
|
||||
Self::Species(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(Species, Arc<dyn crate::static_data::Species>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::Form>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::Form>) -> Self {
|
||||
Self::Form(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(Form, Arc<dyn crate::static_data::Form>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::Item>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::Item>) -> Self {
|
||||
Self::Item(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(Item, Arc<dyn crate::static_data::Item>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::Ability>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::Ability>) -> Self {
|
||||
Self::Ability(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(Ability, Arc<dyn crate::static_data::Ability>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::Nature>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::Nature>) -> Self {
|
||||
Self::Nature(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(Nature, Arc<dyn crate::static_data::Nature>);
|
||||
|
||||
impl From<&Arc<crate::static_data::StaticStatisticSet<u16>>> for WasmObject {
|
||||
fn from(value: &Arc<crate::static_data::StaticStatisticSet<u16>>) -> Self {
|
||||
Self::StaticStatisticSetU16(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(StaticStatisticSetU16, Arc<crate::static_data::StaticStatisticSet<u16>>);
|
||||
|
||||
impl From<&Arc<crate::static_data::StatisticSet<u32>>> for WasmObject {
|
||||
fn from(value: &Arc<crate::static_data::StatisticSet<u32>>) -> Self {
|
||||
Self::StatisticSetU32(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(StatisticSetU32, Arc<crate::static_data::StatisticSet<u32>>);
|
||||
|
||||
impl From<&Arc<crate::static_data::ClampedStatisticSet<i8, -6, 6>>> for WasmObject {
|
||||
fn from(value: &Arc<crate::static_data::ClampedStatisticSet<i8, -6, 6>>) -> Self {
|
||||
Self::StatChangeStatisticSet(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(
|
||||
StatChangeStatisticSet,
|
||||
Arc<crate::static_data::ClampedStatisticSet<i8, -6, 6>>
|
||||
);
|
||||
|
||||
impl From<&Arc<crate::static_data::ClampedStatisticSet<u8, 0, 252>>> for WasmObject {
|
||||
fn from(value: &Arc<crate::static_data::ClampedStatisticSet<u8, 0, 252>>) -> Self {
|
||||
Self::EVStatisticSet(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(EVStatisticSet, Arc<crate::static_data::ClampedStatisticSet<u8, 0, 252>>);
|
||||
|
||||
impl From<&Arc<crate::static_data::ClampedStatisticSet<u8, 0, 31>>> for WasmObject {
|
||||
fn from(value: &Arc<crate::static_data::ClampedStatisticSet<u8, 0, 31>>) -> Self {
|
||||
Self::IVStatisticSet(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(IVStatisticSet, Arc<crate::static_data::ClampedStatisticSet<u8, 0, 31>>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::MoveLibrary>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::MoveLibrary>) -> Self {
|
||||
Self::MoveLibrary(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(MoveLibrary, Arc<dyn crate::static_data::MoveLibrary>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::SpeciesLibrary>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::SpeciesLibrary>) -> Self {
|
||||
Self::SpeciesLibrary(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(SpeciesLibrary, Arc<dyn crate::static_data::SpeciesLibrary>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::ItemLibrary>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::ItemLibrary>) -> Self {
|
||||
Self::ItemLibrary(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(ItemLibrary, Arc<dyn crate::static_data::ItemLibrary>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::TypeLibrary>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::TypeLibrary>) -> Self {
|
||||
Self::TypeLibrary(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(TypeLibrary, Arc<dyn crate::static_data::TypeLibrary>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::LibrarySettings>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::LibrarySettings>) -> Self {
|
||||
Self::LibrarySettings(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(LibrarySettings, Arc<dyn crate::static_data::LibrarySettings>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::AbilityLibrary>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::AbilityLibrary>) -> Self {
|
||||
Self::AbilityLibrary(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(AbilityLibrary, Arc<dyn crate::static_data::AbilityLibrary>);
|
||||
|
||||
impl From<&Arc<dyn crate::static_data::StaticData>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::static_data::StaticData>) -> Self {
|
||||
Self::StaticData(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(StaticData, Arc<dyn crate::static_data::StaticData>);
|
||||
|
||||
impl From<&Pokemon> for WasmObject {
|
||||
fn from(value: &Pokemon) -> Self {
|
||||
Self::Pokemon(value.weak())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&WeakPokemonReference> for WasmObject {
|
||||
fn from(value: &WeakPokemonReference) -> Self {
|
||||
Self::Pokemon(value.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(Pokemon, Pokemon);
|
||||
|
||||
impl From<&Arc<crate::dynamic_data::PokemonParty>> for WasmObject {
|
||||
fn from(value: &Arc<crate::dynamic_data::PokemonParty>) -> Self {
|
||||
Self::PokemonParty(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(PokemonParty, Arc<crate::dynamic_data::PokemonParty>);
|
||||
|
||||
impl From<&Arc<crate::dynamic_data::LearnedMove>> for WasmObject {
|
||||
fn from(value: &Arc<crate::dynamic_data::LearnedMove>) -> Self {
|
||||
Self::LearnedMove(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(LearnedMove, Arc<crate::dynamic_data::LearnedMove>);
|
||||
|
||||
impl From<&Battle> for WasmObject {
|
||||
fn from(value: &Battle) -> Self {
|
||||
Self::Battle(value.weak())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&WeakBattleReference> for WasmObject {
|
||||
fn from(value: &WeakBattleReference) -> Self {
|
||||
Self::Battle(value.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(Battle, crate::dynamic_data::Battle);
|
||||
|
||||
impl From<&Arc<crate::dynamic_data::ChoiceQueue>> for WasmObject {
|
||||
fn from(value: &Arc<crate::dynamic_data::ChoiceQueue>) -> Self {
|
||||
Self::ChoiceQueue(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(ChoiceQueue, Arc<crate::dynamic_data::ChoiceQueue>);
|
||||
|
||||
impl From<&Arc<dyn crate::dynamic_data::DynamicLibrary>> for WasmObject {
|
||||
fn from(value: &Arc<dyn crate::dynamic_data::DynamicLibrary>) -> Self {
|
||||
Self::DynamicLibrary(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(DynamicLibrary, Arc<dyn crate::dynamic_data::DynamicLibrary>);
|
||||
|
||||
impl From<&Arc<crate::dynamic_data::BattleRandom>> for WasmObject {
|
||||
fn from(value: &Arc<crate::dynamic_data::BattleRandom>) -> Self {
|
||||
Self::BattleRandom(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(BattleRandom, Arc<crate::dynamic_data::BattleRandom>);
|
||||
|
||||
impl From<&crate::dynamic_data::BattleSide> for WasmObject {
|
||||
fn from(value: &crate::dynamic_data::BattleSide) -> Self {
|
||||
Self::BattleSide(value.weak())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&WeakBattleSideReference> for WasmObject {
|
||||
fn from(value: &WeakBattleSideReference) -> Self {
|
||||
Self::BattleSide(value.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(BattleSide, crate::dynamic_data::BattleSide);
|
||||
|
||||
impl From<&Arc<crate::dynamic_data::BattleParty>> for WasmObject {
|
||||
fn from(value: &Arc<crate::dynamic_data::BattleParty>) -> Self {
|
||||
Self::BattleParty(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(BattleParty, Arc<crate::dynamic_data::BattleParty>);
|
||||
|
||||
impl From<&Arc<crate::dynamic_data::TurnChoice>> for WasmObject {
|
||||
fn from(value: &Arc<crate::dynamic_data::TurnChoice>) -> Self {
|
||||
Self::TurnChoice(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(TurnChoice, Arc<crate::dynamic_data::TurnChoice>);
|
||||
|
||||
impl From<&Arc<crate::dynamic_data::ExecutingMove>> for WasmObject {
|
||||
fn from(value: &Arc<crate::dynamic_data::ExecutingMove>) -> Self {
|
||||
Self::ExecutingMove(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(ExecutingMove, Arc<crate::dynamic_data::ExecutingMove>);
|
||||
|
||||
impl From<&Arc<crate::dynamic_data::HitData>> for WasmObject {
|
||||
fn from(value: &Arc<crate::dynamic_data::HitData>) -> Self {
|
||||
Self::HitData(Arc::downgrade(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl_from_wasm_obj!(HitData, Arc<crate::dynamic_data::HitData>);
|
||||
|
||||
@@ -10,14 +10,18 @@ pub type WasmResult<T> = (u32, T);
|
||||
/// A result type that can be given to, or returned from WASM, but does not contain a value.
|
||||
pub type WasmVoidResult = u32;
|
||||
|
||||
/// An extension trait for `WasmResult` that provides some convenience methods.
|
||||
pub(crate) trait WasmVoidResultExtension {
|
||||
fn into_result(self, env: FunctionEnvMut<WebAssemblyEnv>) -> anyhow_ext::Result<()>;
|
||||
fn into_result_env(self, env: &Arc<WebAssemblyEnvironmentData>) -> anyhow_ext::Result<()>;
|
||||
fn from_result(res: anyhow_ext::Result<()>, env: &FunctionEnvMut<WebAssemblyEnv>) -> Self;
|
||||
/// Returns a `WasmVoidResult` that indicates success.
|
||||
fn ok() -> Self;
|
||||
/// Returns a `WasmVoidResult` that indicates failure.
|
||||
fn err(err: anyhow::Error, env: &FunctionEnvMut<WebAssemblyEnv>) -> Self;
|
||||
/// Converts a `WasmVoidResult` into a `Result<(), anyhow::Error>`. Used specifically for script
|
||||
/// function calls.
|
||||
fn into_result_env(self, env: &Arc<WebAssemblyEnvironmentData>) -> anyhow::Result<()>;
|
||||
}
|
||||
|
||||
/// Returns a success `WasmResult` with the given value.
|
||||
pub(super) fn wasm_ok<T>(value: T) -> WasmResult<T>
|
||||
where
|
||||
T: FromToNativeWasmType,
|
||||
@@ -26,6 +30,8 @@ where
|
||||
(0, value)
|
||||
}
|
||||
|
||||
/// Returns a failure `WasmResult` with the given error.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
pub(super) fn wasm_err<T>(err: Error, env: &FunctionEnvMut<WebAssemblyEnv>) -> WasmResult<T>
|
||||
where
|
||||
T: FromToNativeWasmType + Default,
|
||||
@@ -36,50 +42,38 @@ where
|
||||
}
|
||||
|
||||
impl WasmVoidResultExtension for WasmVoidResult {
|
||||
fn into_result(self, env: FunctionEnvMut<WebAssemblyEnv>) -> anyhow::Result<()> {
|
||||
Self::into_result_env(self, &env.data().data())
|
||||
fn ok() -> Self {
|
||||
0
|
||||
}
|
||||
|
||||
#[allow(clippy::unwrap_used)]
|
||||
fn err(err: Error, env: &FunctionEnvMut<WebAssemblyEnv>) -> Self {
|
||||
let s = CString::new(err.to_string()).unwrap();
|
||||
let ptr = env.data().data().copy_value_vec_to_wasm(s.as_bytes()).unwrap();
|
||||
ptr
|
||||
}
|
||||
|
||||
#[allow(clippy::unwrap_used)]
|
||||
fn into_result_env(self, env: &Arc<WebAssemblyEnvironmentData>) -> anyhow::Result<()> {
|
||||
if self == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
unsafe {
|
||||
let ptr = self;
|
||||
let mem: *mut c_char = env.get_raw_pointer(ptr as u32);
|
||||
let mem: *mut c_char = env.get_raw_pointer(ptr);
|
||||
let string = std::ffi::CStr::from_ptr(mem);
|
||||
let e = anyhow_ext::anyhow!("{}", string.to_str().unwrap());
|
||||
env.script_function_cache().dealloc_cstring(&env, ptr as u32).unwrap();
|
||||
env.script_function_cache().dealloc_cstring(env, ptr).unwrap();
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn from_result(res: anyhow::Result<()>, env: &FunctionEnvMut<WebAssemblyEnv>) -> Self {
|
||||
match res {
|
||||
Ok(_) => 0,
|
||||
Err(e) => {
|
||||
let s = CString::new(e.to_string()).unwrap();
|
||||
let ptr = env.data().data().copy_value_vec_to_wasm(s.as_bytes()).unwrap();
|
||||
ptr as u32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ok() -> Self {
|
||||
0
|
||||
}
|
||||
|
||||
fn err(err: Error, env: &FunctionEnvMut<WebAssemblyEnv>) -> Self {
|
||||
let s = CString::new(err.to_string()).unwrap();
|
||||
let ptr = env.data().data().copy_value_vec_to_wasm(s.as_bytes()).unwrap();
|
||||
ptr as u32
|
||||
}
|
||||
}
|
||||
|
||||
/// Macro to try an expression, and return a `WasmResult` if it fails.
|
||||
macro_rules! try_wasm {
|
||||
($e:expr, $env:expr) => {
|
||||
match $e.with_context(|| format!("WASM function {}", stdext::function_name!())) {
|
||||
match $e {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
return crate::script_implementations::wasm::export_registry::wasm_err(e.into(), &$env);
|
||||
@@ -88,12 +82,13 @@ macro_rules! try_wasm {
|
||||
};
|
||||
}
|
||||
|
||||
/// Macro to try an expression, and return a `WasmVoidResult` if it fails.
|
||||
macro_rules! try_wasm_void {
|
||||
($e:expr, $env:expr) => {
|
||||
match $e.with_context(|| format!("WASM function {}", stdext::function_name!())) {
|
||||
match $e {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
return WasmVoidResult::from_result(Err(e.into()), &$env);
|
||||
return WasmVoidResult::err(e.into(), &$env);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -102,24 +97,28 @@ macro_rules! try_wasm_void {
|
||||
pub(super) use try_wasm;
|
||||
pub(super) use try_wasm_void;
|
||||
|
||||
/// Resolve an externref to a value. Returns an error if this fails.
|
||||
macro_rules! get_value {
|
||||
($e:expr, $env:expr) => {
|
||||
crate::script_implementations::wasm::export_registry::try_wasm!($e.value_func(&$env), $env)
|
||||
};
|
||||
}
|
||||
|
||||
/// Resolve an externref of an Arc to a value. Returns an error if this fails.
|
||||
macro_rules! get_value_arc {
|
||||
($e:expr, $env:expr) => {
|
||||
crate::script_implementations::wasm::export_registry::try_wasm!($e.value_func_arc(&$env), $env)
|
||||
};
|
||||
}
|
||||
|
||||
/// Resolve an externref to a value. Returns an error if this fails.
|
||||
macro_rules! get_value_void {
|
||||
($e:expr, $env:expr) => {
|
||||
crate::script_implementations::wasm::export_registry::try_wasm_void!($e.value_func(&$env), $env)
|
||||
};
|
||||
}
|
||||
|
||||
/// Resolve an externref of an Arc to a value. Returns an error if this fails.
|
||||
macro_rules! get_value_arc_void {
|
||||
($e:expr, $env:expr) => {
|
||||
crate::script_implementations::wasm::export_registry::try_wasm_void!($e.value_func_arc(&$env), $env)
|
||||
@@ -131,6 +130,7 @@ pub(super) use get_value_arc;
|
||||
pub(super) use get_value_arc_void;
|
||||
pub(super) use get_value_void;
|
||||
|
||||
/// Resolve an externref to a value, and call a getter on it. Returns an error if this fails.
|
||||
macro_rules! get_value_call_getter {
|
||||
($e:ident.$func:ident(), $env:expr) => {{
|
||||
let _value = crate::script_implementations::wasm::export_registry::try_wasm!($e.value_func(&$env), $env);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use crate::{PkmnError, ValueIdentifiable};
|
||||
use crate::ValueIdentifiable;
|
||||
use anyhow_ext::Result;
|
||||
use std::any::Any;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::transmute;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::script_implementations::wasm::export_registry::{FromWasmObj, WasmObject};
|
||||
use crate::script_implementations::wasm::script_resolver::{
|
||||
WebAssemblyEnv, WebAssemblyEnvironmentData, WebAssemblyScriptResolver,
|
||||
};
|
||||
@@ -44,26 +44,26 @@ impl<T: ?Sized> Default for ExternRef<T> {
|
||||
impl<T: ValueIdentifiable + ?Sized> ExternRef<T> {
|
||||
/// Instantiates a new ExternRef for a bit of data. If we already have made an Extern Ref for
|
||||
/// this data and type, we use that instead.
|
||||
pub fn new(env: &WebAssemblyEnvironmentData, value: &dyn Any) -> Self {
|
||||
pub fn new(env: &WebAssemblyEnvironmentData, value: WasmObject) -> Self {
|
||||
Self {
|
||||
index: env.get_extern_ref_index::<T>(value),
|
||||
index: env.get_extern_ref_index(value),
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Instantiates a new ExternRef for a bit of data using the function environment. If we already
|
||||
/// have made an Extern Ref for this data and type, we use that instead.
|
||||
pub fn func_new(env: &FunctionEnvMut<WebAssemblyEnv>, value: &dyn Any) -> Self {
|
||||
pub fn func_new(env: &FunctionEnvMut<WebAssemblyEnv>, value: WasmObject) -> Self {
|
||||
Self {
|
||||
index: env.data().data().get_extern_ref_index::<T>(value),
|
||||
index: env.data().data().get_extern_ref_index(value),
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an ExternRef with a given resolver. This can be used in cases where we do not have an environment variable.
|
||||
pub(crate) fn new_with_resolver(resolver: &WebAssemblyScriptResolver, value: &dyn Any) -> Self {
|
||||
pub(crate) fn new_with_resolver(resolver: &WebAssemblyScriptResolver, value: WasmObject) -> Self {
|
||||
Self {
|
||||
index: resolver.environment_data().get_extern_ref_index::<T>(value),
|
||||
index: resolver.environment_data().get_extern_ref_index(value),
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
@@ -78,62 +78,46 @@ 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
|
||||
/// 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>) -> Result<&'a T>
|
||||
pub fn value_func(&self, env: &FunctionEnvMut<WebAssemblyEnv>) -> Result<T>
|
||||
where
|
||||
T: Sized + 'static,
|
||||
T: FromWasmObj,
|
||||
{
|
||||
self.value(&env.data().data())?.ok_or(PkmnError::NullReference.into())
|
||||
self.value(&env.data().data())
|
||||
}
|
||||
|
||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||
/// value when it was passed before. If these types do not match, this will panic.
|
||||
pub fn value_func_arc(&self, env: &FunctionEnvMut<WebAssemblyEnv>) -> Result<Arc<T>>
|
||||
where
|
||||
T: 'static,
|
||||
Arc<T>: FromWasmObj,
|
||||
{
|
||||
self.value_arc(&env.data().data())?
|
||||
.ok_or(PkmnError::NullReference.into())
|
||||
self.value_arc(&env.data().data())
|
||||
}
|
||||
|
||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||
/// value when it was passed before. If these types do not match, this will panic.
|
||||
pub fn value_func_box(&self, env: &FunctionEnvMut<WebAssemblyEnv>) -> Result<&Box<T>>
|
||||
pub fn value(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Result<T>
|
||||
where
|
||||
T: 'static,
|
||||
T: FromWasmObj,
|
||||
{
|
||||
self.value_box(&env.data().data())
|
||||
let value = env.get_extern_ref_value::<T>(self.index)?;
|
||||
let o = FromWasmObj::from_wasm_obj(value)?;
|
||||
Ok(o)
|
||||
}
|
||||
|
||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||
/// value when it was passed before. If these types do not match, this will panic.
|
||||
pub fn value<'a>(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Result<Option<&'a T>>
|
||||
pub fn value_arc(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Result<Arc<T>>
|
||||
where
|
||||
T: Sized + 'static,
|
||||
Arc<T>: FromWasmObj,
|
||||
{
|
||||
Ok(env.get_extern_ref_value::<T>(self.index)?.downcast_ref::<T>())
|
||||
let wasm_obj = env.get_extern_ref_value::<T>(self.index)?;
|
||||
FromWasmObj::from_wasm_obj(wasm_obj)
|
||||
}
|
||||
|
||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||
/// value when it was passed before. If these types do not match, this will panic.
|
||||
pub fn value_arc(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Result<Option<Arc<T>>>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
Ok(env
|
||||
.get_extern_ref_value::<T>(self.index)?
|
||||
.downcast_ref::<Arc<T>>()
|
||||
.cloned())
|
||||
}
|
||||
|
||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||
/// value when it was passed before. If these types do not match, this will panic.
|
||||
pub fn value_box(&self, env: &Arc<WebAssemblyEnvironmentData>) -> Result<&Box<T>>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
env.get_extern_ref_value::<T>(self.index)?
|
||||
.downcast_ref::<Box<T>>()
|
||||
.ok_or(PkmnError::NullReference.into())
|
||||
/// Returns the internal index for this ExternRef.
|
||||
pub(crate) fn index(&self) -> usize {
|
||||
self.index
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,16 +169,16 @@ impl<T> Default for VecExternRef<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static> VecExternRef<T> {
|
||||
/// Instantiates a new VecExternRef for a given slice.
|
||||
pub fn new(env: &WebAssemblyEnvironmentData, value: &Vec<T>) -> Self {
|
||||
Self {
|
||||
index: env.get_extern_vec_ref_index(value),
|
||||
size: value.len() as u32,
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
// impl<T: 'static> VecExternRef<T> {
|
||||
// /// Instantiates a new VecExternRef for a given slice.
|
||||
// pub fn new(env: &WebAssemblyEnvironmentData, value: &Vec<T>) -> Self {
|
||||
// Self {
|
||||
// index: env.get_extern_vec_ref_index(value),
|
||||
// size: value.len() as u32,
|
||||
// _phantom: Default::default(),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
unsafe impl<T> FromToNativeWasmType for VecExternRef<T> {
|
||||
type Native = i64;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use anyhow_ext::{anyhow, Result};
|
||||
use anyhow_ext::Result;
|
||||
use std::any::Any;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize};
|
||||
use std::sync::Arc;
|
||||
@@ -9,7 +9,7 @@ use crate::dynamic_data::{
|
||||
Battle, DamageSource, DynamicLibrary, ExecutingMove, Pokemon, Script, ScriptOwnerData, TurnChoice,
|
||||
};
|
||||
use crate::script_implementations::wasm::export_registry::WasmVoidResultExtension;
|
||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnvironmentData;
|
||||
use crate::script_implementations::wasm::WebAssemblyScriptCapabilities;
|
||||
use crate::static_data::{EffectParameter, Item, Statistic, TypeIdentifier};
|
||||
@@ -86,14 +86,7 @@ macro_rules! call_func {
|
||||
/// Util macro to reduce extern ref instantiation verbosity.
|
||||
macro_rules! ex_ref {
|
||||
($env:ident, $value:expr) => {
|
||||
ExternRef::new($env.as_ref(), $value)
|
||||
};
|
||||
}
|
||||
|
||||
/// Util macro to reduce vec extern ref instantiation verbosity.
|
||||
macro_rules! vec_ex_ref {
|
||||
($env:ident, $value:expr) => {
|
||||
VecExternRef::new($env.as_ref(), $value)
|
||||
ExternRef::new($env.as_ref(), $value.into())
|
||||
};
|
||||
}
|
||||
|
||||
@@ -132,19 +125,25 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_initialize(&self, library: &Arc<dyn DynamicLibrary>, pars: Vec<EffectParameter>) -> Result<()> {
|
||||
fn on_initialize(&self, library: &Arc<dyn DynamicLibrary>, pars: Vec<Arc<EffectParameter>>) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::Initialize) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().on_initialize(env) {
|
||||
call_func!(func, env, self, ex_ref!(env, library), vec_ex_ref!(env, &pars));
|
||||
let pars = pars
|
||||
.into_iter()
|
||||
.map(|p| ExternRef::<EffectParameter>::new(env, (&p).into()).index() as u32)
|
||||
.collect::<Vec<_>>();
|
||||
let wasm_ptr = env.copy_value_vec_to_wasm(&pars)?;
|
||||
let r: u64 = unsafe { std::mem::transmute((wasm_ptr, pars.len() as u32)) };
|
||||
call_func!(func, env, self, ex_ref!(env, library), r);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_before_turn(&self, choice: &TurnChoice) -> Result<()> {
|
||||
fn on_before_turn(&self, choice: &Arc<TurnChoice>) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::OnBeforeTurn) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -155,7 +154,7 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn change_speed(&self, choice: &TurnChoice, speed: &mut u32) -> Result<()> {
|
||||
fn change_speed(&self, choice: &Arc<TurnChoice>, speed: &mut u32) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangeSpeed) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -169,7 +168,7 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn change_priority(&self, choice: &TurnChoice, priority: &mut i8) -> Result<()> {
|
||||
fn change_priority(&self, choice: &Arc<TurnChoice>, priority: &mut i8) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangePriority) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -183,26 +182,22 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn change_move(&self, choice: &TurnChoice, move_name: &mut StringKey) -> Result<()> {
|
||||
fn change_move(&self, choice: &Arc<TurnChoice>, move_name: &mut StringKey) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangeMove) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_move(env) {
|
||||
let move_ref = ex_ref!(env, move_name);
|
||||
let move_ref = ex_ref!(env, move_name.clone());
|
||||
let ptr = env.allocate_temp::<ExternRef<StringKey>>(move_ref);
|
||||
call_func!(func, env, self, ex_ref!(env, choice), ptr.wasm_ptr);
|
||||
*move_name = ptr
|
||||
.value()
|
||||
.value(env)?
|
||||
.ok_or(anyhow!("Unable to get move name"))?
|
||||
.clone();
|
||||
*move_name = ptr.value().value(env)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn change_number_of_hits(&self, choice: &TurnChoice, number_of_hits: &mut u8) -> Result<()> {
|
||||
fn change_number_of_hits(&self, choice: &Arc<TurnChoice>, number_of_hits: &mut u8) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangeNumberOfHits) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -216,7 +211,7 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prevent_move(&self, mv: &ExecutingMove, prevent: &mut bool) -> Result<()> {
|
||||
fn prevent_move(&self, mv: &Arc<ExecutingMove>, prevent: &mut bool) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::PreventMove) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -230,7 +225,7 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fail_move(&self, mv: &ExecutingMove, fail: &mut bool) -> Result<()> {
|
||||
fn fail_move(&self, mv: &Arc<ExecutingMove>, fail: &mut bool) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::FailMove) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -244,7 +239,7 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn stop_before_move(&self, mv: &ExecutingMove, stop: &mut bool) -> Result<()> {
|
||||
fn stop_before_move(&self, mv: &Arc<ExecutingMove>, stop: &mut bool) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::StopBeforeMove) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -258,7 +253,7 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_before_move(&self, mv: &ExecutingMove) -> Result<()> {
|
||||
fn on_before_move(&self, mv: &Arc<ExecutingMove>) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::OnBeforeMove) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -269,61 +264,47 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fail_incoming_move(&self, mv: &ExecutingMove, target: &Arc<Pokemon>, fail: &mut bool) -> Result<()> {
|
||||
fn fail_incoming_move(&self, mv: &Arc<ExecutingMove>, target: &Pokemon, fail: &mut bool) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::FailIncomingMove) {
|
||||
return Ok(());
|
||||
}
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().fail_incoming_move(env) {
|
||||
let ptr = env.allocate_temp::<bool>(*fail);
|
||||
call_func!(
|
||||
func,
|
||||
env,
|
||||
self,
|
||||
ex_ref!(env, mv),
|
||||
ex_ref!(env, target.as_ref()),
|
||||
ptr.wasm_ptr
|
||||
);
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), ptr.wasm_ptr);
|
||||
*fail = *ptr.value();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_invulnerable(&self, mv: &ExecutingMove, target: &Arc<Pokemon>, invulnerable: &mut bool) -> Result<()> {
|
||||
fn is_invulnerable(&self, mv: &Arc<ExecutingMove>, target: &Pokemon, invulnerable: &mut bool) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::IsInvulnerable) {
|
||||
return Ok(());
|
||||
}
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().is_invulnerable(env) {
|
||||
let ptr = env.allocate_temp::<bool>(*invulnerable);
|
||||
call_func!(
|
||||
func,
|
||||
env,
|
||||
self,
|
||||
ex_ref!(env, mv),
|
||||
ex_ref!(env, target.as_ref()),
|
||||
ptr.wasm_ptr
|
||||
);
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), ptr.wasm_ptr);
|
||||
*invulnerable = *ptr.value();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_move_miss(&self, mv: &ExecutingMove, target: &Arc<Pokemon>) -> Result<()> {
|
||||
fn on_move_miss(&self, mv: &Arc<ExecutingMove>, target: &Pokemon) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::OnMoveMiss) {
|
||||
return Ok(());
|
||||
}
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().on_move_miss(env) {
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target.as_ref()));
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn change_move_type(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
move_type: &mut TypeIdentifier,
|
||||
) -> Result<()> {
|
||||
@@ -333,7 +314,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_move_type(env) {
|
||||
let ptr = env.allocate_temp::<TypeIdentifier>(*move_type);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*move_type = *ptr.value();
|
||||
@@ -343,8 +324,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn change_effectiveness(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
effectiveness: &mut f32,
|
||||
) -> Result<()> {
|
||||
@@ -354,7 +335,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_effectiveness(env) {
|
||||
let ptr = env.allocate_temp(*effectiveness);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*effectiveness = *ptr.value();
|
||||
@@ -364,8 +345,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn block_critical(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
block_critical: &mut bool,
|
||||
) -> Result<()> {
|
||||
@@ -375,7 +356,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().block_critical(env) {
|
||||
let ptr = env.allocate_temp(*block_critical);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*block_critical = *ptr.value();
|
||||
@@ -385,8 +366,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn block_incoming_critical(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
block_critical: &mut bool,
|
||||
) -> Result<()> {
|
||||
@@ -396,7 +377,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().block_incoming_critical(env) {
|
||||
let ptr = env.allocate_temp(*block_critical);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*block_critical = *ptr.value();
|
||||
@@ -404,14 +385,14 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn change_accuracy(&self, mv: &ExecutingMove, target: &Arc<Pokemon>, hit: u8, accuracy: &mut u8) -> Result<()> {
|
||||
fn change_accuracy(&self, mv: &Arc<ExecutingMove>, target: &Pokemon, hit: u8, accuracy: &mut u8) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangeAccuracy) {
|
||||
return Ok(());
|
||||
}
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_accuracy(env) {
|
||||
let ptr = env.allocate_temp(*accuracy);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*accuracy = *ptr.value();
|
||||
@@ -419,14 +400,14 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn change_critical_stage(&self, mv: &ExecutingMove, target: &Arc<Pokemon>, hit: u8, stage: &mut u8) -> Result<()> {
|
||||
fn change_critical_stage(&self, mv: &Arc<ExecutingMove>, target: &Pokemon, hit: u8, stage: &mut u8) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangeCriticalStage) {
|
||||
return Ok(());
|
||||
}
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_critical_stage(env) {
|
||||
let ptr = env.allocate_temp(*stage);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*stage = *ptr.value();
|
||||
@@ -436,8 +417,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn change_critical_modifier(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
modifier: &mut f32,
|
||||
) -> Result<()> {
|
||||
@@ -447,7 +428,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_critical_modifier(env) {
|
||||
let ptr = env.allocate_temp(*modifier);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*modifier = *ptr.value();
|
||||
@@ -457,8 +438,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn change_stab_modifier(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
modifier: &mut f32,
|
||||
) -> Result<()> {
|
||||
@@ -468,7 +449,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_stab_modifier(env) {
|
||||
let ptr = env.allocate_temp(*modifier);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*modifier = *ptr.value();
|
||||
@@ -476,14 +457,14 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn change_base_power(&self, mv: &ExecutingMove, target: &Arc<Pokemon>, hit: u8, base_power: &mut u8) -> Result<()> {
|
||||
fn change_base_power(&self, mv: &Arc<ExecutingMove>, target: &Pokemon, hit: u8, base_power: &mut u8) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangeBasePower) {
|
||||
return Ok(());
|
||||
}
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_base_power(env) {
|
||||
let ptr = env.allocate_temp(*base_power);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*base_power = *ptr.value();
|
||||
@@ -493,8 +474,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn bypass_defensive_stat_boost(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
bypass: &mut bool,
|
||||
) -> Result<()> {
|
||||
@@ -504,7 +485,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().bypass_defensive_stat_boost(env) {
|
||||
let ptr = env.allocate_temp(*bypass);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*bypass = *ptr.value();
|
||||
@@ -514,8 +495,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn bypass_offensive_stat_boost(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
bypass: &mut bool,
|
||||
) -> Result<()> {
|
||||
@@ -525,7 +506,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().bypass_offensive_stat_boost(env) {
|
||||
let ptr = env.allocate_temp(*bypass);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*bypass = *ptr.value();
|
||||
@@ -535,8 +516,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn change_offensive_stat_value(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
amount: &mut u32,
|
||||
) -> Result<()> {
|
||||
@@ -546,7 +527,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_offensive_stat_value(env) {
|
||||
let ptr = env.allocate_temp(*amount);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*amount = *ptr.value();
|
||||
@@ -556,8 +537,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn change_defensive_stat_value(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
amount: &mut u32,
|
||||
) -> Result<()> {
|
||||
@@ -567,7 +548,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_defensive_stat_value(env) {
|
||||
let ptr = env.allocate_temp(*amount);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*amount = *ptr.value();
|
||||
@@ -577,8 +558,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn change_damage_stat_modifier(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
modifier: &mut f32,
|
||||
) -> Result<()> {
|
||||
@@ -588,7 +569,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_damage_stat_modifier(env) {
|
||||
let ptr = env.allocate_temp(*modifier);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*modifier = *ptr.value();
|
||||
@@ -598,8 +579,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn change_damage_modifier(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
modifier: &mut f32,
|
||||
) -> Result<()> {
|
||||
@@ -609,7 +590,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_damage_modifier(env) {
|
||||
let ptr = env.allocate_temp(*modifier);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*modifier = *ptr.value();
|
||||
@@ -617,14 +598,14 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn change_damage(&self, mv: &ExecutingMove, target: &Arc<Pokemon>, hit: u8, damage: &mut u32) -> Result<()> {
|
||||
fn change_damage(&self, mv: &Arc<ExecutingMove>, target: &Pokemon, hit: u8, damage: &mut u32) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangeDamage) {
|
||||
return Ok(());
|
||||
}
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_damage(env) {
|
||||
let ptr = env.allocate_temp(*damage);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*damage = *ptr.value();
|
||||
@@ -634,8 +615,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn change_incoming_damage(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
damage: &mut u32,
|
||||
) -> Result<()> {
|
||||
@@ -645,7 +626,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_incoming_damage(env) {
|
||||
let ptr = env.allocate_temp(*damage);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*damage = *ptr.value();
|
||||
@@ -653,25 +634,25 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_incoming_hit(&self, mv: &ExecutingMove, target: &Arc<Pokemon>, hit: u8) -> Result<()> {
|
||||
fn on_incoming_hit(&self, mv: &Arc<ExecutingMove>, target: &Pokemon, hit: u8) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::OnIncomingHit) {
|
||||
return Ok(());
|
||||
}
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().on_incoming_hit(env) {
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_opponent_faints(&self, mv: &ExecutingMove, target: &Arc<Pokemon>, hit: u8) -> Result<()> {
|
||||
fn on_opponent_faints(&self, mv: &Arc<ExecutingMove>, target: &Pokemon, hit: u8) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::OnFaintingOpponent) {
|
||||
return Ok(());
|
||||
}
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().on_opponent_faints(env) {
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit);
|
||||
}
|
||||
Ok(())
|
||||
@@ -709,8 +690,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn prevent_secondary_effect(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
prevent: &mut bool,
|
||||
) -> Result<()> {
|
||||
@@ -720,7 +701,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().prevent_secondary_effect(env) {
|
||||
let ptr = env.allocate_temp(*prevent);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*prevent = *ptr.value();
|
||||
@@ -728,14 +709,14 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn change_effect_chance(&self, mv: &ExecutingMove, target: &Arc<Pokemon>, hit: u8, chance: &mut f32) -> Result<()> {
|
||||
fn change_effect_chance(&self, mv: &Arc<ExecutingMove>, target: &Pokemon, hit: u8, chance: &mut f32) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangeEffectChance) {
|
||||
return Ok(());
|
||||
}
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_effect_chance(env) {
|
||||
let ptr = env.allocate_temp(*chance);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*chance = *ptr.value();
|
||||
@@ -745,8 +726,8 @@ impl Script for WebAssemblyScript {
|
||||
|
||||
fn change_incoming_effect_chance(
|
||||
&self,
|
||||
mv: &ExecutingMove,
|
||||
target: &Arc<Pokemon>,
|
||||
mv: &Arc<ExecutingMove>,
|
||||
target: &Pokemon,
|
||||
hit: u8,
|
||||
chance: &mut f32,
|
||||
) -> Result<()> {
|
||||
@@ -756,7 +737,7 @@ impl Script for WebAssemblyScript {
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().change_incoming_effect_chance(env) {
|
||||
let ptr = env.allocate_temp(*chance);
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
let w_ptr = ptr.wasm_ptr;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit, w_ptr);
|
||||
*chance = *ptr.value();
|
||||
@@ -764,31 +745,31 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_secondary_effect(&self, mv: &ExecutingMove, target: &Arc<Pokemon>, hit: u8) -> Result<()> {
|
||||
fn on_secondary_effect(&self, mv: &Arc<ExecutingMove>, target: &Pokemon, hit: u8) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::OnFaintingOpponent) {
|
||||
return Ok(());
|
||||
}
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().on_secondary_effect(env) {
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target), hit);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_after_hits(&self, mv: &ExecutingMove, target: &Arc<Pokemon>) -> Result<()> {
|
||||
fn on_after_hits(&self, mv: &Arc<ExecutingMove>, target: &Pokemon) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::OnAfterHits) {
|
||||
return Ok(());
|
||||
}
|
||||
let env = &self.environment;
|
||||
if let Some(func) = env.script_function_cache().on_after_hits(env) {
|
||||
let target = target.as_ref();
|
||||
let target = target;
|
||||
call_func!(func, env, self, ex_ref!(env, mv), ex_ref!(env, target));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prevent_self_switch(&self, choice: &TurnChoice, prevent: &mut bool) -> Result<()> {
|
||||
fn prevent_self_switch(&self, choice: &Arc<TurnChoice>, prevent: &mut bool) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::PreventSelfSwitch) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -801,7 +782,7 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prevent_opponent_switch(&self, choice: &TurnChoice, prevent: &mut bool) -> Result<()> {
|
||||
fn prevent_opponent_switch(&self, choice: &Arc<TurnChoice>, prevent: &mut bool) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::PreventSelfSwitch) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -836,7 +817,7 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prevent_self_run_away(&self, choice: &TurnChoice, prevent: &mut bool) -> Result<()> {
|
||||
fn prevent_self_run_away(&self, choice: &Arc<TurnChoice>, prevent: &mut bool) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::PreventSelfRunAway) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -849,7 +830,7 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prevent_opponent_run_away(&self, choice: &TurnChoice, prevent: &mut bool) -> Result<()> {
|
||||
fn prevent_opponent_run_away(&self, choice: &Arc<TurnChoice>, prevent: &mut bool) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::PreventOpponentRunAway) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -906,7 +887,7 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_after_held_item_consume(&self, pokemon: &Pokemon, item: &dyn Item) -> Result<()> {
|
||||
fn on_after_held_item_consume(&self, pokemon: &Pokemon, item: &Arc<dyn Item>) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::OnAfterHeldItemConsume) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -960,7 +941,7 @@ impl Script for WebAssemblyScript {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn change_capture_rate_bonus(&self, target: &Pokemon, pokeball: &dyn Item, modifier: &mut u8) -> Result<()> {
|
||||
fn change_capture_rate_bonus(&self, target: &Pokemon, pokeball: &Arc<dyn Item>, modifier: &mut u8) -> Result<()> {
|
||||
if !self.has_capability(&WebAssemblyScriptCapabilities::ChangeCaptureRate) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ use paste::paste;
|
||||
|
||||
use crate::dynamic_data::{Battle, DynamicLibrary, ExecutingMove, Pokemon, TurnChoice};
|
||||
use crate::script_implementations::wasm::export_registry::WasmVoidResult;
|
||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnvironmentData;
|
||||
use crate::static_data::{EffectParameter, Item, TypeIdentifier};
|
||||
use crate::static_data::{Item, TypeIdentifier};
|
||||
use crate::StringKey;
|
||||
use wasmer::{FromToNativeWasmType, TypedFunction};
|
||||
|
||||
@@ -123,7 +123,7 @@ unsafe impl<T> FromToNativeWasmType for WasmPtr<T> {
|
||||
script_function_cache! {
|
||||
stack()
|
||||
on_remove()
|
||||
on_initialize(ExternRef<dyn DynamicLibrary>, VecExternRef<EffectParameter>)
|
||||
on_initialize(ExternRef<dyn DynamicLibrary>, u64)
|
||||
on_before_turn(ExternRef<TurnChoice>)
|
||||
change_speed(ExternRef<TurnChoice>, WasmPtr<u32>)
|
||||
change_priority(ExternRef<TurnChoice>, WasmPtr<i8>)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use std::any::Any;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::mem::{align_of, forget, size_of};
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
use anyhow_ext::{anyhow, ensure, Context, Result};
|
||||
use anyhow_ext::{anyhow, Context, Result};
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use parking_lot::lock_api::RwLockReadGuard;
|
||||
use parking_lot::{RawRwLock, RwLock};
|
||||
@@ -13,7 +12,7 @@ use wasmer::{
|
||||
};
|
||||
|
||||
use crate::dynamic_data::{ItemScript, Script, ScriptOwnerData, ScriptResolver};
|
||||
use crate::script_implementations::wasm::export_registry::register_webassembly_funcs;
|
||||
use crate::script_implementations::wasm::export_registry::{register_webassembly_funcs, WasmObject};
|
||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||
use crate::script_implementations::wasm::script_function_cache::ScriptFunctionCache;
|
||||
@@ -192,7 +191,7 @@ impl ScriptResolver for WebAssemblyScriptResolver {
|
||||
.call(
|
||||
&mut self.store_mut(),
|
||||
category as u8,
|
||||
ExternRef::new_with_resolver(self, script_key),
|
||||
ExternRef::new_with_resolver(self, WasmObject::StringKey(script_key.clone())),
|
||||
)?;
|
||||
self.environment_data.setup_script(script, category, script_key, owner)
|
||||
}
|
||||
@@ -223,7 +222,7 @@ pub struct WebAssemblyEnvironmentData {
|
||||
/// we instead keep track of all the data we've sent to WASM, and pass the ID of that data to WASM. This allows us
|
||||
/// to only operate on data we know WASM owns. We currently store this data in this continuous Vec, and give the index
|
||||
/// of the data as the ID.
|
||||
extern_ref_pointers: RwLock<Vec<*const dyn Any>>,
|
||||
extern_ref_pointers: RwLock<Vec<WasmObject>>,
|
||||
/// To make sure we send the same identifier to WASM when we send the same piece of data multiple times, we have a
|
||||
/// backwards lookup on extern_ref_pointers. This allows us to get the index for a given piece of data.
|
||||
extern_ref_pointers_lookup: RwLock<HashMap<ExternRefLookupKey, usize>>,
|
||||
@@ -269,9 +268,7 @@ pub struct WebAssemblyEnvironmentData {
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
struct ExternRefLookupKey {
|
||||
/// The raw pointer to the data
|
||||
pub ptr: *const dyn Any,
|
||||
/// Whether or not the reference is a Vec
|
||||
pub is_vec: bool,
|
||||
pub obj: WasmObject,
|
||||
}
|
||||
|
||||
impl WebAssemblyEnvironmentData {
|
||||
@@ -387,8 +384,8 @@ impl WebAssemblyEnvironmentData {
|
||||
/// when extern refs get actually properly implemented at compile time we might want to get rid
|
||||
/// of this code.
|
||||
#[inline(always)]
|
||||
pub fn get_extern_ref_index<T: ?Sized>(&self, value: &dyn Any) -> usize {
|
||||
self.get_extern_ref_from_identifier(value, false)
|
||||
pub(crate) fn get_extern_ref_index(&self, value: WasmObject) -> usize {
|
||||
self.get_extern_ref_from_identifier(value)
|
||||
}
|
||||
|
||||
/// Get a numeric value from any given value. This is not a true Extern Ref from WASM, as this
|
||||
@@ -397,15 +394,15 @@ impl WebAssemblyEnvironmentData {
|
||||
/// access can be touched through this, and we ensure the value is the correct type. In the future,
|
||||
/// when extern refs get actually properly implemented at compile time we might want to get rid
|
||||
/// of this code.
|
||||
pub fn get_extern_vec_ref_index<T: 'static>(&self, value: &Vec<T>) -> usize {
|
||||
let mut vec = Vec::with_capacity(value.len());
|
||||
for v in value {
|
||||
vec.push(self.get_extern_ref_index::<T>(v));
|
||||
}
|
||||
let p = self.get_extern_ref_from_identifier(value, true);
|
||||
self.extern_vec_ref_lookup.write().insert(p, vec);
|
||||
p
|
||||
}
|
||||
// pub fn get_extern_vec_ref_index<T: 'static>(&self, value: &Vec<T>) -> usize {
|
||||
// let mut vec = Vec::with_capacity(value.len());
|
||||
// for v in value {
|
||||
// vec.push(self.get_extern_ref_index(v));
|
||||
// }
|
||||
// let p = self.get_extern_ref_from_identifier(value);
|
||||
// self.extern_vec_ref_lookup.write().insert(p, vec);
|
||||
// p
|
||||
// }
|
||||
|
||||
/// Get an extern ref belonging to a vector we have passed to WASM.
|
||||
pub fn get_extern_vec_ref_extern_ref(&self, extern_vec_ref: usize, index: usize) -> Result<usize> {
|
||||
@@ -417,44 +414,37 @@ impl WebAssemblyEnvironmentData {
|
||||
/// Gets the extern ref index belonging to a specific pointer. If none exists, this will create
|
||||
/// a new one.
|
||||
#[inline(always)]
|
||||
fn get_extern_ref_from_identifier(&self, value: &dyn Any, is_vec: bool) -> usize {
|
||||
if let Some(v) = self.extern_ref_pointers_lookup.read().get(&ExternRefLookupKey {
|
||||
ptr: value as *const dyn Any,
|
||||
is_vec,
|
||||
}) {
|
||||
fn get_extern_ref_from_identifier(&self, value: WasmObject) -> usize {
|
||||
if let Some(v) = self
|
||||
.extern_ref_pointers_lookup
|
||||
.read()
|
||||
.get(&ExternRefLookupKey { obj: value.clone() })
|
||||
{
|
||||
return *v;
|
||||
}
|
||||
let index = {
|
||||
let mut extern_ref_guard = self.extern_ref_pointers.write();
|
||||
extern_ref_guard.push(value as *const dyn Any);
|
||||
extern_ref_guard.push(value.clone());
|
||||
extern_ref_guard.len()
|
||||
};
|
||||
self.extern_ref_pointers_lookup.write().insert(
|
||||
ExternRefLookupKey {
|
||||
ptr: value as *const dyn Any,
|
||||
is_vec,
|
||||
},
|
||||
index,
|
||||
);
|
||||
self.extern_ref_type_lookup.write().insert(ExternRefLookupKey {
|
||||
ptr: value as *const dyn Any,
|
||||
is_vec,
|
||||
});
|
||||
self.extern_ref_pointers_lookup
|
||||
.write()
|
||||
.insert(ExternRefLookupKey { obj: value.clone() }, index);
|
||||
self.extern_ref_type_lookup
|
||||
.write()
|
||||
.insert(ExternRefLookupKey { obj: value });
|
||||
index
|
||||
}
|
||||
|
||||
/// Gets a value from the extern ref lookup. This turns an earlier registered index back into
|
||||
/// its proper value, validates its type, and returns the value.
|
||||
pub fn get_extern_ref_value<'a, T: ?Sized>(&self, index: usize) -> Result<&'a dyn Any> {
|
||||
pub(crate) fn get_extern_ref_value<T: ?Sized>(&self, index: usize) -> Result<WasmObject> {
|
||||
let read_guard = self.extern_ref_pointers.read();
|
||||
let ptr = read_guard.get_res(index - 1)?;
|
||||
if self
|
||||
.extern_ref_type_lookup
|
||||
.read()
|
||||
.get(&ExternRefLookupKey {
|
||||
ptr: *ptr,
|
||||
is_vec: false,
|
||||
})
|
||||
.get(&ExternRefLookupKey { obj: ptr.clone() })
|
||||
.is_none()
|
||||
{
|
||||
#[allow(clippy::panic)] // Allow panic here, as this is a security error.
|
||||
@@ -466,17 +456,23 @@ impl WebAssemblyEnvironmentData {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe { Ok(ptr.as_ref().unwrap()) }
|
||||
Ok(ptr.clone())
|
||||
}
|
||||
|
||||
/// The WASM store.
|
||||
pub fn store_ref(&self) -> StoreRef<'_> {
|
||||
unsafe { self.store.as_ref().unwrap().as_store_ref() }
|
||||
#[allow(clippy::unwrap_used)] // This should never be None when used.
|
||||
unsafe {
|
||||
self.store.as_ref().unwrap().as_store_ref()
|
||||
}
|
||||
}
|
||||
|
||||
/// The mutable WASM store.
|
||||
pub fn store_mut(&self) -> StoreMut<'_> {
|
||||
unsafe { self.store.as_mut().unwrap().as_store_mut() }
|
||||
#[allow(clippy::unwrap_used)] // This should never be None when used.
|
||||
unsafe {
|
||||
self.store.as_mut().unwrap().as_store_mut()
|
||||
}
|
||||
}
|
||||
|
||||
/// Find a loaded script based on the pointer in WASM memory.
|
||||
@@ -514,12 +510,16 @@ impl WebAssemblyEnvironmentData {
|
||||
.get::<StringKey>(&"get_script_capabilities".into())
|
||||
{
|
||||
let res = get_cap.call(&mut self.store_mut(), &[Value::I32(script_ptr as i32)])?;
|
||||
let ptr =
|
||||
(self.memory() as *const WebAssemblyScriptCapabilities).offset(res[0].i32().unwrap() as isize);
|
||||
let length = res[1].i32();
|
||||
ensure!(length.is_some(), "Script capabilities length was not a valid i32");
|
||||
for i in 0..length.unwrap() as usize {
|
||||
capabilities.insert(*ptr.add(i));
|
||||
let ptr = (self.memory() as *const WebAssemblyScriptCapabilities)
|
||||
.offset(res.get_res(0)?.unwrap_i32() as isize);
|
||||
let length = res.get_res(1)?.i32();
|
||||
match length {
|
||||
None => return Err(anyhow_ext::anyhow!("Script capabilities length was not a valid i32")),
|
||||
Some(length) => {
|
||||
for i in 0..length as usize {
|
||||
capabilities.insert(*ptr.add(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -529,13 +529,16 @@ impl WebAssemblyEnvironmentData {
|
||||
}
|
||||
|
||||
let read_guard = self.script_capabilities.read();
|
||||
let capabilities = read_guard.get(&key).unwrap();
|
||||
let capabilities = read_guard.get(&key).ok_or(anyhow!("Script capabilities not found"))?;
|
||||
|
||||
#[allow(clippy::unwrap_used)] // This should never be None when used.
|
||||
let environment = { self.self_arc.read().as_ref().unwrap().upgrade().unwrap() };
|
||||
|
||||
let script = Arc::new(WebAssemblyScript::new(
|
||||
owner,
|
||||
script_ptr,
|
||||
capabilities.clone(),
|
||||
self.self_arc.read().as_ref().unwrap().upgrade().unwrap(),
|
||||
environment,
|
||||
script_key.clone(),
|
||||
));
|
||||
|
||||
@@ -558,6 +561,7 @@ impl WebAssemblyEnv {
|
||||
}
|
||||
|
||||
/// Get the actual data belonging to the current context.
|
||||
#[allow(clippy::unwrap_used)] // This should never be None when used.
|
||||
pub fn data(&self) -> Arc<WebAssemblyEnvironmentData> {
|
||||
self.data.upgrade().unwrap()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user