Skip to content

fix: mask left shifts in numeric fast path - #1096

Merged
stephenamar-db merged 2 commits into
databricks:masterfrom
He-Pin:fix/left-shift-fast-path-mask
Jul 30, 2026
Merged

fix: mask left shifts in numeric fast path#1096
stephenamar-db merged 2 commits into
databricks:masterfrom
He-Pin:fix/left-shift-fast-path-mask

Conversation

@He-Pin

@He-Pin He-Pin commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Motivation

Jsonnet specifies shift counts are modulo 64. The numeric fast path (visitBinaryOpAsDouble) checked overflow with the unmasked count while the JVM masked the actual shift, making results path-dependent: (1 << 64) * 1 incorrectly errored instead of returning 1.

Modification

  • Normalize left-shift count with rr % 64 before the overflow check in the numeric fast path.
  • Add regressions for counts 64, 65, 128, zero operand, and nested arithmetic.

Result

Expression before after go-jsonnet jrsonnet
(1 << 64) * 1 error 1 1 1
(1 << 65) * 1 2 2 2 2
(1 << 128) * 1 error 1 1 1
(0 << 128) * 1 error 0 0 0
((1 << 64) + 0) * 1 error 1 1 1

Full matrix (JVM/JS/Wasm/Native) + checkFormat passed.

References

Motivation:
Jsonnet interprets shift counts modulo 64, but the numeric fast path validated
left shifts using the unmasked count. Expressions routed through outer
arithmetic could therefore fail even when the generic evaluator succeeded.

Modification:
Normalize non-negative left-shift counts modulo 64 before both overflow
validation and execution, and add regressions for counts 64, 65, and 128.

Result:
Numeric fast-path behavior now matches the generic evaluator, go-jsonnet,
jrsonnet, and the Jsonnet specification without changing valid count-65
behavior.

References:
- databricks#1096
- https://jsonnet.org/ref/spec.html
@He-Pin
He-Pin force-pushed the fix/left-shift-fast-path-mask branch from 6920423 to 34e2b63 Compare July 29, 2026 08:27
@He-Pin He-Pin changed the title Mask large left shifts in the numeric fast path fix: mask left shifts in numeric fast path Jul 29, 2026
Motivation:
The original tests only covered zero and positive left operands.
The overflow check uses math.abs(ll), so negative values exercise
a distinct code path that should be regression-protected.

Modification:
Add assertions for (-1)<<64, (-2)<<65, (-3)<<128 through the
numeric fast path (via * 1).

Result:
Negative operand behavior is now locked in.
@stephenamar-db
stephenamar-db merged commit 837c6ef into databricks:master Jul 30, 2026
5 checks passed
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