Skip to content

Commit 956fe45

Browse files
mtdowlingadwsingh
authored andcommitted
Add peephole optimization for checking null registers
1 parent 45156cc commit 956fe45

3 files changed

Lines changed: 43 additions & 17 deletions

File tree

client/client-rulesengine/src/main/java/software/amazon/smithy/java/client/rulesengine/RulesCompiler.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import software.amazon.smithy.rulesengine.language.syntax.expressions.Reference;
2121
import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.FunctionDefinition;
2222
import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.GetAttr;
23+
import software.amazon.smithy.rulesengine.language.syntax.expressions.functions.IsSet;
2324
import software.amazon.smithy.rulesengine.language.syntax.expressions.literal.BooleanLiteral;
2425
import software.amazon.smithy.rulesengine.language.syntax.expressions.literal.IntegerLiteral;
2526
import software.amazon.smithy.rulesengine.language.syntax.expressions.literal.Literal;
@@ -294,8 +295,13 @@ public Void visitIsSet(Expression fn) {
294295

295296
@Override
296297
public Void visitNot(Expression not) {
297-
compileExpression(not);
298-
add_NOT();
298+
if (not instanceof IsSet isset && isset.getArguments().get(0) instanceof Reference ref) {
299+
add_TEST_REGISTER_NOT_SET(ref.getName().toString());
300+
return null;
301+
} else {
302+
compileExpression(not);
303+
add_NOT();
304+
}
299305
return null;
300306
}
301307

@@ -487,6 +493,11 @@ private void add_TEST_REGISTER_ISSET(String register) {
487493
addInstruction(getRegister(register));
488494
}
489495

496+
private void add_TEST_REGISTER_NOT_SET(String register) {
497+
addInstruction(RulesProgram.TEST_REGISTER_NOT_SET);
498+
addInstruction(getRegister(register));
499+
}
500+
490501
private void add_RETURN_ERROR() {
491502
addInstruction(RulesProgram.RETURN_ERROR);
492503
}

client/client-rulesengine/src/main/java/software/amazon/smithy/java/client/rulesengine/RulesProgram.java

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,38 +70,45 @@ public final class RulesProgram {
7070
static final byte ISSET = 6;
7171

7272
/**
73-
* Checks if a register is set to something that is boolean true or a non null value.
73+
* Checks if a register is set to a non-null value.
7474
*
7575
* <p>Must be followed by an unsigned byte that represents the register to check.
7676
*/
7777
static final byte TEST_REGISTER_ISSET = 7;
7878

79+
/**
80+
* Checks if a register is not set or set to a null value.
81+
*
82+
* <p>Must be followed by an unsigned byte that represents the register to check.
83+
*/
84+
static final byte TEST_REGISTER_NOT_SET = 8;
85+
7986
/**
8087
* Sets an error on the VM and exits.
8188
*
8289
* <p>Pops a single value that provides the error string to set.
8390
*/
84-
static final byte RETURN_ERROR = 8;
91+
static final byte RETURN_ERROR = 9;
8592

8693
/**
8794
* Sets the endpoint result of the VM and exits. Pops the top of the stack, expecting a string value. The opcode
8895
* must be followed by a byte where the first bit of the byte is on if the endpoint has headers, and the second
8996
* bit is on if the endpoint has properties.
9097
*/
91-
static final byte RETURN_ENDPOINT = 9;
98+
static final byte RETURN_ENDPOINT = 10;
9299

93100
/**
94101
* Pops N values off the stack and pushes a list of those values onto the stack. Must be followed by an unsigned
95102
* byte that defines the number of elements in the list.
96103
*/
97-
static final byte CREATE_LIST = 10;
104+
static final byte CREATE_LIST = 11;
98105

99106
/**
100107
* Pops N*2 values off the stack (key then value), creates a map of those values, and pushes the map onto the
101108
* stack. Each popped key must be a string. Must be followed by an unsigned byte that defines the
102109
* number of entries in the map.
103110
*/
104-
static final byte CREATE_MAP = 11;
111+
static final byte CREATE_MAP = 12;
105112

106113
/**
107114
* Resolves a template string. Must be followed by two bytes, a short, that represents the constant pool index
@@ -111,53 +118,53 @@ public final class RulesProgram {
111118
* The popped values fill in values into the template. The resolved template value as a string is then pushed onto
112119
* the stack.
113120
*/
114-
static final byte RESOLVE_TEMPLATE = 12;
121+
static final byte RESOLVE_TEMPLATE = 13;
115122

116123
/**
117124
* Calls a function. Must be followed by a byte to provide the function index to call.
118125
*
119126
* <p>The function pops zero or more values off the stack based on the RulesFunction registered for the index,
120127
* and then pushes the Object result onto the stack.
121128
*/
122-
static final byte FN = 13;
129+
static final byte FN = 14;
123130

124131
/**
125132
* Pops the top level value and applies a getAttr expression on it, pushing the result onto the stack.
126133
*
127134
* <p>Must be followed by two bytes, a short, that represents the constant pool index that stores the
128135
* AttrExpression.
129136
*/
130-
static final byte GET_ATTR = 14;
137+
static final byte GET_ATTR = 15;
131138

132139
/**
133140
* Pops a value and pushes true if the value is boolean true, false if not.
134141
*/
135-
static final byte IS_TRUE = 15;
142+
static final byte IS_TRUE = 16;
136143

137144
/**
138145
* Checks if a register is boolean true and pushes the result onto the stack.
139146
*
140147
* <p>Must be followed by a byte that represents the register to check.
141148
*/
142-
static final byte TEST_REGISTER_IS_TRUE = 16;
149+
static final byte TEST_REGISTER_IS_TRUE = 17;
143150

144151
/**
145152
* Checks if a register is boolean false and pushes the result onto the stack.
146153
*
147154
* <p>Must be followed by a byte that represents the register to check.
148155
*/
149-
static final byte TEST_REGISTER_IS_FALSE = 17;
156+
static final byte TEST_REGISTER_IS_FALSE = 18;
150157

151158
/**
152159
* Pops the value at the top of the stack and returns it from the VM. This can be used for testing purposes or
153160
* for returning things other than endpoint values.
154161
*/
155-
static final byte RETURN_VALUE = 18;
162+
static final byte RETURN_VALUE = 19;
156163

157164
/**
158165
* Pops the top two values off the stack and performs Objects.equals on them, pushing the result onto the stack.
159166
*/
160-
static final byte EQUALS = 19;
167+
static final byte EQUALS = 20;
161168

162169
/**
163170
* Pops the top value off the stack, expecting a string, and extracts a substring of it, pushing the result onto
@@ -166,7 +173,7 @@ public final class RulesProgram {
166173
* <p>Must be followed by three bytes: the start position in the string, the end position in the string, and
167174
* a byte set to 1 if the substring is "reversed" (from the end) or not.
168175
*/
169-
static final byte SUBSTRING = 20;
176+
static final byte SUBSTRING = 21;
170177

171178
final List<RulesExtension> extensions;
172179
final Object[] constantPool;
@@ -392,7 +399,12 @@ private int writeInstruction(StringBuilder s, int pc) {
392399
case TEST_REGISTER_ISSET -> {
393400
skip = 1;
394401
show = Show.REGISTER;
395-
yield "TEST_REGISTER_SET";
402+
yield "TEST_REGISTER_ISSET";
403+
}
404+
case TEST_REGISTER_NOT_SET -> {
405+
skip = 1;
406+
show = Show.REGISTER;
407+
yield "TEST_REGISTER_NOT_SET";
396408
}
397409
case RETURN_ERROR -> "RETURN_ERROR";
398410
case RETURN_ENDPOINT -> {

client/client-rulesengine/src/main/java/software/amazon/smithy/java/client/rulesengine/RulesVm.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ private Object run() {
187187
case RulesProgram.TEST_REGISTER_ISSET -> {
188188
push(registers[instructions[++pc] & 0xFF] != null ? Boolean.TRUE : Boolean.FALSE);
189189
}
190+
case RulesProgram.TEST_REGISTER_NOT_SET -> {
191+
push(registers[instructions[++pc] & 0xFF] == null ? Boolean.TRUE : Boolean.FALSE);
192+
}
190193
case RulesProgram.RETURN_ERROR -> {
191194
throw new RulesEvaluationError((String) stack[--stackPosition], pc);
192195
}

0 commit comments

Comments
 (0)