Skip to content

Commit 0aebb59

Browse files
committed
Improve WriteScope in ir tree write phase (elastic#63267)
This change moves loose ASM labels into the WriteScope as opposed to having these as member data on the nodes when they don't make sense for all executed phases. This adds the required scopes such as loop scope and try scope to the WriteScope to account for this.
1 parent 2b6f248 commit 0aebb59

File tree

71 files changed

+396
-293
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+396
-293
lines changed

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

+3-5
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919

2020
package org.elasticsearch.painless.ir;
2121

22-
import org.elasticsearch.painless.ClassWriter;
2322
import org.elasticsearch.painless.Location;
24-
import org.elasticsearch.painless.MethodWriter;
2523
import org.elasticsearch.painless.phase.IRTreeVisitor;
2624
import org.elasticsearch.painless.symbol.WriteScope;
2725

@@ -47,8 +45,8 @@ public BinaryImplNode(Location location) {
4745
}
4846

4947
@Override
50-
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
51-
getLeftNode().write(classWriter, methodWriter, writeScope);
52-
getRightNode().write(classWriter, methodWriter, writeScope);
48+
protected void write(WriteScope writeScope) {
49+
getLeftNode().write(writeScope);
50+
getRightNode().write(writeScope);
5351
}
5452
}

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.painless.ir;
2121

22-
import org.elasticsearch.painless.ClassWriter;
2322
import org.elasticsearch.painless.Location;
2423
import org.elasticsearch.painless.MethodWriter;
2524
import org.elasticsearch.painless.Operation;
@@ -111,13 +110,14 @@ public BinaryMathNode(Location location) {
111110
}
112111

113112
@Override
114-
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
113+
protected void write(WriteScope writeScope) {
114+
MethodWriter methodWriter = writeScope.getMethodWriter();
115115
methodWriter.writeDebugInfo(getLocation());
116116

117117
if (operation == Operation.FIND || operation == Operation.MATCH) {
118-
getRightNode().write(classWriter, methodWriter, writeScope);
118+
getRightNode().write(writeScope);
119119
methodWriter.push(regexLimit);
120-
getLeftNode().write(classWriter, methodWriter, writeScope);
120+
getLeftNode().write(writeScope);
121121
methodWriter.invokeStatic(org.objectweb.asm.Type.getType(Augmentation.class), WriterConstants.PATTERN_MATCHER);
122122

123123
if (operation == Operation.FIND) {
@@ -129,8 +129,8 @@ protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteSc
129129
"for type [" + getExpressionCanonicalTypeName() + "]");
130130
}
131131
} else {
132-
getLeftNode().write(classWriter, methodWriter, writeScope);
133-
getRightNode().write(classWriter, methodWriter, writeScope);
132+
getLeftNode().write(writeScope);
133+
getRightNode().write(writeScope);
134134

135135
if (binaryType == def.class || (shiftType != null && shiftType == def.class)) {
136136
methodWriter.writeDynamicBinaryInstruction(getLocation(),

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

+2-6
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919

2020
package org.elasticsearch.painless.ir;
2121

22-
import org.elasticsearch.painless.ClassWriter;
2322
import org.elasticsearch.painless.Location;
24-
import org.elasticsearch.painless.MethodWriter;
2523
import org.elasticsearch.painless.phase.IRTreeVisitor;
2624
import org.elasticsearch.painless.symbol.WriteScope;
2725

@@ -75,11 +73,9 @@ public BlockNode(Location location) {
7573
}
7674

7775
@Override
78-
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
76+
protected void write(WriteScope writeScope) {
7977
for (StatementNode statementNode : statementNodes) {
80-
statementNode.continueLabel = continueLabel;
81-
statementNode.breakLabel = breakLabel;
82-
statementNode.write(classWriter, methodWriter, writeScope);
78+
statementNode.write(writeScope);
8379
}
8480
}
8581
}

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.painless.ir;
2121

22-
import org.elasticsearch.painless.ClassWriter;
2322
import org.elasticsearch.painless.Location;
2423
import org.elasticsearch.painless.MethodWriter;
2524
import org.elasticsearch.painless.Operation;
@@ -62,16 +61,17 @@ public BooleanNode(Location location) {
6261
}
6362

6463
@Override
65-
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
64+
protected void write(WriteScope writeScope) {
65+
MethodWriter methodWriter = writeScope.getMethodWriter();
6666
methodWriter.writeDebugInfo(getLocation());
6767

6868
if (operation == Operation.AND) {
6969
Label fals = new Label();
7070
Label end = new Label();
7171

72-
getLeftNode().write(classWriter, methodWriter, writeScope);
72+
getLeftNode().write(writeScope);
7373
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
74-
getRightNode().write(classWriter, methodWriter, writeScope);
74+
getRightNode().write(writeScope);
7575
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
7676

7777
methodWriter.push(true);
@@ -84,9 +84,9 @@ protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteSc
8484
Label fals = new Label();
8585
Label end = new Label();
8686

87-
getLeftNode().write(classWriter, methodWriter, writeScope);
87+
getLeftNode().write(writeScope);
8888
methodWriter.ifZCmp(Opcodes.IFNE, tru);
89-
getRightNode().write(classWriter, methodWriter, writeScope);
89+
getRightNode().write(writeScope);
9090
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
9191

9292
methodWriter.mark(tru);

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.painless.ir;
2121

22-
import org.elasticsearch.painless.ClassWriter;
2322
import org.elasticsearch.painless.Location;
2423
import org.elasticsearch.painless.MethodWriter;
2524
import org.elasticsearch.painless.phase.IRTreeVisitor;
@@ -46,7 +45,8 @@ public BreakNode(Location location) {
4645
}
4746

4847
@Override
49-
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
50-
methodWriter.goTo(breakLabel);
48+
protected void write(WriteScope writeScope) {
49+
MethodWriter methodWriter = writeScope.getMethodWriter();
50+
methodWriter.goTo(writeScope.getBreakLabel());
5151
}
5252
}

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.painless.ir;
2121

22-
import org.elasticsearch.painless.ClassWriter;
2322
import org.elasticsearch.painless.Location;
2423
import org.elasticsearch.painless.MethodWriter;
2524
import org.elasticsearch.painless.lookup.PainlessCast;
@@ -59,8 +58,10 @@ public CastNode(Location location) {
5958
}
6059

6160
@Override
62-
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
63-
getChildNode().write(classWriter, methodWriter, writeScope);
61+
protected void write(WriteScope writeScope) {
62+
MethodWriter methodWriter = writeScope.getMethodWriter();
63+
64+
getChildNode().write(writeScope);
6465
methodWriter.writeDebugInfo(getLocation());
6566
methodWriter.writeCast(cast);
6667
}

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

+7-12
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.painless.ir;
2121

22-
import org.elasticsearch.painless.ClassWriter;
2322
import org.elasticsearch.painless.Location;
2423
import org.elasticsearch.painless.MethodWriter;
2524
import org.elasticsearch.painless.phase.IRTreeVisitor;
@@ -76,16 +75,13 @@ public <Scope> void visitChildren(IRTreeVisitor<Scope> irTreeVisitor, Scope scop
7675

7776
/* ---- end visitor ---- */
7877

79-
Label begin = null;
80-
Label end = null;
81-
Label exception = null;
82-
8378
public CatchNode(Location location) {
8479
super(location);
8580
}
8681

8782
@Override
88-
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
83+
protected void write(WriteScope writeScope) {
84+
MethodWriter methodWriter = writeScope.getMethodWriter();
8985
methodWriter.writeStatementOffset(getLocation());
9086

9187
Variable variable = writeScope.defineVariable(exceptionType, symbol);
@@ -96,15 +92,14 @@ protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteSc
9692
methodWriter.visitVarInsn(variable.getAsmType().getOpcode(Opcodes.ISTORE), variable.getSlot());
9793

9894
if (blockNode != null) {
99-
blockNode.continueLabel = continueLabel;
100-
blockNode.breakLabel = breakLabel;
101-
blockNode.write(classWriter, methodWriter, writeScope);
95+
blockNode.write(writeScope.newBlockScope(true));
10296
}
10397

104-
methodWriter.visitTryCatchBlock(begin, end, jump, variable.getAsmType().getInternalName());
98+
methodWriter.visitTryCatchBlock(
99+
writeScope.getTryBeginLabel(), writeScope.getTryEndLabel(), jump, variable.getAsmType().getInternalName());
105100

106-
if (exception != null && (blockNode == null || blockNode.doAllEscape() == false)) {
107-
methodWriter.goTo(exception);
101+
if (writeScope.getCatchesEndLabel() != null && (blockNode == null || blockNode.doAllEscape() == false)) {
102+
methodWriter.goTo(writeScope.getCatchesEndLabel());
108103
}
109104
}
110105
}

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

+6-4
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ public ClassNode(Location location) {
115115
}
116116

117117
public byte[] write() {
118+
WriteScope writeScope = WriteScope.newScriptScope();
118119
ScriptClassInfo scriptClassInfo = scriptScope.getScriptClassInfo();
119120
BitSet statements = new BitSet(scriptScope.getScriptSource().length());
120121
scriptScope.addStaticConstant("$STATEMENTS", statements);
@@ -131,6 +132,7 @@ public byte[] write() {
131132
scriptClassInfo.getBaseClass(), classFrames, classAccess, className, classInterfaces);
132133
ClassVisitor classVisitor = classWriter.getClassVisitor();
133134
classVisitor.visitSource(Location.computeSourceName(scriptScope.getScriptName()), null);
135+
writeScope = writeScope.newClassScope(classWriter);
134136

135137
org.objectweb.asm.commons.Method init;
136138

@@ -154,19 +156,19 @@ public byte[] write() {
154156
MethodWriter methodWriter = classWriter.newMethodWriter(
155157
Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
156158
new Method("<clinit>", Type.getType(void.class), new Type[0]));
157-
clinitBlockNode.write(classWriter, methodWriter, new WriteScope());
159+
clinitBlockNode.write(writeScope.newMethodScope(methodWriter).newBlockScope());
158160
methodWriter.returnValue();
159161
methodWriter.endMethod();
160162
}
161163

162164
// Write all fields:
163165
for (FieldNode fieldNode : fieldNodes) {
164-
fieldNode.write(classWriter, null, null);
166+
fieldNode.write(writeScope);
165167
}
166168

167169
// Write all functions:
168170
for (FunctionNode functionNode : functionNodes) {
169-
functionNode.write(classWriter, null, new WriteScope());
171+
functionNode.write(writeScope);
170172
}
171173

172174
// End writing the class and store the generated bytes.
@@ -175,7 +177,7 @@ public byte[] write() {
175177
}
176178

177179
@Override
178-
public void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
180+
public void write(WriteScope writeScope) {
179181
throw new UnsupportedOperationException("use write() instead");
180182
}
181183
}

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.painless.ir;
2121

22-
import org.elasticsearch.painless.ClassWriter;
2322
import org.elasticsearch.painless.DefBootstrap;
2423
import org.elasticsearch.painless.Location;
2524
import org.elasticsearch.painless.MethodWriter;
@@ -81,13 +80,14 @@ public ComparisonNode(Location location) {
8180
}
8281

8382
@Override
84-
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
83+
protected void write(WriteScope writeScope) {
84+
MethodWriter methodWriter = writeScope.getMethodWriter();
8585
methodWriter.writeDebugInfo(getLocation());
8686

87-
getLeftNode().write(classWriter, methodWriter, writeScope);
87+
getLeftNode().write(writeScope);
8888

8989
if (getRightNode() instanceof NullNode == false) {
90-
getRightNode().write(classWriter, methodWriter, writeScope);
90+
getRightNode().write(writeScope);
9191
}
9292

9393
Label jump = new Label();

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.painless.ir;
2121

22-
import org.elasticsearch.painless.ClassWriter;
2322
import org.elasticsearch.painless.Location;
2423
import org.elasticsearch.painless.MethodWriter;
2524
import org.elasticsearch.painless.phase.IRTreeVisitor;
@@ -62,19 +61,20 @@ public ConditionalNode(Location location) {
6261
}
6362

6463
@Override
65-
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
64+
protected void write(WriteScope writeScope) {
65+
MethodWriter methodWriter = writeScope.getMethodWriter();
6666
methodWriter.writeDebugInfo(getLocation());
6767

6868
Label fals = new Label();
6969
Label end = new Label();
7070

71-
conditionNode.write(classWriter, methodWriter, writeScope);
71+
conditionNode.write(writeScope);
7272
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
7373

74-
getLeftNode().write(classWriter, methodWriter, writeScope);
74+
getLeftNode().write(writeScope);
7575
methodWriter.goTo(end);
7676
methodWriter.mark(fals);
77-
getRightNode().write(classWriter, methodWriter, writeScope);
77+
getRightNode().write(writeScope);
7878
methodWriter.mark(end);
7979
}
8080
}

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.painless.ir;
2121

22-
import org.elasticsearch.painless.ClassWriter;
2322
import org.elasticsearch.painless.Location;
2423
import org.elasticsearch.painless.MethodWriter;
2524
import org.elasticsearch.painless.phase.IRTreeVisitor;
@@ -58,7 +57,9 @@ public ConstantNode(Location location) {
5857
}
5958

6059
@Override
61-
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
60+
protected void write(WriteScope writeScope) {
61+
MethodWriter methodWriter = writeScope.getMethodWriter();
62+
6263
if (constant instanceof String) methodWriter.push((String)constant);
6364
else if (constant instanceof Double) methodWriter.push((double)constant);
6465
else if (constant instanceof Float) methodWriter.push((float)constant);

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.painless.ir;
2121

22-
import org.elasticsearch.painless.ClassWriter;
2322
import org.elasticsearch.painless.Location;
2423
import org.elasticsearch.painless.MethodWriter;
2524
import org.elasticsearch.painless.phase.IRTreeVisitor;
@@ -46,7 +45,8 @@ public ContinueNode(Location location) {
4645
}
4746

4847
@Override
49-
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
50-
methodWriter.goTo(continueLabel);
48+
protected void write(WriteScope writeScope) {
49+
MethodWriter methodWriter = writeScope.getMethodWriter();
50+
methodWriter.goTo(writeScope.getContinueLabel());
5151
}
5252
}

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

+2-4
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919

2020
package org.elasticsearch.painless.ir;
2121

22-
import org.elasticsearch.painless.ClassWriter;
2322
import org.elasticsearch.painless.Location;
24-
import org.elasticsearch.painless.MethodWriter;
2523
import org.elasticsearch.painless.phase.IRTreeVisitor;
2624
import org.elasticsearch.painless.symbol.WriteScope;
2725

@@ -63,9 +61,9 @@ public DeclarationBlockNode(Location location) {
6361
}
6462

6563
@Override
66-
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
64+
protected void write(WriteScope writeScope) {
6765
for (DeclarationNode declarationNode : declarationNodes) {
68-
declarationNode.write(classWriter, methodWriter, writeScope);
66+
declarationNode.write(writeScope);
6967
}
7068
}
7169
}

0 commit comments

Comments
 (0)