You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Propagation of taint through string/numeric operations
52
-
- Enforcement of taint checks on dangerous ops (`kill`, `exec`, `system`, backticks, `open` with pipes)
53
-
- "Insecure dependency in X while running with -T switch" error mechanism
54
-
- The `-T` command-line switch activating taint mode
55
-
56
-
### Current state
57
-
58
-
`RuntimeScalar.isTainted()` always returns `false`. The `$^X` variable is never marked tainted. The `Config.pm` does not set `taint_support` key, so the test does not skip.
46
+
`Config.pm` now has `taint_support => ''` and `ccflags => '-DSILENT_NO_TAINT_SUPPORT'`, so `op/taint.t` skips gracefully. Full taint tracking remains unimplemented (`RuntimeScalar.isTainted()` always returns `false`).
59
47
60
-
### Quick workaround
61
-
62
-
Add `taint_support => ''` to `Config.pm` so the test skips entirely.
63
-
64
-
### Difficulty: Very Hard (full implementation), Trivial (skip workaround)
48
+
### Difficulty: Very Hard (full implementation) - skip workaround already applied
65
49
66
50
---
67
51
@@ -122,98 +106,33 @@ Making `(?{UNIMPLEMENTED_CODE_BLOCK})` non-fatal (replace with `(?:)` no-op) wou
122
106
123
107
## 4. delete local Construct
124
108
125
-
**Test:**`op/local.t` (0/319 - crashes before any output)
126
-
**Blocked tests:**~319
127
-
128
-
### What is needed
129
-
130
-
The `delete local` syntax:
131
-
```perl
132
-
deletelocal$hash{key}; # Save value, delete, restore on scope exit
133
-
deletelocal$array[idx];
134
-
```
135
-
136
-
Currently:
137
-
- The parser (`parseDelete` in `OperatorParser.java` line 549) does NOT check for a `local` keyword after `delete`
138
-
- No `DeleteLocalNode` or compilation path exists
139
-
- The test crashes at line 164 with "Not implemented: delete with dynamic patterns"
140
-
141
-
### Implementation plan
142
-
143
-
1.**Parser**: `parseDelete` must check for `local` keyword and produce a new AST node
144
-
2.**Compiler**: Emit save-state, delete, and scope-exit restore
145
-
3.**Runtime**: Use existing `dynamicSaveState`/`dynamicRestoreState` mechanism on hash/array elements
146
-
147
-
### Note
109
+
**Status:** FULLY IMPLEMENTED (2026-04-01)
148
110
149
-
Many tests before line 161 in local.t don't use `delete local`. If the parser didn't crash, ~100+ tests might pass.
111
+
`delete local` is fully implemented across all layers: parser (`OperatorParser.parseDelete`), JVM backend (`EmitOperatorDeleteExists`), bytecode compiler (`CompileExistsDelete.visitDeleteLocal`), opcodes (`HASH_DELETE_LOCAL`, `ARRAY_DELETE_LOCAL`, slices), runtime (`RuntimeHash.deleteLocal`, `RuntimeArray.deleteLocal`), and disassembler. Supports all forms: `delete local $hash{key}`, `delete local @hash{@keys}`, `delete local $array[idx]`, `delete local @array[@idx]`, and arrow-deref variants.
150
112
151
-
### Difficulty: Moderate
113
+
### Difficulty: Done
152
114
153
115
---
154
116
155
117
## 5. \(LIST) Reference Creation
156
118
157
-
**Test:**`op/ref.t` (97/265)
158
-
**Blocked tests:**~155
119
+
**Status:** JVM BACKEND IMPLEMENTED (2026-04-01)
159
120
160
-
### What is needed
161
-
162
-
`\(LIST)` should return a list of references to each element. E.g., `\(@array)` returns refs to each element; `\($a, $b)` returns `(\$a, \$b)`.
163
-
164
-
### Root cause
165
-
166
-
`RuntimeList.flattenElements()` (line 424) does not handle `PerlRange` objects. When `\(1..3)` is evaluated, the PerlRange passes through unflattened, then `createReference()` throws "Can't create reference to list".
167
-
168
-
### Fix
169
-
170
-
Add PerlRange handling to `flattenElements()` (~5 lines):
171
-
```java
172
-
} elseif (element instanceofPerlRange range) {
173
-
for (RuntimeScalar scalar : range) {
174
-
result.elements.add(scalar);
175
-
}
176
-
}
177
-
```
178
-
179
-
Also need to update `InlineOpcodeHandler.executeCreateRef()` for the bytecode interpreter path.
121
+
JVM backend works correctly: `EmitOperator.handleCreateReference` calls `flattenElements()` then `createListReference()`. `RuntimeList.flattenElements()` handles `PerlRange`, `RuntimeArray`, and `RuntimeHash`.
**Remaining:** Bytecode interpreter (`InlineOpcodeHandler.executeCreateRef`) does NOT call `flattenElements()`, so `\(@array)`, `\(1..3)` fail in `eval STRING` and `--interpreter` mode.
186
124
187
-
### Difficulty: Easy (this is actually a quick fix, ~5 lines)
125
+
### Difficulty: Easy (1-line fix in interpreter)
188
126
189
127
---
190
128
191
129
## 6. Tied Scalar Code Deref
192
130
193
-
**Test:**`op/tie_fetch_count.t` (64/343)
194
-
**Blocked tests:**~279
195
-
196
-
### What is needed
131
+
**Status:** FULLY IMPLEMENTED (2026-04-01)
197
132
198
-
`RuntimeCode.apply()`does not handle `TIED_SCALAR`type. When `$tied_var` holds a CODE ref and you call `&$tied_var`, the code falls through to "Not a CODE reference" error instead of calling `tiedFetch()`first.
133
+
All three `RuntimeCode.apply()`overloads handle `TIED_SCALAR`by calling `tiedFetch()` before proceeding. `RuntimeScalar.codeDerefNonStrict()`, `globDeref()`, and `globDerefNonStrict()`also handle tied scalars.
199
134
200
-
### Fix
201
-
202
-
Add `TIED_SCALAR` handling in all three `RuntimeCode.apply()` overloads:
203
-
```java
204
-
if (runtimeScalar.type ==RuntimeScalarType.TIED_SCALAR) {
1.**`lstat _` validation** - `Stat.lstatLastHandle()` does NOT validate `lastStatWasLstat`. Should throw "The stat preceding lstat() wasn't an lstat" when the previous call was `stat` not `lstat`. `FileTestOperator.java` already has this check for `-l _` but `Stat.java` doesn't.
### Difficulty: Easy-Medium (lstat validation is a 1-line fix; other items are moderate)
304
+
### Difficulty: Easy-Medium (remaining items)
389
305
390
306
---
391
307
392
308
## 15. printf Array Flattening
393
309
394
-
**Test:**`io/print.t` (8/24)
395
-
**Blocked tests:**~16
396
-
397
-
### What is needed
310
+
**Status:** IMPLEMENTED (2026-04-01)
398
311
399
-
When`printf @array` is called, the RuntimeArray argument is not flattened before extracting the format string. `IOOperator.printf()`calls `list.add(args[i])` which adds the array as-is; then `removeFirst()` expects a RuntimeScalar but gets a RuntimeArray.
312
+
Both`printf` methods in `IOOperator.java` now flatten `RuntimeArray` elements. `printf +()`(empty list) also handled. Remaining io/print.t failures may relate to `$\` null bytes or `%n` format specifier.
400
313
401
-
Additional issues:
402
-
- Null bytes in `$\` (output record separator)
403
-
-`%n` format specifier (writes char count via substr)
404
-
-`printf +()` (empty list)
405
-
406
-
### Key files
407
-
408
-
-`src/main/java/org/perlonjava/operators/IOOperator.java` (printf method, line 2386)
409
-
410
-
### Difficulty: Medium
314
+
### Difficulty: Done (core issue); remaining edge cases Medium
411
315
412
316
---
413
317
@@ -606,9 +510,20 @@ The Perl `class` feature (added in Perl 5.38) is partially implemented. Missing:
606
510
607
511
---
608
512
609
-
## 25. Test Failures Investigated 2026-04-01 (Not Quick Fixes)
513
+
## 25. Test Failures Investigated 2026-04-01 (Status Update)
514
+
515
+
Items marked FIXED were implemented on the `feature/test-failure-fixes` branch.
610
516
611
-
These were investigated during the `feature/test-failure-fixes` branch work session.
| op/while.t | 22/26 |**23/26**| While loop returns false condition value |
612
527
613
528
### op/time.t (71/72) - MOSTLY FIXED
614
529
-**Remaining failure:** Test 7 `changes to $ENV{TZ} respected` - Java caches timezone on startup via `ZoneId.systemDefault()`. Changing `$ENV{TZ}` at runtime has no effect.
@@ -701,55 +616,58 @@ These were investigated during the `feature/test-failure-fixes` branch work sess
701
616
702
617
---
703
618
704
-
## Priority Ranking by Impact
705
-
706
-
### Tier 1: Highest impact (1000+ tests unlocked)
619
+
## Priority Ranking by Impact (Updated 2026-04-01)
0 commit comments