104 lines
4.0 KiB
Rust
104 lines
4.0 KiB
Rust
|
use core::ffi::c_char;
|
||
|
use std::borrow::Cow;
|
||
|
use std::ffi::CString;
|
||
|
use std::mem::{align_of, size_of};
|
||
|
|
||
|
use wasmer::wasmparser::Data;
|
||
|
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();
|
||
|
let mut s: CString = CString::new(string_key.as_bytes()).unwrap();
|
||
|
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())
|
||
|
}
|