From 663401b89e000a70f83cf51c69ad53a0966af2d0 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 27 Oct 2026 18:17:18 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20path=20argum?= =?UTF-8?q?ent=20allocations=20in=20sys=5Fread=5Ffile=20and=20std.fs=20mod?= =?UTF-8?q?ule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com> --- .jules/bolt.md | 4 +++ stdlib/src/sys.rs | 40 +++++++++++++++++++++++++---- stdlib/tests/stdlib_tests.rs | 49 ++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 5 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index 3faa4acb..350a7a52 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -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-09-28 - String Path Borrowing in std.fs Module +**Learning:** Extracting string arguments via `try_into_string()` in standard library callbacks causes unnecessary string cloning and heap allocations even when arguments are already `RuntimeValue::Str`. +**Action:** Borrow `&str` directly from `RuntimeValue::Str` using pattern matching rather than calling `try_into_string()` when passing string path arguments to file I/O operations. diff --git a/stdlib/src/sys.rs b/stdlib/src/sys.rs index 00a45f14..9c680848 100644 --- a/stdlib/src/sys.rs +++ b/stdlib/src/sys.rs @@ -20,12 +20,21 @@ fn check_fs_capability(ctx: &RuntimeContext) -> Result<(), RuntimeError> { Ok(()) } +// ⚡ TechScript stdlib execution model is synchronous and native VM function calls return results directly. +// The blocking file I/O operations below are intentional and aligned with TechScript's synchronous stdlib design. fn sys_read_file( ctx: &mut RuntimeContext, args: Vec, ) -> Result { check_fs_capability(ctx)?; - let path = args[0].try_into_string()?; + let path_buf; + let path = match &args[0] { + RuntimeValue::Str(s) => s.as_str(), + _ => { + path_buf = args[0].try_into_string()?; + &path_buf + } + }; let content = std::fs::read_to_string(path).map_err(|e| { RuntimeError::new( RuntimeErrorKind::InvalidOperation(format!("IO error: {}", e)), @@ -41,8 +50,22 @@ fn sys_write_file( args: Vec, ) -> Result { check_fs_capability(ctx)?; - let path = args[0].try_into_string()?; - let content = args[1].try_into_string()?; + let path_buf; + let path = match &args[0] { + RuntimeValue::Str(s) => s.as_str(), + _ => { + path_buf = args[0].try_into_string()?; + &path_buf + } + }; + let content_buf; + let content = match &args[1] { + RuntimeValue::Str(s) => s.as_str(), + _ => { + content_buf = args[1].try_into_string()?; + &content_buf + } + }; std::fs::write(path, content).map_err(|e| { RuntimeError::new( RuntimeErrorKind::InvalidOperation(format!("IO error: {}", e)), @@ -58,8 +81,15 @@ fn sys_exists( args: Vec, ) -> Result { check_fs_capability(ctx)?; - let path = args[0].try_into_string()?; - Ok(RuntimeValue::Bool(std::path::Path::new(&path).exists())) + let path_buf; + let path = match &args[0] { + RuntimeValue::Str(s) => s.as_str(), + _ => { + path_buf = args[0].try_into_string()?; + &path_buf + } + }; + Ok(RuntimeValue::Bool(std::path::Path::new(path).exists())) } fn sys_now( diff --git a/stdlib/tests/stdlib_tests.rs b/stdlib/tests/stdlib_tests.rs index 05c13a8c..95497639 100644 --- a/stdlib/tests/stdlib_tests.rs +++ b/stdlib/tests/stdlib_tests.rs @@ -1331,3 +1331,52 @@ fn test_uuid_module() { assert!(!uuid_str.is_empty()); assert!(uuid_str.contains("-")); } + +#[test] +fn test_sys_read_file_benchmark() { + let registry = StdlibRegistry::new(); + let fs = registry.get_module("std.fs").unwrap(); + + let temp_dir = std::env::temp_dir(); + let temp_file = temp_dir.join("techscript_sys_read_bench.txt"); + let temp_file_str = temp_file.to_string_lossy().to_string(); + + let mut caps = HashSet::new(); + caps.insert(Capability::FileSystem); + let config = RuntimeConfig { + strict_mode: false, + max_recursion_depth: 1000, + enable_assertions: true, + capabilities: caps, + }; + let mut ctx = RuntimeContext::new(config); + + let write_file = fs.exports.get("write_file").unwrap(); + let read_file = fs.exports.get("read_file").unwrap(); + + write_file + .call( + &mut ctx, + vec![ + RuntimeValue::Str(temp_file_str.clone()), + RuntimeValue::Str("Benchmark test content for sys_read_file".to_string()), + ], + ) + .unwrap(); + + let path_val = RuntimeValue::Str(temp_file_str); + let iterations = 10_000; + let start = std::time::Instant::now(); + + for _ in 0..iterations { + let _ = read_file.call(&mut ctx, vec![path_val.clone()]).unwrap(); + } + + let elapsed = start.elapsed(); + println!( + "\n[BENCHMARK] sys_read_file {} iterations: {:?}", + iterations, elapsed + ); + + std::fs::remove_file(temp_file).ok(); +} From 6f427f9c02d6923b2d02fbe5b3eddc0e8410bdb8 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 27 Oct 2026 19:03:27 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20path=20argum?= =?UTF-8?q?ent=20allocations=20in=20sys=5Fread=5Ffile=20and=20std.fs=20mod?= =?UTF-8?q?ule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com> --- stdlib/tests/stdlib_tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/stdlib/tests/stdlib_tests.rs b/stdlib/tests/stdlib_tests.rs index 95497639..5bb373fd 100644 --- a/stdlib/tests/stdlib_tests.rs +++ b/stdlib/tests/stdlib_tests.rs @@ -519,6 +519,7 @@ fn test_http_module() { let response = "HTTP/1.1 200 OK\r\nContent-Length: 13\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nHello Server!"; let _ = stream.write_all(response.as_bytes()); let _ = stream.flush(); + let _ = stream.shutdown(std::net::Shutdown::Both); } });