Skip to content

Instantly share code, notes, and snippets.

@Deamon5550
Created October 14, 2014 21:10
Show Gist options
  • Save Deamon5550/5685a5f75378b19f3050 to your computer and use it in GitHub Desktop.
Save Deamon5550/5685a5f75378b19f3050 to your computer and use it in GitHub Desktop.
package com.thevoxelbox.node;
public class ASMClassLoader extends ClassLoader
{
public Class defineClass(String name, byte[] b)
{
return defineClass(name, b, 0, b.length);
}
}
package com.thevoxelbox.node;
public class Main
{
public static void main(String[] args) throws Exception
{
VariableScope scope = new VariableScope();
scope.set("body", "Hello ");
StringValueNode in = new StringValueNode("Hello World", IOType.STRING);
PrintNode print = new PrintNode();
print.mapInput("msg", in.getOutput("value"));
NodeTree tree = new NodeTree();
tree.setStartNode(print);
tree.compile();
tree.run(scope);
}
}
package com.thevoxelbox.node;
import java.util.HashMap;
import java.util.Map;
import org.objectweb.asm.MethodVisitor;
/**
* @author Owner-58
*
*/
public abstract class Node
{
Map<String, NodeOutput> outputs = new HashMap<String, NodeOutput>();
Map<String, NodeInput> inputs = new HashMap<String, NodeInput>();
public boolean isExecutable()
{
return false;
}
public void mapInput(String in, NodeOutput out)
{
if(!inputs.containsKey(in)) return;
inputs.get(in).setSource(out);
}
public void addInput(String name, IOType t)
{
inputs.put(name, new NodeInput(name, t));
}
public void addOutput(String name, IOType t, Node p)
{
outputs.put(name, new NodeOutput(name, t, p));
}
public void setOutput(String name, int loc)
{
outputs.get(name).set(loc);
}
public NodeInput getInput(String n)
{
return inputs.get(n);
}
public NodeOutput getOutput(String n)
{
return outputs.get(n);
}
public int insert(MethodVisitor mv, int i)
{
int init = i;
for(String n: inputs.keySet())
{
if(inputs.get(n).getSource().get() == -1)
{
init = inputs.get(n).getSource().getParent().insert(mv, init);
}
}
return insert_(mv, i);
}
protected abstract int insert_(MethodVisitor mv, int i);
}
class NodeInput
{
String name;
IOType type;
NodeOutput out;
public NodeInput(String n, IOType t)
{
this.name = n;
this.type = t;
}
public void setSource(NodeOutput o)
{
this.out = o;
}
public NodeOutput getSource()
{
return this.out;
}
}
class NodeOutput
{
int i = -1;
String name;
IOType type;
Node parent;
public NodeOutput(String n, IOType t, Node parent)
{
this.name = n;
this.type = t;
this.parent = parent;
}
public Node getParent()
{
return this.parent;
}
public void set(int i)
{
this.i = i;
}
public int get()
{
return this.i;
}
}
package com.thevoxelbox.node;
import java.lang.reflect.InvocationTargetException;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class NodeTree implements Opcodes
{
ExecutableNode start = null;
ASMClassLoader cl = new ASMClassLoader();
Class<?> compiled = null;
public void setStartNode(ExecutableNode node)
{
this.start = node;
}
public void compile()
{
compiled = cl.defineClass("com.thevoxelbox.node.ASMTestTree", compile_());
}
public void clear()
{
compiled = null;
cl = null;
}
private byte[] compile_()
{
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
FieldVisitor fv;
MethodVisitor mv;
AnnotationVisitor av0;
cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, "com/thevoxelbox/node/ASMTestTree", null, "java/lang/Object", null);
cw.visitSource("ASMTestTree.java", null);
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "run", "(Lcom/thevoxelbox/node/VariableScope;)V", null, null);
mv.visitCode();
start.insert(mv, 2);
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
public void run(VariableScope scope)
{
if(compiled == null) compile();
try
{
Object tree = compiled.newInstance();
compiled.getMethod("run", VariableScope.class).invoke(tree, scope);
} catch (InstantiationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.thevoxelbox.node;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class PrintNode extends ExecutableNode
{
public PrintNode()
{
addInput("msg", IOType.STRING);
}
@Override
public int insert_(MethodVisitor mv, int i)
{
int msg_i = getInput("msg").getSource().get();
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitVarInsn(Opcodes.ALOAD, msg_i);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
return i;
}
}
package com.thevoxelbox.node;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class StringValueNode extends Node
{
String value;
public StringValueNode(String value, IOType t)
{
this.value = value;
addOutput("value", t, this);
}
@Override
public int insert_(MethodVisitor mv, int i)
{
mv.visitLdcInsn(value.toString());
mv.visitVarInsn(Opcodes.ASTORE, i);
setOutput("value", i);
return i+1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment