aboutsummaryrefslogtreecommitdiffstats
path: root/ExpressionCompiler.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-05-16 00:02:09 +0800
committerchriseth <c@ethdev.com>2015-05-16 00:02:09 +0800
commitdba5ffc280c363b445fb8fcc22737605f2c61498 (patch)
tree57d5ffc9310b8245973b2ea0649ea5930fdcc7c6 /ExpressionCompiler.cpp
parent33e708605881614acefaae2c324732299d7f61fb (diff)
downloaddexon-solidity-dba5ffc280c363b445fb8fcc22737605f2c61498.tar.gz
dexon-solidity-dba5ffc280c363b445fb8fcc22737605f2c61498.tar.zst
dexon-solidity-dba5ffc280c363b445fb8fcc22737605f2c61498.zip
Bare callcode for addresses and contracts.
Diffstat (limited to 'ExpressionCompiler.cpp')
-rw-r--r--ExpressionCompiler.cpp37
1 files changed, 23 insertions, 14 deletions
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 76d05bd0..838ee264 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -458,9 +458,11 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
break;
}
case Location::External:
+ case Location::CallCode:
case Location::Bare:
+ case Location::BareCallCode:
_functionCall.getExpression().accept(*this);
- appendExternalFunctionCall(function, arguments, function.getLocation() == Location::Bare);
+ appendExternalFunctionCall(function, arguments);
break;
case Location::Creation:
{
@@ -527,13 +529,12 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
TypePointers{},
strings(),
strings(),
- Location::External,
+ Location::Bare,
false,
true,
true
),
- {},
- true
+ {}
);
break;
case Location::Suicide:
@@ -622,7 +623,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
m_context << contractAddresses.find(function.getLocation())->second;
for (unsigned i = function.getSizeOnStack(); i > 0; --i)
m_context << eth::swapInstruction(i);
- appendExternalFunctionCall(function, arguments, true);
+ appendExternalFunctionCall(function, arguments);
break;
}
default:
@@ -685,7 +686,7 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
IntegerType(0, IntegerType::Modifier::Address), true);
m_context << eth::Instruction::BALANCE;
}
- else if (member == "send" || member.substr(0, min<size_t>(member.size(), 4)) == "call")
+ else if ((set<string>{"send", "call", "callcode"}).count(member))
appendTypeConversion(*_memberAccess.getExpression().getType(),
IntegerType(0, IntegerType::Modifier::Address), true);
else
@@ -1031,9 +1032,10 @@ void ExpressionCompiler::appendHighBitsCleanup(IntegerType const& _typeOnStack)
m_context << ((u256(1) << _typeOnStack.getNumBits()) - 1) << eth::Instruction::AND;
}
-void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functionType,
- vector<ASTPointer<Expression const>> const& _arguments,
- bool bare)
+void ExpressionCompiler::appendExternalFunctionCall(
+ FunctionType const& _functionType,
+ vector<ASTPointer<Expression const>> const& _arguments
+)
{
solAssert(_functionType.takesArbitraryParameters() ||
_arguments.size() == _functionType.getParameterTypes().size(), "");
@@ -1047,7 +1049,7 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
unsigned gasValueSize = (_functionType.gasSet() ? 1 : 0) + (_functionType.valueSet() ? 1 : 0);
- unsigned contractStackPos = m_context.currentToBaseStackOffset(1 + gasValueSize + (bare ? 0 : 1));
+ unsigned contractStackPos = m_context.currentToBaseStackOffset(1 + gasValueSize + (_functionType.isBareCall() ? 0 : 1));
unsigned gasStackPos = m_context.currentToBaseStackOffset(gasValueSize);
unsigned valueStackPos = m_context.currentToBaseStackOffset(1);
@@ -1057,7 +1059,7 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
unsigned retSize = firstType ? firstType->getCalldataEncodedSize() : 0;
m_context << u256(retSize) << u256(0);
- if (bare)
+ if (_functionType.isBareCall())
m_context << u256(0);
else
{
@@ -1074,7 +1076,8 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
_arguments,
_functionType.getParameterTypes(),
_functionType.padArguments(),
- bare,
+ _functionType.getLocation() == FunctionType::Location::Bare ||
+ _functionType.getLocation() == FunctionType::Location::BareCallCode,
_functionType.takesArbitraryParameters()
);
@@ -1093,14 +1096,20 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
// send all gas except the amount needed to execute "SUB" and "CALL"
// @todo this retains too much gas for now, needs to be fine-tuned.
m_context << u256(50 + (_functionType.valueSet() ? 9000 : 0) + 25000) << eth::Instruction::GAS << eth::Instruction::SUB;
- m_context << eth::Instruction::CALL;
+ if (
+ _functionType.getLocation() == FunctionType::Location::CallCode ||
+ _functionType.getLocation() == FunctionType::Location::BareCallCode
+ )
+ m_context << eth::Instruction::CALLCODE;
+ else
+ m_context << eth::Instruction::CALL;
auto tag = m_context.appendConditionalJump();
m_context << eth::Instruction::STOP << tag; // STOP if CALL leaves 0.
if (_functionType.valueSet())
m_context << eth::Instruction::POP;
if (_functionType.gasSet())
m_context << eth::Instruction::POP;
- if (!bare)
+ if (!_functionType.isBareCall())
m_context << eth::Instruction::POP;
m_context << eth::Instruction::POP; // pop contract address