mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
returnSize assigned according to truth value of returnInfo.dynamicReturnSize
This commit is contained in:
parent
ebefb5d980
commit
beabc51c20
@ -54,4 +54,6 @@ ReturnInfo::ReturnInfo(EVMVersion const& _evmVersion, FunctionType const& _funct
|
||||
estimatedReturnSize += retType->decodingType()->calldataEncodedSize();
|
||||
}
|
||||
}
|
||||
if (dynamicReturnSize)
|
||||
solAssert(estimatedReturnSize == 0);
|
||||
}
|
||||
|
@ -2505,6 +2505,8 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
|
||||
appendCode() << "mstore(add(" << m_utils.allocateUnboundedFunction() << "() , " << to_string(returnInfo.estimatedReturnSize) << "), 0)\n";
|
||||
}
|
||||
|
||||
// NOTE: When the expected size of returndata is static, we pass that in to the call opcode and it gets copied automatically.
|
||||
// When it's dynamic, we get zero from estimatedReturnSize() instead and then we need an explicit returndatacopy().
|
||||
Whiskers templ(R"(
|
||||
<?checkExtcodesize>
|
||||
if iszero(extcodesize(<address>)) { <revertNoCode>() }
|
||||
@ -2514,22 +2516,29 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
|
||||
mstore(<pos>, <shl28>(<funSel>))
|
||||
let <end> := <encodeArgs>(add(<pos>, 4) <argumentString>)
|
||||
|
||||
let <success> := <call>(<gas>, <address>, <?hasValue> <value>, </hasValue> <pos>, sub(<end>, <pos>), <pos>, <reservedReturnSize>)
|
||||
let <success> := <call>(<gas>, <address>, <?hasValue> <value>, </hasValue> <pos>, sub(<end>, <pos>), <pos>, <staticReturndataSize>)
|
||||
<?noTryCall>
|
||||
if iszero(<success>) { <forwardingRevert>() }
|
||||
</noTryCall>
|
||||
<?+retVars> let <retVars> </+retVars>
|
||||
if <success> {
|
||||
<?dynamicReturnSize>
|
||||
// copy dynamic return data out
|
||||
returndatacopy(<pos>, 0, returndatasize())
|
||||
</dynamicReturnSize>
|
||||
<?isReturndataSizeDynamic>
|
||||
let <returnDataSizeVar> := returndatasize()
|
||||
returndatacopy(<pos>, 0, <returnDataSizeVar>)
|
||||
<!isReturndataSizeDynamic>
|
||||
let <returnDataSizeVar> := <staticReturndataSize>
|
||||
<?supportsReturnData>
|
||||
if gt(<returnDataSizeVar>, returndatasize()) {
|
||||
<returnDataSizeVar> := returndatasize()
|
||||
}
|
||||
</supportsReturnData>
|
||||
</isReturndataSizeDynamic>
|
||||
|
||||
// update freeMemoryPointer according to dynamic return size
|
||||
<finalizeAllocation>(<pos>, <returnSize>)
|
||||
<finalizeAllocation>(<pos>, <returnDataSizeVar>)
|
||||
|
||||
// decode return parameters from external try-call into retVars
|
||||
<?+retVars> <retVars> := </+retVars> <abiDecode>(<pos>, add(<pos>, <returnSize>))
|
||||
<?+retVars> <retVars> := </+retVars> <abiDecode>(<pos>, add(<pos>, <returnDataSizeVar>))
|
||||
}
|
||||
)");
|
||||
templ("revertNoCode", m_utils.revertReasonIfDebugFunction("Target contract does not contain code"));
|
||||
@ -2558,21 +2567,18 @@ void IRGeneratorForStatements::appendExternalFunctionCall(
|
||||
templ("funSel", IRVariable(_functionCall.expression()).part("functionSelector").name());
|
||||
templ("address", IRVariable(_functionCall.expression()).part("address").name());
|
||||
|
||||
// Always use the actual return length, and not our calculated expected length, if returndatacopy is supported.
|
||||
// This ensures it can catch badly formatted input from external calls.
|
||||
if (m_context.evmVersion().supportsReturndata())
|
||||
templ("returnSize", "returndatasize()");
|
||||
else
|
||||
templ("returnSize", to_string(returnInfo.estimatedReturnSize));
|
||||
|
||||
templ("reservedReturnSize", returnInfo.dynamicReturnSize ? "0" : to_string(returnInfo.estimatedReturnSize));
|
||||
if (returnInfo.dynamicReturnSize)
|
||||
solAssert(m_context.evmVersion().supportsReturndata());
|
||||
templ("returnDataSizeVar", m_context.newYulVariable());
|
||||
templ("staticReturndataSize", to_string(returnInfo.estimatedReturnSize));
|
||||
templ("supportsReturnData", m_context.evmVersion().supportsReturndata());
|
||||
|
||||
string const retVars = IRVariable(_functionCall).commaSeparatedList();
|
||||
templ("retVars", retVars);
|
||||
solAssert(retVars.empty() == returnInfo.returnTypes.empty());
|
||||
|
||||
templ("abiDecode", m_context.abiFunctions().tupleDecoder(returnInfo.returnTypes, true));
|
||||
templ("dynamicReturnSize", returnInfo.dynamicReturnSize);
|
||||
templ("isReturndataSizeDynamic", returnInfo.dynamicReturnSize);
|
||||
|
||||
templ("noTryCall", !_functionCall.annotation().tryCall);
|
||||
|
||||
|
@ -265,34 +265,39 @@ sub_0: assembly {
|
||||
return
|
||||
/* \"C\":403:411 this.f() */
|
||||
tag_36:
|
||||
/* \"C\":79:428 contract C... */
|
||||
swap1
|
||||
swap2
|
||||
pop
|
||||
/* \"C\":403:411 this.f() */
|
||||
0x20
|
||||
swap1
|
||||
returndatasize
|
||||
dup3
|
||||
gt
|
||||
tag_41
|
||||
jumpi
|
||||
tag_42:
|
||||
/* \"C\":79:428 contract C... */
|
||||
0x1f
|
||||
dup3
|
||||
add
|
||||
not(0x1f)
|
||||
and
|
||||
dup3
|
||||
dup4
|
||||
add
|
||||
swap1
|
||||
0xffffffffffffffff
|
||||
dup3
|
||||
gt
|
||||
dup4
|
||||
dup5
|
||||
dup4
|
||||
lt
|
||||
or
|
||||
tag_41
|
||||
tag_43
|
||||
jumpi
|
||||
pop
|
||||
tag_40
|
||||
swap3
|
||||
/* \"C\":403:411 this.f() */
|
||||
tag_43
|
||||
tag_45
|
||||
/* \"C\":392:422 stateVar + this.f() + immutVar */
|
||||
tag_39
|
||||
/* \"C\":79:428 contract C... */
|
||||
@ -301,34 +306,41 @@ sub_0: assembly {
|
||||
tag_38
|
||||
/* \"C\":79:428 contract C... */
|
||||
swap4
|
||||
tag_40
|
||||
swap7
|
||||
0x40
|
||||
mstore
|
||||
/* \"C\":403:411 this.f() */
|
||||
returndatasize
|
||||
dup2
|
||||
add
|
||||
swap1
|
||||
tag_6
|
||||
jump\t// in
|
||||
tag_43:
|
||||
tag_45:
|
||||
swap3
|
||||
pop
|
||||
swap3
|
||||
jump(tag_37)
|
||||
/* \"C\":79:428 contract C... */
|
||||
tag_41:
|
||||
tag_43:
|
||||
shl(0xe0, 0x4e487b71)
|
||||
dup2
|
||||
mstore
|
||||
mstore(0x04, 0x41)
|
||||
0x24
|
||||
swap4
|
||||
swap5
|
||||
pop
|
||||
swap3
|
||||
pop
|
||||
swap2
|
||||
pop
|
||||
pop
|
||||
revert
|
||||
/* \"C\":403:411 this.f() */
|
||||
tag_41:
|
||||
returndatasize
|
||||
swap2
|
||||
pop
|
||||
jump(tag_42)
|
||||
tag_34:
|
||||
/* \"C\":79:428 contract C... */
|
||||
swap3
|
||||
@ -345,10 +357,10 @@ sub_0: assembly {
|
||||
swap1
|
||||
revert
|
||||
tag_32:
|
||||
tag_44
|
||||
tag_46
|
||||
tag_4
|
||||
jump\t// in
|
||||
tag_44:
|
||||
tag_46:
|
||||
jump(tag_33)
|
||||
/* \"C\":117:119 41 */
|
||||
tag_4:
|
||||
@ -373,9 +385,9 @@ sub_0: assembly {
|
||||
dup5
|
||||
sgt
|
||||
and
|
||||
tag_45
|
||||
tag_47
|
||||
jumpi
|
||||
tag_46:
|
||||
tag_48:
|
||||
shl(0xff, 0x01)
|
||||
dup3
|
||||
swap1
|
||||
@ -383,25 +395,25 @@ sub_0: assembly {
|
||||
dup4
|
||||
slt
|
||||
and
|
||||
tag_47
|
||||
tag_49
|
||||
jumpi
|
||||
add
|
||||
swap1
|
||||
jump\t// out
|
||||
tag_47:
|
||||
tag_49
|
||||
tag_49:
|
||||
tag_51
|
||||
tag_4
|
||||
jump\t// in
|
||||
tag_49:
|
||||
tag_51:
|
||||
add
|
||||
swap1
|
||||
jump\t// out
|
||||
tag_45:
|
||||
tag_50
|
||||
tag_47:
|
||||
tag_52
|
||||
tag_4
|
||||
jump\t// in
|
||||
tag_50:
|
||||
jump(tag_46)
|
||||
tag_52:
|
||||
jump(tag_48)
|
||||
/* \"C\":79:428 contract C... */
|
||||
tag_6:
|
||||
swap1
|
||||
@ -410,12 +422,12 @@ sub_0: assembly {
|
||||
swap2
|
||||
sub
|
||||
slt
|
||||
tag_51
|
||||
tag_53
|
||||
jumpi
|
||||
mload
|
||||
swap1
|
||||
jump\t// out
|
||||
tag_51:
|
||||
tag_53:
|
||||
pop
|
||||
pop
|
||||
0x00
|
||||
@ -732,34 +744,39 @@ sub_0: assembly {
|
||||
return
|
||||
/* \"C\":403:411 this.f() */
|
||||
tag_36:
|
||||
/* \"D\":91:166 contract D is C(3)... */
|
||||
swap1
|
||||
swap2
|
||||
pop
|
||||
/* \"C\":403:411 this.f() */
|
||||
0x20
|
||||
swap1
|
||||
returndatasize
|
||||
dup3
|
||||
gt
|
||||
tag_41
|
||||
jumpi
|
||||
tag_42:
|
||||
/* \"D\":91:166 contract D is C(3)... */
|
||||
0x1f
|
||||
dup3
|
||||
add
|
||||
not(0x1f)
|
||||
and
|
||||
dup3
|
||||
dup4
|
||||
add
|
||||
swap1
|
||||
0xffffffffffffffff
|
||||
dup3
|
||||
gt
|
||||
dup4
|
||||
dup5
|
||||
dup4
|
||||
lt
|
||||
or
|
||||
tag_41
|
||||
tag_43
|
||||
jumpi
|
||||
pop
|
||||
tag_40
|
||||
swap3
|
||||
/* \"C\":403:411 this.f() */
|
||||
tag_43
|
||||
tag_45
|
||||
/* \"C\":392:422 stateVar + this.f() + immutVar */
|
||||
tag_39
|
||||
/* \"D\":91:166 contract D is C(3)... */
|
||||
@ -768,34 +785,41 @@ sub_0: assembly {
|
||||
tag_38
|
||||
/* \"D\":91:166 contract D is C(3)... */
|
||||
swap4
|
||||
tag_40
|
||||
swap7
|
||||
0x40
|
||||
mstore
|
||||
/* \"C\":403:411 this.f() */
|
||||
returndatasize
|
||||
dup2
|
||||
add
|
||||
swap1
|
||||
tag_6
|
||||
jump\t// in
|
||||
tag_43:
|
||||
tag_45:
|
||||
swap3
|
||||
pop
|
||||
swap3
|
||||
jump(tag_37)
|
||||
/* \"D\":91:166 contract D is C(3)... */
|
||||
tag_41:
|
||||
tag_43:
|
||||
shl(0xe0, 0x4e487b71)
|
||||
dup2
|
||||
mstore
|
||||
mstore(0x04, 0x41)
|
||||
0x24
|
||||
swap4
|
||||
swap5
|
||||
pop
|
||||
swap3
|
||||
pop
|
||||
swap2
|
||||
pop
|
||||
pop
|
||||
revert
|
||||
/* \"C\":403:411 this.f() */
|
||||
tag_41:
|
||||
returndatasize
|
||||
swap2
|
||||
pop
|
||||
jump(tag_42)
|
||||
tag_34:
|
||||
/* \"D\":91:166 contract D is C(3)... */
|
||||
swap3
|
||||
@ -812,10 +836,10 @@ sub_0: assembly {
|
||||
swap1
|
||||
revert
|
||||
tag_32:
|
||||
tag_44
|
||||
tag_46
|
||||
tag_4
|
||||
jump\t// in
|
||||
tag_44:
|
||||
tag_46:
|
||||
jump(tag_33)
|
||||
/* \"C\":117:119 41 */
|
||||
tag_4:
|
||||
@ -840,9 +864,9 @@ sub_0: assembly {
|
||||
dup5
|
||||
sgt
|
||||
and
|
||||
tag_45
|
||||
tag_47
|
||||
jumpi
|
||||
tag_46:
|
||||
tag_48:
|
||||
shl(0xff, 0x01)
|
||||
dup3
|
||||
swap1
|
||||
@ -850,25 +874,25 @@ sub_0: assembly {
|
||||
dup4
|
||||
slt
|
||||
and
|
||||
tag_47
|
||||
tag_49
|
||||
jumpi
|
||||
add
|
||||
swap1
|
||||
jump\t// out
|
||||
tag_47:
|
||||
tag_49
|
||||
tag_49:
|
||||
tag_51
|
||||
tag_4
|
||||
jump\t// in
|
||||
tag_49:
|
||||
tag_51:
|
||||
add
|
||||
swap1
|
||||
jump\t// out
|
||||
tag_45:
|
||||
tag_50
|
||||
tag_47:
|
||||
tag_52
|
||||
tag_4
|
||||
jump\t// in
|
||||
tag_50:
|
||||
jump(tag_46)
|
||||
tag_52:
|
||||
jump(tag_48)
|
||||
/* \"D\":91:166 contract D is C(3)... */
|
||||
tag_6:
|
||||
swap1
|
||||
@ -877,12 +901,12 @@ sub_0: assembly {
|
||||
swap2
|
||||
sub
|
||||
slt
|
||||
tag_51
|
||||
tag_53
|
||||
jumpi
|
||||
mload
|
||||
swap1
|
||||
jump\t// out
|
||||
tag_51:
|
||||
tag_53:
|
||||
pop
|
||||
pop
|
||||
0x00
|
||||
|
@ -563,18 +563,24 @@ object \"C_54\" {
|
||||
let expr_47
|
||||
if _12 {
|
||||
|
||||
let _13 := 32
|
||||
|
||||
if gt(_13, returndatasize()) {
|
||||
_13 := returndatasize()
|
||||
}
|
||||
|
||||
// update freeMemoryPointer according to dynamic return size
|
||||
finalize_allocation(_10, returndatasize())
|
||||
finalize_allocation(_10, _13)
|
||||
|
||||
// decode return parameters from external try-call into retVars
|
||||
expr_47 := abi_decode_tuple_t_int256_fromMemory(_10, add(_10, returndatasize()))
|
||||
expr_47 := abi_decode_tuple_t_int256_fromMemory(_10, add(_10, _13))
|
||||
}
|
||||
/// @src 0:399:418 \"stateVar + this.f()\"
|
||||
let expr_48 := checked_add_t_int256(expr_44, expr_47)
|
||||
|
||||
/// @src 0:421:429 \"immutVar\"
|
||||
let _13 := loadimmutable(\"8\")
|
||||
let expr_49 := _13
|
||||
let _14 := loadimmutable(\"8\")
|
||||
let expr_49 := _14
|
||||
/// @src 0:399:429 \"stateVar + this.f() + immutVar\"
|
||||
let expr_50 := checked_add_t_int256(expr_48, expr_49)
|
||||
|
||||
@ -718,8 +724,10 @@ object \"C_54\" {
|
||||
/// @src 0:410:418 \"this.f()\"
|
||||
if _4
|
||||
{
|
||||
let _5 := 32
|
||||
if gt(_5, returndatasize()) { _5 := returndatasize() }
|
||||
/// @src 0:79:435 \"contract C...\"
|
||||
let newFreePtr := add(_3, and(add(/** @src 0:410:418 \"this.f()\" */ returndatasize(), /** @src 0:79:435 \"contract C...\" */ 31), not(31)))
|
||||
let newFreePtr := add(_3, and(add(_5, 31), not(31)))
|
||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _3))
|
||||
{
|
||||
mstore(_1, shl(224, 0x4e487b71))
|
||||
@ -728,7 +736,7 @@ object \"C_54\" {
|
||||
}
|
||||
mstore(64, newFreePtr)
|
||||
/// @src 0:410:418 \"this.f()\"
|
||||
expr := abi_decode_int256_fromMemory(_3, add(_3, returndatasize()))
|
||||
expr := abi_decode_int256_fromMemory(_3, add(_3, _5))
|
||||
}
|
||||
/// @src 0:399:418 \"stateVar + this.f()\"
|
||||
let expr_1 := checked_add_int256(ret, expr)
|
||||
@ -1402,18 +1410,24 @@ object \"D_72\" {
|
||||
let expr_47
|
||||
if _12 {
|
||||
|
||||
let _13 := 32
|
||||
|
||||
if gt(_13, returndatasize()) {
|
||||
_13 := returndatasize()
|
||||
}
|
||||
|
||||
// update freeMemoryPointer according to dynamic return size
|
||||
finalize_allocation(_10, returndatasize())
|
||||
finalize_allocation(_10, _13)
|
||||
|
||||
// decode return parameters from external try-call into retVars
|
||||
expr_47 := abi_decode_tuple_t_int256_fromMemory(_10, add(_10, returndatasize()))
|
||||
expr_47 := abi_decode_tuple_t_int256_fromMemory(_10, add(_10, _13))
|
||||
}
|
||||
/// @src 0:399:418 \"stateVar + this.f()\"
|
||||
let expr_48 := checked_add_t_int256(expr_44, expr_47)
|
||||
|
||||
/// @src 0:421:429 \"immutVar\"
|
||||
let _13 := loadimmutable(\"8\")
|
||||
let expr_49 := _13
|
||||
let _14 := loadimmutable(\"8\")
|
||||
let expr_49 := _14
|
||||
/// @src 0:399:429 \"stateVar + this.f() + immutVar\"
|
||||
let expr_50 := checked_add_t_int256(expr_48, expr_49)
|
||||
|
||||
@ -1565,8 +1579,10 @@ object \"D_72\" {
|
||||
/// @src 0:410:418 \"this.f()\"
|
||||
if _4
|
||||
{
|
||||
let _5 := 32
|
||||
if gt(_5, returndatasize()) { _5 := returndatasize() }
|
||||
/// @src 1:91:166 \"contract D is C(3)...\"
|
||||
let newFreePtr := add(_3, and(add(/** @src 0:410:418 \"this.f()\" */ returndatasize(), /** @src 1:91:166 \"contract D is C(3)...\" */ 31), not(31)))
|
||||
let newFreePtr := add(_3, and(add(_5, 31), not(31)))
|
||||
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, _3))
|
||||
{
|
||||
mstore(_1, shl(224, 0x4e487b71))
|
||||
@ -1575,7 +1591,7 @@ object \"D_72\" {
|
||||
}
|
||||
mstore(64, newFreePtr)
|
||||
/// @src 0:410:418 \"this.f()\"
|
||||
expr := abi_decode_int256_fromMemory(_3, add(_3, returndatasize()))
|
||||
expr := abi_decode_int256_fromMemory(_3, add(_3, _5))
|
||||
}
|
||||
/// @src 0:399:418 \"stateVar + this.f()\"
|
||||
let expr_1 := checked_add_int256(ret, expr)
|
||||
|
@ -60,10 +60,10 @@ contract C {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test_bytes() ->
|
||||
// gas irOptimized: 371847
|
||||
// gas irOptimized: 371919
|
||||
// gas legacy: 418955
|
||||
// gas legacyOptimized: 326783
|
||||
// test_uint256() ->
|
||||
// gas irOptimized: 522929
|
||||
// gas irOptimized: 523001
|
||||
// gas legacy: 586784
|
||||
// gas legacyOptimized: 451529
|
||||
|
@ -26,6 +26,6 @@ contract C {
|
||||
// ----
|
||||
// library: L
|
||||
// f() -> 8, 7, 1, 2, 7, 12
|
||||
// gas irOptimized: 167672
|
||||
// gas irOptimized: 167696
|
||||
// gas legacy: 169347
|
||||
// gas legacyOptimized: 167269
|
||||
|
@ -61,10 +61,10 @@ contract C {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test_bytes() ->
|
||||
// gas irOptimized: 371847
|
||||
// gas irOptimized: 371919
|
||||
// gas legacy: 418955
|
||||
// gas legacyOptimized: 326783
|
||||
// test_uint256() ->
|
||||
// gas irOptimized: 522929
|
||||
// gas irOptimized: 523001
|
||||
// gas legacy: 586784
|
||||
// gas legacyOptimized: 451529
|
||||
|
@ -32,6 +32,6 @@ contract C is B {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() -> 77
|
||||
// gas irOptimized: 119895
|
||||
// gas irOptimized: 119919
|
||||
// gas legacy: 155093
|
||||
// gas legacyOptimized: 111550
|
||||
|
@ -21,6 +21,6 @@ contract C {
|
||||
// f(uint256[][1]): 32, 32, 0 -> true
|
||||
// f(uint256[][1]): 32, 32, 1, 42 -> true
|
||||
// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true
|
||||
// gas irOptimized: 171838
|
||||
// gas irOptimized: 171842
|
||||
// gas legacy: 141644
|
||||
// gas legacyOptimized: 121532
|
||||
|
@ -21,6 +21,6 @@ contract B {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004
|
||||
// gas irOptimized: 130097
|
||||
// gas irOptimized: 130152
|
||||
// gas legacy: 234943
|
||||
// gas legacyOptimized: 132863
|
||||
|
@ -45,6 +45,6 @@ contract C {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() -> 5, 6, 7
|
||||
// gas irOptimized: 290567
|
||||
// gas irOptimized: 298983
|
||||
// gas legacy: 452172
|
||||
// gas legacyOptimized: 285017
|
||||
|
@ -26,6 +26,6 @@ contract Main {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1
|
||||
// gas irOptimized: 113552
|
||||
// gas irOptimized: 113598
|
||||
// gas legacy: 126596
|
||||
// gas legacyOptimized: 113823
|
||||
|
@ -26,6 +26,6 @@ contract Creator {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8
|
||||
// gas irOptimized: 443921
|
||||
// gas irOptimized: 443960
|
||||
// gas legacy: 590683
|
||||
// gas legacyOptimized: 448326
|
||||
|
@ -26,6 +26,6 @@ contract Creator {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h"
|
||||
// gas irOptimized: 300765
|
||||
// gas irOptimized: 300804
|
||||
// gas legacy: 428917
|
||||
// gas legacyOptimized: 298128
|
||||
|
@ -17,7 +17,7 @@ contract C {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor() ->
|
||||
// gas irOptimized: 177344
|
||||
// gas irOptimized: 173672
|
||||
// gas legacy: 250376
|
||||
// gas legacyOptimized: 174522
|
||||
// deposit(bytes32), 18 wei: 0x1234 ->
|
||||
|
@ -17,7 +17,7 @@ contract D {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor(): 2 ->
|
||||
// gas irOptimized: 200295
|
||||
// gas irOptimized: 203967
|
||||
// gas legacy: 245842
|
||||
// gas legacyOptimized: 195676
|
||||
// f() -> 2
|
||||
|
@ -18,7 +18,7 @@ contract D {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor(): 2 ->
|
||||
// gas irOptimized: 200458
|
||||
// gas irOptimized: 204130
|
||||
// gas legacy: 246202
|
||||
// gas legacyOptimized: 195914
|
||||
// f() -> 2
|
||||
|
@ -25,7 +25,7 @@ contract C {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor(), 1 ether ->
|
||||
// gas irOptimized: 308423
|
||||
// gas irOptimized: 315341
|
||||
// gas legacy: 465314
|
||||
// gas legacyOptimized: 304481
|
||||
// f(uint256): 0 -> FAILURE
|
||||
|
@ -27,7 +27,7 @@ contract C {
|
||||
// revertStrings: debug
|
||||
// ----
|
||||
// constructor(), 1 ether ->
|
||||
// gas irOptimized: 445767
|
||||
// gas irOptimized: 452673
|
||||
// gas legacy: 834272
|
||||
// gas legacyOptimized: 510004
|
||||
// f(uint256): 0 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code"
|
||||
|
@ -18,7 +18,7 @@ contract C {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor(), 20 wei
|
||||
// gas irOptimized: 213663
|
||||
// gas irOptimized: 219285
|
||||
// gas legacy: 294569
|
||||
// gas legacyOptimized: 174699
|
||||
// f(uint256): 20 -> 1370859564726510389319704988634906228201275401179
|
||||
@ -26,7 +26,7 @@ contract C {
|
||||
// f(uint256): 20 -> FAILURE
|
||||
// x() -> 1
|
||||
// stack(uint256): 1023 -> FAILURE
|
||||
// gas irOptimized: 304303
|
||||
// gas irOptimized: 314884
|
||||
// gas legacy: 483942
|
||||
// gas legacyOptimized: 298807
|
||||
// x() -> 1
|
||||
|
@ -41,7 +41,7 @@ contract test {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor(), 20 wei ->
|
||||
// gas irOptimized: 274154
|
||||
// gas irOptimized: 283040
|
||||
// gas legacy: 402654
|
||||
// gas legacyOptimized: 274470
|
||||
// sendAmount(uint256): 5 -> 5
|
||||
|
@ -40,7 +40,7 @@ contract test {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor(), 20 wei ->
|
||||
// gas irOptimized: 274154
|
||||
// gas irOptimized: 283040
|
||||
// gas legacy: 402654
|
||||
// gas legacyOptimized: 274470
|
||||
// sendAmount(uint256): 5 -> 5
|
||||
|
@ -0,0 +1,31 @@
|
||||
interface ShortReturn {
|
||||
function f() external pure returns (bytes32);
|
||||
}
|
||||
contract LongReturn {
|
||||
function f() external pure returns (uint[20] memory) {}
|
||||
}
|
||||
|
||||
contract Test {
|
||||
function test() public returns (uint) {
|
||||
LongReturn longReturn = new LongReturn();
|
||||
uint freeMemoryBefore;
|
||||
assembly {
|
||||
freeMemoryBefore := mload(0x40)
|
||||
}
|
||||
|
||||
ShortReturn(address(longReturn)).f();
|
||||
|
||||
uint freeMemoryAfter;
|
||||
|
||||
assembly {
|
||||
freeMemoryAfter := mload(0x40)
|
||||
}
|
||||
|
||||
return freeMemoryAfter - freeMemoryBefore;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: true
|
||||
// ----
|
||||
// test() -> 0x20
|
||||
// gas legacy: 131966
|
@ -0,0 +1,32 @@
|
||||
interface LongReturn {
|
||||
function f() external pure returns (uint[20] memory);
|
||||
}
|
||||
contract ShortReturn {
|
||||
function f() external pure returns (bytes32) {}
|
||||
}
|
||||
|
||||
contract Test {
|
||||
function test() public returns (uint) {
|
||||
ShortReturn shortReturn = new ShortReturn();
|
||||
uint freeMemoryBefore;
|
||||
assembly {
|
||||
freeMemoryBefore := mload(0x40)
|
||||
}
|
||||
|
||||
LongReturn(address(shortReturn)).f();
|
||||
|
||||
uint freeMemoryAfter;
|
||||
|
||||
assembly {
|
||||
freeMemoryAfter := mload(0x40)
|
||||
}
|
||||
|
||||
return freeMemoryAfter - freeMemoryBefore;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: <=homestead
|
||||
// compileViaYul: true
|
||||
// ----
|
||||
// test() -> 0x0500
|
||||
// gas legacy: 131966
|
@ -0,0 +1,34 @@
|
||||
interface LongReturn {
|
||||
function f() external pure returns (uint[20] memory);
|
||||
}
|
||||
contract ShortReturn {
|
||||
function f() external pure returns (bytes32) {}
|
||||
}
|
||||
|
||||
contract Test {
|
||||
function test() public returns (uint) {
|
||||
ShortReturn shortReturn = new ShortReturn();
|
||||
uint freeMemoryBefore;
|
||||
assembly {
|
||||
freeMemoryBefore := mload(0x40)
|
||||
}
|
||||
|
||||
// This reverts. The external call succeeds but ABI decoding fails due to the returned
|
||||
// `bytes32` being much shorter than the expected `uint[20]`.
|
||||
LongReturn(address(shortReturn)).f();
|
||||
|
||||
uint freeMemoryAfter;
|
||||
|
||||
assembly {
|
||||
freeMemoryAfter := mload(0x40)
|
||||
}
|
||||
|
||||
return freeMemoryAfter - freeMemoryBefore;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// compileViaYul: true
|
||||
// ----
|
||||
// test() -> FAILURE
|
||||
// gas legacy: 131966
|
@ -29,7 +29,7 @@ contract C {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 3, 7, 5
|
||||
// gas irOptimized: 127302
|
||||
// gas irOptimized: 127347
|
||||
// gas legacy: 151334
|
||||
// gas legacyOptimized: 125166
|
||||
// x() -> 7
|
||||
|
@ -25,6 +25,6 @@ contract B {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// g() -> 42
|
||||
// gas irOptimized: 111770
|
||||
// gas irOptimized: 111794
|
||||
// gas legacy: 185053
|
||||
// gas legacyOptimized: 114598
|
||||
|
@ -42,7 +42,7 @@ contract Main {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor(), 22 wei ->
|
||||
// gas irOptimized: 276469
|
||||
// gas irOptimized: 284287
|
||||
// gas legacy: 402045
|
||||
// gas legacyOptimized: 266772
|
||||
// getFlag() -> true
|
||||
|
@ -18,7 +18,7 @@ contract ClientReceipt {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor(), 2000 wei ->
|
||||
// gas irOptimized: 184076
|
||||
// gas irOptimized: 188162
|
||||
// gas legacy: 235195
|
||||
// gas legacyOptimized: 176766
|
||||
// balance -> 1500
|
||||
|
@ -25,6 +25,6 @@ contract Test {
|
||||
// ----
|
||||
// library: Lib
|
||||
// f() -> 4, 0x11
|
||||
// gas irOptimized: 115822
|
||||
// gas irOptimized: 115874
|
||||
// gas legacy: 135952
|
||||
// gas legacyOptimized: 119643
|
||||
|
@ -22,6 +22,6 @@ contract Test {
|
||||
// ----
|
||||
// library: Lib
|
||||
// f() -> 1, 0, 0x2a, 0x17, 0, 0x63
|
||||
// gas irOptimized: 119757
|
||||
// gas irOptimized: 119561
|
||||
// gas legacy: 124793
|
||||
// gas legacyOptimized: 119694
|
||||
|
@ -20,6 +20,6 @@ contract Test {
|
||||
// ----
|
||||
// library: Lib
|
||||
// f() -> 1, 0, 0x2a, 0x17, 0, 0x63
|
||||
// gas irOptimized: 120471
|
||||
// gas irOptimized: 120572
|
||||
// gas legacy: 125245
|
||||
// gas legacyOptimized: 120153
|
||||
|
@ -23,5 +23,5 @@ contract Test {
|
||||
// ----
|
||||
// library: Lib
|
||||
// f() -> 7, 8
|
||||
// gas irOptimized: 101869
|
||||
// gas irOptimized: 101820
|
||||
// gas legacy: 101504
|
||||
|
@ -22,6 +22,6 @@ contract A {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(), 10 ether -> 3007, 3008, 3009
|
||||
// gas irOptimized: 272338
|
||||
// gas irOptimized: 272413
|
||||
// gas legacy: 422501
|
||||
// gas legacyOptimized: 287472
|
||||
|
@ -51,7 +51,7 @@ contract C {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test_f() -> true
|
||||
// gas irOptimized: 122413
|
||||
// gas irOptimized: 122364
|
||||
// gas legacy: 126168
|
||||
// gas legacyOptimized: 123199
|
||||
// test_g() -> true
|
||||
|
@ -19,7 +19,7 @@ contract D {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor(), 27 wei ->
|
||||
// gas irOptimized: 175261
|
||||
// gas irOptimized: 178933
|
||||
// gas legacy: 222977
|
||||
// gas legacyOptimized: 169779
|
||||
// f() -> 27
|
||||
|
@ -22,6 +22,6 @@ contract C {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// g() -> 2, 6
|
||||
// gas irOptimized: 178822
|
||||
// gas irOptimized: 178812
|
||||
// gas legacy: 180762
|
||||
// gas legacyOptimized: 179481
|
||||
|
@ -22,7 +22,7 @@ contract test {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor(), 20 wei ->
|
||||
// gas irOptimized: 185891
|
||||
// gas irOptimized: 192113
|
||||
// gas legacy: 265006
|
||||
// gas legacyOptimized: 182842
|
||||
// sendAmount(uint256): 5 -> 8
|
||||
|
@ -21,7 +21,7 @@ contract test {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor(), 20 wei ->
|
||||
// gas irOptimized: 187835
|
||||
// gas irOptimized: 194261
|
||||
// gas legacy: 266728
|
||||
// gas legacyOptimized: 184762
|
||||
// sendAmount(uint256): 5 -> 8
|
||||
|
@ -23,6 +23,6 @@ contract C {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() ->
|
||||
// gas irOptimized: 113096
|
||||
// gas irOptimized: 112998
|
||||
// gas legacy: 112937
|
||||
// gas legacyOptimized: 112608
|
||||
|
Loading…
Reference in New Issue
Block a user