aboutsummaryrefslogtreecommitdiffstats
path: root/ExpressionCompiler.cpp
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2014-11-26 01:23:39 +0800
committerChristian <c@ethdev.com>2014-11-26 22:35:25 +0800
commitf30dc68cdd3ae97305b8dfc8891da81a6d489882 (patch)
treefef4e7a9d17b682b68c20aae9fa2fe887f6ed56a /ExpressionCompiler.cpp
parenta2715c5f34cfa4050ba64b4a1467b9ca5821472b (diff)
downloaddexon-solidity-f30dc68cdd3ae97305b8dfc8891da81a6d489882.tar.gz
dexon-solidity-f30dc68cdd3ae97305b8dfc8891da81a6d489882.tar.zst
dexon-solidity-f30dc68cdd3ae97305b8dfc8891da81a6d489882.zip
Sending ether.
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r--ExpressionCompiler.cpp79
1 files changed, 56 insertions, 23 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 9e396874..f5ab829c 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -179,33 +179,62 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall)
}
else
{
- //@todo: check for "external call" (to be stored in type)
-
- // Calling convention: Caller pushes return address and arguments
- // Callee removes them and pushes return values
FunctionType const& function = dynamic_cast<FunctionType const&>(*_functionCall.getExpression().getType());
-
- eth::AssemblyItem returnLabel = m_context.pushNewTag();
std::vector<ASTPointer<Expression>> const& arguments = _functionCall.getArguments();
if (asserts(arguments.size() == function.getParameterTypes().size()))
BOOST_THROW_EXCEPTION(InternalCompilerError());
- for (unsigned i = 0; i < arguments.size(); ++i)
+
+ if (function.getLocation() == FunctionType::Location::INTERNAL)
{
- arguments[i]->accept(*this);
- appendTypeConversion(*arguments[i]->getType(), *function.getParameterTypes()[i]);
+ // Calling convention: Caller pushes return address and arguments
+ // Callee removes them and pushes return values
+
+ eth::AssemblyItem returnLabel = m_context.pushNewTag();
+ for (unsigned i = 0; i < arguments.size(); ++i)
+ {
+ arguments[i]->accept(*this);
+ appendTypeConversion(*arguments[i]->getType(), *function.getParameterTypes()[i]);
+ }
+ _functionCall.getExpression().accept(*this);
+
+ m_context.appendJump();
+ m_context << returnLabel;
+
+ // callee adds return parameters, but removes arguments and return label
+ m_context.adjustStackOffset(function.getReturnParameterTypes().size() - arguments.size() - 1);
+
+ // @todo for now, the return value of a function is its first return value, so remove
+ // all others
+ for (unsigned i = 1; i < function.getReturnParameterTypes().size(); ++i)
+ m_context << eth::Instruction::POP;
+ }
+ else if (function.getLocation() == FunctionType::Location::EXTERNAL)
+ {
+ BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("External function calls not implemented yet."));
+ }
+ else
+ {
+ switch (function.getLocation())
+ {
+ case FunctionType::Location::SEND:
+ m_context << u256(0) << u256(0) << u256(0) << u256(0);
+ arguments.front()->accept(*this);
+ //@todo might not be necessary
+ appendTypeConversion(*arguments.front()->getType(), *function.getParameterTypes().front());
+ _functionCall.getExpression().accept(*this);
+ m_context << u256(25) << eth::Instruction::GAS << eth::Instruction::SUB
+ << eth::Instruction::CALL
+ << eth::Instruction::POP;
+ break;
+ case FunctionType::Location::SUICIDE:
+ arguments.front()->accept(*this);
+ //@todo might not be necessary
+ appendTypeConversion(*arguments.front()->getType(), *function.getParameterTypes().front());
+ m_context << eth::Instruction::SUICIDE;
+ default:
+ BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Function not yet implemented."));
+ }
}
- _functionCall.getExpression().accept(*this);
-
- m_context.appendJump();
- m_context << returnLabel;
-
- // callee adds return parameters, but removes arguments and return label
- m_context.adjustStackOffset(function.getReturnParameterTypes().size() - arguments.size() - 1);
-
- // @todo for now, the return value of a function is its first return value, so remove
- // all others
- for (unsigned i = 1; i < function.getReturnParameterTypes().size(); ++i)
- m_context << eth::Instruction::POP;
}
return false;
}
@@ -216,9 +245,13 @@ void ExpressionCompiler::endVisit(MemberAccess& _memberAccess)
switch (_memberAccess.getExpression().getType()->getCategory())
{
case Type::Category::INTEGER:
- if (asserts(member == "balance"))
+ if (member == "balance")
+ m_context << eth::Instruction::BALANCE;
+ else if (member == "send")
+ { // no modification
+ }
+ else
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to integer."));
- m_context << eth::Instruction::BALANCE;
break;
case Type::Category::CONTRACT:
// call function