|
51 | 51 | * <ol> |
52 | 52 | * <li><b>Condition Table</b> - Array of 4-byte offsets pointing to each condition's bytecode</li> |
53 | 53 | * <li><b>Result Table</b> - Array of 4-byte offsets pointing to each result's bytecode</li> |
| 54 | + * <li><b>Register Definitions</b> - Array of parameter/register metadata (immediately after result table)</li> |
54 | 55 | * <li><b>Function Table</b> - Array of function names</li> |
55 | | - * <li><b>Register Definitions</b> - Array of parameter/register metadata</li> |
56 | | - * <li><b>BDD Table</b> - Array of BDD nodes</li> |
| 56 | + * <li><b>BDD Table</b> - Array of BDD nodes (3 ints per node)</li> |
57 | 57 | * <li><b>Bytecode Section</b> - Compiled instructions for conditions and results</li> |
58 | 58 | * <li><b>Constant Pool</b> - All constants referenced by the bytecode</li> |
59 | 59 | * </ol> |
60 | 60 | * |
61 | 61 | * <h3>Condition Table</h3> |
62 | 62 | * <p>Array of 4-byte offsets pointing to the start of each condition's bytecode. |
63 | | - * Each offset is absolute from the start of the file. |
| 63 | + * Each offset is absolute from the start of the file. When loaded, these are |
| 64 | + * adjusted to be relative to the bytecode section start for efficient access. |
64 | 65 | * |
65 | 66 | * <h3>Result Table</h3> |
66 | 67 | * <p>Array of 4-byte offsets pointing to the start of each result's bytecode. |
67 | | - * Each offset is absolute from the start of the file. |
68 | | - * |
69 | | - * <h3>Function Table</h3> |
70 | | - * <p>Array of function names used in the bytecode. Each function name is encoded as: |
71 | | - * <pre> |
72 | | - * [length:2][UTF-8 bytes] |
73 | | - * </pre> |
| 68 | + * Each offset is absolute from the start of the file. When loaded, these are |
| 69 | + * adjusted to be relative to the bytecode section start for efficient access. |
74 | 70 | * |
75 | 71 | * <h3>Register Definitions</h3> |
76 | | - * <p>Immediately follows the function table. Each register is encoded as: |
| 72 | + * <p>Immediately follows the result table. Each register is encoded as: |
77 | 73 | * <pre> |
78 | 74 | * [nameLen:2][name:UTF-8][required:1][temp:1][hasDefault:1][default:?][hasBuiltin:1][builtin:?] |
79 | 75 | * </pre> |
|
89 | 85 | * <li>builtin: UTF-8 encoded builtin name (only present if hasBuiltin=1)</li> |
90 | 86 | * </ul> |
91 | 87 | * |
| 88 | + * <h3>Function Table</h3> |
| 89 | + * <p>Array of function names used in the bytecode. Each function name is encoded as: |
| 90 | + * <pre> |
| 91 | + * [length:2][UTF-8 bytes] |
| 92 | + * </pre> |
| 93 | + * |
92 | 94 | * <h3>BDD Table</h3> |
93 | 95 | * <p>Array of BDD nodes for efficient condition evaluation. Each node is encoded as 12 bytes: |
94 | 96 | * <pre> |
95 | 97 | * [varIdx:4][highRef:4][lowRef:4] |
96 | 98 | * </pre> |
| 99 | + * Where: |
| 100 | + * <ul> |
| 101 | + * <li>varIdx: Index of the condition to test (0-based)</li> |
| 102 | + * <li>highRef: Reference to follow if condition is true</li> |
| 103 | + * <li>lowRef: Reference to follow if condition is false</li> |
| 104 | + * </ul> |
| 105 | + * |
| 106 | + * <p>Reference encoding follows the BDD conventions: |
| 107 | + * <ul> |
| 108 | + * <li>1: TRUE terminal</li> |
| 109 | + * <li>-1: FALSE terminal</li> |
| 110 | + * <li>2, 3, ...: Node references (node at index ref-1)</li> |
| 111 | + * <li>-2, -3, ...: Complement node references (logical NOT)</li> |
| 112 | + * <li>100_000_000+: Result terminals (100_000_000 + resultIndex)</li> |
| 113 | + * </ul> |
97 | 114 | * |
98 | 115 | * <h3>Bytecode Section</h3> |
99 | 116 | * <p>Contains the compiled bytecode instructions for all conditions and results. |
100 | | - * The condition/result tables point to offsets within this section. Instructions |
101 | | - * use a stack-based virtual machine with opcodes defined in {@link Opcodes}. |
| 117 | + * The condition/result tables contain absolute offsets from the start of the file that point into this section. |
| 118 | + * Instructions use a stack-based virtual machine with opcodes defined in {@link Opcodes}. This section may include |
| 119 | + * control flow instructions like JT_OR_POP for short-circuit evaluation. |
102 | 120 | * |
103 | 121 | * <h3>Constant Pool</h3> |
104 | 122 | * <p>Contains all constants referenced by the bytecode. Each constant is prefixed |
|
115 | 133 | * 5 MAP [count:2]([keyLen:2][key:UTF-8][value:?])... |
116 | 134 | * </pre> |
117 | 135 | * |
118 | | - * <p>Lists and maps can contain nested values of any supported type. |
| 136 | + * <p>Lists and maps can contain nested values of any supported type, up to a maximum nesting depth of 100 levels. |
119 | 137 | * |
120 | 138 | * <h2>Usage</h2> |
121 | 139 | * |
@@ -171,6 +189,10 @@ public final class Bytecode { |
171 | 189 | int[] bddNodes, |
172 | 190 | int bddRootRef |
173 | 191 | ) { |
| 192 | + if (bddNodes.length % 3 != 0) { |
| 193 | + throw new IllegalArgumentException("BDD nodes length must be multiple of 3, got: " + bddNodes.length); |
| 194 | + } |
| 195 | + |
174 | 196 | this.bytecode = Objects.requireNonNull(bytecode); |
175 | 197 | this.conditionOffsets = Objects.requireNonNull(conditionOffsets); |
176 | 198 | this.resultOffsets = Objects.requireNonNull(resultOffsets); |
|
0 commit comments