aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/codegen/ABIFunctions.cpp
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2017-10-18 20:53:45 +0800
committerGitHub <noreply@github.com>2017-10-18 20:53:45 +0800
commit9cf6e910bd2b90d0c9415d9c257f85fe0c518de8 (patch)
tree6423baec5e26bbe174005c1a89d978cae15015d8 /libsolidity/codegen/ABIFunctions.cpp
parentbdeb9e52a2211510644fb53df93fb98258b40a65 (diff)
parentc85c41880ad1c996517b0ae14f98678b1e6c5613 (diff)
downloaddexon-solidity-9cf6e910bd2b90d0c9415d9c257f85fe0c518de8.tar
dexon-solidity-9cf6e910bd2b90d0c9415d9c257f85fe0c518de8.tar.gz
dexon-solidity-9cf6e910bd2b90d0c9415d9c257f85fe0c518de8.tar.bz2
dexon-solidity-9cf6e910bd2b90d0c9415d9c257f85fe0c518de8.tar.lz
dexon-solidity-9cf6e910bd2b90d0c9415d9c257f85fe0c518de8.tar.xz
dexon-solidity-9cf6e910bd2b90d0c9415d9c257f85fe0c518de8.tar.zst
dexon-solidity-9cf6e910bd2b90d0c9415d9c257f85fe0c518de8.zip
Merge pull request #3099 from ethereum/develop
Merge develop into release for 0.4.18.
Diffstat (limited to 'libsolidity/codegen/ABIFunctions.cpp')
-rw-r--r--libsolidity/codegen/ABIFunctions.cpp75
1 files changed, 45 insertions, 30 deletions
diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp
index 9f6c55ba..080be359 100644
--- a/libsolidity/codegen/ABIFunctions.cpp
+++ b/libsolidity/codegen/ABIFunctions.cpp
@@ -87,7 +87,7 @@ string ABIFunctions::tupleEncoder(
);
elementTempl("values", valueNames);
elementTempl("pos", to_string(headPos));
- elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], _encodeAsLibraryTypes, false));
+ elementTempl("abiEncode", abiEncodingFunction(*_givenTypes[i], *_targetTypes[i], _encodeAsLibraryTypes, true));
encodeElements += elementTempl.render();
headPos += dynamic ? 0x20 : _targetTypes[i]->calldataEncodedSize();
}
@@ -162,7 +162,7 @@ string ABIFunctions::cleanupFunction(Type const& _type, bool _revertOnFailure)
break;
}
case Type::Category::Contract:
- templ("body", "cleaned := " + cleanupFunction(IntegerType(0, IntegerType::Modifier::Address)) + "(value)");
+ templ("body", "cleaned := " + cleanupFunction(IntegerType(160, IntegerType::Modifier::Address)) + "(value)");
break;
case Type::Category::Enum:
{
@@ -243,7 +243,7 @@ string ABIFunctions::conversionFunction(Type const& _from, Type const& _to)
toCategory == Type::Category::Integer ||
toCategory == Type::Category::Contract,
"");
- IntegerType const addressType(0, IntegerType::Modifier::Address);
+ IntegerType const addressType(160, IntegerType::Modifier::Address);
IntegerType const& to =
toCategory == Type::Category::Integer ?
dynamic_cast<IntegerType const&>(_to) :
@@ -371,7 +371,7 @@ string ABIFunctions::abiEncodingFunction(
Type const& _from,
Type const& _to,
bool _encodeAsLibraryTypes,
- bool _compacted
+ bool _fromStack
)
{
solUnimplementedAssert(
@@ -415,7 +415,7 @@ string ABIFunctions::abiEncodingFunction(
dynamic_cast<FunctionType const&>(_from),
to,
_encodeAsLibraryTypes,
- _compacted
+ _fromStack
);
solAssert(_from.sizeOnStack() == 1, "");
@@ -487,6 +487,7 @@ string ABIFunctions::abiEncodingFunctionCalldataArray(
// TODO if this is not a byte array, we might just copy byte-by-byte anyway,
// because the encoding is position-independent, but we have to check that.
Whiskers templ(R"(
+ // <readableTypeNameFrom> -> <readableTypeNameTo>
function <functionName>(start, length, pos) -> end {
<storeLength> // might update pos
<copyFun>(start, pos, length)
@@ -495,6 +496,8 @@ string ABIFunctions::abiEncodingFunctionCalldataArray(
)");
templ("storeLength", _to.isDynamicallySized() ? "mstore(pos, length) pos := add(pos, 0x20)" : "");
templ("functionName", functionName);
+ templ("readableTypeNameFrom", _from.toString(true));
+ templ("readableTypeNameTo", _to.toString(true));
templ("copyFun", copyToMemoryFunction(true));
templ("roundUpFun", roundUpFunction());
return templ.render();
@@ -527,6 +530,7 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
Whiskers templ(
dynamicBase ?
R"(
+ // <readableTypeNameFrom> -> <readableTypeNameTo>
function <functionName>(value, pos) <return> {
let length := <lengthFun>(value)
<storeLength> // might update pos
@@ -538,13 +542,14 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
mstore(pos, sub(tail, headStart))
tail := <encodeToMemoryFun>(<arrayElementAccess>, tail)
srcPtr := <nextArrayElement>(srcPtr)
- pos := add(pos, <elementEncodedSize>)
+ pos := add(pos, 0x20)
}
pos := tail
<assignEnd>
}
)" :
R"(
+ // <readableTypeNameFrom> -> <readableTypeNameTo>
function <functionName>(value, pos) <return> {
let length := <lengthFun>(value)
<storeLength> // might update pos
@@ -560,6 +565,8 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
)"
);
templ("functionName", functionName);
+ templ("readableTypeNameFrom", _from.toString(true));
+ templ("readableTypeNameTo", _to.toString(true));
templ("return", dynamic ? " -> end " : "");
templ("assignEnd", dynamic ? "end := pos" : "");
templ("lengthFun", arrayLengthFunction(_from));
@@ -573,7 +580,7 @@ string ABIFunctions::abiEncodingFunctionSimpleArray(
*_from.baseType(),
*_to.baseType(),
_encodeAsLibraryTypes,
- true
+ false
));
templ("arrayElementAccess", inMemory ? "mload(srcPtr)" : _from.baseType()->isValueType() ? "sload(srcPtr)" : "srcPtr" );
templ("nextArrayElement", nextArrayElementFunction(_from));
@@ -639,6 +646,7 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
{
solAssert(_to.isByteArray(), "");
Whiskers templ(R"(
+ // <readableTypeNameFrom> -> <readableTypeNameTo>
function <functionName>(value, pos) -> ret {
let slotValue := sload(value)
switch and(slotValue, 1)
@@ -665,6 +673,8 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
}
)");
templ("functionName", functionName);
+ templ("readableTypeNameFrom", _from.toString(true));
+ templ("readableTypeNameTo", _to.toString(true));
templ("arrayDataSlot", arrayDataAreaFunction(_from));
return templ.render();
}
@@ -681,6 +691,7 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
// more than desired, i.e. it writes beyond the end of memory.
Whiskers templ(
R"(
+ // <readableTypeNameFrom> -> <readableTypeNameTo>
function <functionName>(value, pos) <return> {
let length := <lengthFun>(value)
<storeLength> // might update pos
@@ -701,6 +712,8 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
)"
);
templ("functionName", functionName);
+ templ("readableTypeNameFrom", _from.toString(true));
+ templ("readableTypeNameTo", _to.toString(true));
templ("return", dynamic ? " -> end " : "");
templ("assignEnd", dynamic ? "end := pos" : "");
templ("lengthFun", arrayLengthFunction(_from));
@@ -716,7 +729,7 @@ string ABIFunctions::abiEncodingFunctionCompactStorageArray(
*_from.baseType(),
*_to.baseType(),
_encodeAsLibraryTypes,
- true
+ false
);
templ("encodeToMemoryFun", encodeToMemoryFun);
std::vector<std::map<std::string, std::string>> items(itemsPerSlot);
@@ -748,6 +761,7 @@ string ABIFunctions::abiEncodingFunctionStruct(
bool fromStorage = _from.location() == DataLocation::Storage;
bool dynamic = _to.isDynamicallyEncoded();
Whiskers templ(R"(
+ // <readableTypeNameFrom> -> <readableTypeNameTo>
function <functionName>(value, pos) <return> {
let tail := add(pos, <headSize>)
<init>
@@ -761,6 +775,8 @@ string ABIFunctions::abiEncodingFunctionStruct(
}
)");
templ("functionName", functionName);
+ templ("readableTypeNameFrom", _from.toString(true));
+ templ("readableTypeNameTo", _to.toString(true));
templ("return", dynamic ? " -> end " : "");
templ("assignEnd", dynamic ? "end := tail" : "");
// to avoid multiple loads from the same slot for subsequent members
@@ -909,7 +925,7 @@ string ABIFunctions::abiEncodingFunctionFunctionType(
FunctionType const& _from,
Type const& _to,
bool _encodeAsLibraryTypes,
- bool _compacted
+ bool _fromStack
)
{
solAssert(_from.kind() == FunctionType::Kind::External, "");
@@ -920,35 +936,31 @@ string ABIFunctions::abiEncodingFunctionFunctionType(
_from.identifier() +
"_to_" +
_to.identifier() +
- (_compacted ? "_compacted" : "") +
+ (_fromStack ? "_fromStack" : "") +
(_encodeAsLibraryTypes ? "_library" : "");
- if (_compacted)
- {
+ if (_fromStack)
return createFunction(functionName, [&]() {
return Whiskers(R"(
- function <functionName>(addr_and_function_id, pos) {
- mstore(pos, <cleanExtFun>(addr_and_function_id))
+ function <functionName>(addr, function_id, pos) {
+ mstore(pos, <combineExtFun>(addr, function_id))
}
)")
("functionName", functionName)
- ("cleanExtFun", cleanupCombinedExternalFunctionIdFunction())
+ ("combineExtFun", combineExternalFunctionIdFunction())
.render();
});
- }
else
- {
return createFunction(functionName, [&]() {
return Whiskers(R"(
- function <functionName>(addr, function_id, pos) {
- mstore(pos, <combineExtFun>(addr, function_id))
+ function <functionName>(addr_and_function_id, pos) {
+ mstore(pos, <cleanExtFun>(addr_and_function_id))
}
)")
("functionName", functionName)
- ("combineExtFun", combineExternalFunctionIdFunction())
+ ("cleanExtFun", cleanupCombinedExternalFunctionIdFunction())
.render();
});
- }
}
string ABIFunctions::copyToMemoryFunction(bool _fromCalldata)
@@ -995,9 +1007,11 @@ string ABIFunctions::shiftLeftFunction(size_t _numBits)
return createFunction(functionName, [&]() {
solAssert(_numBits < 256, "");
return
- Whiskers(R"(function <functionName>(value) -> newValue {
+ Whiskers(R"(
+ function <functionName>(value) -> newValue {
newValue := mul(value, <multiplier>)
- })")
+ }
+ )")
("functionName", functionName)
("multiplier", toCompactHexWithPrefix(u256(1) << _numBits))
.render();
@@ -1010,9 +1024,11 @@ string ABIFunctions::shiftRightFunction(size_t _numBits, bool _signed)
return createFunction(functionName, [&]() {
solAssert(_numBits < 256, "");
return
- Whiskers(R"(function <functionName>(value) -> newValue {
+ Whiskers(R"(
+ function <functionName>(value) -> newValue {
newValue := <div>(value, <multiplier>)
- })")
+ }
+ )")
("functionName", functionName)
("div", _signed ? "sdiv" : "div")
("multiplier", toCompactHexWithPrefix(u256(1) << _numBits))
@@ -1025,9 +1041,11 @@ string ABIFunctions::roundUpFunction()
string functionName = "round_up_to_mul_of_32";
return createFunction(functionName, [&]() {
return
- Whiskers(R"(function <functionName>(value) -> result {
+ Whiskers(R"(
+ function <functionName>(value) -> result {
result := and(add(value, 31), not(31))
- })")
+ }
+ )")
("functionName", functionName)
.render();
});
@@ -1190,10 +1208,7 @@ size_t ABIFunctions::headSize(TypePointers const& _targetTypes)
if (t->isDynamicallyEncoded())
headSize += 0x20;
else
- {
- solAssert(t->calldataEncodedSize() > 0, "");
headSize += t->calldataEncodedSize();
- }
}
return headSize;