More work on WASM handling.
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2022-08-20 12:22:12 +02:00
parent 703fd2c147
commit 2d4253e155
36 changed files with 922 additions and 87 deletions

View File

@@ -0,0 +1,25 @@
use std::intrinsics::transmute;
use crate::dynamic_data::{LearnedMove, MoveLearnMethod, Pokemon, TurnChoice};
use crate::script_implementations::wasm::export_registry::register;
use crate::script_implementations::wasm::extern_ref::ExternRef;
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
use crate::static_data::MoveData;
register! {
fn learned_move_get_learn_method<'a>(
env: &WebAssemblyEnv,
turn_choice: ExternRef<LearnedMove>,
) -> u8 {
unsafe {
transmute(turn_choice.value(env).unwrap().learn_method())
}
}
fn learned_move_get_move_data<'a>(
env: &WebAssemblyEnv,
turn_choice: ExternRef<LearnedMove>,
) -> ExternRef<MoveData> {
ExternRef::new(env.data().as_ref(), turn_choice.value(env).unwrap().move_data())
}
}

View File

@@ -0,0 +1,13 @@
use wasmer::{Exports, Store};
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
mod learned_move;
mod pokemon;
mod turn_choice;
pub(crate) fn register(exports: &mut Exports, store: &Store, env: WebAssemblyEnv) {
turn_choice::register(exports, store, env.clone());
pokemon::register(exports, store, env.clone());
learned_move::register(exports, store, env.clone());
}

View File

@@ -0,0 +1,77 @@
use std::mem::transmute;
use crate::dynamic_data::{DamageSource, DynamicLibrary, Pokemon};
use crate::script_implementations::wasm::export_registry::register;
use crate::script_implementations::wasm::extern_ref::ExternRef;
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
use crate::static_data::StatisticSet;
use crate::static_data::{ClampedStatisticSet, Species};
register! {
fn pokemon_get_library(
env: &WebAssemblyEnv,
pokemon: ExternRef<Pokemon>,
) -> ExternRef<DynamicLibrary> {
let lib = pokemon.value(env).unwrap().library();
ExternRef::new(env.data().as_ref(), lib)
}
fn pokemon_get_boosted_stats(
env: &WebAssemblyEnv,
pokemon: ExternRef<Pokemon>,
) -> ExternRef<StatisticSet<u32>> {
let statistic_set = pokemon.value(env).unwrap().boosted_stats();
ExternRef::new(env.data().as_ref(), statistic_set)
}
fn pokemon_get_flat_stats(
env: &WebAssemblyEnv,
pokemon: ExternRef<Pokemon>,
) -> ExternRef<StatisticSet<u32>> {
let statistic_set = pokemon.value(env).unwrap().flat_stats();
ExternRef::new(env.data().as_ref(), statistic_set)
}
fn pokemon_get_stat_boosts(
env: &WebAssemblyEnv,
pokemon: ExternRef<Pokemon>,
) -> ExternRef<ClampedStatisticSet<i8, -6, 6>> {
let statistic_set = pokemon.value(env).unwrap().stat_boosts();
ExternRef::new(env.data().as_ref(), statistic_set)
}
fn pokemon_get_individual_values(
env: &WebAssemblyEnv,
pokemon: ExternRef<Pokemon>,
) -> ExternRef<ClampedStatisticSet<u8, 0, 31>> {
let statistic_set = pokemon.value(env).unwrap().individual_values();
ExternRef::new(env.data().as_ref(), statistic_set)
}
fn pokemon_get_effort_values(
env: &WebAssemblyEnv,
pokemon: ExternRef<Pokemon>,
) -> ExternRef<ClampedStatisticSet<u8, 0, 252>> {
let statistic_set = pokemon.value(env).unwrap().effort_values();
ExternRef::new(env.data().as_ref(), statistic_set)
}
fn pokemon_get_species(
env: &WebAssemblyEnv,
pokemon: ExternRef<Pokemon>,
) -> ExternRef<Species> {
let species = pokemon.value(env).unwrap().species();
ExternRef::new(env.data().as_ref(), species)
}
fn pokemon_damage(
env: &WebAssemblyEnv,
pokemon: ExternRef<Pokemon>,
damage: u32,
source: u8
) {
unsafe{
pokemon.value(env).unwrap().damage(damage, transmute(source));
}
}
}

View File

@@ -0,0 +1,61 @@
use std::ops::Deref;
use crate::dynamic_data::{LearnedMove, Pokemon, TurnChoice};
use crate::script_implementations::wasm::export_registry::register;
use crate::script_implementations::wasm::extern_ref::ExternRef;
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
register! {
fn turn_choice_get_user<'a>(
env: &WebAssemblyEnv,
turn_choice: ExternRef<TurnChoice<'a, 'a>>,
) -> ExternRef<Pokemon<'a, 'a>> {
let turn_choice = turn_choice.value(env).unwrap();
ExternRef::new(env.data().as_ref(), turn_choice.user().as_ref().deref())
}
fn turn_choice_get_kind(
env: &WebAssemblyEnv,
turn_choice: ExternRef<TurnChoice>,
) -> u8 {
match turn_choice.value(env).unwrap() {
TurnChoice::Move(_) => 0,
TurnChoice::Item(_) => 1,
TurnChoice::Switch(_) => 2,
TurnChoice::Flee(_) => 3,
TurnChoice::Pass(_) => 4,
}
}
fn turn_choice_move_used_move<'a>(
env: &WebAssemblyEnv,
turn_choice: ExternRef<TurnChoice<'a, 'a>>,
) -> ExternRef<LearnedMove<'a>> {
if let TurnChoice::Move(d) = turn_choice.value(env).unwrap() {
return ExternRef::new(env.data().as_ref(), d.used_move().as_ref());
}
panic!("Invalid turn choice");
}
fn turn_choice_move_target_side(
env: &WebAssemblyEnv,
turn_choice: ExternRef<TurnChoice>,
) -> u8 {
if let TurnChoice::Move(d) = turn_choice.value(env).unwrap() {
return d.target_side();
}
panic!("Invalid turn choice");
}
fn turn_choice_move_target_index(
env: &WebAssemblyEnv,
turn_choice: ExternRef<TurnChoice>,
) -> u8 {
if let TurnChoice::Move(d) = turn_choice.value(env).unwrap() {
return d.target_index();
}
panic!("Invalid turn choice");
}
}

View File

@@ -1,14 +1,21 @@
use std::ffi::CString;
use std::mem::{align_of, forget};
use std::process::exit;
use wasmer::{Exports, Function, Store};
use wasmer::{Exports, Store};
pub(crate) use register;
pub(crate) use register_func_with_env;
use crate::dynamic_data::DynamicLibrary;
use crate::script_implementations::wasm::extern_ref::ExternRef;
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
use crate::static_data::{DataLibrary, MoveData, MoveLibrary, StaticData};
use crate::static_data::{EffectParameter, StaticData};
use crate::StringKey;
mod dynamic_data;
mod static_data;
#[allow(unused_macros)]
macro_rules! register_func {
($exports: ident, $store: ident, $func: ident) => {
@@ -20,21 +27,50 @@ macro_rules! register_func_with_env {
($exports: ident, $store: ident, $func: ident, $env: expr) => {
$exports.insert(
stringify!($func),
Function::new_native_with_env($store, $env.clone(), $func),
wasmer::Function::new_native_with_env($store, $env.clone(), $func),
);
};
}
macro_rules! register {
(
$(
fn $name:ident$(<$($lt:lifetime)*>)?($($par:ident: $par_type:ty),*$(,)?) $(-> $return:ty)? $block:block
)*
) => {
pub(crate) fn register(exports: &mut crate::script_implementations::wasm::export_registry::Exports,
store: &crate::script_implementations::wasm::export_registry::Store,
env: crate::script_implementations::wasm::script_resolver::WebAssemblyEnv) {
$(
fn $name<$($($lt)*)*>(
$(
$par: $par_type,
)*
) $(-> $return)* $block
crate::script_implementations::wasm::export_registry::register_func_with_env!(exports, store, $name, env);
)*
}
};
}
pub(crate) fn register_webassembly_funcs(exports: &mut Exports, store: &Store, env: WebAssemblyEnv) {
register_func_with_env!(exports, store, _print, env);
register_func_with_env!(exports, store, _error, env);
register_func_with_env!(exports, store, move_library_get_move_by_hash, env);
register_func_with_env!(exports, store, move_data_get_name, env);
register_func_with_env!(exports, store, move_data_get_base_power, env);
register_func_with_env!(exports, store, const_string_get_hash, env);
register_func_with_env!(exports, store, const_string_get_str, env);
register_func_with_env!(exports, store, battle_library_get_data_library, env);
register_func_with_env!(exports, store, data_library_get_move_library, env);
register_func_with_env!(exports, store, _vec_extern_ref_get_value, env);
static_data::register(exports, store, env.clone());
dynamic_data::register(exports, store, env.clone());
register_func_with_env!(exports, store, string_key_get_hash, env);
register_func_with_env!(exports, store, string_key_get_str, env);
register_func_with_env!(exports, store, dynamic_library_get_static_data, env);
register_func_with_env!(exports, store, effect_parameter_get_type, env);
register_func_with_env!(exports, store, effect_parameter_as_bool, env);
register_func_with_env!(exports, store, effect_parameter_as_int, env);
register_func_with_env!(exports, store, effect_parameter_as_float, env);
register_func_with_env!(exports, store, effect_parameter_as_string, env);
}
fn _print(env: &WebAssemblyEnv, p: u32, len: u32) {
@@ -46,42 +82,29 @@ fn _print(env: &WebAssemblyEnv, p: u32, len: u32) {
}
}
#[track_caller]
fn _error(env: &WebAssemblyEnv, message: u32, message_len: u32, file: u32, file_len: u32, line: u32, position: u32) {
unsafe {
let mem: *mut u8 = env.data().memory().data_ptr().offset(message as isize);
let message = String::from_raw_parts(mem, message_len as usize, message_len as usize);
let message_str = String::from_raw_parts(mem, message_len as usize, message_len as usize);
let mem: *mut u8 = env.data().memory().data_ptr().offset(file as isize);
let file = String::from_raw_parts(mem, file_len as usize, file_len as usize);
println!("Error: {} in file {}, line: {}:{}", message, file, line, position);
forget(message);
forget(file);
let file_str = String::from_raw_parts(mem, file_len as usize, file_len as usize);
panic!(
"Error: {} in file {}, line: {}:{}",
message_str, file_str, line, position
);
}
}
fn move_library_get_move_by_hash(env: &WebAssemblyEnv, lib: ExternRef<MoveLibrary>, hash: u32) -> ExternRef<MoveData> {
let lib = lib.value(env).unwrap();
let m = lib.get_by_hash(hash);
if let Some(v) = m {
ExternRef::new(env.data().as_ref(), v)
} else {
ExternRef::null()
}
fn _vec_extern_ref_get_value(env: &WebAssemblyEnv, reference: u32, index: u32) -> u32 {
env.data().get_extern_vec_ref_extern_ref(reference, index)
}
fn move_data_get_name(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> ExternRef<StringKey> {
let move_data = move_data.value(env).unwrap();
ExternRef::new(env.data().as_ref(), move_data.name())
}
fn move_data_get_base_power(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
move_data.value(env).unwrap().base_power()
}
fn const_string_get_hash(env: &WebAssemblyEnv, string_key: ExternRef<StringKey>) -> u32 {
fn string_key_get_hash(env: &WebAssemblyEnv, string_key: ExternRef<StringKey>) -> u32 {
string_key.value(env).unwrap().hash()
}
fn const_string_get_str(env: &WebAssemblyEnv, string_key: ExternRef<StringKey>) -> u32 {
fn string_key_get_str(env: &WebAssemblyEnv, string_key: ExternRef<StringKey>) -> u32 {
let string_key = string_key.value(env).unwrap().str();
let wasm_string_ptr = env
.data()
@@ -95,13 +118,57 @@ fn const_string_get_str(env: &WebAssemblyEnv, string_key: ExternRef<StringKey>)
wasm_string_ptr.1
}
fn battle_library_get_data_library(
fn dynamic_library_get_static_data(
env: &WebAssemblyEnv,
dynamic_lib: ExternRef<DynamicLibrary>,
) -> ExternRef<StaticData> {
ExternRef::new(env.data().as_ref(), dynamic_lib.value(env).unwrap().static_data())
}
fn data_library_get_move_library(env: &WebAssemblyEnv, data_library: ExternRef<StaticData>) -> ExternRef<MoveLibrary> {
ExternRef::new(env.data().as_ref(), data_library.value(env).unwrap().moves())
fn effect_parameter_get_type(env: &WebAssemblyEnv, parameter: ExternRef<EffectParameter>) -> u8 {
let v = parameter.value(env).unwrap();
match v {
EffectParameter::Bool(_) => 1,
EffectParameter::Int(_) => 2,
EffectParameter::Float(_) => 3,
EffectParameter::String(_) => 4,
}
}
fn effect_parameter_as_bool(env: &WebAssemblyEnv, parameter: ExternRef<EffectParameter>) -> u8 {
let v = parameter.value(env).unwrap();
match v {
EffectParameter::Bool(b) => {
if *b {
1
} else {
0
}
}
_ => panic!("Unexpected parameter type!"),
}
}
fn effect_parameter_as_int(env: &WebAssemblyEnv, parameter: ExternRef<EffectParameter>) -> i64 {
let v = parameter.value(env).unwrap();
match v {
EffectParameter::Int(i) => *i,
_ => panic!("Unexpected parameter type!"),
}
}
fn effect_parameter_as_float(env: &WebAssemblyEnv, parameter: ExternRef<EffectParameter>) -> f32 {
let v = parameter.value(env).unwrap();
match v {
EffectParameter::Float(f) => *f,
_ => panic!("Unexpected parameter type!"),
}
}
fn effect_parameter_as_string(env: &WebAssemblyEnv, parameter: ExternRef<EffectParameter>) -> ExternRef<StringKey> {
let v = parameter.value(env).unwrap();
match v {
EffectParameter::String(s) => ExternRef::new(env.data().as_ref(), s),
_ => panic!("Unexpected parameter type!"),
}
}

View File

@@ -0,0 +1,52 @@
use wasmer::{Exports, Store};
use crate::defines::LevelInt;
use crate::script_implementations::wasm::export_registry::register_func_with_env;
use crate::script_implementations::wasm::extern_ref::ExternRef;
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
use crate::static_data::{ItemLibrary, LibrarySettings, MoveLibrary, SpeciesLibrary, StaticData, TypeLibrary};
mod moves;
mod species;
pub(crate) fn register(exports: &mut Exports, store: &Store, env: WebAssemblyEnv) {
register_func_with_env!(exports, store, static_data_get_move_library, env);
register_func_with_env!(exports, store, static_data_get_species_library, env);
register_func_with_env!(exports, store, static_data_get_item_library, env);
register_func_with_env!(exports, store, static_data_get_type_library, env);
register_func_with_env!(exports, store, static_data_get_library_settings, env);
register_func_with_env!(exports, store, library_settings_get_maximum_level, env);
moves::register(exports, store, env.clone());
species::register(exports, store, env.clone());
}
fn static_data_get_move_library(env: &WebAssemblyEnv, data_library: ExternRef<StaticData>) -> ExternRef<MoveLibrary> {
ExternRef::new(env.data().as_ref(), data_library.value(env).unwrap().moves())
}
fn static_data_get_species_library(
env: &WebAssemblyEnv,
data_library: ExternRef<StaticData>,
) -> ExternRef<SpeciesLibrary> {
ExternRef::new(env.data().as_ref(), data_library.value(env).unwrap().species())
}
fn static_data_get_item_library(env: &WebAssemblyEnv, data_library: ExternRef<StaticData>) -> ExternRef<ItemLibrary> {
ExternRef::new(env.data().as_ref(), data_library.value(env).unwrap().items())
}
fn static_data_get_type_library(env: &WebAssemblyEnv, data_library: ExternRef<StaticData>) -> ExternRef<TypeLibrary> {
ExternRef::new(env.data().as_ref(), data_library.value(env).unwrap().types())
}
fn static_data_get_library_settings(
env: &WebAssemblyEnv,
data_library: ExternRef<StaticData>,
) -> ExternRef<LibrarySettings> {
ExternRef::new(env.data().as_ref(), data_library.value(env).unwrap().settings())
}
fn library_settings_get_maximum_level(env: &WebAssemblyEnv, data_library: ExternRef<LibrarySettings>) -> LevelInt {
data_library.value(env).unwrap().maximum_level()
}

View File

@@ -0,0 +1,71 @@
use crate::script_implementations::wasm::export_registry::register;
use crate::script_implementations::wasm::extern_ref::ExternRef;
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
use crate::static_data::{DataLibrary, MoveData, MoveLibrary};
use crate::StringKey;
register! {
fn move_library_get_move(
env: &WebAssemblyEnv,
lib: ExternRef<MoveLibrary>,
string_key: ExternRef<StringKey>,
) -> ExternRef<MoveData> {
let lib = lib.value(env).unwrap();
let m = lib.get(string_key.value(env).unwrap());
if let Some(v) = m {
ExternRef::new(env.data().as_ref(), v)
} else {
ExternRef::null()
}
}
fn move_library_get_move_by_hash(env: &WebAssemblyEnv, lib: ExternRef<MoveLibrary>, hash: u32) -> ExternRef<MoveData> {
let lib = lib.value(env).unwrap();
let m = lib.get_by_hash(hash);
if let Some(v) = m {
ExternRef::new(env.data().as_ref(), v)
} else {
ExternRef::null()
}
}
fn move_data_get_name(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> ExternRef<StringKey> {
ExternRef::new(env.data().as_ref(), move_data.value(env).unwrap().name())
}
fn move_data_get_type(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
move_data.value(env).unwrap().move_type().into()
}
fn move_data_get_category(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
move_data.value(env).unwrap().category() as u8
}
fn move_data_get_base_power(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
move_data.value(env).unwrap().base_power()
}
fn move_data_get_accuracy(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
move_data.value(env).unwrap().accuracy()
}
fn move_data_get_base_usages(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
move_data.value(env).unwrap().base_usages()
}
fn move_data_get_target(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
move_data.value(env).unwrap().target() as u8
}
fn move_data_get_priority(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> i8 {
move_data.value(env).unwrap().priority()
}
fn move_data_has_flag(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>, flag: ExternRef<StringKey>) -> u8 {
if move_data.value(env).unwrap().has_flag(flag.value(env).unwrap()) {
1
} else {
0
}
}
fn move_data_has_flag_by_hash(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>, flag_hash: u32) -> u8 {
if move_data.value(env).unwrap().has_flag_by_hash(flag_hash) {
1
} else {
0
}
}
}

View File

@@ -0,0 +1,61 @@
use crate::script_implementations::wasm::export_registry::register;
use crate::script_implementations::wasm::extern_ref::ExternRef;
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
use crate::static_data::{DataLibrary, Species, SpeciesLibrary};
use crate::StringKey;
register! {
fn species_library_get_species(
env: &WebAssemblyEnv,
lib: ExternRef<SpeciesLibrary>,
string_key: ExternRef<StringKey>,
) -> ExternRef<Species> {
let lib = lib.value(env).unwrap();
let m = lib.get(string_key.value(env).unwrap());
if let Some(v) = m {
ExternRef::new(env.data().as_ref(), v)
} else {
ExternRef::null()
}
}
fn species_get_capture_rate(
env: &WebAssemblyEnv,
species: ExternRef<Species>,
) -> u8 {
species.value(env).unwrap().capture_rate()
}
fn species_get_growth_rate(
env: &WebAssemblyEnv,
species: ExternRef<Species>,
) -> ExternRef<StringKey> {
let species = species.value(env).unwrap();
ExternRef::new(env.data().as_ref(), species.growth_rate())
}
fn species_get_gender_rate(
env: &WebAssemblyEnv,
species: ExternRef<Species>,
) -> f32 {
species.value(env).unwrap().gender_rate()
}
fn species_get_name(
env: &WebAssemblyEnv,
species: ExternRef<Species>,
) -> ExternRef<StringKey> {
let species = species.value(env).unwrap();
ExternRef::new(env.data().as_ref(), species.name())
}
fn species_get_id(
env: &WebAssemblyEnv,
species: ExternRef<Species>,
) -> u16 {
species.value(env).unwrap().id()
}
}