aboutsummaryrefslogtreecommitdiffstats
path: root/Compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Compiler.cpp')
-rw-r--r--Compiler.cpp46
1 files changed, 22 insertions, 24 deletions
diff --git a/Compiler.cpp b/Compiler.cpp
index 5190f93f..13f8282e 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -201,7 +201,7 @@ set<FunctionDefinition const*> Compiler::getFunctionsCalled(set<ASTNode const*>
void Compiler::appendFunctionSelector(ContractDefinition const& _contract)
{
- map<FixedHash<4>, FunctionDefinition const*> interfaceFunctions = _contract.getInterfaceFunctions();
+ map<FixedHash<4>, FunctionType const*, Declaration const*> interfaceFunctions = _contract.getInterfaceFunctions();
map<FixedHash<4>, const eth::AssemblyItem> callDataUnpackerEntryPoints;
// retrieve the function signature hash from the calldata
@@ -209,7 +209,6 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract)
CompilerUtils(m_context).loadFromMemory(0, 4, false, true);
// stack now is: 1 0 <funhash>
- // for (auto it = interfaceFunctions.cbegin(); it != interfaceFunctions.cend(); ++it)
for (auto const& it: interfaceFunctions)
{
callDataUnpackerEntryPoints.insert(std::make_pair(it.first, m_context.newTag()));
@@ -220,29 +219,28 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract)
for (auto const& it: interfaceFunctions)
{
- FunctionDefinition const& function = *it.second;
+ FunctionType const* functionType = *it.second.first;
m_context << callDataUnpackerEntryPoints.at(it.first);
eth::AssemblyItem returnTag = m_context.pushNewTag();
- appendCalldataUnpacker(function);
- m_context.appendJumpTo(m_context.getFunctionEntryLabel(function));
+ appendCalldataUnpacker(functionType->getParameterTypes());
+ m_context.appendJumpTo(m_context.getFunctionEntryLabel(it.second.second));
m_context << returnTag;
- appendReturnValuePacker(function);
+ appendReturnValuePacker(functionType->getReturnParameterTypes());
}
}
-unsigned Compiler::appendCalldataUnpacker(FunctionDefinition const& _function, bool _fromMemory)
+unsigned Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool _fromMemory)
{
// We do not check the calldata size, everything is zero-padded.
unsigned dataOffset = CompilerUtils::dataStartOffset; // the 4 bytes of the function hash signature
//@todo this can be done more efficiently, saving some CALLDATALOAD calls
- for (ASTPointer<VariableDeclaration> const& var: _function.getParameters())
+ for (TypePointer const& type: _typeParameters)
{
- unsigned const c_numBytes = var->getType()->getCalldataEncodedSize();
+ unsigned const c_numBytes = type->getCalldataEncodedSize();
if (c_numBytes > 32)
BOOST_THROW_EXCEPTION(CompilerError()
- << errinfo_sourceLocation(var->getLocation())
- << errinfo_comment("Type " + var->getType()->toString() + " not yet supported."));
- bool const c_leftAligned = var->getType()->getCategory() == Type::Category::STRING;
+ << errinfo_comment("Type " + type->toString() + " not yet supported."));
+ bool const c_leftAligned = type->getCategory() == Type::Category::STRING;
bool const c_padToWords = true;
dataOffset += CompilerUtils(m_context).loadFromMemory(dataOffset, c_numBytes, c_leftAligned,
!_fromMemory, c_padToWords);
@@ -250,26 +248,26 @@ unsigned Compiler::appendCalldataUnpacker(FunctionDefinition const& _function, b
return dataOffset;
}
-void Compiler::appendReturnValuePacker(FunctionDefinition const& _function)
+void Compiler::appendReturnValuePacker(TypePointers const& _typeParameters)
{
//@todo this can be also done more efficiently
unsigned dataOffset = 0;
- vector<ASTPointer<VariableDeclaration>> const& parameters = _function.getReturnParameters();
- unsigned stackDepth = CompilerUtils(m_context).getSizeOnStack(parameters);
- for (unsigned i = 0; i < parameters.size(); ++i)
+ unsigned stackDepth = 0;
+ for (TypePointer const& type: _typeParameters)
+ stackDepth += type->getSizeOnStack();
+
+ for (TypePointer const& type: _typeParameters)
{
- Type const& paramType = *parameters[i]->getType();
- unsigned numBytes = paramType.getCalldataEncodedSize();
+ unsigned numBytes = type->getCalldataEncodedSize();
if (numBytes > 32)
BOOST_THROW_EXCEPTION(CompilerError()
- << errinfo_sourceLocation(parameters[i]->getLocation())
- << errinfo_comment("Type " + paramType.toString() + " not yet supported."));
- CompilerUtils(m_context).copyToStackTop(stackDepth, paramType);
- ExpressionCompiler::appendTypeConversion(m_context, paramType, paramType, true);
- bool const c_leftAligned = paramType.getCategory() == Type::Category::STRING;
+ << errinfo_comment("Type " + type->toString() + " not yet supported."));
+ CompilerUtils(m_context).copyToStackTop(stackDepth, *type);
+ ExpressionCompiler::appendTypeConversion(m_context, *type, *type, true);
+ bool const c_leftAligned = type->getCategory() == Type::Category::STRING;
bool const c_padToWords = true;
dataOffset += CompilerUtils(m_context).storeInMemory(dataOffset, numBytes, c_leftAligned, c_padToWords);
- stackDepth -= paramType.getSizeOnStack();
+ stackDepth -= type->getSizeOnStack();
}
// note that the stack is not cleaned up here
m_context << u256(dataOffset) << u256(0) << eth::Instruction::RETURN;