From a3381d7260a3338c3f40b2ee828501120e460230 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 12 Nov 2020 01:31:06 +0000 Subject: [PATCH] Add settings.viaIR to standard json --- Changelog.md | 1 + docs/using-the-compiler.rst | 3 + libsolidity/interface/StandardCompiler.cpp | 10 +- libsolidity/interface/StandardCompiler.h | 1 + .../standard_viair_requested/input.json | 21 ++ .../standard_viair_requested/output.json | 210 ++++++++++++++++++ 6 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 test/cmdlineTests/standard_viair_requested/input.json create mode 100644 test/cmdlineTests/standard_viair_requested/output.json diff --git a/Changelog.md b/Changelog.md index c05dc2fe7..7021f7261 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Language Features: Compiler Features: * Command Line Interface: New option ``--experimental-via-ir`` allows switching compilation process to go through the Yul intermediate representation. This is highly experimental and is used for development purposes. + * Standard JSON: New option ``settings.viaIR`` allows the same switch as ``--experimental-via-ir`` on the commandline. * Command Line Interface: Report error if file could not be read in ``--standard-json`` mode. * Command Line interface: Report proper error for each output file which could not be written. Previously an exception was thrown, and execution aborted, on the first error. * SMTChecker: Add division by zero checks in the CHC engine. diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index d84af1088..589bf1e29 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -252,6 +252,9 @@ Input Description // Affects type checking and code generation. Can be homestead, // tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg, istanbul or berlin "evmVersion": "byzantium", + // Optional: Change compilation pipeline to go through the Yul intermediate representation. + // This is a highly EXPERIMENTAL feature, not to be used for production. This is false by default. + "viaIR": true, // Optional: Debugging settings "debug": { // How to treat revert (and require) reason strings. Settings are diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index fa51a5761..5758c4994 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -414,7 +414,7 @@ std::optional checkAuxiliaryInputKeys(Json::Value const& _input) std::optional checkSettingsKeys(Json::Value const& _input) { - static set keys{"parserErrorRecovery", "debug", "evmVersion", "libraries", "metadata", "optimizer", "outputSelection", "remappings", "stopAfter"}; + static set keys{"parserErrorRecovery", "debug", "evmVersion", "libraries", "metadata", "optimizer", "outputSelection", "remappings", "stopAfter", "viaIR"}; return checkKeys(_input, keys, "settings"); } @@ -749,6 +749,13 @@ std::variant StandardCompiler: ret.parserErrorRecovery = settings["parserErrorRecovery"].asBool(); } + if (settings.isMember("viaIR")) + { + if (!settings["viaIR"].isBool()) + return formatFatalError("JSONError", "\"settings.viaIR\" must be a Boolean."); + ret.viaIR = settings["viaIR"].asBool(); + } + if (settings.isMember("evmVersion")) { if (!settings["evmVersion"].isString()) @@ -906,6 +913,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting compilerStack.setSources(sourceList); for (auto const& smtLib2Response: _inputsAndSettings.smtLib2Responses) compilerStack.addSMTLib2Response(smtLib2Response.first, smtLib2Response.second); + compilerStack.setViaIR(_inputsAndSettings.viaIR); compilerStack.setEVMVersion(_inputsAndSettings.evmVersion); compilerStack.setParserErrorRecovery(_inputsAndSettings.parserErrorRecovery); compilerStack.setRemappings(_inputsAndSettings.remappings); diff --git a/libsolidity/interface/StandardCompiler.h b/libsolidity/interface/StandardCompiler.h index 54b3fd3cf..c474ac721 100644 --- a/libsolidity/interface/StandardCompiler.h +++ b/libsolidity/interface/StandardCompiler.h @@ -72,6 +72,7 @@ private: CompilerStack::MetadataHash metadataHash = CompilerStack::MetadataHash::IPFS; Json::Value outputSelection; ModelCheckerSettings modelCheckerSettings = ModelCheckerSettings{}; + bool viaIR = false; }; /// Parses the input json (and potentially invokes the read callback) and either returns diff --git a/test/cmdlineTests/standard_viair_requested/input.json b/test/cmdlineTests/standard_viair_requested/input.json new file mode 100644 index 000000000..6a970357e --- /dev/null +++ b/test/cmdlineTests/standard_viair_requested/input.json @@ -0,0 +1,21 @@ +{ + "language": "Solidity", + "sources": + { + "A": + { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; contract C {} contract D { function f() public { C c = new C(); } }" + } + }, + "settings": + { + "optimizer": { + "enabled": true + }, + "outputSelection": + { + "*": { "*": ["ir", "evm.bytecode.object", "evm.bytecode.generatedSources", "evm.deployedBytecode.object"] } + }, + "viaIR": true + } +} diff --git a/test/cmdlineTests/standard_viair_requested/output.json b/test/cmdlineTests/standard_viair_requested/output.json new file mode 100644 index 000000000..7bf9dd4da --- /dev/null +++ b/test/cmdlineTests/standard_viair_requested/output.json @@ -0,0 +1,210 @@ +{"contracts":{"A":{"C":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""}},"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_2\" { + code { + mstore(64, 128) + if callvalue() { revert(0, 0) } + + constructor_C_2() + + codecopy(0, dataoffset(\"C_2_deployed\"), datasize(\"C_2_deployed\")) + + return(0, datasize(\"C_2_deployed\")) + + function constructor_C_2() { + + } + + } + object \"C_2_deployed\" { + code { + mstore(64, 128) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + default {} + } + if iszero(calldatasize()) { } + revert(0, 0) + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + } + + } + +} + +"},"D":{"evm":{"bytecode":{"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""}},"ir":"/******************************************************* + * WARNING * + * Solidity to Yul compilation is still EXPERIMENTAL * + * It can result in LOSS OF FUNDS or worse * + * !USE AT YOUR OWN RISK! * + *******************************************************/ + + +object \"D_13\" { + code { + mstore(64, 128) + if callvalue() { revert(0, 0) } + + constructor_D_13() + + codecopy(0, dataoffset(\"D_13_deployed\"), datasize(\"D_13_deployed\")) + + return(0, datasize(\"D_13_deployed\")) + + function constructor_D_13() { + + } + + } + object \"D_13_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()) + fun_f_12() + let memPos := allocateMemory(0) + let memEnd := abi_encode_tuple__to__fromStack(memPos ) + return(memPos, sub(memEnd, memPos)) + } + + default {} + } + if iszero(calldatasize()) { } + revert(0, 0) + + function abi_decode_tuple_(headStart, dataEnd) { + if slt(sub(dataEnd, headStart), 0) { revert(0, 0) } + + } + + function abi_encode_tuple__to__fromStack(headStart ) -> tail { + tail := 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)) { panic_error() } + mstore(64, newFreePtr) + } + + function allocateTemporaryMemory() -> memPtr { + memPtr := mload(64) + } + + function fun_f_12() { + + let _1 := allocateTemporaryMemory() + let _2 := add(_1, datasize(\"C_2\")) + if or(gt(_2, 0xffffffffffffffff), lt(_2, _1)) { panic_error() } + datacopy(_1, dataoffset(\"C_2\"), datasize(\"C_2\")) + _2 := abi_encode_tuple__to__fromStack(_2) + + let expr_9_address := create(0, _1, sub(_2, _1)) + + releaseTemporaryMemory() + let vloc_c_6_address := expr_9_address + + } + + function panic_error() { + invalid() + } + + function releaseTemporaryMemory() { + } + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + } + /******************************************************* + * WARNING * + * Solidity to Yul compilation is still EXPERIMENTAL * + * It can result in LOSS OF FUNDS or worse * + * !USE AT YOUR OWN RISK! * + *******************************************************/ + + object \"C_2\" { + code { + mstore(64, 128) + if callvalue() { revert(0, 0) } + + constructor_C_2() + + codecopy(0, dataoffset(\"C_2_deployed\"), datasize(\"C_2_deployed\")) + + return(0, datasize(\"C_2_deployed\")) + + function constructor_C_2() { + + } + + } + object \"C_2_deployed\" { + code { + mstore(64, 128) + + if iszero(lt(calldatasize(), 4)) + { + let selector := shift_right_224_unsigned(calldataload(0)) + switch selector + + default {} + } + if iszero(calldatasize()) { } + revert(0, 0) + + function shift_right_224_unsigned(value) -> newValue { + newValue := + + shr(224, value) + + } + + } + + } + + } + + } + +} + +"}}},"errors":[{"component":"general","errorCode":"2072","formattedMessage":"A:2:73: Warning: Unused local variable. +pragma solidity >=0.0; contract C {} contract D { function f() public { C c = new C(); } } + ^-^ +","message":"Unused local variable.","severity":"warning","sourceLocation":{"end":111,"file":"A","start":108},"type":"Warning"}],"sources":{"A":{"id":0}}}