Skip to content

Commit a8a34ec

Browse files
authored
Add flip index ir nodes (#60841)
This change adds three nodes that support negative brace accesses into collections, arrays, and for def types. This helps separate that logic out from brace accesses in general. This also has some renaming for nodes adding an ir prefix to help differentiate ir node variables from user node variables.
1 parent ce01e48 commit a8a34ec

17 files changed

+388
-233
lines changed

modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/BraceSubDefNode.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import org.elasticsearch.painless.symbol.WriteScope;
2727
import org.objectweb.asm.Type;
2828

29-
public class BraceSubDefNode extends UnaryNode {
29+
public class BraceSubDefNode extends IndexNode {
3030

3131
/* ---- begin visitor ---- */
3232

@@ -50,19 +50,15 @@ protected int accessElementCount() {
5050

5151
@Override
5252
protected void setup(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
53-
methodWriter.dup();
54-
getChildNode().write(classWriter, methodWriter, writeScope);
55-
Type methodType = Type.getMethodType(MethodWriter.getType(
56-
getChildNode().getExpressionType()), Type.getType(Object.class), MethodWriter.getType(getChildNode().getExpressionType()));
57-
methodWriter.invokeDefCall("normalizeIndex", methodType, DefBootstrap.INDEX_NORMALIZE);
53+
getIndexNode().write(classWriter, methodWriter, writeScope);
5854
}
5955

6056
@Override
6157
protected void load(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
6258
methodWriter.writeDebugInfo(location);
6359

6460
Type methodType = Type.getMethodType(MethodWriter.getType(
65-
getExpressionType()), Type.getType(Object.class), MethodWriter.getType(getChildNode().getExpressionType()));
61+
getExpressionType()), Type.getType(Object.class), MethodWriter.getType(getIndexNode().getExpressionType()));
6662
methodWriter.invokeDefCall("arrayLoad", methodType, DefBootstrap.ARRAY_LOAD);
6763
}
6864

@@ -71,7 +67,7 @@ protected void store(ClassWriter classWriter, MethodWriter methodWriter, WriteSc
7167
methodWriter.writeDebugInfo(location);
7268

7369
Type methodType = Type.getMethodType(Type.getType(void.class), Type.getType(Object.class),
74-
MethodWriter.getType(getChildNode().getExpressionType()), MethodWriter.getType(getExpressionType()));
70+
MethodWriter.getType(getIndexNode().getExpressionType()), MethodWriter.getType(getExpressionType()));
7571
methodWriter.invokeDefCall("arrayStore", methodType, DefBootstrap.ARRAY_STORE);
7672
}
7773
}

modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/BraceSubNode.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,8 @@
2323
import org.elasticsearch.painless.MethodWriter;
2424
import org.elasticsearch.painless.phase.IRTreeVisitor;
2525
import org.elasticsearch.painless.symbol.WriteScope;
26-
import org.objectweb.asm.Label;
27-
import org.objectweb.asm.Opcodes;
2826

29-
public class BraceSubNode extends UnaryNode {
27+
public class BraceSubNode extends IndexNode {
3028

3129
/* ---- begin visitor ---- */
3230

@@ -50,16 +48,7 @@ protected int accessElementCount() {
5048

5149
@Override
5250
protected void setup(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
53-
getChildNode().write(classWriter, methodWriter, writeScope);
54-
55-
Label noFlip = new Label();
56-
methodWriter.dup();
57-
methodWriter.ifZCmp(Opcodes.IFGE, noFlip);
58-
methodWriter.swap();
59-
methodWriter.dupX1();
60-
methodWriter.arrayLength();
61-
methodWriter.visitInsn(Opcodes.IADD);
62-
methodWriter.mark(noFlip);
51+
getIndexNode().write(classWriter, methodWriter, writeScope);
6352
}
6453

6554
@Override
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.painless.ir;
21+
22+
import org.elasticsearch.painless.ClassWriter;
23+
import org.elasticsearch.painless.MethodWriter;
24+
import org.elasticsearch.painless.symbol.WriteScope;
25+
import org.objectweb.asm.Label;
26+
import org.objectweb.asm.Opcodes;
27+
28+
public class FlipArrayIndex extends IndexNode {
29+
30+
@Override
31+
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
32+
getIndexNode().write(classWriter, methodWriter, writeScope);
33+
34+
Label noFlip = new Label();
35+
methodWriter.dup();
36+
methodWriter.ifZCmp(Opcodes.IFGE, noFlip);
37+
methodWriter.swap();
38+
methodWriter.dupX1();
39+
methodWriter.arrayLength();
40+
methodWriter.visitInsn(Opcodes.IADD);
41+
methodWriter.mark(noFlip);
42+
}
43+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.painless.ir;
21+
22+
import org.elasticsearch.painless.ClassWriter;
23+
import org.elasticsearch.painless.MethodWriter;
24+
import org.elasticsearch.painless.WriterConstants;
25+
import org.elasticsearch.painless.symbol.WriteScope;
26+
import org.objectweb.asm.Label;
27+
import org.objectweb.asm.Opcodes;
28+
29+
public class FlipCollectionIndex extends IndexNode {
30+
31+
@Override
32+
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
33+
getIndexNode().write(classWriter, methodWriter, writeScope);
34+
35+
Label noFlip = new Label();
36+
methodWriter.dup();
37+
methodWriter.ifZCmp(Opcodes.IFGE, noFlip);
38+
methodWriter.swap();
39+
methodWriter.dupX1();
40+
methodWriter.invokeInterface(WriterConstants.COLLECTION_TYPE, WriterConstants.COLLECTION_SIZE);
41+
methodWriter.visitInsn(Opcodes.IADD);
42+
methodWriter.mark(noFlip);
43+
}
44+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.painless.ir;
21+
22+
import org.elasticsearch.painless.ClassWriter;
23+
import org.elasticsearch.painless.DefBootstrap;
24+
import org.elasticsearch.painless.MethodWriter;
25+
import org.elasticsearch.painless.symbol.WriteScope;
26+
import org.objectweb.asm.Type;
27+
28+
public class FlipDefIndex extends IndexNode {
29+
30+
@Override
31+
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
32+
methodWriter.dup();
33+
getIndexNode().write(classWriter, methodWriter, writeScope);
34+
Type methodType = Type.getMethodType(MethodWriter.getType(
35+
getIndexNode().getExpressionType()), Type.getType(Object.class), MethodWriter.getType(getIndexNode().getExpressionType()));
36+
methodWriter.invokeDefCall("normalizeIndex", methodType, DefBootstrap.INDEX_NORMALIZE);
37+
}
38+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.painless.ir;
21+
22+
public abstract class IndexNode extends ExpressionNode {
23+
24+
/* ---- begin tree structure ---- */
25+
26+
private ExpressionNode indexNode;
27+
28+
public void setIndexNode(ExpressionNode indexNode) {
29+
this.indexNode = indexNode;
30+
}
31+
32+
public ExpressionNode getIndexNode() {
33+
return indexNode;
34+
}
35+
36+
/* ---- end tree structure ---- */
37+
38+
}

modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/CallSubDefNode.java renamed to modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/InvokeCallDefNode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
import static org.elasticsearch.painless.symbol.WriteScope.Variable;
3333

34-
public class CallSubDefNode extends ArgumentsNode {
34+
public class InvokeCallDefNode extends ArgumentsNode {
3535

3636
/* ---- begin node data ---- */
3737

@@ -49,7 +49,7 @@ public String getName() {
4949

5050
@Override
5151
public <Input, Output> Output visit(IRTreeVisitor<Input, Output> irTreeVisitor, Input input) {
52-
return irTreeVisitor.visitCallSubDef(this, input);
52+
return irTreeVisitor.visitInvokeCallDef(this, input);
5353
}
5454

5555
/* ---- end visitor ---- */

modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/MemberCallNode.java renamed to modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/InvokeCallMemberNode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
import static org.elasticsearch.painless.WriterConstants.CLASS_TYPE;
3535

36-
public class MemberCallNode extends ArgumentsNode {
36+
public class InvokeCallMemberNode extends ArgumentsNode {
3737

3838
/* ---- begin node data ---- */
3939

@@ -96,7 +96,7 @@ public String getBindingName() {
9696

9797
@Override
9898
public <Input, Output> Output visit(IRTreeVisitor<Input, Output> irTreeVisitor, Input input) {
99-
return irTreeVisitor.visitMemberCall(this, input);
99+
return irTreeVisitor.visitInvokeCallMember(this, input);
100100
}
101101

102102
/* ---- end visitor ---- */

modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/CallSubNode.java renamed to modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/InvokeCallNode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import org.elasticsearch.painless.phase.IRTreeVisitor;
2626
import org.elasticsearch.painless.symbol.WriteScope;
2727

28-
public class CallSubNode extends ArgumentsNode {
28+
public class InvokeCallNode extends ArgumentsNode {
2929

3030
/* ---- begin node data ---- */
3131

@@ -52,7 +52,7 @@ public Class<?> getBox() {
5252

5353
@Override
5454
public <Input, Output> Output visit(IRTreeVisitor<Input, Output> irTreeVisitor, Input input) {
55-
return irTreeVisitor.visitCallSub(this, input);
55+
return irTreeVisitor.visitInvokeCall(this, input);
5656
}
5757

5858
/* ---- end visitor ---- */

modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/ListSubShortcutNode.java

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,11 @@
2121

2222
import org.elasticsearch.painless.ClassWriter;
2323
import org.elasticsearch.painless.MethodWriter;
24-
import org.elasticsearch.painless.WriterConstants;
2524
import org.elasticsearch.painless.lookup.PainlessMethod;
2625
import org.elasticsearch.painless.phase.IRTreeVisitor;
2726
import org.elasticsearch.painless.symbol.WriteScope;
28-
import org.objectweb.asm.Label;
29-
import org.objectweb.asm.Opcodes;
3027

31-
public class ListSubShortcutNode extends UnaryNode {
28+
public class ListSubShortcutNode extends IndexNode {
3229

3330
/* ---- begin node data ---- */
3431

@@ -73,16 +70,7 @@ protected int accessElementCount() {
7370

7471
@Override
7572
protected void setup(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
76-
getChildNode().write(classWriter, methodWriter, writeScope);
77-
78-
Label noFlip = new Label();
79-
methodWriter.dup();
80-
methodWriter.ifZCmp(Opcodes.IFGE, noFlip);
81-
methodWriter.swap();
82-
methodWriter.dupX1();
83-
methodWriter.invokeInterface(WriterConstants.COLLECTION_TYPE, WriterConstants.COLLECTION_SIZE);
84-
methodWriter.visitInsn(Opcodes.IADD);
85-
methodWriter.mark(noFlip);
73+
getIndexNode().write(classWriter, methodWriter, writeScope);
8674
}
8775

8876
@Override

modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/MemberFieldLoadNode.java renamed to modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/LoadFieldMemberNode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
* Represents reading a value from a member field from
3131
* the main class.
3232
*/
33-
public class MemberFieldLoadNode extends ExpressionNode {
33+
public class LoadFieldMemberNode extends ExpressionNode {
3434

3535
/* ---- begin node data ---- */
3636

@@ -57,7 +57,7 @@ public boolean isStatic() {
5757

5858
@Override
5959
public <Input, Output> Output visit(IRTreeVisitor<Input, Output> irTreeVisitor, Input input) {
60-
return irTreeVisitor.visitMemberFieldLoad(this, input);
60+
return irTreeVisitor.visitLoadFieldMember(this, input);
6161
}
6262

6363
/* ---- end visitor ---- */

modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/MapSubShortcutNode.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import org.elasticsearch.painless.phase.IRTreeVisitor;
2626
import org.elasticsearch.painless.symbol.WriteScope;
2727

28-
public class MapSubShortcutNode extends UnaryNode {
28+
public class MapSubShortcutNode extends IndexNode {
2929

3030
/* ---- begin node data ---- */
3131

@@ -59,7 +59,7 @@ public <Input, Output> Output visit(IRTreeVisitor<Input, Output> irTreeVisitor,
5959

6060
@Override
6161
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
62-
getChildNode().write(classWriter, methodWriter, writeScope);
62+
getIndexNode().write(classWriter, methodWriter, writeScope);
6363

6464
methodWriter.writeDebugInfo(location);
6565
methodWriter.invokeMethodCall(getter);
@@ -76,7 +76,7 @@ protected int accessElementCount() {
7676

7777
@Override
7878
protected void setup(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
79-
getChildNode().write(classWriter, methodWriter, writeScope);
79+
getIndexNode().write(classWriter, methodWriter, writeScope);
8080
}
8181

8282
@Override

modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/MemberFieldStoreNode.java renamed to modules/lang-painless/src/main/java/org/elasticsearch/painless/ir/StoreFieldMemberNode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
* The value to store is generated by the child node accessed
3333
* via {@link #getChildNode()}.
3434
*/
35-
public class MemberFieldStoreNode extends UnaryNode {
35+
public class StoreFieldMemberNode extends UnaryNode {
3636

3737
/* ---- begin node data ---- */
3838

@@ -72,7 +72,7 @@ public boolean isStatic() {
7272

7373
@Override
7474
public <Input, Output> Output visit(IRTreeVisitor<Input, Output> irTreeVisitor, Input input) {
75-
return irTreeVisitor.visitMemberFieldStore(this, input);
75+
return irTreeVisitor.visitStoreFieldMember(this, input);
7676
}
7777

7878
/* ---- end visitor ---- */

0 commit comments

Comments
 (0)