From 8fb020c59e0479d158dae10735f2c947dc3ddabe Mon Sep 17 00:00:00 2001 From: Simon Robertshaw Date: Wed, 30 Jan 2013 23:44:05 +0000 Subject: [PATCH 1/2] Return from procedures, correctly address variables in nested scopes, make space for the return address from the callers stack --- src/pim/Generator.cpp | 62 ++++++++++++++++++++++++++++++++++--------- src/pim/Generator.h | 16 ++++++++--- src/pim/Machine.cpp | 9 +++++-- src/pim/Opcodes.inl | 1 + src/pim/Parser.cpp | 6 ++--- src/pim/X86Native.cpp | 19 ++++++++++--- 6 files changed, 89 insertions(+), 24 deletions(-) diff --git a/src/pim/Generator.cpp b/src/pim/Generator.cpp index a79121182..c7e541ff6 100644 --- a/src/pim/Generator.cpp +++ b/src/pim/Generator.cpp @@ -43,6 +43,15 @@ namespace pim program.push_back((constant>>24) & 0xFF); } + void Generator::writeConstantPlaceholderOffset(int value, int * offset) + { + valueOffsetPlaceholders.push_back(ValueOffsetPlaceholder(program.size(), std::pair(value, offset))); + program.push_back(0); + program.push_back(0); + program.push_back(0); + program.push_back(0); + } + void Generator::writeConstantPlaceholder(std::string label) { placeholders.push_back(Placeholder(program.size(), label)); @@ -118,6 +127,22 @@ namespace pim program[cPosition.first+3] = (value >> 24) & 0xFF; } + for(std::vector::iterator iter = valueOffsetPlaceholders.begin(), end = valueOffsetPlaceholders.end(); iter != end; ++iter) + { + ValueOffsetPlaceholder cPosition = *iter; + int value = cPosition.second.first; + int offset = *cPosition.second.second; + + std::cout << "Setting value placeholder at " << cPosition.first << " with " << value << " + " << offset << std::endl; + + value += offset; + + program[cPosition.first] = value & 0xFF; + program[cPosition.first+1] = (value >> 8) & 0xFF; + program[cPosition.first+2] = (value >> 16) & 0xFF; + program[cPosition.first+3] = (value >> 24) & 0xFF; + } + //Build file int macroSizePos, propSizePos, codeSizePos, macroSize = 0, propSize = 0, codeSize = program.size(); std::vector file; @@ -224,6 +249,8 @@ namespace pim scopes.push(currentScope); Scope * prevScope = currentScope; currentScope = new Scope(); + currentScope->FrameSize += 4; //Space for return address + currentScope->LocalFrameSize += 4; defineLabel(label); output << "." << label << std::endl; @@ -236,6 +263,7 @@ namespace pim currentScope = new Scope(); currentScope->Definitions.insert(currentScope->Definitions.begin(), prevScope->Definitions.begin(), prevScope->Definitions.end()); currentScope->FrameSize = prevScope->FrameSize; + currentScope->OldFrameSize = prevScope->OldFrameSize; defineLabel(label); output << "." << label << std::endl; @@ -243,16 +271,27 @@ namespace pim void Generator::PopScope() { - - writeOpcode(Opcode::Return); + writeOpcode(Opcode::Leave); writeConstant(currentScope->LocalFrameSize); - output << "return " << currentScope->LocalFrameSize << std::endl; + output << "leave " << currentScope->LocalFrameSize << std::endl; currentScope = scopes.top(); scopes.pop(); } + void Generator::ExitScope() + { + currentScope = scopes.top(); + scopes.pop(); + } + + void Generator::Return() + { + writeOpcode(Opcode::Return); + output << "return" << std::endl; + } + void Generator::ScopeLabel(std::string label) { //defineLabelwriteOpcode("." << label); @@ -276,11 +315,11 @@ namespace pim void Generator::ScopeVariable(std::string label) { - currentScope->Definitions.push_back(Definition(label, variableType, currentScope->FrameSize)); + currentScope->Definitions.push_back(Definition(label, variableType, currentScope->LocalFrameSize, currentScope)); currentScope->FrameSize += 4; currentScope->LocalFrameSize += 4; - output << "#declare " << label << " " << currentScope->FrameSize-4 << std::endl; + output << "#declare " << label << " " << currentScope->LocalFrameSize-4 << std::endl; } void Generator::PushVariableAddress(std::string label) @@ -291,7 +330,8 @@ namespace pim void Generator::LoadVariable(std::string label) { writeOpcode(Opcode::Load); - writeConstant(currentScope->GetDefinition(label).StackPosition); + Definition d = currentScope->GetDefinition(label); + writeConstant(d.StackPosition+(currentScope->FrameSize-d.MyScope->FrameSize)); output << "load " << label << std::endl; } @@ -299,7 +339,10 @@ namespace pim void Generator::StoreVariable(std::string label) { writeOpcode(Opcode::Store); - writeConstant(currentScope->GetDefinition(label).StackPosition); + Definition d = currentScope->GetDefinition(label); + writeConstant(d.StackPosition+(currentScope->FrameSize-d.MyScope->FrameSize)); + //writeConstantPlaceholderOffset(currentScope->GetDefinition(label).StackPosition, &(currentScope->OldFrameSize)); + //writeConstant(currentScope->GetDefinition(label).StackPosition); output << "store " << label << std::endl; } @@ -509,10 +552,5 @@ namespace pim } - void Generator::Return() - { - - } - } } \ No newline at end of file diff --git a/src/pim/Generator.h b/src/pim/Generator.h index 2eb1029f1..9d9105bcb 100644 --- a/src/pim/Generator.h +++ b/src/pim/Generator.h @@ -40,16 +40,19 @@ namespace pim { enum { Integer = Token::IntegerSymbol, Decimal = Token::DecimalSymbol }; }; + class Scope; class Definition { public: std::string Name; int Type; int StackPosition; - Definition(std::string name, int type, int position) : + Scope * MyScope; + Definition(std::string name, int type, int position, Scope * myScope) : Type(type), Name(name), - StackPosition(position) + StackPosition(position), + MyScope(myScope) { } @@ -68,9 +71,11 @@ namespace pim std::vector