mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add allocateMemory helper with value known at compile time
This commit is contained in:
parent
9c80f0fc76
commit
a96cc6e0e8
@ -70,6 +70,13 @@ void CompilerUtils::allocateMemory()
|
|||||||
storeFreeMemoryPointer();
|
storeFreeMemoryPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CompilerUtils::allocateMemory(u256 const& size)
|
||||||
|
{
|
||||||
|
fetchFreeMemoryPointer();
|
||||||
|
m_context << Instruction::DUP1 << size << Instruction::ADD;
|
||||||
|
storeFreeMemoryPointer();
|
||||||
|
}
|
||||||
|
|
||||||
void CompilerUtils::toSizeAfterFreeMemoryPointer()
|
void CompilerUtils::toSizeAfterFreeMemoryPointer()
|
||||||
{
|
{
|
||||||
fetchFreeMemoryPointer();
|
fetchFreeMemoryPointer();
|
||||||
@ -813,9 +820,8 @@ void CompilerUtils::convertType(
|
|||||||
{
|
{
|
||||||
auto const& arrayType = dynamic_cast<ArrayType const&>(_targetType);
|
auto const& arrayType = dynamic_cast<ArrayType const&>(_targetType);
|
||||||
solAssert(arrayType.isByteArray(), "");
|
solAssert(arrayType.isByteArray(), "");
|
||||||
u256 storageSize(32 + ((data.size() + 31) / 32) * 32);
|
unsigned storageSize = 32 + ((data.size() + 31) / 32) * 32;
|
||||||
m_context << storageSize;
|
allocateMemory(storageSize);
|
||||||
allocateMemory();
|
|
||||||
// stack: mempos
|
// stack: mempos
|
||||||
m_context << Instruction::DUP1 << u256(data.size());
|
m_context << Instruction::DUP1 << u256(data.size());
|
||||||
storeInMemoryDynamic(IntegerType::uint256());
|
storeInMemoryDynamic(IntegerType::uint256());
|
||||||
@ -938,8 +944,7 @@ void CompilerUtils::convertType(
|
|||||||
{
|
{
|
||||||
case DataLocation::Storage:
|
case DataLocation::Storage:
|
||||||
// stack: <source ref>
|
// stack: <source ref>
|
||||||
m_context << typeOnStack.memorySize();
|
allocateMemory(typeOnStack.memorySize());
|
||||||
allocateMemory();
|
|
||||||
m_context << Instruction::SWAP1 << Instruction::DUP2;
|
m_context << Instruction::SWAP1 << Instruction::DUP2;
|
||||||
// stack: <memory ptr> <source ref> <memory ptr>
|
// stack: <memory ptr> <source ref> <memory ptr>
|
||||||
for (auto const& member: typeOnStack.members(nullptr))
|
for (auto const& member: typeOnStack.members(nullptr))
|
||||||
@ -1103,8 +1108,7 @@ void CompilerUtils::pushZeroValue(Type const& _type)
|
|||||||
1,
|
1,
|
||||||
[type](CompilerContext& _context) {
|
[type](CompilerContext& _context) {
|
||||||
CompilerUtils utils(_context);
|
CompilerUtils utils(_context);
|
||||||
_context << u256(max(32u, type->calldataEncodedSize()));
|
utils.allocateMemory(max(32u, type->calldataEncodedSize()));
|
||||||
utils.allocateMemory();
|
|
||||||
_context << Instruction::DUP1;
|
_context << Instruction::DUP1;
|
||||||
|
|
||||||
if (auto structType = dynamic_cast<StructType const*>(type.get()))
|
if (auto structType = dynamic_cast<StructType const*>(type.get()))
|
||||||
|
@ -49,6 +49,10 @@ public:
|
|||||||
/// Stack pre: <size>
|
/// Stack pre: <size>
|
||||||
/// Stack post: <mem_start>
|
/// Stack post: <mem_start>
|
||||||
void allocateMemory();
|
void allocateMemory();
|
||||||
|
/// Allocates a number of bytes in memory as given on the stack.
|
||||||
|
/// Stack pre:
|
||||||
|
/// Stack post: <mem_start>
|
||||||
|
void allocateMemory(u256 const& size);
|
||||||
/// Appends code that transforms memptr to (memptr - free_memptr) memptr
|
/// Appends code that transforms memptr to (memptr - free_memptr) memptr
|
||||||
/// Stack pre: <mem_end>
|
/// Stack pre: <mem_end>
|
||||||
/// Stack post: <size> <mem_start>
|
/// Stack post: <size> <mem_start>
|
||||||
|
@ -317,8 +317,7 @@ bool ExpressionCompiler::visit(TupleExpression const& _tuple)
|
|||||||
ArrayType const& arrayType = dynamic_cast<ArrayType const&>(*_tuple.annotation().type);
|
ArrayType const& arrayType = dynamic_cast<ArrayType const&>(*_tuple.annotation().type);
|
||||||
|
|
||||||
solAssert(!arrayType.isDynamicallySized(), "Cannot create dynamically sized inline array.");
|
solAssert(!arrayType.isDynamicallySized(), "Cannot create dynamically sized inline array.");
|
||||||
m_context << max(u256(32u), arrayType.memorySize());
|
utils().allocateMemory(max(u256(32u), arrayType.memorySize()));
|
||||||
utils().allocateMemory();
|
|
||||||
m_context << Instruction::DUP1;
|
m_context << Instruction::DUP1;
|
||||||
|
|
||||||
for (auto const& component: _tuple.components())
|
for (auto const& component: _tuple.components())
|
||||||
@ -527,8 +526,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
|||||||
TypeType const& type = dynamic_cast<TypeType const&>(*_functionCall.expression().annotation().type);
|
TypeType const& type = dynamic_cast<TypeType const&>(*_functionCall.expression().annotation().type);
|
||||||
auto const& structType = dynamic_cast<StructType const&>(*type.actualType());
|
auto const& structType = dynamic_cast<StructType const&>(*type.actualType());
|
||||||
|
|
||||||
m_context << max(u256(32u), structType.memorySize());
|
utils().allocateMemory(max(u256(32u), structType.memorySize()));
|
||||||
utils().allocateMemory();
|
|
||||||
m_context << Instruction::DUP1;
|
m_context << Instruction::DUP1;
|
||||||
|
|
||||||
for (unsigned i = 0; i < arguments.size(); ++i)
|
for (unsigned i = 0; i < arguments.size(); ++i)
|
||||||
@ -1396,8 +1394,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
|||||||
{
|
{
|
||||||
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
|
TypePointer arg = dynamic_cast<MagicType const&>(*_memberAccess.expression().annotation().type).typeArgument();
|
||||||
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();
|
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*arg).contractDefinition();
|
||||||
m_context << u256(contract.name().length() + 32);
|
utils().allocateMemory(contract.name().length() + 32);
|
||||||
utils().allocateMemory();
|
|
||||||
// store string length
|
// store string length
|
||||||
m_context << u256(contract.name().length()) << Instruction::DUP2 << Instruction::MSTORE;
|
m_context << u256(contract.name().length()) << Instruction::DUP2 << Instruction::MSTORE;
|
||||||
// adjust pointer
|
// adjust pointer
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
======= gas_test_abiv2/input.sol:C =======
|
======= gas_test_abiv2/input.sol:C =======
|
||||||
Gas estimation:
|
Gas estimation:
|
||||||
construction:
|
construction:
|
||||||
1147 + 1103200 = 1104347
|
1147 + 1103000 = 1104147
|
||||||
external:
|
external:
|
||||||
a(): 530
|
a(): 530
|
||||||
b(uint256): 1124
|
b(uint256): 1124
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
======= gas_test_abiv2_optimize_yul/input.sol:C =======
|
======= gas_test_abiv2_optimize_yul/input.sol:C =======
|
||||||
Gas estimation:
|
Gas estimation:
|
||||||
construction:
|
construction:
|
||||||
651 + 617600 = 618251
|
651 + 617400 = 618051
|
||||||
external:
|
external:
|
||||||
a(): 429
|
a(): 429
|
||||||
b(uint256): 887
|
b(uint256): 887
|
||||||
|
Loading…
Reference in New Issue
Block a user