Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 10 additions & 10 deletions baml_language/.cargo/size-gate.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ policy.max_delta_pct = 3.0
# Baselines re-recorded after merging canary (~+4%). Reclaiming the `syn`
# cost would mean dropping prettyplease (raw, unformatted generated SDK
# output).
# macOS arm64: baseline 18.90 MB file (18_900_160), ceiling = baseline x1.03.
# macOS arm64: baseline 19.55 MB file (19_545_088), ceiling = baseline x1.03.
[artifacts.baml-cli.platform.aarch64-apple-darwin]
max_file_bytes = 19_467_165
# Linux x86_64: baseline 24.51 MB file (24_507_664), ceiling = baseline x1.03.
max_file_bytes = 20_131_441
# Linux x86_64: baseline 25.27 MB file (25_272_400), ceiling = baseline x1.03.
[artifacts.baml-cli.platform.x86_64-unknown-linux-gnu]
max_file_bytes = 25_242_894
# Windows x86_64: baseline 20.43 MB file (20_426_752), ceiling = baseline x1.03.
max_file_bytes = 26_030_572
# Windows x86_64: baseline 21.08 MB file (21_075_968), ceiling = baseline x1.03.
[artifacts.baml-cli.platform.x86_64-pc-windows-msvc]
max_file_bytes = 21_039_555
max_file_bytes = 21_708_248

[artifacts.packed-program]
kind = "pack"
Expand All @@ -61,10 +61,10 @@ policy.max_delta_pct = 3.0
max_file_bytes = 13_602_990
# Linux x86_64: baseline 17.03 MB file.
[artifacts.packed-program.platform.x86_64-unknown-linux-gnu]
max_file_bytes = 17_542_251
max_file_bytes = 17_538_033
# Windows x86_64: baseline 14.14 MB file.
[artifacts.packed-program.platform.x86_64-pc-windows-msvc]
max_file_bytes = 14_567_300
max_file_bytes = 14_566_773

[artifacts.packed-program.pack]
cli_package = "baml_cli"
Expand All @@ -86,6 +86,6 @@ no_default_features = true
wasm = true
policy.max_delta_pct = 3.0

# Single platform; baseline 4.27 MB gzip.
# Single platform; baseline 4.40 MB gzip.
[artifacts.bridge_wasm.platform.wasm32-unknown-unknown]
max_gzip_bytes = 4_400_547
max_gzip_bytes = 4_534_972
12 changes: 6 additions & 6 deletions baml_language/.ci/size-gate/aarch64-apple-darwin.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
version = 1
recorded_at = "2026-07-17T00:35:21Z"
git_sha = "b01ee9c671a00b44a7a9a3832e149e3c2ec93c13"
recorded_at = "2026-07-20T07:51:49Z"
git_sha = "fe3304335ff13eb6355233b1f96690b6ede7ae09"

[artifacts.baml-cli]
file_bytes = 18900160
stripped_bytes = 18900208
gzip_bytes = 8955790
file_bytes = 19545088
stripped_bytes = 19545136
gzip_bytes = 9331881

[artifacts.packed-program]
file_bytes = 13206786
gzip_bytes = 6154161
gzip_bytes = 6154377
8 changes: 4 additions & 4 deletions baml_language/.ci/size-gate/wasm32-unknown-unknown.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version = 1
recorded_at = "2026-07-16T10:00:08Z"
git_sha = "79aa0f44e323e356a172e16e6b0f4a42e569959d"
recorded_at = "2026-07-20T07:51:49Z"
git_sha = "fe3304335ff13eb6355233b1f96690b6ede7ae09"

[artifacts.bridge_wasm]
file_bytes = 15157305
gzip_bytes = 4272375
file_bytes = 16160508
gzip_bytes = 4402885
14 changes: 7 additions & 7 deletions baml_language/.ci/size-gate/x86_64-pc-windows-msvc.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
version = 1
recorded_at = "2026-07-17T00:35:21Z"
git_sha = "b01ee9c671a00b44a7a9a3832e149e3c2ec93c13"
recorded_at = "2026-07-20T07:51:49Z"
git_sha = "fe3304335ff13eb6355233b1f96690b6ede7ae09"

[artifacts.baml-cli]
file_bytes = 20426752
stripped_bytes = 20426752
gzip_bytes = 9169338
file_bytes = 21075968
stripped_bytes = 21075968
gzip_bytes = 9542344

[artifacts.packed-program]
file_bytes = 14143010
gzip_bytes = 6248500
file_bytes = 14142498
gzip_bytes = 6248883
14 changes: 7 additions & 7 deletions baml_language/.ci/size-gate/x86_64-unknown-linux-gnu.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
version = 1
recorded_at = "2026-07-17T00:35:21Z"
git_sha = "b01ee9c671a00b44a7a9a3832e149e3c2ec93c13"
recorded_at = "2026-07-20T07:51:49Z"
git_sha = "fe3304335ff13eb6355233b1f96690b6ede7ae09"

[artifacts.baml-cli]
file_bytes = 24507664
stripped_bytes = 24507656
gzip_bytes = 10325653
file_bytes = 25272400
stripped_bytes = 25272392
gzip_bytes = 10732594

[artifacts.packed-program]
file_bytes = 17031312
gzip_bytes = 7039119
file_bytes = 17027216
gzip_bytes = 7039234
25 changes: 25 additions & 0 deletions baml_language/Cargo.lock

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

1 change: 1 addition & 0 deletions baml_language/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ bex_heap = { path = "crates/bex_heap" }
bex_sap = { path = "crates/bex_sap" }
bridge_ctypes = { path = "crates/bridge_ctypes", default-features = false }
bridge_cffi = { path = "crates/bridge_cffi", default-features = false }
sys_wasm = { path = "crates/sys_wasm" }
baml_exec = { path = "crates/baml_exec" }
bex_events = { path = "crates/bex_events" }
bex_resource_types = { path = "crates/bex_resource_types" }
Expand Down
3 changes: 3 additions & 0 deletions baml_language/crates/bridge_cffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ serde_json = { workspace = true }
tokio = { workspace = true, features = [ "rt", "rt-multi-thread" ] }
vfs = { workspace = true }

[target.'cfg(target_arch = "wasm32")'.dependencies]
vfs = { workspace = true }

[target.'cfg(not(target_os = "windows"))'.dev-dependencies]
cbindgen = { workspace = true }

Expand Down
156 changes: 156 additions & 0 deletions baml_language/crates/bridge_cffi/src/handle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
//! Safe, target-neutral ordinary handle and media operations.

use std::sync::Arc;

use bex_project::{BexExternalAdt, MediaKind, MediaValue};
use bridge_ctypes::{CffiHandleTableEntry, HANDLE_TABLE, baml_bridge::cffi::BamlHandleType};

/// An owned handle-table key and its protocol type tag.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct HandleParts {
pub key: u64,
pub handle_type: i32,
}

/// Failure from a safe ordinary handle or media operation.
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
pub enum HandleError {
#[error("invalid handle")]
InvalidHandle,
#[error("handle type mismatch")]
TypeMismatch,
#[error("unsupported handle type")]
UnsupportedHandleType,
#[error("{0}")]
InvalidInput(String),
}

fn insert_entry(entry: CffiHandleTableEntry) -> HandleParts {
let handle_type = entry.handle_type() as i32;
let key = HANDLE_TABLE.insert(entry);
HandleParts { key, handle_type }
}

fn validate_input(value: &str, field: &str) -> Result<(), HandleError> {
if value.contains('\0') {
return Err(HandleError::InvalidInput(format!(
"{field} contains an embedded NUL byte"
)));
}
Ok(())
}

fn validate_media_input(source: &str, mime_type: Option<&str>) -> Result<(), HandleError> {
validate_input(source, "media source")?;
if let Some(mime_type) = mime_type {
validate_input(mime_type, "media MIME type")?;
}
Ok(())
}

fn resolve_media(key: u64, handle_type: i32) -> Result<Arc<MediaValue>, HandleError> {
let entry = HANDLE_TABLE
.resolve(key)
.ok_or(HandleError::InvalidHandle)?;

if handle_type != BamlHandleType::HandleUnspecified as i32
&& handle_type != entry.handle_type() as i32
{
return Err(HandleError::TypeMismatch);
}

match &*entry {
CffiHandleTableEntry::Adt(BexExternalAdt::Media(media)) => Ok(media.clone()),
_ => Err(HandleError::UnsupportedHandleType),
}
}

/// Clone one live ordinary handle-table row into a distinct owned key.
pub fn clone_handle(key: u64) -> Result<u64, HandleError> {
HANDLE_TABLE
.clone_handle(key)
.ok_or(HandleError::InvalidHandle)
}

/// Release one owned ordinary handle-table key.
pub fn release_handle(key: u64) -> Result<(), HandleError> {
if HANDLE_TABLE.release(key) {
Ok(())
} else {
Err(HandleError::InvalidHandle)
}
}

/// Return the number of currently owned ordinary handle-table keys.
///
/// This is exposed by target adapters only as focused test instrumentation;
/// it is not part of the generated SDK surface.
pub fn live_handle_count() -> usize {
HANDLE_TABLE.len()
}

/// Seed a function-reference handle for focused bridge tests.
pub fn seed_function_ref_handle(global_index: u64) -> HandleParts {
insert_entry(CffiHandleTableEntry::FunctionRef {
global_index: global_index as usize,
})
}

/// Seed a generic-media handle for focused bridge tests.
pub fn seed_generic_media_handle() -> HandleParts {
insert_entry(CffiHandleTableEntry::Adt(BexExternalAdt::Media(
MediaValue::from_url(MediaKind::Generic, "https://example.com/", None),
)))
}

/// Construct an owned media handle from a URL descriptor.
pub fn media_from_url(
kind: MediaKind,
url: &str,
mime_type: Option<&str>,
) -> Result<HandleParts, HandleError> {
validate_media_input(url, mime_type)?;
Ok(insert_entry(CffiHandleTableEntry::Adt(
BexExternalAdt::Media(MediaValue::from_url(kind, url, mime_type)),
)))
}

/// Construct an owned media handle from a file-path descriptor.
pub fn media_from_file(
kind: MediaKind,
file: &str,
mime_type: Option<&str>,
) -> Result<HandleParts, HandleError> {
validate_media_input(file, mime_type)?;
Ok(insert_entry(CffiHandleTableEntry::Adt(
BexExternalAdt::Media(MediaValue::from_file(kind, file, mime_type)),
)))
}

/// Construct an owned media handle from base64 text.
pub fn media_from_base64(
kind: MediaKind,
base64: &str,
mime_type: Option<&str>,
) -> Result<HandleParts, HandleError> {
validate_media_input(base64, mime_type)?;
Ok(insert_entry(CffiHandleTableEntry::Adt(
BexExternalAdt::Media(MediaValue::from_base64(kind, base64, mime_type)),
)))
}

pub fn media_url(key: u64, handle_type: i32) -> Result<Option<String>, HandleError> {
Ok(resolve_media(key, handle_type)?.url())
}

pub fn media_file(key: u64, handle_type: i32) -> Result<Option<String>, HandleError> {
Ok(resolve_media(key, handle_type)?.file())
}

pub fn media_base64(key: u64, handle_type: i32) -> Result<String, HandleError> {
Ok(resolve_media(key, handle_type)?.base64())
}

pub fn media_mime_type(key: u64, handle_type: i32) -> Result<Option<String>, HandleError> {
Ok(resolve_media(key, handle_type)?.mime_type())
}
Loading
Loading