refactor: rename IS_PRIMOP -> PRIMOP_METADATA

This commit is contained in:
2026-01-04 17:32:38 +08:00
parent 45d777a157
commit 89b68d5fe9
6 changed files with 35 additions and 32 deletions

View File

@@ -9,7 +9,7 @@ import { create_thunk } from "../thunk";
* Symbol used to mark functions as primops (primitive operations)
* This is similar to IS_THUNK but for builtin functions
*/
export const IS_PRIMOP = Symbol("is_primop");
export const PRIMOP_METADATA = Symbol("primop_metadata");
/**
* Metadata interface for primop functions
@@ -40,7 +40,7 @@ export const markPrimop = <T extends Function>(
applied: number = 0,
): T => {
// Mark this function as a primop
(func as any)[IS_PRIMOP] = {
(func as any)[PRIMOP_METADATA] = {
name,
arity,
applied,
@@ -59,7 +59,7 @@ export const markPrimop = <T extends Function>(
}) as any;
// Copy the primop metadata to the wrapper
wrappedFunc[IS_PRIMOP] = {
wrappedFunc[PRIMOP_METADATA] = {
name,
arity,
applied,
@@ -76,12 +76,12 @@ export const markPrimop = <T extends Function>(
* @param value - Value to check
* @returns true if value is marked as a primop
*/
export const is_primop = (value: unknown): value is Function & { [IS_PRIMOP]: PrimopMetadata } => {
export const is_primop = (value: unknown): value is Function & { [PRIMOP_METADATA]: PrimopMetadata } => {
return (
typeof value === "function" &&
IS_PRIMOP in value &&
typeof value[IS_PRIMOP] === "object" &&
value[IS_PRIMOP] !== null
PRIMOP_METADATA in value &&
typeof value[PRIMOP_METADATA] === "object" &&
value[PRIMOP_METADATA] !== null
);
};
@@ -92,7 +92,7 @@ export const is_primop = (value: unknown): value is Function & { [IS_PRIMOP]: Pr
*/
export const get_primop_metadata = (func: unknown): PrimopMetadata | undefined => {
if (is_primop(func)) {
return func[IS_PRIMOP];
return func[PRIMOP_METADATA];
}
return undefined;
};
@@ -117,7 +117,7 @@ import * as misc from "./misc";
* - Single argument functions: (a) => result
* - Multi-argument functions: (a) => (b) => result
*
* All primop functions are marked with IS_PRIMOP symbol for runtime introspection
* All primop functions are marked with PRIMOP_METADATA symbol for runtime introspection
*/
export const builtins: any = {
add: markPrimop(arithmetic.add, "add", 2),

View File

@@ -7,7 +7,7 @@
import { create_thunk, force, is_thunk, IS_THUNK } from "./thunk";
import { select, select_with_default, validate_params, resolve_path } from "./helpers";
import { op } from "./operators";
import { builtins, IS_PRIMOP } from "./builtins";
import { builtins, PRIMOP_METADATA } from "./builtins";
export type NixRuntime = typeof Nix;
@@ -27,7 +27,7 @@ export const Nix = {
op,
builtins,
IS_PRIMOP,
PRIMOP_METADATA,
};
globalThis.Nix = Nix;

View File

@@ -62,7 +62,7 @@ impl<Ctx: CodegenContext> Compile<Ctx> for Ir {
&Ir::ExprRef(expr_id) => {
format!("expr{}", expr_id.0)
}
Ir::Builtin(_) => "Nix.builtins".to_string(),
Ir::Builtins(_) => "Nix.builtins".to_string(),
Ir::ConcatStrings(x) => x.compile(ctx),
Ir::HasAttr(x) => x.compile(ctx),
&Ir::Assert(Assert { assertion, expr }) => {
@@ -279,7 +279,7 @@ impl<Ctx: CodegenContext> Compile<Ctx> for ConcatStrings {
.iter()
.map(|part| {
let compiled = ctx.get_ir(*part).compile(ctx);
// TODO: coercce to string
// TODO: coerce to string
format!("String(Nix.force({}))", compiled)
})
.collect();

View File

@@ -29,13 +29,13 @@ impl Drop for Context {
impl Default for Context {
fn default() -> Self {
use crate::ir::{Attr, Builtin, Select, ToIr};
use crate::ir::{Attr, Builtins, Select, ToIr};
let mut symbols = DefaultStringInterner::new();
let mut irs = Vec::new();
let mut global = HashMap::new();
irs.push(Builtin.to_ir());
irs.push(Builtins.to_ir());
let builtins_expr = ExprId(0);
let builtins_sym = symbols.get_or_intern("builtins");

View File

@@ -60,7 +60,7 @@ ir! {
Arg(ArgId),
ExprRef(ExprId),
Thunk(ExprId),
Builtin,
Builtins,
}
impl AttrSet {
@@ -379,6 +379,9 @@ pub struct Path {
}
/// Represents the special `builtins` global object.
/// This is a unit struct with no fields as it maps directly to the runtime builtins.
#[derive(Debug)]
pub struct Builtin;
pub struct Builtins;
/// Represents an attribute in `builtins`.
#[derive(Debug)]
pub struct Builtin(pub String);

View File

@@ -206,17 +206,17 @@ fn op_resolve_path(#[string] path: String) -> std::result::Result<String, NixErr
struct RuntimeContext<'a, 'b> {
scope: &'a v8::PinnedRef<'a, v8::HandleScope<'b>>,
is_thunk_symbol: Option<v8::Local<'a, v8::Symbol>>,
is_primop_symbol: Option<v8::Local<'a, v8::Symbol>>,
primop_metadata_symbol: Option<v8::Local<'a, v8::Symbol>>,
}
impl<'a, 'b> RuntimeContext<'a, 'b> {
fn new(scope: &'a v8::PinnedRef<'a, v8::HandleScope<'b>>) -> Self {
let is_thunk_symbol = Self::get_is_thunk_symbol(scope);
let is_primop_symbol = Self::get_is_primop_symbol(scope);
let primop_metadata_symbol = Self::get_primop_metadata_symbol(scope);
Self {
scope,
is_thunk_symbol,
is_primop_symbol,
primop_metadata_symbol,
}
}
@@ -237,18 +237,18 @@ impl<'a, 'b> RuntimeContext<'a, 'b> {
}
}
fn get_is_primop_symbol(
fn get_primop_metadata_symbol(
scope: &v8::PinnedRef<'a, v8::HandleScope<'b>>,
) -> Option<v8::Local<'a, v8::Symbol>> {
let global = scope.get_current_context().global(scope);
let nix_key = v8::String::new(scope, "Nix")?;
let nix_obj = global.get(scope, nix_key.into())?.to_object(scope)?;
let is_primop_sym_key = v8::String::new(scope, "IS_PRIMOP")?;
let is_primop_sym = nix_obj.get(scope, is_primop_sym_key.into())?;
let primop_metadata_sym_key = v8::String::new(scope, "PRIMOP_METADATA")?;
let primop_metadata_sym = nix_obj.get(scope, primop_metadata_sym_key.into())?;
if is_primop_sym.is_symbol() {
is_primop_sym.try_cast().ok()
if primop_metadata_sym.is_symbol() {
primop_metadata_sym.try_cast().ok()
} else {
None
}
@@ -382,13 +382,13 @@ fn primop_name<'a, 'b>(
return None;
}
// Use cached IS_PRIMOP symbol from context
let is_primop_sym = ctx.is_primop_symbol?;
// Use cached PRIMOP_METADATA symbol from context
let primop_metadata_sym = ctx.primop_metadata_symbol?;
let scope = ctx.scope;
let obj = val.to_object(scope).unwrap();
if let Some(metadata) = obj.get(scope, is_primop_sym.into())
if let Some(metadata) = obj.get(scope, primop_metadata_sym.into())
&& let Some(metadata_obj) = metadata.to_object(scope)
&& let Some(name_key) = v8::String::new(scope, "name")
&& let Some(name_val) = metadata_obj.get(scope, name_key.into())
@@ -406,13 +406,13 @@ fn primop_app_name<'a, 'b>(
) -> Option<String> {
let name = primop_name(val, ctx)?;
// Get cached IS_PRIMOP symbol
let is_primop_sym = ctx.is_primop_symbol?;
// Get cached PRIMOP_METADATA symbol
let primop_metadata_sym = ctx.primop_metadata_symbol?;
let scope = ctx.scope;
let obj = val.to_object(scope).unwrap();
if let Some(metadata) = obj.get(scope, is_primop_sym.into())
if let Some(metadata) = obj.get(scope, primop_metadata_sym.into())
&& let Some(metadata_obj) = metadata.to_object(scope)
&& let Some(applied_key) = v8::String::new(scope, "applied")
&& let Some(applied_val) = metadata_obj.get(scope, applied_key.into())