Skip to content

Commit

Permalink
Began implementing TrapTransformer
Browse files Browse the repository at this point in the history
  • Loading branch information
danielperano committed Nov 25, 2024
1 parent 4dd9637 commit 099b41a
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 4 deletions.
6 changes: 3 additions & 3 deletions Lang/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

plugins {
id 'maven-publish'
id 'org.asciidoctor.jvm.convert' version '3.1.0'
//id 'org.asciidoctor.jvm.convert' version '3.1.0'
}

apply plugin: 'java'
Expand Down Expand Up @@ -114,9 +114,9 @@ publishing {
}
}

asciidoctor {
/*asciidoctor {
sourceDir 'src/doc/asciidoc'
}
}*/

clean {
delete 'build'
Expand Down
4 changes: 4 additions & 0 deletions Lang/src/main/java/chipmunk/vm/ChipmunkScript.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ public TrapHandler getTrapHandler(){
return trapHandler != null ? trapHandler : vm.getDefaultTrapHandler();
}

public static TrapHandler getCurrentTrapHandler(){
return getCurrentScript().getTrapHandler();
}

public void setModuleLoader(ModuleLoader loader){
this.loader = loader;
}
Expand Down
92 changes: 91 additions & 1 deletion Lang/src/main/java/chipmunk/vm/jvm/TrapTransformer.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
package chipmunk.vm.jvm;

import chipmunk.vm.ChipmunkScript;
import chipmunk.vm.TrapHandler;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

import java.util.HashSet;
import java.util.Set;

public class TrapTransformer extends MethodVisitor {
public TrapTransformer(int api, final MethodVisitor delegate) {

protected final String methodName;
protected final Type declaringClass;
protected final Type methodDescriptor;
protected final Set<Label> alreadySeen;
protected int lineNumber;

public TrapTransformer(int api, final MethodVisitor delegate, String methodName, Type declaringClass, Type methodDescriptor) {
super(api, delegate);

this.methodName = methodName;
this.declaringClass = declaringClass;
this.methodDescriptor = methodDescriptor;

alreadySeen = new HashSet<>();
}

@Override
Expand All @@ -30,12 +50,82 @@ public void visitMethodInsn(

@Override
public void visitJumpInsn(final int opcode, final Label label){
if(alreadySeen.contains(label)){
// Backjump, emit trap call

emitGetTrapHandler();
emitTrapSite(TrapSite.Position.PRE);

super.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
Type.getInternalName(TrapHandler.class),
"backJump",
Type.getMethodType(Type.VOID_TYPE, Type.getType(TrapSite.class)).getDescriptor(),
true
);
}
}

@Override
public void visitLabel(final Label label){
alreadySeen.add(label);
}

@Override
public void visitLineNumber(int line, Label start) {
lineNumber = line;
super.visitLineNumber(line, start);
}

protected void emitGetTrapHandler() {
super.visitMethodInsn(
Opcodes.INVOKESTATIC,
Type.getInternalName(ChipmunkScript.class),
"getCurrentTrapHandler",
Type.getMethodType(Type.getType(TrapHandler.class)).getInternalName(),
false
);
}

protected void emitTrapSite(TrapSite.Position position){

// TODO - replace inline trapsite creation with constants (is indy applicable here?)
super.visitTypeInsn(Opcodes.NEW, Type.getInternalName(TrapSite.class));

super.visitFieldInsn(Opcodes.GETSTATIC,
Type.getInternalName(TrapSite.Position.class),
position.name(),
Type.getDescriptor(TrapSite.Position.class));

emitMethodIdentifier(declaringClass.getInternalName(), methodName, methodDescriptor);

super.visitLdcInsn(lineNumber);

super.visitMethodInsn(Opcodes.INVOKESPECIAL,
Type.getInternalName(TrapSite.class),
"<init>",
Type.getMethodType(Type.VOID_TYPE,
Type.getType(TrapSite.Position.class),
Type.getType(MethodIdentifier.class),
Type.getType(int.class))
.getDescriptor(),
false);
}

protected void emitMethodIdentifier(String cls, String methodName, Type methodDescriptor){
super.visitTypeInsn(Opcodes.NEW, Type.getType(MethodIdentifier.class).getInternalName());

super.visitLdcInsn(cls); // TODO - load class
super.visitLdcInsn(methodName);
super.visitLdcInsn(methodDescriptor.getDescriptor()); // TODO - load signature classes

super.visitMethodInsn(Opcodes.INVOKESPECIAL,
Type.getInternalName(MethodIdentifier.class),
"<init>",
Type.getMethodType(Type.VOID_TYPE,
Type.getType(Class.class),
Type.getType(String.class),
Type.getType(Class[].class))
.getDescriptor(),
false);
}
}

0 comments on commit 099b41a

Please sign in to comment.