Skip to content

Commit 25b721e

Browse files
committed
Fix strict-refs NonStrict methods to properly check reference types
The NonStrict methods (hashDerefNonStrict and arrayDerefNonStrict) were incorrectly treating ALL types (including wrong reference types) as symbolic references. This broke type checking and caused tests to fail. The issue: When trying to do $arrayref->{key} or $hashref->[index], these should throw 'Not a HASH reference' or 'Not an ARRAY reference' errors, but instead they were being treated as symbolic references and converting the reference to a string to look up a global variable. Fix: Only STRING and BYTE_STRING types should be treated as symbolic references. Other types (ARRAYREFERENCE trying to be a hash, HASHREFERENCE trying to be an array, etc.) should throw appropriate errors, just like the strict versions do. Also added GLOB support to both NonStrict methods to match the strict versions. Partial fix for regressions in: - t/op/avhv.t: 0/40 → 16/40 (VerifyError remains at line 155) - t/op/magic.t: Still investigating (103/208) - Other tests: TBD
1 parent 4f0328a commit 25b721e

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

src/main/java/org/perlonjava/runtime/RuntimeScalar.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -972,12 +972,20 @@ public RuntimeHash hashDerefNonStrict(String packageName) {
972972
yield AutovivificationHash.createAutovivifiedHash(this);
973973
}
974974
case HASHREFERENCE -> (RuntimeHash) value;
975-
case TIED_SCALAR -> tiedFetch().hashDerefNonStrict(packageName);
976-
default -> {
975+
case GLOB -> {
976+
// When dereferencing a typeglob as a hash, return the hash slot
977+
RuntimeGlob glob = (RuntimeGlob) value;
978+
yield GlobalVariable.getGlobalHash(glob.globName);
979+
}
980+
case STRING, BYTE_STRING -> {
977981
// Symbolic reference: treat the scalar's string value as a variable name
978982
String varName = NameNormalizer.normalizeVariableName(this.toString(), packageName);
979983
yield GlobalVariable.getGlobalHash(varName);
980984
}
985+
case TIED_SCALAR -> tiedFetch().hashDerefNonStrict(packageName);
986+
default ->
987+
// All other types (ARRAYREFERENCE, INTEGER, DOUBLE, etc.) cannot be dereferenced as hashes
988+
throw new PerlCompilerException("Not a HASH reference");
981989
};
982990
}
983991

@@ -1008,12 +1016,20 @@ public RuntimeArray arrayDerefNonStrict(String packageName) {
10081016
yield AutovivificationArray.createAutovivifiedArray(this);
10091017
}
10101018
case ARRAYREFERENCE -> (RuntimeArray) value;
1011-
case TIED_SCALAR -> tiedFetch().arrayDerefNonStrict(packageName);
1012-
default -> {
1019+
case GLOB -> {
1020+
// When dereferencing a typeglob as an array, return the array slot
1021+
RuntimeGlob glob = (RuntimeGlob) value;
1022+
yield GlobalVariable.getGlobalArray(glob.globName);
1023+
}
1024+
case STRING, BYTE_STRING -> {
10131025
// Symbolic reference: treat the scalar's string value as a variable name
10141026
String varName = NameNormalizer.normalizeVariableName(this.toString(), packageName);
10151027
yield GlobalVariable.getGlobalArray(varName);
10161028
}
1029+
case TIED_SCALAR -> tiedFetch().arrayDerefNonStrict(packageName);
1030+
default ->
1031+
// All other types (HASHREFERENCE, INTEGER, DOUBLE, etc.) cannot be dereferenced as arrays
1032+
throw new PerlCompilerException("Not an ARRAY reference");
10171033
};
10181034
}
10191035

0 commit comments

Comments
 (0)