Skip to content

Conversation

@fglock
Copy link
Owner

@fglock fglock commented Jan 13, 2026

Summary

Fixes typeglob assignment for scalar references (e.g. *a = \\1 / *foo = \\$bar) to alias/replace the SCALAR slot container rather than storing into the existing scalar.

Why

Perl treats *foo = \\$bar as aliasing the glob's SCALAR slot. The previous behavior stored into the existing scalar container, which incorrectly triggered tied scalar STORE in cases like FETCH { *a = \\1; ... } (perl5 op/tie.t).

Change

  • RuntimeGlob.set() (case REFERENCE fallback) now calls GlobalVariable.aliasGlobalVariable() for scalar-ref assignments.

Test impact

  • Improves perl5_t/t/op/tie.t from 40/95 to 41/95 by fixing the tied-glob assignment case ("FETCH freeing tie'd SV still works").

fglock added 30 commits January 6, 2026 17:31
…l-like stat buffer caching for stacked filetests, fix -s to return 0 for empty files, add -l warnings for filehandles, fix NullPointerException in exception formatting
fglock added 21 commits January 12, 2026 13:47
…d reuse value instead of calling FETCH multiple times
…d environment array

The issue occurred when eval strings declared new variables at runtime, causing
the runtime symbol table to allocate non-contiguous slot indices (with gaps).
This created a mismatch between compile-time and runtime constructor signatures.

Changes:
- Add capturedEnv field to EmitterContext to store the exact environment array
  from compile-time
- Modify EmitEval to store newEnv in evalCtx.capturedEnv
- Modify RuntimeCode.evalStringHelper to pass capturedEnv to runtime context
- Modify EmitterMethodCreator to use capturedEnv when available instead of
  calling getVariableNames() again
- Update getVariableDescriptor/getVariableClassName to handle null entries
  gracefully (return RuntimeScalar descriptor for gaps)
- Skip null entries when creating fields and PUTFIELD, but include them in
  constructor signature to maintain consistent parameter counts

Result: io/open.t now completes successfully with 181/216 tests passing
(exceeds target of 150 passing tests)
- Fix  aliasing in ListOperators (map/grep/all/any) to prevent read-only assignment errors
- Add fast-path in RuntimeScalar.getDouble() to break infinite recursion with NumberParser
- Fix pack slash-construct Z*/Z<n> to correctly null-terminate within field width
- Fix unpack A* to trim Unicode whitespace only for UTF-8 flagged strings
- Fix pack a/A/Z to preserve byte values 0-255 using ISO-8859-1 encoding

Reduces op/pack.t failures from ~150 to 85 (target: 0)
- Add Pack.getGroupBaseAtLevel() to support multi-level group references
- Fix . format to handle .2 (parent group), .* (absolute position)
- Add PackBuffer methods for character-based positioning (hasUnicodeCharacters, truncateToCharacter)
- Update . and @ formats to use character mode for UTF-8 strings (W format)

Reduces op/pack.t failures from 85 to 77
- Use Math.addExact/subtractExact to detect long overflow and promote to double
- Fix ScalarUtils.stringIncrement to handle Long.MAX_VALUE overflow directly
- Avoids recursion issues and matches Perl NV semantics
- Fixes op/64bitint.t (78/78 passing)
- No regressions in op/pack.t (14620/14726 stable)
- Add UTF-8 byte-aware positioning for .! and @! formats in pack/unpack
- Fix pack to return upgraded strings when output contains Unicode >255
- Fix pack 'c' to avoid triggering string overload (use getDouble for Inf/NaN check)
- Fix pack 'H' to stop at NUL like Perl
- Fix pack 'a*' to preserve Unicode characters instead of replacing with '?'
- Improve string concatenation to preserve BYTE_STRING semantics
- Add PackBuffer UTF-8 byte length/offset/truncate helpers
- Add AtShriekFormatHandler for unpack @! byte positioning

Tests: op/pack.t now at 14628/14726 passing (was ~14570/14726)
The previous stringConcat change incorrectly encoded Unicode strings
to ISO_8859_1 when both operands were BYTE_STRING type, replacing
characters >255 with '?'.

Now checks actual string content for Unicode characters before deciding
to encode as bytes. If Unicode is present, returns STRING type to
preserve characters correctly.

Fixes:
- uni/chomp.t: restored to 446/446 passing
- comp/utf.t: restored to 4208/4216 passing
- pack.t: still 14628/14726 passing (no regression)
When incrementing large integer strings like '2147483648', stringIncrement
was storing the result as a Long object with INTEGER type. This caused
ClassCastException in preAutoIncrement which expects Integer objects for
INTEGER type.

Fix: Check if incremented value fits in int range and store as Integer.
Otherwise, promote to DOUBLE to match Perl semantics.

Fixes:
- op/inc.t: restored to 53/71 passing (was stopping at 11/71)
- re/charset.t: maintained at 5258/5552 passing
- uni/chomp.t: maintained at 446/446 passing
- comp/utf.t: maintained at 4208/4216 passing
- op/pack.t: maintained at 14628/14726 passing
- Add LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME to @EXPORT_OK
- Provide pure-Perl fallback definitions for these constants
- Fixes 'Undefined subroutine &POSIX::LC_CTYPE' errors in op/lc.t

Note: op/lc.t still has other failures, but this resolves the immediate abort.
Reverting regex-related changes from commit c912f6e which introduced regressions:
- re/charset.t: recovered from 5258 to 5282 passing (+24)
- re/subst.t: recovered from 169 to 183 passing (+14)
- re/regex_sets_compat.t: recovered from 2075 to 2084 passing (+9)

Total recovery: +47 tests back to baseline levels.

The reverted changes included:
- \G assertion handling modifications
- Capture snapshotting changes
- Octal escape sequence processing updates
- CharacterClassMapper [:] handling

These changes will need to be re-evaluated and fixed properly in a future commit.
…bytes context

Add isEvalbytes flag to CompilerOptions to distinguish evalbytes context from
regular eval. In evalbytes, string literals with characters <= 255 are treated
as raw byte values instead of being UTF-8 encoded.

This fixes test 3 in op/evalbytes.t where evalbytes(qq('\xff\xfe')) now
correctly returns raw bytes ff fe instead of UTF-8 encoded c3 bf c3 be.

Restores op/evalbytes.t from 5/9 to baseline 6/9.
Include feature flags in eval cache key to prevent incorrect cache hits
when feature context differs. This is part of fixing op/lc.t test 132.

Still investigating why unicode_strings feature flag is not being
preserved in eval compilation.
@fglock fglock merged commit 5eb5039 into master Jan 13, 2026
2 checks passed
@fglock fglock deleted the fix-control-flow-tagged-returns branch January 13, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants