WIP: Improve op/state.t pass rate (69 → 141/170)#414
Merged
Conversation
fglock
added a commit
that referenced
this pull request
Mar 31, 2026
Record PR #414 results: op/state.t 69/170 → 141/170. Mark item 1.5 as done, update Category 5 table, add progress tracking section. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…back - BytecodeCompiler: Split BEGIN-captured variables (RETRIEVE_BEGIN_*) from state variables without initializers (STATE_INIT_*). State vars previously used RETRIEVE_BEGIN_SCALAR which calls removeGlobalVariable(), destroying state on each call. Now uses STATE_INIT_SCALAR which persists correctly. - BytecodeCompiler: Add LoopInfo push/pop for bare blocks so redo/next/last can find their target loop in the interpreter. - EmitControlFlow: Dynamic goto EXPR (computed label) now triggers interpreter fallback instead of creating a GOTO marker that silently exits. The interpreter supports GOTO_DYNAMIC with label-to-PC lookup. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Perl 5 forbids initializing state variables in list context, e.g.: (state $a) = 1; state ($a, $b) = (); (state $a, my $b) = (); Added validation in ParseInfix.java that detects state declarations on the left side of list assignments and throws: "Initialization of state variables in list currently forbidden" This fixes 46 tests in op/state.t (tests 108-153), bringing the pass rate from 95/170 to 141/170. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Record PR #414 results: op/state.t 69/170 → 141/170. Mark item 1.5 as done, update Category 5 table, add progress tracking section. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…tion
Interpreter backend:
- Add opcodes for symlink, chroot, mkdir, exec, fcntl, ioctl,
getpwent, setpwent, endpwent, msgctl, shmctl, semctl
- Wire existing IPC opcodes (shmget, shmread, shmwrite, semget,
semop, msgget, msgsnd, msgrcv) into CompileOperator
- Add NUL-byte guard for file test operators
- Add chroot and setpriority stubs
This fixes "Unsupported operator" errors when large test files
(like op/taint.t) trigger interpreter fallback.
CORE:: subroutine wrappers:
- Add lazy generation in all RuntimeCode.apply() overloads
- &CORE::reverse("hello") and similar calls now work correctly
- Previously only \&CORE::reverse worked; direct &CORE::X calls
threw "Undefined subroutine" because the wrapper was never generated
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
When a GOTO or TAILCALL control flow marker was not handled by labeled
blocks in the interpreter CALL_SUB/CALL_METHOD handlers, it would
propagate all the way out and cause silent process exit. This happened
when code like eval { goto nonexistent_label } ran in functions
that triggered interpreter fallback.
Now, unhandled GOTO/TAILCALL markers check the evalCatchStack. If an
eval catch handler exists, the error variable is set to the error
message and execution jumps to the catch handler, matching the JVM
backend behavior.
Results: goto-sub.t improved from 17/44 to 32/44 (master baseline: 27/44)
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The JVM backend did not recognize goto \&NAME (backslash-reference to a
subroutine) as a tail-call form. It only handled goto &NAME (via
BinaryOperatorNode) and goto &{$var}/goto &$sub forms. The \&NAME
pattern fell through to the Dynamic goto EXPR catch-all, forcing
interpreter fallback.
This caused two problems:
1. Defer blocks did not fire before the tail-call (defer.t test 15)
2. Lexical closure variables were not properly shared after fallback
The fix recognizes OperatorNode("\\") containing a subroutine
reference and routes it through handleGotoSubroutine, which jumps to
returnLabel where try-finally cleanup (including defer blocks) runs
before the TAILCALL marker is returned to the caller.
Results: defer.t restored to 24/33 (master baseline), goto-sub.t 32/44
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
cec6618 to
c915666
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Improves op/state.t from 69/170 (40.6%) to 141/170 (82.9%) passing tests.
Changes
state $a(without initializer) was usingRETRIEVE_BEGIN_SCALARwhich destructively removes the variable from global storage on each call. Now usesSTATE_INIT_SCALARwhich preserves state across calls.goto EXPR(computed label) now triggers interpreter fallback instead of creating a GOTO marker that silently exits. The interpreter supports GOTO_DYNAMIC with label-to-PC lookup.(state $a) = 1,state ($a, $b) = (), etc. with error "Initialization of state variables in list currently forbidden" (Perl 5 parity).Remaining failures (15 tests + 14 blocked)
Test plan
makepasses (all unit tests)Generated with Devin