Modify Painless AST to add synthetic functions during semantic pass (#47611)
This has ELambda and ENewArrayFunctionRef add their generated synthetic methods to the SClass node during the semantic pass and removes this data from the write pass. This is the first step to remove "Globals" (mutable state) from the write pass.
This commit is contained in:
parent
176ca13c57
commit
833ed30f0d
|
@ -19,8 +19,6 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless;
|
package org.elasticsearch.painless;
|
||||||
|
|
||||||
import org.elasticsearch.painless.node.SFunction;
|
|
||||||
|
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -29,7 +27,6 @@ import java.util.Map;
|
||||||
* Program-wide globals (initializers, synthetic methods, etc)
|
* Program-wide globals (initializers, synthetic methods, etc)
|
||||||
*/
|
*/
|
||||||
public class Globals {
|
public class Globals {
|
||||||
private final Map<String,SFunction> syntheticMethods = new HashMap<>();
|
|
||||||
private final Map<String,Constant> constantInitializers = new HashMap<>();
|
private final Map<String,Constant> constantInitializers = new HashMap<>();
|
||||||
private final Map<String,Class<?>> classBindings = new HashMap<>();
|
private final Map<String,Class<?>> classBindings = new HashMap<>();
|
||||||
private final Map<Object,String> instanceBindings = new HashMap<>();
|
private final Map<Object,String> instanceBindings = new HashMap<>();
|
||||||
|
@ -40,16 +37,6 @@ public class Globals {
|
||||||
this.statements = statements;
|
this.statements = statements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a new synthetic method to be written. It must be analyzed! */
|
|
||||||
public void addSyntheticMethod(SFunction function) {
|
|
||||||
if (!function.synthetic) {
|
|
||||||
throw new IllegalStateException("method: " + function.name + " is not synthetic");
|
|
||||||
}
|
|
||||||
if (syntheticMethods.put(function.name, function) != null) {
|
|
||||||
throw new IllegalStateException("synthetic method: " + function.name + " already exists");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds a new constant initializer to be written */
|
/** Adds a new constant initializer to be written */
|
||||||
public void addConstantInitializer(Constant constant) {
|
public void addConstantInitializer(Constant constant) {
|
||||||
if (constantInitializers.put(constant.name, constant) != null) {
|
if (constantInitializers.put(constant.name, constant) != null) {
|
||||||
|
@ -70,11 +57,6 @@ public class Globals {
|
||||||
return instanceBindings.computeIfAbsent(instance, key -> "$instance_binding$" + instanceBindings.size());
|
return instanceBindings.computeIfAbsent(instance, key -> "$instance_binding$" + instanceBindings.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the current synthetic methods */
|
|
||||||
public Map<String,SFunction> getSyntheticMethods() {
|
|
||||||
return syntheticMethods;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the current initializers */
|
/** Returns the current initializers */
|
||||||
public Map<String,Constant> getConstantInitializers() {
|
public Map<String,Constant> getConstantInitializers() {
|
||||||
return constantInitializers;
|
return constantInitializers;
|
||||||
|
|
|
@ -22,9 +22,9 @@ package org.elasticsearch.painless.node;
|
||||||
import org.elasticsearch.painless.AnalyzerCaster;
|
import org.elasticsearch.painless.AnalyzerCaster;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessCast;
|
import org.elasticsearch.painless.lookup.PainlessCast;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,9 @@ import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.Operation;
|
import org.elasticsearch.painless.Operation;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessCast;
|
import org.elasticsearch.painless.lookup.PainlessCast;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
@ -28,10 +28,10 @@ import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.Operation;
|
import org.elasticsearch.painless.Operation;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.WriterConstants;
|
import org.elasticsearch.painless.WriterConstants;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
|
@ -25,10 +25,10 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessClassBinding;
|
import org.elasticsearch.painless.lookup.PainlessClassBinding;
|
||||||
import org.elasticsearch.painless.lookup.PainlessInstanceBinding;
|
import org.elasticsearch.painless.lookup.PainlessInstanceBinding;
|
||||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
|
@ -28,9 +28,9 @@ import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Locals.Variable;
|
import org.elasticsearch.painless.Locals.Variable;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,9 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessCast;
|
import org.elasticsearch.painless.lookup.PainlessCast;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
|
@ -28,9 +28,9 @@ import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.Operation;
|
import org.elasticsearch.painless.Operation;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,8 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
|
@ -27,10 +27,10 @@ import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Locals.Variable;
|
import org.elasticsearch.painless.Locals.Variable;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -185,6 +185,7 @@ public final class ELambda extends AExpression implements ILambda {
|
||||||
desugared.analyze(scriptRoot, Locals.newLambdaScope(locals.getProgramScope(), desugared.name, returnType,
|
desugared.analyze(scriptRoot, Locals.newLambdaScope(locals.getProgramScope(), desugared.name, returnType,
|
||||||
desugared.parameters, captures.size(), settings.getMaxLoopCounter()));
|
desugared.parameters, captures.size(), settings.getMaxLoopCounter()));
|
||||||
scriptRoot.getFunctionTable().addFunction(desugared.name, desugared.returnType, desugared.typeParameters, true);
|
scriptRoot.getFunctionTable().addFunction(desugared.name, desugared.returnType, desugared.typeParameters, true);
|
||||||
|
scriptRoot.getClassNode().addFunction(desugared);
|
||||||
|
|
||||||
// setup method reference to synthetic method
|
// setup method reference to synthetic method
|
||||||
if (expected == null) {
|
if (expected == null) {
|
||||||
|
@ -219,9 +220,6 @@ public final class ELambda extends AExpression implements ILambda {
|
||||||
methodWriter.visitVarInsn(MethodWriter.getType(capture.clazz).getOpcode(Opcodes.ILOAD), capture.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(capture.clazz).getOpcode(Opcodes.ILOAD), capture.getSlot());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add synthetic method to the queue to be written
|
|
||||||
globals.addSyntheticMethod(desugared);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,10 +25,10 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessConstructor;
|
import org.elasticsearch.painless.lookup.PainlessConstructor;
|
||||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.Method;
|
import org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,10 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessConstructor;
|
import org.elasticsearch.painless.lookup.PainlessConstructor;
|
||||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.Method;
|
import org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ public final class ENewArrayFunctionRef extends AExpression implements ILambda {
|
||||||
function.analyze(scriptRoot, Locals.newLambdaScope(locals.getProgramScope(), function.name, function.returnType,
|
function.analyze(scriptRoot, Locals.newLambdaScope(locals.getProgramScope(), function.name, function.returnType,
|
||||||
function.parameters, 0, settings.getMaxLoopCounter()));
|
function.parameters, 0, settings.getMaxLoopCounter()));
|
||||||
scriptRoot.getFunctionTable().addFunction(function.name, function.returnType, function.typeParameters, true);
|
scriptRoot.getFunctionTable().addFunction(function.name, function.returnType, function.typeParameters, true);
|
||||||
|
scriptRoot.getClassNode().addFunction(function);
|
||||||
|
|
||||||
if (expected == null) {
|
if (expected == null) {
|
||||||
ref = null;
|
ref = null;
|
||||||
|
@ -97,8 +98,6 @@ public final class ENewArrayFunctionRef extends AExpression implements ILambda {
|
||||||
// push a null instruction as a placeholder for future lambda instructions
|
// push a null instruction as a placeholder for future lambda instructions
|
||||||
methodWriter.push((String)null);
|
methodWriter.push((String)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
globals.addSyntheticMethod(function);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,9 +25,9 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessConstructor;
|
import org.elasticsearch.painless.lookup.PainlessConstructor;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.Method;
|
import org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,8 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
|
@ -26,8 +26,8 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.WriterConstants;
|
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
|
import org.elasticsearch.painless.WriterConstants;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
|
@ -28,9 +28,9 @@ import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.Operation;
|
import org.elasticsearch.painless.Operation;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
|
@ -25,9 +25,9 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
|
@ -25,9 +25,9 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
|
@ -25,11 +25,11 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessField;
|
import org.elasticsearch.painless.lookup.PainlessField;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
|
@ -25,8 +25,8 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
|
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
|
@ -26,8 +26,8 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
|
|
@ -26,8 +26,8 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
|
|
@ -26,8 +26,8 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
|
import org.elasticsearch.painless.lookup.def;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
|
@ -25,9 +25,9 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessField;
|
import org.elasticsearch.painless.lookup.PainlessField;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
|
|
@ -25,10 +25,10 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.WriterConstants;
|
import org.elasticsearch.painless.WriterConstants;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
|
@ -25,9 +25,9 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
|
@ -25,8 +25,8 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
|
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,9 @@ import org.elasticsearch.painless.Locals.Variable;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.ScriptClassInfo;
|
import org.elasticsearch.painless.ScriptClassInfo;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.WriterConstants;
|
import org.elasticsearch.painless.WriterConstants;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookup;
|
import org.elasticsearch.painless.lookup.PainlessLookup;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.elasticsearch.painless.symbol.FunctionTable;
|
import org.elasticsearch.painless.symbol.FunctionTable;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
|
@ -82,7 +82,7 @@ public final class SClass extends AStatement {
|
||||||
private final ScriptClassInfo scriptClassInfo;
|
private final ScriptClassInfo scriptClassInfo;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final Printer debugStream;
|
private final Printer debugStream;
|
||||||
private final List<SFunction> functions;
|
private final List<SFunction> functions = new ArrayList<>();
|
||||||
private final Globals globals;
|
private final Globals globals;
|
||||||
private final List<AStatement> statements;
|
private final List<AStatement> statements;
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ public final class SClass extends AStatement {
|
||||||
this.scriptClassInfo = Objects.requireNonNull(scriptClassInfo);
|
this.scriptClassInfo = Objects.requireNonNull(scriptClassInfo);
|
||||||
this.name = Objects.requireNonNull(name);
|
this.name = Objects.requireNonNull(name);
|
||||||
this.debugStream = debugStream;
|
this.debugStream = debugStream;
|
||||||
this.functions = Collections.unmodifiableList(functions);
|
this.functions.addAll(Objects.requireNonNull(functions));
|
||||||
this.statements = Collections.unmodifiableList(statements);
|
this.statements = Collections.unmodifiableList(statements);
|
||||||
this.globals = new Globals(new BitSet(sourceText.length()));
|
this.globals = new Globals(new BitSet(sourceText.length()));
|
||||||
|
|
||||||
|
@ -108,6 +108,10 @@ public final class SClass extends AStatement {
|
||||||
this.getMethods = new ArrayList<>();
|
this.getMethods = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addFunction(SFunction function) {
|
||||||
|
functions.add(function);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void storeSettings(CompilerSettings settings) {
|
public void storeSettings(CompilerSettings settings) {
|
||||||
for (SFunction function : functions) {
|
for (SFunction function : functions) {
|
||||||
|
@ -155,7 +159,11 @@ public final class SClass extends AStatement {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void analyze(ScriptRoot scriptRoot, Locals program) {
|
void analyze(ScriptRoot scriptRoot, Locals program) {
|
||||||
for (SFunction function : this.functions) {
|
// copy protection is required because synthetic functions are
|
||||||
|
// added for lambdas/method references and analysis here is
|
||||||
|
// only for user-defined functions
|
||||||
|
List<SFunction> functions = new ArrayList<>(this.functions);
|
||||||
|
for (SFunction function : functions) {
|
||||||
Locals functionLocals =
|
Locals functionLocals =
|
||||||
Locals.newFunctionScope(program, function.returnType, function.parameters, settings.getMaxLoopCounter());
|
Locals.newFunctionScope(program, function.returnType, function.parameters, settings.getMaxLoopCounter());
|
||||||
function.analyze(scriptRoot, functionLocals);
|
function.analyze(scriptRoot, functionLocals);
|
||||||
|
@ -281,15 +289,6 @@ public final class SClass extends AStatement {
|
||||||
function.write(classWriter, globals);
|
function.write(classWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write all synthetic functions. Note that this process may add more :)
|
|
||||||
while (!globals.getSyntheticMethods().isEmpty()) {
|
|
||||||
List<SFunction> current = new ArrayList<>(globals.getSyntheticMethods().values());
|
|
||||||
globals.getSyntheticMethods().clear();
|
|
||||||
for (SFunction function : current) {
|
|
||||||
function.write(classWriter, globals);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the constants
|
// Write the constants
|
||||||
if (false == globals.getConstantInitializers().isEmpty()) {
|
if (false == globals.getConstantInitializers().isEmpty()) {
|
||||||
Collection<Constant> inits = globals.getConstantInitializers().values();
|
Collection<Constant> inits = globals.getConstantInitializers().values();
|
||||||
|
|
|
@ -26,9 +26,9 @@ import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Locals.Variable;
|
import org.elasticsearch.painless.Locals.Variable;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
|
@ -27,9 +27,9 @@ import org.elasticsearch.painless.Locals.Parameter;
|
||||||
import org.elasticsearch.painless.Locals.Variable;
|
import org.elasticsearch.painless.Locals.Variable;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookup;
|
import org.elasticsearch.painless.lookup.PainlessLookup;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
|
|
|
@ -25,8 +25,8 @@ import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,9 @@ import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Locals.Variable;
|
import org.elasticsearch.painless.Locals.Variable;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessCast;
|
import org.elasticsearch.painless.lookup.PainlessCast;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
|
|
@ -28,11 +28,11 @@ import org.elasticsearch.painless.Locals;
|
||||||
import org.elasticsearch.painless.Locals.Variable;
|
import org.elasticsearch.painless.Locals.Variable;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
|
import org.elasticsearch.painless.ScriptRoot;
|
||||||
import org.elasticsearch.painless.lookup.PainlessCast;
|
import org.elasticsearch.painless.lookup.PainlessCast;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.elasticsearch.painless.lookup.PainlessMethod;
|
import org.elasticsearch.painless.lookup.PainlessMethod;
|
||||||
import org.elasticsearch.painless.lookup.def;
|
import org.elasticsearch.painless.lookup.def;
|
||||||
import org.elasticsearch.painless.ScriptRoot;
|
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue