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.Sort;
import org.elasticsearch.painless.Definition.Type; import org.elasticsearch.painless.Definition.Type;
import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.GeneratorAdapter; import org.objectweb.asm.commons.GeneratorAdapter;
@ -87,26 +88,25 @@ import static org.elasticsearch.painless.WriterConstants.UTILITY_TYPE;
* shared by the nodes of the Painless tree. * shared by the nodes of the Painless tree.
*/ */
public final class MethodWriter extends GeneratorAdapter { public final class MethodWriter extends GeneratorAdapter {
private final ClassWriter parent;
private final BitSet statements; private final BitSet statements;
private final Deque<List<org.objectweb.asm.Type>> stringConcatArgs = (INDY_STRING_CONCAT_BOOTSTRAP_HANDLE == null) ? private final Deque<List<org.objectweb.asm.Type>> stringConcatArgs = (INDY_STRING_CONCAT_BOOTSTRAP_HANDLE == null) ?
null : new ArrayDeque<>(); null : new ArrayDeque<>();
MethodWriter(int access, Method method, org.objectweb.asm.Type[] exceptions, ClassVisitor cv, BitSet statements) { MethodWriter(int access, Method method, ClassWriter cw, BitSet statements) {
super(Opcodes.ASM5, cv.visitMethod(access, method.getName(), method.getDescriptor(), null, getInternalNames(exceptions)), super(Opcodes.ASM5, cw.visitMethod(access, method.getName(), method.getDescriptor(), null, null),
access, method.getName(), method.getDescriptor()); access, method.getName(), method.getDescriptor());
this.parent = cw;
this.statements = statements; this.statements = statements;
} }
private static String[] getInternalNames(final org.objectweb.asm.Type[] types) { /**
if (types == null) { * @return A new {@link MethodWriter} with the specified access and signature.
return null; */
} MethodWriter newMethodWriter(int access, Method method) {
String[] names = new String[types.length]; return new MethodWriter(access, method, parent, statements);
for (int i = 0; i < names.length; ++i) {
names[i] = types[i].getInternalName();
}
return names;
} }
/** /**

View File

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

View File

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