Expand description
Shell command executor for zshrs
Executes the parsed shell AST via fusevm bytecodes. Builtins are dispatched through fusevm’s CallBuiltin mechanism, with handlers accessing executor state via thread-local.
Structs§
- Autoload
Flags - Flags for autoloaded functions
- Comp
Group - Completion group for organizing matches
- Comp
Init BgResult - Result from background compinit thread
- Comp
Match - A single completion match for zsh-style completion
- Comp
Spec - A completion specification for the
completebuiltin - Comp
State - zsh completion state (compstate associative array)
- Fork
Flags - Flags for zfork()
- Intercept
- An intercept registration.
- Profile
Entry - Profiling entry for zprof
- Scheduled
Command - Scheduled command for sched builtin
- Shell
Executor - Subshell
Flags - Flags for entersubsh()
- Subshell
Snapshot - Snapshot of subshell-isolated state. Captured at
(entry, restored at)exit. zsh subshell semantics: assignments inside(…)don’t leak to the outer scope — and that includesexport. zsh forks a child for the subshell so the child’s env::set_var dies with the child; without a fork (zshrs runs subshells in-process for perf), we snapshot+restore the OS env table around the subshell. Otherwise(export y=v)would leakyto the parent shell, breaking every script that uses a subshell to scope an env override. - Unix
Socket State - Unix domain socket state
- VarAttr
- Variable attribute record for
(t)flag introspection. Mirrors the type+flag bitmask zsh tracks per Param. Each instance picks exactly one base kind plus zero-or-more attribute markers. - ZStyle
- zstyle entry for completion configuration
- Zpty
State - State for a zpty pseudo-terminal
- Zshrs
Host ShellHostimplementation that delegates to the currentShellExecutorvia thewith_executorthread-local.
Enums§
- Advice
Kind - AOP advice type — before, after, or around.
- Builtin
Type - Builtin command type
- Fork
Result - Result of fork operation
- Loop
Signal - Cross-VM loop-control signal. When
break/continueis hit inside a body that runs on a sub-VM (e.g. select’s body), the inline patches mechanism can’t reach the outer loop — set this flag and the outer-loop builtin drains it after each iteration. - Redir
Mode - Redirection mode
- VarKind
Constants§
- BUILTIN_
APPEND_ ARRAY arr+=(d e f)— append N elements to an existing indexed array. Compile emits N element pushes + name push, thenCallBuiltin(295, N+1). Handler drains args (last popped = name), extendsexecutor.arrays[name](creates the entry if missing). Mirrors zsh’s+=semantics for indexed arrays.- BUILTIN_
APPEND_ ASSOC m[k]+=value— append onto an existing assoc-array value (string concat). If the key doesn’t exist, behaves like SET_ASSOC. Stack: [name, key, value].- BUILTIN_
APPEND_ SCALAR_ OR_ PUSH name+=val(no parens) — runtime-dispatched append. If name is an indexed array → push val as element. If name is an assoc array → error (zsh requires(k v)form). Else → scalar concat (existing SET_VAR behavior).- BUILTIN_
ARITH_ EVAL $((expr))arithmetic substitution. Pops [expr_string], evaluates via the executor’s MathEval (integer-aware), returns result as Value::Str. Bypasses ArithCompiler’s float-only Op::Div path so$((10/3))returns “3” not “3.333…”.- BUILTIN_
ARRAY_ ALL ${arr[@]}— splice all elements as a Value::Array. Pops one arg: name. The Array gets flattened by Op::Exec/ExecBg/CallFunction into argv.- BUILTIN_
ARRAY_ FLATTEN - Flatten one level of Value::Array nesting. Pops N values; for each, if it’s
a Value::Array, its elements are appended directly; otherwise the value is
appended as-is. Pushes a single Value::Array of the flattened result. Used
by the for-loop word-list compile path: when a word like
${arr[@]}produces a nested Array, this letsfor i in ${arr[@]}iterate over the inner elements rather than the outer single-element array. - BUILTIN_
ARRAY_ INDEX ${arr[idx]}— single-element array index. Pops two args: stack: [name, idx_str] Returns the indexed element as Value::str. Indexing semantics: zsh is 1-based by default; bash is 0-based. We follow zsh. Special idx values:@and*return the whole array as Value::Array (which fuses correctly via the Op::Exec splice for argv splice).- BUILTIN_
ARRAY_ JOIN - Builtin ID for
Array → Stringjoining. Pops one value: if it’s an Array, joins its string-coerced elements with a single space; otherwise passes through. Used afterOp::Globto convert the pattern’s matched paths into the single argv-token form the bytecode word model expects (no per-word splitting yet — that’s a future phase). - BUILTIN_
ARRAY_ JOIN_ STAR - BUILTIN_
ARRAY_ LENGTH ${#arr[@]}and${#arr}(when arr is an array name) — array length. Pops one arg: name. Returns Value::str of len.- BUILTIN_
BRACE_ EXPAND - Brace expansion:
{a,b,c}→ 3 values,{1..5}→ 5 values,{01..05}→ zero-padded numerics,{a..e}→ letter range. Pops one string, returns Value::Array of expansions (empty array → original string preserved). - BUILTIN_
CMD_ SUBST_ TEXT $(cmd)command substitution. Pops [cmd_string], runs throughrun_command_substitutionwhich compiles via ZshParser+ZshCompiler and captures stdout via an in-process pipe. Returns trimmed output as Value::Str. Avoids the sub-chunk word-emit quoting bug in the raw Op::CmdSubst path.- BUILTIN_
CONCAT_ DISTRIBUTE - Word-segment concat that does cartesian-product distribution over
arrays. Stack: [lhs, rhs]. Used for RC_EXPAND_PARAM
${arr}and explicit-distribute forms (${^arr},${(@)…}). - BUILTIN_
CONCAT_ SPLICE - Word-segment concat with FIRST/LAST sticking. Stack: [lhs, rhs].
Used for default unquoted splice forms (
${arr[@]},$@,$*) where prefix sticks to first element only and suffix to last only. - BUILTIN_
ERREXIT_ CHECK - BUILTIN_
EXPAND_ TEXT - Text-based word expansion. Pops [preserved_text]: the word with
quotes preserved (DNULL→
", SNULL→', BNULL→\), runsexpand_string(variable + cmd-sub + arith) thenexpand_bracesthenexpand_glob. Returns Value::str (single match) or Value::Array (multi-match brace/glob). - BUILTIN_
FILE_ MODIFIED_ SINCE_ ACCESS [[ -N path ]]— file modified since last accessed (atime <= mtime).- BUILTIN_
FILE_ NEWER [[ a -nt b ]]— fileanewer than fileb(mtime strict). Stack: [path_a, path_b]. Pushes Bool. zsh-compatible “missing” rules: if both exist, compare mtime; if onlyaexists → true; otherwise false.- BUILTIN_
FILE_ OLDER [[ a -ot b ]]— mirror of-nt. If both exist, compare mtime; if onlybexists → true; otherwise false.- BUILTIN_
GET_ VAR - Builtin ID for
${name}reads — routes throughShellExecutor::get_variablewhich knows about special params ($?,$@,$#,$1..$9), shell vars (self.variables), arrays, and env. Replaces emission ofOp::GetVarfor shell variable names so nested VMs (function calls) see the same storage. - BUILTIN_
GLOB_ EXPAND - Pop a scalar from the VM stack, run expand_glob on it, push the
result as Value::Array. Used by the segment-concat compile path
when var refs concatenate with glob meta literals (
$D/*,${prefix}*, etc.) — those skip the bridge’s pathname-expansion pass and would otherwise leak the glob meta to argv as a literal. - BUILTIN_
GLOB_ QUALIFIED - Glob qualifier filter:
*(qualifier)filters glob results by predicate. Pops [pattern, qualifier_string]. Returns Value::Array of matching paths. - BUILTIN_
HAS_ SETGID [[ -g path ]]— setgid bit (S_ISGID).- BUILTIN_
HAS_ SETUID [[ -u path ]]— setuid bit (S_ISUID).- BUILTIN_
HAS_ STICKY [[ -k path ]]— sticky bit (S_ISVTX) set on path.- BUILTIN_
IS_ BLOCKDEV [[ -b path ]]— block device.- BUILTIN_
IS_ CHARDEV [[ -c path ]]— character device.- BUILTIN_
IS_ FIFO [[ -p path ]]— FIFO / named pipe.- BUILTIN_
IS_ SOCKET [[ -S path ]]— socket.- BUILTIN_
IS_ TTY [[ -t fd ]]— fd-is-a-tty check. Stack: [fd_string]. Routes through libc::isatty. Pushes Bool.- BUILTIN_
OPEN_ NAMED_ FD {name}>file/{name}<file/{name}>>file— named-fd allocation. Stack: [path, varid, op_byte]. Openspathperop_byte, gets the new fd (≥10 in zsh; we use libc::open with O_CLOEXEC bit cleared so the inherited fd survives Command::new spawns), stores the fd number as a string in$varid. Pushes Status (0 success, 1 error).- BUILTIN_
OPTION_ SET [[ -o option ]]— shell-option-set test. Stack: [option_name]. Normalizes the name (strip underscores, lowercase) and readsexec.options. Pushes Bool.- BUILTIN_
OWNED_ BY_ GROUP [[ -G path ]]— owned by effective GID.- BUILTIN_
OWNED_ BY_ USER [[ -O path ]]— owned by effective UID.- BUILTIN_
PARAM_ DEFAULT_ FAMILY - Phase 1 native param-modifier builtins. Each takes a fixed argv shape and returns the modified value as Value::Str. Replaces the runtime ShellWord round-trip via BUILTIN_EXPAND_WORD_RUNTIME for the common shapes.
- BUILTIN_
PARAM_ FILTER ${var:#pattern}— array filter: remove elements matchingpattern. Stack: [name, pattern]. For scalarvar, returns empty if it matches the pattern, else the value. For arrayvar, returns Array of non-matching elements.- BUILTIN_
PARAM_ FLAG ${(flags)name}— zsh parameter expansion flags. Stack: [name, flags]. Flags applied left-to-right. Supported subset (high-value, used by zpwr):- BUILTIN_
PARAM_ LENGTH ${#name}— character length of a scalar value, or element count of an indexed/assoc array. Pops [name], returns count as Value::Str.- BUILTIN_
PARAM_ REPLACE ${var/pat/repl}/${var//pat/repl}/${var/#pat/repl}/${var/%pat/repl}— pop [name, pattern, replacement, op_byte]. op_byte: 0=first, 1=all, 2=anchor-prefix, 3=anchor-suffix.- BUILTIN_
PARAM_ STRIP ${var#pat}/${var##pat}/${var%pat}/${var%%pat}— pop [name, pattern, op_byte]. op_byte: 0=#, 1=##, 2=%, 3=%%.- BUILTIN_
PARAM_ SUBSTRING ${var:offset[:length]}— pop [name, offset, length] (length=-1 means “rest of value”; negative offset counts from end).- BUILTIN_
PARAM_ SUBSTRING_ EXPR - BUILTIN_
REGEX_ MATCH - Re-export the regex_match host method as a builtin so
[[ s =~ pat ]]works even when fusevm’s Op::RegexMatch isn’t routed (compat fallback). - BUILTIN_
REGISTER_ COMPILED_ FN - Register a pre-compiled fusevm chunk as a function. Stack: [name, base64-bincode-of-Chunk]. Used by compile_zsh’s compile_funcdef to register functions parsed via ZshParser without going through the ShellCommand JSON serialization path.
- BUILTIN_
RUN_ BG - Builtin ID for
cmd &background execution. IDs 287/288/289 are reserved for the planned array work in Phase G1 (SET_ARRAY/SET_ASSOC/ARRAY_INDEX), so this lands at 290. Pops one sub-chunk index; forks; child detaches (setsid), runs the sub-chunk on a fresh VM, exits with last_status; parent returns Status(0) immediately. Job-table registration (sojobs/fg/waitcan see the pid) is deferred to Phase G6 — fire-and-forget for now. - BUILTIN_
RUN_ COPROC coproc [name] { body }— bidirectional pipe to async child. Pops a name (optional, “” for default) and a sub-chunk index. Creates two pipes, forks, child redirects its fd 0/1 to the inner ends and runs the body, parent stores [write_fd, read_fd] into the named array (defaultCOPROC). Caller closes the fds andwaits when done. Job-table integration deferred to Phase G6 alongside the bg&work.- BUILTIN_
RUN_ PIPELINE - Builtin ID for pipeline execution. Pops N sub-chunk indices from the stack;
each index points into
vm.chunk.sub_chunks(compiled stage bodies). Forks N children, wires stdin/stdout between them via pipes, runs each stage’s bytecode on a fresh VM in its child, parent waits for all and pushes the last stage’s exit status. This is bytecode-native pipeline execution — no tree-walker delegation. - BUILTIN_
RUN_ SELECT select var in words; do body; done— interactive numbered-menu loop. Compile emits N word pushes + var-name push + sub-chunk index push, thenCallBuiltin(296, N+2). Handler prints1) word1\n2) word2\n...to stderr, prints$PROMPT3(default?#) to stderr, reads a line from stdin. On EOF returns 0. On a valid 1-based number, setsvarto the chosen word, runs the sub-chunk, then redisplays the menu and loops. On invalid input redraws the menu without running the body.breakfrom inside the body exits the loop (handled by the body’s own bytecode).- BUILTIN_
SAME_ FILE [[ a -ef b ]]— same-inode test. Stack: [a, b]. Pushes Bool true iff both paths resolve to the same(dev, inode)pair (zsh + bash semantics).- BUILTIN_
SET_ ARRAY - Indexed-array assignment:
arr=(a b c). Compile_simple emits N element pushes followed by name push, thenCallBuiltin(BUILTIN_SET_ARRAY, N+1). The handler pops args (last popped = name in our pushing order) and storesVec<String>intoexecutor.arrays. Tree-walker callers see the same storage. Any prior scalar binding inexecutor.variablesfornameis removed so${name}(scalar context) consistently reflects the array’s first element viaget_variable. - BUILTIN_
SET_ ASSOC - Single-key set on an associative array:
foo[key]=val. Stack (top-down): [name, key, value]. Storesvalueintoexecutor.assoc_arrays[name][key], creating the outer entry if missing. compile_simple detectsvar[...]=...in assignments and emits this builtin. - BUILTIN_
SET_ BREAK breakfrom inside a body that runs on a sub-VM (select, future loop-via- builtin constructs). Setsexecutor.loop_signal = Some(LoopSignal::Break). Outer-loop builtins drain the flag after each body run and exit early.- BUILTIN_
SET_ CONTINUE continuefrom inside a sub-VM body. Sets the signal to Continue. Outer loop builtins drain + skip-to-next-iteration.- BUILTIN_
SET_ LINENO - Update
$LINENOto track the source line of the next statement. Stack: [n] (the line number fromZshPipe.lineno). Direct port of zsh’slinenoglobal tracking (Src/input.c:330) — the compiler emits one of these per top-level pipe so$LINENOreflects the source position at runtime. ID 342 picked because the previous326collided withBUILTIN_HAS_STICKY(the file has several other duplicate IDs — 325 has two as well — but fixing those is out of scope for this port). - BUILTIN_
SET_ RAW_ OPT - BUILTIN_
SET_ SUBSCRIPT_ RANGE a[i]=(elements)/a[i,j]=(elements)/a[i]=()— subscripted-array assign with array-literal RHS. Stack: […elements, name, key]. Empty elements + single-int keya[i]=()removes that element. Comma-keya[i,j]=(...)splices.- BUILTIN_
SET_ TRY_ BLOCK_ ERROR - Capture current
last_statusinto theTRY_BLOCK_ERRORvariable. Emitted between the try block and the always block of{ … } always { … }so the finally arm can read $TRY_BLOCK_ERROR. - BUILTIN_
SET_ VAR - Builtin ID for
name=valueassignments — pops [name, value] and stores intoexecutor.variables. ReplacesOp::SetVaremission for the same reason: the storage must be visible to both bytecode and tree-walker code, across nested VM boundaries. - BUILTIN_
TIME_ SUBLIST time { compound; ... }— wall-clock-time the sub-chunk and print elapsed seconds. Stack: [sub_chunk_idx as Int]. Runs the sub-chunk on the current VM (so positional/local state is shared) and prints the timing summary to stderr in zsh’s format. Pushes Status.- BUILTIN_
UNKNOWN_ COND [[ -X file ]]for unknown unary test op-X. Stack: [op_name]. Emits zsh’sunknown condition: -Xdiagnostic to stderr and pushes Bool(false). Without this, unknown conditions silently returned false matching neither zsh’s error format nor the expected status code (zsh returns 2 for parse error).- BUILTIN_
VAR_ EXISTS - BUILTIN_
WORD_ SPLIT - Word-split a string on IFS (default: whitespace). Pops one string,
returns Value::Array of fields. Used in array-literal context where
arr=($(cmd))should expand cmd’s stdout into multiple elements. - BUILTIN_
XTRACE_ LINE
Functions§
- format_
function_ body_ zsh - Format a function body the way zsh’s
typeset -f/functionsdisplay it: each top-level statement on its own line (split on;and\n), trailing semicolons stripped, no empty lines. Matches/bin/zsh -f -c 'f() { echo a; echo b; }; typeset -f f'output: f () { (tab)echo a (tab)echo b } - format_
int_ in_ base - Format an integer in the given base (2-36) using zsh’s
BASE#DIGITSform. Bases 2-9 are unsigned-style; uppercase A-Z are used for digits - pretty_
io_ err - Strip Rust’s “(os error N)” suffix from an io::Error display so
the message matches BSD/GNU coreutils’ output (e.g. zsh’s bundled
cat/head emit
cat: foo: No such file or directory, notcat: foo: No such file or directory (os error 2)). Used by all the in-process coreutils builtins. - underscore_
separate_ digits - Insert
_separators everygroupdigits, counting from the end of the digit run (right-to-left). Direct port ofconvbase_underscorein src/zsh/Src/params.c:5645-5680. Operates on the digit suffix only, preserving anyBASE#prefix and leading sign.