wasmerio / wasmer Goto Github PK
View Code? Open in Web Editor NEW🚀 The leading Wasm Runtime supporting WASIX, WASI and Emscripten
Home Page: https://wasmer.io/
License: MIT License
🚀 The leading Wasm Runtime supporting WASIX, WASI and Emscripten
Home Page: https://wasmer.io/
License: MIT License
for example:
invoke_iiiiiii
___cxa_end_catch
___cxa_begin_catch
_llvm_eh_typeid_for
_pthread_getspecific
_pthread_key_create
_pthread_once
and so on
you can try to run the attached wasm file and you will find these missed.
It's it possible to use wasmer from a native application written in C++?
This is a very interesting project, and I’m searching for a way to use it.
I’d really like to try building a graph database in a browser. ArangoDB is a graph database built on C++ and javascript so it seems like a nice place to start.
Question is, have you been able to build any other native DBs with wasmer, e.g. postgres or sqlite?
I should be able to combine two import objects from different origins. For example, I should be able to mix my own functions into the Emscripten import object.
See also PR #190.
I was wondering if you have a goal in mind to make wasmer suitable for embedded devices.
Thanks.
I'm very interested in this tool and while I was reading it's architecture docs I was wishing there were references to the implementations in code.
I wrote a tool to accomplish exactly this: https://github.com/vitiral/artifact
Would you be interested in me migrating the architecture docs in artifact, then re-exporting them as ARCHITECTURE.md
? The advantages would be:
Currently, instance calls start_func
automatically when created here https://github.com/wasmerio/wasmer/blob/master/lib/runtime-core/src/instance.rs#L69
Before calling start_func
, I want to be able to modify Ctx
by modifying .data
first. Would be nice to move it out of Instance::new().
Context:
We are using gas meter injector that adds some runtime callback after every operation in wasm. I assume it also modifies start_func and inserts some gas meter calls there as well. Since ctx.data is null at this moment it fails with the following error: CallError(Runtime(Unknown { msg: "trap at 0x40 - segmentation violation" }))
The latest release is 0.1.4 while the crate on crates.io
is 0.1.0. Considering wasmer
is just a single program, crates.io
should be a perfect place to distribute it. Why left it behind?
I was able to get it from:
https://www.wasmjit.org/blog/hello-world.html
Which points to
https://www.dropbox.com/sh/lmz3nnz92jx9szh/AAA-YOEHxwM_nki8jX0uFRuqa?dl=0
That when run results in:
▲ wasmer run nginx.wasm
thread 'main' panicked at 'illegal instruction', src/sighandler.rs:28:23
note: Run with `RUST_BACKTRACE=1` for a backtrace.
▲ wasmer run nginx.wasm
thread 'main' panicked at 'illegal instruction', src/sighandler.rs:28:23
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
1: std::sys_common::backtrace::print
2: std::panicking::default_hook::{{closure}}
3: std::panicking::default_hook
4: std::panicking::rust_panic_with_hook
5: std::panicking::begin_panic
6: wasmer::sighandler::install_sighandler
7: wasmer::main
8: std::rt::lang_start::{{closure}}
9: std::panicking::try::do_call
10: __rust_maybe_catch_panic
11: std::rt::lang_start_internal
12: main
Running wasmer
on:
▲ uname -a
Darwin Guillermos-MacBook-Air.local 18.2.0 Darwin Kernel Version 18.2.0: Fri Oct 5 19:40:55 PDT 2018; root:xnu-4903.221.2~1/RELEASE_X86_64 x86_64
When running the lua.wasm
example on macOS 10.14.1
the program segfaults when you attempt to define a function.
Reproduction:
examples :: λ → wasmer run lua.wasm
Lua 5.4.0 Copyright (C) 1994-2018 Lua.org, PUC-Rio
> function foo
"Runtime(Unknown { msg: \"trap at 0x0 - segmentation violation\" })"
emcc
can generate symbol maps (0:func_name\n1:func_name2...
), wasmer should have a debug option to use these in the debug logs
part of #225
Hi, I am playing around with using the rust runtime to create plugins and I have run into an issue with creating and putting values in a vector.
For a minimal reproduction, take the example here then create and push to a vector inside the hello_wasm function.
#[no_mangle]
pub extern fn hello_wasm() {
// Call the function we just imported and pass in
// the offset of our string and its length as parameters.
let mut vec = Vec::new();
for i in 0..10 {
vec.push(i);
}
unsafe {
print_str(HELLO.as_ptr(), HELLO.len());
}
}
When you run it now, it will panic when you try to instantiate the wasm module.
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:355:21
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at src/libstd/sys_common/backtrace.rs:59
at src/libstd/panicking.rs:211
3: std::panicking::default_hook
at src/libstd/panicking.rs:227
4: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:491
5: std::panicking::continue_panic_fmt
at src/libstd/panicking.rs:398
6: rust_begin_unwind
at src/libstd/panicking.rs:325
7: core::panicking::panic_fmt
at src/libcore/panicking.rs:95
8: core::panicking::panic
at src/libcore/panicking.rs:59
9: wasmer_clif_backend::resolver::FuncResolverBuilder::finalize
10: wasmer_clif_backend::module::Module::compile
11: <wasmer_clif_backend::CraneliftCompiler as wasmer_runtime_core::backend::Compiler>::compile
12: wasmer_runtime_core::compile_with
13: wasmer_runtime::instantiate
14: application::main
15: std::rt::lang_start::{{closure}}
16: std::panicking::try::do_call
at src/libstd/rt.rs:59
at src/libstd/panicking.rs:310
17: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:102
18: std::rt::lang_start_internal
at src/libstd/panicking.rs:289
at src/libstd/panic.rs:398
at src/libstd/rt.rs:58
19: main
20: __libc_start_main
21: _start
EDIT: I stepped through with gdb and it looks like it is panicking on this line
EDIT2: The same thing happens when I try to use a hashmap
use std::collections::HashMap;
#[no_mangle]
pub extern fn hello_wasm() {
// Call the function we just imported and pass in
// the offset of our string and its length as parameters.
let mut hashmap: HashMap<u8, u8> = HashMap::new();
hashmap.insert(0, 0);
unsafe {
print_str(HELLO.as_ptr(), HELLO.len());
}
}
Hi,
I've tried to cache Module completely in memory, but most of the APIs are crate specific. I was able to clone Module and reuse it for the next instance. But it seems crashing my tests.
One option would be just add Clone on Cache.
And if we have Clone on Cache, it would make sense to remove unsafe from into_module
for instances that were cloned and not recovered from disk
Would be great to have the build requirements available alongside the build steps. For eg Ubuntu Linux distros it could list to apt install
line that you'd need to run to pull i the necessary dependencies before compiling wasmer. Here's a good example: https://github.com/servo/servo#other-dependencies
Also, noting that this doesn't build in Windows (yet) would help folks debug the build (I also had problems getting it building on wsl though I didn't dive deep into it yet to see why)
Please add type str for imported functions.
I was thinking about what it would take to support text input for emacripten based apps. Does this work with wasmer?
Basically I’m interested in writing a roguelike on wasmer.
Also could be useful for apps that have command line input after execution.
Keeping all dependencies up-to-date is time consuming. We want to automate that.
https://github.com/marketplace/dependabot/ is a bot (used by rustwasm for instance) to delegate that job. PR example: rustwasm/wasm-snip#23.
This issue is related to #51, windows support. When PR #175 lands, wasmer will have experimental support for windows! This is exciting, but does not mean work is finished. Wasmer will only be able to run simple programs that do not use Emscripten, so no nginx or lua. The reason is that the required syscalls have not been implemented for the Windows target.
There are stubs left for unimplemented functions. Not all of the functions make sense on windows, so a more documented stub should be created if that is what is required. The end result is being able to run programs like nginx and lua, which also means that we can run the existing integration tests. When the stubs are filled and tests are passing, we can close this issue.
The to-be-implemented functions are listed below. The functions should be at least partially tested.
https://github.com/wasmerio/wasmer/blob/master/lib/emscripten/src/syscalls/windows.rs:
https://github.com/wasmerio/wasmer/blob/master/lib/emscripten/src/io/windows.rs:
Enable the tests:
I've been thinking lately about how to use Wasmer as a general-purpose embedder for sandboxed scripting (I'm sure I'm not the only one).
However, there is that venerable problem that, at this point in time, it's not exactly easy to pass around data across the Wasm boundary.
There is, of course, wasm-bindgen
, however, as far as I can tell, it is specifically tailored for the JS <-> RustWasm use-case. It generates the necessary Rust boilerplate on the Wasm side, and complements it with some JS boilerplate on the JS side. Its under-the-hood operations are also non-trivial (you can see just by how much if you try to cargo-expand one of their "small" examples).
Unless I am missing something, this means that we can't really rely on wasm-bindgen
for the use-case where the host application is not a browser (such as with Wasmer), and we need some other solution, and as far as I know, there isn't any at the moment.
So, I'm curious if there's any discussion and/or plans regarding this, both in Wasmer and in the broader Wasm ecosystem, especially now with the growing interest of using Wasm as a general-purpose target rather than Web-only.
There's also the host bindings and reference types proposals, which might make this a little bit easier, but they are still going to take some time to go through. Not to mention that I'm really just a pleb and don't really have any idea what I'm talking about. What can we do now to make our lives easier?
As a simple case study, for now it might be useful to examine just Rust (Native) <-> Rust (Wasm) interop in the scope of Wasmer. For example:
Passing a struct (by value) Native -> Wasm:
However, this use-case is right now impossible in Wasmer, because Wasmer only exposes immutable access to an instance's linear memory. There's no (safe?) way to do this.
The wasmer_runtime::Ctx
struct has the data
and data_finalizer
fields, though no documentation explaining their purpose (I suspect it's a raw pointer to the linear memory). Perhaps with some unsafe glue it'd be possible?
Anyway, I'm extremely curious whether there are any plans for Wasmer to expand in this direction, and whether I should try and dabble in this myself, or wait for the project to mature some more. Thanks!
There seem to be a few barriers to windows support. There is an outstanding bug on wabt-rs
that prevents building on windows. There is a hacky work around, but non-ideal.
The codebase also seems to import many linux-only libraries, so those would have to refactored or conditionally compiled.
Windows support would be a big win for portability, which I imagine is a priority for a tool that aims to be a cross-platform wasm runtime.
Something for you:
https://docs.rs/sthash - https://github.com/jedisct1/rust-sthash
Note that you will need to generate and store a secret seed (once for the whole cache). This is critical in order to protect against forgery, especially with large files.
Hi .. I am understanding CraneLift and related tools and I'm trying to use them to compile and run a standalone (no js or html needed) wasm programs. It is my understanding that CraneLift provides an IR and APIs for optimizing/manipulating WASM and generating executable code. This is what I want to understand. Since wasmer uses cranelift I thought this would be a good place to start to see an end-to-end process of executing WASM in a runtime. However, I am having trouble getting started. I've installed wasmer and am looking for a simple "helloworld" example that will print. The docs point me to a nginx.wasm file which I am not familiar with (google searches show it is some server code?) but when I run it I get this error message:
wasmer run nginx.wasm
nginx: [alert] could not open error log file: open() "/usr/local/nginx/logs/error.log" failed (1: Operation not permitted)
Runtime error: trap at 0x0 - segmentation violation
Since that error log doesn't exist I take it I should have installed something related to nginx first. Clearly this example is more complicated than what I am looking for right now. How should I get started with something straight forward. If I am starting with C and trying to simply print "Hello" compiling this code to WASM using emcc it is not clear to me how to properly create the C file (i.e., should it have a main? what flags do I use) to properly execute using wasmer. Any suggestions?
I am trying to compile and run the emscripten tests (make emtests
). I try and run an output wasm file for example clock_gettime.wasm
and get the following error:
"Can\'t instantiate module: LinkError([ImportNotFound { namespace: \"env\", name: \"_emscripten_get_heap_size\" }, ImportNotFound { namespace: \"env\", name: \"_emscripten_resize_heap\" }, IncorrectImportSignature { namespace: \"env\", name: \"abortOnCannotGrowMemory\", expected: FuncSig { params: [I32], returns: [I32] }, found: FuncSig { params: [], returns: [I32] } }])"
Comparing the resulting wasm files it looks like the type for abortOnCannotGrowMemory
has changed from:
(type $t2 (func (result i32)))
to
(type $t1 (func (param i32) (result i32)))
It also looks like _emscripten_get_heap_size
and _emscripten_resize_heap
are missing. These are not even imported in the original wasm.
It seems like this may be an issue with emscripten and not wasmer. I am using emscripten version 1.38.26.
Hello fellow wasmerians,
In order to continue our quest to quality, I propose to deny warnings. I think it's the first baby step to code quality.
Thus, I'm proposing to add #![deny(warnings)]
into all crates.
Thoughts?
Progression:
clif-backend
,dynasm-backend
,emscripten
,llvm-backend
,runtime
,runtime-abi
,runtime-c-api
,runtime-core
,spectests
,win-exception-handler
.I'm trying to run a very simple Rust program that uses println!
. I'm not sure if this is even supposed to work like I did it (please tell me if not), but certainly the error message could be improved.
The Rust program:
enum E {
A = 0x1234_5678,
B = 0xF321_8765,
}
use std::mem::size_of;
fn main() {
println!("{}", size_of::<E>());
}
Compiled with (current Rust stable or nightly produce the same issue here) rustc test.rs --target=wasm32-unknown-unknown
, then running wasmer run test.wasm
gives this error:
"Resolve(Signature { expected: FuncSig { params: [I32, I32], returns: [I32] }, found: [] })"
(this is on the current wasmer master 7602071)
Unfortunately #183 isn't actually quite resolved yet as the same problem exists for the wasm code calling into the host with an f64 argument. I believe we are dealing with S2 then or something (because of the additional context argument)? I haven't yet investigated this, so I don't quite know enough details yet.
Hello. I was wondering if you intend to support sandboxing and some kind of security model. If it's in the readme or other documentation, I apologize for missing it.
Keys used for cache files only depend on the original wasm file data.
When wasmer is updated or compiled differently, the old cache files keep being silently used forever.
Ideally, a UID generated at compile-time should be used as the BLAKE2B key or salt in order to have a cache directory seamlessly shared by multiple wasmer versions.
Emscripten seems not allow argc == 2, so we cannot pass single arguments for now
$ wasmer run example.wasm -- extra # Segfaults!
There are too many Wasm JITs that seek to provide the same high-level goal! The newest entrant into the foray is Lucet. How would you say that Lucet compares to Wasmer?
Especially with the addition of the dynasm backend to Wasmer and the future addition of Wasi, it looks like this project strives to do everything.
When embedded in a host Rust application, it does not seem to be possible to access the contents of guest global arrays from the host. And it's not even possible to list the exports without linking to wasmer_runtime_core.
For example, if I add the following line to the example in https://github.com/wasmerio/wasmer-rust-example :
#[no_mangle]
pub static mut SCRATCH_I : [u8; 1024] = [0; 1024];
And then loop through instance.exports() in main.rs:
// (at the top of file: ) use wasmer_runtime_core::{export};
for (name, export) in instance.exports() {
match export {
export::Export::Function{ func, ctx, signature } => {println!(" func: {}", name);},
export::Export::Global( global ) => {println!(" global: {}", name);},
_ => {},
}
}
I do get the following:
func: hello_string_from_rust
global: __data_end
func: hello_wasm
global: __heap_base
global: SCRATCH_I
So SCRATCH_I is there.
But how can I access the memory? Global does not seem to have a public way to get the address - if I had that, I could stash it away and then go directly to memory.
Or am I missing something?
I did this
curl https://get.wasmer.io -sSfL | sh
git clone https://github.com/wasmerio/wasmer.git
# sourcing the file as the output instructed me didn't work so I just ran it like this:
~/.wasmer/bin/wasmer run examples/nginx/nginx.wasm -- -p examples/nginx/ -c examples/nginx/nginx.conf
and the output:
â Compiling [======> ] 16%
â Compiling [============> ] 32%
â Compiling [==============================> ] 75% ^[[?64;1;2;6;9;15;18;21;22c
â Compiling [====================================> ] 91%
Runtime error: trap at 0x0 - segmentation violation ] 92%
seems serious
this was on 64 bit linux. (archlinux)
An instance has a context (vm::Ctx
), which is passed as the first argument of any imported function.
In order to integrate the runtime into dynamic languages, we need to add a context per function. So far, to declare an imported function, one must pass a function pointer. Thus, it is not possible to pass a function pointer with an environment/context, which is required in many cases. Think of a closed scope to the function pointer.
I need this for wasmerio/php-ext-wasm and other integrations. In dynamic languages, a function declared in the language land (for instance in the PHP land) has no function pointer. It is a pair of 2 structures. Thus, the strategy to implement imported functions that live in the PHP land is: Register a “dispatcher function” per imported functions, that, given its function context, will look for the appropriated 2 structures, and use them to call the PHP functions.
With a C++-ish pseudocode, it looks like:
int32_t my_imported_dispatcher_function(
const wasmer_instance_context_t *instance_context, /* already here */
const wasmer_function_context_t *function_context, /* NEW! */
int32_t x,
int32_t y
) {
my_structure *function_data = (my_structure *) wasmer_function_context_data_get(function_context);
bool result = php_function_call(function_data->struct1, function_data->struct2);
// …
}
// when registering our imported function, it's classic:
const wasmer_import_func_t *imported_function = wasmer_import_func_new(
(void (*)(void *, void *)) my_imported_dispatcher_function,
inputs_signature,
inputs_signature_length,
outputs_signature,
outputs_signature_length
);
// then, register a specific context for this function:
wasmer_function_context_data_set(
wasmer_function_get_context(imported_function),
my_structure { … }
);
Is there any plan to add support for C#/.Net Core built wasm. Currently Microsoft is using the Blazor https://github.com/aspnet/Blazor project for C# wasm in the browser.
Emscripten uses select
for polling. Select is an inefficient syscall.
We would like to replace the current select
syscall impl with more efficient alternatives on respective platforms.
kevent
and kevent
on macOS and BSD systems.epoll
and co on Linux systems.After updating to the latest nightly (1.32.0-nightly (400c2bc5e 2018-11-27)
), the tests are broken.
The error is something like:
...
test spectests::elem::test_module_18 ... ok
test spectests::elem::test_module_2 ... ok
test spectests::elem::test_module_20 ... ok
error: process didn't exit successfully: `/***/wasmer/target/debug/deps/wasmer-24cae65d1f101576` (signal: 11, SIGSEGV: invalid memory reference)
rustc version:
rustc 1.32.0-nightly (400c2bc5e 2018-11-27)
binary: rustc
commit-hash: 400c2bc5ed292f77c49693320f4eda37bb375e90
commit-date: 2018-11-27
host: x86_64-apple-darwin
release: 1.32.0-nightly
LLVM version: 8.0
Currently wasmer requires a bespoke definition for each invoke/dynCall. This is somewhat non-ideal since the number of invoke_[vid]+
functions is countably infinite. I took a whack at a DynFunc version of invoke, but fn import_functions
returns ImportedFunc
, which won't comfortably hold a DynFunc. It'd be nice to see a clean way to do this!
In an effort to use an instance in an Arc<Mutex< Instance >>, Ctx does not impl Send. After reading the docs, "impl !Send for Ctx" is auto-implemented. Does this mean that I cannot use wasmer in multithreaded applications? Is there a temporary workaround until I can?
This project seems to share many of the goals of https://github.com/CraneStation/wasmtime.
Are they two experiments with the same goals, or are they fundamentally different in some way? Very supportive of both projects!
It would be desirable to be able to execute wasm instruction by instruction and expose the machine's internal instance memory space read only for debugging purposes as well as time sharing. Creation of a debug context containing the textualized Source code and a pointer to the current instruction would help as well.
Hello there,
I would like to propose a feature, that, in my opinion, has great potential for making native WebAssembly modules more popular and useful. The idea is executing WebAssembly modules in ring 0, allowing it to communicate via usual function calls, instead of system calls.
WebAssembly standard itself provides a "guarantee", that the given code will be safe to run in the kernel environment, therefore eliminating the need to execute it in "user-space".
How hard will such an implementation will be in your more professional opinion?
On of the projects implementing the idea: WasmJit
The results of using such a method look very promising, boasting execution times smaller than the execution times of native libraries themselves!
...because it would be rad. I'm imagining something like, opposed to your example (https://medium.com/wasmer/executing-webassembly-in-your-rust-application-d5cd32e8ce46):
#[derive(Wasmable)]
fn print_str(x: u32, y: u32) {
...
}
let import_object = ImportObject::from(vec![
("env", print_str),
]);
Not sure about the details. Seems like it should be possible though.
More specifically, I often find that using macros to define DSL's for building stuff to be a pain in the long run. Either using builders or derives ends up easier to find and deal with, at least IMO. It's a matter of taste though.
(module
(type $t0 (func (result i32)))
(type $t1 (func (param i32 i32 i32) (result i32)))
(import "env" "_emscripten_memcpy_big" (func $env._emscripten_memcpy_big (type $t1)))
(func $main (export "main") (type $t0) (result i32)
i32.const 0)
(memory $memory (export "memory") 2 10)
(global $g0 i32 (i32.const 0))
(global $g1 (mut i32) (i32.const 0)))
Okay, so I've been able to test out wasmer on Windows now and for the most part it seems to work fine, except the occasional segfaults (I have yet to figure out when they happen) and the issue this thread is about: I have an exported function that returns 250.0 f64 value, but the host sees a garbage value instead:
fn main() {
let binary = [
0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x01, 0x23, 0x07, 0x60, 0x03, 0x7F, 0x7F,
0x7F, 0x01, 0x7F, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F, 0x60, 0x02, 0x7F,
0x7F, 0x00, 0x60, 0x01, 0x7F, 0x00, 0x60, 0x01, 0x7F, 0x01, 0x7E, 0x60, 0x00, 0x01, 0x7C,
0x03, 0x0B, 0x0A, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x06, 0x04, 0x05,
0x01, 0x70, 0x01, 0x05, 0x05, 0x05, 0x03, 0x01, 0x00, 0x11, 0x06, 0x19, 0x03, 0x7F, 0x01,
0x41, 0x80, 0x80, 0xC0, 0x00, 0x0B, 0x7F, 0x00, 0x41, 0xB0, 0x82, 0xC0, 0x00, 0x0B, 0x7F,
0x00, 0x41, 0xB0, 0x82, 0xC0, 0x00, 0x0B, 0x07, 0x4D, 0x05, 0x06, 0x6D, 0x65, 0x6D, 0x6F,
0x72, 0x79, 0x02, 0x00, 0x19, 0x5F, 0x5F, 0x69, 0x6E, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74,
0x5F, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x74, 0x61, 0x62, 0x6C, 0x65,
0x01, 0x00, 0x0B, 0x5F, 0x5F, 0x68, 0x65, 0x61, 0x70, 0x5F, 0x62, 0x61, 0x73, 0x65, 0x03,
0x01, 0x0A, 0x5F, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x65, 0x6E, 0x64, 0x03, 0x02, 0x09,
0x67, 0x61, 0x6D, 0x65, 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x00, 0x09, 0x09, 0x0A, 0x01, 0x00,
0x41, 0x01, 0x0B, 0x04, 0x01, 0x02, 0x07, 0x08, 0x0A, 0xCC, 0x0E, 0x0A, 0x89, 0x01, 0x01,
0x01, 0x7F, 0x23, 0x00, 0x41, 0x40, 0x6A, 0x22, 0x00, 0x24, 0x00, 0x20, 0x00, 0x41, 0x10,
0x36, 0x02, 0x0C, 0x20, 0x00, 0x41, 0xAE, 0x81, 0xC0, 0x00, 0x36, 0x02, 0x08, 0x20, 0x00,
0x41, 0x34, 0x6A, 0x41, 0x01, 0x36, 0x02, 0x00, 0x20, 0x00, 0x41, 0x24, 0x6A, 0x41, 0x02,
0x36, 0x02, 0x00, 0x20, 0x00, 0x41, 0x1C, 0x6A, 0x41, 0x02, 0x36, 0x02, 0x00, 0x20, 0x00,
0x41, 0x02, 0x36, 0x02, 0x2C, 0x20, 0x00, 0x41, 0x98, 0x80, 0xC0, 0x00, 0x36, 0x02, 0x18,
0x20, 0x00, 0x41, 0x02, 0x36, 0x02, 0x14, 0x20, 0x00, 0x41, 0xC0, 0x81, 0xC0, 0x00, 0x36,
0x02, 0x10, 0x20, 0x00, 0x20, 0x00, 0x41, 0x38, 0x6A, 0x36, 0x02, 0x30, 0x20, 0x00, 0x20,
0x00, 0x41, 0x08, 0x6A, 0x36, 0x02, 0x28, 0x20, 0x00, 0x20, 0x00, 0x41, 0x28, 0x6A, 0x36,
0x02, 0x20, 0x20, 0x00, 0x41, 0x10, 0x6A, 0x41, 0xD0, 0x81, 0xC0, 0x00, 0x10, 0x03, 0x00,
0x0B, 0x1C, 0x00, 0x20, 0x01, 0x28, 0x02, 0x18, 0x41, 0xA0, 0x81, 0xC0, 0x00, 0x41, 0x0E,
0x20, 0x01, 0x41, 0x1C, 0x6A, 0x28, 0x02, 0x00, 0x28, 0x02, 0x0C, 0x11, 0x00, 0x00, 0x0B,
0xB7, 0x09, 0x01, 0x0D, 0x7F, 0x02, 0x40, 0x02, 0x40, 0x23, 0x00, 0x41, 0x10, 0x6B, 0x22,
0x04, 0x24, 0x00, 0x20, 0x01, 0x28, 0x02, 0x10, 0x21, 0x03, 0x20, 0x00, 0x28, 0x02, 0x04,
0x21, 0x05, 0x20, 0x00, 0x28, 0x02, 0x00, 0x21, 0x07, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40,
0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x08, 0x22, 0x0D,
0x41, 0x01, 0x46, 0x04, 0x40, 0x20, 0x03, 0x0D, 0x01, 0x0C, 0x02, 0x0B, 0x20, 0x03, 0x45,
0x0D, 0x06, 0x0B, 0x20, 0x05, 0x04, 0x40, 0x20, 0x07, 0x20, 0x05, 0x6A, 0x21, 0x0A, 0x20,
0x01, 0x41, 0x14, 0x6A, 0x28, 0x02, 0x00, 0x41, 0x7F, 0x73, 0x21, 0x06, 0x20, 0x07, 0x22,
0x00, 0x21, 0x0E, 0x02, 0x40, 0x02, 0x40, 0x03, 0x40, 0x20, 0x00, 0x41, 0x01, 0x6A, 0x21,
0x03, 0x02, 0x40, 0x20, 0x00, 0x2C, 0x00, 0x00, 0x22, 0x02, 0x41, 0x00, 0x4E, 0x04, 0x40,
0x20, 0x02, 0x41, 0xFF, 0x01, 0x71, 0x21, 0x02, 0x20, 0x03, 0x21, 0x00, 0x20, 0x06, 0x41,
0x01, 0x6A, 0x22, 0x06, 0x0D, 0x01, 0x0C, 0x03, 0x0B, 0x02, 0x40, 0x02, 0x40, 0x20, 0x03,
0x20, 0x0A, 0x47, 0x04, 0x40, 0x20, 0x03, 0x2D, 0x00, 0x00, 0x41, 0x3F, 0x71, 0x21, 0x08,
0x20, 0x00, 0x41, 0x02, 0x6A, 0x22, 0x00, 0x21, 0x03, 0x20, 0x02, 0x41, 0x1F, 0x71, 0x21,
0x0B, 0x20, 0x02, 0x41, 0xFF, 0x01, 0x71, 0x22, 0x02, 0x41, 0xE0, 0x01, 0x49, 0x0D, 0x01,
0x0C, 0x02, 0x0B, 0x41, 0x00, 0x21, 0x08, 0x20, 0x0A, 0x21, 0x00, 0x20, 0x02, 0x41, 0x1F,
0x71, 0x21, 0x0B, 0x20, 0x02, 0x41, 0xFF, 0x01, 0x71, 0x22, 0x02, 0x41, 0xE0, 0x01, 0x4F,
0x0D, 0x01, 0x0B, 0x20, 0x08, 0x20, 0x0B, 0x41, 0x06, 0x74, 0x72, 0x21, 0x02, 0x20, 0x03,
0x21, 0x00, 0x20, 0x06, 0x41, 0x01, 0x6A, 0x22, 0x06, 0x0D, 0x01, 0x0C, 0x03, 0x0B, 0x02,
0x40, 0x02, 0x40, 0x20, 0x00, 0x20, 0x0A, 0x47, 0x04, 0x40, 0x20, 0x00, 0x41, 0x01, 0x6A,
0x22, 0x03, 0x21, 0x0C, 0x20, 0x00, 0x2D, 0x00, 0x00, 0x41, 0x3F, 0x71, 0x20, 0x08, 0x41,
0x06, 0x74, 0x72, 0x21, 0x08, 0x20, 0x02, 0x41, 0xF0, 0x01, 0x49, 0x0D, 0x01, 0x0C, 0x02,
0x0B, 0x20, 0x0A, 0x21, 0x0C, 0x20, 0x08, 0x41, 0x06, 0x74, 0x21, 0x08, 0x20, 0x02, 0x41,
0xF0, 0x01, 0x4F, 0x0D, 0x01, 0x0B, 0x20, 0x08, 0x20, 0x0B, 0x41, 0x0C, 0x74, 0x72, 0x21,
0x02, 0x20, 0x03, 0x21, 0x00, 0x20, 0x06, 0x41, 0x01, 0x6A, 0x22, 0x06, 0x0D, 0x01, 0x0C,
0x03, 0x0B, 0x02, 0x7F, 0x20, 0x0C, 0x20, 0x0A, 0x47, 0x04, 0x40, 0x20, 0x0C, 0x2D, 0x00,
0x00, 0x41, 0x3F, 0x71, 0x21, 0x02, 0x20, 0x0C, 0x41, 0x01, 0x6A, 0x0C, 0x01, 0x0B, 0x41,
0x00, 0x21, 0x02, 0x20, 0x03, 0x0B, 0x21, 0x00, 0x20, 0x08, 0x41, 0x06, 0x74, 0x20, 0x0B,
0x41, 0x12, 0x74, 0x41, 0x80, 0x80, 0xF0, 0x00, 0x71, 0x72, 0x20, 0x02, 0x72, 0x22, 0x02,
0x41, 0x80, 0x80, 0xC4, 0x00, 0x46, 0x0D, 0x03, 0x20, 0x06, 0x41, 0x01, 0x6A, 0x22, 0x06,
0x45, 0x0D, 0x02, 0x0B, 0x20, 0x09, 0x20, 0x0E, 0x6B, 0x20, 0x00, 0x6A, 0x21, 0x09, 0x20,
0x00, 0x21, 0x0E, 0x20, 0x0A, 0x20, 0x00, 0x47, 0x0D, 0x00, 0x0B, 0x0C, 0x01, 0x0B, 0x20,
0x02, 0x41, 0x80, 0x80, 0xC4, 0x00, 0x46, 0x0D, 0x00, 0x02, 0x40, 0x02, 0x40, 0x20, 0x09,
0x45, 0x0D, 0x00, 0x20, 0x09, 0x20, 0x05, 0x46, 0x0D, 0x00, 0x41, 0x00, 0x21, 0x00, 0x20,
0x09, 0x20, 0x05, 0x4F, 0x0D, 0x01, 0x20, 0x07, 0x20, 0x09, 0x6A, 0x2C, 0x00, 0x00, 0x41,
0x40, 0x48, 0x0D, 0x01, 0x0B, 0x20, 0x07, 0x21, 0x00, 0x0B, 0x20, 0x09, 0x20, 0x05, 0x20,
0x00, 0x1B, 0x21, 0x05, 0x20, 0x00, 0x20, 0x07, 0x20, 0x00, 0x1B, 0x21, 0x07, 0x0B, 0x20,
0x0D, 0x45, 0x0D, 0x08, 0x0C, 0x01, 0x0B, 0x41, 0x00, 0x21, 0x05, 0x20, 0x0D, 0x45, 0x0D,
0x07, 0x0B, 0x41, 0x00, 0x21, 0x03, 0x20, 0x05, 0x04, 0x40, 0x20, 0x05, 0x21, 0x02, 0x20,
0x07, 0x21, 0x00, 0x03, 0x40, 0x20, 0x03, 0x20, 0x00, 0x2D, 0x00, 0x00, 0x41, 0xC0, 0x01,
0x71, 0x41, 0x80, 0x01, 0x46, 0x6A, 0x21, 0x03, 0x20, 0x00, 0x41, 0x01, 0x6A, 0x21, 0x00,
0x20, 0x02, 0x41, 0x7F, 0x6A, 0x22, 0x02, 0x0D, 0x00, 0x0B, 0x0B, 0x20, 0x05, 0x20, 0x03,
0x6B, 0x20, 0x01, 0x41, 0x0C, 0x6A, 0x28, 0x02, 0x00, 0x22, 0x06, 0x4F, 0x0D, 0x06, 0x41,
0x00, 0x21, 0x03, 0x20, 0x05, 0x04, 0x40, 0x20, 0x05, 0x21, 0x02, 0x20, 0x07, 0x21, 0x00,
0x03, 0x40, 0x20, 0x03, 0x20, 0x00, 0x2D, 0x00, 0x00, 0x41, 0xC0, 0x01, 0x71, 0x41, 0x80,
0x01, 0x46, 0x6A, 0x21, 0x03, 0x20, 0x00, 0x41, 0x01, 0x6A, 0x21, 0x00, 0x20, 0x02, 0x41,
0x7F, 0x6A, 0x22, 0x02, 0x0D, 0x00, 0x0B, 0x0B, 0x20, 0x03, 0x20, 0x05, 0x6B, 0x20, 0x06,
0x6A, 0x21, 0x02, 0x41, 0x00, 0x20, 0x01, 0x2D, 0x00, 0x30, 0x22, 0x00, 0x20, 0x00, 0x41,
0x03, 0x46, 0x1B, 0x41, 0x03, 0x71, 0x22, 0x00, 0x45, 0x0D, 0x01, 0x20, 0x00, 0x41, 0x02,
0x46, 0x0D, 0x02, 0x41, 0x00, 0x21, 0x06, 0x0C, 0x03, 0x00, 0x0B, 0x00, 0x0B, 0x20, 0x02,
0x21, 0x06, 0x41, 0x00, 0x21, 0x02, 0x0C, 0x01, 0x0B, 0x20, 0x02, 0x41, 0x01, 0x6A, 0x41,
0x01, 0x76, 0x21, 0x06, 0x20, 0x02, 0x41, 0x01, 0x76, 0x21, 0x02, 0x0B, 0x20, 0x04, 0x41,
0x00, 0x36, 0x02, 0x0C, 0x02, 0x7F, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x00, 0x41, 0xFF,
0x00, 0x4D, 0x04, 0x40, 0x20, 0x04, 0x20, 0x00, 0x3A, 0x00, 0x0C, 0x41, 0x01, 0x0C, 0x01,
0x0B, 0x20, 0x00, 0x41, 0xFF, 0x0F, 0x4D, 0x04, 0x40, 0x20, 0x04, 0x20, 0x00, 0x41, 0x3F,
0x71, 0x41, 0x80, 0x01, 0x72, 0x3A, 0x00, 0x0D, 0x20, 0x04, 0x20, 0x00, 0x41, 0x06, 0x76,
0x41, 0x1F, 0x71, 0x41, 0xC0, 0x01, 0x72, 0x3A, 0x00, 0x0C, 0x41, 0x02, 0x0C, 0x01, 0x0B,
0x20, 0x00, 0x41, 0xFF, 0xFF, 0x03, 0x4D, 0x04, 0x40, 0x20, 0x04, 0x20, 0x00, 0x41, 0x3F,
0x71, 0x41, 0x80, 0x01, 0x72, 0x3A, 0x00, 0x0E, 0x20, 0x04, 0x20, 0x00, 0x41, 0x06, 0x76,
0x41, 0x3F, 0x71, 0x41, 0x80, 0x01, 0x72, 0x3A, 0x00, 0x0D, 0x20, 0x04, 0x20, 0x00, 0x41,
0x0C, 0x76, 0x41, 0x0F, 0x71, 0x41, 0xE0, 0x01, 0x72, 0x3A, 0x00, 0x0C, 0x41, 0x03, 0x0C,
0x01, 0x0B, 0x20, 0x04, 0x20, 0x00, 0x41, 0x3F, 0x71, 0x41, 0x80, 0x01, 0x72, 0x3A, 0x00,
0x0F, 0x20, 0x04, 0x20, 0x00, 0x41, 0x12, 0x76, 0x41, 0xF0, 0x01, 0x72, 0x3A, 0x00, 0x0C,
0x20, 0x04, 0x20, 0x00, 0x41, 0x06, 0x76, 0x41, 0x3F, 0x71, 0x41, 0x80, 0x01, 0x72, 0x3A,
0x00, 0x0E, 0x20, 0x04, 0x20, 0x00, 0x41, 0x0C, 0x76, 0x41, 0x3F, 0x71, 0x41, 0x80, 0x01,
0x72, 0x3A, 0x00, 0x0D, 0x41, 0x04, 0x0B, 0x21, 0x03, 0x41, 0x7F, 0x21, 0x00, 0x02, 0x40,
0x02, 0x40, 0x02, 0x40, 0x03, 0x40, 0x20, 0x00, 0x41, 0x01, 0x6A, 0x22, 0x00, 0x20, 0x02,
0x4F, 0x0D, 0x01, 0x20, 0x01, 0x41, 0x18, 0x6A, 0x28, 0x02, 0x00, 0x20, 0x04, 0x41, 0x0C,
0x6A, 0x20, 0x03, 0x20, 0x01, 0x41, 0x1C, 0x6A, 0x28, 0x02, 0x00, 0x28, 0x02, 0x0C, 0x11,
0x00, 0x00, 0x45, 0x0D, 0x00, 0x0B, 0x0C, 0x04, 0x0B, 0x20, 0x01, 0x41, 0x18, 0x6A, 0x22,
0x02, 0x28, 0x02, 0x00, 0x20, 0x07, 0x20, 0x05, 0x20, 0x01, 0x41, 0x1C, 0x6A, 0x22, 0x01,
0x28, 0x02, 0x00, 0x28, 0x02, 0x0C, 0x11, 0x00, 0x00, 0x45, 0x0D, 0x01, 0x0B, 0x0C, 0x02,
0x0B, 0x41, 0x7F, 0x21, 0x00, 0x02, 0x40, 0x03, 0x40, 0x20, 0x00, 0x41, 0x01, 0x6A, 0x22,
0x00, 0x20, 0x06, 0x4F, 0x0D, 0x01, 0x20, 0x02, 0x28, 0x02, 0x00, 0x20, 0x04, 0x41, 0x0C,
0x6A, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x00, 0x28, 0x02, 0x0C, 0x11, 0x00, 0x00, 0x45,
0x0D, 0x00, 0x0B, 0x0C, 0x02, 0x0B, 0x20, 0x04, 0x41, 0x10, 0x6A, 0x24, 0x00, 0x41, 0x00,
0x0F, 0x0B, 0x20, 0x01, 0x28, 0x02, 0x18, 0x20, 0x07, 0x20, 0x05, 0x20, 0x01, 0x41, 0x1C,
0x6A, 0x28, 0x02, 0x00, 0x28, 0x02, 0x0C, 0x11, 0x00, 0x00, 0x21, 0x00, 0x20, 0x04, 0x41,
0x10, 0x6A, 0x24, 0x00, 0x20, 0x00, 0x0F, 0x0B, 0x20, 0x04, 0x41, 0x10, 0x6A, 0x24, 0x00,
0x41, 0x01, 0x0F, 0x0B, 0x20, 0x01, 0x28, 0x02, 0x18, 0x20, 0x07, 0x20, 0x05, 0x20, 0x01,
0x41, 0x1C, 0x6A, 0x28, 0x02, 0x00, 0x28, 0x02, 0x0C, 0x11, 0x00, 0x00, 0x21, 0x00, 0x20,
0x04, 0x41, 0x10, 0x6A, 0x24, 0x00, 0x20, 0x00, 0x0B, 0x4A, 0x02, 0x01, 0x7F, 0x01, 0x7E,
0x23, 0x00, 0x41, 0x20, 0x6B, 0x22, 0x02, 0x24, 0x00, 0x20, 0x01, 0x29, 0x02, 0x00, 0x21,
0x03, 0x20, 0x02, 0x41, 0x14, 0x6A, 0x20, 0x01, 0x29, 0x02, 0x08, 0x37, 0x02, 0x00, 0x20,
0x02, 0x20, 0x03, 0x37, 0x02, 0x0C, 0x20, 0x02, 0x20, 0x00, 0x36, 0x02, 0x08, 0x20, 0x02,
0x41, 0xE0, 0x81, 0xC0, 0x00, 0x36, 0x02, 0x04, 0x20, 0x02, 0x41, 0xE0, 0x80, 0xC0, 0x00,
0x36, 0x02, 0x00, 0x20, 0x02, 0x10, 0x05, 0x00, 0x0B, 0x6D, 0x01, 0x01, 0x7F, 0x41, 0x01,
0x21, 0x00, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x41, 0x88, 0x82, 0xC0, 0x00, 0x28, 0x02,
0x00, 0x41, 0x01, 0x46, 0x04, 0x40, 0x41, 0x8C, 0x82, 0xC0, 0x00, 0x41, 0x8C, 0x82, 0xC0,
0x00, 0x28, 0x02, 0x00, 0x41, 0x01, 0x6A, 0x22, 0x00, 0x36, 0x02, 0x00, 0x20, 0x00, 0x41,
0x03, 0x49, 0x0D, 0x01, 0x0C, 0x02, 0x0B, 0x41, 0x88, 0x82, 0xC0, 0x00, 0x42, 0x81, 0x80,
0x80, 0x80, 0x10, 0x37, 0x03, 0x00, 0x0B, 0x41, 0x90, 0x82, 0xC0, 0x00, 0x28, 0x02, 0x00,
0x22, 0x01, 0x41, 0x7F, 0x4C, 0x0D, 0x00, 0x41, 0x90, 0x82, 0xC0, 0x00, 0x20, 0x01, 0x36,
0x02, 0x00, 0x20, 0x00, 0x41, 0x02, 0x49, 0x0D, 0x01, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x41,
0x01, 0x02, 0x7F, 0x23, 0x00, 0x41, 0x10, 0x6B, 0x22, 0x01, 0x24, 0x00, 0x02, 0x7F, 0x20,
0x00, 0x28, 0x02, 0x08, 0x22, 0x02, 0x20, 0x02, 0x0D, 0x00, 0x1A, 0x41, 0xF0, 0x81, 0xC0,
0x00, 0x10, 0x06, 0x00, 0x0B, 0x1A, 0x20, 0x01, 0x20, 0x00, 0x41, 0x14, 0x6A, 0x29, 0x02,
0x00, 0x37, 0x03, 0x08, 0x20, 0x01, 0x20, 0x00, 0x29, 0x02, 0x0C, 0x37, 0x03, 0x00, 0x20,
0x01, 0x10, 0x04, 0x00, 0x0B, 0x68, 0x02, 0x01, 0x7F, 0x03, 0x7E, 0x23, 0x00, 0x41, 0x30,
0x6B, 0x22, 0x01, 0x24, 0x00, 0x20, 0x00, 0x29, 0x02, 0x08, 0x21, 0x02, 0x20, 0x00, 0x29,
0x02, 0x10, 0x21, 0x03, 0x20, 0x00, 0x29, 0x02, 0x00, 0x21, 0x04, 0x20, 0x01, 0x41, 0x14,
0x6A, 0x41, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x04, 0x37, 0x03, 0x18, 0x20, 0x01,
0x41, 0xE0, 0x80, 0xC0, 0x00, 0x36, 0x02, 0x10, 0x20, 0x01, 0x42, 0x01, 0x37, 0x02, 0x04,
0x20, 0x01, 0x20, 0x01, 0x41, 0x18, 0x6A, 0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x03, 0x37,
0x03, 0x28, 0x20, 0x01, 0x20, 0x02, 0x37, 0x03, 0x20, 0x20, 0x01, 0x20, 0x01, 0x41, 0x20,
0x6A, 0x10, 0x03, 0x00, 0x0B, 0x03, 0x00, 0x01, 0x0B, 0x0C, 0x00, 0x42, 0x8E, 0xF4, 0xBC,
0xB0, 0xF7, 0x9B, 0xAF, 0xC8, 0x2D, 0x0B, 0x74, 0x01, 0x01, 0x7C, 0x02, 0x40, 0x41, 0x98,
0x82, 0xC0, 0x00, 0x29, 0x03, 0x00, 0x42, 0x01, 0x51, 0x04, 0x40, 0x41, 0xA0, 0x82, 0xC0,
0x00, 0x28, 0x02, 0x00, 0x0D, 0x01, 0x41, 0xA8, 0x82, 0xC0, 0x00, 0x2B, 0x03, 0x00, 0x21,
0x00, 0x41, 0xA0, 0x82, 0xC0, 0x00, 0x41, 0x00, 0x36, 0x02, 0x00, 0x20, 0x00, 0x0F, 0x0B,
0x41, 0xA8, 0x82, 0xC0, 0x00, 0x42, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xD0, 0xB7, 0xC0,
0x00, 0x37, 0x03, 0x00, 0x41, 0x98, 0x82, 0xC0, 0x00, 0x42, 0x01, 0x37, 0x03, 0x00, 0x41,
0xA0, 0x82, 0xC0, 0x00, 0x41, 0x00, 0x36, 0x02, 0x00, 0x41, 0xA0, 0x82, 0xC0, 0x00, 0x41,
0x00, 0x36, 0x02, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6F, 0x40, 0x0F, 0x0B,
0x10, 0x00, 0x00, 0x0B, 0x0B, 0x95, 0x02, 0x02, 0x00, 0x41, 0x80, 0x80, 0xC0, 0x00, 0x0B,
0xBE, 0x01, 0x3A, 0x20, 0x73, 0x72, 0x63, 0x2F, 0x6C, 0x69, 0x62, 0x63, 0x6F, 0x72, 0x65,
0x2F, 0x72, 0x65, 0x73, 0x75, 0x6C, 0x74, 0x2E, 0x72, 0x73, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x63, 0x61, 0x6C, 0x6C, 0x65, 0x64, 0x20,
0x60, 0x4F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x3A, 0x75, 0x6E, 0x77, 0x72, 0x61, 0x70,
0x28, 0x29, 0x60, 0x20, 0x6F, 0x6E, 0x20, 0x61, 0x20, 0x60, 0x4E, 0x6F, 0x6E, 0x65, 0x60,
0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x73, 0x72, 0x63, 0x2F, 0x6C, 0x69, 0x62, 0x63, 0x6F,
0x72, 0x65, 0x2F, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x2E, 0x72, 0x73, 0x42, 0x6F, 0x72,
0x72, 0x6F, 0x77, 0x4D, 0x75, 0x74, 0x45, 0x72, 0x72, 0x6F, 0x72, 0x61, 0x6C, 0x72, 0x65,
0x61, 0x64, 0x79, 0x20, 0x62, 0x6F, 0x72, 0x72, 0x6F, 0x77, 0x65, 0x64, 0x00, 0x41, 0xC0,
0x81, 0xC0, 0x00, 0x0B, 0x45, 0x60, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x15, 0x00, 0x00, 0x00, 0xF1,
0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x60, 0x00, 0x10, 0x00, 0x2B, 0x00, 0x00,
0x00, 0x8B, 0x00, 0x10, 0x00, 0x15, 0x00, 0x00, 0x00, 0x63, 0x01, 0x00, 0x00, 0x15, 0x00,
0x51, 0x09, 0x70, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x65, 0x72, 0x73, 0x02, 0x08, 0x6C, 0x61,
0x6E, 0x67, 0x75, 0x61, 0x67, 0x65, 0x01, 0x04, 0x52, 0x75, 0x73, 0x74, 0x04, 0x32, 0x30,
0x31, 0x38, 0x0C, 0x70, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x2D, 0x62, 0x79,
0x01, 0x05, 0x72, 0x75, 0x73, 0x74, 0x63, 0x1D, 0x31, 0x2E, 0x33, 0x32, 0x2E, 0x30, 0x20,
0x28, 0x39, 0x66, 0x64, 0x61, 0x37, 0x63, 0x32, 0x32, 0x33, 0x20, 0x32, 0x30, 0x31, 0x39,
0x2D, 0x30, 0x31, 0x2D, 0x31, 0x36, 0x29,
];
let import_object = wasmer_runtime::imports! {};
let instance = wasmer_runtime::instantiate(&binary, &import_object).unwrap();
if let Ok(func) = instance.func::<(), f64>("game_time") {
let ret_val = func.call().unwrap();
println!("{}", ret_val);
}
}
The game_time function as WAST looks like this:
(func $game_time (type $t6) (result f64)
(local $l0 f64)
block $B0
i32.const 1048856
i64.load
i64.const 1
i64.eq
if $I1
i32.const 1048864
i32.load
br_if $B0
i32.const 1048872
f64.load
set_local $l0
i32.const 1048864
i32.const 0
i32.store
get_local $l0
return
end
i32.const 1048872
i64.const 4643000109586448384
i64.store
i32.const 1048856
i64.const 1
i64.store
i32.const 1048864
i32.const 0
i32.store
i32.const 1048864
i32.const 0
i32.store
f64.const 0x1.f4p+7 (;=250;)
return
end
call $f0
unreachable)
This is the original source of the wasm file:
use std::cell::RefCell;
struct Context {
val: f64,
}
fn build_context() -> RefCell<Context> {
RefCell::new(Context {
val: 250.0,
})
}
thread_local! {
static CONTEXT: RefCell<Context> = build_context();
}
#[no_mangle]
pub extern "C" fn game_time() -> f64 {
CONTEXT.with(|ctx| {
ctx.borrow_mut().val
})
}
It does not break if I return 250.0 as a constant instead. So the thread_local RefCell is important (maybe just a static or thread_local would suffice, not sure yet).
This may or may not be broken on Linux and macOS too.
I want to run wasmer on bare metal. Is it on the roadmap?
Hello fellow wasmerians,
I would like to propose to forbid missing documentations, with #[deny(missing_docs)]
. I think it's important to provide a strong documentation and a strong code quality. This attribute is a first step in that direction. It will also ease contributions.
If everyone agrees, I think it would be great to create one issue per crate so that it's easier to track the progression.
Thoughts?
I try to build wasmer with carto and Android NDK have some problems,Is the project planned to run on Android?
Would it be possible to make wabt/wat optional and put it in default features, so you can turn it off with default-features = false
?
WASI is a WebAssembly System Interface.
Here's a detailed blogpost from Mozilla about it: https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/
Wasmer should support WASI, in a similar way we support emscripten.
So binaries/libraries can be executed with wasmer easily.
Rust is also trying to target wasi
from rust libraries: rust-lang/rust#59464
WASI API: https://github.com/CraneStation/wasmtime-wasi/blob/wasi/docs/WASI-api.md
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.