@@ -79,6 +79,10 @@
Char(char),
String(String),
List(Vec<Val>),
+ /// MongoDB extension: raw byte buffer lowered as list<u8> via bulk copy.
+ /// This is a write-only optimisation: Bytes is produced by C++ callers and
+ /// lowered into WASM linear memory; it is never lifted from WASM output.
+ Bytes(Vec<u8>),
/// A map type represented as a list of key-value pairs.
/// Duplicate keys are allowed and follow "last value wins" semantics.
Map(Vec<(Val, Val)>),
@@ -431,6 +433,15 @@
next_mut(dst).write(ValRaw::i64(len as i64));
Ok(())
}
+ (InterfaceType::List(_), Val::Bytes(bytes)) => {
+ // MongoDB fast path: bulk-copy the byte buffer into WASM
+ // linear memory rather than boxing each byte individually.
+ let ptr = cx.realloc(0, 0, 1, bytes.len())?;
+ cx.as_slice_mut()[ptr..][..bytes.len()].copy_from_slice(bytes);
+ next_mut(dst).write(ValRaw::i64(ptr as i64));
+ next_mut(dst).write(ValRaw::i64(bytes.len() as i64));
+ Ok(())
+ }
(InterfaceType::List(_), _) => unexpected(ty, self),
(InterfaceType::Map(ty), Val::Map(pairs)) => {
let map_ty = &cx.types[ty];
@@ -568,6 +579,16 @@
*cx.get(offset + 4) = u32::try_from(len).unwrap().to_le_bytes();
Ok(())
}
+ (InterfaceType::List(_), Val::Bytes(bytes)) => {
+ // MongoDB fast path: bulk-copy the byte buffer into WASM
+ // linear memory rather than boxing each byte individually.
+ let ptr = cx.realloc(0, 0, 1, bytes.len())?;
+ cx.as_slice_mut()[ptr..][..bytes.len()].copy_from_slice(bytes);
+ // FIXME(#4311): needs memory64 handling
+ *cx.get(offset + 0) = u32::try_from(ptr).unwrap().to_le_bytes();
+ *cx.get(offset + 4) = u32::try_from(bytes.len()).unwrap().to_le_bytes();
+ Ok(())
+ }
(InterfaceType::List(_), _) => unexpected(ty, self),
(InterfaceType::Map(ty_idx), Val::Map(values)) => {
let map_ty = &cx.types[ty_idx];
@@ -690,6 +711,7 @@
Val::Float64(_) => "f64",
Val::Char(_) => "char",
Val::List(_) => "list",
+ Val::Bytes(_) => "list",
Val::Map(_) => "map",
Val::String(_) => "string",
Val::Record(_) => "record",
@@ -765,6 +787,8 @@
(Self::String(_), _) => false,
(Self::List(l), Self::List(r)) => l == r,
(Self::List(_), _) => false,
+ (Self::Bytes(l), Self::Bytes(r)) => l == r,
+ (Self::Bytes(_), _) => false,
(Self::Map(l), Self::Map(r)) => l == r,
(Self::Map(_), _) => false,
(Self::Record(l), Self::Record(r)) => l == r,