Skip to main content

runshfunc

Function runshfunc 

Source
pub fn runshfunc(prog: &eprog, wrap: Option<&funcwrap>, name: &str)
Expand description

Port of void runshfunc(Eprog prog, FuncWrap wrap, char *name) from Src/exec.c:6166. The inner shell-function executor — fires module-registered wrapper handlers around the function body, with $_ (zunderscore) save/restore and a paramscope push/pop around the wordcode walk.

C control flow:

queue_signals();
ou = zalloc(ouu = underscoreused);
if (ou) memcpy(ou, zunderscore, underscoreused);
while (wrap) {                       // wrapper chain
    wrap->module->wrapper++;
    cont = wrap->handler(prog, wrap->next, name);
    wrap->module->wrapper--;
    if (!wrap->module->wrapper && (wrap->module->node.flags & MOD_UNLOAD))
        unload_module(wrap->module);
    if (!cont) {                     // wrapper handled it
        if (ou) zfree(ou, ouu);
        unqueue_signals();
        return;
    }
    wrap = wrap->next;
}
startparamscope();
execode(prog, 1, 0, "shfunc");
if (ou) { setunderscore(ou); zfree(ou, ouu); }
endparamscope();
unqueue_signals();

(a) wrap->module->wrapper++/-- (c:6178/6180) wired against module::MODULESTAB.modules[name].wrapper (i32), looked up by wrap.module.node.nam. Recursive unload during handler defers correctly. (b) unload_module(wrap->module) (c:6184) wired via modulestab.unload_module(name) when wrapper hits 0 AND MOD_UNLOAD flag is set on the module’s hashnode. (c) execode(prog, 1, 0, "shfunc") (c:6195) ported at exec.rs:6047. Body uses execode for the no-source (compiled-wordcode) branch and fusevm for the source-preserving (autoloaded) branch per cache coherence. (d) startparamscope/endparamscope Rust signatures take &mut HashTable (params.rs:7425/7435). We pass the global paramtab handle via the params crate.