Do not store immutables packed.

This commit is contained in:
chriseth 2021-09-28 16:41:32 +02:00
parent ed7884e341
commit 90f4ca1048
5 changed files with 50 additions and 7 deletions

View File

@ -95,9 +95,9 @@ public:
/// @returns the number of bytes consumed in memory. /// @returns the number of bytes consumed in memory.
unsigned loadFromMemory( unsigned loadFromMemory(
unsigned _offset, unsigned _offset,
Type const& _type = *TypeProvider::uint256(), Type const& _type,
bool _fromCalldata = false, bool _fromCalldata,
bool _padToWords = false bool _padToWords
); );
/// Dynamic version of @see loadFromMemory, expects the memory offset on the stack. /// Dynamic version of @see loadFromMemory, expects the memory offset on the stack.
/// Stack pre: memory_offset /// Stack pre: memory_offset

View File

@ -192,7 +192,12 @@ size_t ContractCompiler::packIntoContractCreator(ContractDefinition const& _cont
auto const& immutables = contractType.immutableVariables(); auto const& immutables = contractType.immutableVariables();
// Push all immutable values on the stack. // Push all immutable values on the stack.
for (auto const& immutable: immutables) for (auto const& immutable: immutables)
CompilerUtils(m_context).loadFromMemory(static_cast<unsigned>(m_context.immutableMemoryOffset(*immutable)), *immutable->annotation().type); CompilerUtils(m_context).loadFromMemory(
static_cast<unsigned>(m_context.immutableMemoryOffset(*immutable)),
*immutable->annotation().type,
false,
true
);
m_context.pushSubroutineSize(m_context.runtimeSub()); m_context.pushSubroutineSize(m_context.runtimeSub());
if (immutables.empty()) if (immutables.empty())
m_context << Instruction::DUP1; m_context << Instruction::DUP1;
@ -439,7 +444,7 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac
// retrieve the function signature hash from the calldata // retrieve the function signature hash from the calldata
if (!interfaceFunctions.empty()) if (!interfaceFunctions.empty())
{ {
CompilerUtils(m_context).loadFromMemory(0, IntegerType(CompilerUtils::dataStartOffset * 8), true); CompilerUtils(m_context).loadFromMemory(0, IntegerType(CompilerUtils::dataStartOffset * 8), true, false);
// stack now is: <can-call-non-view-functions>? <funhash> // stack now is: <can-call-non-view-functions>? <funhash>
vector<FixedHash<4>> sortedIDs; vector<FixedHash<4>> sortedIDs;

View File

@ -159,7 +159,9 @@ void ImmutableItem::retrieveValue(SourceLocation const&, bool) const
if (m_context.runtimeContext()) if (m_context.runtimeContext())
CompilerUtils(m_context).loadFromMemory( CompilerUtils(m_context).loadFromMemory(
static_cast<unsigned>(m_context.immutableMemoryOffset(m_variable)), static_cast<unsigned>(m_context.immutableMemoryOffset(m_variable)),
*m_dataType *m_dataType,
false,
true
); );
else else
for (auto&& slotName: m_context.immutableVariableSlotNames(m_variable)) for (auto&& slotName: m_context.immutableVariableSlotNames(m_variable))
@ -178,7 +180,7 @@ void ImmutableItem::storeValue(Type const& _sourceType, SourceLocation const&, b
utils.moveIntoStack(m_dataType->sizeOnStack()); utils.moveIntoStack(m_dataType->sizeOnStack());
else else
utils.copyToStackTop(m_dataType->sizeOnStack() + 1, m_dataType->sizeOnStack()); utils.copyToStackTop(m_dataType->sizeOnStack() + 1, m_dataType->sizeOnStack());
utils.storeInMemoryDynamic(*m_dataType, false); utils.storeInMemoryDynamic(*m_dataType);
m_context << Instruction::POP; m_context << Instruction::POP;
} }

View File

@ -0,0 +1,15 @@
contract C {
int8 immutable a = -2;
bytes2 immutable b = "ab";
function() internal returns (uint) immutable f = g;
function viaasm() view external returns (bytes32 x, bytes32 y) {
int8 _a = a;
bytes2 _b = b;
assembly { x := _a y := _b }
}
function g() internal pure returns (uint) { return 2; }
}
// ====
// compileViaYul: also
// ----
// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000

View File

@ -0,0 +1,21 @@
contract A {
uint16 public immutable a;
uint16 public immutable b;
uint16 public immutable c;
uint16[3] public x;
constructor() {
c = 0xffff;
b = 0x0f0f;
a = 0x1234;
x = [a, b, c];
}
}
// ====
// compileViaYul: also
// ----
// a() -> 4660
// b() -> 0x0f0f
// c() -> 0xffff
// x(uint256): 0 -> 4660
// x(uint256): 1 -> 0x0f0f
// x(uint256): 2 -> 0xffff