From 23197da679d203669ba95c9668041ecdee3f4c22 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 6 Oct 2009 03:17:12 +0000 Subject: [PATCH] fix handling of subroutines in methods of return type long on 32-bit systems --- src/compiler.cpp | 42 +++++++++++++++++++++++++----------------- test/Subroutine.java | 4 ++-- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/compiler.cpp b/src/compiler.cpp index f3e9cb3dd4..d5e1db2bd9 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -5405,6 +5405,28 @@ maybeBuddy(Context* c, Value* v) } } +void +linkLocals(Context* c, Local* oldLocals, Local* newLocals) +{ + for (int i = 0; i < static_cast(c->localFootprint); ++i) { + Local* local = oldLocals + i; + if (local->value) { + int highOffset = c->arch->bigEndian() ? 1 : -1; + + if (i + highOffset >= 0 + and i + highOffset < static_cast(c->localFootprint) + and local->value->next == local[highOffset].value) + { + Value* v = newLocals[i].value; + Value* next = newLocals[i + highOffset].value; + v->next = next; + next->next = v; + next->index = 1; + } + } + } +} + class Client: public Assembler::Client { public: Client(Context* c): c(c) { } @@ -5467,7 +5489,9 @@ class MyCompiler: public Compiler { } virtual void linkSubroutine(Subroutine* subroutine) { + Local* oldLocals = c.locals; restoreState(static_cast(subroutine)->forkState); + linkLocals(&c, oldLocals, c.locals); } virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint, @@ -5878,23 +5902,7 @@ class MyCompiler: public Compiler { } } - for (int i = 0; i < static_cast(c.localFootprint); ++i) { - Local* local = e->localsBefore + i; - if (local->value) { - int highOffset = c.arch->bigEndian() ? 1 : -1; - - if (i + highOffset >= 0 - and i + highOffset < static_cast(c.localFootprint) - and local->value->next == local[highOffset].value) - { - Value* v = c.locals[i].value; - Value* next = c.locals[i + highOffset].value; - v->next = next; - next->next = v; - next->index = 1; - } - } - } + linkLocals(&c, e->localsBefore, newLocals); } virtual void storeLocal(unsigned footprint, Operand* src, unsigned index) { diff --git a/test/Subroutine.java b/test/Subroutine.java index c7c04d501d..2516d34398 100644 --- a/test/Subroutine.java +++ b/test/Subroutine.java @@ -118,7 +118,7 @@ public class Subroutine { try { switch (path) { case 1: - return 0xFFFFFFFFFFL; + return 0xFABFABFABFL; case 2: { int a = 42; @@ -187,7 +187,7 @@ public class Subroutine { String.valueOf(test4(2)); String.valueOf(test4(3)); - expect(test4(1) == 0xFFFFFFFFFFL); + expect(test4(1) == 0xFABFABFABFL); } private static class DummyException extends RuntimeException { }