1 package io.jawk.intermediate;
2
3 /*-
4 * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
5 * Jawk
6 * ჻჻჻჻჻჻
7 * Copyright (C) 2006 - 2026 MetricsHub
8 * ჻჻჻჻჻჻
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation, either version 3 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Lesser Public License for more details.
18 *
19 * You should have received a copy of the GNU General Lesser Public
20 * License along with this program. If not, see
21 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22 * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
23 *
24 * <p>
25 * Each enum constant describes one tuple opcode understood by the AVM.
26 * </p>
27 */
28 public enum Opcode {
29 /**
30 * Pops an item off the operand stack.
31 * <p>
32 * Stack before: x ...<br/>
33 * Stack after: ...
34 */
35 POP,
36 /**
37 * Pushes a long constant onto the operand stack.
38 * <p>
39 * Argument: the long value<br/>
40 * Stack before: ...<br/>
41 * Stack after: x ...
42 */
43 PUSH_LONG,
44 /**
45 * Pushes a double constant onto the operand stack.
46 * <p>
47 * Argument: the double value<br/>
48 * Stack before: ...<br/>
49 * Stack after: x ...
50 */
51 PUSH_DOUBLE,
52 /**
53 * Pushes a string constant onto the operand stack.
54 * <p>
55 * Argument: the string value<br/>
56 * Stack before: ...<br/>
57 * Stack after: x ...
58 */
59 PUSH_STRING,
60 /**
61 * Pops and evaluates the top-of-stack; if
62 * false, it jumps to a specified address.
63 * <p>
64 * Argument: address
65 * <p>
66 * Stack before: x ...<br/>
67 * Stack after: ...
68 */
69 IFFALSE,
70 /**
71 * Converts the top-of-stack to a number.
72 * <p>
73 * Stack before: x ...<br/>
74 * Stack after: x (as a number)
75 */
76 TO_NUMBER,
77 /**
78 * Pops and evaluates the top-of-stack; if
79 * true, it jumps to a specified address.
80 * <p>
81 * Argument: address
82 * <p>
83 * Stack before: x ...<br/>
84 * Stack after: ...
85 */
86 IFTRUE,
87 /**
88 * Jumps to a specified address. The operand stack contents
89 * are unaffected.
90 */
91 GOTO,
92 /**
93 * A no-operation. The operand stack contents are
94 * unaffected.
95 */
96 NOP,
97 /**
98 * Prints N number of items that are on the operand stack.
99 * The number of items are passed in as a tuple argument.
100 * <p>
101 * Argument: # of items (N)
102 * <p>
103 * Stack before: x1 x2 x3 .. xN ...<br/>
104 * Stack after: ...
105 */
106 PRINT,
107 /**
108 * Prints N number of items that are on the operand stack to
109 * a specified file. The file is passed in on the stack.
110 * The number of items are passed in as a tuple argument,
111 * as well as whether to overwrite the file or not (append mode).
112 * <p>
113 * Argument 1: # of items (N)<br/>
114 * Argument 2: true = append, false = overwrite
115 * <p>
116 * Stack before: x1 x2 x3 .. xN filename ...<br/>
117 * Stack after: ...
118 */
119 PRINT_TO_FILE,
120 /**
121 * Prints N number of items that are on the operand stack to
122 * a process executing a specified command (via a pipe).
123 * The command string is passed in on the stack.
124 * The number of items are passed in as a tuple argument.
125 * <p>
126 * Argument: # of items (N)
127 * <p>
128 * Stack before: x1 x2 x3 .. xN command-string ...<br/>
129 * Stack after: ...
130 */
131 PRINT_TO_PIPE,
132 /**
133 * Performs a formatted print of N items that are on the operand stack.
134 * The number of items are passed in as a tuple argument.
135 * <p>
136 * Argument: # of items (N)
137 * <p>
138 * Stack before: x1 x2 x3 .. xN ...<br/>
139 * Stack after: ...
140 */
141 PRINTF,
142 /**
143 * Performs a formatted print of N items that are on the operand stack to
144 * a specified file. The file is passed in on the stack.
145 * The number of items are passed in as a tuple argument,
146 * as well as whether to overwrite the file or not (append mode).
147 * <p>
148 * Argument 1: # of items (N)<br/>
149 * Argument 2: true = append, false = overwrite
150 * <p>
151 * Stack before: x1 x2 x3 .. xN filename ...<br/>
152 * Stack after: ...
153 */
154 PRINTF_TO_FILE,
155 /**
156 * Performs a formatted print of N items that are on the operand stack to
157 * a process executing a specified command (via a pipe).
158 * The command string is passed in on the stack.
159 * The number of items are passed in as a tuple argument.
160 * <p>
161 * Argument: # of items (N)
162 * <p>
163 * Stack before: x1 x2 x3 .. xN command-string ...<br/>
164 * Stack after: ...
165 */
166 PRINTF_TO_PIPE,
167 /** Constant <code>SPRINTF=270</code> */
168 SPRINTF,
169 /**
170 * Depending on the argument, pop and evaluate the string length of the top-of-stack
171 * or evaluate the string length of $0; in either case, push the result onto
172 * the stack.
173 * <p>
174 * The input field length evaluation mode is provided to support backward
175 * compatibility with the deprecated usage of length (i.e., no arguments).
176 * <p>
177 * Argument: 0 to use $0, use top-of-stack otherwise
178 * <p>
179 * If argument is 0:
180 * <blockquote>
181 * Stack before: ...<br/>
182 * Stack after: length-of-$0 ...
183 * </blockquote>
184 * else
185 * <blockquote>
186 * Stack before: x ...<br/>
187 * Stack after: length-of-x ...
188 * </blockquote>
189 */
190 LENGTH,
191 /**
192 * Pop and concatenate two strings from the top-of-stack; push the result onto
193 * the stack.
194 * <p>
195 * Stack before: x y ...<br/>
196 * Stack after: x-concatenated-with-y ...
197 */
198 CONCAT,
199 /**
200 * Pops and concatenates N values from the top-of-stack after AWK string
201 * conversion; pushes the result onto the stack. The number of items is passed
202 * in as a tuple argument.
203 * <p>
204 * Argument: # of items (N)
205 * <p>
206 * Stack before: x1 x2 x3 .. xN ...<br/>
207 * Stack after: x1-concatenated-through-xN ...
208 */
209 MULTI_CONCAT,
210 /**
211 * Assigns the top-of-stack to a variable and pushes the assigned value back
212 * onto the stack.
213 * <p>
214 * Argument 1: offset of the particular variable into the variable manager<br/>
215 * Argument 2: whether the variable is global or local
216 * <p>
217 * Stack before: x ...<br/>
218 * Stack after: x ...
219 */
220 ASSIGN,
221 /**
222 * Assigns the top-of-stack to a variable without pushing the assigned value
223 * back onto the stack.
224 * <p>
225 * Argument 1: offset of the particular variable into the variable manager<br/>
226 * Argument 2: whether the variable is global or local
227 * <p>
228 * Stack before: x ...<br/>
229 * Stack after: ...
230 */
231 ASSIGN_NOPUSH,
232 /**
233 * Assigns an item to an array element. The item remains on the stack.
234 * <p>
235 * Argument 1: offset of the particular associative array into the variable manager<br/>
236 * Argument 2: whether the associative array is global or local
237 * <p>
238 * Stack before: index-into-array item ...<br/>
239 * Stack after: item ...
240 */
241 ASSIGN_ARRAY,
242 /**
243 * Assigns an item to an element of the associative array currently on the stack.
244 * The item remains on the stack.
245 * <p>
246 * Stack before: array-index associative-array item ...<br/>
247 * Stack after: item ...
248 */
249 ASSIGN_MAP_ELEMENT,
250 /**
251 * Assigns the top-of-stack to $0. The contents of the stack are unaffected.
252 * Upon assignment, individual field variables are recalculated.
253 * <p>
254 * Stack before: x ...<br/>
255 * Stack after: x ...
256 */
257 ASSIGN_AS_INPUT,
258 /**
259 * Assigns an item as a particular input field; the field number can be 0.
260 * Upon assignment, associating input fields are affected. For example, if
261 * the following assignment were made:
262 * <blockquote>
263 *
264 * <pre>
265 * $3 = "hi"
266 * </pre>
267 *
268 * </blockquote>
269 * $0 would be recalculated. Likewise, if the following assignment were made:
270 * <blockquote>
271 *
272 * <pre>
273 * $0 = "hello there"
274 * </pre>
275 *
276 * </blockquote>
277 * $1, $2, ... would be recalculated.
278 * <p>
279 * Stack before: field-num x ...<br/>
280 * Stack after: x ...
281 */
282 ASSIGN_AS_INPUT_FIELD,
283 /**
284 * Obtains an item from the variable manager and push it onto the stack.
285 * <p>
286 * Argument 1: offset of the particular variable into the variable manager<br/>
287 * Argument 2: whether the variable is global or local
288 * <p>
289 * Stack before: ...<br/>
290 * Stack after: x ...
291 */
292 DEREFERENCE,
293 /**
294 * Obtains an item from the variable manager without assigning a blank value
295 * when the variable is still untyped.
296 * <p>
297 * This differs from {@link #DEREFERENCE} only for introspection paths that
298 * must observe an unassigned scalar-or-array state without changing it.
299 * </p>
300 * <p>
301 * Argument 1: offset of the particular variable into the variable manager<br/>
302 * Argument 2: whether the variable is global or local
303 * <p>
304 * Stack before: ...<br/>
305 * Stack after: x ...
306 */
307 PEEK_DEREFERENCE,
308 /**
309 * Increase the contents of the variable by an adjustment value;
310 * assigns the result to the variable and pushes the result onto the stack.
311 * <p>
312 * Argument 1: offset of the particular variable into the variable manager<br/>
313 * Argument 2: whether the variable is global or local
314 * <p>
315 * Stack before: n ...<br/>
316 * Stack after: x+n ...
317 */
318 PLUS_EQ,
319 /**
320 * Decreases the contents of the variable by an adjustment value;
321 * assigns the result to the variable and pushes the result onto the stack.
322 * <p>
323 * Argument 1: offset of the particular variable into the variable manager<br/>
324 * Argument 2: whether the variable is global or local
325 * <p>
326 * Stack before: n ...<br/>
327 * Stack after: x-n ...
328 */
329 MINUS_EQ,
330 /**
331 * Multiplies the contents of the variable by an adjustment value;
332 * assigns the result to the variable and pushes the result onto the stack.
333 * <p>
334 * Argument 1: offset of the particular variable into the variable manager<br/>
335 * Argument 2: whether the variable is global or local
336 * <p>
337 * Stack before: n ...<br/>
338 * Stack after: x*n ...
339 */
340 MULT_EQ,
341 /**
342 * Divides the contents of the variable by an adjustment value;
343 * assigns the result to the variable and pushes the result onto the stack.
344 * <p>
345 * Argument 1: offset of the particular variable into the variable manager<br/>
346 * Argument 2: whether the variable is global or local
347 * <p>
348 * Stack before: n ...<br/>
349 * Stack after: x/n ...
350 */
351 DIV_EQ,
352 /**
353 * Takes the modules of the contents of the variable by an adjustment value;
354 * assigns the result to the variable and pushes the result onto the stack.
355 * <p>
356 * Argument 1: offset of the particular variable into the variable manager<br/>
357 * Argument 2: whether the variable is global or local
358 * <p>
359 * Stack before: n ...<br/>
360 * Stack after: x%n ...
361 */
362 MOD_EQ,
363 /**
364 * Raises the contents of the variable to the power of the adjustment value;
365 * assigns the result to the variable and pushes the result onto the stack.
366 * <p>
367 * Argument 1: offset of the particular variable into the variable manager<br/>
368 * Argument 2: whether the variable is global or local
369 * <p>
370 * Stack before: n ...<br/>
371 * Stack after: x^n ...
372 */
373 POW_EQ,
374 /**
375 * Increase the contents of an indexed array by an adjustment value;
376 * assigns the result to the array and pushes the result onto the stack.
377 * <p>
378 * Argument 1: offset of the associative array into the variable manager<br/>
379 * Argument 2: whether the associative array is global or local
380 * <p>
381 * Stack before: array-idx n ...<br/>
382 * Stack after: x+n ...
383 */
384 PLUS_EQ_ARRAY,
385 /**
386 * Decreases the contents of an indexed array by an adjustment value;
387 * assigns the result to the array and pushes the result onto the stack.
388 * <p>
389 * Argument 1: offset of the associative array into the variable manager<br/>
390 * Argument 2: whether the associative array is global or local
391 * <p>
392 * Stack before: array-idx n ...<br/>
393 * Stack after: x-n ...
394 */
395 MINUS_EQ_ARRAY,
396 /**
397 * Multiplies the contents of an indexed array by an adjustment value;
398 * assigns the result to the array and pushes the result onto the stack.
399 * <p>
400 * Argument 1: offset of the associative array into the variable manager<br/>
401 * Argument 2: whether the associative array is global or local
402 * <p>
403 * Stack before: array-idx n ...<br/>
404 * Stack after: x*n ...
405 */
406 MULT_EQ_ARRAY,
407 /**
408 * Divides the contents of an indexed array by an adjustment value;
409 * assigns the result to the array and pushes the result onto the stack.
410 * <p>
411 * Argument 1: offset of the associative array into the variable manager<br/>
412 * Argument 2: whether the associative array is global or local
413 * <p>
414 * Stack before: array-idx n ...<br/>
415 * Stack after: x/n ...
416 */
417 DIV_EQ_ARRAY,
418 /**
419 * Takes the modulus of the contents of an indexed array by an adjustment value;
420 * assigns the result to the array and pushes the result onto the stack.
421 * <p>
422 * Argument 1: offset of the associative array into the variable manager<br/>
423 * Argument 2: whether the associative array is global or local
424 * <p>
425 * Stack before: array-idx n ...<br/>
426 * Stack after: x%n ...
427 */
428 MOD_EQ_ARRAY,
429 /**
430 * Raises the contents of an indexed array to the power of an adjustment value;
431 * assigns the result to the array and pushes the result onto the stack.
432 * <p>
433 * Argument 1: offset of the associative array into the variable manager<br/>
434 * Argument 2: whether the associative array is global or local
435 * <p>
436 * Stack before: array-idx n ...<br/>
437 * Stack after: x^n ...
438 */
439 POW_EQ_ARRAY,
440 /**
441 * Increase the contents of a stack-provided associative-array element by an
442 * adjustment value; assigns the result to the array and pushes the result onto
443 * the stack.
444 * <p>
445 * Stack before: array-idx associative-array n ...<br/>
446 * Stack after: x+n ...
447 */
448 PLUS_EQ_MAP_ELEMENT,
449 /**
450 * Decreases the contents of a stack-provided associative-array element by an
451 * adjustment value; assigns the result to the array and pushes the result onto
452 * the stack.
453 * <p>
454 * Stack before: array-idx associative-array n ...<br/>
455 * Stack after: x-n ...
456 */
457 MINUS_EQ_MAP_ELEMENT,
458 /**
459 * Multiplies the contents of a stack-provided associative-array element by an
460 * adjustment value; assigns the result to the array and pushes the result onto
461 * the stack.
462 * <p>
463 * Stack before: array-idx associative-array n ...<br/>
464 * Stack after: x*n ...
465 */
466 MULT_EQ_MAP_ELEMENT,
467 /**
468 * Divides the contents of a stack-provided associative-array element by an
469 * adjustment value; assigns the result to the array and pushes the result onto
470 * the stack.
471 * <p>
472 * Stack before: array-idx associative-array n ...<br/>
473 * Stack after: x/n ...
474 */
475 DIV_EQ_MAP_ELEMENT,
476 /**
477 * Takes the modulus of the contents of a stack-provided associative-array
478 * element by an adjustment value; assigns the result to the array and pushes the
479 * result onto the stack.
480 * <p>
481 * Stack before: array-idx associative-array n ...<br/>
482 * Stack after: x%n ...
483 */
484 MOD_EQ_MAP_ELEMENT,
485 /**
486 * Raises the contents of a stack-provided associative-array element to the
487 * power of an adjustment value; assigns the result to the array and pushes the
488 * result onto the stack.
489 * <p>
490 * Stack before: array-idx associative-array n ...<br/>
491 * Stack after: x^n ...
492 */
493 POW_EQ_MAP_ELEMENT,
494 /**
495 * Increases the contents of an input field by an adjustment value;
496 * assigns the result to the input field and pushes the result onto the stack.
497 * <p>
498 * Stack before: input-field_number n ...<br/>
499 * Stack after: x+n ...
500 */
501 PLUS_EQ_INPUT_FIELD,
502 /**
503 * Decreases the contents of an input field by an adjustment value;
504 * assigns the result to the input field and pushes the result onto the stack.
505 * <p>
506 * Stack before: input-field_number n ...<br/>
507 * Stack after: x-n ...
508 */
509 MINUS_EQ_INPUT_FIELD,
510 /**
511 * Multiplies the contents of an input field by an adjustment value;
512 * assigns the result to the input field and pushes the result onto the stack.
513 * <p>
514 * Stack before: input-field_number n ...<br/>
515 * Stack after: x*n ...
516 */
517 MULT_EQ_INPUT_FIELD,
518 /**
519 * Divides the contents of an input field by an adjustment value;
520 * assigns the result to the input field and pushes the result onto the stack.
521 * <p>
522 * Stack before: input-field_number n ...<br/>
523 * Stack after: x/n ...
524 */
525 DIV_EQ_INPUT_FIELD,
526 /**
527 * Takes the modulus of the contents of an input field by an adjustment value;
528 * assigns the result to the input field and pushes the result onto the stack.
529 * <p>
530 * Stack before: input-field_number n ...<br/>
531 * Stack after: x%n ...
532 */
533 MOD_EQ_INPUT_FIELD,
534 /**
535 * Raises the contents of an input field to the power of an adjustment value;
536 * assigns the result to the input field and pushes the result onto the stack.
537 * <p>
538 * Stack before: input-field_number n ...<br/>
539 * Stack after: x^n ...
540 */
541 POW_EQ_INPUT_FIELD,
542
543 /**
544 * Seeds the random number generator. If there are no arguments, the current
545 * time (as a long value) is used as the seed. Otherwise, the top-of-stack is
546 * popped and used as the seed value.
547 * <p>
548 * Argument: # of arguments
549 * <p>
550 * If # of arguments is 0:
551 * <blockquote>
552 * Stack before: ...<br/>
553 * Stack after: old-seed ...
554 * </blockquote>
555 * else
556 * <blockquote>
557 * Stack before: x ...<br/>
558 * Stack after: old-seed ...
559 * </blockquote>
560 */
561 SRAND,
562 /**
563 * Obtains the next random number from the random number generator
564 * and push it onto the stack.
565 * <p>
566 * Stack before: ...<br/>
567 * Stack after: random-number ...
568 */
569 RAND,
570 /**
571 * Built-in function that pops the top-of-stack, removes its fractional part,
572 * if any, and places the result onto the stack.
573 * <p>
574 * Stack before: x ...<br/>
575 * Stack after: (int)x ...
576 */
577 INTFUNC,
578 /**
579 * Built-in function that pops the top-of-stack, takes its square root,
580 * and places the result onto the stack.
581 * <p>
582 * Stack before: x ...<br/>
583 * Stack after: sqrt(x) ...
584 */
585 SQRT,
586 /**
587 * Built-in function that pops the top-of-stack, calls the java.lang.Math.log method
588 * with the top-of-stack as the argument, and places the result onto the stack.
589 * <p>
590 * Stack before: x ...<br/>
591 * Stack after: log(x) ...
592 */
593 LOG,
594 /**
595 * Built-in function that pops the top-of-stack, calls the java.lang.Math.exp method
596 * with the top-of-stack as the argument, and places the result onto the stack.
597 * <p>
598 * Stack before: x ...<br/>
599 * Stack after: exp(x) ...
600 */
601 EXP,
602 /**
603 * Built-in function that pops the top-of-stack, calls the java.lang.Math.sin method
604 * with the top-of-stack as the argument, and places the result onto the stack.
605 * <p>
606 * Stack before: x ...<br/>
607 * Stack after: sin(x) ...
608 */
609 SIN,
610 /**
611 * Built-in function that pops the top-of-stack, calls the java.lang.Math.cos method
612 * with the top-of-stack as the argument, and places the result onto the stack.
613 * <p>
614 * Stack before: x ...<br/>
615 * Stack after: cos(x) ...
616 */
617 COS,
618 /**
619 * Built-in function that pops the first two items off the stack,
620 * calls the java.lang.Math.atan2 method
621 * with these as arguments, and places the result onto the stack.
622 * <p>
623 * Stack before: x1 x2 ...<br/>
624 * Stack after: atan2(x1,x2) ...
625 */
626 ATAN2,
627 /**
628 * Built-in function that searches a string as input to a regular expression,
629 * the location of the match is pushed onto the stack.
630 * The RSTART and RLENGTH variables are set as a side effect.
631 * If a match is found, RSTART and function return value are set
632 * to the location of the match and RLENGTH is set to the length
633 * of the substring matched against the regular expression.
634 * If no match is found, RSTART (and return value) is set to
635 * 0 and RLENGTH is set to -1.
636 * <p>
637 * Stack before: string regexp ...<br/>
638 * Stack after: RSTART ...
639 */
640 MATCH,
641 /**
642 * Built-in function that locates a substring within a source string
643 * and pushes the location onto the stack. If the substring is
644 * not found, 0 is pushed onto the stack.
645 * <p>
646 * Stack before: string substring ...<br/>
647 * Stack after: location-index ...
648 */
649 INDEX,
650 /**
651 * Built-in function that substitutes an occurrence (or all occurrences)
652 * of a string in $0 and replaces it with another.
653 * <p>
654 * Argument: true if global sub, false otherwise.
655 * <p>
656 * Stack before: regexp replacement-string ...<br/>
657 * Stack after: ...
658 */
659 SUB_FOR_DOLLAR_0,
660 /**
661 * Built-in function that substitutes an occurrence (or all occurrences)
662 * of a string in a field reference and replaces it with another.
663 * <p>
664 * Argument: true if global sub, false otherwise.
665 * <p>
666 * Stack before: field-num regexp replacement-string ...<br/>
667 * Stack after: ...
668 */
669 SUB_FOR_DOLLAR_REFERENCE,
670 /**
671 * Built-in function that substitutes an occurrence (or all occurrences)
672 * of a string in a particular variable and replaces it with another.
673 * <p>
674 * Argument 1: variable offset in variable manager<br/>
675 * Argument 2: is global variable<br/>
676 * Argument 3: is global sub
677 * <p>
678 * Stack before: regexp replacement-string orig-string ...<br/>
679 * Stack after: ...
680 */
681 SUB_FOR_VARIABLE,
682 /**
683 * Built-in function that substitutes an occurrence (or all occurrences)
684 * of a string in a particular array cell and replaces it with another.
685 * <p>
686 * Argument 1: array map offset in variable manager<br/>
687 * Argument 2: is global array map<br/>
688 * Argument 3: is global sub
689 * <p>
690 * Stack before: array-index regexp replacement-string orig-string ...<br/>
691 * Stack after: ...
692 */
693 SUB_FOR_ARRAY_REFERENCE,
694 /**
695 * Built-in function that substitutes an occurrence (or all occurrences) of a
696 * string in a particular stack-provided array cell and replaces it with another.
697 * <p>
698 * Argument 1: is global sub
699 * <p>
700 * Stack before: array-index associative-array orig-string replacement-string regexp ...<br/>
701 * Stack after: ...
702 */
703 SUB_FOR_MAP_REFERENCE,
704 /**
705 * Built-in function to split a string by a regexp and put the
706 * components into an array.
707 * <p>
708 * Argument: # of arguments (parameters on stack)
709 * <p>
710 * If # of arguments is 2:
711 * <blockquote>
712 * Stack before: string array ...<br/>
713 * Stack after: n ...
714 * </blockquote>
715 * else
716 * <blockquote>
717 * Stack before: string array regexp ...<br/>
718 * Stack after: n ...
719 * </blockquote>
720 */
721 SPLIT,
722 /**
723 * Built-in function that pushes a substring of the top-of-stack
724 * onto the stack.
725 * The tuple argument indicates whether to limit the substring
726 * to a particular end position, or to take the substring
727 * up to the end-of-string.
728 * <p>
729 * Argument: # of arguments
730 * <p>
731 * If # of arguments is 2:
732 * <blockquote>
733 * Stack before: string start-pos ...<br/>
734 * Stack after: substring ...
735 * </blockquote>
736 * else
737 * <blockquote>
738 * Stack before: string start-pos end-pos ...<br/>
739 * Stack after: substring ...
740 * </blockquote>
741 */
742 SUBSTR,
743 /**
744 * Built-in function that converts all the letters in the top-of-stack
745 * to lower case and pushes the result onto the stack.
746 * <p>
747 * Stack before: STRING-ARGUMENT ...<br/>
748 * Stack after: string-argument ...
749 */
750 TOLOWER,
751 /**
752 * Built-in function that converts all the letters in the top-of-stack
753 * to upper case and pushes the result onto the stack.
754 * <p>
755 * Stack before: string-argument ...<br/>
756 * Stack after: STRING-ARGUMENT ...
757 */
758 TOUPPER,
759 /**
760 * Built-in function that executes the top-of-stack as a system command
761 * and pushes the return code onto the stack.
762 * <p>
763 * Stack before: cmd ...<br/>
764 * Stack after: return-code ...
765 */
766 SYSTEM,
767
768 /**
769 * Swaps the top two elements of the stack.
770 * <p>
771 * Stack before: x1 x2 ...<br/>
772 * Stack after: x2 x1 ...
773 */
774 SWAP,
775
776 /**
777 * Numerically adds the top two elements of the stack with the result
778 * pushed onto the stack.
779 * <p>
780 * Stack before: x1 x2 ...<br/>
781 * Stack after: x1+x2 ...
782 */
783 ADD,
784 /**
785 * Numerically subtracts the top two elements of the stack with the result
786 * pushed onto the stack.
787 * <p>
788 * Stack before: x1 x2 ...<br/>
789 * Stack after: x1-x2 ...
790 */
791 SUBTRACT,
792 /**
793 * Numerically multiplies the top two elements of the stack with the result
794 * pushed onto the stack.
795 * <p>
796 * Stack before: x1 x2 ...<br/>
797 * Stack after: x1*x2 ...
798 */
799 MULTIPLY,
800 /**
801 * Numerically divides the top two elements of the stack with the result
802 * pushed onto the stack.
803 * <p>
804 * Stack before: x1 x2 ...<br/>
805 * Stack after: x1/x2 ...
806 */
807 DIVIDE,
808 /**
809 * Numerically takes the modulus of the top two elements of the stack with the result
810 * pushed onto the stack.
811 * <p>
812 * Stack before: x1 x2 ...<br/>
813 * Stack after: x1%x2 ...
814 */
815 MOD,
816 /**
817 * Numerically raises the top element to the power of the next element with the result
818 * pushed onto the stack.
819 * <p>
820 * Stack before: x1 x2 ...<br/>
821 * Stack after: x1^x2 ...
822 */
823 POW,
824
825 /**
826 * Increases the variable reference by one; pushes the result
827 * onto the stack.
828 * <p>
829 * Argument 1: offset of the particular variable into the variable manager<br/>
830 * Argument 2: whether the variable is global or local
831 * <p>
832 * Stack before: ...<br/>
833 * Stack after: x+1 ...
834 */
835 INC,
836 /**
837 * Decreases the variable reference by one; pushes the result
838 * onto the stack.
839 * <p>
840 * Argument 1: offset of the particular variable into the variable manager<br/>
841 * Argument 2: whether the variable is global or local
842 * <p>
843 * Stack before: ...<br/>
844 * Stack after: x-1 ...
845 */
846 DEC,
847 /**
848 * Increases the array element reference by one; pushes the result
849 * onto the stack.
850 * <p>
851 * Argument 1: offset of the associative array into the variable manager<br/>
852 * Argument 2: whether the associative array is global or local
853 * <p>
854 * Stack before: array-idx ...<br/>
855 * Stack after: x+1 ...
856 */
857 INC_ARRAY_REF,
858 /**
859 * Decreases the array element reference by one; pushes the result
860 * onto the stack.
861 * <p>
862 * Argument 1: offset of the associative array into the variable manager<br/>
863 * Argument 2: whether the associative array is global or local
864 * <p>
865 * Stack before: array-idx ...<br/>
866 * Stack after: x-1 ...
867 */
868 DEC_ARRAY_REF,
869 /**
870 * Increases the stack-provided array element reference by one.
871 * <p>
872 * Stack before: array-idx associative-array ...<br/>
873 * Stack after: x+1 ...
874 */
875 INC_MAP_REF,
876 /**
877 * Decreases the stack-provided array element reference by one.
878 * <p>
879 * Stack before: array-idx associative-array ...<br/>
880 * Stack after: x-1 ...
881 */
882 DEC_MAP_REF,
883 /**
884 * Increases the input field variable by one; pushes the result
885 * onto the stack.
886 * <p>
887 * Stack before: field-idx ...<br/>
888 * Stack after: x+1
889 */
890 INC_DOLLAR_REF,
891 /**
892 * Decreases the input field variable by one; pushes the result
893 * onto the stack.
894 * <p>
895 * Stack before: field-idx ...<br/>
896 * Stack after: x-1
897 */
898 DEC_DOLLAR_REF,
899
900 /**
901 * Duplicates the top-of-stack on the stack.
902 * <p>
903 * Stack before: x ...<br/>
904 * Stack after: x x ...
905 */
906 DUP,
907 /**
908 * Evaluates the logical NOT of the top stack element;
909 * pushes the result onto the stack.
910 * <p>
911 * Stack before: x ...<br/>
912 * Stack after: !x ...
913 */
914 NOT,
915 /**
916 * Evaluates the numerical NEGATION of the top stack element;
917 * pushes the result onto the stack.
918 * <p>
919 * Stack before: x ...<br/>
920 * Stack after: -x ...
921 */
922 NEGATE,
923
924 /**
925 * Compares the top two stack elements; pushes 1 onto the stack if equal, 0 if not equal.
926 * <p>
927 * Stack before: x1 x2 ...<br/>
928 * Stack after: x1==x2
929 */
930 CMP_EQ,
931 /**
932 * Compares the top two stack elements; pushes 1 onto the stack if x1 < x2, 0 if not equal.
933 * <p>
934 * Stack before: x1 x2 ...<br/>
935 * Stack after: x1<x2
936 */
937 CMP_LT,
938 /**
939 * Compares the top two stack elements; pushes 1 onto the stack if x1 > x2, 0 if not equal.
940 * <p>
941 * Stack before: x1 x2 ...<br/>
942 * Stack after: x1>x2
943 */
944 CMP_GT,
945 /**
946 * Applies a regular expression to the top stack element; pushes 1 if it matches,
947 * 0 if it does not match.
948 * <p>
949 * Stack before: x1 x2 ...<br/>
950 * Stack after: (x1 ~ /x2/) ...
951 */
952 MATCHES,
953
954 /** Constant <code>DEREF_ARRAY=336</code> */
955 DEREF_ARRAY,
956
957 // for (x in y) {keyset} support
958 /**
959 * Retrieves and pushes a set of keys from an associative array onto the stack.
960 * The set is stored in a {@link java.util.Deque} for iteration.
961 * <p>
962 * Stack before: associative-array ...<br/>
963 * Stack after: key-list-set ...
964 */
965 KEYLIST,
966 /**
967 * Tests whether the key list (deque) is empty; jumps to the argument
968 * address if empty, steps to the next instruction if not.
969 * <p>
970 * Argument: jump-address-if-empty
971 * <p>
972 * Stack before: key-list ...<br/>
973 * Stack after: ...
974 */
975 IS_EMPTY_KEYLIST,
976 /**
977 * Removes an item from the key list (deque) and pushes it onto the operand stack.
978 * <p>
979 * Stack before: key-list ...<br/>
980 * Stack after: 1st-item ...
981 */
982 GET_FIRST_AND_REMOVE_FROM_KEYLIST,
983
984 // assertions
985 /**
986 * Checks whether the top-of-stack is of a particular class type;
987 * if not, an AwkRuntimeException is thrown.
988 * The stack remains unchanged upon a successful check.
989 * <p>
990 * Argument: class-type (i.e., java.util.Deque.class)
991 * <p>
992 * Stack before: obj ...<br/>
993 * Stack after: obj ...
994 */
995 CHECK_CLASS,
996
997 // input
998 // * Obtain an input string from stdin; push the result onto the stack.
999 /**
1000 * Push an input field onto the stack.
1001 * <p>
1002 * Stack before: field-id ...<br/>
1003 * Stack after: x ...
1004 */
1005 GET_INPUT_FIELD,
1006 /**
1007 * Pushes an input field onto the stack using an embedded field index.
1008 * <p>
1009 * Argument: field-id
1010 * <p>
1011 * Stack before: ...<br/>
1012 * Stack after: x ...
1013 */
1014 GET_INPUT_FIELD_CONST,
1015 /**
1016 * Consume next line of input; assigning $0 and recalculating $1, $2, etc.
1017 * The input can come from the following sources:
1018 * <ul>
1019 * <li>stdin
1020 * <li>filename arguments
1021 * </ul>
1022 * The operand stack is unaffected.
1023 */
1024 CONSUME_INPUT,
1025 /**
1026 * Obtains input from stdin/filename-args, stores it into
1027 * {@code $0}, {@code $1..$NF}, and pushes only the status code
1028 * onto the stack.
1029 * The input is partitioned into records based on the RS variable
1030 * assignment as a regular expression.
1031 * <p>
1032 * If there is input available, a return code of 1 is pushed.
1033 * If EOF is reached, a 0 return code is pushed.
1034 * Upon an IO error, the exception is propagated.
1035 * <p>
1036 * Stack before: ...<br/>
1037 * Stack after: return-code ...
1038 */
1039 GETLINE_INPUT,
1040 /**
1041 * Obtains input from stdin/filename-args and pushes
1042 * the input line and status code onto the stack without
1043 * updating {@code $0}, {@code $1..$NF}.
1044 * The input is partitioned into records based on the RS variable
1045 * assignment as a regular expression.
1046 * <p>
1047 * If there is input available, the input string and a return code
1048 * of 1 is pushed. If EOF is reached, an empty string ("")
1049 * is pushed along with a 0 return code. Upon an IO error,
1050 * the exception is propagated.
1051 * <p>
1052 * Stack before: ...<br/>
1053 * Stack after: input-string return-code ...
1054 */
1055 GETLINE_INPUT_TO_TARGET,
1056 /**
1057 * Obtains input from a file and pushes
1058 * input line and status code onto the stack.
1059 * The input is partitioned into records based on the RS variable
1060 * assignment as a regular expression.
1061 * <p>
1062 * Upon initial execution, the file is opened and the handle
1063 * is maintained until it is explicitly closed, or until
1064 * the VM exits. Subsequent calls will obtain subsequent
1065 * lines (records) of input until no more records are available.
1066 * <p>
1067 * If there is input available, the input string and a return code
1068 * of 1 is pushed. If EOF is reached, an empty string ("")
1069 * is pushed along with a 0 return code. Upon an IO error,
1070 * a blank string and a -1 is pushed onto the operand stack.
1071 * <p>
1072 * Stack before: filename ...<br/>
1073 * Stack after: input-string return-code ...
1074 */
1075 USE_AS_FILE_INPUT,
1076 /**
1077 * Obtains input from a command (process) and pushes
1078 * input line and status code onto the stack.
1079 * The input is partitioned into records based on the RS variable
1080 * assignment as a regular expression.
1081 * <p>
1082 * Upon initial execution, the a process is spawned to execute
1083 * the specified command and the process reference
1084 * is maintained until it is explicitly closed, or until
1085 * the VM exits. Subsequent calls will obtain subsequent
1086 * lines (records) of input until no more records are available.
1087 * <p>
1088 * If there is input available, the input string and a return code
1089 * of 1 is pushed. If EOF is reached, an empty string ("")
1090 * is pushed along with a 0 return code. Upon an IO error,
1091 * a blank string and a -1 is pushed onto the operand stack.
1092 * <p>
1093 * Stack before: command-line ...<br/>
1094 * Stack after: input-string return-code ...
1095 */
1096 USE_AS_COMMAND_INPUT,
1097
1098 // variable housekeeping
1099 /**
1100 * Assign the NF variable offset. This is important for the
1101 * AVM to set the variables as new input lines are processed.
1102 * <p>
1103 * The operand stack is unaffected.
1104 */
1105 NF_OFFSET,
1106 /**
1107 * Assign the NR variable offset. This is important for the
1108 * AVM to increase the record number as new input lines received.
1109 * <p>
1110 * The operand stack is unaffected.
1111 */
1112 NR_OFFSET,
1113 /**
1114 * Assign the FNR variable offset. This is important for the
1115 * AVM to increase the "file" record number as new input lines are received.
1116 * <p>
1117 * The operand stack is unaffected.
1118 */
1119 FNR_OFFSET,
1120 /**
1121 * Assign the FS variable offset. This is important for the
1122 * AVM to know how to split fields upon incoming records of input.
1123 * <p>
1124 * The operand stack is unaffected.
1125 */
1126 FS_OFFSET,
1127 /**
1128 * Assign the RS variable offset. This is important for the
1129 * AVM to know how to create records from the stream(s) of input.
1130 * <p>
1131 * The operand stack is unaffected.
1132 */
1133 RS_OFFSET,
1134 /**
1135 * Assign the OFS variable offset. This is important for the
1136 * AVM to use when outputting expressions via PRINT.
1137 * <p>
1138 * The operand stack is unaffected.
1139 */
1140 OFS_OFFSET,
1141 /**
1142 * Assign the RSTART variable offset. The AVM sets this variable while
1143 * executing the match() builtin function.
1144 * <p>
1145 * The operand stack is unaffected.
1146 */
1147 RSTART_OFFSET,
1148 /**
1149 * Assign the RLENGTH variable offset. The AVM sets this variable while
1150 * executing the match() builtin function.
1151 * <p>
1152 * The operand stack is unaffected.
1153 */
1154 RLENGTH_OFFSET,
1155 /**
1156 * Assign the FILENAME variable offset. The AVM sets this variable while
1157 * processing files from the command-line for input.
1158 * <p>
1159 * The operand stack is unaffected.
1160 */
1161 FILENAME_OFFSET,
1162 /**
1163 * Assign the SUBSEP variable offset. The AVM uses this variable while
1164 * building an index of a multi-dimensional array.
1165 * <p>
1166 * The operand stack is unaffected.
1167 */
1168 SUBSEP_OFFSET,
1169 /**
1170 * Assign the CONVFMT variable offset. The AVM uses this variable while
1171 * converting numbers to strings.
1172 * <p>
1173 * The operand stack is unaffected.
1174 */
1175 CONVFMT_OFFSET,
1176 /**
1177 * Assign the OFMT variable offset. The AVM uses this variable while
1178 * converting numbers to strings for printing.
1179 * <p>
1180 * The operand stack is unaffected.
1181 */
1182 OFMT_OFFSET,
1183 /**
1184 * Assign the ENVIRON variable offset. The AVM provides environment
1185 * variables through this array.
1186 * <p>
1187 * The operand stack is unaffected.
1188 */
1189 ENVIRON_OFFSET,
1190 /**
1191 * Assign the ARGC variable offset. The AVM provides the number of
1192 * arguments via this variable.
1193 * <p>
1194 * The operand stack is unaffected.
1195 */
1196 ARGC_OFFSET,
1197 /**
1198 * Assign the ARGV variable offset. The AVM provides command-line
1199 * arguments via this variable.
1200 * <p>
1201 * The operand stack is unaffected.
1202 */
1203 ARGV_OFFSET,
1204
1205 /**
1206 * Apply the RS variable by notifying the partitioning reader that
1207 * there is a new regular expression to use when partitioning input
1208 * records.
1209 * <p>
1210 * The stack remains unaffected.
1211 */
1212 APPLY_RS,
1213
1214 /**
1215 * Call a user function.
1216 * <p>
1217 * Stack before: x1, x2, ..., xn <br>
1218 * Stack after: f(x1, x2, ..., xn)
1219 */
1220 CALL_FUNCTION,
1221
1222 /**
1223 * Define a user function.
1224 * <p>
1225 * Stack remains unchanged
1226 */
1227 FUNCTION,
1228
1229 /**
1230 * Sets the return value of a user function.
1231 * <p>
1232 * Stack before: x <br>
1233 * Stack after: ...
1234 */
1235 SET_RETURN_RESULT,
1236
1237 /**
1238 * Get the return value of the user function that was called
1239 * <p>
1240 * Stack before: ... <br>
1241 * Stack after: x
1242 */
1243 RETURN_FROM_FUNCTION,
1244
1245 /**
1246 * Internal: sets the number of global variables
1247 */
1248 SET_NUM_GLOBALS,
1249
1250 /**
1251 * Close the specified file.
1252 * <p>
1253 * Stack before: file name <br>
1254 * Stack after: result of the close operation
1255 */
1256 CLOSE,
1257
1258 /**
1259 * Convert a list of array indices to a concatenated string with SUBSEP.
1260 * This is used for multidimensional arrays.
1261 * <p>
1262 * Stack before: i1, i2, ..., in <br>
1263 * Stack after: "i1SUBSEPi2SUBSEP...in"
1264 */
1265 APPLY_SUBSEP,
1266
1267 /**
1268 * Deletes an entry in an array.
1269 * <p>
1270 * Stack before: i <br>
1271 * Stack after: ...
1272 */
1273 DELETE_ARRAY_ELEMENT,
1274 /**
1275 * Deletes an entry in a stack-provided associative array.
1276 * <p>
1277 * Stack before: array-index associative-array <br/>
1278 * Stack after: ...
1279 */
1280 DELETE_MAP_ELEMENT,
1281
1282 /**
1283 * Internal.
1284 * <p>
1285 * Stack remains unchanged.
1286 */
1287 SET_WITHIN_END_BLOCKS,
1288
1289 /**
1290 * Terminates execution and returns specified exit code.
1291 * <p>
1292 * Stack before: integer <br>
1293 * Stack after: N/A
1294 */
1295 EXIT_WITH_CODE,
1296
1297 /**
1298 * Returns a regex pattern.
1299 * <p>
1300 * Stack before: ... <br>
1301 * Stack after: the regex pattern object
1302 */
1303 REGEXP,
1304
1305 /**
1306 * Returns a pair of regex patterns.
1307 * <p>
1308 * Stack before: pattern1, pattern2 <br>
1309 * Stack after: regex pair object
1310 */
1311 CONDITION_PAIR,
1312
1313 /**
1314 * Returns whether the specified key is in the array.
1315 * <p>
1316 * Stack before: key, array <br>
1317 * Stack after: true|false
1318 */
1319 IS_IN,
1320
1321 /**
1322 * Deprecated.
1323 */
1324 THIS,
1325
1326 /**
1327 * Call a function from an extension
1328 * <p>
1329 * Stack before: x1, x2, ..., xn <br>
1330 * Stack after: f(x1, x2, ..., xn)
1331 */
1332 EXTENSION,
1333
1334 /**
1335 * Delete the specified array.
1336 * <p>
1337 * Stack remains unchanged.
1338 */
1339 DELETE_ARRAY,
1340
1341 /**
1342 * Converts the top stack element to a number;
1343 * pushes the result onto the stack.
1344 * <p>
1345 * Stack before: x ...<br/>
1346 * Stack after: x ... (as a number)
1347 */
1348 UNARY_PLUS,
1349
1350 /**
1351 * Terminates execution without specifying an exit code.
1352 * <p>
1353 * Stack before: N/A <br>
1354 * Stack after: N/A
1355 */
1356 EXIT_WITHOUT_CODE,
1357
1358 /**
1359 * Assign to the special variable NF via JRT and push the assigned value.
1360 * <p>
1361 * Stack before: value ...<br/>
1362 * Stack after: value ...
1363 */
1364 ASSIGN_NF,
1365 /**
1366 * Push the current value of the special variable NF via JRT.
1367 * <p>
1368 * Stack before: ...<br/>
1369 * Stack after: NF ...
1370 */
1371 PUSH_NF,
1372
1373 /** Assign to NR via JRT and push the assigned value. */
1374 ASSIGN_NR,
1375 /** Push the current NR via JRT. */
1376 PUSH_NR,
1377
1378 /** Assign to FNR via JRT and push the assigned value. */
1379 ASSIGN_FNR,
1380 /** Push the current FNR via JRT. */
1381 PUSH_FNR,
1382
1383 /** Assign to FS via JRT and push the assigned value. */
1384 ASSIGN_FS,
1385 /** Push the current FS via JRT. */
1386 PUSH_FS,
1387
1388 /** Assign to RS via JRT and push the assigned value. */
1389 ASSIGN_RS,
1390 /** Push the current RS via JRT. */
1391 PUSH_RS,
1392
1393 /** Assign to OFS via JRT and push the assigned value. */
1394 ASSIGN_OFS,
1395 /** Push the current OFS via JRT. */
1396 PUSH_OFS,
1397
1398 /** Assign to ORS via JRT and push the assigned value. */
1399 ASSIGN_ORS,
1400 /** Push the current ORS via JRT. */
1401 PUSH_ORS,
1402
1403 /** Assign to RSTART via JRT and push the assigned value. */
1404 ASSIGN_RSTART,
1405 /** Push the current RSTART via JRT. */
1406 PUSH_RSTART,
1407
1408 /** Assign to RLENGTH via JRT and push the assigned value. */
1409 ASSIGN_RLENGTH,
1410 /** Push the current RLENGTH via JRT. */
1411 PUSH_RLENGTH,
1412
1413 /** Assign to FILENAME via JRT and push the assigned value. */
1414 ASSIGN_FILENAME,
1415 /** Push the current FILENAME via JRT. */
1416 PUSH_FILENAME,
1417
1418 /** Assign to SUBSEP via JRT and push the assigned value. */
1419 ASSIGN_SUBSEP,
1420 /** Push the current SUBSEP via JRT. */
1421 PUSH_SUBSEP,
1422
1423 /** Assign to CONVFMT via JRT and push the assigned value. */
1424 ASSIGN_CONVFMT,
1425 /** Push the current CONVFMT via JRT. */
1426 PUSH_CONVFMT,
1427
1428 /** Assign to OFMT via JRT and push the assigned value. */
1429 ASSIGN_OFMT,
1430 /** Push the current OFMT via JRT. */
1431 PUSH_OFMT,
1432
1433 /** Assign to ARGC via JRT and push the assigned value. */
1434 ASSIGN_ARGC,
1435 /** Push the current ARGC via JRT. */
1436 PUSH_ARGC,
1437
1438 /**
1439 * Assign the ORS variable offset. This is important for the
1440 * AVM to use when outputting expressions via PRINT.
1441 * <p>
1442 * The operand stack is unaffected.
1443 */
1444 ORS_OFFSET,
1445
1446 /**
1447 * Increases the variable reference by one; pushes the original value
1448 * onto the stack.
1449 * <p>
1450 * Argument 1: offset of the particular variable into the variable manager<br/>
1451 * Argument 2: whether the variable is global or local
1452 * <p>
1453 * Stack before: ...<br/>
1454 * Stack after: x ... or 0 if uninitialized
1455 */
1456 POSTINC,
1457
1458 /**
1459 * Decreases the variable reference by one; pushes the original value
1460 * onto the stack.
1461 * <p>
1462 * Argument 1: offset of the particular variable into the variable manager<br/>
1463 * Argument 2: whether the variable is global or local
1464 * <p>
1465 * Stack before: ...<br/>
1466 * Stack after: x ... or 0 if uninitialized
1467 */
1468 POSTDEC,
1469
1470 /**
1471 * Dereferences an associative-array element as an array, creating a nested
1472 * array when the element is currently blank or uninitialized.
1473 * <p>
1474 * Stack before: array-index associative-array ...<br/>
1475 * Stack after: nested-associative-array ...
1476 */
1477 ENSURE_ARRAY_ELEMENT,
1478
1479 /**
1480 * Looks up an associative-array element without creating a blank entry when
1481 * the key is missing.
1482 * <p>
1483 * Stack before: array-index associative-array ...<br/>
1484 * Stack after: item ...
1485 */
1486 PEEK_ARRAY_ELEMENT,
1487
1488 /**
1489 * Assigns the top of the stack to IGNORECASE, managed by the JRT.
1490 * <p>
1491 * Stack before: value ...<br/>
1492 * Stack after: value ...
1493 */
1494 ASSIGN_IGNORECASE,
1495
1496 /**
1497 * Pushes the value of IGNORECASE, managed by the JRT.
1498 * <p>
1499 * Stack before: ...<br/>
1500 * Stack after: ignorecase-value ...
1501 */
1502 PUSH_IGNORECASE,
1503
1504 /**
1505 * Prints a diagnostic message to the warning stream.
1506 * <p>
1507 * Stack unchanged.
1508 */
1509 WARNING,
1510
1511 /**
1512 * Runs the extension beforeStart hooks. Emitted by the parser at the end
1513 * of the preamble; executed at most once per AVM instance.
1514 * <p>
1515 * Stack unchanged.
1516 */
1517 BEFORE_START_HOOKS,
1518
1519 /**
1520 * Populates the SYMTAB array with the names and values of the program's
1521 * symbols. Emitted only when the script references SYMTAB outside POSIX
1522 * mode.
1523 * <p>
1524 * Argument: offset of the SYMTAB global<br/>
1525 * Stack unchanged.
1526 */
1527 UPDATE_SYMTAB,
1528
1529 /**
1530 * Populates the FUNCTAB array with the names of the program's functions.
1531 * Emitted only when the script references FUNCTAB outside POSIX mode.
1532 * <p>
1533 * Argument: offset of the FUNCTAB global<br/>
1534 * Stack unchanged.
1535 */
1536 UPDATE_FUNCTAB,
1537
1538 /**
1539 * Advances the main input to the next input file, applying pending
1540 * {@code name=value} command-line assignments along the way. On success,
1541 * FILENAME, FNR, ARGIND, and ERRNO are updated and execution falls through
1542 * to the BEGINFILE rules. When no input file remains, it jumps to the
1543 * specified address. Emitted only when BEGINFILE/ENDFILE rules or a
1544 * {@code nextfile} statement require per-file input stepping.
1545 * <p>
1546 * Argument: address to jump to when no more input files remain
1547 * <p>
1548 * Stack unchanged.
1549 */
1550 NEXT_FILE,
1551
1552 /**
1553 * Consume the next record of the current input file only; assigning $0 and
1554 * recalculating $1, $2, etc. Unlike {@link #CONSUME_INPUT}, it never
1555 * advances to the next input file: at end of the current file it jumps to
1556 * the specified address so the ENDFILE rules can run.
1557 * <p>
1558 * Argument: address to jump to at end of the current input file
1559 * <p>
1560 * Stack unchanged.
1561 */
1562 CONSUME_FILE_INPUT,
1563
1564 /**
1565 * Executes the {@code nextfile} statement: abandons the current input
1566 * file and resumes the per-file input loop. The runtime jumps to the
1567 * ENDFILE rules when the current file was opened successfully, or
1568 * directly past them when the file could not be opened (BEGINFILE error
1569 * handling). The jump targets are carried as properties of the tuple
1570 * stream, not as tuples. The runtime stack and operand stack are
1571 * cleared, allowing {@code nextfile} to be invoked from user-defined
1572 * functions.
1573 * <p>
1574 * Stack after: (empty)
1575 */
1576 EXEC_NEXTFILE,
1577
1578 /**
1579 * Assigns the top of the stack to ERRNO, managed by the JRT.
1580 * <p>
1581 * Stack before: value ...<br/>
1582 * Stack after: value ...
1583 */
1584 ASSIGN_ERRNO,
1585
1586 /**
1587 * Pushes the value of ERRNO, managed by the JRT.
1588 * <p>
1589 * Stack before: ...<br/>
1590 * Stack after: errno-value ...
1591 */
1592 PUSH_ERRNO,
1593
1594 /**
1595 * Assigns the top of the stack to ARGIND, managed by the JRT.
1596 * <p>
1597 * Stack before: value ...<br/>
1598 * Stack after: value ...
1599 */
1600 ASSIGN_ARGIND,
1601
1602 /**
1603 * Pushes the value of ARGIND, managed by the JRT.
1604 * <p>
1605 * Stack before: ...<br/>
1606 * Stack after: argind-value ...
1607 */
1608 PUSH_ARGIND,
1609
1610 /**
1611 * Call a user-defined, built-in, or extension function selected by name at
1612 * runtime. New opcodes are appended to preserve serialized numeric identifiers.
1613 */
1614 INDIRECT_CALL,
1615
1616 /**
1617 * Push an indirect-call argument that snapshots its scalar value while retaining
1618 * its variable location. The target selected at runtime determines whether to
1619 * use the scalar snapshot or materialize/read an array at that location.
1620 */
1621 PUSH_INDIRECT_ARGUMENT,
1622
1623 /**
1624 * Push an indirect-call subarray argument that snapshots its scalar value while
1625 * retaining its containing map and key for a runtime-selected array parameter.
1626 */
1627 PUSH_INDIRECT_ARRAY_ARGUMENT,
1628
1629 /**
1630 * Pushes whether the range pattern identified by the tuple's operand is
1631 * currently active (i.e. its start condition matched a previous record and its
1632 * end condition has not matched yet).
1633 * <p>
1634 * Stack before: ... <br>
1635 * Stack after: 1|0 ...
1636 */
1637 CONDITION_PAIR_IN_RANGE,
1638
1639 /**
1640 * Marks the range pattern identified by the tuple's operand as active, after
1641 * its start condition matched the current record.
1642 * <p>
1643 * Stack before: ... <br>
1644 * Stack after: ...
1645 */
1646 CONDITION_PAIR_ENTER,
1647
1648 /**
1649 * Marks the range pattern identified by the tuple's operand as inactive, after
1650 * its end condition matched the current record.
1651 * <p>
1652 * Stack before: ... <br>
1653 * Stack after: ...
1654 */
1655 CONDITION_PAIR_LEAVE;
1656
1657 private static final Opcode[] VALUES = values();
1658
1659 /**
1660 * Resolves an opcode enum constant from its serialized numeric identifier.
1661 *
1662 * @param id Numeric opcode identifier
1663 * @return Matching {@link Opcode}
1664 * @throws IllegalArgumentException If the identifier is outside the valid
1665 * opcode range
1666 */
1667 public static Opcode fromId(int id) {
1668 if (id < 0 || id >= VALUES.length) {
1669 throw new IllegalArgumentException("Unknown opcode: " + id);
1670 }
1671 return VALUES[id];
1672 }
1673 }