Skip to content

Commit fe072fc

Browse files
committed
Test: Use new universal compiler host
1 parent 20b4440 commit fe072fc

8 files changed

+144
-97
lines changed

test/ExecutionFramework.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class ExecutionFramework
6565
std::string const& _contractName = "",
6666
bytes const& _arguments = {},
6767
std::map<std::string, util::h160> const& _libraryAddresses = {},
68-
std::optional<std::string> const& _sourceName = std::nullopt
68+
std::optional<std::string> const& _mainSourceName = std::nullopt
6969
) = 0;
7070

7171
bytes const& compileAndRun(

test/libsolidity/GasCosts.cpp

+16-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
* Tests that check that the cost of certain operations stay within range.
2020
*/
2121

22+
#include <test/libsolidity/util/SoltestErrors.h>
2223
#include <test/libsolidity/SolidityExecutionFramework.h>
24+
2325
#include <liblangutil/EVMVersion.h>
2426
#include <libsolutil/IpfsHash.h>
2527
#include <libevmasm/GasMeter.h>
@@ -38,7 +40,10 @@ namespace solidity::frontend::test
3840
#define CHECK_DEPLOY_GAS(_gasNoOpt, _gasOpt, _evmVersion) \
3941
do \
4042
{ \
41-
u256 metaCost = GasMeter::dataGas(m_compiler.cborMetadata(m_compiler.lastContractName()), true, _evmVersion); \
43+
auto const& output = m_compiler.output(); \
44+
auto const* contract = output.contract(); \
45+
soltestAssert(contract); \
46+
u256 metaCost = GasMeter::dataGas(contract->cborMetadata, true, _evmVersion); \
4247
u256 gasOpt{_gasOpt}; \
4348
u256 gasNoOpt{_gasNoOpt}; \
4449
u256 gas = m_optimiserSettings == OptimiserSettings::minimal() ? gasNoOpt : gasOpt; \
@@ -90,7 +95,7 @@ BOOST_AUTO_TEST_CASE(string_storage)
9095
}
9196
}
9297
)";
93-
m_compiler.setMetadataFormat(CompilerStack::MetadataFormat::NoMetadata);
98+
9499
m_appendCBORMetadata = false;
95100
compileAndRun(sourceCode);
96101

@@ -202,8 +207,15 @@ BOOST_AUTO_TEST_CASE(single_callvaluecheck)
202207
}
203208
)";
204209
compileAndRun(sourceCode);
205-
size_t bytecodeSizeNonpayable = m_compiler.object("Nonpayable").bytecode.size();
206-
size_t bytecodeSizePayable = m_compiler.object("Payable").bytecode.size();
210+
auto const& output = m_compiler.output();
211+
auto const* nonpayable = output.contract("Nonpayable");
212+
auto const* payable = output.contract("Payable");
213+
214+
soltestAssert(nonpayable);
215+
soltestAssert(payable);
216+
217+
size_t bytecodeSizeNonpayable = nonpayable->object.size();
218+
size_t bytecodeSizePayable = payable->object.size();
207219

208220
auto evmVersion = solidity::test::CommonOptions::get().evmVersion();
209221
if (evmVersion < EVMVersion::shanghai())

test/libsolidity/GasMeter.cpp

+37-9
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,14 @@
2222
*/
2323

2424
#include <test/libsolidity/SolidityExecutionFramework.h>
25+
26+
#include <test/libsolidity/util/Common.h>
27+
#include <test/libsolidity/util/SoltestErrors.h>
28+
2529
#include <libevmasm/GasMeter.h>
2630
#include <libevmasm/KnownState.h>
2731
#include <libevmasm/PathGasMeter.h>
32+
2833
#include <libsolidity/ast/AST.h>
2934
#include <libsolidity/interface/GasEstimator.h>
3035

@@ -43,24 +48,39 @@ class GasMeterTestFramework: public SolidityExecutionFramework
4348
void compile(std::string const& _sourceCode)
4449
{
4550
m_compiler.reset();
46-
m_compiler.setSources({{"", "pragma solidity >=0.0;\n"
47-
"// SPDX-License-Identifier: GPL-3.0\n" + _sourceCode}});
48-
m_compiler.setOptimiserSettings(solidity::test::CommonOptions::get().optimize);
49-
m_compiler.setEVMVersion(m_evmVersion);
50-
BOOST_REQUIRE_MESSAGE(m_compiler.compile(), "Compiling contract failed");
51+
m_compilerInput = CompilerInput{};
52+
53+
m_compilerInput.sourceCode = {{"", withPreamble(_sourceCode)}};
54+
m_compilerInput.optimise = solidity::test::CommonOptions::get().optimize;
55+
m_compilerInput.evmVersion = std::make_optional(m_evmVersion);
56+
57+
m_compiler.compile(m_compilerInput);
58+
59+
BOOST_REQUIRE_MESSAGE(m_compiler.output().success(), "Compiling contract failed");
5160
}
5261

5362
void testCreationTimeGas(std::string const& _sourceCode, u256 const& _tolerance = u256(0))
5463
{
5564
compileAndRun(_sourceCode);
65+
5666
auto state = std::make_shared<KnownState>();
57-
PathGasMeter meter(*m_compiler.assemblyItems(m_compiler.lastContractName()), solidity::test::CommonOptions::get().evmVersion());
67+
auto const& output = m_compiler.output();
68+
auto const* contract = output.contract();
69+
70+
soltestAssert(contract);
71+
soltestAssert(contract->assemblyItems.has_value());
72+
73+
auto object = contract->object;
74+
auto runtimeObject = contract->runtimeObject;
75+
auto assemblyItems = contract->assemblyItems.value();
76+
77+
PathGasMeter meter(assemblyItems, solidity::test::CommonOptions::get().evmVersion());
5878
GasMeter::GasConsumption gas = meter.estimateMax(0, state);
59-
u256 bytecodeSize(m_compiler.runtimeObject(m_compiler.lastContractName()).bytecode.size());
79+
u256 bytecodeSize(runtimeObject.size());
6080
// costs for deployment
6181
gas += bytecodeSize * GasCosts::createDataGas;
6282
// costs for transaction
63-
gas += gasForTransaction(m_compiler.object(m_compiler.lastContractName()).bytecode, true);
83+
gas += gasForTransaction(object, true);
6484

6585
BOOST_REQUIRE(!gas.isInfinite);
6686
BOOST_CHECK_LE(m_gasUsed, gas.value);
@@ -71,6 +91,14 @@ class GasMeterTestFramework: public SolidityExecutionFramework
7191
/// against the actual gas usage computed by the VM on the given set of argument variants.
7292
void testRunTimeGas(std::string const& _sig, std::vector<bytes> _argumentVariants, u256 const& _tolerance = u256(0))
7393
{
94+
auto const& output = m_compiler.output();
95+
auto const* contract = output.contract();
96+
97+
soltestAssert(contract);
98+
soltestAssert(contract->runtimeAssemblyItems.has_value());
99+
100+
auto runtimeAssemblyItems = contract->runtimeAssemblyItems.value();
101+
74102
u256 gasUsed = 0;
75103
GasMeter::GasConsumption gas;
76104
util::FixedHash<4> hash = util::selectorFromSignatureH32(_sig);
@@ -83,7 +111,7 @@ class GasMeterTestFramework: public SolidityExecutionFramework
83111
}
84112

85113
gas += GasEstimator(solidity::test::CommonOptions::get().evmVersion()).functionalEstimation(
86-
*m_compiler.runtimeAssemblyItems(m_compiler.lastContractName()),
114+
runtimeAssemblyItems,
87115
_sig
88116
);
89117
BOOST_REQUIRE(!gas.isInfinite);

test/libsolidity/SemanticTest.cpp

+24-38
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ SemanticTest::SemanticTest(
118118

119119
if (m_enforceGasCost)
120120
{
121-
m_compiler.setMetadataFormat(CompilerStack::MetadataFormat::NoMetadata);
122-
m_compiler.setMetadataHash(CompilerStack::MetadataHash::None);
121+
m_compilerInput.metadataFormat = MetadataFormat::NoMetadata;
122+
m_compilerInput.metadataHash = MetadataHash::None;
123123
}
124124
}
125125

@@ -196,7 +196,7 @@ std::vector<SideEffectHook> SemanticTest::makeSideEffectHooks() const
196196
};
197197
}
198198

199-
std::string SemanticTest::formatEventParameter(std::optional<AnnotatedEventSignature> _signature, bool _indexed, size_t _index, bytes const& _data)
199+
std::string SemanticTest::formatEventParameter(EventSignature const* _signature, bool _indexed, size_t _index, bytes const& _data)
200200
{
201201
auto isPrintableASCII = [](bytes const& s)
202202
{
@@ -217,7 +217,7 @@ std::string SemanticTest::formatEventParameter(std::optional<AnnotatedEventSigna
217217
ABIType abiType(ABIType::Type::Hex);
218218
if (isPrintableASCII(_data))
219219
abiType = ABIType(ABIType::Type::String);
220-
if (_signature.has_value())
220+
if (_signature)
221221
{
222222
std::vector<std::string> const& types = _indexed ? _signature->indexedTypes : _signature->nonIndexedTypes;
223223
if (_index < types.size())
@@ -231,17 +231,19 @@ std::string SemanticTest::formatEventParameter(std::optional<AnnotatedEventSigna
231231

232232
std::vector<std::string> SemanticTest::eventSideEffectHook(FunctionCall const&) const
233233
{
234+
auto const& output = m_compiler.output();
235+
234236
std::vector<std::string> sideEffects;
235237
std::vector<LogRecord> recordedLogs = ExecutionFramework::recordedLogs();
236238
for (LogRecord const& log: recordedLogs)
237239
{
238-
std::optional<AnnotatedEventSignature> eventSignature;
240+
EventSignature const* eventSignature = nullptr;
239241
if (!log.topics.empty())
240-
eventSignature = matchEvent(log.topics[0]);
242+
eventSignature = output.matchEvent(log.topics[0]);
241243
std::stringstream sideEffect;
242244
sideEffect << "emit ";
243-
if (eventSignature.has_value())
244-
sideEffect << eventSignature.value().signature;
245+
if (eventSignature)
246+
sideEffect << eventSignature->signature;
245247
else
246248
sideEffect << "<anonymous>";
247249

@@ -252,7 +254,7 @@ std::vector<std::string> SemanticTest::eventSideEffectHook(FunctionCall const&)
252254
size_t index{0};
253255
for (h256 const& topic: log.topics)
254256
{
255-
if (!eventSignature.has_value() || index != 0)
257+
if (!eventSignature || index != 0)
256258
eventStrings.push_back("#" + formatEventParameter(eventSignature, true, index, topic.asBytes()));
257259
++index;
258260
}
@@ -273,31 +275,6 @@ std::vector<std::string> SemanticTest::eventSideEffectHook(FunctionCall const&)
273275
return sideEffects;
274276
}
275277

276-
std::optional<AnnotatedEventSignature> SemanticTest::matchEvent(util::h256 const& hash) const
277-
{
278-
std::optional<AnnotatedEventSignature> result;
279-
for (std::string& contractName: m_compiler.contractNames())
280-
{
281-
ContractDefinition const& contract = m_compiler.contractDefinition(contractName);
282-
for (EventDefinition const* event: contract.events() + contract.usedInterfaceEvents())
283-
{
284-
FunctionTypePointer eventFunctionType = event->functionType(true);
285-
if (!event->isAnonymous() && keccak256(eventFunctionType->externalSignature()) == hash)
286-
{
287-
AnnotatedEventSignature eventInfo;
288-
eventInfo.signature = eventFunctionType->externalSignature();
289-
for (auto const& param: event->parameters())
290-
if (param->isIndexed())
291-
eventInfo.indexedTypes.emplace_back(param->type()->toString(true));
292-
else
293-
eventInfo.nonIndexedTypes.emplace_back(param->type()->toString(true));
294-
result = eventInfo;
295-
}
296-
}
297-
}
298-
return result;
299-
}
300-
301278
frontend::OptimiserSettings SemanticTest::optimizerSettingsFor(RequiresYulOptimizer _requiresYulOptimizer)
302279
{
303280
switch (_requiresYulOptimizer)
@@ -383,13 +360,14 @@ TestCase::TestResult SemanticTest::runTest(
383360
}
384361
else if (test.call().kind == FunctionCall::Kind::Library)
385362
{
363+
std::string name = test.call().libraryFile + ":" + test.call().signature;
386364
soltestAssert(
387-
deploy(test.call().signature, 0, {}, libraries) && m_transactionSuccessful,
365+
deploy(name, 0, {}, libraries) && m_transactionSuccessful,
388366
"Failed to deploy library " + test.call().signature);
389367
// For convenience, in semantic tests we assume that an unqualified name like `L` is equivalent to one
390368
// with an empty source unit name (`:L`). This is fine because the compiler never uses unqualified
391369
// names in the Yul code it produces and does not allow `linkersymbol()` at all in inline assembly.
392-
libraries[test.call().libraryFile + ":" + test.call().signature] = m_contractAddress;
370+
libraries[name] = m_contractAddress;
393371
continue;
394372
}
395373
else
@@ -416,7 +394,13 @@ TestCase::TestResult SemanticTest::runTest(
416394
}
417395
else
418396
{
397+
ContractName contractName{m_sources.mainSourceFile, ""};
398+
399+
auto contract = m_compiler.output().contract(contractName);
400+
soltestAssert(contract);
401+
419402
bytes output;
403+
420404
if (test.call().kind == FunctionCall::Kind::LowLevel)
421405
output = callLowLevel(test.call().arguments.rawBytes(), test.call().value.value);
422406
else if (test.call().kind == FunctionCall::Kind::Builtin)
@@ -432,9 +416,10 @@ TestCase::TestResult SemanticTest::runTest(
432416
}
433417
else
434418
{
419+
soltestAssert(contract->interfaceSymbols.has_value());
435420
soltestAssert(
436421
m_allowNonExistingFunctions ||
437-
m_compiler.interfaceSymbols(m_compiler.lastContractName(m_sources.mainSourceFile))["methods"].contains(test.call().signature),
422+
contract->interfaceSymbols.value()["methods"].contains(test.call().signature),
438423
"The function " + test.call().signature + " is not known to the compiler"
439424
);
440425

@@ -462,7 +447,8 @@ TestCase::TestResult SemanticTest::runTest(
462447
test.setFailure(!m_transactionSuccessful);
463448
test.setRawBytes(std::move(output));
464449
if (test.call().kind != FunctionCall::Kind::LowLevel)
465-
test.setContractABI(m_compiler.contractABI(m_compiler.lastContractName(m_sources.mainSourceFile)));
450+
if (contract->contractABI.has_value())
451+
test.setContractABI(contract->contractABI.value());
466452
}
467453

468454
std::vector<std::string> effects;

test/libsolidity/SemanticTest.h

+1-9
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,6 @@
3030
namespace solidity::frontend::test
3131
{
3232

33-
struct AnnotatedEventSignature
34-
{
35-
std::string signature;
36-
std::vector<std::string> indexedTypes;
37-
std::vector<std::string> nonIndexedTypes;
38-
};
39-
4033
enum class RequiresYulOptimizer
4134
{
4235
False,
@@ -107,8 +100,7 @@ class SemanticTest: public SolidityExecutionFramework, public EVMVersionRestrict
107100
std::map<std::string, Builtin> makeBuiltins();
108101
std::vector<SideEffectHook> makeSideEffectHooks() const;
109102
std::vector<std::string> eventSideEffectHook(FunctionCall const&) const;
110-
std::optional<AnnotatedEventSignature> matchEvent(util::h256 const& hash) const;
111-
static std::string formatEventParameter(std::optional<AnnotatedEventSignature> _signature, bool _indexed, size_t _index, bytes const& _data);
103+
static std::string formatEventParameter(EventSignature const* _signature, bool _indexed, size_t _index, bytes const& _data);
112104

113105
OptimiserSettings optimizerSettingsFor(RequiresYulOptimizer _requiresYulOptimizer);
114106

test/libsolidity/SolidityEndToEndTest.cpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ BOOST_AUTO_TEST_CASE(creation_code_optimizer)
105105
}
106106
)";
107107

108-
m_metadataHash = CompilerStack::MetadataHash::None;
108+
m_metadataHash = MetadataHash::None;
109109
ALSO_VIA_YUL({
110110
bytes bytecodeC = compileContract(codeC);
111111
reset();
@@ -2815,9 +2815,17 @@ BOOST_AUTO_TEST_CASE(include_creation_bytecode_only_once)
28152815
}
28162816
)";
28172817
compileAndRun(sourceCode);
2818+
2819+
auto const& output = m_compiler.output();
2820+
auto const* contractDouble = output.contract("Double");
2821+
auto const* contractSingle = output.contract("Single");
2822+
2823+
solAssert(contractDouble);
2824+
solAssert(contractSingle);
2825+
28182826
BOOST_CHECK_LE(
2819-
double(m_compiler.object("Double").bytecode.size()),
2820-
1.2 * double(m_compiler.object("Single").bytecode.size())
2827+
double(contractDouble->object.size()),
2828+
1.2 * double(contractSingle->object.size())
28212829
);
28222830
}
28232831

0 commit comments

Comments
 (0)