Merge pull request #2975 from ethereum/encode-memory

Split encodeToMemory into packedEncode and abiEncode
This commit is contained in:
Alex Beregszaszi 2017-09-27 13:04:37 +01:00 committed by GitHub
commit 3f783c8dad
4 changed files with 45 additions and 22 deletions

View File

@ -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

View File

@ -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.

View File

@ -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;
} }

View File

@ -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));