Update to Wasmer 3.0 beta
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
c5fb81c179
commit
bd62c1ac62
|
@ -22,15 +22,6 @@ steps:
|
||||||
- cargo miri test --release --color=always
|
- cargo miri test --release --color=always
|
||||||
depends_on:
|
depends_on:
|
||||||
- test-debug-linux
|
- test-debug-linux
|
||||||
- name: test-address-sanitizer
|
|
||||||
image: deukhoofd/linux64builder
|
|
||||||
environment:
|
|
||||||
RUSTFLAGS: -Zsanitizer=address
|
|
||||||
RUSTDOCFLAGS: -Zsanitizer=address
|
|
||||||
commands:
|
|
||||||
- cargo test -Zbuild-std --target x86_64-unknown-linux-gnu --color=always -- --test-threads=1
|
|
||||||
depends_on:
|
|
||||||
- test-debug-linux
|
|
||||||
- name: test-coverage
|
- name: test-coverage
|
||||||
image: deukhoofd/linux64builder
|
image: deukhoofd/linux64builder
|
||||||
commands:
|
commands:
|
||||||
|
|
|
@ -53,7 +53,7 @@ indexmap = "1.8.2"
|
||||||
parking_lot = "0.12.1"
|
parking_lot = "0.12.1"
|
||||||
conquer-once = "0.3.2"
|
conquer-once = "0.3.2"
|
||||||
serde = { version = "1.0.137", optional = true, features = ["derive"] }
|
serde = { version = "1.0.137", optional = true, features = ["derive"] }
|
||||||
wasmer = { version = "2.3.0", optional = true, default-features = false, features = ["default-cranelift", "universal", "experimental-reference-types-extern-ref"] }
|
wasmer = { version = "3.0.0-beta", optional = true, default-features = true }
|
||||||
unique-type-id = { version = "1.0.0", optional = true }
|
unique-type-id = { version = "1.0.0", optional = true }
|
||||||
unique-type-id-derive = { version = "1.0.0", optional = true }
|
unique-type-id-derive = { version = "1.0.0", optional = true }
|
||||||
paste = { version = "1.0.8" }
|
paste = { version = "1.0.8" }
|
||||||
|
|
|
@ -5,21 +5,22 @@ use crate::script_implementations::wasm::export_registry::register;
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::MoveData;
|
use crate::static_data::MoveData;
|
||||||
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
fn learned_move_get_learn_method(
|
fn learned_move_get_learn_method(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<LearnedMove>,
|
turn_choice: ExternRef<LearnedMove>,
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
unsafe {
|
unsafe {
|
||||||
transmute(turn_choice.value(env).unwrap().learn_method())
|
transmute(turn_choice.value(&env).unwrap().learn_method())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn learned_move_get_move_data(
|
fn learned_move_get_move_data(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<LearnedMove>,
|
turn_choice: ExternRef<LearnedMove>,
|
||||||
) -> ExternRef<MoveData> {
|
) -> ExternRef<MoveData> {
|
||||||
ExternRef::new(env.data().as_ref(), turn_choice.value(env).unwrap().move_data())
|
ExternRef::func_new(&env, turn_choice.value(&env).unwrap().move_data())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::dynamic_data::DynamicLibrary;
|
use crate::dynamic_data::DynamicLibrary;
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::register;
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use wasmer::{Exports, Store};
|
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
||||||
|
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::StaticData;
|
use crate::static_data::StaticData;
|
||||||
|
@ -15,17 +15,17 @@ mod turn_choice;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
fn dynamic_library_get_static_data(
|
fn dynamic_library_get_static_data(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
dynamic_lib: ExternRef<DynamicLibrary>,
|
dynamic_lib: ExternRef<DynamicLibrary>,
|
||||||
) -> ExternRef<StaticData> {
|
) -> ExternRef<StaticData> {
|
||||||
ExternRef::new(env.data().as_ref(), dynamic_lib.value(env).unwrap().static_data())
|
ExternRef::func_new(&env, dynamic_lib.value(&env).unwrap().static_data())
|
||||||
}
|
}
|
||||||
manual manual_register
|
manual manual_register
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional required manual registration
|
/// Additional required manual registration
|
||||||
fn manual_register(exports: &mut Exports, store: &Store, env: WebAssemblyEnv) {
|
fn manual_register(imports: &mut Imports, store: &mut StoreMut, env: &FunctionEnv<WebAssemblyEnv>) {
|
||||||
turn_choice::register(exports, store, env.clone());
|
turn_choice::register(imports, store, env);
|
||||||
pokemon::register(exports, store, env.clone());
|
pokemon::register(imports, store, env);
|
||||||
learned_move::register(exports, store, env);
|
learned_move::register(imports, store, env);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,72 +6,73 @@ use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::StatisticSet;
|
use crate::static_data::StatisticSet;
|
||||||
use crate::static_data::{ClampedStatisticSet, Species};
|
use crate::static_data::{ClampedStatisticSet, Species};
|
||||||
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
fn pokemon_get_library(
|
fn pokemon_get_library(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<DynamicLibrary> {
|
) -> ExternRef<DynamicLibrary> {
|
||||||
let lib = pokemon.value(env).unwrap().library();
|
let lib = pokemon.value(&env).unwrap().library();
|
||||||
ExternRef::new(env.data().as_ref(), lib)
|
ExternRef::func_new(&env, lib)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_boosted_stats(
|
fn pokemon_get_boosted_stats(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<StatisticSet<u32>> {
|
) -> ExternRef<StatisticSet<u32>> {
|
||||||
let statistic_set = pokemon.value(env).unwrap().boosted_stats();
|
let statistic_set = pokemon.value(&env).unwrap().boosted_stats();
|
||||||
ExternRef::new(env.data().as_ref(), statistic_set)
|
ExternRef::func_new(&env, statistic_set)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_flat_stats(
|
fn pokemon_get_flat_stats(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<StatisticSet<u32>> {
|
) -> ExternRef<StatisticSet<u32>> {
|
||||||
let statistic_set = pokemon.value(env).unwrap().flat_stats();
|
let statistic_set = pokemon.value(&env).unwrap().flat_stats();
|
||||||
ExternRef::new(env.data().as_ref(), statistic_set)
|
ExternRef::func_new(&env, statistic_set)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_stat_boosts(
|
fn pokemon_get_stat_boosts(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<ClampedStatisticSet<i8, -6, 6>> {
|
) -> ExternRef<ClampedStatisticSet<i8, -6, 6>> {
|
||||||
let statistic_set = pokemon.value(env).unwrap().stat_boosts();
|
let statistic_set = pokemon.value(&env).unwrap().stat_boosts();
|
||||||
ExternRef::new(env.data().as_ref(), statistic_set)
|
ExternRef::func_new(&env, statistic_set)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_individual_values(
|
fn pokemon_get_individual_values(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<ClampedStatisticSet<u8, 0, 31>> {
|
) -> ExternRef<ClampedStatisticSet<u8, 0, 31>> {
|
||||||
let statistic_set = pokemon.value(env).unwrap().individual_values();
|
let statistic_set = pokemon.value(&env).unwrap().individual_values();
|
||||||
ExternRef::new(env.data().as_ref(), statistic_set)
|
ExternRef::func_new(&env, statistic_set)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_effort_values(
|
fn pokemon_get_effort_values(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<ClampedStatisticSet<u8, 0, 252>> {
|
) -> ExternRef<ClampedStatisticSet<u8, 0, 252>> {
|
||||||
let statistic_set = pokemon.value(env).unwrap().effort_values();
|
let statistic_set = pokemon.value(&env).unwrap().effort_values();
|
||||||
ExternRef::new(env.data().as_ref(), statistic_set)
|
ExternRef::func_new(&env, statistic_set)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_species(
|
fn pokemon_get_species(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> ExternRef<Species> {
|
) -> ExternRef<Species> {
|
||||||
let species = pokemon.value(env).unwrap().species();
|
let species = pokemon.value(&env).unwrap().species();
|
||||||
ExternRef::new(env.data().as_ref(), species)
|
ExternRef::func_new(&env, species)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_damage(
|
fn pokemon_damage(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
damage: u32,
|
damage: u32,
|
||||||
source: u8
|
source: u8
|
||||||
) {
|
) {
|
||||||
unsafe{
|
unsafe{
|
||||||
pokemon.value(env).unwrap().damage(damage, transmute(source));
|
pokemon.value(&env).unwrap().damage(damage, transmute(source));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,22 +4,23 @@ use crate::dynamic_data::{LearnedMove, Pokemon, TurnChoice};
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::register;
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
|
|
||||||
fn turn_choice_get_user(
|
fn turn_choice_get_user(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> ExternRef<Pokemon> {
|
) -> ExternRef<Pokemon> {
|
||||||
let turn_choice = turn_choice.value(env).unwrap();
|
let turn_choice = turn_choice.value(&env).unwrap();
|
||||||
ExternRef::new(env.data().as_ref(), turn_choice.user().as_ref().deref())
|
ExternRef::func_new(&env, turn_choice.user().as_ref().deref())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_get_kind(
|
fn turn_choice_get_kind(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
match turn_choice.value(env).unwrap() {
|
match turn_choice.value(&env).unwrap() {
|
||||||
TurnChoice::Move(_) => 0,
|
TurnChoice::Move(_) => 0,
|
||||||
TurnChoice::Item(_) => 1,
|
TurnChoice::Item(_) => 1,
|
||||||
TurnChoice::Switch(_) => 2,
|
TurnChoice::Switch(_) => 2,
|
||||||
|
@ -29,30 +30,30 @@ register! {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_move_used_move(
|
fn turn_choice_move_used_move(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> ExternRef<LearnedMove> {
|
) -> ExternRef<LearnedMove> {
|
||||||
if let TurnChoice::Move(d) = turn_choice.value(env).unwrap() {
|
if let TurnChoice::Move(d) = turn_choice.value(&env).unwrap() {
|
||||||
return ExternRef::new(env.data().as_ref(), d.used_move().as_ref());
|
return ExternRef::func_new(&env, d.used_move().as_ref());
|
||||||
}
|
}
|
||||||
panic!("Invalid turn choice");
|
panic!("Invalid turn choice");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_move_target_side(
|
fn turn_choice_move_target_side(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
if let TurnChoice::Move(d) = turn_choice.value(env).unwrap() {
|
if let TurnChoice::Move(d) = turn_choice.value(&env).unwrap() {
|
||||||
return d.target_side();
|
return d.target_side();
|
||||||
}
|
}
|
||||||
panic!("Invalid turn choice");
|
panic!("Invalid turn choice");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_move_target_index(
|
fn turn_choice_move_target_index(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
if let TurnChoice::Move(d) = turn_choice.value(env).unwrap() {
|
if let TurnChoice::Move(d) = turn_choice.value(&env).unwrap() {
|
||||||
return d.target_index();
|
return d.target_index();
|
||||||
}
|
}
|
||||||
panic!("Invalid turn choice");
|
panic!("Invalid turn choice");
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::mem::{align_of, forget};
|
use std::mem::{align_of, forget};
|
||||||
|
|
||||||
use wasmer::{Exports, Store};
|
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
||||||
|
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
@ -14,19 +14,12 @@ mod dynamic_data;
|
||||||
mod static_data;
|
mod static_data;
|
||||||
|
|
||||||
/// Register a single function.
|
/// Register a single function.
|
||||||
#[allow(unused_macros)]
|
|
||||||
macro_rules! register_func {
|
|
||||||
($exports: ident, $store: ident, $func: ident) => {
|
|
||||||
$exports.insert(stringify!($func), Function::new_native($store, $func));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register a single function that requires environment data.
|
|
||||||
macro_rules! register_func_with_env {
|
macro_rules! register_func_with_env {
|
||||||
($exports: ident, $store: ident, $func: ident, $env: expr) => {
|
($imports: ident, $store: ident, $func: ident, $env: expr) => {
|
||||||
$exports.insert(
|
$imports.define(
|
||||||
|
"env",
|
||||||
stringify!($func),
|
stringify!($func),
|
||||||
wasmer::Function::new_native_with_env($store, $env.clone(), $func),
|
wasmer::Function::new_typed_with_env($store, $env, $func),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -41,19 +34,22 @@ macro_rules! register {
|
||||||
manual $manual_name:ident
|
manual $manual_name:ident
|
||||||
)?
|
)?
|
||||||
) => {
|
) => {
|
||||||
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(
|
fn $name(
|
||||||
$(
|
$(
|
||||||
$par: $par_type,
|
$par: $par_type,
|
||||||
)*
|
)*
|
||||||
) $(-> $return)* $block
|
) $(-> $return)* $block
|
||||||
crate::script_implementations::wasm::export_registry::register_func_with_env!(exports, store, $name, env);
|
|
||||||
)*
|
)*
|
||||||
$( $manual_name(exports, store, env) )*
|
|
||||||
|
pub(crate) fn register(imports: &mut wasmer::Imports,
|
||||||
|
store: &mut wasmer::StoreMut,
|
||||||
|
env: &wasmer::FunctionEnv<crate::script_implementations::wasm::script_resolver::WebAssemblyEnv>) {
|
||||||
|
$(
|
||||||
|
crate::script_implementations::wasm::export_registry::register_func_with_env!(imports, store, $name, env);
|
||||||
|
)*
|
||||||
|
$( $manual_name(imports, store, env) )*
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -62,27 +58,31 @@ pub(crate) use register;
|
||||||
pub(crate) use register_func_with_env;
|
pub(crate) use register_func_with_env;
|
||||||
|
|
||||||
/// Register the functions we expose to WASM.
|
/// Register the functions we expose to WASM.
|
||||||
pub(crate) fn register_webassembly_funcs(exports: &mut Exports, store: &Store, env: WebAssemblyEnv) {
|
pub(crate) fn register_webassembly_funcs(
|
||||||
register_func_with_env!(exports, store, _print, env);
|
imports: &mut Imports,
|
||||||
register_func_with_env!(exports, store, _error, env);
|
store: &mut StoreMut,
|
||||||
register_func_with_env!(exports, store, _vec_extern_ref_get_value, env);
|
env: &FunctionEnv<WebAssemblyEnv>,
|
||||||
|
) {
|
||||||
|
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(exports, store, env.clone());
|
static_data::register(imports, store, env);
|
||||||
dynamic_data::register(exports, store, env.clone());
|
dynamic_data::register(imports, store, env);
|
||||||
|
|
||||||
register_func_with_env!(exports, store, string_key_get_hash, env);
|
register_func_with_env!(imports, store, string_key_get_hash, env);
|
||||||
register_func_with_env!(exports, store, string_key_get_str, env);
|
register_func_with_env!(imports, store, string_key_get_str, env);
|
||||||
register_func_with_env!(exports, store, effect_parameter_get_type, env);
|
register_func_with_env!(imports, store, effect_parameter_get_type, env);
|
||||||
register_func_with_env!(exports, store, effect_parameter_as_bool, env);
|
register_func_with_env!(imports, store, effect_parameter_as_bool, env);
|
||||||
register_func_with_env!(exports, store, effect_parameter_as_int, env);
|
register_func_with_env!(imports, store, effect_parameter_as_int, env);
|
||||||
register_func_with_env!(exports, store, effect_parameter_as_float, env);
|
register_func_with_env!(imports, store, effect_parameter_as_float, env);
|
||||||
register_func_with_env!(exports, store, effect_parameter_as_string, env);
|
register_func_with_env!(imports, store, effect_parameter_as_string, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Logging function for WASM.
|
/// Logging function for WASM.
|
||||||
fn _print(env: &WebAssemblyEnv, p: u32, len: u32) {
|
fn _print(env: FunctionEnvMut<WebAssemblyEnv>, p: u32, len: u32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mem: *mut u8 = env.data().memory().data_ptr().offset(p as isize);
|
let mem: *mut u8 = env.data().data().memory().offset(p as isize);
|
||||||
let s = String::from_raw_parts(mem, len as usize, len as usize);
|
let s = String::from_raw_parts(mem, len as usize, len as usize);
|
||||||
println!("{}", s);
|
println!("{}", s);
|
||||||
forget(s);
|
forget(s);
|
||||||
|
@ -91,11 +91,19 @@ fn _print(env: &WebAssemblyEnv, p: u32, len: u32) {
|
||||||
|
|
||||||
/// Triggers when WASM panics.
|
/// Triggers when WASM panics.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn _error(env: &WebAssemblyEnv, message: u32, message_len: u32, file: u32, file_len: u32, line: u32, position: u32) {
|
fn _error(
|
||||||
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
|
message: u32,
|
||||||
|
message_len: u32,
|
||||||
|
file: u32,
|
||||||
|
file_len: u32,
|
||||||
|
line: u32,
|
||||||
|
position: u32,
|
||||||
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mem: *mut u8 = env.data().memory().data_ptr().offset(message as isize);
|
let mem: *mut u8 = env.data().data().memory().offset(message as isize);
|
||||||
let message_str = 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 mem: *mut u8 = env.data().data().memory().offset(file as isize);
|
||||||
let file_str = String::from_raw_parts(mem, file_len as usize, file_len as usize);
|
let file_str = String::from_raw_parts(mem, file_len as usize, file_len as usize);
|
||||||
panic!(
|
panic!(
|
||||||
"Error: {} in file {}, line: {}:{}",
|
"Error: {} in file {}, line: {}:{}",
|
||||||
|
@ -105,20 +113,21 @@ fn _error(env: &WebAssemblyEnv, message: u32, message_len: u32, file: u32, file_
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a single item from an earlier passed VecExternRef
|
/// Get a single item from an earlier passed VecExternRef
|
||||||
fn _vec_extern_ref_get_value(env: &WebAssemblyEnv, reference: u32, index: u32) -> u32 {
|
fn _vec_extern_ref_get_value(env: FunctionEnvMut<WebAssemblyEnv>, reference: u32, index: u32) -> u32 {
|
||||||
env.data().get_extern_vec_ref_extern_ref(reference, index)
|
env.data().data().get_extern_vec_ref_extern_ref(reference, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the hash value of a StringKey.
|
/// Gets the hash value of a StringKey.
|
||||||
fn string_key_get_hash(env: &WebAssemblyEnv, string_key: ExternRef<StringKey>) -> u32 {
|
fn string_key_get_hash(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> u32 {
|
||||||
string_key.value(env).unwrap().hash()
|
string_key.value(&env).unwrap().hash()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a null-terminated C string from a StringKey. Note that this involves a copy into WASM
|
/// Get a null-terminated C string from a StringKey. Note that this involves a copy into WASM
|
||||||
/// memory, so this is relatively heavy.
|
/// memory, so this is relatively heavy.
|
||||||
fn string_key_get_str(env: &WebAssemblyEnv, string_key: ExternRef<StringKey>) -> u32 {
|
fn string_key_get_str(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> u32 {
|
||||||
let string_key = string_key.value(env).unwrap().str();
|
let string_key = string_key.value(&env).unwrap().str();
|
||||||
let wasm_string_ptr = env
|
let wasm_string_ptr = env
|
||||||
|
.data()
|
||||||
.data()
|
.data()
|
||||||
.allocate_mem((string_key.len() + 1) as u32, align_of::<CString>() as u32);
|
.allocate_mem((string_key.len() + 1) as u32, align_of::<CString>() as u32);
|
||||||
let mut wasm_string: Vec<u8> =
|
let mut wasm_string: Vec<u8> =
|
||||||
|
@ -131,8 +140,8 @@ fn string_key_get_str(env: &WebAssemblyEnv, string_key: ExternRef<StringKey>) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the type of an EffectParameter
|
/// Gets the type of an EffectParameter
|
||||||
fn effect_parameter_get_type(env: &WebAssemblyEnv, parameter: ExternRef<EffectParameter>) -> u8 {
|
fn effect_parameter_get_type(env: FunctionEnvMut<WebAssemblyEnv>, parameter: ExternRef<EffectParameter>) -> u8 {
|
||||||
let v = parameter.value(env).unwrap();
|
let v = parameter.value(&env).unwrap();
|
||||||
match v {
|
match v {
|
||||||
EffectParameter::Bool(_) => 1,
|
EffectParameter::Bool(_) => 1,
|
||||||
EffectParameter::Int(_) => 2,
|
EffectParameter::Int(_) => 2,
|
||||||
|
@ -142,8 +151,8 @@ fn effect_parameter_get_type(env: &WebAssemblyEnv, parameter: ExternRef<EffectPa
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inner bool data of an EffectParameter. Panics if it's not a bool.
|
/// Gets the inner bool data of an EffectParameter. Panics if it's not a bool.
|
||||||
fn effect_parameter_as_bool(env: &WebAssemblyEnv, parameter: ExternRef<EffectParameter>) -> u8 {
|
fn effect_parameter_as_bool(env: FunctionEnvMut<WebAssemblyEnv>, parameter: ExternRef<EffectParameter>) -> u8 {
|
||||||
let v = parameter.value(env).unwrap();
|
let v = parameter.value(&env).unwrap();
|
||||||
match v {
|
match v {
|
||||||
EffectParameter::Bool(b) => {
|
EffectParameter::Bool(b) => {
|
||||||
if *b {
|
if *b {
|
||||||
|
@ -157,8 +166,8 @@ fn effect_parameter_as_bool(env: &WebAssemblyEnv, parameter: ExternRef<EffectPar
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inner int data of an EffectParameter. Panics if it's not an int.
|
/// Gets the inner int data of an EffectParameter. Panics if it's not an int.
|
||||||
fn effect_parameter_as_int(env: &WebAssemblyEnv, parameter: ExternRef<EffectParameter>) -> i64 {
|
fn effect_parameter_as_int(env: FunctionEnvMut<WebAssemblyEnv>, parameter: ExternRef<EffectParameter>) -> i64 {
|
||||||
let v = parameter.value(env).unwrap();
|
let v = parameter.value(&env).unwrap();
|
||||||
match v {
|
match v {
|
||||||
EffectParameter::Int(i) => *i,
|
EffectParameter::Int(i) => *i,
|
||||||
_ => panic!("Unexpected parameter type!"),
|
_ => panic!("Unexpected parameter type!"),
|
||||||
|
@ -166,8 +175,8 @@ fn effect_parameter_as_int(env: &WebAssemblyEnv, parameter: ExternRef<EffectPara
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inner float data of an EffectParameter. Panics if it's not a float.
|
/// Gets the inner float data of an EffectParameter. Panics if it's not a float.
|
||||||
fn effect_parameter_as_float(env: &WebAssemblyEnv, parameter: ExternRef<EffectParameter>) -> f32 {
|
fn effect_parameter_as_float(env: FunctionEnvMut<WebAssemblyEnv>, parameter: ExternRef<EffectParameter>) -> f32 {
|
||||||
let v = parameter.value(env).unwrap();
|
let v = parameter.value(&env).unwrap();
|
||||||
match v {
|
match v {
|
||||||
EffectParameter::Float(f) => *f,
|
EffectParameter::Float(f) => *f,
|
||||||
_ => panic!("Unexpected parameter type!"),
|
_ => panic!("Unexpected parameter type!"),
|
||||||
|
@ -175,10 +184,13 @@ fn effect_parameter_as_float(env: &WebAssemblyEnv, parameter: ExternRef<EffectPa
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inner string data of an EffectParameter. Panics if it's not a string.
|
/// Gets the inner string data of an EffectParameter. Panics if it's not a string.
|
||||||
fn effect_parameter_as_string(env: &WebAssemblyEnv, parameter: ExternRef<EffectParameter>) -> ExternRef<StringKey> {
|
fn effect_parameter_as_string(
|
||||||
let v = parameter.value(env).unwrap();
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
|
parameter: ExternRef<EffectParameter>,
|
||||||
|
) -> ExternRef<StringKey> {
|
||||||
|
let v = parameter.value(&env).unwrap();
|
||||||
match v {
|
match v {
|
||||||
EffectParameter::String(s) => ExternRef::new(env.data().as_ref(), s),
|
EffectParameter::String(s) => ExternRef::func_new(&env, s),
|
||||||
_ => panic!("Unexpected parameter type!"),
|
_ => panic!("Unexpected parameter type!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use wasmer::{Exports, Store};
|
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
||||||
|
|
||||||
use crate::defines::LevelInt;
|
use crate::defines::LevelInt;
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::register;
|
||||||
|
@ -12,41 +12,41 @@ mod moves;
|
||||||
mod species;
|
mod species;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
fn static_data_get_move_library(env: &WebAssemblyEnv, data_library: ExternRef<StaticData>) -> ExternRef<MoveLibrary> {
|
fn static_data_get_move_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<StaticData>) -> ExternRef<MoveLibrary> {
|
||||||
ExternRef::new(env.data().as_ref(), data_library.value(env).unwrap().moves())
|
ExternRef::func_new(&env, data_library.value(&env).unwrap().moves())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn static_data_get_species_library(
|
fn static_data_get_species_library(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
data_library: ExternRef<StaticData>,
|
data_library: ExternRef<StaticData>,
|
||||||
) -> ExternRef<SpeciesLibrary> {
|
) -> ExternRef<SpeciesLibrary> {
|
||||||
ExternRef::new(env.data().as_ref(), data_library.value(env).unwrap().species())
|
ExternRef::func_new(&env, data_library.value(&env).unwrap().species())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn static_data_get_item_library(env: &WebAssemblyEnv, data_library: ExternRef<StaticData>) -> ExternRef<ItemLibrary> {
|
fn static_data_get_item_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<StaticData>) -> ExternRef<ItemLibrary> {
|
||||||
ExternRef::new(env.data().as_ref(), data_library.value(env).unwrap().items())
|
ExternRef::func_new(&env, data_library.value(&env).unwrap().items())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn static_data_get_type_library(env: &WebAssemblyEnv, data_library: ExternRef<StaticData>) -> ExternRef<TypeLibrary> {
|
fn static_data_get_type_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<StaticData>) -> ExternRef<TypeLibrary> {
|
||||||
ExternRef::new(env.data().as_ref(), data_library.value(env).unwrap().types())
|
ExternRef::func_new(&env, data_library.value(&env).unwrap().types())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn static_data_get_library_settings(
|
fn static_data_get_library_settings(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
data_library: ExternRef<StaticData>,
|
data_library: ExternRef<StaticData>,
|
||||||
) -> ExternRef<LibrarySettings> {
|
) -> ExternRef<LibrarySettings> {
|
||||||
ExternRef::new(env.data().as_ref(), data_library.value(env).unwrap().settings())
|
ExternRef::func_new(&env, data_library.value(&env).unwrap().settings())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn library_settings_get_maximum_level(env: &WebAssemblyEnv, data_library: ExternRef<LibrarySettings>) -> LevelInt {
|
fn library_settings_get_maximum_level(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<LibrarySettings>) -> LevelInt {
|
||||||
data_library.value(env).unwrap().maximum_level()
|
data_library.value(&env).unwrap().maximum_level()
|
||||||
}
|
}
|
||||||
|
|
||||||
manual manual_registration
|
manual manual_registration
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional required manual registration.
|
/// Additional required manual registration.
|
||||||
fn manual_registration(exports: &mut Exports, store: &Store, env: WebAssemblyEnv) {
|
fn manual_registration(imports: &mut Imports, store: &mut StoreMut, env: &FunctionEnv<WebAssemblyEnv>) {
|
||||||
moves::register(exports, store, env.clone());
|
moves::register(imports, store, env);
|
||||||
species::register(exports, store, env);
|
species::register(imports, store, env);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,66 +3,67 @@ use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::{DataLibrary, MoveData, MoveLibrary};
|
use crate::static_data::{DataLibrary, MoveData, MoveLibrary};
|
||||||
use crate::StringKey;
|
use crate::StringKey;
|
||||||
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
fn move_library_get_move(
|
fn move_library_get_move(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
lib: ExternRef<MoveLibrary>,
|
lib: ExternRef<MoveLibrary>,
|
||||||
string_key: ExternRef<StringKey>,
|
string_key: ExternRef<StringKey>,
|
||||||
) -> ExternRef<MoveData> {
|
) -> ExternRef<MoveData> {
|
||||||
let lib = lib.value(env).unwrap();
|
let lib = lib.value(&env).unwrap();
|
||||||
let m = lib.get(string_key.value(env).unwrap());
|
let m = lib.get(string_key.value(&env).unwrap());
|
||||||
if let Some(v) = m {
|
if let Some(v) = m {
|
||||||
ExternRef::new(env.data().as_ref(), v)
|
ExternRef::func_new(&env, v)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_library_get_move_by_hash(env: &WebAssemblyEnv, lib: ExternRef<MoveLibrary>, hash: u32) -> ExternRef<MoveData> {
|
fn move_library_get_move_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, lib: ExternRef<MoveLibrary>, hash: u32) -> ExternRef<MoveData> {
|
||||||
let lib = lib.value(env).unwrap();
|
let lib = lib.value(&env).unwrap();
|
||||||
let m = lib.get_by_hash(hash);
|
let m = lib.get_by_hash(hash);
|
||||||
if let Some(v) = m {
|
if let Some(v) = m {
|
||||||
ExternRef::new(env.data().as_ref(), v)
|
ExternRef::func_new(&env, v)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_data_get_name(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> ExternRef<StringKey> {
|
fn move_data_get_name(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>) -> ExternRef<StringKey> {
|
||||||
ExternRef::new(env.data().as_ref(), move_data.value(env).unwrap().name())
|
ExternRef::func_new(&env, move_data.value(&env).unwrap().name())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_data_get_type(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
|
fn move_data_get_type(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>) -> u8 {
|
||||||
move_data.value(env).unwrap().move_type().into()
|
move_data.value(&env).unwrap().move_type().into()
|
||||||
}
|
}
|
||||||
fn move_data_get_category(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
|
fn move_data_get_category(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>) -> u8 {
|
||||||
move_data.value(env).unwrap().category() as u8
|
move_data.value(&env).unwrap().category() as u8
|
||||||
}
|
}
|
||||||
fn move_data_get_base_power(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
|
fn move_data_get_base_power(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>) -> u8 {
|
||||||
move_data.value(env).unwrap().base_power()
|
move_data.value(&env).unwrap().base_power()
|
||||||
}
|
}
|
||||||
fn move_data_get_accuracy(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
|
fn move_data_get_accuracy(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>) -> u8 {
|
||||||
move_data.value(env).unwrap().accuracy()
|
move_data.value(&env).unwrap().accuracy()
|
||||||
}
|
}
|
||||||
fn move_data_get_base_usages(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
|
fn move_data_get_base_usages(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>) -> u8 {
|
||||||
move_data.value(env).unwrap().base_usages()
|
move_data.value(&env).unwrap().base_usages()
|
||||||
}
|
}
|
||||||
fn move_data_get_target(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
|
fn move_data_get_target(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>) -> u8 {
|
||||||
move_data.value(env).unwrap().target() as u8
|
move_data.value(&env).unwrap().target() as u8
|
||||||
}
|
}
|
||||||
fn move_data_get_priority(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> i8 {
|
fn move_data_get_priority(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>) -> i8 {
|
||||||
move_data.value(env).unwrap().priority()
|
move_data.value(&env).unwrap().priority()
|
||||||
}
|
}
|
||||||
fn move_data_has_flag(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>, flag: ExternRef<StringKey>) -> u8 {
|
fn move_data_has_flag(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>, flag: ExternRef<StringKey>) -> u8 {
|
||||||
if move_data.value(env).unwrap().has_flag(flag.value(env).unwrap()) {
|
if move_data.value(&env).unwrap().has_flag(flag.value(&env).unwrap()) {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn move_data_has_flag_by_hash(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>, flag_hash: u32) -> u8 {
|
fn move_data_has_flag_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, move_data: ExternRef<MoveData>, flag_hash: u32) -> u8 {
|
||||||
if move_data.value(env).unwrap().has_flag_by_hash(flag_hash) {
|
if move_data.value(&env).unwrap().has_flag_by_hash(flag_hash) {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
|
|
|
@ -3,58 +3,59 @@ use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::{DataLibrary, Species, SpeciesLibrary};
|
use crate::static_data::{DataLibrary, Species, SpeciesLibrary};
|
||||||
use crate::StringKey;
|
use crate::StringKey;
|
||||||
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
|
|
||||||
fn species_library_get_species(
|
fn species_library_get_species(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
lib: ExternRef<SpeciesLibrary>,
|
lib: ExternRef<SpeciesLibrary>,
|
||||||
string_key: ExternRef<StringKey>,
|
string_key: ExternRef<StringKey>,
|
||||||
) -> ExternRef<Species> {
|
) -> ExternRef<Species> {
|
||||||
let lib = lib.value(env).unwrap();
|
let lib = lib.value(&env).unwrap();
|
||||||
let m = lib.get(string_key.value(env).unwrap());
|
let m = lib.get(string_key.value(&env).unwrap());
|
||||||
if let Some(v) = m {
|
if let Some(v) = m {
|
||||||
ExternRef::new(env.data().as_ref(), v)
|
ExternRef::func_new(&env, v)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn species_get_capture_rate(
|
fn species_get_capture_rate(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
species: ExternRef<Species>,
|
species: ExternRef<Species>,
|
||||||
) -> u8 {
|
) -> u8 {
|
||||||
species.value(env).unwrap().capture_rate()
|
species.value(&env).unwrap().capture_rate()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn species_get_growth_rate(
|
fn species_get_growth_rate(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
species: ExternRef<Species>,
|
species: ExternRef<Species>,
|
||||||
) -> ExternRef<StringKey> {
|
) -> ExternRef<StringKey> {
|
||||||
let species = species.value(env).unwrap();
|
let species = species.value(&env).unwrap();
|
||||||
ExternRef::new(env.data().as_ref(), species.growth_rate())
|
ExternRef::func_new(&env, species.growth_rate())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn species_get_gender_rate(
|
fn species_get_gender_rate(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
species: ExternRef<Species>,
|
species: ExternRef<Species>,
|
||||||
) -> f32 {
|
) -> f32 {
|
||||||
species.value(env).unwrap().gender_rate()
|
species.value(&env).unwrap().gender_rate()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn species_get_name(
|
fn species_get_name(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
species: ExternRef<Species>,
|
species: ExternRef<Species>,
|
||||||
) -> ExternRef<StringKey> {
|
) -> ExternRef<StringKey> {
|
||||||
let species = species.value(env).unwrap();
|
let species = species.value(&env).unwrap();
|
||||||
ExternRef::new(env.data().as_ref(), species.name())
|
ExternRef::func_new(&env, species.name())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn species_get_id(
|
fn species_get_id(
|
||||||
env: &WebAssemblyEnv,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
species: ExternRef<Species>,
|
species: ExternRef<Species>,
|
||||||
) -> u16 {
|
) -> u16 {
|
||||||
species.value(env).unwrap().id()
|
species.value(&env).unwrap().id()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
|
|
||||||
use unique_type_id::UniqueTypeId;
|
|
||||||
use wasmer::FromToNativeWasmType;
|
|
||||||
|
|
||||||
use crate::script_implementations::wasm::script_resolver::{
|
use crate::script_implementations::wasm::script_resolver::{
|
||||||
WebAssemblyEnv, WebAssemblyEnvironmentData, WebAssemblyScriptResolver,
|
WebAssemblyEnv, WebAssemblyEnvironmentData, WebAssemblyScriptResolver,
|
||||||
};
|
};
|
||||||
|
use unique_type_id::UniqueTypeId;
|
||||||
|
use wasmer::FromToNativeWasmType;
|
||||||
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
/// An Extern Ref allows us to pass objects to WASM without actually passing raw memory, or
|
/// An Extern Ref allows us to pass objects to WASM without actually passing raw memory, or
|
||||||
/// requiring us to make copies. Instead, we pass a simple increment index, that we can then use
|
/// requiring us to make copies. Instead, we pass a simple increment index, that we can then use
|
||||||
|
@ -28,6 +28,15 @@ impl<T: UniqueTypeId<u64>> ExternRef<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Instantiates a new ExternRef for a bit of data using the function environment. If we already
|
||||||
|
/// have made an Extern Ref for this data and type, we use that instead.
|
||||||
|
pub fn func_new(env: &FunctionEnvMut<WebAssemblyEnv>, value: &T) -> Self {
|
||||||
|
Self {
|
||||||
|
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.
|
/// Creates an ExternRef with a given resolver. This can be used in cases where we do not have an environment variable.
|
||||||
pub(crate) fn new_with_resolver(resolver: &WebAssemblyScriptResolver, value: &T) -> Self {
|
pub(crate) fn new_with_resolver(resolver: &WebAssemblyScriptResolver, value: &T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -46,8 +55,8 @@ impl<T: UniqueTypeId<u64>> ExternRef<T> {
|
||||||
|
|
||||||
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
/// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the
|
||||||
/// value when it was passed before. If these types do not match, this will panic.
|
/// value when it was passed before. If these types do not match, this will panic.
|
||||||
pub fn value<'a, 'b>(&'a self, env: &'b WebAssemblyEnv) -> Option<&'b T> {
|
pub fn value<'a, 'b>(&'a self, env: &'b FunctionEnvMut<WebAssemblyEnv>) -> Option<&'b T> {
|
||||||
let ptr = env.data().get_extern_ref_value(self.index) as *const T;
|
let ptr = env.data().data().get_extern_ref_value(self.index) as *const T;
|
||||||
unsafe { ptr.as_ref() }
|
unsafe { ptr.as_ref() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ impl Script for WebAssemblyScript {
|
||||||
let env = self.environment.upgrade().unwrap();
|
let env = self.environment.upgrade().unwrap();
|
||||||
let func = env.script_function_cache().stack(&env);
|
let func = env.script_function_cache().stack(&env);
|
||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
func.call(self.self_ptr).unwrap();
|
func.call(&mut env.store_mut(), self.self_ptr).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ impl Script for WebAssemblyScript {
|
||||||
let env = self.environment.upgrade().unwrap();
|
let env = self.environment.upgrade().unwrap();
|
||||||
let func = env.script_function_cache().on_remove(&env);
|
let func = env.script_function_cache().on_remove(&env);
|
||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
func.call(self.self_ptr).unwrap();
|
func.call(&mut env.store_mut(), self.self_ptr).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@ impl Script for WebAssemblyScript {
|
||||||
let func = env.script_function_cache().on_initialize(&env);
|
let func = env.script_function_cache().on_initialize(&env);
|
||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
func.call(
|
func.call(
|
||||||
|
&mut env.store_mut(),
|
||||||
self.self_ptr,
|
self.self_ptr,
|
||||||
ExternRef::new(env.as_ref(), library),
|
ExternRef::new(env.as_ref(), library),
|
||||||
VecExternRef::new(env.as_ref(), pars),
|
VecExternRef::new(env.as_ref(), pars),
|
||||||
|
@ -112,7 +113,12 @@ impl Script for WebAssemblyScript {
|
||||||
let env = self.environment.upgrade().unwrap();
|
let env = self.environment.upgrade().unwrap();
|
||||||
let func = env.script_function_cache().on_before_turn(&env);
|
let func = env.script_function_cache().on_before_turn(&env);
|
||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
func.call(self.self_ptr, ExternRef::new(env.as_ref(), choice)).unwrap();
|
func.call(
|
||||||
|
&mut env.store_mut(),
|
||||||
|
self.self_ptr,
|
||||||
|
ExternRef::new(env.as_ref(), choice),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +131,12 @@ impl Script for WebAssemblyScript {
|
||||||
let func = env.script_function_cache().change_speed(&env);
|
let func = env.script_function_cache().change_speed(&env);
|
||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
let ptr = env.temp_allocate_mem_typed::<u32>(*speed);
|
let ptr = env.temp_allocate_mem_typed::<u32>(*speed);
|
||||||
func.call(self.self_ptr, ExternRef::new(env.as_ref(), choice), ptr.wasm_pointer)
|
func.call(
|
||||||
|
&mut env.store_mut(),
|
||||||
|
self.self_ptr,
|
||||||
|
ExternRef::new(env.as_ref(), choice),
|
||||||
|
ptr.wasm_pointer,
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
*speed = *ptr.value();
|
*speed = *ptr.value();
|
||||||
}
|
}
|
||||||
|
@ -143,7 +154,12 @@ impl Script for WebAssemblyScript {
|
||||||
let func = env.script_function_cache().change_priority(&env);
|
let func = env.script_function_cache().change_priority(&env);
|
||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
let ptr = env.temp_allocate_mem_typed::<i8>(*priority);
|
let ptr = env.temp_allocate_mem_typed::<i8>(*priority);
|
||||||
func.call(self.self_ptr, ExternRef::new(env.as_ref(), choice), ptr.wasm_pointer)
|
func.call(
|
||||||
|
&mut env.store_mut(),
|
||||||
|
self.self_ptr,
|
||||||
|
ExternRef::new(env.as_ref(), choice),
|
||||||
|
ptr.wasm_pointer,
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
*priority = *ptr.value();
|
*priority = *ptr.value();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
use wasmer::NativeFunc;
|
|
||||||
|
|
||||||
use crate::dynamic_data::{DynamicLibrary, TurnChoice};
|
use crate::dynamic_data::{DynamicLibrary, TurnChoice};
|
||||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnvironmentData;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnvironmentData;
|
||||||
use crate::static_data::EffectParameter;
|
use crate::static_data::EffectParameter;
|
||||||
use crate::StringKey;
|
use crate::StringKey;
|
||||||
|
use wasmer::TypedFunction;
|
||||||
|
|
||||||
/// A macro to generate the script function cache a bit easier.
|
/// A macro to generate the script function cache a bit easier.
|
||||||
macro_rules! script_function_cache {
|
macro_rules! script_function_cache {
|
||||||
|
@ -21,7 +21,7 @@ macro_rules! script_function_cache {
|
||||||
#[allow(unused_parens)]
|
#[allow(unused_parens)]
|
||||||
pub struct ScriptFunctionCache {
|
pub struct ScriptFunctionCache {
|
||||||
$(
|
$(
|
||||||
$name: RwLock<Option<NativeFunc<(u32$(, $par_type)*), ()>>>,
|
$name: RwLock<Option<TypedFunction<(u32$(, $par_type)*), ()>>>,
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ macro_rules! script_function_cache {
|
||||||
let exported = env.exported_functions();
|
let exported = env.exported_functions();
|
||||||
let f = exported.get::<StringKey>(&stringify!([< script_ $name >]).into());
|
let f = exported.get::<StringKey>(&stringify!([< script_ $name >]).into());
|
||||||
if let Some(f) = f {
|
if let Some(f) = f {
|
||||||
let func: NativeFunc<(u32 $(,$par_type)*), ()> = f.native().unwrap();
|
let func: TypedFunction<(u32 $(,$par_type)*), ()> = f.typed(&env.store_ref()).unwrap();
|
||||||
let _ = self.$name.write().insert(func);
|
let _ = self.$name.write().insert(func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ macro_rules! script_function_cache {
|
||||||
pub(crate) fn [<$name>](
|
pub(crate) fn [<$name>](
|
||||||
&self,
|
&self,
|
||||||
env: &Arc<WebAssemblyEnvironmentData>,
|
env: &Arc<WebAssemblyEnvironmentData>,
|
||||||
) -> Option<NativeFunc<(u32 $(,$par_type)*), ()>> {
|
) -> Option<TypedFunction<(u32 $(,$par_type)*), ()>> {
|
||||||
{
|
{
|
||||||
let read_lock = self.$name.read();
|
let read_lock = self.$name.read();
|
||||||
if let Some(f) = read_lock.as_ref() {
|
if let Some(f) = read_lock.as_ref() {
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::mem::{align_of, size_of};
|
use std::mem::{align_of, forget, size_of};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use parking_lot::lock_api::{MappedRwLockReadGuard, RwLockReadGuard};
|
use parking_lot::lock_api::RwLockReadGuard;
|
||||||
use parking_lot::{RawRwLock, RwLock};
|
use parking_lot::{RawRwLock, RwLock};
|
||||||
use unique_type_id::UniqueTypeId;
|
use unique_type_id::UniqueTypeId;
|
||||||
use wasmer::{
|
use wasmer::{
|
||||||
Cranelift, Exports, Extern, Features, Function, ImportObject, Instance, Memory, Module, NativeFunc, Store,
|
AsStoreMut, AsStoreRef, Cranelift, EngineBuilder, Extern, Features, Function, FunctionEnv, Imports, Instance,
|
||||||
Universal, Value, WasmerEnv,
|
Memory, Module, Store, StoreMut, StoreRef, TypedFunction, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::dynamic_data::{ItemScript, Script, ScriptResolver};
|
use crate::dynamic_data::{ItemScript, Script, ScriptResolver};
|
||||||
|
@ -24,7 +24,7 @@ use crate::{PkmnResult, ScriptCategory, StringKey};
|
||||||
/// A WebAssembly script resolver implements the dynamic scripts functionality with WebAssembly.
|
/// A WebAssembly script resolver implements the dynamic scripts functionality with WebAssembly.
|
||||||
pub struct WebAssemblyScriptResolver {
|
pub struct WebAssemblyScriptResolver {
|
||||||
/// The global state storage of WASM.
|
/// The global state storage of WASM.
|
||||||
store: Store,
|
_store: *mut Store,
|
||||||
/// The WASM modules we have loaded.
|
/// The WASM modules we have loaded.
|
||||||
modules: Vec<Module>,
|
modules: Vec<Module>,
|
||||||
/// Our currently loaded WASM instances. Empty until finalize() is called, after which the loaded modules get turned
|
/// Our currently loaded WASM instances. Empty until finalize() is called, after which the loaded modules get turned
|
||||||
|
@ -32,7 +32,7 @@ pub struct WebAssemblyScriptResolver {
|
||||||
instances: Vec<Instance>,
|
instances: Vec<Instance>,
|
||||||
|
|
||||||
/// This is the WASM function to load a script.
|
/// This is the WASM function to load a script.
|
||||||
load_script_fn: Option<NativeFunc<(u8, ExternRef<StringKey>), u32>>,
|
load_script_fn: Option<TypedFunction<(u8, ExternRef<StringKey>), u32>>,
|
||||||
|
|
||||||
/// Script capabilities tell us which functions are implemented on a given script. This allows us to skip unneeded
|
/// Script capabilities tell us which functions are implemented on a given script. This allows us to skip unneeded
|
||||||
/// WASM calls.
|
/// WASM calls.
|
||||||
|
@ -54,39 +54,55 @@ struct ScriptCapabilitiesKey {
|
||||||
impl WebAssemblyScriptResolver {
|
impl WebAssemblyScriptResolver {
|
||||||
/// Instantiates a new WebAssemblyScriptResolver.
|
/// Instantiates a new WebAssemblyScriptResolver.
|
||||||
pub fn new() -> Box<WebAssemblyScriptResolver> {
|
pub fn new() -> Box<WebAssemblyScriptResolver> {
|
||||||
let config = Cranelift::default();
|
let compiler = Cranelift::default();
|
||||||
let mut features = Features::new();
|
let mut features = Features::new();
|
||||||
features.multi_value = true;
|
features.multi_value = true;
|
||||||
features.reference_types = true;
|
features.reference_types = true;
|
||||||
let universal = Universal::new(config).features(features);
|
let engine = EngineBuilder::new(compiler).set_features(Some(features));
|
||||||
let engine = universal.engine();
|
let mut store = Box::new(Store::new(engine));
|
||||||
let store = Store::new(&engine);
|
let store_ptr: *mut Store = store.as_mut();
|
||||||
|
forget(store);
|
||||||
|
|
||||||
let s = Self {
|
let s = Self {
|
||||||
store,
|
_store: store_ptr,
|
||||||
modules: Default::default(),
|
modules: Default::default(),
|
||||||
instances: Default::default(),
|
instances: Default::default(),
|
||||||
load_script_fn: None,
|
load_script_fn: None,
|
||||||
script_capabilities: Default::default(),
|
script_capabilities: Default::default(),
|
||||||
environment_data: Arc::new(Default::default()),
|
environment_data: Arc::new(WebAssemblyEnvironmentData::new(store_ptr)),
|
||||||
};
|
};
|
||||||
|
|
||||||
Box::new(s)
|
Box::new(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get an immutable reference to the current WASM Store.
|
||||||
|
fn store_ref(&self) -> StoreRef<'_> {
|
||||||
|
unsafe { self._store.as_ref().unwrap().as_store_ref() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a mutable reference to the current WASM Store.
|
||||||
|
fn store_mut(&self) -> StoreMut<'_> {
|
||||||
|
unsafe { self._store.as_mut().unwrap().as_store_mut() }
|
||||||
|
}
|
||||||
|
|
||||||
/// Load a compiled WASM module.
|
/// Load a compiled WASM module.
|
||||||
pub fn load_wasm_from_bytes(&mut self, bytes: &[u8]) {
|
pub fn load_wasm_from_bytes(&mut self, bytes: &[u8]) {
|
||||||
// FIXME: Error handling
|
// FIXME: Error handling
|
||||||
let module = Module::new(&self.store, bytes).unwrap();
|
let module = Module::new(&self.store_ref(), bytes).unwrap();
|
||||||
self.modules.push(module);
|
self.modules.push(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialise all the data we need.
|
/// Initialise all the data we need.
|
||||||
pub fn finalize(&mut self) {
|
pub fn finalize(&mut self) {
|
||||||
let mut imports = ImportObject::new();
|
let mut imports = Imports::new();
|
||||||
let mut exports = Exports::new();
|
//let mut exports = Exports::new();
|
||||||
|
|
||||||
let env = WebAssemblyEnv::new(Arc::downgrade(&self.environment_data));
|
let env = FunctionEnv::new(
|
||||||
register_webassembly_funcs(&mut exports, &self.store, env);
|
&mut self.store_mut(),
|
||||||
imports.register("env", exports);
|
WebAssemblyEnv::new(Arc::downgrade(&self.environment_data)),
|
||||||
|
);
|
||||||
|
register_webassembly_funcs(&mut imports, &mut self.store_mut(), &env);
|
||||||
|
//imports.register("env", exports);
|
||||||
|
|
||||||
for module in &self.modules {
|
for module in &self.modules {
|
||||||
for import in module.imports() {
|
for import in module.imports() {
|
||||||
|
@ -99,12 +115,12 @@ impl WebAssemblyScriptResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let instance = Instance::new(module, &imports).unwrap();
|
let instance = Instance::new(&mut self.store_mut(), module, &imports).unwrap();
|
||||||
let exports = &instance.exports;
|
let exports = &instance.exports;
|
||||||
|
|
||||||
let init_fn = exports.get_extern("_init");
|
let init_fn = exports.get_extern("_init");
|
||||||
if let Some(Extern::Function(init_fn)) = init_fn {
|
if let Some(Extern::Function(init_fn)) = init_fn {
|
||||||
init_fn.call(&[]).unwrap();
|
init_fn.call(&mut self.store_mut(), &[]).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut exported_functions = self.environment_data.exported_functions.write();
|
let mut exported_functions = self.environment_data.exported_functions.write();
|
||||||
|
@ -120,17 +136,17 @@ impl WebAssemblyScriptResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(m) = &self.environment_data.memory.read().as_ref() {
|
if let Some(m) = &self.environment_data.memory.read().as_ref() {
|
||||||
m.grow(32).unwrap();
|
m.grow(&mut self.store_mut(), 32).unwrap();
|
||||||
}
|
}
|
||||||
if let Some(f) = exported_functions.get::<StringKey>(&"load_script".into()) {
|
if let Some(f) = exported_functions.get::<StringKey>(&"load_script".into()) {
|
||||||
self.load_script_fn = Some(f.native().unwrap())
|
self.load_script_fn = Some(f.typed(&self.store_ref()).unwrap())
|
||||||
}
|
}
|
||||||
if let Some(f) = exported_functions.get::<StringKey>(&"allocate_mem".into()) {
|
if let Some(f) = exported_functions.get::<StringKey>(&"allocate_mem".into()) {
|
||||||
let _ = self
|
let _ = self
|
||||||
.environment_data
|
.environment_data
|
||||||
.allocate_mem_fn
|
.allocate_mem_fn
|
||||||
.write()
|
.write()
|
||||||
.insert(f.native().unwrap());
|
.insert(f.typed(&self.store_ref()).unwrap());
|
||||||
|
|
||||||
let temp_memory_slab = self.environment_data.allocate_mem(128, 1);
|
let temp_memory_slab = self.environment_data.allocate_mem(128, 1);
|
||||||
let _ = self
|
let _ = self
|
||||||
|
@ -160,7 +176,11 @@ impl ScriptResolver for WebAssemblyScriptResolver {
|
||||||
.load_script_fn
|
.load_script_fn
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.call(category as u8, ExternRef::new_with_resolver(self, script_key))
|
.call(
|
||||||
|
&mut self.store_mut(),
|
||||||
|
category as u8,
|
||||||
|
ExternRef::new_with_resolver(self, script_key),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if script == 0 {
|
if script == 0 {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
@ -180,9 +200,10 @@ impl ScriptResolver for WebAssemblyScriptResolver {
|
||||||
.read()
|
.read()
|
||||||
.get::<StringKey>(&"get_script_capabilities".into())
|
.get::<StringKey>(&"get_script_capabilities".into())
|
||||||
{
|
{
|
||||||
let res = get_cap.call(&[Value::I32(script as i32)]).unwrap();
|
let res = get_cap
|
||||||
let ptr = (self.environment_data.memory.read().as_ref().unwrap().data_ptr()
|
.call(&mut self.store_mut(), &[Value::I32(script as i32)])
|
||||||
as *const WebAssemblyScriptCapabilities)
|
.unwrap();
|
||||||
|
let ptr = (self.environment_data.memory() as *const WebAssemblyScriptCapabilities)
|
||||||
.offset(res[0].i32().unwrap() as isize);
|
.offset(res[0].i32().unwrap() as isize);
|
||||||
let length = res[1].i32().unwrap() as usize;
|
let length = res[1].i32().unwrap() as usize;
|
||||||
for i in 0..length {
|
for i in 0..length {
|
||||||
|
@ -218,8 +239,15 @@ impl Debug for WebAssemblyScriptResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for WebAssemblyScriptResolver {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
drop(Box::from_raw(self._store));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This data is what is passed to every function that requires access to the global runtime context.
|
/// This data is what is passed to every function that requires access to the global runtime context.
|
||||||
#[derive(Default)]
|
|
||||||
pub struct WebAssemblyEnvironmentData {
|
pub struct WebAssemblyEnvironmentData {
|
||||||
/// We currently have a hacky implementation of extern refs while we're waiting for ExternRef support to hit the
|
/// We currently have a hacky implementation of extern refs while we're waiting for ExternRef support to hit the
|
||||||
/// wasm32-unknown-unknown target of Rust. As we don't want to pass raw memory pointers to WASM for security reasons,
|
/// wasm32-unknown-unknown target of Rust. As we don't want to pass raw memory pointers to WASM for security reasons,
|
||||||
|
@ -248,10 +276,13 @@ pub struct WebAssemblyEnvironmentData {
|
||||||
script_function_cache: ScriptFunctionCache,
|
script_function_cache: ScriptFunctionCache,
|
||||||
|
|
||||||
/// This is the WASM function to allocate memory inside the WASM container.
|
/// This is the WASM function to allocate memory inside the WASM container.
|
||||||
allocate_mem_fn: RwLock<Option<NativeFunc<(u32, u32), u32>>>,
|
allocate_mem_fn: RwLock<Option<TypedFunction<(u32, u32), u32>>>,
|
||||||
|
|
||||||
/// An allocator for quick short lifetime allocations within WASM.
|
/// An allocator for quick short lifetime allocations within WASM.
|
||||||
temp_allocator: RwLock<Option<TempWasmAllocator>>,
|
temp_allocator: RwLock<Option<TempWasmAllocator>>,
|
||||||
|
|
||||||
|
/// The WASM store.
|
||||||
|
store: *mut Store,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A quick lookup so we can find the extern ref of the value.
|
/// A quick lookup so we can find the extern ref of the value.
|
||||||
|
@ -266,9 +297,25 @@ struct ExternRefLookupKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebAssemblyEnvironmentData {
|
impl WebAssemblyEnvironmentData {
|
||||||
|
/// Instantiates new Environment data with a given store.
|
||||||
|
pub(crate) fn new(store: *mut Store) -> Self {
|
||||||
|
Self {
|
||||||
|
extern_ref_pointers: Default::default(),
|
||||||
|
extern_ref_pointers_lookup: Default::default(),
|
||||||
|
extern_ref_type_lookup: Default::default(),
|
||||||
|
extern_vec_ref_lookup: Default::default(),
|
||||||
|
memory: Default::default(),
|
||||||
|
exported_functions: Default::default(),
|
||||||
|
script_function_cache: Default::default(),
|
||||||
|
allocate_mem_fn: Default::default(),
|
||||||
|
temp_allocator: Default::default(),
|
||||||
|
store,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This returns the memory of the WASM container.
|
/// This returns the memory of the WASM container.
|
||||||
pub fn memory(&self) -> MappedRwLockReadGuard<'_, RawRwLock, Memory> {
|
pub fn memory(&self) -> *mut u8 {
|
||||||
RwLockReadGuard::map(self.memory.read(), |a| a.as_ref().unwrap())
|
self.memory.read().as_ref().unwrap().view(&self.store_ref()).data_ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This returns the functions exported from WASM.
|
/// This returns the functions exported from WASM.
|
||||||
|
@ -286,18 +333,14 @@ impl WebAssemblyEnvironmentData {
|
||||||
/// The return is a tuple containing both the actual pointer to the memory (usable by the host),
|
/// The return is a tuple containing both the actual pointer to the memory (usable by the host),
|
||||||
/// and the WASM offset to the memory (usable by the client).
|
/// and the WASM offset to the memory (usable by the client).
|
||||||
pub fn allocate_mem(&self, size: u32, align: u32) -> (*mut u8, u32) {
|
pub fn allocate_mem(&self, size: u32, align: u32) -> (*mut u8, u32) {
|
||||||
let wasm_ptr = self.allocate_mem_fn.read().as_ref().unwrap().call(size, align).unwrap();
|
let wasm_ptr = self
|
||||||
unsafe {
|
.allocate_mem_fn
|
||||||
(
|
|
||||||
self.memory
|
|
||||||
.read()
|
.read()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.data_ptr()
|
.call(&mut self.store_mut(), size, align)
|
||||||
.offset(wasm_ptr as isize),
|
.unwrap();
|
||||||
wasm_ptr,
|
unsafe { (self.memory().offset(wasm_ptr as isize), wasm_ptr) }
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocates memory inside the WASM container with a given size and alignment. This memory is
|
/// Allocates memory inside the WASM container with a given size and alignment. This memory is
|
||||||
|
@ -310,19 +353,9 @@ impl WebAssemblyEnvironmentData {
|
||||||
.read()
|
.read()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.call(size_of::<T>() as u32, align_of::<T>() as u32)
|
.call(&mut self.store_mut(), size_of::<T>() as u32, align_of::<T>() as u32)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
unsafe {
|
unsafe { (self.memory().offset(wasm_ptr as isize), wasm_ptr) }
|
||||||
(
|
|
||||||
self.memory
|
|
||||||
.read()
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.data_ptr()
|
|
||||||
.offset(wasm_ptr as isize),
|
|
||||||
wasm_ptr,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate a piece of memory inside WASM with a very short lifespan. This is mainly used for
|
/// Allocate a piece of memory inside WASM with a very short lifespan. This is mainly used for
|
||||||
|
@ -419,6 +452,16 @@ impl WebAssemblyEnvironmentData {
|
||||||
|
|
||||||
unsafe { (*ptr as *const T).as_ref().unwrap() }
|
unsafe { (*ptr as *const T).as_ref().unwrap() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The WASM store.
|
||||||
|
pub fn store_ref(&self) -> StoreRef<'_> {
|
||||||
|
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() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The runtime environment for script execution. This is passed to most of the host functions being called.
|
/// The runtime environment for script execution. This is passed to most of the host functions being called.
|
||||||
|
@ -447,5 +490,3 @@ unsafe impl Send for WebAssemblyEnv {}
|
||||||
unsafe impl Sync for WebAssemblyEnvironmentData {}
|
unsafe impl Sync for WebAssemblyEnvironmentData {}
|
||||||
|
|
||||||
unsafe impl Send for WebAssemblyEnvironmentData {}
|
unsafe impl Send for WebAssemblyEnvironmentData {}
|
||||||
|
|
||||||
impl WasmerEnv for WebAssemblyEnv {}
|
|
||||||
|
|
Loading…
Reference in New Issue