Skip to content

Commit

Permalink
Fix the code gen for try with resources
Browse files Browse the repository at this point in the history
  • Loading branch information
Gene Gleyzer committed Jul 5, 2024
1 parent 1d059dc commit 0486e50
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 56 deletions.
18 changes: 14 additions & 4 deletions javatools/src/main/java/org/xvm/compiler/ast/TryStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -356,15 +356,15 @@ protected boolean emit(Context ctx, boolean fReachable, Code code, ErrorListener
BinaryAST astBlock;

// using() or try()-with-resources
FinallyStart[] aFinallyClose = null;
FinallyStart[] aFinallyStart = null;
if (resources != null)
{
// the first resource is declared outside of any try/finally block, but it is not
// visible beyond this statement
code.add(new Enter());

int c = resources.size();
aFinallyClose = new FinallyStart[c];
aFinallyStart = new FinallyStart[c];
aAstResources = new ExprAST[c];
for (int i = 0; i < c; ++i)
{
Expand All @@ -373,7 +373,7 @@ protected boolean emit(Context ctx, boolean fReachable, Code code, ErrorListener
aAstResources[i] = (ExprAST) holder.getAst(stmt);

FinallyStart opFinally = new FinallyStart(code.createRegister(pool.typeException१()));
aFinallyClose[i] = opFinally;
aFinallyStart[i] = opFinally;
code.add(new GuardAll(opFinally));
}
}
Expand All @@ -390,6 +390,11 @@ protected boolean emit(Context ctx, boolean fReachable, Code code, ErrorListener
labelCatchEnd = new Label();
code.add(new GuardAll(opFinallyBlock));
}
else if (resources != null)
{
// resources without "finally" add their own "FinallyStart" ops
labelCatchEnd = new Label();
}

// try..catch
RegAllocAST[] aAllocCatch = null;
Expand Down Expand Up @@ -471,12 +476,17 @@ protected boolean emit(Context ctx, boolean fReachable, Code code, ErrorListener
// skip_throw: CATCH_E
// FINALLY_E
// EXIT
if (catchall == null)
{
code.add(labelCatchEnd);
}

TypeConstant typeCloseable = pool.typeCloseable();
MethodConstant methodClose = typeCloseable.ensureTypeInfo(errs)
.findMethods("close", 1, MethodKind.Method).iterator().next();
for (int i = resources.size() - 1; i >= 0; --i)
{
code.add(aFinallyClose[i]);
code.add(aFinallyStart[i]);
Register regException = code.lastRegister();

Register regCatch = code.createRegister(pool.typeException());
Expand Down
55 changes: 9 additions & 46 deletions manualTests/src/main/x/TestSimple.x
Original file line number Diff line number Diff line change
@@ -1,54 +1,17 @@
// this test is a copy of not-yet submitted tck test "clazz/Medium.x" which failed to compile

module TestSimple {
@Inject Console console;

void run(String[] args=[""]) {
incorp();
void run() {
// this test used to fail to call Resource.close();
try (val t = new Resource(1)) {
throw new Exception();
} catch (Exception e) {}
}

mixin MixIn<Element> into Base1<Element> | Base2<Element> {
class Resource(Int t) implements Closeable {
@Override
String add(Element e) = $"MX[{e=} " + super(e) + " ]MX";
}

class Super1<Element> {
String add(Element e) = $"S[{e=}]S";
}
class Base1<Element> extends Super1<Element> incorporates MixIn<Element> {
@Override String add(Element e) = $"B[{e=} " + super(e) + " ]B";
}
class Derived1<Element> extends Base1<Element> {
@Override String add(Element e) = $"D[{e=} " + super(e) + " ]D";
}
class Super2<Element> {
String add(Element e) = $"s[{e=}]s";
}
class Base2<Element> extends Super2<Element> incorporates MixIn<Element> {
@Override String add(Element e) = $"b[{e=} " + super(e) + " ]b";
}
class Derived2<Element> extends Base2<Element> {
@Override String add(Element e) = $"d[{e=} " + super(e) + " ]d";
}
void incorp() {
String baseint1 = new Base1 < Int >().add( 123 );
String basestr1 = new Base1 <String>().add("abc");
String dervint1 = new Derived1< Int >().add( 123 );
String dervstr1 = new Derived1<String>().add("abc");
assert baseint1 == "B[e=123 MX[e=123 S[e=123]S ]MX ]B" ;
assert basestr1 == "B[e=abc MX[e=abc S[e=abc]S ]MX ]B" ;
assert dervint1 == "D[e=123 B[e=123 MX[e=123 S[e=123]S ]MX ]B ]D";
assert dervstr1 == "D[e=abc B[e=abc MX[e=abc S[e=abc]S ]MX ]B ]D";
String baseint2 = new Base2 < Int >().add( 123 );
String basestr2 = new Base2 <String>().add("abc");
String dervint2 = new Derived2< Int >().add( 123 );
String dervstr2 = new Derived2<String>().add("abc");
assert baseint2 == "b[e=123 MX[e=123 s[e=123]s ]MX ]b" ;
assert basestr2 == "b[e=abc MX[e=abc s[e=abc]s ]MX ]b" ;
assert dervint2 == "d[e=123 b[e=123 MX[e=123 s[e=123]s ]MX ]b ]d";
assert dervstr2 == "d[e=abc b[e=abc MX[e=abc s[e=abc]s ]MX ]b ]d";
void close(Exception? e = Null) {
console.print($"close {t}");
}
}
}
12 changes: 6 additions & 6 deletions manualTests/src/main/x/exceptions.x
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ module TestTry {

try {
testThrow();
console.print("DIDN'T THROW!");
assert as "DIDN'T THROW!";
} catch (Exception e) {
console.print("caught: " + e);
}
Expand All @@ -86,16 +86,16 @@ module TestTry {
try {
using (ByeBye bye = new ByeBye()) {
testThrow();
console.print("DIDN'T THROW!");
assert as "DIDN'T THROW!";
}
} catch (Exception e) {
console.print("ok");
}

try (ByeBye bye = new ByeBye()) {
console.print(bye);
} finally {
console.print("in finally: " + bye);
try (ByeBye bye = new ByeBye()) {
testThrow();
assert as "DIDN'T THROW!";
} catch (Exception e) {
}

console.print("done");
Expand Down

0 comments on commit 0486e50

Please sign in to comment.