Skip to content

Commit

Permalink
Improve WriteScope in ir tree write phase (elastic#63267)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jdconrad committed Oct 8, 2020
1 parent 2b6f248 commit 0aebb59
Show file tree
Hide file tree
Showing 71 changed files with 396 additions and 293 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@

package org.elasticsearch.painless.ir;

import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.phase.IRTreeVisitor;
import org.elasticsearch.painless.symbol.WriteScope;

Expand All @@ -47,8 +45,8 @@ public BinaryImplNode(Location location) {
}

@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
getLeftNode().write(classWriter, methodWriter, writeScope);
getRightNode().write(classWriter, methodWriter, writeScope);
protected void write(WriteScope writeScope) {
getLeftNode().write(writeScope);
getRightNode().write(writeScope);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.elasticsearch.painless.ir;

import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.Operation;
Expand Down Expand Up @@ -111,13 +110,14 @@ public BinaryMathNode(Location location) {
}

@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
protected void write(WriteScope writeScope) {
MethodWriter methodWriter = writeScope.getMethodWriter();
methodWriter.writeDebugInfo(getLocation());

if (operation == Operation.FIND || operation == Operation.MATCH) {
getRightNode().write(classWriter, methodWriter, writeScope);
getRightNode().write(writeScope);
methodWriter.push(regexLimit);
getLeftNode().write(classWriter, methodWriter, writeScope);
getLeftNode().write(writeScope);
methodWriter.invokeStatic(org.objectweb.asm.Type.getType(Augmentation.class), WriterConstants.PATTERN_MATCHER);

if (operation == Operation.FIND) {
Expand All @@ -129,8 +129,8 @@ protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteSc
"for type [" + getExpressionCanonicalTypeName() + "]");
}
} else {
getLeftNode().write(classWriter, methodWriter, writeScope);
getRightNode().write(classWriter, methodWriter, writeScope);
getLeftNode().write(writeScope);
getRightNode().write(writeScope);

if (binaryType == def.class || (shiftType != null && shiftType == def.class)) {
methodWriter.writeDynamicBinaryInstruction(getLocation(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@

package org.elasticsearch.painless.ir;

import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.phase.IRTreeVisitor;
import org.elasticsearch.painless.symbol.WriteScope;

Expand Down Expand Up @@ -75,11 +73,9 @@ public BlockNode(Location location) {
}

@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
protected void write(WriteScope writeScope) {
for (StatementNode statementNode : statementNodes) {
statementNode.continueLabel = continueLabel;
statementNode.breakLabel = breakLabel;
statementNode.write(classWriter, methodWriter, writeScope);
statementNode.write(writeScope);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.elasticsearch.painless.ir;

import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.Operation;
Expand Down Expand Up @@ -62,16 +61,17 @@ public BooleanNode(Location location) {
}

@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
protected void write(WriteScope writeScope) {
MethodWriter methodWriter = writeScope.getMethodWriter();
methodWriter.writeDebugInfo(getLocation());

if (operation == Operation.AND) {
Label fals = new Label();
Label end = new Label();

getLeftNode().write(classWriter, methodWriter, writeScope);
getLeftNode().write(writeScope);
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
getRightNode().write(classWriter, methodWriter, writeScope);
getRightNode().write(writeScope);
methodWriter.ifZCmp(Opcodes.IFEQ, fals);

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

getLeftNode().write(classWriter, methodWriter, writeScope);
getLeftNode().write(writeScope);
methodWriter.ifZCmp(Opcodes.IFNE, tru);
getRightNode().write(classWriter, methodWriter, writeScope);
getRightNode().write(writeScope);
methodWriter.ifZCmp(Opcodes.IFEQ, fals);

methodWriter.mark(tru);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.elasticsearch.painless.ir;

import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.phase.IRTreeVisitor;
Expand All @@ -46,7 +45,8 @@ public BreakNode(Location location) {
}

@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
methodWriter.goTo(breakLabel);
protected void write(WriteScope writeScope) {
MethodWriter methodWriter = writeScope.getMethodWriter();
methodWriter.goTo(writeScope.getBreakLabel());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.elasticsearch.painless.ir;

import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.lookup.PainlessCast;
Expand Down Expand Up @@ -59,8 +58,10 @@ public CastNode(Location location) {
}

@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
getChildNode().write(classWriter, methodWriter, writeScope);
protected void write(WriteScope writeScope) {
MethodWriter methodWriter = writeScope.getMethodWriter();

getChildNode().write(writeScope);
methodWriter.writeDebugInfo(getLocation());
methodWriter.writeCast(cast);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.elasticsearch.painless.ir;

import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.phase.IRTreeVisitor;
Expand Down Expand Up @@ -76,16 +75,13 @@ public <Scope> void visitChildren(IRTreeVisitor<Scope> irTreeVisitor, Scope scop

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

Label begin = null;
Label end = null;
Label exception = null;

public CatchNode(Location location) {
super(location);
}

@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
protected void write(WriteScope writeScope) {
MethodWriter methodWriter = writeScope.getMethodWriter();
methodWriter.writeStatementOffset(getLocation());

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

if (blockNode != null) {
blockNode.continueLabel = continueLabel;
blockNode.breakLabel = breakLabel;
blockNode.write(classWriter, methodWriter, writeScope);
blockNode.write(writeScope.newBlockScope(true));
}

methodWriter.visitTryCatchBlock(begin, end, jump, variable.getAsmType().getInternalName());
methodWriter.visitTryCatchBlock(
writeScope.getTryBeginLabel(), writeScope.getTryEndLabel(), jump, variable.getAsmType().getInternalName());

if (exception != null && (blockNode == null || blockNode.doAllEscape() == false)) {
methodWriter.goTo(exception);
if (writeScope.getCatchesEndLabel() != null && (blockNode == null || blockNode.doAllEscape() == false)) {
methodWriter.goTo(writeScope.getCatchesEndLabel());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public ClassNode(Location location) {
}

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

org.objectweb.asm.commons.Method init;

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

// Write all fields:
for (FieldNode fieldNode : fieldNodes) {
fieldNode.write(classWriter, null, null);
fieldNode.write(writeScope);
}

// Write all functions:
for (FunctionNode functionNode : functionNodes) {
functionNode.write(classWriter, null, new WriteScope());
functionNode.write(writeScope);
}

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

@Override
public void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
public void write(WriteScope writeScope) {
throw new UnsupportedOperationException("use write() instead");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.elasticsearch.painless.ir;

import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.DefBootstrap;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
Expand Down Expand Up @@ -81,13 +80,14 @@ public ComparisonNode(Location location) {
}

@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
protected void write(WriteScope writeScope) {
MethodWriter methodWriter = writeScope.getMethodWriter();
methodWriter.writeDebugInfo(getLocation());

getLeftNode().write(classWriter, methodWriter, writeScope);
getLeftNode().write(writeScope);

if (getRightNode() instanceof NullNode == false) {
getRightNode().write(classWriter, methodWriter, writeScope);
getRightNode().write(writeScope);
}

Label jump = new Label();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.elasticsearch.painless.ir;

import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.phase.IRTreeVisitor;
Expand Down Expand Up @@ -62,19 +61,20 @@ public ConditionalNode(Location location) {
}

@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
protected void write(WriteScope writeScope) {
MethodWriter methodWriter = writeScope.getMethodWriter();
methodWriter.writeDebugInfo(getLocation());

Label fals = new Label();
Label end = new Label();

conditionNode.write(classWriter, methodWriter, writeScope);
conditionNode.write(writeScope);
methodWriter.ifZCmp(Opcodes.IFEQ, fals);

getLeftNode().write(classWriter, methodWriter, writeScope);
getLeftNode().write(writeScope);
methodWriter.goTo(end);
methodWriter.mark(fals);
getRightNode().write(classWriter, methodWriter, writeScope);
getRightNode().write(writeScope);
methodWriter.mark(end);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.elasticsearch.painless.ir;

import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.phase.IRTreeVisitor;
Expand Down Expand Up @@ -58,7 +57,9 @@ public ConstantNode(Location location) {
}

@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
protected void write(WriteScope writeScope) {
MethodWriter methodWriter = writeScope.getMethodWriter();

if (constant instanceof String) methodWriter.push((String)constant);
else if (constant instanceof Double) methodWriter.push((double)constant);
else if (constant instanceof Float) methodWriter.push((float)constant);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.elasticsearch.painless.ir;

import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.phase.IRTreeVisitor;
Expand All @@ -46,7 +45,8 @@ public ContinueNode(Location location) {
}

@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
methodWriter.goTo(continueLabel);
protected void write(WriteScope writeScope) {
MethodWriter methodWriter = writeScope.getMethodWriter();
methodWriter.goTo(writeScope.getContinueLabel());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@

package org.elasticsearch.painless.ir;

import org.elasticsearch.painless.ClassWriter;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
import org.elasticsearch.painless.phase.IRTreeVisitor;
import org.elasticsearch.painless.symbol.WriteScope;

Expand Down Expand Up @@ -63,9 +61,9 @@ public DeclarationBlockNode(Location location) {
}

@Override
protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteScope writeScope) {
protected void write(WriteScope writeScope) {
for (DeclarationNode declarationNode : declarationNodes) {
declarationNode.write(classWriter, methodWriter, writeScope);
declarationNode.write(writeScope);
}
}
}
Loading

0 comments on commit 0aebb59

Please sign in to comment.