Skip to content

Commit 947215a

Browse files
committed
Take builtin functions into account in the compilability checker.
1 parent b43d75c commit 947215a

File tree

10 files changed

+123
-4
lines changed

10 files changed

+123
-4
lines changed

Diff for: Changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Bugfixes:
1818
* Optimizer: Fix internal error related to unused tag removal across assemblies. This never generated any invalid code.
1919
* SMTChecker: Fixed crash when used with fixed-sized arrays.
2020
* Yul: Properly detect name clashes with functions before their declaration.
21+
* Yul: Take builtin functions into account in the compilability checker.
2122

2223

2324
Build System:

Diff for: libyul/CompilabilityChecker.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@ std::map<YulString, int> CompilabilityChecker::run(std::shared_ptr<Dialect> _dia
4040

4141
solAssert(_dialect->flavour == AsmFlavour::Strict, "");
4242

43-
EVMDialect const& evmDialect = dynamic_cast<EVMDialect const&>(*_dialect);
43+
solAssert(dynamic_cast<EVMDialect const*>(_dialect.get()), "");
44+
shared_ptr<NoOutputEVMDialect> noOutputDialect = make_shared<NoOutputEVMDialect>(dynamic_pointer_cast<EVMDialect>(_dialect));
4445

4546
bool optimize = true;
4647
yul::AsmAnalysisInfo analysisInfo =
47-
yul::AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, EVMVersion(), _ast);
48+
yul::AsmAnalyzer::analyzeStrictAssertCorrect(noOutputDialect, EVMVersion(), _ast);
49+
4850
NoOutputAssembly assembly;
49-
CodeTransform transform(assembly, analysisInfo, _ast, evmDialect, optimize);
51+
CodeTransform transform(assembly, analysisInfo, _ast, *noOutputDialect, optimize);
5052
try
5153
{
5254
transform(_ast);

Diff for: libyul/backends/evm/EVMDialect.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ struct EVMDialect: public Dialect
6666
/// Sets the current object. Used during code generation.
6767
void setCurrentObject(Object const* _object);
6868

69-
private:
69+
protected:
7070
void addFunction(
7171
std::string _name,
7272
size_t _params,

Diff for: libyul/backends/evm/NoOutputAssembly.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,22 @@ AbstractAssembly::SubID NoOutputAssembly::appendData(bytes const&)
141141
{
142142
return 1;
143143
}
144+
145+
NoOutputEVMDialect::NoOutputEVMDialect(shared_ptr<EVMDialect> const& _copyFrom):
146+
EVMDialect(_copyFrom->flavour, _copyFrom->providesObjectAccess())
147+
{
148+
for (auto& fun: m_functions)
149+
{
150+
size_t parameters = fun.second.parameters.size();
151+
size_t returns = fun.second.returns.size();
152+
fun.second.generateCode = [=](FunctionCall const&, AbstractAssembly& _asm, std::function<void()> _visitArguments)
153+
{
154+
_visitArguments();
155+
for (size_t i = 0; i < parameters; i++)
156+
_asm.appendInstruction(dev::solidity::Instruction::POP);
157+
158+
for (size_t i = 0; i < returns; i++)
159+
_asm.appendConstant(u256(0));
160+
};
161+
}
162+
}

Diff for: libyul/backends/evm/NoOutputAssembly.h

+13
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
#include <libyul/backends/evm/AbstractAssembly.h>
2424

25+
#include <libyul/backends/evm/EVMDialect.h>
26+
2527
#include <libevmasm/LinkerObject.h>
2628

2729
#include <map>
@@ -34,6 +36,7 @@ struct SourceLocation;
3436
namespace yul
3537
{
3638

39+
3740
/**
3841
* Assembly class that just ignores everything and only performs stack counting.
3942
* The purpose is to use this assembly for compilation dry-runs.
@@ -72,4 +75,14 @@ class NoOutputAssembly: public AbstractAssembly
7275
int m_stackHeight = 0;
7376
};
7477

78+
79+
/**
80+
* EVM dialect that does not generate any code.
81+
*/
82+
struct NoOutputEVMDialect: public EVMDialect
83+
{
84+
explicit NoOutputEVMDialect(std::shared_ptr<EVMDialect> const& _copyFrom);
85+
};
86+
87+
7588
}

Diff for: test/cmdlineTests/object_compiler/args

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--strict-assembly --optimize

Diff for: test/cmdlineTests/object_compiler/err

Whitespace-only changes.

Diff for: test/cmdlineTests/object_compiler/exit

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0

Diff for: test/cmdlineTests/object_compiler/input.sol

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
object "MyContract" {
2+
code {
3+
// this is the constructor.
4+
// store the creator in the first storage slot
5+
sstore(0, caller())
6+
// now return the runtime code using the special functions
7+
datacopy(0, dataoffset("Runtime"), datasize("Runtime"))
8+
return(0, datasize("Runtime"))
9+
}
10+
object "Runtime" {
11+
code {
12+
// runtime - just return the creator
13+
mstore(0, sload(0))
14+
return(0, 0x20)
15+
}
16+
}
17+
}

Diff for: test/cmdlineTests/object_compiler/output

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
======= object_compiler/input.sol (EVM) =======
3+
4+
Pretty printed source:
5+
object "MyContract" {
6+
code {
7+
sstore(0, caller())
8+
let _3 := datasize("Runtime")
9+
datacopy(0, dataoffset("Runtime"), _3)
10+
return(0, _3)
11+
}
12+
object "Runtime" {
13+
code {
14+
mstore(0, sload(0))
15+
return(0, 0x20)
16+
}
17+
}
18+
}
19+
20+
21+
Binary representation:
22+
33600055600b806012600039806000f350fe60005460005260206000f3
23+
24+
Text representation:
25+
/* "object_compiler/input.sol":128:136 */
26+
caller
27+
/* "object_compiler/input.sol":125:126 */
28+
0x00
29+
/* "object_compiler/input.sol":118:137 */
30+
sstore
31+
dataSize(sub_0)
32+
/* "object_compiler/input.sol":240:259 */
33+
dup1
34+
dataOffset(sub_0)
35+
/* "object_compiler/input.sol":125:126 */
36+
0x00
37+
/* "object_compiler/input.sol":205:260 */
38+
codecopy
39+
/* "object_compiler/input.sol":275:294 */
40+
dup1
41+
/* "object_compiler/input.sol":125:126 */
42+
0x00
43+
/* "object_compiler/input.sol":265:295 */
44+
return
45+
/* "object_compiler/input.sol":29:299 */
46+
pop
47+
stop
48+
49+
sub_0: assembly {
50+
/* "object_compiler/input.sol":397:398 */
51+
0x00
52+
/* "object_compiler/input.sol":391:399 */
53+
sload
54+
/* "object_compiler/input.sol":397:398 */
55+
0x00
56+
/* "object_compiler/input.sol":381:400 */
57+
mstore
58+
/* "object_compiler/input.sol":417:421 */
59+
0x20
60+
/* "object_compiler/input.sol":397:398 */
61+
0x00
62+
/* "object_compiler/input.sol":407:422 */
63+
return
64+
}
65+

0 commit comments

Comments
 (0)