Skip to content

Instantly share code, notes, and snippets.

@MasterDuke17
Last active November 20, 2016 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MasterDuke17/6a9848f5b19e4d4d52ac6fe191617fe1 to your computer and use it in GitHub Desktop.
Save MasterDuke17/6a9848f5b19e4d4d52ac6fe191617fe1 to your computer and use it in GitHub Desktop.
nqp jvm line directive support
diff --git a/src/vm/jvm/QAST/Compiler.nqp b/src/vm/jvm/QAST/Compiler.nqp
index af9361c..a2e04ae 100644
--- a/src/vm/jvm/QAST/Compiler.nqp
+++ b/src/vm/jvm/QAST/Compiler.nqp
@@ -4192,8 +4192,10 @@ class QAST::CompilerJAST {
for @stmts {
if $_.node && nqp::can($_.node,'orig') {
my $node := $_.node;
- my $line := HLL::Compiler.lineof($node.orig(), $node.from(), :cache(1));
- $il.append(JAST::Annotation.new( :line($line) ));
+ my @line_file := HLL::Compiler.linefileof($node.orig(), $node.from(), :cache(1), :directives(1));
+ my $line := @line_file[0];
+ my $file := @line_file[1] || $*JCLASS.filename();
+ $il.append(JAST::Annotation.new( :$line, :$file ));
}
my $void := $all_void || $i != $resultchild;
diff --git a/src/vm/jvm/QAST/JASTNodes.nqp b/src/vm/jvm/QAST/JASTNodes.nqp
index f448db0..2d33d57 100644
--- a/src/vm/jvm/QAST/JASTNodes.nqp
+++ b/src/vm/jvm/QAST/JASTNodes.nqp
@@ -29,6 +29,7 @@ class JAST::Class is JAST::Node {
method super(*@value) { @value ?? ($!super := @value[0]) !! $!super }
method serialized(*@value) { @value ?? ($!serialized := @value[0]) !! $!serialized }
method methods() { @!methods }
+ method filename() { $!filename }
method dump() {
my @dumped;
@@ -390,15 +391,20 @@ class JAST::TryCatch is JAST::Node {
class JAST::Annotation is JAST::Node {
has int $!line;
+ has str $!file;
- method BUILD(:$line!) {
+ method BUILD(:$line!, :$file!) {
$!line := $line;
+ $!file := $file;
}
method line() { $!line }
+
+ method file() { $!file }
method dump(@dumped) {
- nqp::push(@dumped, ".line $!line")
+ nqp::push(@dumped, ".line $!line");
+ nqp::push(@dumped, ".file $!file");
}
}
diff --git a/src/vm/jvm/runtime/org/perl6/nqp/jast2bc/JASTCompiler.java b/src/vm/jvm/runtime/org/perl6/nqp/jast2bc/JASTCompiler.java
index 750ee30..1f3349b 100644
--- a/src/vm/jvm/runtime/org/perl6/nqp/jast2bc/JASTCompiler.java
+++ b/src/vm/jvm/runtime/org/perl6/nqp/jast2bc/JASTCompiler.java
@@ -26,6 +26,7 @@ import org.perl6.nqp.runtime.ThreadContext;
import org.perl6.nqp.sixmodel.SixModelObject;
+
public class JASTCompiler {
public static JavaClass buildClass(SixModelObject jast, SixModelObject jastNodes, boolean split, ThreadContext tc) {
try {
@@ -288,6 +289,8 @@ public class JASTCompiler {
m.visitLabel(afterCatch);
}
else if (istype(insn, jastAnnotation, tc) != 0) {
+ String file = getattr_s(insn, jastAnnotation, "$!file", 1, tc);
+ m.visitAttribute(new SourceFilenameAttribute(file));
int line = (int) getattr_i(insn, jastAnnotation, "$!line", 0, tc);
Label l = new Label();
m.visitLabel(l);
diff --git a/src/vm/jvm/runtime/org/perl6/nqp/runtime/ExceptionHandling.java b/src/vm/jvm/runtime/org/perl6/nqp/runtime/ExceptionHandling.java
index 5ce7431..6e7b4af 100644
--- a/src/vm/jvm/runtime/org/perl6/nqp/runtime/ExceptionHandling.java
+++ b/src/vm/jvm/runtime/org/perl6/nqp/runtime/ExceptionHandling.java
@@ -6,6 +6,16 @@ import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.List;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Attribute;
+
+import org.perl6.nqp.jast2bc.SourceFilenameAttribute;
+
import org.perl6.nqp.sixmodel.SixModelObject;
import org.perl6.nqp.sixmodel.reprs.VMExceptionInstance;
@@ -307,17 +317,56 @@ all:
while (ncursor != null) {
StaticCodeInfo info = ncursor.codeRef.staticInfo;
String kls = info.compUnit.getClass().getName();
- String method = info.methodName;
+ final String method = info.methodName;
+ final Holder filename = new Holder(null);
while (jcursor < ex.nativeTrace.length && !kls.equals(ex.nativeTrace[jcursor].getClassName()) &&
(method == null || !method.equals(ex.nativeTrace[jcursor].getMethodName())))
jcursor++;
StackTraceElement el = jcursor < ex.nativeTrace.length ? ex.nativeTrace[jcursor++] : null;
+ try {
+ if (el != null && el.getFileName().equals("gen/jvm/CORE.setting")) {
+ new ClassReader(kls).accept(
+ new ClassVisitor(Opcodes.ASM4) {
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+ if (!name.equals(method)) {
+ return null;
+ }
+ return new MethodVisitor(Opcodes.ASM4) {
+ @Override
+ public void visitAttribute(Attribute attr) {
+ filename.setValue(attr.type);
+ }
+ };
+ }
+ },
+ 0);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
- result.add(new TraceElement(ncursor, el != null ? el.getFileName() : null, el != null ? el.getLineNumber() : -1));
+ result.add(new TraceElement(ncursor, filename.value != null ? filename.value : el != null ? el.getFileName() : null, el != null ? el.getLineNumber() : -1));
ncursor = ncursor.caller;
}
return result;
}
+
+ static class Holder {
+ private String value;
+
+ Holder(String value) {
+ setValue(value);
+ }
+
+ String getValue() {
+ return value;
+ }
+
+ void setValue(String value) {
+ this.value = value;
+ }
+ }
}
package org.perl6.nqp.jast2bc;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.ByteVector;
import org.objectweb.asm.Label;
public class SourceFilenameAttribute extends Attribute {
public String file;
public SourceFilenameAttribute(String f) {
super(f);
this.file = f;
}
public String getFile() {
return file;
}
@Override
public boolean isUnknown() {
return false;
}
@Override
public boolean isCodeAttribute() {
return false;
}
@Override
protected Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) {
return new SourceFilenameAttribute(cr.readUTF8(off, buf));
}
@Override
protected ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
return new ByteVector().putShort(cw.newUTF8(file));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment