From 4264625c69a30c4534e977ce3ca709bb95103dad Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sun, 5 Feb 2017 20:21:14 +0000 Subject: Implement address.transfer() --- libsolidity/codegen/ExpressionCompiler.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'libsolidity/codegen/ExpressionCompiler.cpp') diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 2ed19a83..b0031513 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -616,6 +616,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) arguments.front()->accept(*this); break; case Location::Send: + case Location::Transfer: _functionCall.expression().accept(*this); // Provide the gas stipend manually at first because we may send zero ether. // Will be zeroed if we send more than zero ether. @@ -625,9 +626,12 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) *arguments.front()->annotation().type, *function.parameterTypes().front(), true ); - // gas <- gas * !value - m_context << Instruction::SWAP1 << Instruction::DUP2; - m_context << Instruction::ISZERO << Instruction::MUL << Instruction::SWAP1; + if (function.location() != Location::Transfer) + { + // gas <- gas * !value + m_context << Instruction::SWAP1 << Instruction::DUP2; + m_context << Instruction::ISZERO << Instruction::MUL << Instruction::SWAP1; + } appendExternalFunctionCall( FunctionType( TypePointers{}, @@ -644,6 +648,12 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) ), {} ); + if (function.location() == Location::Transfer) + { + // Check if zero (out of stack or not enough balance). + m_context << Instruction::ISZERO; + m_context.appendConditionalInvalid(); + } break; case Location::Selfdestruct: arguments.front()->accept(*this); @@ -960,6 +970,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) case FunctionType::Location::Bare: case FunctionType::Location::BareCallCode: case FunctionType::Location::BareDelegateCall: + case FunctionType::Location::Transfer: _memberAccess.expression().accept(*this); m_context << funType->externalIdentifier(); break; @@ -1041,7 +1052,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) ); m_context << Instruction::BALANCE; } - else if ((set{"send", "call", "callcode", "delegatecall"}).count(member)) + else if ((set{"send", "transfer", "call", "callcode", "delegatecall"}).count(member)) utils().convertType( *_memberAccess.expression().annotation().type, IntegerType(0, IntegerType::Modifier::Address), -- cgit