mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Adjust data section size during creation.
This commit is contained in:
parent
b8f74c968e
commit
b73d082809
@ -71,6 +71,7 @@ public:
|
||||
|
||||
IRGenerationContext(
|
||||
langutil::EVMVersion _evmVersion,
|
||||
std::optional<uint8_t> _eofVersion,
|
||||
ExecutionContext _executionContext,
|
||||
RevertStrings _revertStrings,
|
||||
OptimiserSettings _optimiserSettings,
|
||||
@ -79,6 +80,7 @@ public:
|
||||
langutil::CharStreamProvider const* _soliditySourceProvider
|
||||
):
|
||||
m_evmVersion(_evmVersion),
|
||||
m_eofVersion(_eofVersion),
|
||||
m_executionContext(_executionContext),
|
||||
m_revertStrings(_revertStrings),
|
||||
m_optimiserSettings(std::move(_optimiserSettings)),
|
||||
@ -149,6 +151,7 @@ public:
|
||||
YulUtilFunctions utils();
|
||||
|
||||
langutil::EVMVersion evmVersion() const { return m_evmVersion; }
|
||||
std::optional<uint8_t> eofVersion() const { return m_eofVersion; }
|
||||
ExecutionContext executionContext() const { return m_executionContext; }
|
||||
|
||||
void setArithmetic(Arithmetic _value) { m_arithmetic = _value; }
|
||||
@ -182,6 +185,7 @@ public:
|
||||
|
||||
private:
|
||||
langutil::EVMVersion m_evmVersion;
|
||||
std::optional<uint8_t> m_eofVersion;
|
||||
ExecutionContext m_executionContext;
|
||||
RevertStrings m_revertStrings;
|
||||
OptimiserSettings m_optimiserSettings;
|
||||
|
@ -1110,6 +1110,7 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon
|
||||
);
|
||||
IRGenerationContext newContext(
|
||||
m_evmVersion,
|
||||
m_eofVersion,
|
||||
_context,
|
||||
m_context.revertStrings(),
|
||||
m_optimiserSettings,
|
||||
|
@ -58,6 +58,7 @@ public:
|
||||
m_optimiserSettings(_optimiserSettings),
|
||||
m_context(
|
||||
_evmVersion,
|
||||
_eofVersion,
|
||||
ExecutionContext::Creation,
|
||||
_revertStrings,
|
||||
std::move(_optimiserSettings),
|
||||
|
@ -1483,10 +1483,21 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
m_context.subObjectsCreated().insert(contract);
|
||||
|
||||
Whiskers t(R"(let <memPos> := <allocateUnbounded>()
|
||||
let <memEnd> := add(<memPos>, datasize("<object>"))
|
||||
if or(gt(<memEnd>, 0xffffffffffffffff), lt(<memEnd>, <memPos>)) { <panic>() }
|
||||
let <argPos> := add(<memPos>, datasize("<object>"))
|
||||
if or(gt(<argPos>, 0xffffffffffffffff), lt(<argPos>, <memPos>)) { <panic>() }
|
||||
datacopy(<memPos>, dataoffset("<object>"), datasize("<object>"))
|
||||
<memEnd> := <abiEncode>(<memEnd><constructorParams>)
|
||||
let <memEnd> := <abiEncode>(<argPos><constructorParams>)
|
||||
<?eof>
|
||||
// TODO: this is horrible and hopefully avoided at the spec level
|
||||
let <argSize> := sub(<memEnd>, <argPos>)
|
||||
let <numCodeSections> := shr(240, mload(add(<memPos>, 7)))
|
||||
let <dataSectionOffset> := add(<memPos>, add(10, mul(<numCodeSections>, 2)))
|
||||
let <tmp> := mload(<dataSectionOffset>)
|
||||
let <dataSectionSize> := shr(240, <tmp>)
|
||||
<dataSectionSize> := add(<dataSectionSize>, <argSize>)
|
||||
if gt(<dataSectionSize>, 0xFFFF) { <panic>() }
|
||||
mstore(<dataSectionOffset>, or(shr(16, shl(16, <tmp>)), shl(240, <dataSectionSize>)))
|
||||
</eof>
|
||||
<?saltSet>
|
||||
let <address> := create2(<value>, <memPos>, sub(<memEnd>, <memPos>), <salt>)
|
||||
<!saltSet>
|
||||
@ -1498,7 +1509,17 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
if iszero(<address>) { <forwardingRevert>() }
|
||||
</isTryCall>
|
||||
)");
|
||||
t("eof", m_context.eofVersion().has_value());
|
||||
if (m_context.eofVersion().has_value())
|
||||
{
|
||||
t("argSize", m_context.newYulVariable());
|
||||
t("numCodeSections", m_context.newYulVariable());
|
||||
t("dataSectionOffset", m_context.newYulVariable());
|
||||
t("dataSectionSize", m_context.newYulVariable());
|
||||
t("tmp", m_context.newYulVariable());
|
||||
}
|
||||
t("memPos", m_context.newYulVariable());
|
||||
t("argPos", m_context.newYulVariable());
|
||||
t("memEnd", m_context.newYulVariable());
|
||||
t("allocateUnbounded", m_utils.allocateUnboundedFunction());
|
||||
t("object", IRNames::creationObject(*contract));
|
||||
|
@ -5,14 +5,31 @@ contract D {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this is horrible and hopefully avoided at the spec level
|
||||
function adjustContractCodeForArgSize(bytes memory x, uint16 argSize)
|
||||
{
|
||||
assembly {
|
||||
let memPos := add(x, 32)
|
||||
let numCodeSections := shr(240, mload(add(memPos, 7)))
|
||||
let dataSectionSizeOffset := add(memPos, add(10, mul(numCodeSections, 2)))
|
||||
let tmp := mload(dataSectionSizeOffset)
|
||||
let dataSectionSize := shr(240, tmp)
|
||||
dataSectionSize := add(dataSectionSize, argSize)
|
||||
if gt(dataSectionSize, 0xFFFF) { revert(0,0) }
|
||||
mstore(dataSectionSizeOffset, or(shr(16, shl(16, tmp)), shl(240, dataSectionSize)))
|
||||
}
|
||||
}
|
||||
|
||||
contract C {
|
||||
function createDSalted(bytes32 salt, uint arg) public {
|
||||
bytes memory creationCode = type(D).creationCode;
|
||||
adjustContractCodeForArgSize(creationCode, 32);
|
||||
address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
|
||||
bytes1(0xff),
|
||||
address(this),
|
||||
salt,
|
||||
keccak256(abi.encodePacked(
|
||||
type(D).creationCode,
|
||||
creationCode,
|
||||
arg
|
||||
))
|
||||
)))));
|
||||
|
Loading…
Reference in New Issue
Block a user