Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/about/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ priorities and future plans.
- Reuse static literal regular-expression match wrappers per runtime and call
site, reducing recurring pattern-resolution and compilation overhead.

- Avoid arbitrary-precision allocation for ordinary native-integer unsigned
shifts while retaining the existing wide-integer fallback.

- Restore lexical-sub debugger dispatch and `glob` fallback behavior after an
undefined `CORE::GLOBAL::glob` slot on both execution backends.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ private static RuntimeScalar unsignedShiftRight(BigInteger value, long shift) {
return unsignedResult(value.shiftRight((int) shift));
}

/**
* Shift an ordinary native integer as a Perl unsigned value. Java long
* overflow supplies the required low 64-bit truncation; unsignedResult
* retains a BigInteger only when the resulting UV cannot be represented
* as a non-negative signed long.
*/
private static RuntimeScalar nativeUnsignedShift(long value, long shift, boolean left) {
if (shift >= 64) return RuntimeScalarCache.scalarZero;
return unsignedResult(left ? value << (int) shift : value >>> (int) shift);
}

private static BigInteger exactInteger(RuntimeScalar scalar) {
return scalar.type == RuntimeScalarType.INTEGER && scalar.value instanceof BigInteger
? (BigInteger) scalar.value : null;
Expand Down Expand Up @@ -525,13 +536,12 @@ public static RuntimeScalar shiftLeft(RuntimeScalar runtimeScalar, RuntimeScalar
// Fast path: both INTEGER with non-negative shift within Java's 64-bit word.
int t1 = runtimeScalar.type;
int t2 = arg2.type;
if (t1 == RuntimeScalarType.INTEGER && t2 == RuntimeScalarType.INTEGER
&& exactInteger(arg2) == null) {
if (hasNativeInteger(runtimeScalar) && hasNativeInteger(arg2)) {
long shift = arg2.getLong();
if (shift >= 0) {
return unsignedShiftLeft(unsignedValue(runtimeScalar), shift);
return nativeUnsignedShift(((Number) runtimeScalar.value).longValue(), shift, true);
} else if (shift != Long.MIN_VALUE) {
return unsignedShiftRight(unsignedValue(runtimeScalar), -shift);
return nativeUnsignedShift(((Number) runtimeScalar.value).longValue(), -shift, false);
}
return RuntimeScalarCache.scalarZero;
}
Expand Down Expand Up @@ -616,13 +626,12 @@ public static RuntimeScalar shiftRight(RuntimeScalar runtimeScalar, RuntimeScala
// Fast path: both INTEGER with non-negative shift within Java's 64-bit word.
int t1 = runtimeScalar.type;
int t2 = arg2.type;
if (t1 == RuntimeScalarType.INTEGER && t2 == RuntimeScalarType.INTEGER
&& exactInteger(arg2) == null) {
if (hasNativeInteger(runtimeScalar) && hasNativeInteger(arg2)) {
long shift = arg2.getLong();
if (shift >= 0) {
return unsignedShiftRight(unsignedValue(runtimeScalar), shift);
return nativeUnsignedShift(((Number) runtimeScalar.value).longValue(), shift, false);
} else if (shift != Long.MIN_VALUE) {
return unsignedShiftLeft(unsignedValue(runtimeScalar), -shift);
return nativeUnsignedShift(((Number) runtimeScalar.value).longValue(), -shift, true);
}
return RuntimeScalarCache.scalarZero;
}
Expand Down
Loading