PkmnLib_rs/src/script_implementations/wasm/export_registry/mod.rs

102 lines
3.9 KiB
Rust
Raw Normal View History

2022-07-18 08:16:47 +00:00
use core::ffi::c_char;
use std::ffi::CString;
2022-07-18 08:49:58 +00:00
use std::mem::align_of;
2022-07-18 08:16:47 +00:00
use wasmer::{Exports, Function, Store};
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::StringKey;
macro_rules! register_func {
($exports: ident, $store: ident, $func: ident) => {
$exports.insert(stringify!($func), Function::new_native($store, $func));
};
}
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),
);
};
}
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);
}
fn _print(env: &WebAssemblyEnv, p: u32, len: u32) {
unsafe {
let mem: *mut u8 = env.resolver().memory().data_ptr().offset(p as isize);
let s = String::from_raw_parts(mem, len as usize, len as usize);
println!("{}", s);
}
}
fn _error(env: &WebAssemblyEnv, message: u32, message_len: u32, file: u32, file_len: u32, line: u32, position: u32) {
unsafe {
let mem: *mut u8 = env.resolver().memory().data_ptr().offset(message as isize);
let message = String::from_raw_parts(mem, message_len as usize, message_len as usize);
let mem: *mut u8 = env.resolver().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);
}
}
fn move_library_get_move_by_hash(env: &WebAssemblyEnv, lib: ExternRef<MoveLibrary>, hash: u32) -> ExternRef<MoveData> {
let lib = lib.value(env);
let m = lib.get_by_hash(hash);
if let Some(v) = m {
ExternRef::new(env, v)
} else {
ExternRef::null()
}
}
fn move_data_get_name(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> ExternRef<StringKey> {
let move_data = move_data.value(env);
ExternRef::new(env, move_data.name())
}
fn move_data_get_base_power(env: &WebAssemblyEnv, move_data: ExternRef<MoveData>) -> u8 {
move_data.value(env).base_power()
}
fn const_string_get_hash(env: &WebAssemblyEnv, string_key: ExternRef<StringKey>) -> u32 {
string_key.value(env).hash()
}
fn const_string_get_str(env: &WebAssemblyEnv, string_key: ExternRef<StringKey>) -> u32 {
let string_key = string_key.value(env).str();
2022-07-18 08:49:58 +00:00
let s: CString = CString::new(string_key.as_bytes()).unwrap();
2022-07-18 08:16:47 +00:00
let wasm_string_ptr = env
.resolver()
.allocate_mem(string_key.len() as u32, align_of::<CString>() as u32);
let mut wasm_string = unsafe { CString::from_raw(wasm_string_ptr.0 as *mut c_char) };
s.clone_into(&mut wasm_string);
wasm_string_ptr.1
}
fn battle_library_get_data_library(
env: &WebAssemblyEnv,
dynamic_lib: ExternRef<DynamicLibrary>,
) -> ExternRef<StaticData> {
ExternRef::new(env, dynamic_lib.value(env).static_data())
}
fn data_library_get_move_library(env: &WebAssemblyEnv, data_library: ExternRef<StaticData>) -> ExternRef<MoveLibrary> {
ExternRef::new(env, data_library.value(env).moves())
}