Files
jq/src/opcode_list.h
T
itchyny df24981307 Fix reduce to preserve its input across init backtracking (#3633)
`reduce f as $x (init; update)` evaluated `f` against a stack slot
that forkpoints created while evaluating `init` restore. Both the
`DUPN` opening the reduction loop and the `LOADVN` retrieving the
result pop that slot destructively, nulling it out, so an `init`
that backtracks (e.g. `0, 0`) made `f` see `null` and fail with
"Cannot iterate over null".

Duplicate the input before the `FORK` instead of inside the loop,
and drop the leftover copy with `POP` once the loop is exhausted.
The slot left live at the `FORK` is then a block pushed after
`init` completed, which no earlier forkpoint can reach, so nulling
it is harmless. This is the same approach `gen_foreach` has used
since c70ae1a.

`DUPN` had no other user, so remove the opcode.
2026-09-19 15:21:29 +09:00

51 lines
1.2 KiB
C

OP(LOADK, CONSTANT, 1, 1)
OP(DUP, NONE, 1, 2)
OP(DUP2, NONE, 2, 3)
OP(PUSHK_UNDER, CONSTANT, 1, 2)
OP(POP, NONE, 1, 0)
OP(LOADV, VARIABLE, 1, 1)
OP(LOADVN, VARIABLE, 1, 1)
OP(STOREV, VARIABLE, 1, 0)
OP(STORE_GLOBAL, GLOBAL, 0, 0)
OP(INDEX, NONE, 2, 1)
OP(INDEX_OPT, NONE, 2, 1)
OP(EACH, NONE, 1, 1)
OP(EACH_OPT, NONE, 1, 1)
OP(FORK, BRANCH, 0, 0)
OP(TRY_BEGIN, BRANCH, 0, 0)
OP(TRY_END, NONE, 0, 0)
OP(JUMP, BRANCH, 0, 0)
OP(JUMP_F,BRANCH, 1, 0)
OP(BACKTRACK, NONE, 0, 0)
OP(APPEND, VARIABLE,1, 0)
OP(INSERT, NONE, 4, 2)
OP(RANGE, VARIABLE, 1, 1)
OP(SUBEXP_BEGIN, NONE, 1, 2)
OP(SUBEXP_END, NONE, 2, 2)
OP(PATH_BEGIN, NONE, 1, 2)
OP(PATH_END, NONE, 2, 1)
OP(CALL_BUILTIN, CFUNC, -1, 1)
OP(CALL_JQ, UFUNC, 1, 1)
OP(RET, NONE, 1, 1)
OP(TAIL_CALL_JQ, UFUNC, 1, 1)
OP(CLOSURE_PARAM, DEFINITION, 0, 0)
OP(CLOSURE_REF, CLOSURE_REF_IMM, 0, 0)
OP(CLOSURE_CREATE, DEFINITION, 0, 0)
OP(CLOSURE_CREATE_C, DEFINITION, 0, 0)
OP(TOP, NONE, 0, 0)
OP(CLOSURE_PARAM_REGULAR, DEFINITION, 0, 0)
OP(DEPS, CONSTANT, 0, 0)
OP(MODULEMETA, CONSTANT, 0, 0)
OP(GENLABEL, NONE, 0, 1)
OP(DESTRUCTURE_ALT, BRANCH, 0, 0)
OP(STOREVN, VARIABLE, 1, 0)
OP(ERRORK, CONSTANT, 1, 0)