mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
fix jsr/ret code generation bug
We were generating code to marshal values into place prior to a jump, but placing it after the jump instruction, which made it useless.
This commit is contained in:
parent
20f92bbd05
commit
3686d2131d
@ -1638,7 +1638,9 @@ class Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void returnFromSubroutine(unsigned returnAddressLocal) {
|
void returnFromSubroutine(unsigned returnAddressLocal) {
|
||||||
c->endSubroutine(subroutine->handle);
|
c->returnFromSubroutine
|
||||||
|
(subroutine->handle, loadLocal(context, 1, returnAddressLocal));
|
||||||
|
|
||||||
subroutine->stackIndex = localOffsetFromStack
|
subroutine->stackIndex = localOffsetFromStack
|
||||||
(t, translateLocalIndex(context, 1, returnAddressLocal),
|
(t, translateLocalIndex(context, 1, returnAddressLocal),
|
||||||
context->method);
|
context->method);
|
||||||
@ -4670,8 +4672,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
case ret: {
|
case ret: {
|
||||||
unsigned index = codeBody(t, code, ip);
|
unsigned index = codeBody(t, code, ip);
|
||||||
c->saveLocals();
|
|
||||||
c->jmp(loadLocal(context, 1, index));
|
|
||||||
frame->returnFromSubroutine(index);
|
frame->returnFromSubroutine(index);
|
||||||
} return;
|
} return;
|
||||||
|
|
||||||
|
@ -4790,8 +4790,10 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first,
|
|||||||
|
|
||||||
class JumpEvent: public Event {
|
class JumpEvent: public Event {
|
||||||
public:
|
public:
|
||||||
JumpEvent(Context* c, UnaryOperation type, Value* address, bool exit):
|
JumpEvent(Context* c, UnaryOperation type, Value* address, bool exit,
|
||||||
Event(c), type(type), address(address), exit(exit)
|
bool cleanLocals):
|
||||||
|
Event(c), type(type), address(address), exit(exit),
|
||||||
|
cleanLocals(cleanLocals)
|
||||||
{
|
{
|
||||||
bool thunk;
|
bool thunk;
|
||||||
uint8_t typeMask;
|
uint8_t typeMask;
|
||||||
@ -4815,6 +4817,13 @@ class JumpEvent: public Event {
|
|||||||
for (Read* r = reads; r; r = r->eventNext) {
|
for (Read* r = reads; r; r = r->eventNext) {
|
||||||
popRead(c, this, r->value);
|
popRead(c, this, r->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cleanLocals) {
|
||||||
|
for (FrameIterator it(c, 0, c->locals); it.hasMore();) {
|
||||||
|
FrameIterator::Element e = it.next(c);
|
||||||
|
clean(c, e.value, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isBranch() { return true; }
|
virtual bool isBranch() { return true; }
|
||||||
@ -4826,13 +4835,15 @@ class JumpEvent: public Event {
|
|||||||
UnaryOperation type;
|
UnaryOperation type;
|
||||||
Value* address;
|
Value* address;
|
||||||
bool exit;
|
bool exit;
|
||||||
|
bool cleanLocals;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
appendJump(Context* c, UnaryOperation type, Value* address, bool exit = false)
|
appendJump(Context* c, UnaryOperation type, Value* address, bool exit = false,
|
||||||
|
bool cleanLocals = false)
|
||||||
{
|
{
|
||||||
append(c, new (c->zone->allocate(sizeof(JumpEvent)))
|
append(c, new (c->zone->allocate(sizeof(JumpEvent)))
|
||||||
JumpEvent(c, type, address, exit));
|
JumpEvent(c, type, address, exit, cleanLocals));
|
||||||
}
|
}
|
||||||
|
|
||||||
class BoundsCheckEvent: public Event {
|
class BoundsCheckEvent: public Event {
|
||||||
@ -5037,31 +5048,6 @@ appendSaveLocals(Context* c)
|
|||||||
SaveLocalsEvent(c));
|
SaveLocalsEvent(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
class CleanLocalsEvent: public Event {
|
|
||||||
public:
|
|
||||||
CleanLocalsEvent(Context* c):
|
|
||||||
Event(c)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual const char* name() {
|
|
||||||
return "CleanLocalsEvent";
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
|
||||||
for (FrameIterator it(c, 0, c->locals); it.hasMore();) {
|
|
||||||
FrameIterator::Element e = it.next(c);
|
|
||||||
clean(c, e.value, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
appendCleanLocals(Context* c)
|
|
||||||
{
|
|
||||||
append(c, new (c->zone->allocate(sizeof(CleanLocalsEvent)))
|
|
||||||
CleanLocalsEvent(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
class DummyEvent: public Event {
|
class DummyEvent: public Event {
|
||||||
public:
|
public:
|
||||||
DummyEvent(Context* c):
|
DummyEvent(Context* c):
|
||||||
@ -5923,8 +5909,9 @@ class MyCompiler: public Compiler {
|
|||||||
MySubroutine;
|
MySubroutine;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void endSubroutine(Subroutine* subroutine) {
|
virtual void returnFromSubroutine(Subroutine* subroutine, Operand* address) {
|
||||||
appendCleanLocals(&c);
|
appendSaveLocals(&c);
|
||||||
|
appendJump(&c, Jump, static_cast<Value*>(address), false, true);
|
||||||
static_cast<MySubroutine*>(subroutine)->forkState = local::saveState(&c);
|
static_cast<MySubroutine*>(subroutine)->forkState = local::saveState(&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,8 @@ class Compiler {
|
|||||||
virtual void restoreState(State* state) = 0;
|
virtual void restoreState(State* state) = 0;
|
||||||
|
|
||||||
virtual Subroutine* startSubroutine() = 0;
|
virtual Subroutine* startSubroutine() = 0;
|
||||||
virtual void endSubroutine(Subroutine* subroutine) = 0;
|
virtual void returnFromSubroutine(Subroutine* subroutine, Operand* address)
|
||||||
|
= 0;
|
||||||
virtual void linkSubroutine(Subroutine* subroutine) = 0;
|
virtual void linkSubroutine(Subroutine* subroutine) = 0;
|
||||||
|
|
||||||
virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint,
|
virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint,
|
||||||
|
Loading…
Reference in New Issue
Block a user