mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #2975 from ethereum/encode-memory
Split encodeToMemory into packedEncode and abiEncode
This commit is contained in:
commit
3f783c8dad
@ -191,7 +191,7 @@ void CompilerUtils::encodeToMemory(
|
|||||||
{
|
{
|
||||||
// Use the new JULIA-based encoding function
|
// Use the new JULIA-based encoding function
|
||||||
auto stackHeightBefore = m_context.stackHeight();
|
auto stackHeightBefore = m_context.stackHeight();
|
||||||
abiEncode(_givenTypes, targetTypes, _encodeAsLibraryTypes);
|
abiEncodeV2(_givenTypes, targetTypes, _encodeAsLibraryTypes);
|
||||||
solAssert(stackHeightBefore - m_context.stackHeight() == sizeOnStack(_givenTypes), "");
|
solAssert(stackHeightBefore - m_context.stackHeight() == sizeOnStack(_givenTypes), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -302,7 +302,7 @@ void CompilerUtils::encodeToMemory(
|
|||||||
popStackSlots(argSize + dynPointers + 1);
|
popStackSlots(argSize + dynPointers + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerUtils::abiEncode(
|
void CompilerUtils::abiEncodeV2(
|
||||||
TypePointers const& _givenTypes,
|
TypePointers const& _givenTypes,
|
||||||
TypePointers const& _targetTypes,
|
TypePointers const& _targetTypes,
|
||||||
bool _encodeAsLibraryTypes
|
bool _encodeAsLibraryTypes
|
||||||
|
@ -102,13 +102,26 @@ public:
|
|||||||
/// @note the locations of target reference types are ignored, because it will always be
|
/// @note the locations of target reference types are ignored, because it will always be
|
||||||
/// memory.
|
/// memory.
|
||||||
void encodeToMemory(
|
void encodeToMemory(
|
||||||
TypePointers const& _givenTypes = {},
|
TypePointers const& _givenTypes,
|
||||||
TypePointers const& _targetTypes = {},
|
TypePointers const& _targetTypes,
|
||||||
bool _padToWords = true,
|
bool _padToWords,
|
||||||
bool _copyDynamicDataInPlace = false,
|
bool _copyDynamicDataInPlace,
|
||||||
bool _encodeAsLibraryTypes = false
|
bool _encodeAsLibraryTypes = false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Special case of @a encodeToMemory which assumes tight packing, e.g. no zero padding
|
||||||
|
/// and dynamic data is encoded in-place.
|
||||||
|
/// Stack pre: <value0> <value1> ... <valueN-1> <head_start>
|
||||||
|
/// Stack post: <mem_ptr>
|
||||||
|
void packedEncode(
|
||||||
|
TypePointers const& _givenTypes,
|
||||||
|
TypePointers const& _targetTypes,
|
||||||
|
bool _encodeAsLibraryTypes = false
|
||||||
|
)
|
||||||
|
{
|
||||||
|
encodeToMemory(_givenTypes, _targetTypes, false, true, _encodeAsLibraryTypes);
|
||||||
|
}
|
||||||
|
|
||||||
/// Special case of @a encodeToMemory which assumes that everything is padded to words
|
/// Special case of @a encodeToMemory which assumes that everything is padded to words
|
||||||
/// and dynamic data is not copied in place (i.e. a proper ABI encoding).
|
/// and dynamic data is not copied in place (i.e. a proper ABI encoding).
|
||||||
/// Stack pre: <value0> <value1> ... <valueN-1> <head_start>
|
/// Stack pre: <value0> <value1> ... <valueN-1> <head_start>
|
||||||
@ -117,6 +130,20 @@ public:
|
|||||||
TypePointers const& _givenTypes,
|
TypePointers const& _givenTypes,
|
||||||
TypePointers const& _targetTypes,
|
TypePointers const& _targetTypes,
|
||||||
bool _encodeAsLibraryTypes = false
|
bool _encodeAsLibraryTypes = false
|
||||||
|
)
|
||||||
|
{
|
||||||
|
encodeToMemory(_givenTypes, _targetTypes, true, false, _encodeAsLibraryTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Special case of @a encodeToMemory which assumes that everything is padded to words
|
||||||
|
/// and dynamic data is not copied in place (i.e. a proper ABI encoding).
|
||||||
|
/// Uses a new, less tested encoder implementation.
|
||||||
|
/// Stack pre: <value0> <value1> ... <valueN-1> <head_start>
|
||||||
|
/// Stack post: <mem_ptr>
|
||||||
|
void abiEncodeV2(
|
||||||
|
TypePointers const& _givenTypes,
|
||||||
|
TypePointers const& _targetTypes,
|
||||||
|
bool _encodeAsLibraryTypes = false
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Zero-initialises (the data part of) an already allocated memory array.
|
/// Zero-initialises (the data part of) an already allocated memory array.
|
||||||
|
@ -421,7 +421,7 @@ void ContractCompiler::appendReturnValuePacker(TypePointers const& _typeParamete
|
|||||||
utils.fetchFreeMemoryPointer();
|
utils.fetchFreeMemoryPointer();
|
||||||
//@todo optimization: if we return a single memory array, there should be enough space before
|
//@todo optimization: if we return a single memory array, there should be enough space before
|
||||||
// its data to add the needed parts and we avoid a memory copy.
|
// its data to add the needed parts and we avoid a memory copy.
|
||||||
utils.encodeToMemory(_typeParameters, _typeParameters, true, false, _isLibrary);
|
utils.abiEncode(_typeParameters, _typeParameters, _isLibrary);
|
||||||
utils.toSizeAfterFreeMemoryPointer();
|
utils.toSizeAfterFreeMemoryPointer();
|
||||||
m_context << Instruction::RETURN;
|
m_context << Instruction::RETURN;
|
||||||
}
|
}
|
||||||
|
@ -581,7 +581,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
_context << Instruction::ADD;
|
_context << Instruction::ADD;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
utils().encodeToMemory(argumentTypes, function.parameterTypes());
|
utils().abiEncode(argumentTypes, function.parameterTypes());
|
||||||
// now on stack: memory_end_ptr
|
// now on stack: memory_end_ptr
|
||||||
// need: size, offset, endowment
|
// need: size, offset, endowment
|
||||||
utils().toSizeAfterFreeMemoryPointer();
|
utils().toSizeAfterFreeMemoryPointer();
|
||||||
@ -675,7 +675,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
argumentTypes.push_back(arg->annotation().type);
|
argumentTypes.push_back(arg->annotation().type);
|
||||||
}
|
}
|
||||||
utils().fetchFreeMemoryPointer();
|
utils().fetchFreeMemoryPointer();
|
||||||
utils().encodeToMemory(argumentTypes, TypePointers(), function.padArguments(), true);
|
solAssert(!function.padArguments(), "");
|
||||||
|
utils().packedEncode(argumentTypes, TypePointers());
|
||||||
utils().toSizeAfterFreeMemoryPointer();
|
utils().toSizeAfterFreeMemoryPointer();
|
||||||
m_context << Instruction::KECCAK256;
|
m_context << Instruction::KECCAK256;
|
||||||
break;
|
break;
|
||||||
@ -694,11 +695,10 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
}
|
}
|
||||||
arguments.front()->accept(*this);
|
arguments.front()->accept(*this);
|
||||||
utils().fetchFreeMemoryPointer();
|
utils().fetchFreeMemoryPointer();
|
||||||
utils().encodeToMemory(
|
utils().packedEncode(
|
||||||
{arguments.front()->annotation().type},
|
{arguments.front()->annotation().type},
|
||||||
{function.parameterTypes().front()},
|
{function.parameterTypes().front()}
|
||||||
false,
|
);
|
||||||
true);
|
|
||||||
utils().toSizeAfterFreeMemoryPointer();
|
utils().toSizeAfterFreeMemoryPointer();
|
||||||
m_context << logInstruction(logNumber);
|
m_context << logInstruction(logNumber);
|
||||||
break;
|
break;
|
||||||
@ -717,11 +717,9 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
if (auto const& arrayType = dynamic_pointer_cast<ArrayType const>(function.parameterTypes()[arg - 1]))
|
if (auto const& arrayType = dynamic_pointer_cast<ArrayType const>(function.parameterTypes()[arg - 1]))
|
||||||
{
|
{
|
||||||
utils().fetchFreeMemoryPointer();
|
utils().fetchFreeMemoryPointer();
|
||||||
utils().encodeToMemory(
|
utils().packedEncode(
|
||||||
{arguments[arg - 1]->annotation().type},
|
{arguments[arg - 1]->annotation().type},
|
||||||
{arrayType},
|
{arrayType}
|
||||||
false,
|
|
||||||
true
|
|
||||||
);
|
);
|
||||||
utils().toSizeAfterFreeMemoryPointer();
|
utils().toSizeAfterFreeMemoryPointer();
|
||||||
m_context << Instruction::KECCAK256;
|
m_context << Instruction::KECCAK256;
|
||||||
@ -751,7 +749,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
nonIndexedParamTypes.push_back(function.parameterTypes()[arg]);
|
nonIndexedParamTypes.push_back(function.parameterTypes()[arg]);
|
||||||
}
|
}
|
||||||
utils().fetchFreeMemoryPointer();
|
utils().fetchFreeMemoryPointer();
|
||||||
utils().encodeToMemory(nonIndexedArgTypes, nonIndexedParamTypes);
|
utils().abiEncode(nonIndexedArgTypes, nonIndexedParamTypes);
|
||||||
// need: topic1 ... topicn memsize memstart
|
// need: topic1 ... topicn memsize memstart
|
||||||
utils().toSizeAfterFreeMemoryPointer();
|
utils().toSizeAfterFreeMemoryPointer();
|
||||||
m_context << logInstruction(numIndexed);
|
m_context << logInstruction(numIndexed);
|
||||||
@ -1212,11 +1210,9 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
|
|||||||
utils().fetchFreeMemoryPointer();
|
utils().fetchFreeMemoryPointer();
|
||||||
// stack: base index mem
|
// stack: base index mem
|
||||||
// note: the following operations must not allocate memory!
|
// note: the following operations must not allocate memory!
|
||||||
utils().encodeToMemory(
|
utils().packedEncode(
|
||||||
TypePointers{_indexAccess.indexExpression()->annotation().type},
|
TypePointers{_indexAccess.indexExpression()->annotation().type},
|
||||||
TypePointers{keyType},
|
TypePointers{keyType}
|
||||||
false,
|
|
||||||
true
|
|
||||||
);
|
);
|
||||||
m_context << Instruction::SWAP1;
|
m_context << Instruction::SWAP1;
|
||||||
utils().storeInMemoryDynamic(IntegerType(256));
|
utils().storeInMemoryDynamic(IntegerType(256));
|
||||||
|
Loading…
Reference in New Issue
Block a user