This commit is contained in:
Simon Robertshaw 2013-01-31 23:43:11 +00:00
commit 833cbf9b77
6 changed files with 93 additions and 28 deletions

View File

@ -43,6 +43,15 @@ namespace pim
program.push_back((constant>>24) & 0xFF); program.push_back((constant>>24) & 0xFF);
} }
void Generator::writeConstantPlaceholderOffset(int value, int * offset)
{
valueOffsetPlaceholders.push_back(ValueOffsetPlaceholder(program.size(), std::pair<int, int*>(value, offset)));
program.push_back(0);
program.push_back(0);
program.push_back(0);
program.push_back(0);
}
void Generator::writeConstantPlaceholder(std::string label) void Generator::writeConstantPlaceholder(std::string label)
{ {
placeholders.push_back(Placeholder(program.size(), label)); placeholders.push_back(Placeholder(program.size(), label));
@ -118,6 +127,22 @@ namespace pim
program[cPosition.first+3] = (value >> 24) & 0xFF; program[cPosition.first+3] = (value >> 24) & 0xFF;
} }
for(std::vector<ValueOffsetPlaceholder>::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 //Build file
int macroSizePos, propSizePos, codeSizePos, macroSize = 0, propSize = 0, codeSize = program.size(); int macroSizePos, propSizePos, codeSizePos, macroSize = 0, propSize = 0, codeSize = program.size();
std::vector<unsigned char> file; std::vector<unsigned char> file;
@ -224,6 +249,8 @@ namespace pim
scopes.push(currentScope); scopes.push(currentScope);
Scope * prevScope = currentScope; Scope * prevScope = currentScope;
currentScope = new Scope(); currentScope = new Scope();
currentScope->FrameSize += 4; //Space for return address
currentScope->LocalFrameSize += 4;
defineLabel(label); defineLabel(label);
output << "." << label << std::endl; output << "." << label << std::endl;
@ -236,6 +263,7 @@ namespace pim
currentScope = new Scope(); currentScope = new Scope();
currentScope->Definitions.insert(currentScope->Definitions.begin(), prevScope->Definitions.begin(), prevScope->Definitions.end()); currentScope->Definitions.insert(currentScope->Definitions.begin(), prevScope->Definitions.begin(), prevScope->Definitions.end());
currentScope->FrameSize = prevScope->FrameSize; currentScope->FrameSize = prevScope->FrameSize;
currentScope->OldFrameSize = prevScope->OldFrameSize;
defineLabel(label); defineLabel(label);
output << "." << label << std::endl; output << "." << label << std::endl;
@ -243,16 +271,27 @@ namespace pim
void Generator::PopScope() void Generator::PopScope()
{ {
writeOpcode(Opcode::Leave);
writeOpcode(Opcode::Return);
writeConstant(currentScope->LocalFrameSize); writeConstant(currentScope->LocalFrameSize);
output << "return " << currentScope->LocalFrameSize << std::endl; output << "leave " << currentScope->LocalFrameSize << std::endl;
currentScope = scopes.top(); currentScope = scopes.top();
scopes.pop(); 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) void Generator::ScopeLabel(std::string label)
{ {
//defineLabelwriteOpcode("." << label); //defineLabelwriteOpcode("." << label);
@ -294,12 +333,12 @@ namespace pim
void Generator::ScopeVariable(std::string label) void Generator::ScopeVariable(std::string label)
{ {
currentScope->Definitions.push_back(Definition(label, typeStack.top(), currentScope->FrameSize)); currentScope->Definitions.push_back(Definition(label, variableType, currentScope->LocalFrameSize, currentScope));
currentScope->FrameSize += 4; currentScope->FrameSize += 4;
currentScope->LocalFrameSize += 4; currentScope->LocalFrameSize += 4;
typeStack.pop(); typeStack.pop();
output << "#declare " << label << " " << currentScope->FrameSize-4 << std::endl; output << "#declare " << label << " " << currentScope->LocalFrameSize-4 << std::endl;
} }
void Generator::PushVariableAddress(std::string label) void Generator::PushVariableAddress(std::string label)
@ -313,7 +352,8 @@ namespace pim
pushType(d.Type); pushType(d.Type);
writeOpcode(Opcode::Load); writeOpcode(Opcode::Load);
writeConstant(d.StackPosition);
writeConstant(d.StackPosition+(currentScope->FrameSize-d.MyScope->FrameSize));
output << "load " << label << std::endl; output << "load " << label << std::endl;
} }
@ -337,14 +377,17 @@ namespace pim
popType(2); popType(2);
writeOpcode(Opcode::Store); writeOpcode(Opcode::Store);
writeConstant(d.StackPosition);
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; output << "store " << label << std::endl;
} }
void Generator::RTConstant(std::string name) void Generator::RTConstant(std::string name)
{ {
pushType(Type::Integer); pushType(DataType::Integer);
writeOpcode(Opcode::Constant); writeOpcode(Opcode::Constant);
writeConstantMacroPlaceholder(name); writeConstantMacroPlaceholder(name);
@ -417,14 +460,14 @@ namespace pim
{ {
popType(1); popType(1);
pushType(DataType::Integer); pushType(DataType::Integer);
writeOpcode(OpCode::ToInteger); writeOpcode(Opcode::ToInteger);
} }
void Generator::ToFloat() void Generator::ToFloat()
{ {
popType(1); popType(1);
pushType(DataType::Float); pushType(DataType::Float);
writeOpcode(OpCode::ToFloat); writeOpcode(Opcode::ToFloat);
} }
void Generator::Divide() void Generator::Divide()
@ -592,10 +635,5 @@ namespace pim
} }
void Generator::Return()
{
}
} }
} }

View File

@ -37,16 +37,19 @@ namespace pim
} }
~SymbolNotFoundException() throw() {}; ~SymbolNotFoundException() throw() {};
}; };
class Scope;
class Definition class Definition
{ {
public: public:
std::string Name; std::string Name;
int Type; int Type;
int StackPosition; int StackPosition;
Definition(std::string name, int type, int position) : Scope * MyScope;
Definition(std::string name, int type, int position, Scope * myScope) :
Type(type), Type(type),
Name(name), Name(name),
StackPosition(position) StackPosition(position),
MyScope(myScope)
{ {
} }
@ -65,9 +68,11 @@ namespace pim
std::vector<Label> Labels; std::vector<Label> Labels;
int FrameSize; int FrameSize;
int LocalFrameSize; int LocalFrameSize;
int OldFrameSize;
Scope(): Scope():
FrameSize(0), FrameSize(0),
LocalFrameSize(0) LocalFrameSize(0),
OldFrameSize(0)
{ {
} }
@ -98,6 +103,9 @@ namespace pim
typedef std::pair<int, int*> ValuePlaceholder; typedef std::pair<int, int*> ValuePlaceholder;
std::vector<ValuePlaceholder> valuePlaceholders; std::vector<ValuePlaceholder> valuePlaceholders;
typedef std::pair<int, std::pair<int, int*> > ValueOffsetPlaceholder;
std::vector<ValueOffsetPlaceholder> valueOffsetPlaceholders;
typedef std::pair<int, std::string> PropertyPlaceholder; typedef std::pair<int, std::string> PropertyPlaceholder;
std::vector<PropertyPlaceholder> propertyPlaceholders; std::vector<PropertyPlaceholder> propertyPlaceholders;
@ -117,6 +125,7 @@ namespace pim
void writeConstant(int constant); void writeConstant(int constant);
void writeConstantPlaceholder(std::string label); void writeConstantPlaceholder(std::string label);
void writeConstantPlaceholder(int * value); void writeConstantPlaceholder(int * value);
void writeConstantPlaceholderOffset(int value, int * offset);
void writeConstantMacroPlaceholder(std::string macro); void writeConstantMacroPlaceholder(std::string macro);
void writeConstantPropertyPlaceholder(std::string property); void writeConstantPropertyPlaceholder(std::string property);
@ -131,6 +140,7 @@ namespace pim
void PushLocalScope(std::string label); void PushLocalScope(std::string label);
void LocalEnter(); void LocalEnter();
void PopScope(); void PopScope();
void ExitScope();
void ScopeLabel(std::string label); void ScopeLabel(std::string label);
void ScopeVariableType(int type); void ScopeVariableType(int type);

View File

@ -251,11 +251,12 @@ namespace pim
case Opcode::JumpLess: case Opcode::JumpLess:
case Opcode::JumpLessEqual: case Opcode::JumpLessEqual:
case Opcode::Jump: case Opcode::Jump:
case Opcode::Return: case Opcode::Leave:
case Opcode::LocalEnter: case Opcode::LocalEnter:
case Opcode::LoadProperty: case Opcode::LoadProperty:
case Opcode::StoreProperty: case Opcode::StoreProperty:
return 4; return 4;
case Opcode::Return:
case Opcode::Discard: case Opcode::Discard:
case Opcode::Duplicate: case Opcode::Duplicate:
case Opcode::Add: case Opcode::Add:
@ -402,9 +403,11 @@ namespace pim
case Opcode::Jump: case Opcode::Jump:
programCounter = argument.Integer-1; programCounter = argument.Integer-1;
break; break;
case Opcode::Return: case Opcode::Leave:
callStack += argument.Integer; callStack += argument.Integer;
break; break;
case Opcode::Return:
break;
case Opcode::LocalEnter: case Opcode::LocalEnter:
callStack -= argument.Integer; callStack -= argument.Integer;
break; break;
@ -425,6 +428,8 @@ namespace pim
std::fill(romAddress, romAddress+executableCode.size()+8, 0x90); //Fill with NOP for debugging std::fill(romAddress, romAddress+executableCode.size()+8, 0x90); //Fill with NOP for debugging
std::copy(executableCode.begin(), executableCode.end(), romAddress+4); std::copy(executableCode.begin(), executableCode.end(), romAddress+4);
nativeRom = (intptr_t)romAddress; nativeRom = (intptr_t)romAddress;
printf("%p\n", romAddress);
fflush(stdout);
delete native; delete native;
} }

View File

@ -27,4 +27,5 @@ OPDEF(JumpLess)
OPDEF(JumpLessEqual) OPDEF(JumpLessEqual)
OPDEF(Jump) OPDEF(Jump)
OPDEF(Return) OPDEF(Return)
OPDEF(Leave)
OPDEF(LocalEnter) OPDEF(LocalEnter)

View File

@ -50,7 +50,6 @@ namespace pim
expect(Token::FunctionSymbol); expect(Token::FunctionSymbol);
functionName = token.Source; functionName = token.Source;
//generator->ScopeLabel(functionName); //Function name
generator->PushScope(functionName); generator->PushScope(functionName);
expect(Token::Identifier); expect(Token::Identifier);
@ -62,9 +61,10 @@ namespace pim
} }
block(); block();
expect(Token::EndSymbol); expect(Token::EndSymbol);
generator->ExitScope();
generator->Return(); generator->Return();
generator->PopScope();
} }
/* /*
@ -401,7 +401,7 @@ namespace pim
generator->Jump(loopLabel+"Next"); generator->Jump(loopLabel+"Next");
generator->ScopeLabel(loopLabel+"End"); generator->ScopeLabel(loopLabel+"End");
generator->Return(); //generator->Return();
generator->PopScope(); generator->PopScope();
expect(Token::EndSymbol); expect(Token::EndSymbol);
} }

View File

@ -14,8 +14,12 @@ namespace pim
//int * esi = malloc(1024*1024); //int * esi = malloc(1024*1024);
emit("BE"); //mov esi, machineStack emit("BE"); //mov esi, machineStack
emit((intptr_t)esi); emit((intptr_t)esi);
//emit("81 EC"); //sub esp, 12
//emit(12);
#ifdef DEBUG
emit("81 C4"); //add esp, 4 emit("81 C4"); //add esp, 4
emit(4); emit(4);
#endif
while(programCounter < romSize) while(programCounter < romSize)
{ {
Word argument = rom[programCounter].Parameter; Word argument = rom[programCounter].Parameter;
@ -226,7 +230,7 @@ namespace pim
emitPlaceholder(argument.Integer); emitPlaceholder(argument.Integer);
break; break;
case Opcode::JumpNotEqual: case Opcode::JumpNotEqual:
emit("83 C6 04"); //add esi, 8 emit("83 C6 08"); //add esi, 8
emit("8B 46 FC"); //mov eax, [esi-4] emit("8B 46 FC"); //mov eax, [esi-4]
emit("3B 46 F8"); //cmp eax, [esi-8] emit("3B 46 F8"); //cmp eax, [esi-8]
emit("74 05"); //je 8 emit("74 05"); //je 8
@ -270,21 +274,28 @@ namespace pim
emitPlaceholder(argument.Integer); emitPlaceholder(argument.Integer);
break; break;
case Opcode::Return: case Opcode::Return:
emit("81 C7"); //add edi, constant emit("C3"); //ret
break;
case Opcode::Leave:
//emit("81 C7"); //add edi, constant
emit("81 C4"); //add esp, constant
emit(argument.Integer); emit(argument.Integer);
break; break;
case Opcode::LocalEnter: case Opcode::LocalEnter:
emit("81 EF"); //sub edi constant //emit("81 EF"); //sub edi constant
emit("81 EC"); //sub esp constant
emit(argument.Integer); emit(argument.Integer);
break; break;
} }
//std::cout << programStack << std::endl; //std::cout << programStack << std::endl;
programCounter++; programCounter++;
} }
#ifdef DEBUG
emit("81 EC"); //sub esp, 4 emit("81 EC"); //sub esp, 4
//emit("81 EC"); //sub esp, 4
emit(4); emit(4);
emit("C9"); //leave emit("C9"); //leave //When -fomit-frame-pointers is used, don't 'leave', since ebp isn't on the stack
emit("C3"); //ret #endif
for(std::map<int, int>::iterator iter = placeholders.begin(), end = placeholders.end(); iter != end; ++iter) for(std::map<int, int>::iterator iter = placeholders.begin(), end = placeholders.end(); iter != end; ++iter)
{ {
std::pair<int, int> placeholder = *iter; std::pair<int, int> placeholder = *iter;