Merge pull request #12589 from ethereum/emit-immutable-references

Emit immutable references for pure yul code
This commit is contained in:
Mathias L. Baumann 2022-02-07 13:21:44 +01:00 committed by GitHub
commit c139d39b9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 12 deletions

View File

@ -7,6 +7,7 @@ Language Features:
Compiler Features:
* Yul Optimizer: Remove ``mstore`` and ``sstore`` operations if the slot already contains the same value.
* Yul: Emit immutable references for pure yul code when requested.

View File

@ -1461,36 +1461,36 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
stack.optimize();
MachineAssemblyObject object;
MachineAssemblyObject runtimeObject;
tie(object, runtimeObject) = stack.assembleWithDeployed();
MachineAssemblyObject deployedObject;
tie(object, deployedObject) = stack.assembleWithDeployed();
if (object.bytecode)
object.bytecode->link(_inputsAndSettings.libraries);
if (runtimeObject.bytecode)
runtimeObject.bytecode->link(_inputsAndSettings.libraries);
if (deployedObject.bytecode)
deployedObject.bytecode->link(_inputsAndSettings.libraries);
for (string const& objectKind: vector<string>{"bytecode", "deployedBytecode"})
for (auto&& [kind, isDeployed]: {make_pair("bytecode"s, false), make_pair("deployedBytecode"s, true)})
if (isArtifactRequested(
_inputsAndSettings.outputSelection,
sourceName,
contractName,
evmObjectComponents(objectKind),
evmObjectComponents(kind),
wildcardMatchesExperimental
))
{
MachineAssemblyObject const& o = objectKind == "bytecode" ? object : runtimeObject;
MachineAssemblyObject const& o = isDeployed ? deployedObject : object;
if (o.bytecode)
output["contracts"][sourceName][contractName]["evm"][objectKind] =
output["contracts"][sourceName][contractName]["evm"][kind] =
collectEVMObject(
*o.bytecode,
o.sourceMappings.get(),
Json::arrayValue,
false,
[&](string const& _element) { return isArtifactRequested(
isDeployed,
[&, kind = kind](string const& _element) { return isArtifactRequested(
_inputsAndSettings.outputSelection,
sourceName,
contractName,
"evm." + objectKind + "." + _element,
"evm." + kind + "." + _element,
wildcardMatchesExperimental
); }
);

View File

@ -0,0 +1 @@
--pretty-json

View File

@ -0,0 +1,22 @@
{
"language": "Yul",
"sources":
{
"A":
{
"content": "object \"YulTest\" { code { let size := datasize(\"runtime\") datacopy(0, dataoffset(\"runtime\"), size) setimmutable(0, \"test\", 1) return(0, size) } object \"runtime\" { code { mstore(0, loadimmutable(\"test\")) return(0, 0x20) } }}"
}
},
"settings":
{
"outputSelection": {
"A": {
"*": [
"evm.deployedBytecode.immutableReferences",
"evm.bytecode",
"evm.deployedBytecode"
]
}
}
}
}

View File

@ -0,0 +1,52 @@
{
"contracts":
{
"A":
{
"YulTest":
{
"evm":
{
"bytecode":
{
"functionDebugData": {},
"generatedSources": [],
"linkReferences": {},
"object": "60298060156000396001600060010152806000f3fe7f000000000000000000000000000000000000000000000000000000000000000060005260206000f3",
"opcodes": "PUSH1 0x29 DUP1 PUSH1 0x15 PUSH1 0x0 CODECOPY PUSH1 0x1 PUSH1 0x0 PUSH1 0x1 ADD MSTORE DUP1 PUSH1 0x0 RETURN INVALID PUSH32 0x0 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 RETURN ",
"sourceMap": "42:19:0:-:0;100:4;77:21;74:1;65:40;133:1;122;109:26;;;149:4;146:1;139:15"
},
"deployedBytecode":
{
"functionDebugData": {},
"generatedSources": [],
"immutableReferences":
{
"test":
[
{
"length": 32,
"start": 1
}
]
},
"linkReferences": {},
"object": "7f000000000000000000000000000000000000000000000000000000000000000060005260206000f3",
"opcodes": "PUSH32 0x0 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 RETURN ",
"sourceMap": "203:21:0:-:0;200:1;193:32;241:4;238:1;231:15"
}
}
}
}
},
"errors":
[
{
"component": "general",
"formattedMessage": "Yul is still experimental. Please use the output with care.",
"message": "Yul is still experimental. Please use the output with care.",
"severity": "warning",
"type": "Warning"
}
]
}

View File

@ -23,7 +23,7 @@ sub_0: assembly {
/* \"A\":137:149 */
revert
}
","bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"<BYTECODE REMOVED>","opcodes":"<OPCODES REMOVED>","sourceMap":"<SOURCEMAP REMOVED>"},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"<BYTECODE REMOVED>","opcodes":"<OPCODES REMOVED>","sourceMap":"<SOURCEMAP REMOVED>"}},"ir":"object \"NamedObject\" {
","bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"<BYTECODE REMOVED>","opcodes":"<OPCODES REMOVED>","sourceMap":"<SOURCEMAP REMOVED>"},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"<BYTECODE REMOVED>","opcodes":"<OPCODES REMOVED>","sourceMap":"<SOURCEMAP REMOVED>"}},"ir":"object \"NamedObject\" {
code {
let x := dataoffset(\"DataName\")
sstore(add(x, 0), 0)