diff options
author | Christian <c@ethdev.com> | 2014-11-26 01:23:39 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2014-11-26 22:35:25 +0800 |
commit | f30dc68cdd3ae97305b8dfc8891da81a6d489882 (patch) | |
tree | fef4e7a9d17b682b68c20aae9fa2fe887f6ed56a /ExpressionCompiler.cpp | |
parent | a2715c5f34cfa4050ba64b4a1467b9ca5821472b (diff) | |
download | dexon-solidity-f30dc68cdd3ae97305b8dfc8891da81a6d489882.tar.gz dexon-solidity-f30dc68cdd3ae97305b8dfc8891da81a6d489882.tar.zst dexon-solidity-f30dc68cdd3ae97305b8dfc8891da81a6d489882.zip |
Sending ether.
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r-- | ExpressionCompiler.cpp | 79 |
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 |