Skip to content

Commit 3326be2

Browse files
committed
Generate handler currently in invokeInternal.
1 parent a33f00e commit 3326be2

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

src/vm/jvm/QAST/Compiler.nqp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ my $TYPE_MHL := 'Ljava/lang/invoke/MethodHandles$Lookup;';
2222
my $TYPE_CLASS := 'Ljava/lang/Class;';
2323
my $TYPE_LONG := 'Ljava/lang/Long;';
2424
my $TYPE_DOUBLE := 'Ljava/lang/Double;';
25+
my $TYPE_EH := 'Lorg/perl6/nqp/runtime/ExceptionHandling;';
2526
my $TYPE_EX_LEX := 'Lorg/perl6/nqp/runtime/LexoticException;';
2627
my $TYPE_EX_UNWIND := 'Lorg/perl6/nqp/runtime/UnwindException;';
28+
my $TYPE_EX_CONT := 'Lorg/perl6/nqp/runtime/ControlException;';
29+
my $TYPE_EX_RT := 'Ljava/lang/RuntimeException;';
30+
my $TYPE_THROWABLE := 'Ljava/lang/Throwable;';
2731

2832
# Exception handler categories.
2933
my $EX_CAT_CATCH := 1;
@@ -2755,7 +2759,7 @@ class QAST::CompilerJAST {
27552759
# Stash lexical names.
27562760
$*CODEREFS.set_lexical_names($node.cuid, |$block.lexical_names_by_type());
27572761

2758-
# Emit prelude. This crates and stashes the CallFrame.
2762+
# Emit prelude. This creates and stashes the CallFrame.
27592763
$*JMETH.add_local('cf', $TYPE_CF);
27602764
$*JMETH.append(JAST::Instruction.new( :op('new'), $TYPE_CF ));
27612765
$*JMETH.append(JAST::Instruction.new( :op('dup') ));
@@ -2895,17 +2899,30 @@ class QAST::CompilerJAST {
28952899
$il.append(JAST::Instruction.new( :op('invokestatic'), $TYPE_OPS,
28962900
'return_' ~ typechar($body.type), 'Void', jtype($body.type), $TYPE_CF ));
28972901

2898-
# Keep the thread state in sync. Note, JVM doesn't do finally
2899-
# natively, so we just emit this in a catch as well as at the
2900-
# end before exit.
2901-
my $unwind := JAST::InstructionList.new();
2902-
for ($il, $unwind) {
2903-
$_.append(JAST::Instruction.new( :op('aload'), 'cf' ));
2904-
$_.append(JAST::Instruction.new( :op('invokevirtual'),
2905-
$TYPE_CF, 'leave', 'Void' ));
2906-
}
2907-
$unwind.append(JAST::Instruction.new( :op('athrow') ));
2908-
$*JMETH.append(JAST::TryCatch.new( :try($il), :catch($unwind), :type('') ));
2902+
# Emit the postlude. We catch any exceptions. Control ones are
2903+
# rethrown, after calling CallFrame.leave. Others are passed on to
2904+
# dieInternal. Finally, if there's no exception, we also need to
2905+
# call CallFrame.leave.
2906+
$il.append(JAST::Instruction.new( :op('aload'), 'cf' ));
2907+
$il.append(JAST::Instruction.new( :op('invokevirtual'),
2908+
$TYPE_CF, 'leave', 'Void' ));
2909+
my $posthan := JAST::InstructionList.new();
2910+
my $nclab := JAST::Label.new( :name('non_cont_ex') );
2911+
$posthan.append(JAST::Instruction.new( :op('dup') ));
2912+
$posthan.append(JAST::Instruction.new( :op('instanceof'), $TYPE_EX_CONT ));
2913+
$posthan.append(JAST::Instruction.new( :op('ifeq'), $nclab ));
2914+
$posthan.append(JAST::Instruction.new( :op('aload'), 'cf' ));
2915+
$posthan.append(JAST::Instruction.new( :op('invokevirtual'),
2916+
$TYPE_CF, 'leave', 'Void' ));
2917+
$posthan.append(JAST::Instruction.new( :op('athrow') ));
2918+
$posthan.append($nclab);
2919+
$posthan.append(JAST::Instruction.new( :op('aload_1') ));
2920+
$posthan.append(JAST::Instruction.new( :op('swap') ));
2921+
$posthan.append(JAST::Instruction.new( :op('invokestatic'),
2922+
$TYPE_EH, 'dieInternal', $TYPE_EX_RT, $TYPE_TC, $TYPE_THROWABLE ));
2923+
$posthan.append(JAST::Instruction.new( :op('athrow') ));
2924+
$*JMETH.append(JAST::TryCatch.new( :try($il), :catch($posthan),
2925+
:type($TYPE_THROWABLE) ));
29092926
$*JMETH.append(JAST::Instruction.new( :op('return') ));
29102927

29112928
# Finalize method and add it to the class.

src/vm/jvm/runtime/org/perl6/nqp/jast2bc/JASTToJVMBytecode.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,8 @@ else if (argIndexes.containsKey(rest))
610610
emitInvokeDynamic(m, rest);
611611
break;
612612
case 0xbb: // new
613+
case 0xc0: // checkcast
614+
case 0xc1: // instanceof
613615
Type t = processType(rest);
614616
m.visitTypeInsn(instruction, t.getInternalName());
615617
break;

0 commit comments

Comments
 (0)