[Yul] Format string literals back to quoted string literals

This commit is contained in:
Leonardo Alt 2019-11-21 18:56:25 +01:00 committed by chriseth
parent 200a92b40e
commit ce83bfb088
16 changed files with 842 additions and 4 deletions

View File

@ -5,6 +5,7 @@ Language Features:
Compiler Features:
* Yul: When compiling via Yul, string literals from the Solidity code are kept as string literals if every character is safely printable.
Bugfixes:

View File

@ -23,6 +23,7 @@
#include <libdevcore/Exceptions.h>
#include <libdevcore/Assertions.h>
#include <libdevcore/Keccak256.h>
#include <libdevcore/FixedHash.h>
#include <boost/algorithm/string.hpp>
@ -181,3 +182,15 @@ bool dev::isValidDecimal(string const& _string)
return false;
return true;
}
// Returns a quoted string if all characters are printable ASCII chars,
// or its hex representation otherwise.
std::string dev::formatAsStringOrNumber(std::string const& _value)
{
if (_value.length() <= 32)
for (auto const& c: _value)
if (c <= 0x1f || c >= 0x7f || c == '"')
return "0x" + h256(_value, h256::AlignLeft).hex();
return "\"" + _value + "\"";
}

View File

@ -290,7 +290,6 @@ void iterateReplacing(std::vector<T>& _vector, F const& _f)
_vector = std::move(modifiedVector);
}
namespace detail
{
template <typename T, typename F, std::size_t... I>
@ -355,6 +354,10 @@ std::string getChecksummedAddress(std::string const& _addr);
bool isValidHex(std::string const& _string);
bool isValidDecimal(std::string const& _string);
/// @returns a quoted string if all characters are printable ASCII chars,
/// or its hex representation otherwise.
std::string formatAsStringOrNumber(std::string const& _value);
template<typename Container, typename Compare>
bool containerEqual(Container const& _lhs, Container const& _rhs, Compare&& _compare)
{

View File

@ -23,6 +23,7 @@
#include <libsolidity/codegen/ABIFunctions.h>
#include <libsolidity/codegen/CompilerUtils.h>
#include <libdevcore/CommonData.h>
#include <libdevcore/Whiskers.h>
#include <libdevcore/StringUtils.h>
@ -975,7 +976,7 @@ string ABIFunctions::abiEncodingFunctionStringLiteral(
for (size_t i = 0; i < words; ++i)
{
wordParams[i]["offset"] = to_string(i * 32);
wordParams[i]["wordValue"] = "0x" + h256(value.substr(32 * i, 32), h256::AlignLeft).hex();
wordParams[i]["wordValue"] = formatAsStringOrNumber(value.substr(32 * i, 32));
}
templ("word", wordParams);
return templ.render();
@ -990,7 +991,7 @@ string ABIFunctions::abiEncodingFunctionStringLiteral(
}
)");
templ("functionName", functionName);
templ("wordValue", "0x" + h256(value, h256::AlignLeft).hex());
templ("wordValue", formatAsStringOrNumber(value));
return templ.render();
}
});

View File

@ -23,6 +23,8 @@
#include <libsolidity/codegen/MultiUseYulFunctionCollector.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/codegen/CompilerUtils.h>
#include <libdevcore/CommonData.h>
#include <libdevcore/Whiskers.h>
#include <libdevcore/StringUtils.h>
@ -1756,7 +1758,7 @@ string YulUtilFunctions::conversionFunctionSpecial(Type const& _from, Type const
for (size_t i = 0; i < words; ++i)
{
wordParams[i]["offset"] = to_string(32 + i * 32);
wordParams[i]["wordValue"] = "0x" + h256(data.substr(32 * i, 32), h256::AlignLeft).hex();
wordParams[i]["wordValue"] = formatAsStringOrNumber(data.substr(32 * i, 32));
}
templ("word", wordParams);
return templ.render();

View File

@ -0,0 +1,17 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "pragma solidity >=0.0; contract C { function f() external pure returns (string memory) { return \"abcabc\"; } }"
}
},
"settings":
{
"outputSelection":
{
"*": { "*": ["ir"] }
}
}
}

View File

@ -0,0 +1,161 @@
{"contracts":{"A":{"C":{"ir":"/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object \"C_10\" {
code {
mstore(64, 128)
// Begin state variable initialization for contract \"C\" (0 variables)
// End state variable initialization for contract \"C\".
codecopy(0, dataoffset(\"C_10_deployed\"), datasize(\"C_10_deployed\"))
return(0, datasize(\"C_10_deployed\"))
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
mstore(64, newFreePtr)
}
function convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_string_memory_ptr() -> converted {
converted := allocateMemory(64)
mstore(converted, 6)
mstore(add(converted, 32), \"abcabc\")
}
function fun_f_9() -> vloc__4 {
for { let return_flag := 1 } return_flag {} {
vloc__4 := convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_string_memory_ptr()
return_flag := 0
break
break
}
}
}
object \"C_10_deployed\" {
code {
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
switch selector
case 0x26121ff0
{
// f()
if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize())
let ret_0 := fun_f_9()
let memPos := allocateMemory(0)
let memEnd := abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(memPos , ret_0)
return(memPos, sub(memEnd, memPos))
}
default {}
}
revert(0, 0)
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert(0, 0) }
}
function abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value, pos) -> end {
let length := array_length_t_string_memory_ptr(value)
pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length)
copy_memory_to_memory(add(value, 0x20), pos, length)
end := add(pos, round_up_to_mul_of_32(length))
}
function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(headStart , value0) -> tail {
tail := add(headStart, 32)
mstore(add(headStart, 0), sub(tail, headStart))
tail := abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value0, tail)
}
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
mstore(64, newFreePtr)
}
function array_length_t_string_memory_ptr(value) -> length {
length := mload(value)
}
function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos {
mstore(pos, length)
updated_pos := add(pos, 0x20)
}
function convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_string_memory_ptr() -> converted {
converted := allocateMemory(64)
mstore(converted, 6)
mstore(add(converted, 32), \"abcabc\")
}
function copy_memory_to_memory(src, dst, length) {
let i := 0
for { } lt(i, length) { i := add(i, 32) }
{
mstore(add(dst, i), mload(add(src, i)))
}
if gt(i, length)
{
// clear end
mstore(add(dst, length), 0)
}
}
function fun_f_9() -> vloc__4 {
for { let return_flag := 1 } return_flag {} {
vloc__4 := convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_string_memory_ptr()
return_flag := 0
break
break
}
}
function round_up_to_mul_of_32(value) -> result {
result := and(add(value, 31), not(31))
}
function shift_right_224_unsigned(value) -> newValue {
newValue :=
shr(224, value)
}
}
}
}
"}}},"sources":{"A":{"id":0}}}

View File

@ -0,0 +1,17 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "pragma solidity >=0.0; contract C { function f() external pure returns (bytes32) { return \"abcabc\"; } }"
}
},
"settings":
{
"outputSelection":
{
"*": { "*": ["ir"] }
}
}
}

View File

@ -0,0 +1,114 @@
{"contracts":{"A":{"C":{"ir":"/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object \"C_10\" {
code {
mstore(64, 128)
// Begin state variable initialization for contract \"C\" (0 variables)
// End state variable initialization for contract \"C\".
codecopy(0, dataoffset(\"C_10_deployed\"), datasize(\"C_10_deployed\"))
return(0, datasize(\"C_10_deployed\"))
function convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_bytes32() -> converted {
converted := 0x6162636162630000000000000000000000000000000000000000000000000000
}
function fun_f_9() -> vloc__4 {
for { let return_flag := 1 } return_flag {} {
vloc__4 := convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_bytes32()
return_flag := 0
break
break
}
}
}
object \"C_10_deployed\" {
code {
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
switch selector
case 0x26121ff0
{
// f()
if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize())
let ret_0 := fun_f_9()
let memPos := allocateMemory(0)
let memEnd := abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack(memPos , ret_0)
return(memPos, sub(memEnd, memPos))
}
default {}
}
revert(0, 0)
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert(0, 0) }
}
function abi_encode_t_bytes32_to_t_bytes32_fromStack(value, pos) {
mstore(pos, cleanup_t_bytes32(value))
}
function abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack(headStart , value0) -> tail {
tail := add(headStart, 32)
abi_encode_t_bytes32_to_t_bytes32_fromStack(value0, add(headStart, 0))
}
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
mstore(64, newFreePtr)
}
function cleanup_t_bytes32(value) -> cleaned {
cleaned := value
}
function convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_bytes32() -> converted {
converted := 0x6162636162630000000000000000000000000000000000000000000000000000
}
function fun_f_9() -> vloc__4 {
for { let return_flag := 1 } return_flag {} {
vloc__4 := convert_t_stringliteral_9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21_to_t_bytes32()
return_flag := 0
break
break
}
}
function shift_right_224_unsigned(value) -> newValue {
newValue :=
shr(224, value)
}
}
}
}
"}}},"sources":{"A":{"id":0}}}

View File

@ -0,0 +1,17 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "pragma solidity >=0.0; contract C { function f() external pure returns (bytes4) { return 0x61626364; } }"
}
},
"settings":
{
"outputSelection":
{
"*": { "*": ["ir"] }
}
}
}

View File

@ -0,0 +1,138 @@
{"contracts":{"A":{"C":{"ir":"/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object \"C_10\" {
code {
mstore(64, 128)
// Begin state variable initialization for contract \"C\" (0 variables)
// End state variable initialization for contract \"C\".
codecopy(0, dataoffset(\"C_10_deployed\"), datasize(\"C_10_deployed\"))
return(0, datasize(\"C_10_deployed\"))
function cleanup_t_rational_1633837924_by_1(value) -> cleaned {
cleaned := value
}
function convert_t_rational_1633837924_by_1_to_t_bytes4(value) -> converted {
converted := shift_left_224(cleanup_t_rational_1633837924_by_1(value))
}
function fun_f_9() -> vloc__4 {
for { let return_flag := 1 } return_flag {} {
let expr_6 := 0x61626364
vloc__4 := convert_t_rational_1633837924_by_1_to_t_bytes4(expr_6)
return_flag := 0
break
break
}
}
function shift_left_224(value) -> newValue {
newValue :=
shl(224, value)
}
}
object \"C_10_deployed\" {
code {
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
switch selector
case 0x26121ff0
{
// f()
if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize())
let ret_0 := fun_f_9()
let memPos := allocateMemory(0)
let memEnd := abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack(memPos , ret_0)
return(memPos, sub(memEnd, memPos))
}
default {}
}
revert(0, 0)
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert(0, 0) }
}
function abi_encode_t_bytes4_to_t_bytes4_fromStack(value, pos) {
mstore(pos, cleanup_t_bytes4(value))
}
function abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack(headStart , value0) -> tail {
tail := add(headStart, 32)
abi_encode_t_bytes4_to_t_bytes4_fromStack(value0, add(headStart, 0))
}
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
mstore(64, newFreePtr)
}
function cleanup_t_bytes4(value) -> cleaned {
cleaned := and(value, 0xffffffff00000000000000000000000000000000000000000000000000000000)
}
function cleanup_t_rational_1633837924_by_1(value) -> cleaned {
cleaned := value
}
function convert_t_rational_1633837924_by_1_to_t_bytes4(value) -> converted {
converted := shift_left_224(cleanup_t_rational_1633837924_by_1(value))
}
function fun_f_9() -> vloc__4 {
for { let return_flag := 1 } return_flag {} {
let expr_6 := 0x61626364
vloc__4 := convert_t_rational_1633837924_by_1_to_t_bytes4(expr_6)
return_flag := 0
break
break
}
}
function shift_left_224(value) -> newValue {
newValue :=
shl(224, value)
}
function shift_right_224_unsigned(value) -> newValue {
newValue :=
shr(224, value)
}
}
}
}
"}}},"sources":{"A":{"id":0}}}

View File

@ -0,0 +1,17 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "pragma solidity >=0.0; contract C { function f() external pure returns (string memory) { return \"abcdabcdcafecafeabcdabcdcafecafeffffzzzzoooo0123456789,.<,>.?:;'[{]}|`~!@#$%^&*()-_=+\"; } }"
}
},
"settings":
{
"outputSelection":
{
"*": { "*": ["ir"] }
}
}
}

View File

@ -0,0 +1,169 @@
{"contracts":{"A":{"C":{"ir":"/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object \"C_10\" {
code {
mstore(64, 128)
// Begin state variable initialization for contract \"C\" (0 variables)
// End state variable initialization for contract \"C\".
codecopy(0, dataoffset(\"C_10_deployed\"), datasize(\"C_10_deployed\"))
return(0, datasize(\"C_10_deployed\"))
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
mstore(64, newFreePtr)
}
function convert_t_stringliteral_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571_to_t_string_memory_ptr() -> converted {
converted := allocateMemory(128)
mstore(converted, 85)
mstore(add(converted, 32), \"abcdabcdcafecafeabcdabcdcafecafe\")
mstore(add(converted, 64), \"ffffzzzzoooo0123456789,.<,>.?:;'\")
mstore(add(converted, 96), \"[{]}|`~!@#$%^&*()-_=+\")
}
function fun_f_9() -> vloc__4 {
for { let return_flag := 1 } return_flag {} {
vloc__4 := convert_t_stringliteral_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571_to_t_string_memory_ptr()
return_flag := 0
break
break
}
}
}
object \"C_10_deployed\" {
code {
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
switch selector
case 0x26121ff0
{
// f()
if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize())
let ret_0 := fun_f_9()
let memPos := allocateMemory(0)
let memEnd := abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(memPos , ret_0)
return(memPos, sub(memEnd, memPos))
}
default {}
}
revert(0, 0)
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert(0, 0) }
}
function abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value, pos) -> end {
let length := array_length_t_string_memory_ptr(value)
pos := array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length)
copy_memory_to_memory(add(value, 0x20), pos, length)
end := add(pos, round_up_to_mul_of_32(length))
}
function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack(headStart , value0) -> tail {
tail := add(headStart, 32)
mstore(add(headStart, 0), sub(tail, headStart))
tail := abi_encode_t_string_memory_ptr_to_t_string_memory_ptr_fromStack(value0, tail)
}
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
mstore(64, newFreePtr)
}
function array_length_t_string_memory_ptr(value) -> length {
length := mload(value)
}
function array_storeLengthForEncoding_t_string_memory_ptr_fromStack(pos, length) -> updated_pos {
mstore(pos, length)
updated_pos := add(pos, 0x20)
}
function convert_t_stringliteral_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571_to_t_string_memory_ptr() -> converted {
converted := allocateMemory(128)
mstore(converted, 85)
mstore(add(converted, 32), \"abcdabcdcafecafeabcdabcdcafecafe\")
mstore(add(converted, 64), \"ffffzzzzoooo0123456789,.<,>.?:;'\")
mstore(add(converted, 96), \"[{]}|`~!@#$%^&*()-_=+\")
}
function copy_memory_to_memory(src, dst, length) {
let i := 0
for { } lt(i, length) { i := add(i, 32) }
{
mstore(add(dst, i), mload(add(src, i)))
}
if gt(i, length)
{
// clear end
mstore(add(dst, length), 0)
}
}
function fun_f_9() -> vloc__4 {
for { let return_flag := 1 } return_flag {} {
vloc__4 := convert_t_stringliteral_d6604f85ac07e2b33103a620b3d3d75b0473c7214912beded67b9b624d41c571_to_t_string_memory_ptr()
return_flag := 0
break
break
}
}
function round_up_to_mul_of_32(value) -> result {
result := and(add(value, 31), not(31))
}
function shift_right_224_unsigned(value) -> newValue {
newValue :=
shr(224, value)
}
}
}
}
"}}},"sources":{"A":{"id":0}}}

View File

@ -0,0 +1,17 @@
{
"language": "Solidity",
"sources":
{
"A":
{
"content": "pragma solidity >=0.0; contract C { function f() external pure returns (bytes4) { return 0xaabbccdd; } }"
}
},
"settings":
{
"outputSelection":
{
"*": { "*": ["ir"] }
}
}
}

View File

@ -0,0 +1,138 @@
{"contracts":{"A":{"C":{"ir":"/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object \"C_10\" {
code {
mstore(64, 128)
// Begin state variable initialization for contract \"C\" (0 variables)
// End state variable initialization for contract \"C\".
codecopy(0, dataoffset(\"C_10_deployed\"), datasize(\"C_10_deployed\"))
return(0, datasize(\"C_10_deployed\"))
function cleanup_t_rational_2864434397_by_1(value) -> cleaned {
cleaned := value
}
function convert_t_rational_2864434397_by_1_to_t_bytes4(value) -> converted {
converted := shift_left_224(cleanup_t_rational_2864434397_by_1(value))
}
function fun_f_9() -> vloc__4 {
for { let return_flag := 1 } return_flag {} {
let expr_6 := 0xaabbccdd
vloc__4 := convert_t_rational_2864434397_by_1_to_t_bytes4(expr_6)
return_flag := 0
break
break
}
}
function shift_left_224(value) -> newValue {
newValue :=
shl(224, value)
}
}
object \"C_10_deployed\" {
code {
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
switch selector
case 0x26121ff0
{
// f()
if callvalue() { revert(0, 0) }
abi_decode_tuple_(4, calldatasize())
let ret_0 := fun_f_9()
let memPos := allocateMemory(0)
let memEnd := abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack(memPos , ret_0)
return(memPos, sub(memEnd, memPos))
}
default {}
}
revert(0, 0)
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert(0, 0) }
}
function abi_encode_t_bytes4_to_t_bytes4_fromStack(value, pos) {
mstore(pos, cleanup_t_bytes4(value))
}
function abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack(headStart , value0) -> tail {
tail := add(headStart, 32)
abi_encode_t_bytes4_to_t_bytes4_fromStack(value0, add(headStart, 0))
}
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
mstore(64, newFreePtr)
}
function cleanup_t_bytes4(value) -> cleaned {
cleaned := and(value, 0xffffffff00000000000000000000000000000000000000000000000000000000)
}
function cleanup_t_rational_2864434397_by_1(value) -> cleaned {
cleaned := value
}
function convert_t_rational_2864434397_by_1_to_t_bytes4(value) -> converted {
converted := shift_left_224(cleanup_t_rational_2864434397_by_1(value))
}
function fun_f_9() -> vloc__4 {
for { let return_flag := 1 } return_flag {} {
let expr_6 := 0xaabbccdd
vloc__4 := convert_t_rational_2864434397_by_1_to_t_bytes4(expr_6)
return_flag := 0
break
break
}
}
function shift_left_224(value) -> newValue {
newValue :=
shl(224, value)
}
function shift_right_224_unsigned(value) -> newValue {
newValue :=
shr(224, value)
}
}
}
}
"}}},"sources":{"A":{"id":0}}}

View File

@ -0,0 +1,13 @@
contract C {
function f1() external pure returns (string memory) { return "abcabc"; }
function f2() external pure returns (string memory) { return "abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?"; }
function g() external pure returns (bytes32) { return "abcabc"; }
function h() external pure returns (bytes4) { return 0xcafecafe; }
}
// ====
// compileViaYul: only
// ----
// f1() -> 0x20, 6, left(0x616263616263)
// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728
// g() -> left(0x616263616263)
// h() -> left(0xcafecafe)