diff --git a/doc/crates.js b/doc/crates.js
index 03ca93387a..a5dfadc6d0 100644
--- a/doc/crates.js
+++ b/doc/crates.js
@@ -1 +1 @@
-window.ALL_CRATES = ["___Theseus_Crates___","acpi","acpi_table","acpi_table_handler","ap_start","apic","app_io","async_channel","ata","atomic_linked_list","block_allocator","block_cache","bootloader_modules","captain","catch_unwind","color","compositor","console","context_switch","context_switch_avx","context_switch_regular","context_switch_sse","cow_arc","crate_metadata","crate_name_utils","crate_swap","debug_info","debugit","deferred_interrupt_tasks","device_manager","dfqueue","displayable","dmar","e1000","entryflags_x86_64","environment","ethernet_smoltcp_device","event_types","exceptions_early","exceptions_full","fadt","fault_crate_swap","fault_log","first_application","font","frame_allocator","framebuffer","framebuffer_compositor","framebuffer_drawer","framebuffer_printer","fs_node","gdt","heap","heapfile","hpet","http_client","intel_ethernet","interrupts","io","ioapic","iommu","ixgbe","kernel_config","keyboard","keycodes_ascii","libterm","libtest","lockable","logger","madt","mapper_spillful","memfs","memory","memory_initialization","memory_structs","memory_x86_64","mlx5","mlx_ethernet","mod_mgmt","mouse","mouse_data","multicore_bringup","multiple_heaps","mutex_sleep","nano_core","network_interface_card","network_manager","nic_buffers","nic_initialization","nic_queues","ota_update_client","page_allocator","page_table_entry","panic_entry","panic_wrapper","path","pause","pci","percent_encoding","physical_nic","pic","pit_clock","pmu_x86","port_io","print","ps2","rendezvous","root","rsdp","rsdt","rtc","runqueue","runqueue_priority","runqueue_round_robin","scheduler","scheduler_priority","scheduler_round_robin","sdt","serial_port","serial_port_basic","shapes","simd_personality","simd_test","simple_ipc","single_simd_task_optimization","slabmalloc","slabmalloc_safe","slabmalloc_unsafe","smoltcp_helper","spawn","stack","stack_trace","stack_trace_frame_pointers","state_store","state_transfer","stdio","storage_device","storage_manager","task","task_fs","terminal_print","test_thread_local","text_display","text_terminal","thread_local_macro","tlb_shootdown","tsc","tss","unified_channel","unwind","util","vfs_node","vga_buffer","virtual_nic","wait_condition","wait_queue","window","window_inner","window_manager"];
\ No newline at end of file
+window.ALL_CRATES = ["___Theseus_Crates___","acpi","acpi_table","acpi_table_handler","ap_start","apic","app_io","async_channel","ata","atomic_linked_list","block_allocator","block_cache","bootloader_modules","captain","catch_unwind","color","compositor","console","context_switch","context_switch_avx","context_switch_regular","context_switch_sse","cow_arc","crate_metadata","crate_name_utils","crate_swap","debug_info","debugit","deferred_interrupt_tasks","device_manager","dfqueue","displayable","dmar","e1000","entryflags_x86_64","environment","ethernet_smoltcp_device","event_types","exceptions_early","exceptions_full","fadt","fault_crate_swap","fault_log","first_application","font","frame_allocator","framebuffer","framebuffer_compositor","framebuffer_drawer","framebuffer_printer","fs_node","gdt","heap","heapfile","hpet","http_client","intel_ethernet","interrupts","io","ioapic","iommu","ixgbe","kernel_config","keyboard","keycodes_ascii","libterm","libtest","lockable","logger","madt","mapper_spillful","memfs","memory","memory_initialization","memory_structs","memory_x86_64","mlx5","mlx_ethernet","mod_mgmt","mouse","mouse_data","multicore_bringup","multiple_heaps","mutex_sleep","nano_core","network_interface_card","network_manager","nic_buffers","nic_initialization","nic_queues","ota_update_client","page_allocator","page_table_entry","panic_entry","panic_wrapper","path","pause","pci","percent_encoding","physical_nic","pic","pit_clock","pmu_x86","port_io","print","ps2","rendezvous","root","rsdp","rsdt","rtc","runqueue","runqueue_priority","runqueue_round_robin","scheduler","scheduler_priority","scheduler_round_robin","sdt","serial_port","serial_port_basic","shapes","simd_personality","simd_test","simple_ipc","single_simd_task_optimization","slabmalloc","slabmalloc_safe","slabmalloc_unsafe","smoltcp_helper","spawn","stack","stack_trace","stack_trace_frame_pointers","state_store","state_transfer","stdio","storage_device","storage_manager","task","task_fs","terminal_print","test_thread_local","text_display","text_terminal","thread_local_macro","tlb_shootdown","tsc","tss","unified_channel","unwind","util","vfs_node","vga_buffer","virtual_nic","wait_condition","wait_queue","wasi_interpreter","window","window_inner","window_manager"];
\ No newline at end of file
diff --git a/doc/implementors/core/marker/trait.Freeze.js b/doc/implementors/core/marker/trait.Freeze.js
index 637a532da0..894195f8fd 100644
--- a/doc/implementors/core/marker/trait.Freeze.js
+++ b/doc/implementors/core/marker/trait.Freeze.js
@@ -105,6 +105,7 @@ implementors["vga_buffer"] = [{"text":"impl Freeze for VirtualNic<S, T, U, V>","synthetic":true,"types":["virtual_nic::VirtualNic"]}];
implementors["wait_condition"] = [{"text":"impl<F> !Freeze for WaitCondition<F>","synthetic":true,"types":["wait_condition::WaitCondition"]},{"text":"impl<'wc, F> Freeze for SatisfiedWaitCondition<'wc, F>","synthetic":true,"types":["wait_condition::SatisfiedWaitCondition"]}];
implementors["wait_queue"] = [{"text":"impl Freeze for WaitGuard","synthetic":true,"types":["wait_queue::WaitGuard"]},{"text":"impl Freeze for WaitError","synthetic":true,"types":["wait_queue::WaitError"]},{"text":"impl !Freeze for WaitQueue","synthetic":true,"types":["wait_queue::WaitQueue"]}];
+implementors["wasi_interpreter"] = [{"text":"impl Freeze for HostExternals","synthetic":true,"types":["wasi_interpreter::HostExternals"]}];
implementors["window"] = [{"text":"impl Freeze for Window","synthetic":true,"types":["window::Window"]}];
implementors["window_inner"] = [{"text":"impl Freeze for WindowMovingStatus","synthetic":true,"types":["window_inner::WindowMovingStatus"]},{"text":"impl Freeze for WindowInner","synthetic":true,"types":["window_inner::WindowInner"]}];
implementors["window_manager"] = [{"text":"impl Freeze for WindowManager","synthetic":true,"types":["window_manager::WindowManager"]}];
diff --git a/doc/implementors/core/marker/trait.Send.js b/doc/implementors/core/marker/trait.Send.js
index c1242f3427..92bdbe6400 100644
--- a/doc/implementors/core/marker/trait.Send.js
+++ b/doc/implementors/core/marker/trait.Send.js
@@ -105,6 +105,7 @@ implementors["vga_buffer"] = [{"text":"impl Send for VirtualNic<S, T, U, V>","synthetic":true,"types":["virtual_nic::VirtualNic"]}];
implementors["wait_condition"] = [{"text":"impl<F> Send for WaitCondition<F> where F: Send, ","synthetic":true,"types":["wait_condition::WaitCondition"]},{"text":"impl<'wc, F> Send for SatisfiedWaitCondition<'wc, F> where F: Sync, ","synthetic":true,"types":["wait_condition::SatisfiedWaitCondition"]}];
implementors["wait_queue"] = [{"text":"impl Send for WaitGuard","synthetic":true,"types":["wait_queue::WaitGuard"]},{"text":"impl Send for WaitError","synthetic":true,"types":["wait_queue::WaitError"]},{"text":"impl Send for WaitQueue","synthetic":true,"types":["wait_queue::WaitQueue"]}];
+implementors["wasi_interpreter"] = [{"text":"impl !Send for HostExternals","synthetic":true,"types":["wasi_interpreter::HostExternals"]}];
implementors["window"] = [{"text":"impl Send for Window","synthetic":true,"types":["window::Window"]}];
implementors["window_inner"] = [{"text":"impl Send for WindowMovingStatus","synthetic":true,"types":["window_inner::WindowMovingStatus"]},{"text":"impl Send for WindowInner","synthetic":true,"types":["window_inner::WindowInner"]}];
implementors["window_manager"] = [{"text":"impl Send for WindowManager","synthetic":true,"types":["window_manager::WindowManager"]}];
diff --git a/doc/implementors/core/marker/trait.Sync.js b/doc/implementors/core/marker/trait.Sync.js
index a70032aac8..0c8fc79b30 100644
--- a/doc/implementors/core/marker/trait.Sync.js
+++ b/doc/implementors/core/marker/trait.Sync.js
@@ -105,6 +105,7 @@ implementors["vga_buffer"] = [{"text":"impl Sync for VirtualNic<S, T, U, V>","synthetic":true,"types":["virtual_nic::VirtualNic"]}];
implementors["wait_condition"] = [{"text":"impl<F> Sync for WaitCondition<F> where F: Sync, ","synthetic":true,"types":["wait_condition::WaitCondition"]},{"text":"impl<'wc, F> Sync for SatisfiedWaitCondition<'wc, F> where F: Sync, ","synthetic":true,"types":["wait_condition::SatisfiedWaitCondition"]}];
implementors["wait_queue"] = [{"text":"impl Sync for WaitGuard","synthetic":true,"types":["wait_queue::WaitGuard"]},{"text":"impl Sync for WaitError","synthetic":true,"types":["wait_queue::WaitError"]},{"text":"impl Sync for WaitQueue","synthetic":true,"types":["wait_queue::WaitQueue"]}];
+implementors["wasi_interpreter"] = [{"text":"impl !Sync for HostExternals","synthetic":true,"types":["wasi_interpreter::HostExternals"]}];
implementors["window"] = [{"text":"impl Sync for Window","synthetic":true,"types":["window::Window"]}];
implementors["window_inner"] = [{"text":"impl Sync for WindowMovingStatus","synthetic":true,"types":["window_inner::WindowMovingStatus"]},{"text":"impl Sync for WindowInner","synthetic":true,"types":["window_inner::WindowInner"]}];
implementors["window_manager"] = [{"text":"impl Sync for WindowManager","synthetic":true,"types":["window_manager::WindowManager"]}];
diff --git a/doc/implementors/core/marker/trait.Unpin.js b/doc/implementors/core/marker/trait.Unpin.js
index dea8b5fe66..d5b9e69c2d 100644
--- a/doc/implementors/core/marker/trait.Unpin.js
+++ b/doc/implementors/core/marker/trait.Unpin.js
@@ -105,6 +105,7 @@ implementors["vga_buffer"] = [{"text":"impl Unpin for VirtualNic<S, T, U, V> where S: Unpin, U: Unpin, ","synthetic":true,"types":["virtual_nic::VirtualNic"]}];
implementors["wait_condition"] = [{"text":"impl<F> Unpin for WaitCondition<F> where F: Unpin, ","synthetic":true,"types":["wait_condition::WaitCondition"]},{"text":"impl<'wc, F> Unpin for SatisfiedWaitCondition<'wc, F>","synthetic":true,"types":["wait_condition::SatisfiedWaitCondition"]}];
implementors["wait_queue"] = [{"text":"impl Unpin for WaitGuard","synthetic":true,"types":["wait_queue::WaitGuard"]},{"text":"impl Unpin for WaitError","synthetic":true,"types":["wait_queue::WaitError"]},{"text":"impl Unpin for WaitQueue","synthetic":true,"types":["wait_queue::WaitQueue"]}];
+implementors["wasi_interpreter"] = [{"text":"impl Unpin for HostExternals","synthetic":true,"types":["wasi_interpreter::HostExternals"]}];
implementors["window"] = [{"text":"impl Unpin for Window","synthetic":true,"types":["window::Window"]}];
implementors["window_inner"] = [{"text":"impl Unpin for WindowMovingStatus","synthetic":true,"types":["window_inner::WindowMovingStatus"]},{"text":"impl Unpin for WindowInner","synthetic":true,"types":["window_inner::WindowInner"]}];
implementors["window_manager"] = [{"text":"impl Unpin for WindowManager","synthetic":true,"types":["window_manager::WindowManager"]}];
diff --git a/doc/implementors/wasmi/host/trait.Externals.js b/doc/implementors/wasmi/host/trait.Externals.js
new file mode 100644
index 0000000000..c9b7d2d747
--- /dev/null
+++ b/doc/implementors/wasmi/host/trait.Externals.js
@@ -0,0 +1,3 @@
+(function() {var implementors = {};
+implementors["wasi_interpreter"] = [{"text":"impl Externals for HostExternals","synthetic":false,"types":["wasi_interpreter::HostExternals"]}];
+if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})()
\ No newline at end of file
diff --git a/doc/search-index.js b/doc/search-index.js
index 8306d5047a..2e0610ed01 100644
--- a/doc/search-index.js
+++ b/doc/search-index.js
@@ -155,6 +155,7 @@ var searchIndex = JSON.parse('{\
"virtual_nic":{"doc":"This crate defines a struct that enables language-level …","t":[3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["VirtualNic","borrow","borrow_mut","drop","from","get_received_frame","id","into","mac_address","new","poll_receive","send_packet","send_packet_on_queue","try_from","try_into","type_id"],"q":["virtual_nic","","","","","","","","","","","","","","",""],"d":["A structure that contains a set of RxQueues and TxQueues …","","","","","","","","","Create a new VirtualNIC with the given parameters. For …","","","Send a packet on the specified queue.","","",""],"i":[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"f":[null,[[]],[[]],[[]],[[]],[[],[["option",4],["receivedframe",3]]],[[],["u8",15]],[[]],[[]],[[["vec",3],["rxqueue",3],["mutexirqsafe",3],["txqueue",3],["usize",15],["vec",3]],[["virtualnic",3],["str",15],["result",4]]],[[],[["result",4],["str",15]]],[[["transmitbuffer",3]],[["result",4],["str",15]]],[[["usize",15],["transmitbuffer",3]],[["result",4],["str",15]]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]]],"p":[[3,"VirtualNic"]]},\
"wait_condition":{"doc":"Simple condition variables that are convenience wrappers …","t":[3,3,25,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["SatisfiedWaitCondition","WaitCondition","WaitConditionFn","borrow","borrow","borrow_mut","borrow_mut","condition_satisfied","from","from","into","into","new","notify_one","notify_specific","try_from","try_from","try_into","try_into","type_id","type_id","wait"],"q":["wait_condition","","","","","","","","","","","","","","","","","","","","",""],"d":["A type wrapper that guarantees a given condition has been …","A condition variable that allows multiple Tasks to wait …","The closure type that can be used within a WaitCondition: …","","","","","This function should be invoked after the wait condition …","","","","","Create a new WaitCondition in which Tasks can wait for a …","Wake up a random Task that is waiting on this condition.","Wake up a specific Task that is waiting on this condition.","","","","","","","Waits for the condition to be true in a blocking fashion …"],"i":[0,0,0,1,2,1,2,1,1,2,1,2,1,2,2,1,2,1,2,1,2,1],"f":[null,null,null,[[]],[[]],[[]],[[]],[[],[["option",4],["satisfiedwaitcondition",3]]],[[]],[[]],[[]],[[]],[[],["waitcondition",3]],[[],["bool",15]],[[["taskref",3]],["bool",15]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],[["result",4],["waiterror",4]]]],"p":[[3,"WaitCondition"],[3,"SatisfiedWaitCondition"]]},\
"wait_queue":{"doc":"","t":[13,13,13,13,4,3,3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["Interrupted","NoCurrentTask","SpuriousWakeup","Timeout","WaitError","WaitGuard","WaitQueue","block_again","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","drop","eq","fmt","from","from","from","into","into","into","new","new","notify_one","notify_specific","task","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","wait","wait_until","wait_until_mut","with_capacity"],"q":["wait_queue","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["","","","","Errors that may occur while waiting on a …","An object that holds a blocked Task that will be …","A queue in which multiple Tasks can wait for other Tasks …","Blocks the task guarded by this waitguard, which is …","","","","","","","","","","","","","","","","Blocks the given Task and returns a new WaitGuard object …","Create a new empty WaitQueue.","Wake up one random Task that is waiting on this queue.","Wake up a specific Task that is waiting on this queue.","Returns a reference to the Task being blocked in this …","","","","","","","","","","Puts the current Task to sleep where it blocks on this …","Similar to wait, but this function blocks until the given …","Similar to wait_until, but this function accepts a …","Create a new empty WaitQueue."],"i":[1,1,1,1,0,0,0,2,2,3,1,2,3,1,2,1,1,2,3,1,2,3,1,2,3,3,3,2,2,3,1,2,3,1,2,3,1,3,3,3,3],"f":[null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[["waiterror",4]],["bool",15]],[[["formatter",3]],["result",6]],[[]],[[]],[[]],[[]],[[]],[[]],[[["taskref",3]],["waitguard",3]],[[],["waitqueue",3]],[[],["bool",15]],[[["taskref",3]],["bool",15]],[[],["taskref",3]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]],[[],["typeid",3]],[[],[["waiterror",4],["result",4]]],[[["fn",8]],[["result",4],["waiterror",4]]],[[["fnmut",8]],[["result",4],["waiterror",4]]],[[["usize",15]],["waitqueue",3]]],"p":[[4,"WaitError"],[3,"WaitGuard"],[3,"WaitQueue"]]},\
+"wasi_interpreter":{"doc":"Interpreter for executing WASI-compliant WASM binaries.","t":[3,11,11,11,11,5,11,11,11,11,11,14,11,11,11],"n":["HostExternals","as_any","as_any_mut","borrow","borrow_mut","execute_binary","from","into","into_any","into_any_rc","invoke_index","sig","try_from","try_into","type_id"],"q":["wasi_interpreter","","","","","","","","","","","","","",""],"d":["Theseus and wasmi I/O required to execute WASI system …","","","","","Executes a WASI-compliant WebAssembly binary.","","","","","Function used by wasmi to invoke a system call given a …","Macro to efficiently generate wasmi function signature.","","",""],"i":[0,1,1,1,1,0,1,1,1,1,1,0,1,1,1],"f":[null,[[],["any",8]],[[],["any",8]],[[]],[[]],[[["string",3],["vec",3],["vec",3],["u8",15]],["isize",15]],[[]],[[]],[[["box",3],["global",3]],[["box",3],["any",8],["global",3]]],[[["rc",3]],[["any",8],["rc",3]]],[[["usize",15],["runtimeargs",3]],[["trap",3],["result",4],["option",4]]],null,[[],["result",4]],[[],["result",4]],[[],["typeid",3]]],"p":[[3,"HostExternals"]]},\
"window":{"doc":"A Window object should be owned by an application. It can …","t":[3,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["Window","area","borrow","borrow_mut","drop","framebuffer","framebuffer_mut","from","handle_event","into","is_active","new","render","try_from","try_into","type_id"],"q":["window","","","","","","","","","","","","","","",""],"d":["This struct is the application-facing representation of a …","Returns a Rectangle describing the position and …","","","","Returns an immutable reference to this window’s virtual …","Returns a mutable reference to this window’s virtual …","","Tries to receive an Event that has been sent to this …","","Returns true if this window is the currently active …","Creates a new window to be displayed on screen. ","Renders the area of this Window specified by the given …","","",""],"i":[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"f":[null,[[],["rectangle",3]],[[]],[[]],[[]],[[],[["framebuffer",3],["mutexguardref",6],["windowinner",3]]],[[],[["framebuffer",3],["mutexguardrefmut",6],["windowinner",3]]],[[]],[[],[["str",15],["result",4],["option",4]]],[[]],[[],["bool",15]],[[["color",3],["usize",15],["coord",3]],[["str",15],["window",3],["result",4]]],[[["option",4],["rectangle",3]],[["result",4],["str",15]]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]]],"p":[[3,"Window"]]},\
"window_inner":{"doc":"The WindowInner struct is the internal representation of …","t":[17,17,13,13,3,4,12,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,11,11,11,11,12,11,11,11,11,11,11],"n":["DEFAULT_BORDER_SIZE","DEFAULT_TITLE_BAR_HEIGHT","Moving","Stationary","WindowInner","WindowMovingStatus","border_size","borrow","borrow","borrow_mut","borrow_mut","contains","content_area","framebuffer","framebuffer_mut","from","from","get_border_size","get_pixel","get_position","get_size","get_title_bar_height","into","into","moving","new","resize","send_event","set_position","title_bar_height","try_from","try_from","try_into","try_into","type_id","type_id"],"q":["window_inner","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"d":["","","The window is currently in motion. The enclosed Coord …","The window is not in motion.","The WindowInner struct is the internal system-facing …","Whether a window is moving (being dragged by the mouse).","The width of the border in pixels. By default, there is a …","","","","","Returns true if the given coordinate (relative to the …","Returns the position and dimensions of the Window’s …","Returns an immutable reference to this window’s virtual …","Returns a mutable reference to this window’s virtual …","","","Returns the size of the Window border in pixels. There …","Returns the pixel value at the given coordinate, if the …","Gets the top-left position of the window relative to the …","Gets the size of a window in pixels","Returns the size of the Window title bar in pixels. …","","","Whether a window is moving or stationary.","Creates a new WindowInner object backed by the given …","Resizes and moves this window to fit the given Rectangle …","Sends the given event to this window.","Sets the top-left position of the window relative to the …","The height of title bar in pixels. By default, there is …","","","","","",""],"i":[0,0,1,1,0,0,2,1,2,1,2,2,2,2,2,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,1,2,1,2,1,2],"f":[null,null,null,null,null,null,null,[[]],[[]],[[]],[[]],[[["coord",3]],["bool",15]],[[],["rectangle",3]],[[],["framebuffer",3]],[[],["framebuffer",3]],[[]],[[]],[[],["usize",15]],[[["coord",3]],[["option",4],["alphapixel",3]]],[[],["coord",3]],[[]],[[],["usize",15]],[[]],[[]],null,[[["queue",3],["alphapixel",3],["framebuffer",3],["coord",3],["event",4]],["windowinner",3]],[[["rectangle",3]],[["result",4],["str",15]]],[[["event",4]],[["event",4],["result",4]]],[[["coord",3]]],null,[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]],[[],["typeid",3]]],"p":[[4,"WindowMovingStatus"],[3,"WindowInner"]]},\
"window_manager":{"doc":"This crate acts as a manager of a list of windows. It …","t":[7,3,11,11,11,12,11,11,5,11,11,11,11,11,11,11,11,11,11,11,11,11],"n":["WINDOW_MANAGER","WindowManager","borrow","borrow_mut","delete_window","final_fb","from","get_screen_size","init","into","is_active","move_active_window","move_floating_border","refresh_active_window","refresh_bottom_windows","refresh_mouse","refresh_top","refresh_windows","set_active","try_from","try_into","type_id"],"q":["window_manager","","","","","","","","","","","","","","","","","","","","",""],"d":["The instance of the default window manager","Window manager structure which maintains a list of …","","","delete a window and refresh its region","The final framebuffer which is mapped to the screen (the …","","Returns the (width, height) in pixels of the screen …","Initialize the window manager. It returns …","","Returns true if the given window is the currently active …","take active window’s base position and current mouse, …","Move the floating border when a window is moving.","Refresh the part in bounding_box of the active window. …","Refresh the region in bounding_box. Only render the …","Refresh the mouse display","Refresh the region of bounding_box in the top framebuffer","Refresh the part in bounding_box of every window. …","Sets one window as active, push last active (if exists) …","","",""],"i":[0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1],"f":[null,null,[[]],[[]],[[["arc",3]],[["result",4],["str",15]]],null,[[]],[[]],[[],[["str",15],["result",4]]],[[]],[[["arc",3]],["bool",15]],[[],[["result",4],["str",15]]],[[],[["result",4],["str",15]]],[[["option",4],["rectangle",3]],[["result",4],["str",15]]],[[["bool",15]],[["result",4],["str",15]]],[[],[["result",4],["str",15]]],[[],[["result",4],["str",15]]],[[],[["result",4],["str",15]]],[[["bool",15],["arc",3]],[["str",15],["result",4],["bool",15]]],[[],["result",4]],[[],["result",4]],[[],["typeid",3]]],"p":[[3,"WindowManager"]]}\
diff --git a/doc/source-files.js b/doc/source-files.js
index e9ddee28b0..2b2a24ae5d 100644
--- a/doc/source-files.js
+++ b/doc/source-files.js
@@ -155,6 +155,7 @@ sourcesIndex["vga_buffer"] = {"name":"","files":["lib.rs"]};
sourcesIndex["virtual_nic"] = {"name":"","files":["lib.rs"]};
sourcesIndex["wait_condition"] = {"name":"","files":["lib.rs"]};
sourcesIndex["wait_queue"] = {"name":"","files":["lib.rs"]};
+sourcesIndex["wasi_interpreter"] = {"name":"","files":["lib.rs","posix_file_system.rs","wasi_definitions.rs","wasi_syscalls.rs","wasmi_state_machine.rs"]};
sourcesIndex["window"] = {"name":"","files":["lib.rs"]};
sourcesIndex["window_inner"] = {"name":"","files":["lib.rs"]};
sourcesIndex["window_manager"] = {"name":"","files":["lib.rs"]};
diff --git a/doc/src/wasi_interpreter/lib.rs.html b/doc/src/wasi_interpreter/lib.rs.html
new file mode 100644
index 0000000000..0d06106260
--- /dev/null
+++ b/doc/src/wasi_interpreter/lib.rs.html
@@ -0,0 +1,319 @@
+
+//! Module for resolving memory and function imports from WebAssembly module into state machine.
+//!
+//! Subset of functionality borrowed from tomaka/redshirt:
+//! <https://github.com/tomaka/redshirt/blob/4df506f68821353a7fd67bb94c4223df6b683e1b/kernel/core/src/scheduler/vm.rs>
+//!
+
+usealloc::string::String;
+usecore::{cell::RefCell, convert::TryFromas_};
+
+usewasmi::{Module, Signature};
+
+#[derive(Debug)]
+pubenumNewErr {
+ /// Error in the interpreter.
+ Interpreter(wasmi::Error),
+ /// If a "memory" symbol is provided, it must be a memory.
+ MemoryIsntMemory,
+ /// A memory object has both been imported and exported.
+ MultipleMemoriesNotSupported,
+ /// If a "__indirect_function_table" symbol is provided, it must be a table.
+ IndirectTableIsntTable,
+}
+
+pubstructProcessStateMachine {
+ /// Original module, with resolved imports.
+ pubmodule: wasmi::ModuleRef,
+
+ /// Memory of the module instantiation.
+ ///
+ /// Right now we only support one unique `Memory` object per process. This is it.
+ /// Contains `None` if the process doesn't export any memory object, which means it doesn't use
+ /// any memory.
+ pubmemory: Option<wasmi::MemoryRef>,
+
+ /// Table of the indirect function calls.
+ ///
+ /// In WASM, function pointers are in reality indices in a table called
+ /// `__indirect_function_table`. This is this table, if it exists.
+ pubindirect_table: Option<wasmi::TableRef>,
+}
+
+implProcessStateMachine {
+ /// Creates a new process state machine from the given module.
+ ///
+ /// The closure is called for each import that the module has. It must assign a number to each
+ /// import, or return an error if the import can't be resolved. When the VM calls one of these
+ /// functions, this number will be returned back in order for the user to know how to handle
+ /// the call.
+ ///
+ /// A single main thread (whose user data is passed by parameter) is automatically created and
+ /// is paused at the start of the "_start" function of the module.
+ pubfnnew(
+ module: &Module,
+ mutsymbols: implFnMut(&str, &str, &Signature) ->Result<usize, ()>,
+ ) ->Result<Self, NewErr> {
+ structImportResolve<'a> {
+ func: RefCell<&'amutdynFnMut(&str, &str, &Signature) ->Result<usize, ()>>,
+ memory: RefCell<&'amutOption<wasmi::MemoryRef>>,
+ }
+
+ impl<'a>wasmi::ImportResolverforImportResolve<'a> {
+ fnresolve_func(
+ &self,
+ module_name: &str,
+ field_name: &str,
+ signature: &wasmi::Signature,
+ ) ->Result<wasmi::FuncRef, wasmi::Error> {
+ letclosure=&mut**self.func.borrow_mut();
+ letindex=matchclosure(module_name, field_name, signature) {
+ Ok(i) =>i,
+ Err(_) => {
+ returnErr(wasmi::Error::Instantiation(format!(
+ "Couldn't resolve `{}`:`{}`",
+ module_name, field_name
+ )))
+ }
+ };
+
+ Ok(wasmi::FuncInstance::alloc_host(signature.clone(), index))
+ }
+
+ fnresolve_global(
+ &self,
+ _module_name: &str,
+ _field_name: &str,
+ _global_type: &wasmi::GlobalDescriptor,
+ ) ->Result<wasmi::GlobalRef, wasmi::Error> {
+ Err(wasmi::Error::Instantiation(String::from(
+ "Importing globals is not supported yet",
+ )))
+ }
+
+ fnresolve_memory(
+ &self,
+ _module_name: &str,
+ _field_name: &str,
+ memory_type: &wasmi::MemoryDescriptor,
+ ) ->Result<wasmi::MemoryRef, wasmi::Error> {
+ letmutmem=self.memory.borrow_mut();
+ ifmem.is_some() {
+ returnErr(wasmi::Error::Instantiation(String::from(
+ "Only one memory object is supported yet",
+ )));
+ }
+
+ letnew_mem=wasmi::MemoryInstance::alloc(
+ wasmi::memory_units::Pages(usize::try_from(memory_type.initial()).unwrap()),
+ memory_type
+ .maximum()
+ .map(|p|wasmi::memory_units::Pages(usize::try_from(p).unwrap())),
+ )
+ .unwrap();
+ **mem=Some(new_mem.clone());
+ Ok(new_mem)
+ }
+
+ fnresolve_table(
+ &self,
+ _module_name: &str,
+ _field_name: &str,
+ _table_type: &wasmi::TableDescriptor,
+ ) ->Result<wasmi::TableRef, wasmi::Error> {
+ Err(wasmi::Error::Instantiation(String::from(
+ "Importing tables is not supported yet",
+ )))
+ }
+ }
+
+ let (not_started, imported_memory) = {
+ letmutimported_memory=None;
+ letresolve=ImportResolve {
+ func: RefCell::new(&mutsymbols),
+ memory: RefCell::new(&mutimported_memory),
+ };
+ letnot_started=
+ wasmi::ModuleInstance::new(&module, &resolve).map_err(NewErr::Interpreter)?;
+ (not_started, imported_memory)
+ };
+
+ // TODO: WASM has a special "start" instruction that can be used to designate a function
+ // that must be executed before the module is considered initialized. It is unclear whether
+ // this is intended to be a function that for example initializes global variables, or if
+ // this is an equivalent of "_start". In practice, Rust never seems to generate such as
+ // "start" instruction, so for now we ignore it. The code below panics if there is such
+ // a "start" item, so we will fortunately not blindly run into troubles.
+ letmodule=not_started.assert_no_start();
+
+ letmemory=ifletSome(imported_mem) =imported_memory {
+ ifmodule
+ .export_by_name("memory")
+ .map_or(false, |m|m.as_memory().is_some())
+ {
+ returnErr(NewErr::MultipleMemoriesNotSupported);
+ }
+ Some(imported_mem)
+ } elseifletSome(mem) =module.export_by_name("memory") {
+ ifletSome(mem) =mem.as_memory() {
+ Some(mem.clone())
+ } else {
+ returnErr(NewErr::MemoryIsntMemory);
+ }
+ } else {
+ None
+ };
+
+ letindirect_table=ifletSome(tbl) =module.export_by_name("__indirect_function_table") {
+ ifletSome(tbl) =tbl.as_table() {
+ Some(tbl.clone())
+ } else {
+ returnErr(NewErr::IndirectTableIsntTable);
+ }
+ } else {
+ None
+ };
+
+ letstate_machine=ProcessStateMachine {
+ module,
+ memory,
+ indirect_table,
+ };
+
+ Ok(state_machine)
+ }
+}
+
+
+
\ No newline at end of file
diff --git a/doc/wasi_interpreter/all.html b/doc/wasi_interpreter/all.html
new file mode 100644
index 0000000000..ea3a077e92
--- /dev/null
+++ b/doc/wasi_interpreter/all.html
@@ -0,0 +1,7 @@
+List of all items in this crate
+
+
+
\ No newline at end of file
diff --git a/doc/wasi_interpreter/fn.execute_binary.html b/doc/wasi_interpreter/fn.execute_binary.html
new file mode 100644
index 0000000000..bf05150107
--- /dev/null
+++ b/doc/wasi_interpreter/fn.execute_binary.html
@@ -0,0 +1,15 @@
+execute_binary in wasi_interpreter - Rust
+
+
This function constructs a wasmi state machine from a WebAssembly binary, constructs a
+HostExternals object consisting of any necessary Theseus or wasmi I/O, opens file descriptors
+for accessible directories, and executes.
Interpreter for executing WASI-compliant WASM binaries.
+
wasi_interpreter provides an interface between the wasmi crate (used to interpret
+WebAssembly) and Theseus under the assumption of a WASI interface.
+
This library exposes a public method called execute_binary to allow for the execution of a
+WebAssembly binary given directory permissions (in accordance to the WASI capabilities model)
+and arguments.
+
+
+
\ No newline at end of file
diff --git a/doc/wasi_interpreter/macro.sig.html b/doc/wasi_interpreter/macro.sig.html
new file mode 100644
index 0000000000..caee1f37ce
--- /dev/null
+++ b/doc/wasi_interpreter/macro.sig.html
@@ -0,0 +1,14 @@
+sig in wasi_interpreter - Rust
+
+
+
\ No newline at end of file
diff --git a/doc/wasi_interpreter/sidebar-items.js b/doc/wasi_interpreter/sidebar-items.js
new file mode 100644
index 0000000000..346a549e8d
--- /dev/null
+++ b/doc/wasi_interpreter/sidebar-items.js
@@ -0,0 +1 @@
+initSidebarItems({"fn":[["execute_binary","Executes a WASI-compliant WebAssembly binary."]],"macro":[["sig","Macro to efficiently generate wasmi function signature."]],"struct":[["HostExternals","Theseus and wasmi I/O required to execute WASI system calls."]]});
\ No newline at end of file
diff --git a/doc/wasi_interpreter/struct.HostExternals.html b/doc/wasi_interpreter/struct.HostExternals.html
new file mode 100644
index 0000000000..38a2d2bfb5
--- /dev/null
+++ b/doc/wasi_interpreter/struct.HostExternals.html
@@ -0,0 +1,25 @@
+HostExternals in wasi_interpreter - Rust
+
+
Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
+then be further downcast into Box<ConcreteType> where ConcreteType implements Trait. Read more
Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
+further downcast into Rc<ConcreteType> where ConcreteType implements Trait. Read more