From 348657163df1e9b98b1ffee20930ab3c7f742d26 Mon Sep 17 00:00:00 2001 From: Dennis Ranke Date: Wed, 3 Nov 2021 23:58:44 +0100 Subject: [PATCH] improve file selection button, first version of uw8-tool to build base.wasm --- uw8-tool/Cargo.lock | 39 +++++++++ uw8-tool/Cargo.toml | 11 +++ uw8-tool/src/base_module.rs | 152 ++++++++++++++++++++++++++++++++++++ uw8-tool/src/main.rs | 9 +++ web/src/index.html | 3 +- web/src/main.js | 32 +++++--- 6 files changed, 231 insertions(+), 15 deletions(-) create mode 100644 uw8-tool/Cargo.lock create mode 100644 uw8-tool/Cargo.toml create mode 100644 uw8-tool/src/base_module.rs create mode 100644 uw8-tool/src/main.rs diff --git a/uw8-tool/Cargo.lock b/uw8-tool/Cargo.lock new file mode 100644 index 0000000..b03ccbf --- /dev/null +++ b/uw8-tool/Cargo.lock @@ -0,0 +1,39 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "uw8-tool" +version = "0.1.0" +dependencies = [ + "anyhow", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasm-encoder" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db0c351632e46cc06a58a696a6c11e4cf90cad4b9f8f07a0b59128d616c29bb0" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasmparser" +version = "0.81.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98930446519f63d00a836efdc22f67766ceae8dbcc1571379f2bcabc6b2b9abc" diff --git a/uw8-tool/Cargo.toml b/uw8-tool/Cargo.toml new file mode 100644 index 0000000..cad53cf --- /dev/null +++ b/uw8-tool/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "uw8-tool" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +wasmparser = "0.81" +wasm-encoder = "0.8" +anyhow = "1" diff --git a/uw8-tool/src/base_module.rs b/uw8-tool/src/base_module.rs new file mode 100644 index 0000000..45cde72 --- /dev/null +++ b/uw8-tool/src/base_module.rs @@ -0,0 +1,152 @@ +use std::{collections::HashMap, fs::File, path::Path}; + +use wasm_encoder::{ + CodeSection, EntityType, Export, ExportSection, Function, FunctionSection, + ImportSection, Instruction, MemoryType, Module, TypeSection, ValType, +}; +use ValType::*; +use anyhow::{Result, bail}; +use std::io::prelude::*; + +pub struct BaseModule { + pub types: Vec, + pub function_imports: Vec<(&'static str, &'static str, u32)>, + pub functions: Vec, + pub exports: Vec<(&'static str, u32)>, + pub memory: u32 +} + +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct FunctionType { + pub params: Vec, + pub result: Option +} + +impl BaseModule { + pub fn for_format_version(version: u32) -> Result { + if version != 1 { + bail!("Unsupported format version ({})", version); + } + + let mut types = vec![]; + let mut type_map = HashMap::new(); + for num_params in 0..6 { + for num_f32 in 0..=num_params { + for &result in &[None, Some(ValType::I32), Some(ValType::F32)] { + let mut params = vec![]; + for _ in 0..num_f32 { + params.push(F32); + } + for _ in num_f32..num_params { + params.push(I32); + } + let type_ = FunctionType { params, result }; + type_map.insert(type_.clone(), types.len() as u32); + types.push(type_); + } + } + } + + let mut functions = vec![]; + add_function(&mut functions, &type_map, "math","sin", &[F32], Some(F32)); + add_function(&mut functions, &type_map, "math", "cos", &[F32], Some(F32)); + add_function(&mut functions, &type_map, "math", "tan", &[F32], Some(F32)); + add_function(&mut functions, &type_map, "math", "asin", &[F32], Some(F32)); + add_function(&mut functions, &type_map, "math", "acos", &[F32], Some(F32)); + add_function(&mut functions, &type_map, "math", "atan", &[F32], Some(F32)); + add_function(&mut functions, &type_map, "math", "atan2", &[F32, F32], Some(F32)); + add_function(&mut functions, &type_map, "math", "pow", &[F32, F32], Some(F32)); + add_function(&mut functions, &type_map, "math", "log", &[F32], Some(F32)); + + let first_function = functions.len() as u32; + + Ok(BaseModule { + types, + function_imports: functions, + functions: vec![lookup_type(&type_map, &[I32], None)], + exports: vec![("tic", first_function)], + memory: 4 + }) + } + + pub fn write_to_file>(&self, path: P) -> Result<()> { + fn inner(m: &BaseModule, path: &Path) -> Result<()> { + let mut module = Module::new(); + + { + let mut types = TypeSection::new(); + for type_ in &m.types { + types.function(type_.params.iter().cloned(), type_.result.iter().cloned()); + } + module.section(&types); + } + + { + let mut imports = ImportSection::new(); + + for (module, name, type_) in &m.function_imports { + imports.import(*module, Some(*name), EntityType::Function(*type_)); + } + + imports.import("env", Some("memory"), MemoryType { + minimum: m.memory as u64, + maximum: None, + memory64: false + }); + + module.section(&imports); + } + + { + let mut functions = FunctionSection::new(); + + for type_ in &m.functions { + functions.function(*type_); + } + + module.section(&functions); + } + + { + let mut exports = ExportSection::new(); + + for (name, fnc) in &m.exports { + exports.export(*name, Export::Function(*fnc)); + } + + module.section(&exports); + } + + { + let mut code = CodeSection::new(); + + for _ in &m.functions { + let mut function = Function::new([]); + function.instruction(&Instruction::End); + code.function(&function); + } + + module.section(&code); + } + + let data = module.finish(); + + File::create(path)?.write_all(&data)?; + + Ok(()) + } + inner(self, path.as_ref()) + } +} + +fn add_function(functions: &mut Vec<(&'static str, &'static str, u32)>, type_map: &HashMap, module: &'static str, name: &'static str, params: &[ValType], result: Option) { + functions.push((module, name, lookup_type(type_map, params, result))); +} + +fn lookup_type(type_map: &HashMap, params: &[ValType], result: Option) -> u32 { + let key = FunctionType { + params: params.to_vec(), + result + }; + *type_map.get(&key).unwrap() +} \ No newline at end of file diff --git a/uw8-tool/src/main.rs b/uw8-tool/src/main.rs new file mode 100644 index 0000000..8db87cb --- /dev/null +++ b/uw8-tool/src/main.rs @@ -0,0 +1,9 @@ +mod base_module; + +use base_module::BaseModule; +use anyhow::Result; + +fn main() -> Result<()> { + BaseModule::for_format_version(1)?.write_to_file("base.wasm")?; + Ok(()) +} diff --git a/web/src/index.html b/web/src/index.html index 357a6ca..35d4e30 100644 --- a/web/src/index.html +++ b/web/src/index.html @@ -12,8 +12,7 @@
- - +