Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
First pass at adding filename and linenumber annotations to generated…
… bytecode.
  • Loading branch information
donaldh committed May 14, 2013
1 parent 740258f commit de8c590
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
12 changes: 11 additions & 1 deletion src/vm/jvm/QAST/Compiler.nqp
@@ -1,5 +1,6 @@
use JASTNodes;
use QASTNode;
use NQPHLL;

# Instruction constants for argument-less ops.
my $ACONST_NULL := JAST::Instruction.new( :op('aconst_null') );
Expand Down Expand Up @@ -2825,12 +2826,15 @@ class QAST::CompilerJAST {
# Wrap $source in a QAST::Block if it's not already a viable root node.
$source := QAST::Block.new($source)
unless nqp::istype($source, QAST::CompUnit) || nqp::istype($source, QAST::Block);

my $file := nqp::getlexdyn('$?FILES');

# Set up a JAST::Class that will hold all the blocks (which become Java
# methods) that we shall compile.
my $*JCLASS := JAST::Class.new(
:name($classname),
:super('org.perl6.nqp.runtime.CompilationUnit')
:super('org.perl6.nqp.runtime.CompilationUnit'),
:filename($file)
);

# We'll also need to keep track of all the blocks we compile into Java
Expand Down Expand Up @@ -3488,6 +3492,12 @@ class QAST::CompilerJAST {
unless nqp::defined($resultchild) {
$resultchild := $n - 1;
}

if $node {
my $line := HLL::Compiler.lineof($node.orig(), $node.from(), :cache(1));
$il.append(JAST::Annotation.new( :line($line) ));
}

for @stmts {
my $void := $all_void || $i != $resultchild;
if $void {
Expand Down
19 changes: 18 additions & 1 deletion src/vm/jvm/QAST/JASTNodes.nqp
Expand Up @@ -4,12 +4,14 @@ class JAST::Node {
class JAST::Class is JAST::Node {
has str $!name;
has str $!super;
has str $!filename;
has @!methods;
has @!fields;

method BUILD(:$name!, :$super!) {
method BUILD(:$name!, :$super!, :$filename) {
$!name := $name;
$!super := $super;
$!filename := $filename;
@!methods := [];
@!fields := [];
}
Expand All @@ -30,6 +32,7 @@ class JAST::Class is JAST::Node {
my @dumped;
nqp::push(@dumped, "+ class $!name");
nqp::push(@dumped, "+ super $!super");
nqp::push(@dumped, "+ filename $!filename");
for @!fields {
nqp::push(@dumped, $_.dump());
}
Expand Down Expand Up @@ -355,6 +358,20 @@ class JAST::TryCatch is JAST::Node {
}
}

class JAST::Annotation is JAST::Node {
has int $!line;

method BUILD(:$line!) {
$!line := $line;
}

method line() { $!line }

method dump() {
".line $!line"
}
}

my %opmap := nqp::hash(
'nop', 0x00,
'aconst_null', 0x01,
Expand Down
14 changes: 12 additions & 2 deletions src/vm/jvm/runtime/org/perl6/nqp/jast2bc/JASTToJVMBytecode.java
Expand Up @@ -71,7 +71,7 @@ public static void writeClassFromString(String in, String filename) {
private static JavaClass buildClassFrom(BufferedReader in) throws Exception
{
// Read in class name, superclass and any fields.
String curLine, className = null, superName = null;
String curLine, className = null, superName = null, fileName = null;
List<String> fieldLines = new ArrayList<String>();
while ((curLine = in.readLine()) != null) {
if (curLine.startsWith("+ class ")) {
Expand All @@ -80,6 +80,9 @@ private static JavaClass buildClassFrom(BufferedReader in) throws Exception
else if (curLine.startsWith("+ super ")) {
superName = curLine.substring("+ super ".length());
}
else if (curLine.startsWith("+ filename ")) {
fileName = curLine.substring("+ filename ".length());
}
else if (curLine.startsWith("+ field ")) {
fieldLines.add(curLine.substring("+ field ".length()));
}
Expand All @@ -97,10 +100,11 @@ else if (curLine.equals("+ method")) {

className = className.replace('.', '/');
superName = superName.replace('.', '/');

ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, className, null,
superName, null);
cw.visitSource(fileName, null);

// Add the fields.
for (String field : fieldLines) {
Expand Down Expand Up @@ -279,6 +283,12 @@ else if (curLine.equals(".endtry")) {
tryStartStack.pop();
m.visitLabel(tryEndStack.pop());
}
else if (curLine.startsWith(".line ")) {
int lineNumber = Integer.parseInt(curLine.substring(".line ".length()), 10);
Label l = new Label();
m.visitLabel(l);
m.visitLineNumber(lineNumber, l);
}
else {
throw new Exception("Don't understand directive: " + curLine);
}
Expand Down

0 comments on commit de8c590

Please sign in to comment.