Added method to allow creation of new methods on-the-fly.

This commit is contained in:
Jack Conradson 2016-06-07 11:24:33 -07:00
parent 32bd869b28
commit f9b45107c4
3 changed files with 17 additions and 18 deletions

View File

@ -23,6 +23,7 @@ import org.elasticsearch.painless.Definition.Cast;
import org.elasticsearch.painless.Definition.Sort;
import org.elasticsearch.painless.Definition.Type;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.GeneratorAdapter;
@ -87,30 +88,29 @@ import static org.elasticsearch.painless.WriterConstants.UTILITY_TYPE;
* shared by the nodes of the Painless tree.
*/
public final class MethodWriter extends GeneratorAdapter {
private final ClassWriter parent;
private final BitSet statements;
private final Deque<List<org.objectweb.asm.Type>> stringConcatArgs = (INDY_STRING_CONCAT_BOOTSTRAP_HANDLE == null) ?
null : new ArrayDeque<>();
MethodWriter(int access, Method method, org.objectweb.asm.Type[] exceptions, ClassVisitor cv, BitSet statements) {
super(Opcodes.ASM5, cv.visitMethod(access, method.getName(), method.getDescriptor(), null, getInternalNames(exceptions)),
MethodWriter(int access, Method method, ClassWriter cw, BitSet statements) {
super(Opcodes.ASM5, cw.visitMethod(access, method.getName(), method.getDescriptor(), null, null),
access, method.getName(), method.getDescriptor());
this.parent = cw;
this.statements = statements;
}
private static String[] getInternalNames(final org.objectweb.asm.Type[] types) {
if (types == null) {
return null;
}
String[] names = new String[types.length];
for (int i = 0; i < names.length; ++i) {
names[i] = types[i].getInternalName();
}
return names;
/**
* @return A new {@link MethodWriter} with the specified access and signature.
*/
MethodWriter newMethodWriter(int access, Method method) {
return new MethodWriter(access, method, parent, statements);
}
/**
* Marks a new statement boundary.
/**
* Marks a new statement boundary.
* <p>
* This is invoked for each statement boundary (leaf {@code S*} nodes).
*/
@ -122,7 +122,7 @@ public final class MethodWriter extends GeneratorAdapter {
statements.set(offset);
}
/**
/**
* Encodes the offset into the line number table as {@code offset + 1}.
* <p>
* This is invoked before instructions that can hit exceptions.

View File

@ -41,8 +41,7 @@ import java.util.BitSet;
final class Writer {
static byte[] write(CompilerSettings settings, String name, String source, Variables variables, SSource root, BitSet expressions) {
Writer writer = new Writer(settings, name, source, variables, root, expressions);
return writer.getBytes();
return new Writer(settings, name, source, variables, root, expressions).getBytes();
}
private final CompilerSettings settings;
@ -66,7 +65,7 @@ final class Writer {
writeBegin();
writeConstructor();
adapter = new MethodWriter(Opcodes.ACC_PUBLIC, EXECUTE, null, writer, expressions);
adapter = new MethodWriter(Opcodes.ACC_PUBLIC, EXECUTE, writer, expressions);
writeExecute();
writeEnd();

View File

@ -143,7 +143,7 @@ public final class WriterConstants {
public final static Method CHECKEQUALS = getAsmMethod(boolean.class, "checkEquals", Object.class, Object.class);
private static Method getAsmMethod(final Class<?> rtype, final String name, final Class<?>... ptypes) {
public static Method getAsmMethod(final Class<?> rtype, final String name, final Class<?>... ptypes) {
return new Method(name, MethodType.methodType(rtype, ptypes).toMethodDescriptorString());
}