From 041d7b7dd217575dfebd7eaa9a9f3ac70b5c5835 Mon Sep 17 00:00:00 2001 From: imxyy_soope_ Date: Thu, 22 Jan 2026 16:46:11 +0800 Subject: [PATCH] feat: builtins.getEnv --- nix-js/runtime-ts/src/builtins/index.ts | 2 +- nix-js/runtime-ts/src/builtins/io.ts | 4 ++-- nix-js/runtime-ts/src/types/global.d.ts | 1 + nix-js/src/codegen.rs | 5 ++-- nix-js/src/context.rs | 31 ++++++++++++------------- nix-js/src/runtime.rs | 7 ++++++ 6 files changed, 29 insertions(+), 21 deletions(-) diff --git a/nix-js/runtime-ts/src/builtins/index.ts b/nix-js/runtime-ts/src/builtins/index.ts index b37b2c7..1421723 100644 --- a/nix-js/runtime-ts/src/builtins/index.ts +++ b/nix-js/runtime-ts/src/builtins/index.ts @@ -261,5 +261,5 @@ export const builtins: any = { langVersion: 6, nixPath: [], nixVersion: "2.31.2", - storeDir: "/home/imxyy/.cache/nix-js/fetchers/store", + storeDir: "INVALID_PATH", }; diff --git a/nix-js/runtime-ts/src/builtins/io.ts b/nix-js/runtime-ts/src/builtins/io.ts index e111a9d..ea61920 100644 --- a/nix-js/runtime-ts/src/builtins/io.ts +++ b/nix-js/runtime-ts/src/builtins/io.ts @@ -391,6 +391,6 @@ export const findFile = throw new Error("Not implemented: findFile"); }; -export const getEnv = (s: NixValue): never => { - throw new Error("Not implemented: getEnv"); +export const getEnv = (s: NixValue): string => { + return Deno.core.ops.op_get_env(forceString(s)) }; diff --git a/nix-js/runtime-ts/src/types/global.d.ts b/nix-js/runtime-ts/src/types/global.d.ts index daf6ed0..c979cb7 100644 --- a/nix-js/runtime-ts/src/types/global.d.ts +++ b/nix-js/runtime-ts/src/types/global.d.ts @@ -79,6 +79,7 @@ declare global { function op_store_path(path: string): string; function op_to_file(name: string, contents: string, references: string[]): string; function op_copy_path_to_store(path: string): string; + function op_get_env(key: string): string; } } } diff --git a/nix-js/src/codegen.rs b/nix-js/src/codegen.rs index b5cdc7e..8012f9a 100644 --- a/nix-js/src/codegen.rs +++ b/nix-js/src/codegen.rs @@ -22,8 +22,8 @@ pub(crate) fn compile(expr: &Ir, ctx: &impl CodegenContext) -> String { let cur_dir = ctx.get_current_dir().display().to_string().escape_quote(); format!( - "(()=>{{{}const currentDir={};return {}}})()", - debug_prefix, cur_dir, code + "(()=>{{{}Nix.builtins.storeDir={};const currentDir={};return {}}})()", + debug_prefix, ctx.get_store_dir().escape_quote(), cur_dir, code ) } @@ -35,6 +35,7 @@ pub(crate) trait CodegenContext { fn get_ir(&self, id: ExprId) -> &Ir; fn get_sym(&self, id: SymId) -> &str; fn get_current_dir(&self) -> &Path; + fn get_store_dir(&self) -> &str; fn get_current_source_id(&self) -> usize; } diff --git a/nix-js/src/context.rs b/nix-js/src/context.rs index 34adc1e..7a4a6cc 100644 --- a/nix-js/src/context.rs +++ b/nix-js/src/context.rs @@ -66,21 +66,16 @@ pub(crate) struct SccInfo { pub struct Context { ctx: Ctx, runtime: Runtime, - store: Arc, } impl Context { pub fn new() -> Result { - let ctx = Ctx::new(); + let ctx = Ctx::new()?; let runtime = Runtime::new()?; - let config = StoreConfig::from_env(); - let store = Arc::new(StoreBackend::new(config)?); - Ok(Self { ctx, runtime, - store, }) } @@ -90,7 +85,7 @@ impl Context { tracing::debug!("Compiling code"); let code = self.compile_code(source)?; - self.runtime.op_state().borrow_mut().put(self.store.clone()); + self.runtime.op_state().borrow_mut().put(self.ctx.store.clone()); tracing::debug!("Executing JavaScript"); self.runtime @@ -107,7 +102,7 @@ impl Context { } pub fn get_store_dir(&self) -> &str { - self.store.as_store().get_store_dir() + self.ctx.get_store_dir() } } @@ -116,10 +111,11 @@ pub(crate) struct Ctx { symbols: DefaultStringInterner, global: NonNull>, sources: Vec, + store: Arc, } -impl Default for Ctx { - fn default() -> Self { +impl Ctx { + fn new() -> Result { use crate::ir::{Builtins, ToIr as _}; let mut symbols = DefaultStringInterner::new(); @@ -203,20 +199,20 @@ impl Default for Ctx { global.insert(name_sym, id); } - Self { + let config = StoreConfig::from_env(); + let store = Arc::new(StoreBackend::new(config)?); + + Ok(Self { symbols, irs, global: unsafe { NonNull::new_unchecked(Box::leak(Box::new(global))) }, sources: Vec::new(), - } + store, + }) } } impl Ctx { - pub(crate) fn new() -> Self { - Self::default() - } - pub(crate) fn downgrade_ctx<'a>(&'a mut self) -> DowngradeCtx<'a> { let global_ref = unsafe { self.global.as_ref() }; DowngradeCtx::new(self, global_ref) @@ -281,6 +277,9 @@ impl CodegenContext for Ctx { .checked_sub(1) .expect("current_source not set") } + fn get_store_dir(&self) -> &str { + self.store.as_store().get_store_dir() + } } struct DependencyTracker { diff --git a/nix-js/src/runtime.rs b/nix-js/src/runtime.rs index a0f1612..6b39bb1 100644 --- a/nix-js/src/runtime.rs +++ b/nix-js/src/runtime.rs @@ -38,6 +38,7 @@ fn runtime_extension() -> Extension { op_store_path(), op_to_file(), op_copy_path_to_store(), + op_get_env(), ]; ops.extend(crate::fetcher::register_ops()); @@ -390,6 +391,12 @@ fn op_copy_path_to_store( Ok(store_path) } +#[deno_core::op2] +#[string] +fn op_get_env(#[string] key: String) -> std::result::Result { + Ok(std::env::var(key).map_err(|err| format!("Failed to read env var: {err}"))?) +} + pub(crate) struct Runtime { js_runtime: JsRuntime, is_thunk_symbol: v8::Global,