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
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@
## 2024-05-24 - Web Property Extraction Optimization
**Learning:** Extracting properties from the `RuntimeValue` DSL property lists in `stdlib/src/web/renderer.rs` and `stdlib/src/web/db.rs` was inefficient because the code called `.iter().find()` to resolve `text`, `id`, and `name` attributes, which creates unnecessary iterator overhead and closure allocation.
**Action:** Replace `.iter().find()` calls with a single-pass `for p in &dsl.properties` loop and `if` statements on the property names, stopping early when found, which significantly reduces execution overhead.

## 2026-10-28 - Standard Library File Operations String Allocation Optimization
**Learning:** Calling `try_into_string(&self)` on owned `RuntimeValue` arguments in standard library functions like `sys_write_file` and `sys_read_file` clones the string payload, causing redundant string allocations and memory copy overhead for file operations.
**Action:** Provide and use an `into_string(self)` method on `RuntimeValue` when owned arguments are available in standard library callback handlers to extract strings directly without allocation.
7 changes: 7 additions & 0 deletions runtime/runtime/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,13 @@ impl RuntimeValue {
}
}

pub fn into_string(self) -> Result<String, RuntimeError> {
match self {
Self::Str(s) => Ok(s),
other => Ok(other.to_string()),
}
}

/// Verifies reference identity check (===).
pub fn physical_eq(&self, other: &Self) -> bool {
match (self, other) {
Expand Down
59 changes: 55 additions & 4 deletions stdlib/src/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,20 @@ fn sys_read_file(
args: Vec<RuntimeValue>,
) -> Result<RuntimeValue, RuntimeError> {
check_fs_capability(ctx)?;
let path = args[0].try_into_string()?;
let mut args_iter = args.into_iter();
let path = args_iter
.next()
.ok_or_else(|| {
RuntimeError::new(
RuntimeErrorKind::ArityMismatch {
expected: 1,
found: 0,
},
None,
None,
)
})?
.into_string()?;
let content = std::fs::read_to_string(path).map_err(|e| {
RuntimeError::new(
RuntimeErrorKind::InvalidOperation(format!("IO error: {}", e)),
Expand All @@ -41,8 +54,33 @@ fn sys_write_file(
args: Vec<RuntimeValue>,
) -> Result<RuntimeValue, RuntimeError> {
check_fs_capability(ctx)?;
let path = args[0].try_into_string()?;
let content = args[1].try_into_string()?;
let mut args_iter = args.into_iter();
let path = args_iter
.next()
.ok_or_else(|| {
RuntimeError::new(
RuntimeErrorKind::ArityMismatch {
expected: 2,
found: 0,
},
None,
None,
)
})?
.into_string()?;
let content = args_iter
.next()
.ok_or_else(|| {
RuntimeError::new(
RuntimeErrorKind::ArityMismatch {
expected: 2,
found: 1,
},
None,
None,
)
})?
.into_string()?;
std::fs::write(path, content).map_err(|e| {
RuntimeError::new(
RuntimeErrorKind::InvalidOperation(format!("IO error: {}", e)),
Expand All @@ -58,7 +96,20 @@ fn sys_exists(
args: Vec<RuntimeValue>,
) -> Result<RuntimeValue, RuntimeError> {
check_fs_capability(ctx)?;
let path = args[0].try_into_string()?;
let mut args_iter = args.into_iter();
let path = args_iter
.next()
.ok_or_else(|| {
RuntimeError::new(
RuntimeErrorKind::ArityMismatch {
expected: 1,
found: 0,
},
None,
None,
)
})?
.into_string()?;
Ok(RuntimeValue::Bool(std::path::Path::new(&path).exists()))
}

Expand Down
Loading