├── .gitignore ├── LICENSE ├── redis-cli ├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src │ └── main.rs ├── rust ├── shared-cgo │ ├── Cargo.lock │ ├── Cargo.toml │ ├── shared │ │ ├── libwasm2oci.dylib │ │ ├── libwasm2oci.go │ │ └── libwasm2oci.h │ └── src │ │ ├── ffilib.rs │ │ ├── lib.rs │ │ └── main.rs └── static-cgo │ ├── Cargo.lock │ ├── Cargo.toml │ ├── build.rs │ ├── libwasm2oci │ ├── libwasm2oci.go │ └── libwasm2oci.h │ ├── src │ ├── lib.rs │ ├── libffi.rs │ └── main.rs │ └── target │ └── rls │ ├── .rustc_info.json │ └── debug │ ├── .cargo-lock │ ├── .fingerprint │ ├── static-cgo-90182fbc8faa4da8 │ │ ├── run-build-script-build_script_build-90182fbc8faa4da8 │ │ └── run-build-script-build_script_build-90182fbc8faa4da8.json │ └── static-cgo-d37bb035757b1f0c │ │ ├── build-script-build_script_build-d37bb035757b1f0c │ │ ├── build-script-build_script_build-d37bb035757b1f0c.json │ │ ├── dep-build-script-build_script_build-d37bb035757b1f0c │ │ └── invoked.timestamp │ └── build │ ├── static-cgo-90182fbc8faa4da8 │ ├── invoked.timestamp │ ├── output │ ├── root-output │ └── stderr │ └── static-cgo-d37bb035757b1f0c │ ├── build-script-build │ ├── build_script_build-d37bb035757b1f0c │ ├── build_script_build-d37bb035757b1f0c.d │ ├── build_script_build-d37bb035757b1f0c.dSYM │ └── Contents │ │ ├── Info.plist │ │ └── Resources │ │ └── DWARF │ │ └── build_script_build-d37bb035757b1f0c │ └── save-analysis │ └── build_script_build-d37bb035757b1f0c.json └── wasm └── wasm-ffi ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── index.html ├── site ├── hybrid.min.css ├── index.js ├── main.css └── wasm-ffi.browser.js └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Radu M 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /redis-cli/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /redis-cli/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "async-attributes" 5 | version = "1.1.1" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423" 8 | dependencies = [ 9 | "quote", 10 | "syn", 11 | ] 12 | 13 | [[package]] 14 | name = "async-std" 15 | version = "1.5.0" 16 | source = "registry+https://github.com/rust-lang/crates.io-index" 17 | checksum = "538ecb01eb64eecd772087e5b6f7540cbc917f047727339a472dafed2185b267" 18 | dependencies = [ 19 | "async-attributes", 20 | "async-task", 21 | "crossbeam-channel", 22 | "crossbeam-deque", 23 | "crossbeam-utils", 24 | "futures-core", 25 | "futures-io", 26 | "futures-timer", 27 | "kv-log-macro", 28 | "log", 29 | "memchr", 30 | "mio", 31 | "mio-uds", 32 | "num_cpus", 33 | "once_cell", 34 | "pin-project-lite", 35 | "pin-utils", 36 | "slab", 37 | ] 38 | 39 | [[package]] 40 | name = "async-task" 41 | version = "1.3.1" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | checksum = "0ac2c016b079e771204030951c366db398864f5026f84a44dafb0ff20f02085d" 44 | dependencies = [ 45 | "libc", 46 | "winapi 0.3.8", 47 | ] 48 | 49 | [[package]] 50 | name = "autocfg" 51 | version = "1.0.0" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" 54 | 55 | [[package]] 56 | name = "bitflags" 57 | version = "1.2.1" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 60 | 61 | [[package]] 62 | name = "cfg-if" 63 | version = "0.1.10" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 66 | 67 | [[package]] 68 | name = "crossbeam-channel" 69 | version = "0.4.2" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061" 72 | dependencies = [ 73 | "crossbeam-utils", 74 | "maybe-uninit", 75 | ] 76 | 77 | [[package]] 78 | name = "crossbeam-deque" 79 | version = "0.7.3" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" 82 | dependencies = [ 83 | "crossbeam-epoch", 84 | "crossbeam-utils", 85 | "maybe-uninit", 86 | ] 87 | 88 | [[package]] 89 | name = "crossbeam-epoch" 90 | version = "0.8.2" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" 93 | dependencies = [ 94 | "autocfg", 95 | "cfg-if", 96 | "crossbeam-utils", 97 | "lazy_static", 98 | "maybe-uninit", 99 | "memoffset", 100 | "scopeguard", 101 | ] 102 | 103 | [[package]] 104 | name = "crossbeam-utils" 105 | version = "0.7.2" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 108 | dependencies = [ 109 | "autocfg", 110 | "cfg-if", 111 | "lazy_static", 112 | ] 113 | 114 | [[package]] 115 | name = "fuchsia-zircon" 116 | version = "0.3.3" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 119 | dependencies = [ 120 | "bitflags", 121 | "fuchsia-zircon-sys", 122 | ] 123 | 124 | [[package]] 125 | name = "fuchsia-zircon-sys" 126 | version = "0.3.3" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 129 | 130 | [[package]] 131 | name = "futures-core" 132 | version = "0.3.4" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a" 135 | 136 | [[package]] 137 | name = "futures-io" 138 | version = "0.3.4" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6" 141 | 142 | [[package]] 143 | name = "futures-timer" 144 | version = "2.0.2" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" 147 | 148 | [[package]] 149 | name = "hermit-abi" 150 | version = "0.1.10" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e" 153 | dependencies = [ 154 | "libc", 155 | ] 156 | 157 | [[package]] 158 | name = "iovec" 159 | version = "0.1.4" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 162 | dependencies = [ 163 | "libc", 164 | ] 165 | 166 | [[package]] 167 | name = "kernel32-sys" 168 | version = "0.2.2" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 171 | dependencies = [ 172 | "winapi 0.2.8", 173 | "winapi-build", 174 | ] 175 | 176 | [[package]] 177 | name = "kv-log-macro" 178 | version = "1.0.4" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "8c54d9f465d530a752e6ebdc217e081a7a614b48cb200f6f0aee21ba6bc9aabb" 181 | dependencies = [ 182 | "log", 183 | ] 184 | 185 | [[package]] 186 | name = "lazy_static" 187 | version = "1.4.0" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 190 | 191 | [[package]] 192 | name = "libc" 193 | version = "0.2.68" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" 196 | 197 | [[package]] 198 | name = "log" 199 | version = "0.4.8" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 202 | dependencies = [ 203 | "cfg-if", 204 | ] 205 | 206 | [[package]] 207 | name = "maybe-uninit" 208 | version = "2.0.0" 209 | source = "registry+https://github.com/rust-lang/crates.io-index" 210 | checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" 211 | 212 | [[package]] 213 | name = "memchr" 214 | version = "2.3.3" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" 217 | 218 | [[package]] 219 | name = "memoffset" 220 | version = "0.5.4" 221 | source = "registry+https://github.com/rust-lang/crates.io-index" 222 | checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" 223 | dependencies = [ 224 | "autocfg", 225 | ] 226 | 227 | [[package]] 228 | name = "mio" 229 | version = "0.6.21" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" 232 | dependencies = [ 233 | "cfg-if", 234 | "fuchsia-zircon", 235 | "fuchsia-zircon-sys", 236 | "iovec", 237 | "kernel32-sys", 238 | "libc", 239 | "log", 240 | "miow", 241 | "net2", 242 | "slab", 243 | "winapi 0.2.8", 244 | ] 245 | 246 | [[package]] 247 | name = "mio-uds" 248 | version = "0.6.7" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" 251 | dependencies = [ 252 | "iovec", 253 | "libc", 254 | "mio", 255 | ] 256 | 257 | [[package]] 258 | name = "miow" 259 | version = "0.2.1" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 262 | dependencies = [ 263 | "kernel32-sys", 264 | "net2", 265 | "winapi 0.2.8", 266 | "ws2_32-sys", 267 | ] 268 | 269 | [[package]] 270 | name = "net2" 271 | version = "0.2.33" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" 274 | dependencies = [ 275 | "cfg-if", 276 | "libc", 277 | "winapi 0.3.8", 278 | ] 279 | 280 | [[package]] 281 | name = "num_cpus" 282 | version = "1.12.0" 283 | source = "registry+https://github.com/rust-lang/crates.io-index" 284 | checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" 285 | dependencies = [ 286 | "hermit-abi", 287 | "libc", 288 | ] 289 | 290 | [[package]] 291 | name = "once_cell" 292 | version = "1.3.1" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" 295 | 296 | [[package]] 297 | name = "pin-project-lite" 298 | version = "0.1.4" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" 301 | 302 | [[package]] 303 | name = "pin-utils" 304 | version = "0.1.0-alpha.4" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" 307 | 308 | [[package]] 309 | name = "proc-macro2" 310 | version = "1.0.10" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" 313 | dependencies = [ 314 | "unicode-xid", 315 | ] 316 | 317 | [[package]] 318 | name = "quote" 319 | version = "1.0.3" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" 322 | dependencies = [ 323 | "proc-macro2", 324 | ] 325 | 326 | [[package]] 327 | name = "redis-cli" 328 | version = "0.1.0" 329 | dependencies = [ 330 | "async-std", 331 | ] 332 | 333 | [[package]] 334 | name = "scopeguard" 335 | version = "1.1.0" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 338 | 339 | [[package]] 340 | name = "slab" 341 | version = "0.4.2" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 344 | 345 | [[package]] 346 | name = "syn" 347 | version = "1.0.17" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" 350 | dependencies = [ 351 | "proc-macro2", 352 | "quote", 353 | "unicode-xid", 354 | ] 355 | 356 | [[package]] 357 | name = "unicode-xid" 358 | version = "0.2.0" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 361 | 362 | [[package]] 363 | name = "winapi" 364 | version = "0.2.8" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 367 | 368 | [[package]] 369 | name = "winapi" 370 | version = "0.3.8" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 373 | dependencies = [ 374 | "winapi-i686-pc-windows-gnu", 375 | "winapi-x86_64-pc-windows-gnu", 376 | ] 377 | 378 | [[package]] 379 | name = "winapi-build" 380 | version = "0.1.1" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 383 | 384 | [[package]] 385 | name = "winapi-i686-pc-windows-gnu" 386 | version = "0.4.0" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 389 | 390 | [[package]] 391 | name = "winapi-x86_64-pc-windows-gnu" 392 | version = "0.4.0" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 395 | 396 | [[package]] 397 | name = "ws2_32-sys" 398 | version = "0.2.1" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 401 | dependencies = [ 402 | "winapi 0.2.8", 403 | "winapi-build", 404 | ] 405 | -------------------------------------------------------------------------------- /redis-cli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "redis-cli" 3 | version = "0.1.0" 4 | authors = ["Radu M "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | async-std = {version = "1.5.0", features = ["attributes"]} 11 | -------------------------------------------------------------------------------- /redis-cli/src/main.rs: -------------------------------------------------------------------------------- 1 | use async_std::io; 2 | use async_std::net::{TcpStream, ToSocketAddrs}; 3 | use async_std::prelude::*; 4 | 5 | #[async_std::main] 6 | async fn main() -> io::Result<()> { 7 | let mut client = Client::new("localhost:6379").await?; 8 | println!("{}", client.set("foo".into(), "bar".into()).await.unwrap()); 9 | println!("{}", client.get("foo".into()).await.unwrap()); 10 | 11 | Ok(()) 12 | } 13 | 14 | fn parse_response(buffer: &[u8]) -> Result<&str, Error> { 15 | if buffer.is_empty() { 16 | return Err(Error {}); 17 | } 18 | 19 | if buffer[0] == '-' as u8 { 20 | return Err(Error {}); 21 | } 22 | 23 | Ok(std::str::from_utf8(&buffer[1..buffer.len() - 2]).unwrap()) 24 | } 25 | 26 | struct Client { 27 | stream: TcpStream, 28 | } 29 | 30 | impl Client { 31 | async fn new(addr: A) -> Result { 32 | let stream = TcpStream::connect(addr).await?; 33 | Ok(Client { stream }) 34 | } 35 | } 36 | 37 | impl Client { 38 | async fn set(&mut self, key: String, value: String) -> Result { 39 | let mut buffer = vec![]; 40 | let command = RespValue::Array(vec![ 41 | RespValue::BulkString(b"SET".to_vec()), 42 | RespValue::BulkString(key.into_bytes()), 43 | RespValue::BulkString(value.into_bytes()), 44 | ]); 45 | 46 | command.serialize(&mut buffer); 47 | self.stream.write_all(&buffer).await?; 48 | 49 | let bytes_read = self.stream.read(&mut buffer).await?; 50 | let resp = parse_response(&buffer[..bytes_read])?; 51 | 52 | Ok(resp.to_owned()) 53 | } 54 | 55 | async fn get(&mut self, key: String) -> Result { 56 | let mut buffer = vec![]; 57 | let command = RespValue::Array(vec![ 58 | RespValue::BulkString(b"GET".to_vec()), 59 | RespValue::BulkString(key.into_bytes()), 60 | ]); 61 | 62 | command.serialize(&mut buffer); 63 | self.stream.write_all(&buffer).await?; 64 | 65 | let bytes_read = self.stream.read(&mut buffer).await?; 66 | let resp = parse_response(&buffer[..bytes_read])?; 67 | 68 | Ok(resp.to_owned()) 69 | } 70 | } 71 | 72 | #[derive(Debug)] 73 | struct Error {} 74 | impl std::convert::From for Error { 75 | fn from(_: io::Error) -> Self { 76 | Error {} 77 | } 78 | } 79 | 80 | enum RespValue { 81 | SimpleString(String), 82 | Error(Vec), 83 | Integer(i64), 84 | BulkString(Vec), 85 | Array(Vec), 86 | } 87 | 88 | impl RespValue { 89 | fn serialize(self, buf: &mut Vec) { 90 | match self { 91 | RespValue::Array(values) => { 92 | buf.push(b'*'); 93 | buf.append(&mut format!("{}", values.len()).into_bytes()); 94 | buf.push(b'\r'); 95 | buf.push(b'\n'); 96 | 97 | for value in values { 98 | value.serialize(buf); 99 | } 100 | } 101 | RespValue::BulkString(mut data) => { 102 | buf.push(b'$'); 103 | buf.append(&mut format!("{}", data.len()).into_bytes()); 104 | buf.push(b'\r'); 105 | buf.push(b'\n'); 106 | buf.append(&mut data); 107 | buf.push(b'\r'); 108 | buf.push(b'\n'); 109 | } 110 | _ => unimplemented!(), 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /rust/shared-cgo/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "cc" 5 | version = "1.0.50" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | 8 | [[package]] 9 | name = "libloading" 10 | version = "0.5.2" 11 | source = "registry+https://github.com/rust-lang/crates.io-index" 12 | dependencies = [ 13 | "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", 14 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 15 | ] 16 | 17 | [[package]] 18 | name = "shared-cgo" 19 | version = "0.1.0" 20 | dependencies = [ 21 | "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 22 | ] 23 | 24 | [[package]] 25 | name = "winapi" 26 | version = "0.3.8" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | dependencies = [ 29 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 30 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 31 | ] 32 | 33 | [[package]] 34 | name = "winapi-i686-pc-windows-gnu" 35 | version = "0.4.0" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | 38 | [[package]] 39 | name = "winapi-x86_64-pc-windows-gnu" 40 | version = "0.4.0" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | 43 | [metadata] 44 | "checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" 45 | "checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" 46 | "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 47 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 48 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 49 | -------------------------------------------------------------------------------- /rust/shared-cgo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "shared-cgo" 3 | version = "0.1.0" 4 | authors = ["Radu M "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | libloading = "0.5" 11 | -------------------------------------------------------------------------------- /rust/shared-cgo/shared/libwasm2oci.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radu-matei/experiments/87611db554154b2e858b3adc1dd63bd1b6e3850d/rust/shared-cgo/shared/libwasm2oci.dylib -------------------------------------------------------------------------------- /rust/shared-cgo/shared/libwasm2oci.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "C" 5 | "fmt" 6 | 7 | "github.com/engineerd/wasm-to-oci/pkg/oci" 8 | ) 9 | 10 | //export Pull 11 | func Pull(ref, outFile string) int64 { 12 | err := oci.Pull(ref, outFile) 13 | if err != nil { 14 | fmt.Printf("cannot pull module: %v", err) 15 | return 1 16 | } 17 | 18 | return 0 19 | } 20 | 21 | //export Sum 22 | func Sum(s []int, c chan int) (chan int, error) { 23 | sum := 0 24 | for _, v := range s { 25 | sum += v 26 | } 27 | c <- sum // send sum to c 28 | 29 | return c, nil 30 | } 31 | 32 | func main() {} 33 | -------------------------------------------------------------------------------- /rust/shared-cgo/shared/libwasm2oci.h: -------------------------------------------------------------------------------- 1 | /* Code generated by cmd/cgo; DO NOT EDIT. */ 2 | 3 | /* package command-line-arguments */ 4 | 5 | 6 | #line 1 "cgo-builtin-export-prolog" 7 | 8 | #include /* for ptrdiff_t below */ 9 | 10 | #ifndef GO_CGO_EXPORT_PROLOGUE_H 11 | #define GO_CGO_EXPORT_PROLOGUE_H 12 | 13 | #ifndef GO_CGO_GOSTRING_TYPEDEF 14 | typedef struct { const char *p; ptrdiff_t n; } _GoString_; 15 | #endif 16 | 17 | #endif 18 | 19 | /* Start of preamble from import "C" comments. */ 20 | 21 | 22 | 23 | 24 | /* End of preamble from import "C" comments. */ 25 | 26 | 27 | /* Start of boilerplate cgo prologue. */ 28 | #line 1 "cgo-gcc-export-header-prolog" 29 | 30 | #ifndef GO_CGO_PROLOGUE_H 31 | #define GO_CGO_PROLOGUE_H 32 | 33 | typedef signed char GoInt8; 34 | typedef unsigned char GoUint8; 35 | typedef short GoInt16; 36 | typedef unsigned short GoUint16; 37 | typedef int GoInt32; 38 | typedef unsigned int GoUint32; 39 | typedef long long GoInt64; 40 | typedef unsigned long long GoUint64; 41 | typedef GoInt64 GoInt; 42 | typedef GoUint64 GoUint; 43 | typedef __SIZE_TYPE__ GoUintptr; 44 | typedef float GoFloat32; 45 | typedef double GoFloat64; 46 | typedef float _Complex GoComplex64; 47 | typedef double _Complex GoComplex128; 48 | 49 | /* 50 | static assertion to make sure the file is being used on architecture 51 | at least with matching size of GoInt. 52 | */ 53 | typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1]; 54 | 55 | #ifndef GO_CGO_GOSTRING_TYPEDEF 56 | typedef _GoString_ GoString; 57 | #endif 58 | typedef void *GoMap; 59 | typedef void *GoChan; 60 | typedef struct { void *t; void *v; } GoInterface; 61 | typedef struct { void *data; GoInt len; GoInt cap; } GoSlice; 62 | 63 | #endif 64 | 65 | /* End of boilerplate cgo prologue. */ 66 | 67 | #ifdef __cplusplus 68 | extern "C" { 69 | #endif 70 | 71 | 72 | extern GoInt64 Pull(GoString p0, GoString p1); 73 | 74 | /* Return type for Sum */ 75 | struct Sum_return { 76 | GoChan r0; 77 | GoInterface r1; 78 | }; 79 | 80 | extern struct Sum_return Sum(GoSlice p0, GoChan p1); 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | -------------------------------------------------------------------------------- /rust/shared-cgo/src/ffilib.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::CString; 2 | 3 | extern crate libloading as lib; 4 | 5 | fn lib_file() -> String { 6 | #[cfg(target_os = "linux")] 7 | { 8 | String::from("shared/libwasm2oci.so") 9 | } 10 | #[cfg(target_os = "macos")] 11 | { 12 | String::from("shared/libwasm2oci.dylib") 13 | } 14 | #[cfg(target_os = "windows")] 15 | { 16 | String::from("shared/libwasm2oci.dll") 17 | } 18 | } 19 | 20 | pub fn pull_wasm(reference: String, file: String) -> Result<(), OCIError> { 21 | println!("pulling {:?} into {:?}", reference, file); 22 | let c_ref = CString::new(reference)?; 23 | let c_file = CString::new(file)?; 24 | 25 | let go_str_ref = GoString { 26 | p: c_ref.as_ptr(), 27 | n: c_ref.as_bytes().len() as isize, 28 | }; 29 | let go_str_file = GoString { 30 | p: c_file.as_ptr(), 31 | n: c_file.as_bytes().len() as isize, 32 | }; 33 | 34 | let lib = lib::Library::new(lib_file())?; 35 | unsafe { 36 | let func: lib::Symbol i64> = 37 | lib.get(b"Pull")?; 38 | match func(go_str_ref, go_str_file) { 39 | 0 => return Ok(()), 40 | _ => return Err(OCIError::Custom(String::from("cannot pull module"))), 41 | } 42 | } 43 | } 44 | 45 | #[derive(Debug)] 46 | pub enum OCIError { 47 | Custom(String), 48 | Io(std::io::Error), 49 | Nul(std::ffi::NulError), 50 | } 51 | 52 | impl From for OCIError { 53 | fn from(err: std::io::Error) -> Self { 54 | OCIError::Io(err) 55 | } 56 | } 57 | 58 | impl From for OCIError { 59 | fn from(err: std::ffi::NulError) -> Self { 60 | OCIError::Nul(err) 61 | } 62 | } 63 | 64 | #[test] 65 | fn test_pull_wasm() { 66 | // this is a public registry, so this test is both making sure the library is working, 67 | // as well as ensuring the registry is publicly accessible 68 | let module = "webassembly.azurecr.io/hello-wasm:v1"; 69 | pull_wasm(String::from(module), String::from("target/pulled.wasm")).unwrap(); 70 | } 71 | 72 | /* automatically generated by rust-bindgen */ 73 | 74 | #[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] 75 | #[repr(C)] 76 | pub struct __BindgenComplex { 77 | pub re: T, 78 | pub im: T, 79 | } 80 | pub type wchar_t = ::std::os::raw::c_int; 81 | pub type max_align_t = u128; 82 | #[repr(C)] 83 | #[derive(Debug, Copy, Clone)] 84 | pub struct _GoString_ { 85 | pub p: *const ::std::os::raw::c_char, 86 | pub n: isize, 87 | } 88 | #[test] 89 | fn bindgen_test_layout__GoString_() { 90 | assert_eq!( 91 | ::std::mem::size_of::<_GoString_>(), 92 | 16usize, 93 | concat!("Size of: ", stringify!(_GoString_)) 94 | ); 95 | assert_eq!( 96 | ::std::mem::align_of::<_GoString_>(), 97 | 8usize, 98 | concat!("Alignment of ", stringify!(_GoString_)) 99 | ); 100 | assert_eq!( 101 | unsafe { &(*(::std::ptr::null::<_GoString_>())).p as *const _ as usize }, 102 | 0usize, 103 | concat!( 104 | "Offset of field: ", 105 | stringify!(_GoString_), 106 | "::", 107 | stringify!(p) 108 | ) 109 | ); 110 | assert_eq!( 111 | unsafe { &(*(::std::ptr::null::<_GoString_>())).n as *const _ as usize }, 112 | 8usize, 113 | concat!( 114 | "Offset of field: ", 115 | stringify!(_GoString_), 116 | "::", 117 | stringify!(n) 118 | ) 119 | ); 120 | } 121 | pub type GoInt8 = ::std::os::raw::c_schar; 122 | pub type GoUint8 = ::std::os::raw::c_uchar; 123 | pub type GoInt16 = ::std::os::raw::c_short; 124 | pub type GoUint16 = ::std::os::raw::c_ushort; 125 | pub type GoInt32 = ::std::os::raw::c_int; 126 | pub type GoUint32 = ::std::os::raw::c_uint; 127 | pub type GoInt64 = ::std::os::raw::c_longlong; 128 | pub type GoUint64 = ::std::os::raw::c_ulonglong; 129 | pub type GoInt = GoInt64; 130 | pub type GoUint = GoUint64; 131 | pub type GoUintptr = ::std::os::raw::c_ulong; 132 | pub type GoFloat32 = f32; 133 | pub type GoFloat64 = f64; 134 | pub type GoComplex64 = __BindgenComplex; 135 | pub type GoComplex128 = __BindgenComplex; 136 | pub type _check_for_64_bit_pointer_matching_GoInt = [::std::os::raw::c_char; 1usize]; 137 | pub type GoString = _GoString_; 138 | pub type GoMap = *mut ::std::os::raw::c_void; 139 | pub type GoChan = *mut ::std::os::raw::c_void; 140 | #[repr(C)] 141 | #[derive(Debug, Copy, Clone)] 142 | pub struct GoInterface { 143 | pub t: *mut ::std::os::raw::c_void, 144 | pub v: *mut ::std::os::raw::c_void, 145 | } 146 | #[test] 147 | fn bindgen_test_layout_GoInterface() { 148 | assert_eq!( 149 | ::std::mem::size_of::(), 150 | 16usize, 151 | concat!("Size of: ", stringify!(GoInterface)) 152 | ); 153 | assert_eq!( 154 | ::std::mem::align_of::(), 155 | 8usize, 156 | concat!("Alignment of ", stringify!(GoInterface)) 157 | ); 158 | assert_eq!( 159 | unsafe { &(*(::std::ptr::null::())).t as *const _ as usize }, 160 | 0usize, 161 | concat!( 162 | "Offset of field: ", 163 | stringify!(GoInterface), 164 | "::", 165 | stringify!(t) 166 | ) 167 | ); 168 | assert_eq!( 169 | unsafe { &(*(::std::ptr::null::())).v as *const _ as usize }, 170 | 8usize, 171 | concat!( 172 | "Offset of field: ", 173 | stringify!(GoInterface), 174 | "::", 175 | stringify!(v) 176 | ) 177 | ); 178 | } 179 | #[repr(C)] 180 | #[derive(Debug, Copy, Clone)] 181 | pub struct GoSlice { 182 | pub data: *mut ::std::os::raw::c_void, 183 | pub len: GoInt, 184 | pub cap: GoInt, 185 | } 186 | #[test] 187 | fn bindgen_test_layout_GoSlice() { 188 | assert_eq!( 189 | ::std::mem::size_of::(), 190 | 24usize, 191 | concat!("Size of: ", stringify!(GoSlice)) 192 | ); 193 | assert_eq!( 194 | ::std::mem::align_of::(), 195 | 8usize, 196 | concat!("Alignment of ", stringify!(GoSlice)) 197 | ); 198 | assert_eq!( 199 | unsafe { &(*(::std::ptr::null::())).data as *const _ as usize }, 200 | 0usize, 201 | concat!( 202 | "Offset of field: ", 203 | stringify!(GoSlice), 204 | "::", 205 | stringify!(data) 206 | ) 207 | ); 208 | assert_eq!( 209 | unsafe { &(*(::std::ptr::null::())).len as *const _ as usize }, 210 | 8usize, 211 | concat!( 212 | "Offset of field: ", 213 | stringify!(GoSlice), 214 | "::", 215 | stringify!(len) 216 | ) 217 | ); 218 | assert_eq!( 219 | unsafe { &(*(::std::ptr::null::())).cap as *const _ as usize }, 220 | 16usize, 221 | concat!( 222 | "Offset of field: ", 223 | stringify!(GoSlice), 224 | "::", 225 | stringify!(cap) 226 | ) 227 | ); 228 | } 229 | extern "C" { 230 | pub fn Pull(p0: GoString, p1: GoString) -> GoInt64; 231 | } 232 | #[repr(C)] 233 | #[derive(Debug, Copy, Clone)] 234 | pub struct Sum_return { 235 | pub r0: GoChan, 236 | pub r1: GoInterface, 237 | } 238 | #[test] 239 | fn bindgen_test_layout_Sum_return() { 240 | assert_eq!( 241 | ::std::mem::size_of::(), 242 | 24usize, 243 | concat!("Size of: ", stringify!(Sum_return)) 244 | ); 245 | assert_eq!( 246 | ::std::mem::align_of::(), 247 | 8usize, 248 | concat!("Alignment of ", stringify!(Sum_return)) 249 | ); 250 | assert_eq!( 251 | unsafe { &(*(::std::ptr::null::())).r0 as *const _ as usize }, 252 | 0usize, 253 | concat!( 254 | "Offset of field: ", 255 | stringify!(Sum_return), 256 | "::", 257 | stringify!(r0) 258 | ) 259 | ); 260 | assert_eq!( 261 | unsafe { &(*(::std::ptr::null::())).r1 as *const _ as usize }, 262 | 8usize, 263 | concat!( 264 | "Offset of field: ", 265 | stringify!(Sum_return), 266 | "::", 267 | stringify!(r1) 268 | ) 269 | ); 270 | } 271 | extern "C" { 272 | pub fn Sum(p0: GoSlice, p1: GoChan) -> Sum_return; 273 | } 274 | -------------------------------------------------------------------------------- /rust/shared-cgo/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod ffilib; 2 | -------------------------------------------------------------------------------- /rust/shared-cgo/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world!"); 3 | } 4 | -------------------------------------------------------------------------------- /rust/static-cgo/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "static-cgo" 5 | version = "0.1.0" 6 | 7 | -------------------------------------------------------------------------------- /rust/static-cgo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "static-cgo" 3 | version = "0.1.0" 4 | authors = ["Radu M "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /rust/static-cgo/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("cargo:rustc-link-search=native={}", "./target"); 3 | println!("cargo:rustc-link-lib=static={}", "wasm2oci"); 4 | 5 | #[cfg(target_os = "macos")] 6 | { 7 | println!("cargo:rustc-flags=-l framework=CoreFoundation -l framework=Security"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /rust/static-cgo/libwasm2oci/libwasm2oci.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "C" 5 | "fmt" 6 | 7 | "github.com/engineerd/wasm-to-oci/pkg/oci" 8 | ) 9 | 10 | //export Pull 11 | func Pull(ref, outFile string) int64 { 12 | err := oci.Pull(ref, outFile) 13 | if err != nil { 14 | fmt.Printf("cannot pull module: %v", err) 15 | return 1 16 | } 17 | 18 | return 0 19 | } 20 | 21 | //export Sum 22 | func Sum(s []int, c chan int) (chan int, error) { 23 | sum := 0 24 | for _, v := range s { 25 | sum += v 26 | } 27 | c <- sum // send sum to c 28 | 29 | return c, nil 30 | } 31 | 32 | func main() {} 33 | -------------------------------------------------------------------------------- /rust/static-cgo/libwasm2oci/libwasm2oci.h: -------------------------------------------------------------------------------- 1 | /* Code generated by cmd/cgo; DO NOT EDIT. */ 2 | 3 | /* package command-line-arguments */ 4 | 5 | 6 | #line 1 "cgo-builtin-export-prolog" 7 | 8 | #include /* for ptrdiff_t below */ 9 | 10 | #ifndef GO_CGO_EXPORT_PROLOGUE_H 11 | #define GO_CGO_EXPORT_PROLOGUE_H 12 | 13 | #ifndef GO_CGO_GOSTRING_TYPEDEF 14 | typedef struct { const char *p; ptrdiff_t n; } _GoString_; 15 | #endif 16 | 17 | #endif 18 | 19 | /* Start of preamble from import "C" comments. */ 20 | 21 | 22 | 23 | 24 | /* End of preamble from import "C" comments. */ 25 | 26 | 27 | /* Start of boilerplate cgo prologue. */ 28 | #line 1 "cgo-gcc-export-header-prolog" 29 | 30 | #ifndef GO_CGO_PROLOGUE_H 31 | #define GO_CGO_PROLOGUE_H 32 | 33 | typedef signed char GoInt8; 34 | typedef unsigned char GoUint8; 35 | typedef short GoInt16; 36 | typedef unsigned short GoUint16; 37 | typedef int GoInt32; 38 | typedef unsigned int GoUint32; 39 | typedef long long GoInt64; 40 | typedef unsigned long long GoUint64; 41 | typedef GoInt64 GoInt; 42 | typedef GoUint64 GoUint; 43 | typedef __SIZE_TYPE__ GoUintptr; 44 | typedef float GoFloat32; 45 | typedef double GoFloat64; 46 | typedef float _Complex GoComplex64; 47 | typedef double _Complex GoComplex128; 48 | 49 | /* 50 | static assertion to make sure the file is being used on architecture 51 | at least with matching size of GoInt. 52 | */ 53 | typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1]; 54 | 55 | #ifndef GO_CGO_GOSTRING_TYPEDEF 56 | typedef _GoString_ GoString; 57 | #endif 58 | typedef void *GoMap; 59 | typedef void *GoChan; 60 | typedef struct { void *t; void *v; } GoInterface; 61 | typedef struct { void *data; GoInt len; GoInt cap; } GoSlice; 62 | 63 | #endif 64 | 65 | /* End of boilerplate cgo prologue. */ 66 | 67 | #ifdef __cplusplus 68 | extern "C" { 69 | #endif 70 | 71 | 72 | extern GoInt64 Pull(GoString p0, GoString p1); 73 | 74 | /* Return type for Sum */ 75 | struct Sum_return { 76 | GoChan r0; 77 | GoInterface r1; 78 | }; 79 | 80 | extern struct Sum_return Sum(GoSlice p0, GoChan p1); 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | -------------------------------------------------------------------------------- /rust/static-cgo/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod libffi; 2 | -------------------------------------------------------------------------------- /rust/static-cgo/src/libffi.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::CString; 2 | 3 | pub fn pull_wasm(reference: String, file: String) -> Result<(), OCIError> { 4 | let c_ref = CString::new(reference)?; 5 | let c_file = CString::new(file)?; 6 | 7 | let go_str_ref = GoString { 8 | p: c_ref.as_ptr(), 9 | n: c_ref.as_bytes().len() as isize, 10 | }; 11 | let go_str_file = GoString { 12 | p: c_file.as_ptr(), 13 | n: c_file.as_bytes().len() as isize, 14 | }; 15 | 16 | let result = unsafe { Pull(go_str_ref, go_str_file) }; 17 | 18 | match result { 19 | 0 => return Ok(()), 20 | _ => return Err(OCIError::Custom(String::from("cannot pull module"))), 21 | } 22 | } 23 | 24 | #[test] 25 | fn test_pull_wasm() { 26 | let module = "webassembly.azurecr.io/hello-wasm:v1"; 27 | pull_wasm(String::from(module), String::from("target/pulled.wasm")).unwrap(); 28 | } 29 | 30 | #[derive(Debug)] 31 | pub enum OCIError { 32 | Custom(String), 33 | Io(std::io::Error), 34 | Nul(std::ffi::NulError), 35 | } 36 | 37 | impl From for OCIError { 38 | fn from(err: std::io::Error) -> Self { 39 | OCIError::Io(err) 40 | } 41 | } 42 | 43 | impl From for OCIError { 44 | fn from(err: std::ffi::NulError) -> Self { 45 | OCIError::Nul(err) 46 | } 47 | } 48 | 49 | /* automatically generated by rust-bindgen */ 50 | 51 | #[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] 52 | #[repr(C)] 53 | pub struct __BindgenComplex { 54 | pub re: T, 55 | pub im: T, 56 | } 57 | pub type wchar_t = ::std::os::raw::c_int; 58 | pub type max_align_t = u128; 59 | #[repr(C)] 60 | #[derive(Debug, Copy, Clone)] 61 | pub struct _GoString_ { 62 | pub p: *const ::std::os::raw::c_char, 63 | pub n: isize, 64 | } 65 | #[test] 66 | fn bindgen_test_layout__GoString_() { 67 | assert_eq!( 68 | ::std::mem::size_of::<_GoString_>(), 69 | 16usize, 70 | concat!("Size of: ", stringify!(_GoString_)) 71 | ); 72 | assert_eq!( 73 | ::std::mem::align_of::<_GoString_>(), 74 | 8usize, 75 | concat!("Alignment of ", stringify!(_GoString_)) 76 | ); 77 | assert_eq!( 78 | unsafe { &(*(::std::ptr::null::<_GoString_>())).p as *const _ as usize }, 79 | 0usize, 80 | concat!( 81 | "Offset of field: ", 82 | stringify!(_GoString_), 83 | "::", 84 | stringify!(p) 85 | ) 86 | ); 87 | assert_eq!( 88 | unsafe { &(*(::std::ptr::null::<_GoString_>())).n as *const _ as usize }, 89 | 8usize, 90 | concat!( 91 | "Offset of field: ", 92 | stringify!(_GoString_), 93 | "::", 94 | stringify!(n) 95 | ) 96 | ); 97 | } 98 | pub type GoInt8 = ::std::os::raw::c_schar; 99 | pub type GoUint8 = ::std::os::raw::c_uchar; 100 | pub type GoInt16 = ::std::os::raw::c_short; 101 | pub type GoUint16 = ::std::os::raw::c_ushort; 102 | pub type GoInt32 = ::std::os::raw::c_int; 103 | pub type GoUint32 = ::std::os::raw::c_uint; 104 | pub type GoInt64 = ::std::os::raw::c_longlong; 105 | pub type GoUint64 = ::std::os::raw::c_ulonglong; 106 | pub type GoInt = GoInt64; 107 | pub type GoUint = GoUint64; 108 | pub type GoUintptr = ::std::os::raw::c_ulong; 109 | pub type GoFloat32 = f32; 110 | pub type GoFloat64 = f64; 111 | pub type GoComplex64 = __BindgenComplex; 112 | pub type GoComplex128 = __BindgenComplex; 113 | pub type _check_for_64_bit_pointer_matching_GoInt = [::std::os::raw::c_char; 1usize]; 114 | pub type GoString = _GoString_; 115 | pub type GoMap = *mut ::std::os::raw::c_void; 116 | pub type GoChan = *mut ::std::os::raw::c_void; 117 | #[repr(C)] 118 | #[derive(Debug, Copy, Clone)] 119 | pub struct GoInterface { 120 | pub t: *mut ::std::os::raw::c_void, 121 | pub v: *mut ::std::os::raw::c_void, 122 | } 123 | #[test] 124 | fn bindgen_test_layout_GoInterface() { 125 | assert_eq!( 126 | ::std::mem::size_of::(), 127 | 16usize, 128 | concat!("Size of: ", stringify!(GoInterface)) 129 | ); 130 | assert_eq!( 131 | ::std::mem::align_of::(), 132 | 8usize, 133 | concat!("Alignment of ", stringify!(GoInterface)) 134 | ); 135 | assert_eq!( 136 | unsafe { &(*(::std::ptr::null::())).t as *const _ as usize }, 137 | 0usize, 138 | concat!( 139 | "Offset of field: ", 140 | stringify!(GoInterface), 141 | "::", 142 | stringify!(t) 143 | ) 144 | ); 145 | assert_eq!( 146 | unsafe { &(*(::std::ptr::null::())).v as *const _ as usize }, 147 | 8usize, 148 | concat!( 149 | "Offset of field: ", 150 | stringify!(GoInterface), 151 | "::", 152 | stringify!(v) 153 | ) 154 | ); 155 | } 156 | #[repr(C)] 157 | #[derive(Debug, Copy, Clone)] 158 | pub struct GoSlice { 159 | pub data: *mut ::std::os::raw::c_void, 160 | pub len: GoInt, 161 | pub cap: GoInt, 162 | } 163 | #[test] 164 | fn bindgen_test_layout_GoSlice() { 165 | assert_eq!( 166 | ::std::mem::size_of::(), 167 | 24usize, 168 | concat!("Size of: ", stringify!(GoSlice)) 169 | ); 170 | assert_eq!( 171 | ::std::mem::align_of::(), 172 | 8usize, 173 | concat!("Alignment of ", stringify!(GoSlice)) 174 | ); 175 | assert_eq!( 176 | unsafe { &(*(::std::ptr::null::())).data as *const _ as usize }, 177 | 0usize, 178 | concat!( 179 | "Offset of field: ", 180 | stringify!(GoSlice), 181 | "::", 182 | stringify!(data) 183 | ) 184 | ); 185 | assert_eq!( 186 | unsafe { &(*(::std::ptr::null::())).len as *const _ as usize }, 187 | 8usize, 188 | concat!( 189 | "Offset of field: ", 190 | stringify!(GoSlice), 191 | "::", 192 | stringify!(len) 193 | ) 194 | ); 195 | assert_eq!( 196 | unsafe { &(*(::std::ptr::null::())).cap as *const _ as usize }, 197 | 16usize, 198 | concat!( 199 | "Offset of field: ", 200 | stringify!(GoSlice), 201 | "::", 202 | stringify!(cap) 203 | ) 204 | ); 205 | } 206 | extern "C" { 207 | pub fn Pull(p0: GoString, p1: GoString) -> GoInt64; 208 | } 209 | -------------------------------------------------------------------------------- /rust/static-cgo/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world!"); 3 | } 4 | -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/.rustc_info.json: -------------------------------------------------------------------------------- 1 | {"rustc_fingerprint":5322397255696461156,"outputs":{"1164083562126845933":["rustc 1.40.0 (73528e339 2019-12-16)\nbinary: rustc\ncommit-hash: 73528e339aae0f17a15ffa49a8ac608f50c6cf14\ncommit-date: 2019-12-16\nhost: x86_64-apple-darwin\nrelease: 1.40.0\nLLVM version: 9.0\n",""],"4476964694761187371":["___\nlib___.rlib\nlib___.dylib\nlib___.dylib\nlib___.a\nlib___.dylib\n/Users/radu/.rustup/toolchains/stable-x86_64-apple-darwin\ndebug_assertions\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_feature=\"sse3\"\ntarget_feature=\"ssse3\"\ntarget_os=\"macos\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"apple\"\nunix\n",""],"10915535544655558915":["rustdoc [options] \n\nOptions:\n -h, --help show this help message\n -V, --version print rustdoc's version\n -v, --verbose use verbose output\n -r, --input-format [rust]\n the input type of the specified file\n -w, --output-format [html]\n the output type to write\n -o, --output PATH where to place the output\n --crate-name NAME\n specify the name of this crate\n --crate-type [bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]\n Comma separated list of types of crates\n for the compiler to emit\n -L, --library-path DIR\n directory to add to crate search path\n --cfg pass a --cfg to rustc\n --extern NAME=PATH\n pass an --extern to rustc\n --extern-html-root-url NAME=URL\n base URL to use for dependencies\n --plugin-path DIR\n removed\n -C, --codegen OPT[=VALUE]\n pass a codegen option to rustc\n --passes PASSES list of passes to also run, you might want to pass it\n multiple times; a value of `list` will print available\n passes\n --plugins PLUGINS\n removed\n --no-defaults don't run the default passes\n --document-private-items \n document private items\n --test run code examples as tests\n --test-args ARGS\n arguments to pass to the test runner\n --target TRIPLE target triple to document\n --markdown-css FILES\n CSS files to include via in a rendered Markdown\n file\n --html-in-header FILES\n files to include inline in the section of a\n rendered Markdown file or generated documentation\n --html-before-content FILES\n files to include inline between and the content\n of a rendered Markdown file or generated documentation\n --html-after-content FILES\n files to include inline between the content and\n of a rendered Markdown file or generated\n documentation\n --markdown-before-content FILES\n files to include inline between and the content\n of a rendered Markdown file or generated documentation\n --markdown-after-content FILES\n files to include inline between the content and\n of a rendered Markdown file or generated\n documentation\n --markdown-playground-url URL\n URL to send code snippets to\n --markdown-no-toc \n don't include table of contents\n -e, --extend-css PATH\n To add some CSS rules with a given file to generate\n doc with your own theme. However, your theme might\n break if the rustdoc's generated HTML changes, so be\n careful!\n -Z FLAG internal and debugging options (only on nightly build)\n --sysroot PATH Override the system root\n --playground-url URL\n URL to send code snippets to, may be reset by\n --markdown-playground-url or\n `#![doc(html_playground_url=...)]`\n --display-warnings \n to print code warnings when testing doc\n --crate-version VERSION\n crate version to print into documentation\n --sort-modules-by-appearance \n sort modules by where they appear in the program,\n rather than alphabetically\n --themes FILES additional themes which will be added to the generated\n docs\n --theme-checker FILES\n check if given theme is valid\n --resource-suffix PATH\n suffix to add to CSS and JavaScript files, e.g.,\n \"light.css\" will become \"light-suffix.css\"\n --edition EDITION\n edition to use when compiling rust code (default:\n 2015)\n --color auto|always|never\n Configure coloring of output:\n auto = colorize, if output goes to a tty (default);\n always = always colorize output;\n never = never colorize output\n --error-format human|json|short\n How errors and other messages are produced\n --json CONFIG Configure the structure of JSON diagnostics\n --disable-minification \n Disable minification applied on JS files\n -W, --warn OPT Set lint warnings\n -A, --allow OPT Set lint allowed\n -D, --deny OPT Set lint denied\n -F, --forbid OPT Set lint forbidden\n --cap-lints LEVEL\n Set the most restrictive lint level. More restrictive\n lints are capped at this level. By default, it is at\n `forbid` level.\n --index-page PATH\n Markdown file to be used as index page\n --enable-index-page \n To enable generation of the index page\n --static-root-path PATH\n Path string to force loading static files from in\n output pages. If not set, uses combinations of '../'\n to reach the documentation root.\n --disable-per-crate-search \n disables generating the crate selector on the search\n box\n --persist-doctests PATH\n Directory to persist doctest executables into\n --generate-redirect-pages \n Generate extra pages to support legacy URLs and tool\n links\n --show-coverage \n calculate percentage of public items with\n documentation\n --enable-per-target-ignores \n parse ignore-foo for ignoring doctests on a per-target\n basis\n --runtool The tool to run tests with when building for a different target than host\n \n --runtool-arg One (of possibly many) arguments to pass to the runtool\n \n --test-builder specified the rustc-like binary to use as the test\n builder\n\n",""]},"successes":{}} -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/.cargo-lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radu-matei/experiments/87611db554154b2e858b3adc1dd63bd1b6e3850d/rust/static-cgo/target/rls/debug/.cargo-lock -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/.fingerprint/static-cgo-90182fbc8faa4da8/run-build-script-build_script_build-90182fbc8faa4da8: -------------------------------------------------------------------------------- 1 | 543ed1044d87c867 -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/.fingerprint/static-cgo-90182fbc8faa4da8/run-build-script-build_script_build-90182fbc8faa4da8.json: -------------------------------------------------------------------------------- 1 | {"rustc":7897068085718338035,"features":"","target":0,"profile":0,"path":0,"deps":[[2138633133281996564,"build_script_build",false,15231352838644174553]],"local":[{"Precalculated":"1578878089.846076256s (/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/src/main.rs)"}],"rustflags":[],"metadata":0} -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/.fingerprint/static-cgo-d37bb035757b1f0c/build-script-build_script_build-d37bb035757b1f0c: -------------------------------------------------------------------------------- 1 | d90e0624b5a260d3 -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/.fingerprint/static-cgo-d37bb035757b1f0c/build-script-build_script_build-d37bb035757b1f0c.json: -------------------------------------------------------------------------------- 1 | {"rustc":7897068085718338035,"features":"[]","target":10429514197457385088,"profile":14996655781355331481,"path":4820456077575211582,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/static-cgo-d37bb035757b1f0c/dep-build-script-build_script_build-d37bb035757b1f0c"}}],"rustflags":[],"metadata":16931530746497386970} -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/.fingerprint/static-cgo-d37bb035757b1f0c/dep-build-script-build_script_build-d37bb035757b1f0c: -------------------------------------------------------------------------------- 1 | build.rs -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/.fingerprint/static-cgo-d37bb035757b1f0c/invoked.timestamp: -------------------------------------------------------------------------------- 1 | This file has an mtime of when this was started. -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/build/static-cgo-90182fbc8faa4da8/invoked.timestamp: -------------------------------------------------------------------------------- 1 | This file has an mtime of when this was started. -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/build/static-cgo-90182fbc8faa4da8/output: -------------------------------------------------------------------------------- 1 | cargo:rustc-link-search=native=./target 2 | cargo:rustc-link-lib=static=wasm2oci 3 | cargo:rustc-flags=-l framework=CoreFoundation -l framework=Security 4 | -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/build/static-cgo-90182fbc8faa4da8/root-output: -------------------------------------------------------------------------------- 1 | /Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/target/rls/debug/build/static-cgo-90182fbc8faa4da8/out -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/build/static-cgo-90182fbc8faa4da8/stderr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radu-matei/experiments/87611db554154b2e858b3adc1dd63bd1b6e3850d/rust/static-cgo/target/rls/debug/build/static-cgo-90182fbc8faa4da8/stderr -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c/build-script-build: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radu-matei/experiments/87611db554154b2e858b3adc1dd63bd1b6e3850d/rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c/build-script-build -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c/build_script_build-d37bb035757b1f0c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radu-matei/experiments/87611db554154b2e858b3adc1dd63bd1b6e3850d/rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c/build_script_build-d37bb035757b1f0c -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c/build_script_build-d37bb035757b1f0c.d: -------------------------------------------------------------------------------- 1 | /Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c/build_script_build-d37bb035757b1f0c: build.rs 2 | 3 | /Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c/build_script_build-d37bb035757b1f0c.d: build.rs 4 | 5 | build.rs: 6 | -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c/build_script_build-d37bb035757b1f0c.dSYM/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.apple.xcode.dsym.build_script_build-d37bb035757b1f0c 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundlePackageType 12 | dSYM 13 | CFBundleSignature 14 | ???? 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleVersion 18 | 1 19 | 20 | 21 | -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c/build_script_build-d37bb035757b1f0c.dSYM/Contents/Resources/DWARF/build_script_build-d37bb035757b1f0c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radu-matei/experiments/87611db554154b2e858b3adc1dd63bd1b6e3850d/rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c/build_script_build-d37bb035757b1f0c.dSYM/Contents/Resources/DWARF/build_script_build-d37bb035757b1f0c -------------------------------------------------------------------------------- /rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c/save-analysis/build_script_build-d37bb035757b1f0c.json: -------------------------------------------------------------------------------- 1 | {"config":{"output_file":null,"full_docs":false,"pub_only":true,"reachable_only":true,"distro_crate":false,"signatures":false,"borrow_data":false},"version":"0.19.0","compilation":{"directory":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo","program":"/Users/radu/.rustup/toolchains/stable-x86_64-apple-darwin/bin/rls","arguments":["--edition=2018","--crate-name","build_script_build","build.rs","--json=diagnostic-rendered-ansi","--crate-type","bin","--emit=dep-info,link","-C","debuginfo=2","-C","metadata=d37bb035757b1f0c","-C","extra-filename=-d37bb035757b1f0c","--out-dir","/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c","-C","incremental=/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/target/rls/debug/incremental","-L","dependency=/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/target/rls/debug/deps","--error-format=json","--sysroot","/Users/radu/.rustup/toolchains/stable-x86_64-apple-darwin"],"output":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/target/rls/debug/build/static-cgo-d37bb035757b1f0c/build_script_build-d37bb035757b1f0c"},"prelude":{"crate_id":{"name":"build_script_build","disambiguator":[1933686844041296895,16963830436766238606]},"crate_root":"","external_crates":[{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":1,"id":{"name":"std","disambiguator":[12480940028815742386,17133840292323062676]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":2,"id":{"name":"core","disambiguator":[12740277115278631702,12640810556085455126]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":3,"id":{"name":"compiler_builtins","disambiguator":[9032649326521538135,12667967411968509476]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":4,"id":{"name":"rustc_std_workspace_core","disambiguator":[10009283058736322418,8662397509334631840]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":5,"id":{"name":"alloc","disambiguator":[3924216512132021142,13433065908605684942]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":6,"id":{"name":"libc","disambiguator":[3030377414627030993,4885163689723098329]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":7,"id":{"name":"unwind","disambiguator":[13235301763130876389,11956675772311029582]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":8,"id":{"name":"cfg_if","disambiguator":[5839480494490908876,4697973287732230237]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":9,"id":{"name":"backtrace","disambiguator":[1041246640194432752,18216372201816767321]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":10,"id":{"name":"rustc_demangle","disambiguator":[4759184321302818619,12022396673976004994]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":11,"id":{"name":"backtrace_sys","disambiguator":[1295962249923865998,4753204618089216455]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":12,"id":{"name":"hashbrown","disambiguator":[11309261669264167917,12633313349437080871]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":13,"id":{"name":"rustc_std_workspace_alloc","disambiguator":[11563747115584760512,7975991426192958756]}},{"file_name":"/Users/radu/projects/src/github.com/radu-matei/experiments/rust/static-cgo/build.rs","num":14,"id":{"name":"panic_unwind","disambiguator":[2660116328215505580,9545010463301493925]}}],"span":{"file_name":"build.rs","byte_start":0,"byte_end":270,"line_start":1,"line_end":9,"column_start":1,"column_end":2}},"imports":[],"defs":[{"kind":"Mod","id":{"krate":0,"index":0},"span":{"file_name":"build.rs","byte_start":0,"byte_end":270,"line_start":1,"line_end":9,"column_start":1,"column_end":2},"name":"","qualname":"::","value":"build.rs","parent":null,"children":[{"krate":0,"index":10},{"krate":0,"index":11},{"krate":0,"index":12}],"decl_id":null,"docs":"","sig":null,"attributes":[]}],"impls":[],"refs":[],"macro_refs":[],"relations":[]} -------------------------------------------------------------------------------- /wasm/wasm-ffi/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | node_modules/ -------------------------------------------------------------------------------- /wasm/wasm-ffi/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "wasm-ffi" 5 | version = "0.1.0" 6 | 7 | -------------------------------------------------------------------------------- /wasm/wasm-ffi/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wasm-ffi" 3 | version = "0.1.0" 4 | authors = ["Radu M "] 5 | edition = "2018" 6 | 7 | [lib] 8 | crate-type = ["cdylib"] 9 | 10 | [profile.dev] 11 | opt-level = 2 -------------------------------------------------------------------------------- /wasm/wasm-ffi/README.md: -------------------------------------------------------------------------------- 1 | # Using `wasm-ffi` with Rust 2 | 3 | ``` 4 | $ cargo build --target=wasm32-unknown-unknown 5 | $ 6 | ``` 7 | 8 | All credits for this demo go to https://demille.github.io/wasm-ffi/docs/rust/ -------------------------------------------------------------------------------- /wasm/wasm-ffi/site/index.js: -------------------------------------------------------------------------------- 1 | // ghetto jquery 2 | const $ = sel => document.querySelector(sel); 3 | 4 | const Person = new ffi.Struct({ 5 | name: 'string', 6 | age: 'uint8', 7 | favorite_number: 'uint32', 8 | }); 9 | 10 | const library = new ffi.Wrapper({ 11 | say: ['string', ['string']], 12 | 13 | get_sum: ['number', ['array', 'number']], 14 | 15 | get_pointer: [ffi.types.pointer('uint32')], 16 | pass_pointer: ['number', [ffi.types.pointer('uint32')]], 17 | 18 | get_person: [Person], 19 | person_facts: ['string', [Person]], 20 | 21 | barrel_roll: [], 22 | multiply_input: ['number', ['string']], 23 | }); 24 | 25 | library.imports(wrap => ({ 26 | env: { 27 | rotate: function () { 28 | $('body').classList.toggle('rotate'); 29 | }, 30 | 31 | get_input_value: wrap(['number', ['string']], (selector) => { 32 | return parseInt($(selector).value); 33 | }), 34 | }, 35 | })); 36 | 37 | library.fetch('../target/wasm32-unknown-unknown/debug/wasm_ffi.wasm').then(() => { 38 | 39 | $('#say-hello').addEventListener('click', () => { 40 | alert(library.say('Hello')); 41 | }); 42 | 43 | $('#get-sum').addEventListener('click', () => { 44 | const arr = new Uint32Array([1, 1, 2, 3, 5, 8, 13, 21]); 45 | const sum = library.get_sum(arr, arr.length); 46 | 47 | $('#sum-log').innerText = `Sum of ${arr} is: ${sum}`; 48 | }); 49 | 50 | $('#get-pointer').addEventListener('click', () => { 51 | const ptr = library.get_pointer(); 52 | $('#pointer-log').innerText = `Value ${ptr.deref()} is located @ ${ptr.ref()}`; 53 | }); 54 | 55 | $('#pass-pointer').addEventListener('click', () => { 56 | const ptr = new ffi.Pointer('uint32', 365); 57 | const value = library.pass_pointer(ptr); 58 | 59 | $('#pointer-log').innerText = `Wasm read ${value} from the pointer you sent`; 60 | }); 61 | 62 | $('#get-person').addEventListener('click', () => { 63 | const p = library.get_person(); 64 | 65 | const about = `${p.name} is ${p.age}. His favorite number is ${p.favorite_number}.`; 66 | $('#person-log').innerText = about; 67 | }); 68 | 69 | $('#modify-person').addEventListener('click', () => { 70 | const p = library.get_person(); 71 | p.age = 255; 72 | p.favorite_number = 100; 73 | 74 | $('#person-log').innerText = `New age: ${p.age}\n`; 75 | $('#person-log').innerText += `New favorite: ${p.favorite_number}\n`; 76 | $('#person-log').innerText += library.person_facts(p); 77 | }); 78 | 79 | $('#make-person').addEventListener('click', () => { 80 | const name = $('#name').value; 81 | const age = parseInt($('#age').value); 82 | const num = parseInt($('#num').value); 83 | 84 | const person = new Person({ 85 | name: name, 86 | age: age, 87 | favorite_number: num, 88 | }); 89 | 90 | $('#make-log').innerText = library.person_facts(person); 91 | }); 92 | 93 | $('#barrel-roll').addEventListener('click', () => { 94 | library.barrel_roll(); 95 | }); 96 | 97 | $('#multiply').addEventListener('click', () => { 98 | var number = library.multiply_input('input#number'); 99 | 100 | $('#multiply-log').innerText = `Result: ${number}`; 101 | }); 102 | 103 | }); 104 | 105 | // common.js 106 | if (typeof WebAssembly === 'undefined') { 107 | document.getElementById('warning-header').classList.remove('hidden'); 108 | } 109 | 110 | function toArray(list) { 111 | return Array.prototype.slice.call(list); 112 | } 113 | 114 | // tab switching 115 | toArray(document.querySelectorAll('.tabnav-tab')).forEach(function (tab) { 116 | if (!tab.dataset.target) return; 117 | 118 | var target = tab 119 | .parentElement // .tabnav-tabs 120 | .parentElement // .tabnav 121 | .parentElement // .col 122 | .querySelector(`[data-tab="${tab.dataset.target}"]`); 123 | 124 | var targets = toArray(target.parentElement.querySelectorAll('[data-tab]')); 125 | var otherTabs = toArray(tab.parentElement.children); 126 | 127 | tab.addEventListener('click', function () { 128 | target.classList.remove('hidden'); 129 | tab.classList.add('selected'); 130 | 131 | otherTabs.forEach(function (other) { 132 | if (other !== tab) { 133 | other.classList.remove('selected'); 134 | } 135 | }); 136 | 137 | targets.forEach(function (other) { 138 | if (other !== target) { 139 | other.classList.add('hidden'); 140 | } 141 | }); 142 | }); 143 | }); -------------------------------------------------------------------------------- /wasm/wasm-ffi/site/main.css: -------------------------------------------------------------------------------- 1 | .capped-container-fluid { 2 | padding: 0 30px; 3 | } 4 | 5 | .col-md-7 { 6 | margin-left: 20px; 7 | } 8 | 9 | @media (max-width: 850px) { 10 | .capped-container-fluid { 11 | padding: 0 15px; 12 | } 13 | .col-md-7 { 14 | margin-left: 0px; 15 | } 16 | } 17 | 18 | .hidden { 19 | display: none; 20 | } 21 | 22 | #warning-header { 23 | background: #f7e1e1; 24 | border-bottom: 1px solid #9e3e3e; 25 | color: #2d1414; 26 | } 27 | 28 | .header { 29 | color: #fff; 30 | background: #bf6060 url('./bg.png') center center no-repeat; 31 | background-size: cover; 32 | } 33 | 34 | .header h1 { 35 | line-height: 1.1; 36 | margin-bottom: 5px; 37 | font-size: 40px; 38 | font-weight: 500; 39 | } 40 | 41 | .UnderlineNav { 42 | border-bottom: 1px solid #f1f1f1; 43 | } 44 | 45 | .UnderlineNav-item { 46 | padding: 14px 8px; 47 | font-size: 11px; 48 | font-weight: 500; 49 | color: #888; 50 | } 51 | 52 | #reliable { 53 | position: relative; 54 | } 55 | 56 | #reliable.yes .no { display: none; } 57 | #reliable.no .yes { display: none; } 58 | 59 | #reliable.yes .yes { 60 | display: inline-block; 61 | background: url("./assets/verified.svg") no-repeat center center; 62 | height: 24px; 63 | width: 24px; 64 | position: relative; 65 | top: 2px; 66 | right: 5px; 67 | } 68 | 69 | #reliable.no .no { 70 | display: inline-block; 71 | background: url("./assets/unverified.svg") no-repeat center center; 72 | height: 24px; 73 | width: 24px; 74 | position: relative; 75 | top: 2px; 76 | right: 5px; 77 | } 78 | 79 | #reliable #language { 80 | position: relative; 81 | right: 8px; 82 | font-size: 30px; 83 | } 84 | 85 | .meter { 86 | display: flex; 87 | margin-bottom: -1px; 88 | overflow: hidden; 89 | box-shadow: 0px 4px 2px -3px #5252522e; 90 | -webkit-box-shadow: 0px 4px 2px -3px #5252522e; 91 | position: relative; 92 | z-index: 10; 93 | } 94 | 95 | .meter > p { 96 | position: relative; 97 | z-index: 10; 98 | margin: 0px; 99 | padding: 2px 6px 2px 5px; 100 | background: #3a4446; 101 | color: #fff; 102 | font-size: 9px; 103 | letter-spacing: 0.5px; 104 | font-weight: bold; 105 | text-transform: uppercase; 106 | border: 1px solid #3a4446; 107 | border-right: none; 108 | border-bottom: none; 109 | border-radius: 3px 0 0 0; 110 | box-shadow: 0px 4px 2px -3px #5252522e; 111 | } 112 | 113 | .meter > p span { 114 | min-width: 40px; 115 | display: inline-block; 116 | text-align: center; 117 | } 118 | 119 | .meter > div { 120 | flex: 1; 121 | background-color: #53f024; 122 | border: 1px solid #d1d5da; 123 | border-left: none; 124 | border-bottom: none; 125 | border-radius: 0 3px 0 0; 126 | } 127 | 128 | .meter > div > progress { 129 | position: relative; 130 | display: block; 131 | height: 100%; 132 | margin: 0; 133 | border-radius: 0; 134 | z-index: 1; 135 | } 136 | 137 | .form-group textarea.form-control { 138 | position: relative; 139 | z-index: 1; 140 | border-radius: 0 0 3px 3px; 141 | padding: 10px; 142 | box-shadow: none; 143 | font-size: 16px; 144 | background-color: #fbfbfb; 145 | } 146 | 147 | .form-control:focus { 148 | border-color: #d1d5da; 149 | outline: none; 150 | box-shadow: none; 151 | } 152 | 153 | .Box { 154 | border: 1px solid #efefef; 155 | } 156 | 157 | .flash-warn { 158 | padding: 12px 16px; 159 | border-color: #ede4d9; 160 | background-color: #fff7eb; 161 | background-color: #ffefeb; 162 | color: #6f5845; 163 | } 164 | 165 | .flash-warn h3 { 166 | font-weight: 500; 167 | } 168 | 169 | .warning-block { 170 | padding-bottom: 24px; 171 | } 172 | 173 | @media (max-width: 768px) { 174 | .warning-block { 175 | padding-bottom: 0; 176 | } 177 | } 178 | 179 | .zap { 180 | height: 70px; 181 | background: url("./assets/zap.svg") no-repeat center center; 182 | } 183 | 184 | .icon-alert { 185 | display: inline-block; 186 | height: 14px; 187 | width: 14px; 188 | position: relative; 189 | top: 2px; 190 | margin-right: 8px; 191 | background: url(./assets/alert.svg); 192 | background-size: contain; 193 | } 194 | 195 | .Subhead { 196 | /* padding-bottom: 6px; */ 197 | padding-bottom: 0; 198 | border-bottom: 0; 199 | } 200 | 201 | .Subhead-heading, 202 | .Subhead-heading code { 203 | font-size: 20px; 204 | } 205 | 206 | .markdown-body p, li { 207 | font-size: 14px; 208 | } 209 | 210 | .markdown-body .btn { 211 | padding: 4px 10px; 212 | font-size: 13px; 213 | } 214 | 215 | .markdown-body .btn-sm { 216 | padding: 3px 8px; 217 | font-size: 12px; 218 | } 219 | 220 | .markdown-body .form-group { 221 | display: flex; 222 | align-items: center; 223 | } 224 | 225 | .markdown-body label { 226 | display: inline-block; 227 | width: 70px; 228 | font-size: 12px; 229 | } 230 | 231 | .markdown-body .form-control { 232 | width: auto; 233 | height: 28px; 234 | } 235 | 236 | .btn:focus, 237 | .btn.focus { 238 | box-shadow: none; 239 | } 240 | 241 | .markdown-body .btn > span { 242 | font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace; 243 | } 244 | 245 | .tabnav { 246 | border-bottom: 0; 247 | } 248 | 249 | .tabnav-tab { 250 | user-select: none; 251 | cursor: pointer; 252 | border: 0; 253 | color: #0366d6; 254 | padding: 10px 11px; 255 | line-height: 1; 256 | } 257 | 258 | .tabnav-tab.selected { 259 | /* border-radius: 2px 2px 0 0; */ 260 | border-radius: 3px; 261 | color: #3a3e42; 262 | background: #f7f7f7; 263 | border: 0; 264 | cursor: initial; 265 | } 266 | 267 | .tag { 268 | border-radius: 0; 269 | font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace; 270 | font-size: 9px; 271 | letter-spacing: 1px; 272 | font-weight: bold; 273 | color: #353532d6; 274 | background: #ffdd57; 275 | padding: 3px 6px 2px; 276 | box-shadow: none; 277 | text-transform: uppercase; 278 | 279 | font-size: 8.5px; 280 | letter-spacing: 1px; 281 | font-weight: bold; 282 | color: #58552bcf; 283 | background: #ffdd57; 284 | padding: 3px 4px 2px 6px; 285 | } 286 | 287 | .tag.right { 288 | position: absolute; 289 | right: 0px; 290 | top: 0px; 291 | z-index: 10; 292 | } 293 | 294 | .log { 295 | margin-bottom: 20px; 296 | padding-top: 20px; 297 | position: relative; 298 | } 299 | 300 | .log pre { 301 | border-radius: 2px; 302 | margin: 0; 303 | border: 1px solid #ddd; 304 | white-space: pre-wrap; 305 | } 306 | 307 | .log pre:before { 308 | content: 'LOG'; 309 | position: absolute; 310 | bottom: calc(100% - 21px); 311 | left: 0px; 312 | padding: 3px 8px 3px; 313 | font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace; 314 | font-size: 8px; 315 | letter-spacing: 1px; 316 | font-weight: bold; 317 | text-transform: uppercase; 318 | color: #2f3131; 319 | background: #f6f8fa; 320 | border-left: 1px solid #ddd; 321 | border-top: 1px solid #ddd; 322 | border-right: 1px solid #ddd; 323 | } 324 | 325 | body { 326 | transition: transform 0.5s ease-in-out; 327 | } 328 | 329 | .rotate { 330 | transform: rotate(360deg); 331 | } 332 | 333 | .src { 334 | /* padding: 15; */ 335 | /* border: 2px dashed #eee; */ 336 | position: relative; 337 | } 338 | 339 | .paint-bordered { 340 | border: 1px solid #dddddd; 341 | border-radius: 2px; 342 | } 343 | .paint-bordered .info { 344 | display: flex; 345 | justify-content: space-between; 346 | color: rgba(36, 41, 46, 0.7490196); 347 | background: #f9f9f9; 348 | margin: 0; 349 | padding: 10px 15px 10px; 350 | font-size: 11px; 351 | line-height: 1.2; 352 | } 353 | .paint-bordered .info.header { 354 | border-bottom: 1px solid #dddddd; 355 | } 356 | .paint-bordered .info.footer { 357 | border-top: 1px solid #dddddd; 358 | } 359 | .paint-bordered .info .left { 360 | font-weight: bold; 361 | } 362 | .paint-bordered .info .right span:not(:last-child) { 363 | padding-right: 10px; 364 | margin-right: 10px; 365 | border-right: 1px solid rgba(36, 41, 46, 0.101960786); 366 | } 367 | 368 | .paint { 369 | display: block; 370 | width: 100%; 371 | padding: 10px 0; 372 | overflow-x: auto; 373 | -webkit-overflow-scrolling: touch; 374 | color: #24292e; 375 | background-color: #ffffff; 376 | } 377 | .paint table { 378 | width: 100%; 379 | border-spacing: 0; 380 | border-collapse: separate; 381 | font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace; 382 | font-size: 12px; 383 | line-height: 20px; 384 | tab-size: 4; 385 | color: inherit; 386 | -webkit-text-size-adjust: 100%; 387 | -moz-text-size-adjust: 100%; 388 | -ms-text-size-adjust: 100%; 389 | text-rendering: optimizeLegibility; 390 | 391 | } 392 | .paint td { 393 | padding: 0 13px; white-space: pre; 394 | } 395 | .paint .ln { 396 | width: 1px; 397 | min-width: 20px; 398 | box-sizing: content-box; 399 | text-align: right; 400 | -webkit-user-select: none; 401 | -moz-user-select: none; 402 | -ms-user-select: none; 403 | user-select: none; 404 | color: #bebfbf; 405 | } 406 | .paint .ln::after { 407 | content: attr(data-ln); 408 | } 409 | .paint .hi { 410 | background-color: #fffbdd; 411 | } 412 | .paint .un { text-decoration: underline; } 413 | .paint .bo { font-weight: bold; } 414 | .paint .it { font-style: italic; } 415 | .paint .pt12 { color: #6a737d; } 416 | .paint .pt2 { background: #b31d28; } 417 | .paint .pt15 { color: #959da5; } 418 | .paint .pt18 { color: #e36209; } 419 | .paint .pt8 { color: #032f62; } 420 | .paint .pt10 { color: #242930; } 421 | .paint .pt16 { color: #b31d28; } 422 | .paint .pt6 { background: #ffeef0; } 423 | .paint .pt13 { color: #6f42c1; } 424 | .paint .pt1 { background: #005cc5; } 425 | .paint .pt11 { color: #586069; } 426 | .paint .pt14 { color: #735c0f; } 427 | .paint .pt19 { color: #f6f8fa; } 428 | .paint .pt17 { color: #d73a49; } 429 | .paint .pt20 { color: #fafbfc; } 430 | .paint .pt4 { background: #f0fff4; } 431 | .paint .pt3 { background: #d73a49; } 432 | .paint .pt7 { color: #005cc5; } 433 | .paint .pt5 { background: #ffebda; } 434 | .paint .pt9 { color: #22863a; } 435 | 436 | .gh { 437 | font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace; 438 | font-size: 12px; 439 | text-align: center; 440 | } 441 | 442 | .gh a { 443 | color: inherit; 444 | } 445 | 446 | .gh svg { 447 | position: relative; 448 | top: 4px; 449 | width: 16px; 450 | fill: currentColor; 451 | } 452 | 453 | progress { 454 | -moz-appearance: none; 455 | -webkit-appearance: none; 456 | border: none; 457 | overflow: hidden; 458 | padding: 0; 459 | width: 100%; 460 | } 461 | 462 | progress::-webkit-progress-bar { background-color: #eee; } 463 | progress::-webkit-progress-value { background-color: #eee; } 464 | progress::-moz-progress-bar { background-color: #eee;} 465 | progress::-ms-fill { background-color: #eee; border: none; } 466 | 467 | progress[value^='1.']::-webkit-progress-value { background-color: #eb0808 !important; } 468 | progress[value^='2.']::-webkit-progress-value { background-color: #eb0808 !important; } 469 | progress[value^='3.']::-webkit-progress-value { background-color: #eb0808 !important; } 470 | progress[value^='4.']::-webkit-progress-value { background-color: #eb0808 !important; } 471 | progress[value^='5.']::-webkit-progress-value { background-color: #eb0808 !important; } 472 | progress[value^='6.']::-webkit-progress-value { background-color: #eb0808 !important; } 473 | progress[value^='7.']::-webkit-progress-value { background-color: #eb0808 !important; } 474 | progress[value^='8.']::-webkit-progress-value { background-color: #eb0808 !important; } 475 | progress[value^='9.']::-webkit-progress-value { background-color: #eb0808 !important; } 476 | 477 | progress[value^='1']::-webkit-progress-value { background-color: #eb5008; } 478 | progress[value^='2']::-webkit-progress-value { background-color: #eb7608; } 479 | progress[value^='3']::-webkit-progress-value { background-color: #eba308; } 480 | progress[value^='4']::-webkit-progress-value { background-color: #f1d530; } 481 | progress[value^='5']::-webkit-progress-value { background-color: #dee75b; } 482 | progress[value^='6']::-webkit-progress-value { background-color: #c8eb4d; } 483 | progress[value^='7']::-webkit-progress-value { background-color: #baec46; } 484 | progress[value^='8']::-webkit-progress-value { background-color: #91e94a; } 485 | progress[value^='9']::-webkit-progress-value { background-color: #89ec38; } 486 | progress[value^='100']::-webkit-progress-value { background-color: #53f024; } 487 | 488 | progress[value^='1.']::-moz-progress-bar { background-color: #eb0808 !important; } 489 | progress[value^='2.']::-moz-progress-bar { background-color: #eb0808 !important; } 490 | progress[value^='3.']::-moz-progress-bar { background-color: #eb0808 !important; } 491 | progress[value^='4.']::-moz-progress-bar { background-color: #eb0808 !important; } 492 | progress[value^='5.']::-moz-progress-bar { background-color: #eb0808 !important; } 493 | progress[value^='6.']::-moz-progress-bar { background-color: #eb0808 !important; } 494 | progress[value^='7.']::-moz-progress-bar { background-color: #eb0808 !important; } 495 | progress[value^='8.']::-moz-progress-bar { background-color: #eb0808 !important; } 496 | progress[value^='9.']::-moz-progress-bar { background-color: #eb0808 !important; } 497 | 498 | progress[value^='1']::-moz-progress-bar { background-color: #eb5008; } 499 | progress[value^='2']::-moz-progress-bar { background-color: #eb7608; } 500 | progress[value^='3']::-moz-progress-bar { background-color: #eba308; } 501 | progress[value^='4']::-moz-progress-bar { background-color: #f1d530; } 502 | progress[value^='5']::-moz-progress-bar { background-color: #dee75b; } 503 | progress[value^='6']::-moz-progress-bar { background-color: #c8eb4d; } 504 | progress[value^='7']::-moz-progress-bar { background-color: #baec46; } 505 | progress[value^='8']::-moz-progress-bar { background-color: #91e94a; } 506 | progress[value^='9']::-moz-progress-bar { background-color: #89ec38; } 507 | progress[value^='100']::-moz-progress-bar { background-color: #53f024; } 508 | 509 | progress[value^='1.']::-ms-fill { background-color: #eb0808 !important; } 510 | progress[value^='2.']::-ms-fill { background-color: #eb0808 !important; } 511 | progress[value^='3.']::-ms-fill { background-color: #eb0808 !important; } 512 | progress[value^='4.']::-ms-fill { background-color: #eb0808 !important; } 513 | progress[value^='5.']::-ms-fill { background-color: #eb0808 !important; } 514 | progress[value^='6.']::-ms-fill { background-color: #eb0808 !important; } 515 | progress[value^='7.']::-ms-fill { background-color: #eb0808 !important; } 516 | progress[value^='8.']::-ms-fill { background-color: #eb0808 !important; } 517 | progress[value^='9.']::-ms-fill { background-color: #eb0808 !important; } 518 | 519 | progress[value^='1']::-ms-fill { background-color: #eb5008; } 520 | progress[value^='2']::-ms-fill { background-color: #eb7608; } 521 | progress[value^='3']::-ms-fill { background-color: #eba308; } 522 | progress[value^='4']::-ms-fill { background-color: #f1d530; } 523 | progress[value^='5']::-ms-fill { background-color: #dee75b; } 524 | progress[value^='6']::-ms-fill { background-color: #c8eb4d; } 525 | progress[value^='7']::-ms-fill { background-color: #baec46; } 526 | progress[value^='8']::-ms-fill { background-color: #91e94a; } 527 | progress[value^='9']::-ms-fill { background-color: #89ec38; } 528 | progress[value^='100']::-ms-fill { background-color: #53f024; } -------------------------------------------------------------------------------- /wasm/wasm-ffi/site/wasm-ffi.browser.js: -------------------------------------------------------------------------------- 1 | var ffi = 2 | /******/ (function(modules) { // webpackBootstrap 3 | /******/ // The module cache 4 | /******/ var installedModules = {}; 5 | /******/ 6 | /******/ // The require function 7 | /******/ function __webpack_require__(moduleId) { 8 | /******/ 9 | /******/ // Check if module is in cache 10 | /******/ if(installedModules[moduleId]) { 11 | /******/ return installedModules[moduleId].exports; 12 | /******/ } 13 | /******/ // Create a new module (and put it into the cache) 14 | /******/ var module = installedModules[moduleId] = { 15 | /******/ i: moduleId, 16 | /******/ l: false, 17 | /******/ exports: {} 18 | /******/ }; 19 | /******/ 20 | /******/ // Execute the module function 21 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 22 | /******/ 23 | /******/ // Flag the module as loaded 24 | /******/ module.l = true; 25 | /******/ 26 | /******/ // Return the exports of the module 27 | /******/ return module.exports; 28 | /******/ } 29 | /******/ 30 | /******/ 31 | /******/ // expose the modules object (__webpack_modules__) 32 | /******/ __webpack_require__.m = modules; 33 | /******/ 34 | /******/ // expose the module cache 35 | /******/ __webpack_require__.c = installedModules; 36 | /******/ 37 | /******/ // define getter function for harmony exports 38 | /******/ __webpack_require__.d = function(exports, name, getter) { 39 | /******/ if(!__webpack_require__.o(exports, name)) { 40 | /******/ Object.defineProperty(exports, name, { 41 | /******/ configurable: false, 42 | /******/ enumerable: true, 43 | /******/ get: getter 44 | /******/ }); 45 | /******/ } 46 | /******/ }; 47 | /******/ 48 | /******/ // getDefaultExport function for compatibility with non-harmony modules 49 | /******/ __webpack_require__.n = function(module) { 50 | /******/ var getter = module && module.__esModule ? 51 | /******/ function getDefault() { return module['default']; } : 52 | /******/ function getModuleExports() { return module; }; 53 | /******/ __webpack_require__.d(getter, 'a', getter); 54 | /******/ return getter; 55 | /******/ }; 56 | /******/ 57 | /******/ // Object.prototype.hasOwnProperty.call 58 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 59 | /******/ 60 | /******/ // __webpack_public_path__ 61 | /******/ __webpack_require__.p = ""; 62 | /******/ 63 | /******/ // Load entry module and return exports 64 | /******/ return __webpack_require__(__webpack_require__.s = 5); 65 | /******/ }) 66 | /************************************************************************/ 67 | /******/ ([ 68 | /* 0 */ 69 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 70 | 71 | "use strict"; 72 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return types; }); 73 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return CustomType; }); 74 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return Pointer; }); 75 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return StringPointer; }); 76 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return parseType; }); 77 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__misc__ = __webpack_require__(1); 78 | 79 | 80 | 81 | // Makes a type of a given size. 82 | // Optional read / write methods, just gives a DataView by default. 83 | class CustomType { 84 | constructor(size, opts = {}) { 85 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])(!isNaN(size), 'Type size must be a number, given: %s', size); 86 | 87 | this.width = size; 88 | this.alignment = ('alignment' in opts) ? opts.alignment : size; 89 | 90 | if (opts.read) this.read = opts.read; 91 | if (opts.write) this.write = opts.write; 92 | } 93 | 94 | read(view) { 95 | return view; 96 | } 97 | 98 | write(view, value) { 99 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])(value instanceof ArrayBuffer || ArrayBuffer.isView(value), 100 | 'Value must be an `ArrayBuffer` or a `DataView` (like `Uint8Array`)'); 101 | 102 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["f" /* toUint8Array */])(view).set(Object(__WEBPACK_IMPORTED_MODULE_0__misc__["f" /* toUint8Array */])(value)); 103 | } 104 | } 105 | 106 | 107 | class SignedInteger { 108 | constructor(width) { 109 | this.width = width; 110 | this.alignment = width; 111 | 112 | const get = `getInt${width * 8}`; 113 | const set = `setInt${width * 8}`; 114 | 115 | this.read = view => view[get](0, true /* little-endian */); 116 | this.write = (view, value) => view[set](0, value, true /* little-endian */); 117 | } 118 | } 119 | 120 | 121 | class UnsignedInteger { 122 | constructor(width) { 123 | this.width = width; 124 | this.alignment = width; 125 | 126 | const get = `getUint${width * 8}`; 127 | const set = `setUint${width * 8}`; 128 | 129 | this.read = view => view[get](0, true /* little-endian */); 130 | this.write = (view, value) => view[set](0, value, true /* little-endian */); 131 | } 132 | } 133 | 134 | 135 | const types = {}; 136 | 137 | types.void = { 138 | width: 0, 139 | alignment: 0, 140 | read: () => null, 141 | write: () => {}, 142 | }; 143 | 144 | types.int8 = new SignedInteger(1); 145 | types.int16 = new SignedInteger(2); 146 | types.int32 = new SignedInteger(4); 147 | types.uint8 = new UnsignedInteger(1); 148 | types.uint16 = new UnsignedInteger(2); 149 | types.uint32 = new UnsignedInteger(4); 150 | 151 | types.int64 = new CustomType(8); 152 | types.uint64 = new CustomType(8); 153 | 154 | types.float = { 155 | width: 4, 156 | alignment: 4, 157 | 158 | read(view) { 159 | return view.getFloat32(0, true /* little-endian */); 160 | }, 161 | 162 | write(view, value) { 163 | view.setFloat32(0, value, true /* little-endian */); 164 | }, 165 | }; 166 | 167 | types.double = { 168 | width: 8, 169 | alignment: 8, 170 | 171 | read(view) { 172 | return view.getFloat64(0, true /* little-endian */); 173 | }, 174 | 175 | write(view, value) { 176 | view.setFloat64(0, value, true /* little-endian */); 177 | }, 178 | }; 179 | 180 | types.bool = { 181 | width: 1, 182 | alignment: 1, 183 | 184 | read(view) { 185 | return !!view.getInt8(0); 186 | }, 187 | 188 | write(view, value) { 189 | view.setInt8(0, (!!value) ? 1 : 0); 190 | }, 191 | }; 192 | 193 | 194 | // A pointer to some other data type in memory 195 | class Pointer { 196 | constructor(type, value) { 197 | this.type = parseType(type); 198 | this.view = null; 199 | this.wrapper = null; 200 | 201 | this._temp = value; 202 | } 203 | 204 | size() { 205 | return this.type.width; 206 | } 207 | 208 | commit() { 209 | if (this._temp) { 210 | this.type.write(this.view, this._temp, this.wrapper); 211 | } 212 | } 213 | 214 | ref() { 215 | return (this.view) ? this.view.byteOffset : 0; 216 | } 217 | 218 | deref() { 219 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])(this.view, 'Trying to deref an unallocated pointer'); 220 | return this.type.read(this.view, this.wrapper); 221 | } 222 | 223 | set(value) { 224 | if (this.view) { 225 | this.type.write(this.view, value, this.wrapper); 226 | } else { 227 | this._temp = value; 228 | } 229 | } 230 | 231 | free() { 232 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])(this.view, 'Cant free pointer: unallocated / already freed'); 233 | 234 | this.wrapper.free(this.ref(), this.type.width); 235 | this.view = null; 236 | } 237 | 238 | toString() { 239 | return (this.ref()) 240 | ? `Pointer( ${this.deref()} )` 241 | : 'Pointer( null )'; 242 | } 243 | } 244 | 245 | types.pointer = function(typedef) { 246 | const type = parseType(typedef); 247 | 248 | return { 249 | type, 250 | width: 4, 251 | alignment: 4, 252 | isPointer: true, 253 | 254 | read(view, wrapper) { 255 | const addr = view.getUint32(0, true /* little-endian */); 256 | const data = new DataView(view.buffer, addr, type.width); 257 | 258 | const pointer = new Pointer(type); 259 | pointer.view = data; 260 | pointer.wrapper = wrapper; 261 | 262 | return pointer; 263 | }, 264 | 265 | write(view, value, wrapper) { 266 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])(value instanceof Pointer, `Trying to write ${value} as a pointer`); 267 | 268 | if (!value.ref()) wrapper.writePointer(value); 269 | view.setUint32(0, value.ref(), true /* little-endian */); 270 | }, 271 | }; 272 | }; 273 | 274 | 275 | class StringPointer { 276 | constructor(value) { 277 | this.view = null; 278 | this.wrapper = null; 279 | 280 | this._tempStr = value; 281 | this._tempBuf = null; 282 | this._width = null; 283 | } 284 | 285 | size() { 286 | this._tempBuf = this.wrapper.encodeString(this._tempStr); 287 | this._width = this._tempBuf.byteLength; 288 | 289 | return this._width; 290 | } 291 | 292 | commit() { 293 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])(!!this.view, 'Cant commit StringPointer, no view!'); 294 | 295 | if (this._tempBuf) { 296 | const memory = new Uint8Array(this.view.buffer); 297 | memory.set(this._tempBuf, this.view.byteOffset); 298 | } 299 | } 300 | 301 | ref() { 302 | return (this.view) ? this.view.byteOffset : 0; 303 | } 304 | 305 | deref() { 306 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])(this.view, 'Trying to deref an unallocated StringPointer'); 307 | return this.wrapper.decodeString(this.view); 308 | } 309 | 310 | free() { 311 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])(!!this.view, 'Cant free StringPointer: unallocated / already freed'); 312 | this.wrapper.free(this.ref(), this._width); 313 | this.view = null; 314 | } 315 | } 316 | 317 | Object.defineProperty(StringPointer.prototype, 'value', { 318 | enumerable: true, 319 | 320 | get() { 321 | return this.deref(); 322 | }, 323 | }); 324 | 325 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["b" /* addStringFns */])(StringPointer); 326 | 327 | 328 | types.string = { 329 | width: 4, 330 | alignment: 4, 331 | isPointer: true, 332 | 333 | read(view, wrapper) { 334 | const addr = view.getUint32(0, true /* little-endian */); 335 | 336 | const pointer = new StringPointer(); 337 | pointer.view = wrapper.readStringView(addr); 338 | pointer.wrapper = wrapper; 339 | 340 | return pointer; 341 | }, 342 | 343 | write(view, value, wrapper) { 344 | if (typeof value === 'string') { 345 | value = new StringPointer(value); 346 | } 347 | 348 | if (!value.ref()) wrapper.writePointer(value); 349 | view.setUint32(0, value.ref(), true /* little-endian */); 350 | }, 351 | }; 352 | 353 | 354 | // An array (of known size) of sub-types. 355 | class ArrayType { 356 | constructor(type, length) { 357 | this.type = type; 358 | this.length = length; 359 | 360 | this.width = type.width * length; 361 | this.alignment = type.alignment; 362 | } 363 | 364 | read(view, wrapper) { 365 | const arr = []; 366 | 367 | for (let i = 0; i <= this.length - 1; i++) { 368 | const subview = Object(__WEBPACK_IMPORTED_MODULE_0__misc__["g" /* vslice */])(view, i * this.type.width, this.type.width); 369 | arr.push(this.type.read(subview, wrapper)); 370 | } 371 | 372 | return arr; 373 | } 374 | 375 | write(view, values, wrapper) { 376 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])(values.length === this.length, 377 | 'Values length does not match struct array length'); 378 | 379 | values.forEach((value, i) => { 380 | const subview = Object(__WEBPACK_IMPORTED_MODULE_0__misc__["g" /* vslice */])(view, i * this.type.width, this.type.width); 381 | this.type.write(subview, value, wrapper); 382 | }); 383 | } 384 | } 385 | 386 | 387 | // Maps other names to base types 388 | // 389 | // Some questionable decisions: 390 | // - char = uint8 (I mean, what do you do, really) 391 | // - long = int32 (windows=32, linux=64, wasm is 32bit right now, so...) 392 | // 393 | const aliases = { 394 | u8: types.uint8, 395 | u16: types.uint16, 396 | u32: types.uint32, 397 | u64: types.uint64, 398 | i8: types.int8, 399 | i16: types.int16, 400 | i32: types.int32, 401 | i64: types.int64, 402 | f32: types.float, 403 | f64: types.double, 404 | char: types.uint8, 405 | uchar: types.uint8, 406 | schar: types.int8, 407 | short: types.int16, 408 | ushort: types.uint16, 409 | int: types.int32, 410 | uint: types.uint32, 411 | long: types.int32, 412 | ulong: types.uint32, 413 | longlong: types.uint64, 414 | ulonglong: types.uint64, 415 | size_t: types.uint32, 416 | usize: types.uint32, 417 | }; 418 | 419 | 420 | function parseTypeString(str) { 421 | const name = str.toLowerCase(); 422 | 423 | if (name in types) return types[name]; 424 | if (name in aliases) return aliases[name]; 425 | 426 | throw new Error(`Parsing unknown type '${str}'`); 427 | } 428 | 429 | 430 | // parse a type from some type definition. 431 | // may be a string, an actual type, or an array of types 432 | function parseType(typedef) { 433 | if (typeof typedef === 'string') { 434 | return parseTypeString(typedef); 435 | } 436 | 437 | if (Array.isArray(typedef)) { 438 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])(typedef.length === 2, 439 | 'Array type needs 2 arguments: [type, length], given: \n%s', typedef); 440 | 441 | const type = parseType(typedef[0]); 442 | const length = typedef[1]; 443 | 444 | return new ArrayType(type, length); 445 | } 446 | 447 | // make sure its an ok type interface 448 | const errMsg = "Given argument type isn't a proper 'type' interface: \n%s"; 449 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])('width' in typedef, errMsg, typedef); 450 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])('alignment' in typedef, errMsg, typedef); 451 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])('read' in typedef, errMsg, typedef); 452 | Object(__WEBPACK_IMPORTED_MODULE_0__misc__["c" /* assert */])('write' in typedef, errMsg, typedef); 453 | 454 | return typedef; 455 | } 456 | 457 | 458 | 459 | 460 | 461 | /***/ }), 462 | /* 1 */ 463 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 464 | 465 | "use strict"; 466 | /* harmony export (immutable) */ __webpack_exports__["c"] = assert; 467 | /* harmony export (immutable) */ __webpack_exports__["g"] = vslice; 468 | /* harmony export (immutable) */ __webpack_exports__["f"] = toUint8Array; 469 | /* harmony export (immutable) */ __webpack_exports__["d"] = isNil; 470 | /* harmony export (immutable) */ __webpack_exports__["b"] = addStringFns; 471 | /* harmony export (immutable) */ __webpack_exports__["a"] = addArrayFns; 472 | /* harmony export (immutable) */ __webpack_exports__["e"] = makeIterable; 473 | // simple assert, throws if assertion fails 474 | // also matches args to %s formatters 475 | function assert(condition, errMsg, ...args) { 476 | if (condition) return; 477 | if (!args || !args.length) throw new Error(errMsg); 478 | 479 | let msg = ''; 480 | let strings; 481 | 482 | try { 483 | strings = args.map(arg => JSON.stringify(arg, null, 2)); 484 | } catch (e) { 485 | throw new Error(errMsg); 486 | } 487 | 488 | errMsg.split('%s').forEach((part) => { 489 | msg += part; 490 | if (strings.length) msg += strings.pop(); 491 | }); 492 | 493 | throw new Error(msg); 494 | } 495 | 496 | 497 | // takes a subslice of a DataView 498 | function vslice(view, start, length) { 499 | return new DataView(view.buffer, view.byteOffset + start, length); 500 | } 501 | 502 | 503 | function toUint8Array(arr) { 504 | return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength); 505 | } 506 | 507 | 508 | function isNil(thing) { 509 | return thing === null || typeof thing === 'undefined'; 510 | } 511 | 512 | 513 | const has = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); 514 | const isFunction = thing => (typeof thing === 'function'); 515 | 516 | 517 | function addStringFns(StringLike) { 518 | assert(!!has(StringLike.prototype, 'value'), 'Missing `value` property'); 519 | 520 | Object.getOwnPropertyNames(String.prototype).forEach((prop) => { 521 | if (has(StringLike.prototype, prop)) return; 522 | if (!isFunction(String.prototype[prop])) return; 523 | 524 | StringLike.prototype[prop] = function(...args) { 525 | return this.value[prop](...args); 526 | }; 527 | }); 528 | } 529 | 530 | 531 | function addArrayFns(ArrayLike) { 532 | assert(!!has(ArrayLike.prototype, 'values'), 'Missing `values` property'); 533 | 534 | Object.getOwnPropertyNames(Array.prototype).forEach((prop) => { 535 | if (has(ArrayLike.prototype, prop)) return; 536 | if (!isFunction(Array.prototype[prop])) return; 537 | 538 | ArrayLike.prototype[prop] = function(...args) { 539 | return this.values[prop](...args); 540 | }; 541 | }); 542 | } 543 | 544 | 545 | function makeIterable(ArrayLike) { 546 | assert(!!has(ArrayLike.prototype, 'values'), 'Missing `values` property'); 547 | assert(!!has(ArrayLike.prototype, 'length'), 'Missing `length` property'); 548 | 549 | ArrayLike.prototype[Symbol.iterator] = function() { 550 | const values = this.values; 551 | const length = this.length; 552 | let i = 0; 553 | 554 | return { 555 | next() { 556 | return (i < length) 557 | ? { value: values[i++], done: false } 558 | : { done: true }; 559 | } 560 | }; 561 | }; 562 | } 563 | 564 | 565 | /***/ }), 566 | /* 2 */ 567 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 568 | 569 | "use strict"; 570 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return encode; }); 571 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return decode; }); 572 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return encodeUTF8; }); 573 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return decodeUTF8; }); 574 | function encodeUTF16(str) { 575 | const buf = new ArrayBuffer(str.length * 2); // 2 per char 576 | const arr = new Uint16Array(buf); 577 | 578 | for (let i = 0; i < str.length; i++) { 579 | arr[i] = str.charCodeAt(i); 580 | } 581 | 582 | return new Uint8Array(buf); 583 | } 584 | 585 | function decodeUTF16(buf) { 586 | const len = buf.byteLength; 587 | const num = (len % 2) ? ((len + 1) / 2) : (len / 2); 588 | const pts = new Uint16Array(buf.buffer, buf.byteOffset, num); 589 | 590 | return String.fromCharCode(...pts); 591 | } 592 | 593 | // utf8 decode/encode adapted from the buffer module 594 | // @ github.com/feross/buffer 595 | // 596 | function encodeUTF8(str) { 597 | let codePoint; 598 | let leadSurrogate = null; 599 | let units = Infinity; 600 | 601 | const bytes = []; 602 | 603 | for (let i = 0; i < str.length; ++i) { 604 | codePoint = str.charCodeAt(i); 605 | 606 | // is surrogate component 607 | if (codePoint > 0xD7FF && codePoint < 0xE000) { 608 | // last char was a lead 609 | if (!leadSurrogate) { 610 | // no lead yet 611 | if (codePoint > 0xDBFF) { 612 | // unexpected trail 613 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD); 614 | continue; 615 | 616 | } else if (i + 1 === str.length) { 617 | // unpaired lead 618 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD); 619 | continue; 620 | } 621 | 622 | // valid lead 623 | leadSurrogate = codePoint; 624 | continue; 625 | } 626 | 627 | // 2 leads in a row 628 | if (codePoint < 0xDC00) { 629 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD); 630 | leadSurrogate = codePoint; 631 | continue; 632 | } 633 | 634 | // valid surrogate pair 635 | codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000; 636 | } else if (leadSurrogate) { 637 | // valid bmp char, but last char was a lead 638 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD); 639 | } 640 | 641 | leadSurrogate = null; 642 | 643 | // encode utf8 644 | if (codePoint < 0x80) { 645 | if ((units -= 1) < 0) break; 646 | bytes.push(codePoint); 647 | 648 | } else if (codePoint < 0x800) { 649 | if ((units -= 2) < 0) break; 650 | bytes.push( 651 | codePoint >> 0x6 | 0xC0, 652 | codePoint & 0x3F | 0x80 653 | ); 654 | 655 | } else if (codePoint < 0x10000) { 656 | if ((units -= 3) < 0) break; 657 | bytes.push( 658 | codePoint >> 0xC | 0xE0, 659 | codePoint >> 0x6 & 0x3F | 0x80, 660 | codePoint & 0x3F | 0x80 661 | ); 662 | 663 | } else if (codePoint < 0x110000) { 664 | if ((units -= 4) < 0) break; 665 | bytes.push( 666 | codePoint >> 0x12 | 0xF0, 667 | codePoint >> 0xC & 0x3F | 0x80, 668 | codePoint >> 0x6 & 0x3F | 0x80, 669 | codePoint & 0x3F | 0x80 670 | ); 671 | 672 | } else { 673 | throw new Error('Invalid code point'); 674 | } 675 | } 676 | 677 | return Uint8Array.from(bytes); 678 | } 679 | 680 | 681 | function decodeUTF8(buf) { 682 | const start = 0; // view.byteOffset; 683 | const end = buf.length; 684 | 685 | const pts = []; 686 | let i = start; 687 | 688 | while (i < end) { 689 | const firstByte = buf[i]; 690 | let codePoint = null; 691 | 692 | let bytesPerSequence = (firstByte > 0xEF) ? 4 693 | : (firstByte > 0xDF) ? 3 694 | : (firstByte > 0xBF) ? 2 695 | : 1; 696 | 697 | if (i + bytesPerSequence <= end) { 698 | let secondByte, thirdByte, fourthByte, tempCodePoint; 699 | 700 | switch (bytesPerSequence) { 701 | case 1: 702 | if (firstByte < 0x80) { 703 | codePoint = firstByte; 704 | } 705 | break; 706 | case 2: 707 | secondByte = buf[i + 1]; 708 | if ((secondByte & 0xC0) === 0x80) { 709 | tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F); 710 | if (tempCodePoint > 0x7F) { 711 | codePoint = tempCodePoint; 712 | } 713 | } 714 | break; 715 | case 3: 716 | secondByte = buf[i + 1]; 717 | thirdByte = buf[i + 2]; 718 | if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { 719 | tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F); 720 | if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { 721 | codePoint = tempCodePoint; 722 | } 723 | } 724 | break; 725 | case 4: 726 | secondByte = buf[i + 1]; 727 | thirdByte = buf[i + 2]; 728 | fourthByte = buf[i + 3]; 729 | if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { 730 | tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F); 731 | if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { 732 | codePoint = tempCodePoint; 733 | } 734 | } 735 | break; 736 | default: 737 | } 738 | } 739 | 740 | if (codePoint === null) { 741 | // we did not generate a valid codePoint so insert a 742 | // replacement char (U+FFFD) and advance only 1 byte 743 | codePoint = 0xFFFD; 744 | bytesPerSequence = 1; 745 | } else if (codePoint > 0xFFFF) { 746 | // encode to utf16 (surrogate pair dance) 747 | codePoint -= 0x10000; 748 | pts.push(codePoint >>> 10 & 0x3FF | 0xD800); 749 | codePoint = 0xDC00 | codePoint & 0x3FF; 750 | } 751 | 752 | pts.push(codePoint); 753 | i += bytesPerSequence; 754 | } 755 | 756 | // Based on http://stackoverflow.com/a/22747272/680742, the browser with 757 | // the lowest limit is Chrome, with 0x10000 args. 758 | // We go 1 magnitude less, for safety 759 | const MAX = 0x1000; 760 | 761 | if (pts.length <= MAX) { 762 | return String.fromCharCode.call(String, ...pts); // avoid extra slice() 763 | } 764 | 765 | // Decode in chunks to avoid "call stack size exceeded". 766 | let str = ''; 767 | let j = 0; 768 | 769 | while (j < pts.length) { 770 | str += String.fromCharCode.call(String, ...pts.slice(j, j += MAX)); 771 | } 772 | 773 | return str; 774 | } 775 | 776 | 777 | function encode(str, type) { 778 | if (type === 'utf-16') return encodeUTF16(str); 779 | 780 | return (typeof TextEncoder !== 'undefined') 781 | ? (new TextEncoder()).encode(str) 782 | : encodeUTF8(str); 783 | } 784 | 785 | 786 | function decode(str, type) { 787 | if (type === 'utf-16') return decodeUTF16(str); 788 | 789 | return (typeof TextDecoder !== 'undefined') 790 | ? (new TextDecoder()).decode(str) 791 | : decodeUTF8(str); 792 | } 793 | 794 | 795 | 796 | 797 | 798 | /***/ }), 799 | /* 3 */ 800 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 801 | 802 | "use strict"; 803 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__types__ = __webpack_require__(0); 804 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__misc__ = __webpack_require__(1); 805 | 806 | 807 | 808 | 809 | const DATA = (typeof Symbol !== 'undefined') 810 | ? Symbol.for('struct-data') 811 | : '__data'; 812 | 813 | 814 | class AbstractStructType { 815 | constructor(obj) { 816 | // structs can be made with any object keys 817 | // hide internal info behind the data symbol so you can still have 818 | // struct fields like `.view` 819 | this[DATA] = { 820 | temp: {}, 821 | view: null, 822 | wrapper: null, 823 | }; 824 | 825 | if (obj) { 826 | Object.entries(obj).forEach(([key, value]) => { 827 | Object(__WEBPACK_IMPORTED_MODULE_1__misc__["c" /* assert */])(key in this, `Can't set value, struct missing field '${key}'`); 828 | this[key] = value; 829 | }); 830 | } 831 | } 832 | 833 | ref() { 834 | return (this[DATA].view) ? this[DATA].view.byteOffset : 0; 835 | } 836 | 837 | free(internal = false) { 838 | Object(__WEBPACK_IMPORTED_MODULE_1__misc__["c" /* assert */])(!!this[DATA].wrapper, 839 | 'Cant free struct, either: unallocated / already freed / sub-struct'); 840 | 841 | // frees any pointers contained in the struct 842 | const freePointers = (struct) => { 843 | struct.constructor.fields.forEach((field, name) => { 844 | if (field.type.isPointer) struct[name].free(); 845 | if (field.type.isStruct) freePointers(struct[name]); 846 | }); 847 | }; 848 | 849 | if (internal) freePointers(this); 850 | 851 | this[DATA].wrapper.free(this.ref(), this.constructor.width); 852 | this[DATA].wrapper = null; 853 | this[DATA].view = null; 854 | } 855 | 856 | toString() { 857 | let out = '{\n'; 858 | 859 | const stringify = (struct) => { 860 | const fields = struct.constructor.fields; 861 | const proto = struct.constructor.prototype; 862 | 863 | fields.forEach((field, name) => { 864 | out += ` ${name}: ${struct[name]},\n`; 865 | }); 866 | 867 | Object.getOwnPropertyNames(proto).forEach((name) => { 868 | if (fields.has(name)) return; 869 | 870 | const value = struct[name]; 871 | 872 | if (typeof value !== 'function') { 873 | out += ` ${name}: ${value},\n`; 874 | } 875 | }); 876 | }; 877 | 878 | stringify(this); 879 | 880 | if (out.length <= 80) { 881 | out = out.replace(/\n/g, '') // remove line breaks 882 | .replace(/ {2}/g, ' ') // collapse whitespace 883 | .replace(/,$/g, ' '); // trailing comma 884 | } 885 | 886 | out += '}'; 887 | 888 | return out; 889 | } 890 | 891 | dataview(name) { 892 | const view = this[DATA].view; 893 | Object(__WEBPACK_IMPORTED_MODULE_1__misc__["c" /* assert */])(!!view, "Struct hasn't been written yet, can't get dataview"); 894 | 895 | if (!name) return view; 896 | 897 | const StructType = this.constructor; 898 | const field = StructType.fields.get(name); 899 | Object(__WEBPACK_IMPORTED_MODULE_1__misc__["c" /* assert */])(!!field, `Field '${name}' doesn't exist on struct`); 900 | 901 | return Object(__WEBPACK_IMPORTED_MODULE_1__misc__["g" /* vslice */])(view, field.offset, field.type.width); 902 | } 903 | 904 | static read(view, wrapper) { 905 | const StructType = this; 906 | 907 | const struct = new StructType(); 908 | struct[DATA].view = view; 909 | struct[DATA].wrapper = wrapper; 910 | 911 | return struct; 912 | } 913 | 914 | static write(view, struct, wrapper) { 915 | const StructType = this; 916 | 917 | if (Object(__WEBPACK_IMPORTED_MODULE_1__misc__["d" /* isNil */])(struct) || !struct.constructor.isStruct) { 918 | struct = new StructType(struct); 919 | } 920 | 921 | StructType.fields.forEach((field, name) => { 922 | const type = field.type; 923 | let value = struct[name]; 924 | 925 | if (typeof value !== 'undefined') { 926 | if (type.isStruct && (Object(__WEBPACK_IMPORTED_MODULE_1__misc__["d" /* isNil */])(value) || !value.constructor.isStruct)) { 927 | value = new type(value); 928 | } 929 | 930 | const fieldView = Object(__WEBPACK_IMPORTED_MODULE_1__misc__["g" /* vslice */])(view, field.offset, type.width); 931 | type.write(fieldView, value, wrapper); 932 | } 933 | }); 934 | 935 | struct[DATA].view = view; 936 | struct[DATA].wrapper = wrapper; 937 | } 938 | } 939 | 940 | 941 | // Creates a new class that will create new struct instances 942 | // (this returns a constructor) 943 | class Struct { 944 | constructor(fields = {}, opt = {}) { 945 | // preserve field insertion order with [[OwnPropertyKeys]] 946 | const names = Object.getOwnPropertyNames(fields); 947 | 948 | // check for field name conflicts 949 | ['ref', 'free', 'dataview'].forEach(name => 950 | Object(__WEBPACK_IMPORTED_MODULE_1__misc__["c" /* assert */])(!(names in names), `Field '${name}' is a reserved method name`)); 951 | 952 | // keep metadata on the constructor itself 953 | class StructType extends AbstractStructType {} 954 | StructType.fields = new Map(); 955 | StructType.packed = ('packed' in opt) ? !!opt.packed : false; 956 | StructType.alignment = opt.alignment || 0; 957 | StructType.isStruct = true; 958 | 959 | let offset = 0; 960 | 961 | // get type/size/alignment for each field 962 | names.forEach((name) => { 963 | const type = Object(__WEBPACK_IMPORTED_MODULE_0__types__["d" /* parseType */])(fields[name]); 964 | 965 | if (!opt.alignment && type.alignment > StructType.alignment) { 966 | StructType.alignment = type.alignment; 967 | } 968 | 969 | if (!StructType.packed && offset % type.alignment !== 0) { 970 | offset += type.alignment - (offset % type.alignment); 971 | } 972 | 973 | StructType.fields.set(name, { name, offset, type }); 974 | offset += type.width; 975 | }); 976 | 977 | StructType.width = (offset % StructType.alignment) 978 | ? offset + StructType.alignment - (offset % StructType.alignment) 979 | : offset; 980 | 981 | // define getter / setter behavior for each field 982 | // these will read / write each field to memory according to its type 983 | StructType.fields.forEach((field, name) => { 984 | Object.defineProperty(StructType.prototype, name, { 985 | enumerable: true, 986 | 987 | get() { 988 | if (!this[DATA].view) { 989 | return this[DATA].temp[name]; 990 | } 991 | 992 | const view = Object(__WEBPACK_IMPORTED_MODULE_1__misc__["g" /* vslice */])(this[DATA].view, field.offset, field.type.width); 993 | return field.type.read(view, this[DATA].wrapper); 994 | }, 995 | 996 | set(value) { 997 | if (!this[DATA].view) { 998 | this[DATA].temp[name] = value; 999 | return; 1000 | } 1001 | 1002 | const view = Object(__WEBPACK_IMPORTED_MODULE_1__misc__["g" /* vslice */])(this[DATA].view, field.offset, field.type.width); 1003 | field.type.write(view, value, this[DATA].wrapper); 1004 | }, 1005 | }); 1006 | }); 1007 | 1008 | return StructType; 1009 | } 1010 | } 1011 | 1012 | 1013 | /* harmony default export */ __webpack_exports__["a"] = (Struct); 1014 | 1015 | 1016 | /***/ }), 1017 | /* 4 */ 1018 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 1019 | 1020 | "use strict"; 1021 | /* harmony export (immutable) */ __webpack_exports__["a"] = demangleStack; 1022 | // Rust demangle logic adpated from Alex Crichton's ructc-demangle: 1023 | // http://alexcrichton.com/rustc-demangle/src/rustc_demangle/lib.rs.html 1024 | const symbols = [ 1025 | [/^_\$/, '$'], 1026 | [/\$C\$/g, ','], 1027 | [/\$SP\$/g, '@'], 1028 | [/\$BP\$/g, '*'], 1029 | [/\$RF\$/g, '&'], 1030 | [/\$LT\$/g, '<'], 1031 | [/\$GT\$/g, '>'], 1032 | [/\$LP\$/g, '('], 1033 | [/\$RP\$/g, ')'], 1034 | [/\$u7e\$/g, '~'], 1035 | [/\$u20\$/g, ' '], 1036 | [/\$u27\$/g, "'"], 1037 | [/\$u5b\$/g, '['], 1038 | [/\$u5d\$/g, ']'], 1039 | [/\$u7b\$/g, '{'], 1040 | [/\$u7d\$/g, '}'], 1041 | [/\$u3b\$/g, ';'], 1042 | [/\$u2b\$/g, '+'], 1043 | [/\$u22\$/g, '"'], 1044 | [/\.\./g, '::'], 1045 | ]; 1046 | 1047 | function isHash(str) { 1048 | return str.length && 1049 | str[0] === 'h' && 1050 | str.split('').slice(1).every(char => /[0-9a-f]/i.test(char)); 1051 | } 1052 | 1053 | // replaces all symbols in string, returning a new string 1054 | function replaceAllSymbols(str) { 1055 | return symbols.reduce( 1056 | (result, [re, char]) => result.replace(re, char), 1057 | str 1058 | ); 1059 | } 1060 | 1061 | // Basic rust demangle rules: 1062 | // - starts with "ZN | _ZN | __ZN" and ends in "E" 1063 | // - name is made up of chunks. chunks are length prefixed 1064 | // 1065 | // Bails early if string isn't a valid rust mangle 1066 | // 1067 | function demangle(mangled = '') { 1068 | const startsWith = sub => mangled.indexOf(sub) === 0; 1069 | const endsWith = sub => mangled.slice(-1) === sub; 1070 | let inner; 1071 | 1072 | if (!endsWith('E')) return mangled; 1073 | 1074 | if (startsWith('ZN')) inner = mangled.slice(2, -1); 1075 | else if (startsWith('_ZN')) inner = mangled.slice(3, -1); 1076 | else if (startsWith('__ZN')) inner = mangled.slice(4, -1); 1077 | 1078 | if (!inner) return mangled; 1079 | 1080 | const chars = inner.split(''); 1081 | const labels = []; 1082 | let label = ''; 1083 | let digits = ''; 1084 | let length = 0; 1085 | 1086 | chars.forEach((char) => { 1087 | // add characters to label while length marker > 0 1088 | if (length) { 1089 | label += char; 1090 | length--; 1091 | 1092 | // otherwise, this label is complete and we start on the next 1093 | } else { 1094 | if (label) { 1095 | labels.push(label); 1096 | label = ''; 1097 | } 1098 | 1099 | // build length prefix, one digit at a time until we hit non-digit 1100 | if (/[0-9]/.test(char)) { 1101 | digits += char; 1102 | } else { 1103 | length = parseInt(digits, 10); // parse # the collected string 1104 | digits = ''; // clear for next time 1105 | label += char; // add first char to label 1106 | length--; // decrement 1107 | } 1108 | } 1109 | }); 1110 | 1111 | // make sure last label is included 1112 | labels.push(label); 1113 | 1114 | // if the last element is a hash, exclude it so the result is more readable 1115 | if (isHash(labels.slice(-1)[0])) labels.pop(); 1116 | 1117 | // replace symbol markers in labels with the actual symbols before joining 1118 | return labels.map(replaceAllSymbols).join('::'); 1119 | } 1120 | 1121 | 1122 | // Tries to demangle an error stack on an Error object. 1123 | // Only demangles rust right now. 1124 | // 1125 | function demangleStack(err) { 1126 | // matches error stack line patterns in chrome and firefox 1127 | // chrome: "at function_name (..." 1128 | // firefox: "function_name @ ..." 1129 | const re = /(?:at (.+) \()|(?:(.+) line.replace(re, (_, m1, m2) => `at ${demangle(m1 || m2)} (`)) 1135 | .join('\n'); 1136 | 1137 | return err; 1138 | } 1139 | 1140 | 1141 | /***/ }), 1142 | /* 5 */ 1143 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 1144 | 1145 | "use strict"; 1146 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 1147 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CString", function() { return CString; }); 1148 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_encodeUTF8", function() { return _encodeUTF8; }); 1149 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_decodeUTF8", function() { return _decodeUTF8; }); 1150 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Wrapper__ = __webpack_require__(6); 1151 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Struct__ = __webpack_require__(3); 1152 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__demangle__ = __webpack_require__(4); 1153 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__rust__ = __webpack_require__(7); 1154 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__assemblyscript__ = __webpack_require__(8); 1155 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__types__ = __webpack_require__(0); 1156 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__encoding__ = __webpack_require__(2); 1157 | /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Wrapper", function() { return __WEBPACK_IMPORTED_MODULE_0__Wrapper__["a"]; }); 1158 | /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "cwrap", function() { return __WEBPACK_IMPORTED_MODULE_0__Wrapper__["c"]; }); 1159 | /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ccall", function() { return __WEBPACK_IMPORTED_MODULE_0__Wrapper__["b"]; }); 1160 | /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Struct", function() { return __WEBPACK_IMPORTED_MODULE_1__Struct__["a"]; }); 1161 | /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "types", function() { return __WEBPACK_IMPORTED_MODULE_5__types__["e"]; }); 1162 | /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "CustomType", function() { return __WEBPACK_IMPORTED_MODULE_5__types__["a"]; }); 1163 | /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Pointer", function() { return __WEBPACK_IMPORTED_MODULE_5__types__["b"]; }); 1164 | /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "StringPointer", function() { return __WEBPACK_IMPORTED_MODULE_5__types__["c"]; }); 1165 | /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "demangle", function() { return __WEBPACK_IMPORTED_MODULE_2__demangle__["a"]; }); 1166 | /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "rust", function() { return __WEBPACK_IMPORTED_MODULE_3__rust__["a"]; }); 1167 | /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "assemblyscript", function() { return __WEBPACK_IMPORTED_MODULE_4__assemblyscript__["a"]; }); 1168 | 1169 | 1170 | 1171 | 1172 | 1173 | 1174 | 1175 | 1176 | const _encodeUTF8 = __WEBPACK_IMPORTED_MODULE_6__encoding__["d" /* encodeUTF8 */]; 1177 | const _decodeUTF8 = __WEBPACK_IMPORTED_MODULE_6__encoding__["b" /* decodeUTF8 */]; 1178 | 1179 | const CString = __WEBPACK_IMPORTED_MODULE_5__types__["c" /* StringPointer */]; 1180 | 1181 | /* harmony default export */ __webpack_exports__["default"] = ({ 1182 | Wrapper: __WEBPACK_IMPORTED_MODULE_0__Wrapper__["a" /* Wrapper */], 1183 | cwrap: __WEBPACK_IMPORTED_MODULE_0__Wrapper__["c" /* cwrap */], 1184 | ccall: __WEBPACK_IMPORTED_MODULE_0__Wrapper__["b" /* ccall */], 1185 | Struct: __WEBPACK_IMPORTED_MODULE_1__Struct__["a" /* default */], 1186 | types: __WEBPACK_IMPORTED_MODULE_5__types__["e" /* types */], 1187 | CustomType: __WEBPACK_IMPORTED_MODULE_5__types__["a" /* CustomType */], 1188 | Pointer: __WEBPACK_IMPORTED_MODULE_5__types__["b" /* Pointer */], 1189 | StringPointer: __WEBPACK_IMPORTED_MODULE_5__types__["c" /* StringPointer */], 1190 | CString, // deprecated 1191 | demangle: __WEBPACK_IMPORTED_MODULE_2__demangle__["a" /* default */], 1192 | rust: __WEBPACK_IMPORTED_MODULE_3__rust__["a" /* default */], 1193 | assemblyscript: __WEBPACK_IMPORTED_MODULE_4__assemblyscript__["a" /* default */], 1194 | _encodeUTF8, 1195 | _decodeUTF8, 1196 | }); 1197 | 1198 | 1199 | 1200 | 1201 | /***/ }), 1202 | /* 6 */ 1203 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 1204 | 1205 | "use strict"; 1206 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Wrapper; }); 1207 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return cwrap; }); 1208 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return ccall; }); 1209 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__types__ = __webpack_require__(0); 1210 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__encoding__ = __webpack_require__(2); 1211 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__misc__ = __webpack_require__(1); 1212 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__demangle__ = __webpack_require__(4); 1213 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | const numbers = new Set([ 1220 | 'int8', 'int16', 'int32', 'int64', 1221 | 'uint8', 'uint16', 'uint32', 'uint64', 1222 | 'float', 'double', 1223 | 'u8', 'u16', 'u32', 'u64', 1224 | 'i8', 'i16', 'i32', 'i64', 1225 | 'f32', 'f64', 1226 | 'schar', 'short', 'int', 'long', 1227 | 'char', 'uchar', 'ushort', 'uint', 'ulong', 1228 | 'size_t', 1229 | 'usize', 1230 | ]); 1231 | 1232 | 1233 | function areValid(argTypes) { 1234 | return argTypes.every(type => 1235 | type === null || 1236 | type === undefined || 1237 | type === 'void' || 1238 | type === 'number' || 1239 | type === 'boolean' || 1240 | type === 'bool' || 1241 | type === 'string' || 1242 | type === 'array' || 1243 | numbers.has(type) || 1244 | type.isStruct || 1245 | type.isPointer); 1246 | } 1247 | 1248 | 1249 | // a node fetch polyfill that won't trigger webpack 1250 | // idea borrowed from: 1251 | // https://github.com/dcodeIO/webassembly/blob/master/src/index.js#L223 1252 | let fs; 1253 | function fetch_polyfill(file) { 1254 | return new Promise((resolve, reject) => { 1255 | (fs || (fs = eval('equire'.replace(/^/, 'r'))('fs'))).readFile( 1256 | file, 1257 | function(err, data) { 1258 | return (err) 1259 | ? reject(err) 1260 | : resolve({ 1261 | arrayBuffer: () => Promise.resolve(data), 1262 | ok: true, 1263 | }); 1264 | } 1265 | ); 1266 | }); 1267 | } 1268 | 1269 | 1270 | const fetchFn = (typeof fetch === 'function' && fetch) || fetch_polyfill; 1271 | 1272 | 1273 | // gets the wasm at a url and instantiates it. 1274 | // checks if streaming instantiation is available and uses that 1275 | function fetchAndInstantiate(url, imports) { 1276 | return fetchFn(url) 1277 | .then((resp) => { 1278 | if (!resp.ok) { 1279 | throw new Error(`Got a ${resp.status} fetching wasm @ ${url}`); 1280 | } 1281 | 1282 | const wasm = 'application/wasm'; 1283 | const type = resp.headers && resp.headers.get('content-type'); 1284 | 1285 | return (WebAssembly.instantiateStreaming && type === wasm) 1286 | ? WebAssembly.instantiateStreaming(resp, imports) 1287 | : resp.arrayBuffer().then(buf => WebAssembly.instantiate(buf, imports)); 1288 | }) 1289 | .then(result => result.instance); 1290 | } 1291 | 1292 | 1293 | const DATA = (typeof Symbol !== 'undefined') 1294 | ? Symbol.for('wrapper-data') 1295 | : '__data'; 1296 | 1297 | 1298 | class Wrapper { 1299 | constructor(signatures, opts = {}) { 1300 | const dialect = opts.dialect && opts.dialect.toLowerCase(); 1301 | 1302 | // Keep internal info behind the DATA symbol so wrapped function names 1303 | // won't cause conflicts 1304 | this[DATA] = { 1305 | instance: null, 1306 | imports: null, 1307 | signatures: new Set(), 1308 | allocations: new Map(), 1309 | memory: opts.memory, 1310 | debug: !!opts.debug, 1311 | isAssemblyScript: dialect === 'assemblyscript', 1312 | }; 1313 | 1314 | Object.entries(signatures).forEach(([fn, [returnType, argTypes = []]]) => { 1315 | // check for name collisions: 1316 | ['exports', 'imports', 'utils', 'fetch', 'use'].forEach(name => 1317 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(fn !== name, '`%s` is a reserved wrapper name', name)); 1318 | 1319 | // validate arg types 1320 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(argTypes.every(arg => !!arg), '`%s` has undefined types', fn); 1321 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(areValid([returnType]), '`%s` has invalid types', fn); 1322 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(areValid(argTypes), '`%s` has invalid types', fn); 1323 | 1324 | this[DATA].signatures.add({ fnName: fn, returnType, argTypes }); 1325 | }); 1326 | 1327 | // exposing some methods via `.utils` 1328 | this.utils = { 1329 | encodeString: this.__encodeString.bind(this), 1330 | decodeString: this.__decodeString.bind(this), 1331 | readStringView: this.__readStringView.bind(this), 1332 | readString: this.__readString.bind(this), 1333 | writeString: this.__writeString.bind(this), 1334 | writeArray: this.__writeArray.bind(this), 1335 | readStruct: this.__readStruct.bind(this), 1336 | writeStruct: this.__writeStruct.bind(this), 1337 | readPointer: this.__readPointer.bind(this), 1338 | writePointer: this.__writePointer.bind(this), 1339 | 1340 | allocate: function(value) { 1341 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(typeof value.ref === 'function', 1342 | "Can't allocate '%s' This method is for Pointer & Structs", value); 1343 | 1344 | (value instanceof __WEBPACK_IMPORTED_MODULE_0__types__["b" /* Pointer */] || value instanceof __WEBPACK_IMPORTED_MODULE_0__types__["c" /* StringPointer */]) 1345 | ? this.__writePointer(value) 1346 | : this.__writeStruct(value); 1347 | }.bind(this), 1348 | 1349 | free: function(value) { 1350 | (typeof value.ref === 'function') 1351 | ? this.__free(value.ref()) 1352 | : this.__free(value); 1353 | }.bind(this), 1354 | }; 1355 | 1356 | this.exports = null; 1357 | } 1358 | 1359 | // takes an import object or a function what will produce a import object 1360 | imports(importArg, applyDefaults = true) { 1361 | const wrap = (...fnConfig) => { 1362 | // function to wrap is always the last argument 1363 | const fn = fnConfig.pop(); 1364 | // two argument formats (this might be a bad idea): 1365 | // 1) with return type: wrap([returnType, [...argTypes]], fn) 1366 | // 2) no return type: wrap(arg1, arg2, ..., fn) 1367 | // 1368 | // detructure into appropriate vars 1369 | const [returnType, argTypes = []] = (Array.isArray(fnConfig[0])) 1370 | ? fnConfig[0] // 1st format 1371 | : [null, fnConfig]; // 2nd format 1372 | 1373 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(areValid(argTypes), `Import has invalid types: ${argTypes}`); 1374 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(areValid([returnType]), `Import has invalid types: ${returnType}`); 1375 | 1376 | return (...args) => { 1377 | const ffi_args = argTypes.map((type, i) => this.__out(args[i], type)); 1378 | 1379 | if (args.length > argTypes.length) { 1380 | ffi_args.push(...args.slice(argTypes.length - args.length)); 1381 | } 1382 | 1383 | const value = fn(...ffi_args); 1384 | 1385 | if (returnType && returnType !== 'void') { 1386 | return this.__in(value, returnType); 1387 | } 1388 | }; 1389 | }; 1390 | 1391 | const env = { 1392 | // wasm-glue 1393 | print: wrap('string', (str, ...args) => console.log(str, ...args)), 1394 | eprint: wrap('string', (str, ...args) => console.error(str, ...args)), 1395 | trace: wrap('string', (str) => { throw new Error(str); }), 1396 | 1397 | // assemblyscript 1398 | abort: wrap('string', 'string', 'number', 'number', (msg, file, line, col) => { 1399 | throw new Error(`${msg} @ ${file}:${line}:${col}`); 1400 | }), 1401 | 1402 | // 1403 | _abort(errCode) { 1404 | throw new Error(`Aborting, error code: ${errCode}`); 1405 | }, 1406 | 1407 | _exit(exitCode) { 1408 | if (exitCode) throw new Error(`Exit error code: ${exitCode}`); 1409 | }, 1410 | 1411 | _grow() {}, 1412 | }; 1413 | 1414 | const obj = (typeof importArg === 'function') 1415 | ? importArg(wrap) 1416 | : importArg; 1417 | 1418 | if (applyDefaults) obj.env = Object.assign(env, obj.env); 1419 | this[DATA].imports = obj; 1420 | 1421 | return obj; 1422 | } 1423 | 1424 | fetch(url) { 1425 | const imports = this[DATA].imports || this.imports({}); 1426 | 1427 | return fetchAndInstantiate(url, imports).then((instance) => { 1428 | this.__link(instance); 1429 | return this; 1430 | }); 1431 | } 1432 | 1433 | use(instance) { 1434 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(instance instanceof WebAssembly.Instance, 1435 | '.use(instance) requires a WebAssembly.Instance'); 1436 | 1437 | this.__link(instance); 1438 | return this; 1439 | } 1440 | 1441 | __link(instance) { 1442 | const memory = this[DATA].memory || 1443 | instance.exports.memory || 1444 | (this[DATA].imports.env && this[DATA].imports.env.memory); 1445 | 1446 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(!!memory, '' + 1447 | 'Wrapper needs access to your WebAssemmbly memory. It looks for this in' + 1448 | 'either your `imports.env.memory` or `exports.env.memory`. If you don\'t' + 1449 | 'use either, you need to add it in the options with `new Wrapper`'); 1450 | 1451 | this.exports = instance.exports; 1452 | this[DATA].instance = instance; 1453 | this[DATA].memory = memory; 1454 | 1455 | this[DATA].signatures.forEach(({ fnName, returnType, argTypes }) => { 1456 | const fn = this.exports[fnName]; 1457 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(!!fn, `Fn '${fnName}' missing from wasm exports`); 1458 | 1459 | this[fnName] = this.__wrap(fn, argTypes, returnType); 1460 | }); 1461 | } 1462 | 1463 | __wrap(fn, argTypes, returnType) { 1464 | return function(...args) { 1465 | const stack = []; 1466 | const ffi_args = argTypes.map((type, i) => this.__in(args[i], type, stack)); 1467 | let value; 1468 | 1469 | if (args.length > argTypes.length) { 1470 | ffi_args.push(...args.slice(argTypes.length - args.length)); 1471 | } 1472 | 1473 | try { 1474 | value = fn(...ffi_args); 1475 | } catch (err) { 1476 | throw Object(__WEBPACK_IMPORTED_MODULE_3__demangle__["a" /* default */])(err); 1477 | } 1478 | 1479 | stack.forEach(ptr => this.__free(ptr)); 1480 | 1481 | if (returnType && returnType !== 'void') { 1482 | return this.__out(value, returnType); 1483 | } 1484 | }; 1485 | } 1486 | 1487 | // wrap a variable heading into a wasm function 1488 | __in(value, type, stack) { 1489 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(!!type, 'No arg type was specified for this function'); 1490 | 1491 | if (type === 'number' || numbers.has(type)) return value; 1492 | if (type === 'boolean' || type === 'bool') return !!value; 1493 | if (type === 'string') return this.__writeString(value, stack); 1494 | if (type === 'array') return this.__writeArray(value, stack); 1495 | if (type.isStruct) return this.__writeStruct(value, type); 1496 | if (type.isPointer) return this.__writePointer(value); 1497 | 1498 | throw new Error(`Unknown type: \n${JSON.stringify(type)}`); 1499 | } 1500 | 1501 | // wrap a variable heading out of a wasm function 1502 | __out(value, type) { 1503 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(!!type, 'No arg type was specified for this function'); 1504 | 1505 | if (type === 'number' || numbers.has(type)) return value; 1506 | if (type === 'boolean' || type === 'bool') return !!value; 1507 | if (type === 'string') return this.__readString(value); 1508 | if (type.isStruct) return this.__readStruct(value, type); 1509 | if (type.isPointer) return this.__readPointer(value, type); 1510 | 1511 | throw new Error(`Unknown type: \n${JSON.stringify(type)}`); 1512 | } 1513 | 1514 | __allocate(size) { 1515 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(!!this.exports.allocate && !!this.exports.deallocate, 1516 | "Missing allocate/deallocate fns in wasm exports, can't allocate memory"); 1517 | 1518 | const ptr = this.exports.allocate(size); 1519 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(!!ptr, 'allocate failed'); 1520 | 1521 | if (this[DATA].debug) console.log('Alloc: %s (size=%s)', ptr, size); 1522 | this[DATA].allocations.set(ptr, size); 1523 | 1524 | return ptr; 1525 | } 1526 | 1527 | __free(ptr, optSize) { 1528 | const size = optSize || this[DATA].allocations.get(ptr); 1529 | if (this[DATA].debug) console.log('Free: %s (size=%s)', ptr, size); 1530 | 1531 | this.exports.deallocate(ptr, size); 1532 | this[DATA].allocations.delete(ptr); 1533 | } 1534 | 1535 | __view(start, length) { 1536 | return new DataView(this[DATA].memory.buffer, start, length); 1537 | } 1538 | 1539 | __encodeString(str) { 1540 | const encoded = (this[DATA].isAssemblyScript) 1541 | ? Object(__WEBPACK_IMPORTED_MODULE_1__encoding__["c" /* encode */])(str, 'utf-16') 1542 | : Object(__WEBPACK_IMPORTED_MODULE_1__encoding__["c" /* encode */])(str); 1543 | 1544 | const len = (this[DATA].isAssemblyScript) 1545 | ? encoded.byteLength + 4 // assemblyscript header 1546 | : encoded.byteLength + 1; // null terminating byte 1547 | 1548 | const buf = new Uint8Array(new ArrayBuffer(len)); 1549 | 1550 | if (this[DATA].isAssemblyScript) { 1551 | const header = encoded.byteLength / 2; 1552 | (new DataView(buf.buffer)).setUint32(0, header, true); 1553 | buf.set(encoded, 4); 1554 | } else { 1555 | buf.set(encoded, 0); 1556 | buf[len - 1] = 0; 1557 | } 1558 | 1559 | return buf; 1560 | } 1561 | 1562 | __decodeString(view) { 1563 | const buf = Object(__WEBPACK_IMPORTED_MODULE_2__misc__["f" /* toUint8Array */])(view); 1564 | 1565 | return (this[DATA].isAssemblyScript) 1566 | ? Object(__WEBPACK_IMPORTED_MODULE_1__encoding__["a" /* decode */])(buf.subarray(4), 'utf-16') 1567 | : Object(__WEBPACK_IMPORTED_MODULE_1__encoding__["a" /* decode */])(buf.subarray(0, -1)); 1568 | } 1569 | 1570 | __readStringView(ptr) { 1571 | // length prefixed 1572 | if (this[DATA].isAssemblyScript) { 1573 | const strlen = this.__view().getUint32(ptr, true); // header 1574 | const len = 4 + (strlen * 2); 1575 | 1576 | return this.__view(ptr, len); 1577 | } 1578 | 1579 | // null terminated 1580 | const memory = new Uint8Array(this[DATA].memory.buffer); 1581 | 1582 | let end = ptr; 1583 | while (memory[end]) ++end; 1584 | 1585 | return this.__view(ptr, (end - ptr + 1)); 1586 | } 1587 | 1588 | __readString(ptr) { 1589 | return this.__decodeString(this.__readStringView(ptr)); 1590 | } 1591 | 1592 | __writeString(str, stack) { 1593 | const buf = this.__encodeString(str); 1594 | 1595 | const ptr = this.__allocate(buf.byteLength); 1596 | if (stack) stack.push(ptr); 1597 | 1598 | const memory = new Uint8Array(this[DATA].memory.buffer); 1599 | memory.set(buf, ptr); 1600 | 1601 | return ptr; 1602 | } 1603 | 1604 | __writeArray(arg, stack) { 1605 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(arg instanceof ArrayBuffer || ArrayBuffer.isView(arg), 1606 | 'Argument must be an ArrayBuffer or a TypedArray (like Uint8Array)'); 1607 | 1608 | const arr = (!ArrayBuffer.isView(arg)) ? new Uint8Array(arg) : arg; 1609 | 1610 | const len = (this[DATA].isAssemblyScript) 1611 | ? arr.byteLength + 16 /* Array/ArrayBuffer header */ 1612 | : arr.byteLength; 1613 | 1614 | const ptr = this.__allocate(len); 1615 | if (stack) stack.push(ptr); 1616 | 1617 | const memory = new Uint8Array(this[DATA].memory.buffer); 1618 | const data = Object(__WEBPACK_IMPORTED_MODULE_2__misc__["f" /* toUint8Array */])(arr); 1619 | 1620 | if (this[DATA].isAssemblyScript) { 1621 | this.__view().setUint32(ptr + 0, ptr + 8, true); // arraybuffer ptr 1622 | this.__view().setUint32(ptr + 4, arr.length, true); // array length 1623 | this.__view().setUint32(ptr + 8, arr.byteLength, true); // byteLength 1624 | memory.set(data, ptr + 16); // contents 1625 | } else { 1626 | memory.set(data, ptr); 1627 | } 1628 | 1629 | return ptr; 1630 | } 1631 | 1632 | __readStruct(ptr, StructType) { 1633 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(!!StructType, 'No struct StructType given'); 1634 | 1635 | const view = this.__view(ptr, StructType.width); 1636 | const struct = StructType.read(view, this.utils); 1637 | 1638 | return struct; 1639 | } 1640 | 1641 | __writeStruct(value, Type) { 1642 | // if struct has already been allocated: 1643 | if (!Object(__WEBPACK_IMPORTED_MODULE_2__misc__["d" /* isNil */])(value) && value.ref && value.ref()) return value.ref(); 1644 | 1645 | const StructType = Type || value.constructor; 1646 | const ptr = this.__allocate(StructType.width); 1647 | const view = this.__view(ptr, StructType.width); 1648 | 1649 | StructType.write(view, value, this.utils); 1650 | 1651 | return ptr; 1652 | } 1653 | 1654 | __readPointer(ptr, ptrType) { 1655 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(!!ptrType, 'No pointer type given'); 1656 | 1657 | // get the size of what the pointer points to 1658 | const view = this.__view(ptr, ptrType.type.width); 1659 | 1660 | // handle pointer of a pointer cases (structs are pointers too here) 1661 | if (ptrType.type.isStruct || ptrType.type.isPointer) { 1662 | return ptrType.read(view, this.utils); 1663 | } 1664 | 1665 | const pointer = new __WEBPACK_IMPORTED_MODULE_0__types__["b" /* Pointer */](ptrType.type); 1666 | pointer.view = view; 1667 | pointer.wrapper = this.utils; 1668 | 1669 | return pointer; 1670 | } 1671 | 1672 | __writePointer(pointer) { 1673 | if (pointer.ref()) return pointer.ref(); 1674 | 1675 | pointer.wrapper = this.utils; 1676 | 1677 | // allocate space for what the pointer points to 1678 | const size = pointer.size(); 1679 | const addr = this.__allocate(size); 1680 | const view = this.__view(addr, size); 1681 | 1682 | pointer.view = view; 1683 | pointer.commit(); 1684 | 1685 | return addr; 1686 | } 1687 | } 1688 | 1689 | 1690 | function cwrap(instance, fnName, returnType = null, argTypes = []) { 1691 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(instance instanceof WebAssembly.Instance, 1692 | '.cwrap() requires a ready WebAssembly.Instance'); 1693 | 1694 | const wrapper = new Wrapper({ [fnName]: [returnType, argTypes] }); 1695 | wrapper.use(instance); 1696 | 1697 | return wrapper[fnName].bind(wrapper); 1698 | } 1699 | 1700 | function ccall(instance, fnName, returnType = null, argTypes = [], ...args) { 1701 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["c" /* assert */])(instance instanceof WebAssembly.Instance, 1702 | '.ccall() requires a ready WebAssembly.Instance'); 1703 | 1704 | const wrapper = new Wrapper({ [fnName]: [returnType, argTypes] }); 1705 | wrapper.use(instance); 1706 | 1707 | return wrapper[fnName].call(wrapper, ...args); 1708 | } 1709 | 1710 | 1711 | 1712 | 1713 | 1714 | /***/ }), 1715 | /* 7 */ 1716 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 1717 | 1718 | "use strict"; 1719 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Struct__ = __webpack_require__(3); 1720 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__types__ = __webpack_require__(0); 1721 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__encoding__ = __webpack_require__(2); 1722 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__misc__ = __webpack_require__(1); 1723 | 1724 | 1725 | 1726 | 1727 | 1728 | 1729 | // get the symbol for struct-data since we need access here 1730 | const DATA = (typeof Symbol !== 'undefined') 1731 | ? Symbol.for('struct-data') 1732 | : '__data'; 1733 | 1734 | 1735 | function RustTuple(tupleTypes, values) { 1736 | const fields = {}; 1737 | 1738 | tupleTypes.forEach((type, i) => { 1739 | fields[i] = Object(__WEBPACK_IMPORTED_MODULE_1__types__["d" /* parseType */])(type); 1740 | }); 1741 | 1742 | const Tuple = new __WEBPACK_IMPORTED_MODULE_0__Struct__["a" /* default */](fields); 1743 | 1744 | return (values) 1745 | ? new Tuple(values) 1746 | : Tuple; 1747 | } 1748 | 1749 | 1750 | function RustVector(typedef, initialValues) { 1751 | const type = Object(__WEBPACK_IMPORTED_MODULE_1__types__["d" /* parseType */])(typedef); 1752 | 1753 | const Base = new __WEBPACK_IMPORTED_MODULE_0__Struct__["a" /* default */]({ 1754 | ptr: __WEBPACK_IMPORTED_MODULE_1__types__["e" /* types */].pointer(type), 1755 | cap: 'usize', 1756 | length: 'usize', 1757 | /* values */ 1758 | }); 1759 | 1760 | Object.defineProperty(Base.prototype, 'values', { 1761 | enumerable: true, 1762 | 1763 | get() { 1764 | const memory = this[DATA].view.buffer; 1765 | const wrapper = this[DATA].wrapper; 1766 | 1767 | const arrayType = Object(__WEBPACK_IMPORTED_MODULE_1__types__["d" /* parseType */])([type, this.length]); 1768 | const view = new DataView(memory, this.ptr.ref(), arrayType.width); 1769 | 1770 | return arrayType.read(view, wrapper); 1771 | }, 1772 | 1773 | set(values) { 1774 | this.ptr = new __WEBPACK_IMPORTED_MODULE_1__types__["b" /* Pointer */]([type, values.length], values); 1775 | this.length = values.length; 1776 | this.cap = values.length; 1777 | }, 1778 | }); 1779 | 1780 | Object(__WEBPACK_IMPORTED_MODULE_3__misc__["a" /* addArrayFns */])(Base); 1781 | Object(__WEBPACK_IMPORTED_MODULE_3__misc__["e" /* makeIterable */])(Base); 1782 | 1783 | class Vector extends Base { 1784 | constructor(values) { 1785 | super(); 1786 | if (values) this.values = values; 1787 | } 1788 | 1789 | free() { 1790 | super.free(true); // free ptr data 1791 | } 1792 | } 1793 | 1794 | return (initialValues) 1795 | ? new Vector(initialValues) 1796 | : Vector; 1797 | } 1798 | 1799 | 1800 | function RustSlice(typedef, initialValues) { 1801 | const type = Object(__WEBPACK_IMPORTED_MODULE_1__types__["d" /* parseType */])(typedef); 1802 | 1803 | const Base = new __WEBPACK_IMPORTED_MODULE_0__Struct__["a" /* default */]({ 1804 | ptr: __WEBPACK_IMPORTED_MODULE_1__types__["e" /* types */].pointer(type), 1805 | length: 'usize', 1806 | /* values */ 1807 | }); 1808 | 1809 | Object.defineProperty(Base.prototype, 'values', { 1810 | enumerable: true, 1811 | 1812 | get() { 1813 | const memory = this[DATA].view.buffer; 1814 | const wrapper = this[DATA].wrapper; 1815 | 1816 | const arrayType = Object(__WEBPACK_IMPORTED_MODULE_1__types__["d" /* parseType */])([type, this.length]); 1817 | const view = new DataView(memory, this.ptr.ref(), arrayType.width); 1818 | 1819 | return arrayType.read(view, wrapper); 1820 | }, 1821 | 1822 | set(values) { 1823 | this.ptr = new __WEBPACK_IMPORTED_MODULE_1__types__["b" /* Pointer */]([type, values.length], values); 1824 | this.length = values.length; 1825 | }, 1826 | }); 1827 | 1828 | Object(__WEBPACK_IMPORTED_MODULE_3__misc__["a" /* addArrayFns */])(Base); 1829 | Object(__WEBPACK_IMPORTED_MODULE_3__misc__["e" /* makeIterable */])(Base); 1830 | 1831 | class Slice extends Base { 1832 | constructor(values) { 1833 | super(); 1834 | if (values) this.values = values; 1835 | } 1836 | 1837 | free() { 1838 | super.free(true); // free ptr data 1839 | } 1840 | } 1841 | 1842 | return (initialValues) 1843 | ? new Slice(initialValues) 1844 | : Slice; 1845 | } 1846 | 1847 | 1848 | function RustString() { 1849 | const Base = new __WEBPACK_IMPORTED_MODULE_0__Struct__["a" /* default */]({ 1850 | ptr: __WEBPACK_IMPORTED_MODULE_1__types__["e" /* types */].pointer('u8'), 1851 | length: 'usize', 1852 | cap: 'usize', 1853 | /* value */ 1854 | }); 1855 | 1856 | Object.defineProperty(Base.prototype, 'value', { 1857 | enumerable: true, 1858 | 1859 | get() { 1860 | const memory = this[DATA].view.buffer; 1861 | const buf = new Uint8Array(memory, this.ptr.ref(), this.length); 1862 | 1863 | return Object(__WEBPACK_IMPORTED_MODULE_2__encoding__["a" /* decode */])(buf); 1864 | }, 1865 | 1866 | set(str) { 1867 | const buf = Object(__WEBPACK_IMPORTED_MODULE_2__encoding__["c" /* encode */])(str); 1868 | 1869 | this.ptr = new __WEBPACK_IMPORTED_MODULE_1__types__["b" /* Pointer */](['u8', buf.length], buf); 1870 | this.length = buf.length; 1871 | this.cap = buf.length; 1872 | }, 1873 | }); 1874 | 1875 | Object(__WEBPACK_IMPORTED_MODULE_3__misc__["b" /* addStringFns */])(Base); 1876 | 1877 | class _RustString extends Base { 1878 | constructor(value) { 1879 | super(); 1880 | if (value) this.value = value; 1881 | } 1882 | 1883 | free() { 1884 | super.free(true); // free ptr data 1885 | } 1886 | } 1887 | 1888 | return _RustString; 1889 | } 1890 | 1891 | 1892 | function RustStr() { 1893 | const Base = new __WEBPACK_IMPORTED_MODULE_0__Struct__["a" /* default */]({ 1894 | ptr: __WEBPACK_IMPORTED_MODULE_1__types__["e" /* types */].pointer('u8'), 1895 | length: 'usize', 1896 | /* value */ 1897 | }); 1898 | 1899 | Object.defineProperty(Base.prototype, 'value', { 1900 | enumerable: true, 1901 | 1902 | get() { 1903 | const memory = this[DATA].view.buffer; 1904 | const buf = new Uint8Array(memory, this.ptr.ref(), this.length); 1905 | 1906 | return Object(__WEBPACK_IMPORTED_MODULE_2__encoding__["a" /* decode */])(buf); 1907 | }, 1908 | 1909 | set(str) { 1910 | const buf = Object(__WEBPACK_IMPORTED_MODULE_2__encoding__["c" /* encode */])(str); 1911 | 1912 | this.ptr = new __WEBPACK_IMPORTED_MODULE_1__types__["b" /* Pointer */](['u8', buf.length], buf); 1913 | this.length = buf.length; 1914 | }, 1915 | }); 1916 | 1917 | Object(__WEBPACK_IMPORTED_MODULE_3__misc__["b" /* addStringFns */])(Base); 1918 | 1919 | class _RustStr extends Base { 1920 | constructor(value) { 1921 | super(); 1922 | if (value) this.value = value; 1923 | } 1924 | 1925 | free() { 1926 | super.free(true); // free ptr data 1927 | } 1928 | } 1929 | 1930 | return _RustStr; 1931 | } 1932 | 1933 | 1934 | function RustOption(typedef, isNonNullable = false, tagSize) { 1935 | const type = Object(__WEBPACK_IMPORTED_MODULE_1__types__["d" /* parseType */])(typedef); 1936 | let discriminant; 1937 | 1938 | if (tagSize) discriminant = __WEBPACK_IMPORTED_MODULE_1__types__["e" /* types */][`uint${tagSize * 8}`]; 1939 | else if (type.alignment === 1) discriminant = 'uint8'; 1940 | else if (type.alignment === 2) discriminant = 'uint16'; 1941 | else discriminant = 'uint32'; 1942 | 1943 | const fields = (isNonNullable) 1944 | ? { value: type } 1945 | : { discriminant, value: type }; 1946 | 1947 | const Base = new __WEBPACK_IMPORTED_MODULE_0__Struct__["a" /* default */](fields); 1948 | 1949 | class OptionType extends Base { 1950 | constructor(value) { 1951 | super(); 1952 | this.value = value; 1953 | this.discriminant = (Object(__WEBPACK_IMPORTED_MODULE_3__misc__["d" /* isNil */])(value)) ? 0 : 1; 1954 | } 1955 | 1956 | static some(value) { 1957 | return new OptionType(value); 1958 | } 1959 | 1960 | static none() { 1961 | return new OptionType(); 1962 | } 1963 | 1964 | isSome() { 1965 | return ('discriminant' in fields) ? !!this.discriminant : !!this.value; 1966 | } 1967 | 1968 | isNone() { 1969 | return !this.isSome(); 1970 | } 1971 | 1972 | expect(msg) { 1973 | if (!this.isSome()) throw new Error(msg); 1974 | return this.value; 1975 | } 1976 | 1977 | unwrap() { 1978 | if (!this.isSome()) throw new Error('Error unwrapping none'); 1979 | return this.value; 1980 | } 1981 | 1982 | unwrapOr(defaultValue) { 1983 | return (this.isSome()) ? this.value : defaultValue; 1984 | } 1985 | 1986 | unwrapOrElse(fn) { 1987 | return (this.isSome()) ? this.value : fn(); 1988 | } 1989 | } 1990 | 1991 | return OptionType; 1992 | } 1993 | 1994 | 1995 | function RustEnum(obj, tagSize = 4) { 1996 | const variants = Object.getOwnPropertyNames(obj); 1997 | const vtypes = variants.map(name => Object(__WEBPACK_IMPORTED_MODULE_1__types__["d" /* parseType */])(obj[name])); 1998 | const discriminant = __WEBPACK_IMPORTED_MODULE_1__types__["e" /* types */][`uint${tagSize * 8}`]; 1999 | 2000 | const StructType = new __WEBPACK_IMPORTED_MODULE_0__Struct__["a" /* default */]({ 2001 | discriminant, 2002 | /* value */ 2003 | }); 2004 | 2005 | class Enum extends StructType { 2006 | constructor(variant) { 2007 | super(); 2008 | if (variant) this._set(variant); 2009 | } 2010 | 2011 | _set(variant) { 2012 | Object(__WEBPACK_IMPORTED_MODULE_3__misc__["c" /* assert */])(Object.keys(variant).length === 1, 'Enum value must be a variant'); 2013 | 2014 | const [name, value] = Object.entries(variant)[0]; 2015 | 2016 | this.discriminant = variants.indexOf(name); 2017 | this.value = value; 2018 | } 2019 | 2020 | tag() { 2021 | const tag = this.discriminant; 2022 | Object(__WEBPACK_IMPORTED_MODULE_3__misc__["c" /* assert */])(tag <= variants.length, 'Enum discriminant > than # of variants'); 2023 | return tag; 2024 | } 2025 | 2026 | free(internal = false) { 2027 | const type = vtypes[this.tag()]; 2028 | 2029 | if (internal && type.isPointer || type.isStruct) { 2030 | this.value.free(internal); 2031 | } 2032 | 2033 | this[DATA].wrapper.free(this.ref(), Enum.width); 2034 | this[DATA].wrapper = null; 2035 | this[DATA].view = null; 2036 | } 2037 | 2038 | name() { 2039 | return variants[this.tag()]; 2040 | } 2041 | 2042 | is(name) { 2043 | return (variants.indexOf(name) === this.tag()); 2044 | } 2045 | 2046 | match(arms) { 2047 | const name = variants[this.tag()]; 2048 | const val = this.value; 2049 | 2050 | if (name in arms) { 2051 | return (typeof arms[name] === 'function') ? arms[name](val) : arms[name]; 2052 | } 2053 | 2054 | if ('_' in arms) { 2055 | return (typeof arms._ === 'function') ? arms._(val) : arms._; 2056 | } 2057 | } 2058 | 2059 | static write(view, struct, wrapper) { 2060 | if (Object(__WEBPACK_IMPORTED_MODULE_3__misc__["d" /* isNil */])(struct) || !struct.constructor.isStruct) { 2061 | struct = new Enum(struct); 2062 | } 2063 | 2064 | const tag = struct.tag(); 2065 | const type = vtypes[tag]; 2066 | let value = (struct.ref()) ? struct.value : struct[DATA].temp.value; 2067 | 2068 | if (type.isStruct && (Object(__WEBPACK_IMPORTED_MODULE_3__misc__["d" /* isNil */])(value) || !value.constructor.isStruct)) { 2069 | value = new type(value); 2070 | } 2071 | 2072 | const field_1 = Object(__WEBPACK_IMPORTED_MODULE_3__misc__["g" /* vslice */])(view, 0, discriminant.width); 2073 | discriminant.write(field_1, tag); 2074 | 2075 | const field_2 = Object(__WEBPACK_IMPORTED_MODULE_3__misc__["g" /* vslice */])(view, discriminant.width, type.width); 2076 | type.write(field_2, value, wrapper); 2077 | 2078 | struct[DATA].view = view; 2079 | struct[DATA].wrapper = wrapper; 2080 | } 2081 | } 2082 | 2083 | Object.defineProperty(Enum.prototype, 'value', { 2084 | enumerable: true, 2085 | 2086 | get() { 2087 | const memory = this[DATA].view.buffer; 2088 | const wrapper = this[DATA].wrapper; 2089 | 2090 | const type = vtypes[this.tag()]; 2091 | const addr = this.ref() + discriminant.width; 2092 | const view = new DataView(memory, addr, type.width); 2093 | 2094 | return type.read(view, wrapper); 2095 | }, 2096 | 2097 | set(value) { 2098 | this[DATA].temp.value = value; 2099 | }, 2100 | }); 2101 | 2102 | const width = discriminant.width + Math.max(...vtypes.map(t => t.width)); 2103 | const align = Math.max(...vtypes.map(t => t.alignment), discriminant.alignment); 2104 | 2105 | Enum.width = (width % align) 2106 | ? width + align - (width % align) 2107 | : width; 2108 | 2109 | return Enum; 2110 | } 2111 | 2112 | 2113 | const rust = { 2114 | tuple: RustTuple, 2115 | vector: RustVector, 2116 | slice: RustSlice, 2117 | string: RustString(), 2118 | str: RustStr(), 2119 | enum: RustEnum, 2120 | option: RustOption, 2121 | 2122 | some: function ctor(type, value, ...opts) { 2123 | return new (RustOption(type, ...opts))(value); 2124 | }, 2125 | none: function ctor(type, ...opts) { 2126 | return new (RustOption(type, ...opts))(); 2127 | }, 2128 | 2129 | // deprecated 2130 | Tuple: RustTuple, 2131 | Vector: RustVector, 2132 | Slice: RustSlice, 2133 | String: RustString(), 2134 | Str: RustStr(), 2135 | Option: function ctor(type, value, ...opts) { 2136 | return new (RustOption(type, ...opts))(value); 2137 | }, 2138 | Some: function ctor(type, value, ...opts) { 2139 | return new (RustOption(type, ...opts))(value); 2140 | }, 2141 | None: function ctor(type, ...opts) { 2142 | return new (RustOption(type, ...opts))(); 2143 | }, 2144 | }; 2145 | 2146 | 2147 | /* harmony default export */ __webpack_exports__["a"] = (rust); 2148 | 2149 | 2150 | /***/ }), 2151 | /* 8 */ 2152 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 2153 | 2154 | "use strict"; 2155 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Struct__ = __webpack_require__(3); 2156 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__types__ = __webpack_require__(0); 2157 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__misc__ = __webpack_require__(1); 2158 | 2159 | 2160 | 2161 | 2162 | 2163 | // get the symbol for struct-data since we need access here 2164 | const DATA = (typeof Symbol !== 'undefined') 2165 | ? Symbol.for('struct-data') 2166 | : '__data'; 2167 | 2168 | 2169 | function ASArrayBuffer(typedef, n) { 2170 | const type = Object(__WEBPACK_IMPORTED_MODULE_1__types__["d" /* parseType */])(typedef); 2171 | 2172 | return new __WEBPACK_IMPORTED_MODULE_0__Struct__["a" /* default */]({ 2173 | byteLength: 'usize', 2174 | _: 'usize', // allocator alignment? 2175 | values: [type, n], 2176 | }); 2177 | } 2178 | 2179 | 2180 | function ASArray(typedef, initialValues) { 2181 | const type = Object(__WEBPACK_IMPORTED_MODULE_1__types__["d" /* parseType */])(typedef); 2182 | 2183 | const Base = new __WEBPACK_IMPORTED_MODULE_0__Struct__["a" /* default */]({ 2184 | ptr: __WEBPACK_IMPORTED_MODULE_1__types__["e" /* types */].pointer('void'), 2185 | length: 'usize', 2186 | /* buffer */ 2187 | /* values */ 2188 | }); 2189 | 2190 | Object.defineProperty(Base.prototype, 'buffer', { 2191 | enumerable: true, 2192 | 2193 | get() { 2194 | const memory = this[DATA].view.buffer; 2195 | const wrapper = this[DATA].wrapper; 2196 | 2197 | const AB = new ASArrayBuffer(type, this.length); 2198 | const view = new DataView(memory, this.ptr.ref(), AB.width); 2199 | 2200 | return AB.read(view, wrapper); 2201 | }, 2202 | }); 2203 | 2204 | Object.defineProperty(Base.prototype, 'values', { 2205 | enumerable: true, 2206 | 2207 | get() { 2208 | return this.buffer.values; 2209 | }, 2210 | 2211 | set(values) { 2212 | const n = values.length; 2213 | const byteLength = n * type.width; 2214 | 2215 | const AB = new ASArrayBuffer(type, n); 2216 | const buf = new AB({ byteLength, values }); 2217 | 2218 | this.ptr = new __WEBPACK_IMPORTED_MODULE_1__types__["b" /* Pointer */](AB, buf); 2219 | this.length = n; 2220 | }, 2221 | }); 2222 | 2223 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["a" /* addArrayFns */])(Base); 2224 | Object(__WEBPACK_IMPORTED_MODULE_2__misc__["e" /* makeIterable */])(Base); 2225 | 2226 | class _Array extends Base { 2227 | constructor(values) { 2228 | super(); 2229 | if (values) this.values = values; 2230 | } 2231 | 2232 | free() { 2233 | super.free(true); // free buffer_ too 2234 | } 2235 | 2236 | dataview(field) { 2237 | if (field === 'buffer') return this.buffer.dataview(); 2238 | if (field === 'values') return this.buffer.dataview('values'); 2239 | 2240 | return super.dataview(field); 2241 | } 2242 | } 2243 | 2244 | return (initialValues) 2245 | ? new _Array(initialValues) 2246 | : _Array; 2247 | } 2248 | 2249 | 2250 | /* harmony default export */ __webpack_exports__["a"] = ({ 2251 | array: ASArray, 2252 | }); 2253 | 2254 | 2255 | /***/ }) 2256 | /******/ ]); -------------------------------------------------------------------------------- /wasm/wasm-ffi/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::{CStr, CString}; 2 | use std::os::raw::{c_char, c_void}; 3 | 4 | extern "C" { 5 | fn rotate(); 6 | fn get_input_value(selector: *const c_char) -> u32; 7 | } 8 | 9 | #[no_mangle] 10 | pub fn say(ptr: *const c_char) -> *const c_char { 11 | assert!(!ptr.is_null()); 12 | 13 | let hello = unsafe { CStr::from_ptr(ptr) }; 14 | let greeting = format!("{}, World!", hello.to_string_lossy()); 15 | 16 | CString::new(greeting).unwrap().into_raw() 17 | } 18 | 19 | #[no_mangle] 20 | pub fn get_sum(ptr: *const u32, length: usize) -> u32 { 21 | assert!(!ptr.is_null()); 22 | 23 | let slice = unsafe { std::slice::from_raw_parts(ptr, length) }; 24 | 25 | slice.iter().sum() 26 | } 27 | 28 | #[no_mangle] 29 | pub fn get_pointer() -> *mut u32 { 30 | Box::into_raw(Box::new(123)) 31 | } 32 | 33 | #[no_mangle] 34 | pub fn pass_pointer(ptr: *mut u32) -> u32 { 35 | assert!(!ptr.is_null()); 36 | let value = unsafe { &mut *ptr }; 37 | 38 | *value 39 | } 40 | 41 | #[repr(C)] 42 | pub struct Person { 43 | name: *const c_char, 44 | age: u8, 45 | favorite_number: u32, 46 | } 47 | 48 | #[no_mangle] 49 | pub fn get_person() -> *mut Person { 50 | let name = CString::new("Jean-Luc Picard").unwrap(); 51 | 52 | Box::into_raw(Box::new(Person { 53 | name: name.into_raw(), 54 | age: 61, 55 | favorite_number: 1701, 56 | })) 57 | } 58 | 59 | #[no_mangle] 60 | pub fn person_facts(ptr: *mut Person) -> *const c_char { 61 | assert!(!ptr.is_null()); 62 | let person = unsafe { &mut *ptr }; 63 | let name = unsafe { CStr::from_ptr(person.name).to_string_lossy() }; 64 | 65 | let fact = if person.age as u32 > person.favorite_number { 66 | format!("{} is older than his favorite_number", name) 67 | } else { 68 | format!("{} is younger than his favorite_number", name) 69 | }; 70 | 71 | CString::new(fact).unwrap().into_raw() 72 | } 73 | 74 | #[no_mangle] 75 | pub fn barrel_roll() { 76 | unsafe { rotate() }; 77 | } 78 | 79 | #[no_mangle] 80 | pub fn multiply_input(dom_selector: *const c_char) -> u32 { 81 | unsafe { get_input_value(dom_selector) * 2 } 82 | } 83 | 84 | #[no_mangle] 85 | pub fn allocate(length: usize) -> *mut c_void { 86 | let mut v = Vec::with_capacity(length); 87 | let ptr = v.as_mut_ptr(); 88 | std::mem::forget(v); 89 | ptr 90 | } 91 | 92 | #[no_mangle] 93 | pub fn deallocate(ptr: *mut c_void, length: usize) { 94 | unsafe { 95 | std::mem::drop(Vec::from_raw_parts(ptr, 0, length)); 96 | } 97 | } 98 | --------------------------------------------------------------------------------