mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Some tests and bugfixes for the compiler.
This commit is contained in:
parent
643c781a6d
commit
4dfd6dfa13
26
Compiler.cpp
26
Compiler.cpp
@ -94,25 +94,20 @@ void Compiler::appendFunctionSelector(vector<ASTPointer<FunctionDefinition>> con
|
|||||||
for (pair<string, pair<FunctionDefinition const*, eth::AssemblyItem>> const& f: publicFunctions)
|
for (pair<string, pair<FunctionDefinition const*, eth::AssemblyItem>> const& f: publicFunctions)
|
||||||
m_context.appendJumpTo(f.second.second) << eth::Instruction::JUMPDEST;
|
m_context.appendJumpTo(f.second.second) << eth::Instruction::JUMPDEST;
|
||||||
|
|
||||||
m_context << returnTag << eth::Instruction::RETURN;
|
m_context << returnTag << eth::Instruction::STOP;
|
||||||
|
|
||||||
for (pair<string, pair<FunctionDefinition const*, eth::AssemblyItem>> const& f: publicFunctions)
|
for (pair<string, pair<FunctionDefinition const*, eth::AssemblyItem>> const& f: publicFunctions)
|
||||||
{
|
{
|
||||||
|
FunctionDefinition const& function = *f.second.first;
|
||||||
m_context << f.second.second;
|
m_context << f.second.second;
|
||||||
appendFunctionCallSection(*f.second.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Compiler::appendFunctionCallSection(FunctionDefinition const& _function)
|
|
||||||
{
|
|
||||||
eth::AssemblyItem returnTag = m_context.pushNewTag();
|
eth::AssemblyItem returnTag = m_context.pushNewTag();
|
||||||
|
appendCalldataUnpacker(function);
|
||||||
appendCalldataUnpacker(_function);
|
m_context.appendJumpTo(m_context.getFunctionEntryLabel(function));
|
||||||
|
|
||||||
m_context.appendJumpTo(m_context.getFunctionEntryLabel(_function));
|
|
||||||
m_context << returnTag;
|
m_context << returnTag;
|
||||||
|
|
||||||
appendReturnValuePacker(_function);
|
appendReturnValuePacker(function);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::appendCalldataUnpacker(FunctionDefinition const& _function)
|
void Compiler::appendCalldataUnpacker(FunctionDefinition const& _function)
|
||||||
@ -142,7 +137,7 @@ void Compiler::appendReturnValuePacker(FunctionDefinition const& _function)
|
|||||||
//@todo this can be also done more efficiently
|
//@todo this can be also done more efficiently
|
||||||
unsigned dataOffset = 0;
|
unsigned dataOffset = 0;
|
||||||
vector<ASTPointer<VariableDeclaration>> const& parameters = _function.getReturnParameters();
|
vector<ASTPointer<VariableDeclaration>> const& parameters = _function.getReturnParameters();
|
||||||
for (unsigned i = 0 ; i < parameters.size(); ++i)
|
for (unsigned i = 0; i < parameters.size(); ++i)
|
||||||
{
|
{
|
||||||
unsigned numBytes = parameters[i]->getType()->getCalldataEncodedSize();
|
unsigned numBytes = parameters[i]->getType()->getCalldataEncodedSize();
|
||||||
if (numBytes == 0)
|
if (numBytes == 0)
|
||||||
@ -150,11 +145,9 @@ void Compiler::appendReturnValuePacker(FunctionDefinition const& _function)
|
|||||||
<< errinfo_sourceLocation(parameters[i]->getLocation())
|
<< errinfo_sourceLocation(parameters[i]->getLocation())
|
||||||
<< errinfo_comment("Type not yet supported."));
|
<< errinfo_comment("Type not yet supported."));
|
||||||
m_context << eth::dupInstruction(parameters.size() - i);
|
m_context << eth::dupInstruction(parameters.size() - i);
|
||||||
if (numBytes == 32)
|
if (numBytes != 32)
|
||||||
|
m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::MUL;
|
||||||
m_context << u256(dataOffset) << eth::Instruction::MSTORE;
|
m_context << u256(dataOffset) << eth::Instruction::MSTORE;
|
||||||
else
|
|
||||||
m_context << u256(dataOffset) << (u256(1) << ((32 - numBytes) * 8))
|
|
||||||
<< eth::Instruction::MUL << eth::Instruction::MSTORE;
|
|
||||||
dataOffset += numBytes;
|
dataOffset += numBytes;
|
||||||
}
|
}
|
||||||
// note that the stack is not cleaned up here
|
// note that the stack is not cleaned up here
|
||||||
@ -215,6 +208,7 @@ bool Compiler::visit(FunctionDefinition& _function)
|
|||||||
m_context << eth::swapInstruction(stackLayout.size() - stackLayout.back() - 1);
|
m_context << eth::swapInstruction(stackLayout.size() - stackLayout.back() - 1);
|
||||||
swap(stackLayout[stackLayout.back()], stackLayout.back());
|
swap(stackLayout[stackLayout.back()], stackLayout.back());
|
||||||
}
|
}
|
||||||
|
//@todo assert that everything is in place now
|
||||||
|
|
||||||
m_context << eth::Instruction::JUMP;
|
m_context << eth::Instruction::JUMP;
|
||||||
|
|
||||||
|
@ -43,7 +43,6 @@ private:
|
|||||||
/// Creates a new compiler context / assembly and packs the current code into the data part.
|
/// Creates a new compiler context / assembly and packs the current code into the data part.
|
||||||
void packIntoContractCreator();
|
void packIntoContractCreator();
|
||||||
void appendFunctionSelector(std::vector<ASTPointer<FunctionDefinition> > const& _functions);
|
void appendFunctionSelector(std::vector<ASTPointer<FunctionDefinition> > const& _functions);
|
||||||
void appendFunctionCallSection(FunctionDefinition const& _function);
|
|
||||||
void appendCalldataUnpacker(FunctionDefinition const& _function);
|
void appendCalldataUnpacker(FunctionDefinition const& _function);
|
||||||
void appendReturnValuePacker(FunctionDefinition const& _function);
|
void appendReturnValuePacker(FunctionDefinition const& _function);
|
||||||
|
|
||||||
|
@ -264,6 +264,7 @@ void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation& _binaryOperati
|
|||||||
if (op == Token::AND)
|
if (op == Token::AND)
|
||||||
m_context << eth::Instruction::ISZERO;
|
m_context << eth::Instruction::ISZERO;
|
||||||
eth::AssemblyItem endLabel = m_context.appendConditionalJump();
|
eth::AssemblyItem endLabel = m_context.appendConditionalJump();
|
||||||
|
m_context << eth::Instruction::POP;
|
||||||
_binaryOperation.getRightExpression().accept(*this);
|
_binaryOperation.getRightExpression().accept(*this);
|
||||||
m_context << endLabel;
|
m_context << endLabel;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user