Problem
Most variable assignments require 3 opcodes: PUSH + ASSIGN + POP. See example below:
AWK script:
Which results in the below opcodes:
283 : PUSH_LONG, -2
284 : ASSIGN, 11, true
285 : POP
286 : PUSH_LONG, 2
287 : ASSIGN, 12, true
288 : POP
289 : PUSH_LONG, 4
290 : ASSIGN, 13, true
291 : POP
Specification
Most variable assignments don't need to be pushed on the stack, just to be poped immediately and discarded. Combinations of ASSIGN + POP should be simplified so that ASSIGN doesn't push to the stack.
In AVM.java, the below method should be updated to include a boolean push argument:
/**
* Awk variable assignment functionality.
*/
private void assign(long l, Object value, boolean isGlobal, PositionTracker position, boolean push) {
// check if curr value already refers to an array
if (runtimeStack.getVariable(l, isGlobal) instanceof Map) {
throw new AwkRuntimeException(position.lineNumber(), "cannot assign anything to an unindexed associative array");
}
if (push) { push(value); }
runtimeStack.setVariable(l, value, isGlobal);
// When specials are compiled correctly, they use ASSIGN_* and skip this path.
}
And the optimization methods in AwkTuples.java must detect ASSIGN + POP opcodes and replace with a single ASSIGN(push: false) opcode (see notably peepholeOptimizePass()).
Problem
Most variable assignments require 3 opcodes: PUSH + ASSIGN + POP. See example below:
AWK script:
Which results in the below opcodes:
Specification
Most variable assignments don't need to be pushed on the stack, just to be poped immediately and discarded. Combinations of ASSIGN + POP should be simplified so that ASSIGN doesn't push to the stack.
In AVM.java, the below method should be updated to include a
boolean pushargument:And the optimization methods in AwkTuples.java must detect ASSIGN + POP opcodes and replace with a single ASSIGN(push: false) opcode (see notably
peepholeOptimizePass()).