Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
f35c0cb
Small fixes for the SDK
syrusakbary Jul 28, 2026
82cefa1
Fix panic in Wasmer when used as library in debug mode
syrusakbary Jul 28, 2026
cb17195
fix(compiler): use JIT image base for macOS compact unwind
syrusakbary Jul 28, 2026
64b0344
Fix panic in Wasmer when used as library in debug mode
syrusakbary Jul 28, 2026
fb5297c
fix(compiler): use JIT image base for macOS compact unwind
syrusakbary Jul 28, 2026
a741220
Merge branch 'macos-unwind-fixes' into sdk
syrusakbary Jul 29, 2026
f502590
Fix panic in Wasmer when used as library in debug mode
syrusakbary Jul 28, 2026
b5718d1
fix(compiler): use JIT image base for macOS compact unwind
syrusakbary Jul 28, 2026
b5332d4
Added Module new_async function
syrusakbary Jul 29, 2026
86f4264
Improved polyfill support of table element types
syrusakbary Jul 29, 2026
07a480c
Added support for jspi
syrusakbary Jul 29, 2026
03ca02f
Make WASIX work well with JSPI changes for JS
syrusakbary Jul 29, 2026
2d1be9f
Simplify task management (with context switching)
syrusakbary Jul 29, 2026
b4d789a
Merge remote-tracking branch 'origin/sdk' into sdk
syrusakbary Jul 29, 2026
d0b8979
feat(wasix): add pluggable package caches
syrusakbary Jul 30, 2026
24bfbaa
Use only context switching or asyncify when needed
syrusakbary Jul 31, 2026
31a0fba
feat(wasix): scope terminals to process trees
syrusakbary Jul 31, 2026
9096508
fix(wasix): preserve descriptor rights in dup2
syrusakbary Jul 31, 2026
e8d722f
fix(wasix): deduplicate spawned command environment
syrusakbary Aug 1, 2026
9d62f5f
Improved dependencies for SDK
syrusakbary Aug 3, 2026
b5fb301
Improve dependencies features further
syrusakbary Aug 3, 2026
652ca3b
Split wasmer-package with two features: execution and authoring, for …
syrusakbary Aug 3, 2026
a5aa7e2
fix(WASIX): Add support for shebang scripts
syrusakbary Aug 4, 2026
18a62c6
Improved executable retrieval
syrusakbary Aug 4, 2026
0463075
fix(api-js-backend): Allow up to 4Gb memory pointers in JS backend
syrusakbary Aug 4, 2026
a59b36f
fix(api-js-backend): Add support for ExternRefs in Wasmer JS backend
syrusakbary Aug 4, 2026
cfeadfc
fix(api-js-backend): add copy_range_to_memory to the MemoryViews
syrusakbary Aug 5, 2026
a537593
fix(wasix): fix moving a directory preservers extternal hard link bac…
syrusakbary Aug 5, 2026
27ed718
fix(wasix, import apis): Added a prepare_imports to the runtime hooks…
syrusakbary Aug 5, 2026
6fadc92
fix(api-js-backend): Properly annotate all tables, not just imported …
syrusakbary Aug 5, 2026
b576f86
fix(wasm-c-api): Add shared memory extension to the wasm-c-api (and t…
syrusakbary Aug 6, 2026
84a0c4d
fix(api-js-backend): make memory maximum pages limit bigger
syrusakbary Aug 6, 2026
4a84ca0
fix(wasix): Fix WASIX thread lifecycle handling
syrusakbary Aug 6, 2026
3acacb2
fix(api-js-backend): bubble js panics up so errors are inspectable
syrusakbary Aug 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ version = "7.2.1"

[workspace.dependencies]
# Repo-local crates
wasmer-package = { version = "0.702.1", path = "lib/package" }
wasmer-package = { version = "0.702.1", path = "lib/package", default-features = false }
wasmer-config = { path = "./lib/config" }
wasmer-wasix = { path = "./lib/wasix" }
wasmer-sdk = { path = "./lib/sdk" }

# Wasmer-owned crates
webc = "=12.0.0"
webc = { version = "=12.0.0", default-features = false }
shared-buffer = "0.1.4"
loupe = "0.2.0"

Expand Down
11 changes: 8 additions & 3 deletions lib/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ bytes.workspace = true
tracing = { workspace = true, default-features = true }
# - Optional shared dependencies.
wat = { workspace = true, optional = true }
symbolic-demangle.workspace = true
symbolic-demangle = { workspace = true, optional = true }
shared-buffer.workspace = true

loupe = { workspace = true, optional = true, features = [
Expand Down Expand Up @@ -86,6 +86,7 @@ wasmer-types = { path = "../types", version = "=7.2.1", default-features = false
"std",
] }
wasm-bindgen.workspace = true
wasm-bindgen-futures = { workspace = true, optional = true }
js-sys.workspace = true
wasmer-derive = { path = "../derive", version = "=7.2.1" }
wasmer-compiler = { path = "../compiler", version = "=7.2.1" }
Expand All @@ -100,6 +101,7 @@ target-lexicon.workspace = true
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wat.workspace = true
anyhow.workspace = true
futures.workspace = true
wasm-bindgen-test.workspace = true
macro-wasmer-engine-test = { version = "7.2.1", path = "./macro-wasmer-engine-test" }

Expand All @@ -125,7 +127,10 @@ artifact-size = [

# Features for `sys`.
sys = ["std", "dep:wasmer-vm", "dep:wasmer-compiler"]
sys-default = ["sys", "wat", "cranelift"]
sys-default = ["sys", "wat", "cranelift", "demangle"]

# Improve native stack traces without forcing the demanglers into browser builds.
demangle = ["dep:symbolic-demangle"]

headless = []

Expand Down Expand Up @@ -158,7 +163,7 @@ v8-default = ["v8", "wat"]
wasm-c-api = ["wasm-types-polyfill"]

# Features for `js`.
js = ["wasm-bindgen", "js-sys"]
js = ["wasm-bindgen", "wasm-bindgen-futures", "js-sys"]
js-default = ["js", "std", "wasm-types-polyfill"]

wasm-types-polyfill = ["wasmparser"]
Expand Down
111 changes: 97 additions & 14 deletions lib/api/src/backend/js/entities/external.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,127 @@
use std::any::Any;

use js_sys::{Object, Symbol};
use wasm_bindgen::JsValue;

use crate::js::entities::store::StoreHandle;
use crate::js::utils::js_handle::JsHandle;
use crate::js::vm::VMExternRef;
use crate::store::{AsStoreMut, AsStoreRef};

#[derive(Debug, Clone)]
#[repr(transparent)]
/// A WebAssembly `extern ref` in `js`.
pub struct ExternRef;
pub(crate) struct ExternRefData(pub(crate) Box<dyn Any + Send + Sync>);

impl std::fmt::Debug for ExternRefData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ExternRefData").finish_non_exhaustive()
}
}

#[derive(Debug, Clone)]
pub struct ExternRef {
value: JsHandle<JsValue>,
host_data: Option<StoreHandle<ExternRefData>>,
}

unsafe impl Send for ExternRef {}
unsafe impl Sync for ExternRef {}

impl ExternRef {
pub fn new<T>(_store: &mut impl AsStoreMut, _value: T) -> Self
pub fn new<T>(store: &mut impl AsStoreMut, value: T) -> Self
where
T: Any + Send + Sync + 'static + Sized,
{
unimplemented!("ExternRef is not yet supported in Javascript");
let handle = StoreHandle::new(
store.objects_mut().as_js_mut(),
ExternRefData(Box::new(value)),
);
let object = Object::new();
js_sys::Reflect::set(
&object,
host_ref_index_key().as_ref(),
&JsValue::from_f64(handle.internal_handle().index() as f64),
)
.expect("setting the externref store index should succeed");
js_sys::Reflect::set(
&object,
host_ref_store_key().as_ref(),
&JsValue::from_f64(handle.store_id().as_raw().get() as f64),
)
.expect("setting the externref store ID should succeed");
Self {
value: JsHandle::new(object.into()),
host_data: Some(handle),
}
}

pub(crate) fn from_js_value(store: &mut impl AsStoreMut, value: JsValue) -> Self {
let host_data = host_handle_from_js_value(store, &value);
Self {
value: JsHandle::new(value),
host_data,
}
}

pub(crate) fn as_js_value(&self) -> JsValue {
(*self.value).clone()
}

pub fn downcast<'a, T>(&self, _store: &'a impl AsStoreRef) -> Option<&'a T>
pub fn downcast<'a, T>(&self, store: &'a impl AsStoreRef) -> Option<&'a T>
where
T: Any + Send + Sync + 'static + Sized,
{
unimplemented!("ExternRef is not yet supported in Javascript");
self.host_data
.as_ref()?
.get(store.as_store_ref().objects().as_js())
.0
.downcast_ref()
}

pub(crate) fn vm_externref(&self) -> VMExternRef {
unimplemented!("ExternRef is not yet supported in Javascript");
VMExternRef::new(self.as_js_value())
}

pub(crate) unsafe fn from_vm_externref(
_store: &mut impl AsStoreMut,
_vm_externref: VMExternRef,
store: &mut impl AsStoreMut,
vm_externref: VMExternRef,
) -> Self {
unimplemented!("ExternRef is not yet supported in Javascript");
Self::from_js_value(store, vm_externref.into_js_value())
}

pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
self.host_data
.as_ref()
.is_none_or(|handle| handle.store_id() == store.as_store_ref().objects().id())
}

pub fn is_from_store(&self, _store: &impl AsStoreRef) -> bool {
true
pub fn ptr_eq(&self, other: &Self) -> bool {
js_sys::Object::is(&self.value, &other.value)
}
}

fn host_ref_index_key() -> Symbol {
Symbol::for_("wasmer.externref-index")
}

fn host_ref_store_key() -> Symbol {
Symbol::for_("wasmer.externref-store")
}

pub fn ptr_eq(&self, _other: &Self) -> bool {
unimplemented!("ExternRef is not yet supported in Javascript");
fn host_handle_from_js_value(
store: &mut impl AsStoreMut,
value: &JsValue,
) -> Option<StoreHandle<ExternRefData>> {
let index = js_sys::Reflect::get(value, host_ref_index_key().as_ref())
.ok()?
.as_f64()? as usize;
let store_id = js_sys::Reflect::get(value, host_ref_store_key().as_ref())
.ok()?
.as_f64()? as u64;
let objects = store.objects_mut();
if objects.id().as_raw().get() as u64 != store_id {
return None;
}
let internal = crate::js::entities::store::InternalStoreHandle::from_index(index)?;
Some(unsafe { StoreHandle::from_internal(objects.id(), internal) })
}
Loading