mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #6179 from ethereum/solidity-yul1
Solidity to Yul compiler
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources":
|
||||
{
|
||||
"A":
|
||||
{
|
||||
"content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
|
||||
}
|
||||
},
|
||||
"settings":
|
||||
{
|
||||
"outputSelection":
|
||||
{
|
||||
"*": { "*": ["irOptimized"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"contracts":{"A":{"C":{"irOptimized":"/*******************************************************\n * WARNING *\n * Solidity to Yul compilation is still EXPERIMENTAL *\n * It can result in LOSS OF FUNDS or worse *\n * !USE AT YOUR OWN RISK! *\n *******************************************************/\n\nobject \"C_6\" {\n code {\n mstore(64, 128)\n codecopy(0, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))\n return(0, datasize(\"C_6_deployed\"))\n }\n object \"C_6_deployed\" {\n code {\n mstore(64, 128)\n if iszero(lt(calldatasize(), 4))\n {\n let selector := shift_right_224_unsigned(calldataload(0))\n switch selector\n case 0x26121ff0 {\n if callvalue()\n {\n revert(0, 0)\n }\n abi_decode_tuple_(4, calldatasize())\n fun_5_f()\n let memPos := allocateMemory(0)\n let memEnd := abi_encode_tuple__to__fromStack(memPos)\n return(memPos, sub(memEnd, memPos))\n }\n default {\n }\n }\n revert(0, 0)\n function abi_decode_tuple_(headStart, dataEnd)\n {\n if slt(sub(dataEnd, headStart), 0)\n {\n revert(0, 0)\n }\n }\n function abi_encode_tuple__to__fromStack(headStart) -> tail\n {\n tail := add(headStart, 0)\n }\n function allocateMemory(size) -> memPtr\n {\n memPtr := mload(64)\n let newFreePtr := add(memPtr, size)\n if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr))\n {\n revert(0, 0)\n }\n mstore(64, newFreePtr)\n }\n function fun_5_f()\n {\n }\n function shift_right_224_unsigned(value) -> newValue\n {\n newValue := shr(224, value)\n }\n }\n }\n}\n"}}},"sources":{"A":{"id":0}}}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources":
|
||||
{
|
||||
"A":
|
||||
{
|
||||
"content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
|
||||
}
|
||||
},
|
||||
"settings":
|
||||
{
|
||||
"outputSelection":
|
||||
{
|
||||
"*": { "*": ["ir"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"contracts":{"A":{"C":{"ir":"/*******************************************************\n * WARNING *\n * Solidity to Yul compilation is still EXPERIMENTAL *\n * It can result in LOSS OF FUNDS or worse *\n * !USE AT YOUR OWN RISK! *\n *******************************************************/\n\n\n\t\tobject \"C_6\" {\n\t\t\tcode {\n\t\t\t\tmstore(64, 128)\n\t\t\t\t\n\t\t\t\t\n\t\tcodecopy(0, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))\n\t\treturn(0, datasize(\"C_6_deployed\"))\n\t\n\t\t\t\t\n\t\t\t}\n\t\t\tobject \"C_6_deployed\" {\n\t\t\t\tcode {\n\t\t\t\t\tmstore(64, 128)\n\t\t\t\t\t\n\t\tif iszero(lt(calldatasize(), 4))\n\t\t{\n\t\t\tlet selector := shift_right_224_unsigned(calldataload(0))\n\t\t\tswitch selector\n\t\t\t\n\t\t\tcase 0x26121ff0\n\t\t\t{\n\t\t\t\t// f()\n\t\t\t\tif callvalue() { revert(0, 0) }\n\t\t\t\t abi_decode_tuple_(4, calldatasize())\n\t\t\t\t fun_5_f()\n\t\t\t\tlet memPos := allocateMemory(0)\n\t\t\t\tlet memEnd := abi_encode_tuple__to__fromStack(memPos )\n\t\t\t\treturn(memPos, sub(memEnd, memPos))\n\t\t\t}\n\t\t\t\n\t\t\tdefault {}\n\t\t}\n\t\trevert(0, 0)\n\t\n\t\t\t\t\t\n\t\t\tfunction abi_decode_tuple_(headStart, dataEnd) {\n\t\t\t\tif slt(sub(dataEnd, headStart), 0) { revert(0, 0) }\n\t\t\t\t\n\t\t\t}\n\t\t\n\t\t\tfunction abi_encode_tuple__to__fromStack(headStart ) -> tail {\n\t\t\t\ttail := add(headStart, 0)\n\t\t\t\t\n\t\t\t}\n\t\t\n\t\t\tfunction allocateMemory(size) -> memPtr {\n\t\t\t\tmemPtr := mload(64)\n\t\t\t\tlet newFreePtr := add(memPtr, size)\n\t\t\t\t// protect against overflow\n\t\t\t\tif or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }\n\t\t\t\tmstore(64, newFreePtr)\n\t\t\t}\n\t\tfunction fun_5_f() {}\n\t\t\t\tfunction shift_right_224_unsigned(value) -> newValue {\n\t\t\t\t\tnewValue := shr(224, value)\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t"}}},"sources":{"A":{"id":0}}}
|
||||
@@ -44,6 +44,12 @@ SemanticTest::SemanticTest(string const& _filename, string const& _ipcPath, lang
|
||||
file.exceptions(ios::badbit);
|
||||
|
||||
m_source = parseSourceAndSettings(file);
|
||||
if (m_settings.count("compileViaYul"))
|
||||
{
|
||||
m_validatedSettings["compileViaYul"] = m_settings["compileViaYul"];
|
||||
m_compileViaYul = true;
|
||||
m_settings.erase("compileViaYul");
|
||||
}
|
||||
parseExpectations(file);
|
||||
}
|
||||
|
||||
@@ -105,7 +111,7 @@ void SemanticTest::parseExpectations(istream& _stream)
|
||||
{
|
||||
TestFileParser parser{_stream};
|
||||
auto functionCalls = parser.parseFunctionCalls();
|
||||
move(functionCalls.begin(), functionCalls.end(), back_inserter(m_tests));
|
||||
std::move(functionCalls.begin(), functionCalls.end(), back_inserter(m_tests));
|
||||
}
|
||||
|
||||
bool SemanticTest::deploy(string const& _contractName, u256 const& _value, bytes const& _arguments)
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
#include <test/ExecutionFramework.h>
|
||||
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
|
||||
#include <libyul/AssemblyStack.h>
|
||||
|
||||
#include <liblangutil/Exceptions.h>
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
|
||||
@@ -74,6 +77,7 @@ public:
|
||||
m_compiler.setLibraries(_libraryAddresses);
|
||||
m_compiler.setEVMVersion(m_evmVersion);
|
||||
m_compiler.setOptimiserSettings(m_optimiserSettings);
|
||||
m_compiler.enableIRGeneration(m_compileViaYul);
|
||||
if (!m_compiler.compile())
|
||||
{
|
||||
langutil::SourceReferenceFormatter formatter(std::cerr);
|
||||
@@ -85,13 +89,39 @@ public:
|
||||
);
|
||||
BOOST_ERROR("Compiling contract failed");
|
||||
}
|
||||
eth::LinkerObject obj = m_compiler.object(_contractName.empty() ? m_compiler.lastContractName() : _contractName);
|
||||
eth::LinkerObject obj;
|
||||
if (m_compileViaYul)
|
||||
{
|
||||
yul::AssemblyStack asmStack(
|
||||
m_evmVersion,
|
||||
yul::AssemblyStack::Language::StrictAssembly,
|
||||
m_optimiserSettings
|
||||
);
|
||||
if (!asmStack.parseAndAnalyze("", m_compiler.yulIROptimized(
|
||||
_contractName.empty() ? m_compiler.lastContractName() : _contractName
|
||||
)))
|
||||
{
|
||||
langutil::SourceReferenceFormatter formatter(std::cerr);
|
||||
|
||||
for (auto const& error: m_compiler.errors())
|
||||
formatter.printExceptionInformation(
|
||||
*error,
|
||||
(error->type() == langutil::Error::Type::Warning) ? "Warning" : "Error"
|
||||
);
|
||||
BOOST_ERROR("Assembly contract failed. IR: " + m_compiler.yulIROptimized({}));
|
||||
}
|
||||
asmStack.optimize();
|
||||
obj = std::move(*asmStack.assemble(yul::AssemblyStack::Machine::EVM).bytecode);
|
||||
}
|
||||
else
|
||||
obj = m_compiler.object(_contractName.empty() ? m_compiler.lastContractName() : _contractName);
|
||||
BOOST_REQUIRE(obj.linkReferences.empty());
|
||||
return obj.bytecode;
|
||||
}
|
||||
|
||||
protected:
|
||||
dev::solidity::CompilerStack m_compiler;
|
||||
bool m_compileViaYul = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
contract C {
|
||||
function f() public returns (uint) {
|
||||
}
|
||||
function g(uint x, uint y) public returns (uint) {
|
||||
}
|
||||
function h() public payable returns (uint) {
|
||||
}
|
||||
function i(bytes32 b) public returns (bytes32) {
|
||||
}
|
||||
function j(bool b) public returns (bool) {
|
||||
}
|
||||
function k(bytes32 b) public returns (bytes32) {
|
||||
}
|
||||
function s() public returns (uint256[] memory) {
|
||||
}
|
||||
function t(uint) public pure {
|
||||
}
|
||||
}
|
||||
// ===
|
||||
// compileViaYul: true
|
||||
// ----
|
||||
// f() -> 0
|
||||
// g(uint256,uint256): 1, -2 -> 0
|
||||
// h(), 1 ether -> 0
|
||||
// i(bytes32), 1 ether: 2 -> FAILURE
|
||||
// i(bytes32): 2 -> 0
|
||||
// j(bool): true -> false
|
||||
// k(bytes32): 0x31 -> 0x00
|
||||
// s(): hex"4200ef" -> 0x20, 0
|
||||
// t(uint256) -> FAILURE
|
||||
@@ -0,0 +1,6 @@
|
||||
contract C {
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: true
|
||||
// ----
|
||||
// f() -> FAILURE
|
||||
Reference in New Issue
Block a user