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
62ccf2efc4
commit
b055325a8e
@ -71,6 +71,7 @@ public:
|
|||||||
|
|
||||||
IRGenerationContext(
|
IRGenerationContext(
|
||||||
langutil::EVMVersion _evmVersion,
|
langutil::EVMVersion _evmVersion,
|
||||||
|
std::optional<uint8_t> _eofVersion,
|
||||||
ExecutionContext _executionContext,
|
ExecutionContext _executionContext,
|
||||||
RevertStrings _revertStrings,
|
RevertStrings _revertStrings,
|
||||||
OptimiserSettings _optimiserSettings,
|
OptimiserSettings _optimiserSettings,
|
||||||
@ -79,6 +80,7 @@ public:
|
|||||||
langutil::CharStreamProvider const* _soliditySourceProvider
|
langutil::CharStreamProvider const* _soliditySourceProvider
|
||||||
):
|
):
|
||||||
m_evmVersion(_evmVersion),
|
m_evmVersion(_evmVersion),
|
||||||
|
m_eofVersion(_eofVersion),
|
||||||
m_executionContext(_executionContext),
|
m_executionContext(_executionContext),
|
||||||
m_revertStrings(_revertStrings),
|
m_revertStrings(_revertStrings),
|
||||||
m_optimiserSettings(std::move(_optimiserSettings)),
|
m_optimiserSettings(std::move(_optimiserSettings)),
|
||||||
@ -149,6 +151,7 @@ public:
|
|||||||
YulUtilFunctions utils();
|
YulUtilFunctions utils();
|
||||||
|
|
||||||
langutil::EVMVersion evmVersion() const { return m_evmVersion; }
|
langutil::EVMVersion evmVersion() const { return m_evmVersion; }
|
||||||
|
std::optional<uint8_t> eofVersion() const { return m_eofVersion; }
|
||||||
ExecutionContext executionContext() const { return m_executionContext; }
|
ExecutionContext executionContext() const { return m_executionContext; }
|
||||||
|
|
||||||
void setArithmetic(Arithmetic _value) { m_arithmetic = _value; }
|
void setArithmetic(Arithmetic _value) { m_arithmetic = _value; }
|
||||||
@ -182,6 +185,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
langutil::EVMVersion m_evmVersion;
|
langutil::EVMVersion m_evmVersion;
|
||||||
|
std::optional<uint8_t> m_eofVersion;
|
||||||
ExecutionContext m_executionContext;
|
ExecutionContext m_executionContext;
|
||||||
RevertStrings m_revertStrings;
|
RevertStrings m_revertStrings;
|
||||||
OptimiserSettings m_optimiserSettings;
|
OptimiserSettings m_optimiserSettings;
|
||||||
|
@ -1110,6 +1110,7 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon
|
|||||||
);
|
);
|
||||||
IRGenerationContext newContext(
|
IRGenerationContext newContext(
|
||||||
m_evmVersion,
|
m_evmVersion,
|
||||||
|
m_eofVersion,
|
||||||
_context,
|
_context,
|
||||||
m_context.revertStrings(),
|
m_context.revertStrings(),
|
||||||
m_optimiserSettings,
|
m_optimiserSettings,
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
m_optimiserSettings(_optimiserSettings),
|
m_optimiserSettings(_optimiserSettings),
|
||||||
m_context(
|
m_context(
|
||||||
_evmVersion,
|
_evmVersion,
|
||||||
|
_eofVersion,
|
||||||
ExecutionContext::Creation,
|
ExecutionContext::Creation,
|
||||||
_revertStrings,
|
_revertStrings,
|
||||||
std::move(_optimiserSettings),
|
std::move(_optimiserSettings),
|
||||||
|
@ -1483,10 +1483,21 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|||||||
m_context.subObjectsCreated().insert(contract);
|
m_context.subObjectsCreated().insert(contract);
|
||||||
|
|
||||||
Whiskers t(R"(let <memPos> := <allocateUnbounded>()
|
Whiskers t(R"(let <memPos> := <allocateUnbounded>()
|
||||||
let <memEnd> := add(<memPos>, datasize("<object>"))
|
let <argPos> := add(<memPos>, datasize("<object>"))
|
||||||
if or(gt(<memEnd>, 0xffffffffffffffff), lt(<memEnd>, <memPos>)) { <panic>() }
|
if or(gt(<argPos>, 0xffffffffffffffff), lt(<argPos>, <memPos>)) { <panic>() }
|
||||||
datacopy(<memPos>, dataoffset("<object>"), datasize("<object>"))
|
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>
|
<?saltSet>
|
||||||
let <address> := create2(<value>, <memPos>, sub(<memEnd>, <memPos>), <salt>)
|
let <address> := create2(<value>, <memPos>, sub(<memEnd>, <memPos>), <salt>)
|
||||||
<!saltSet>
|
<!saltSet>
|
||||||
@ -1498,7 +1509,17 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
|||||||
if iszero(<address>) { <forwardingRevert>() }
|
if iszero(<address>) { <forwardingRevert>() }
|
||||||
</isTryCall>
|
</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("memPos", m_context.newYulVariable());
|
||||||
|
t("argPos", m_context.newYulVariable());
|
||||||
t("memEnd", m_context.newYulVariable());
|
t("memEnd", m_context.newYulVariable());
|
||||||
t("allocateUnbounded", m_utils.allocateUnboundedFunction());
|
t("allocateUnbounded", m_utils.allocateUnboundedFunction());
|
||||||
t("object", IRNames::creationObject(*contract));
|
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 {
|
contract C {
|
||||||
function createDSalted(bytes32 salt, uint arg) public {
|
function createDSalted(bytes32 salt, uint arg) public {
|
||||||
|
bytes memory creationCode = type(D).creationCode;
|
||||||
|
adjustContractCodeForArgSize(creationCode, 32);
|
||||||
address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
|
address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
|
||||||
bytes1(0xff),
|
bytes1(0xff),
|
||||||
address(this),
|
address(this),
|
||||||
salt,
|
salt,
|
||||||
keccak256(abi.encodePacked(
|
keccak256(abi.encodePacked(
|
||||||
type(D).creationCode,
|
creationCode,
|
||||||
arg
|
arg
|
||||||
))
|
))
|
||||||
)))));
|
)))));
|
||||||
|
Loading…
Reference in New Issue
Block a user