mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[Yul] Format string literals back to quoted string literals
This commit is contained in:
parent
200a92b40e
commit
ce83bfb088
@ -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:
|
||||
|
@ -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 + "\"";
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
});
|
||||
|
@ -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();
|
||||
|
17
test/cmdlineTests/yul_string_format_ascii/input.json
Normal file
17
test/cmdlineTests/yul_string_format_ascii/input.json
Normal 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"] }
|
||||
}
|
||||
}
|
||||
}
|
161
test/cmdlineTests/yul_string_format_ascii/output.json
Normal file
161
test/cmdlineTests/yul_string_format_ascii/output.json
Normal 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}}}
|
17
test/cmdlineTests/yul_string_format_ascii_bytes32/input.json
Normal file
17
test/cmdlineTests/yul_string_format_ascii_bytes32/input.json
Normal 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"] }
|
||||
}
|
||||
}
|
||||
}
|
114
test/cmdlineTests/yul_string_format_ascii_bytes32/output.json
Normal file
114
test/cmdlineTests/yul_string_format_ascii_bytes32/output.json
Normal 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}}}
|
@ -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"] }
|
||||
}
|
||||
}
|
||||
}
|
@ -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}}}
|
17
test/cmdlineTests/yul_string_format_ascii_long/input.json
Normal file
17
test/cmdlineTests/yul_string_format_ascii_long/input.json
Normal 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"] }
|
||||
}
|
||||
}
|
||||
}
|
169
test/cmdlineTests/yul_string_format_ascii_long/output.json
Normal file
169
test/cmdlineTests/yul_string_format_ascii_long/output.json
Normal 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}}}
|
17
test/cmdlineTests/yul_string_format_hex/input.json
Normal file
17
test/cmdlineTests/yul_string_format_hex/input.json
Normal 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"] }
|
||||
}
|
||||
}
|
||||
}
|
138
test/cmdlineTests/yul_string_format_hex/output.json
Normal file
138
test/cmdlineTests/yul_string_format_hex/output.json
Normal 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}}}
|
13
test/libsolidity/semanticTests/viaYul/string_format.sol
Normal file
13
test/libsolidity/semanticTests/viaYul/string_format.sol
Normal 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)
|
Loading…
Reference in New Issue
Block a user