@@ -99,7 +99,7 @@ using solidity::util::toHex;
99
99
static int g_compilerStackCounts = 0 ;
100
100
101
101
CompilerStack::CompilerStack (ReadCallback::Callback _readFile):
102
- m_readFile{std:: move (_readFile)},
102
+ m_readFile{move (_readFile)},
103
103
m_errorReporter{m_errorList}
104
104
{
105
105
// Because TypeProvider is currently a singleton API, we must ensure that
@@ -208,7 +208,7 @@ void CompilerStack::setRemappings(vector<ImportRemapper::Remapping> _remappings)
208
208
solThrow (CompilerError, " Must set remappings before parsing." );
209
209
for (auto const & remapping: _remappings)
210
210
solAssert (!remapping.prefix .empty (), " " );
211
- m_importRemapper.setRemappings (std:: move (_remappings));
211
+ m_importRemapper.setRemappings (move (_remappings));
212
212
}
213
213
214
214
void CompilerStack::setViaIR (bool _viaIR)
@@ -232,7 +232,7 @@ void CompilerStack::setModelCheckerSettings(ModelCheckerSettings _settings)
232
232
m_modelCheckerSettings = _settings;
233
233
}
234
234
235
- void CompilerStack::setLibraries (std:: map<std:: string, util::h160> const & _libraries)
235
+ void CompilerStack::setLibraries (map<string, util::h160> const & _libraries)
236
236
{
237
237
if (m_stackState >= ParsedAndImported)
238
238
solThrow (CompilerError, " Must set libraries before parsing." );
@@ -242,15 +242,16 @@ void CompilerStack::setLibraries(std::map<std::string, util::h160> const& _libra
242
242
void CompilerStack::setOptimiserSettings (bool _optimize, size_t _runs)
243
243
{
244
244
OptimiserSettings settings = _optimize ? OptimiserSettings::standard () : OptimiserSettings::minimal ();
245
+ settings.enabled = _optimize;
245
246
settings.expectedExecutionsPerDeployment = _runs;
246
- setOptimiserSettings (std:: move (settings));
247
+ setOptimiserSettings (move (settings));
247
248
}
248
249
249
250
void CompilerStack::setOptimiserSettings (OptimiserSettings _settings)
250
251
{
251
252
if (m_stackState >= ParsedAndImported)
252
253
solThrow (CompilerError, " Must set optimiser settings before parsing." );
253
- m_optimiserSettings = std:: move (_settings);
254
+ m_optimiserSettings = move (_settings);
254
255
}
255
256
256
257
void CompilerStack::setRevertStringBehaviour (RevertStrings _revertStrings)
@@ -326,7 +327,7 @@ void CompilerStack::setSources(StringMap _sources)
326
327
if (m_stackState != Empty)
327
328
solThrow (CompilerError, " Must set sources before parsing." );
328
329
for (auto source: _sources)
329
- m_sources[source.first ].charStream = make_unique<CharStream>(/* content*/ std:: move (source.second ), /* name*/ source.first );
330
+ m_sources[source.first ].charStream = make_unique<CharStream>(/* content*/ move (source.second ), /* name*/ source.first );
330
331
m_stackState = SourcesSet;
331
332
}
332
333
@@ -408,14 +409,37 @@ void CompilerStack::importASTs(map<string, Json::Value> const& _sources)
408
409
src.first ,
409
410
true // imported from AST
410
411
);
411
- m_sources[path] = std:: move (source);
412
+ m_sources[path] = move (source);
412
413
}
413
414
m_stackState = ParsedAndImported;
414
415
m_compilationSourceType = CompilationSourceType::SolidityAST;
415
416
416
417
storeContractDefinitions ();
417
418
}
418
419
420
+ void CompilerStack::importEvmAssemblyJson (map<string, Json::Value> const & _sources)
421
+ {
422
+ solAssert (_sources.size () == 1 , " " );
423
+ solAssert (m_sourceJsons.empty (), " " );
424
+ solAssert (m_sourceOrder.empty (), " " );
425
+ if (m_stackState != Empty)
426
+ solThrow (CompilerError, " Must call importEvmAssemblyJson only before the SourcesSet state." );
427
+
428
+ m_sourceJsons = _sources;
429
+ Json::Value jsonValue = _sources.begin ()->second ;
430
+ if (jsonValue.isMember (" sourceList" ))
431
+ for (auto const & item: jsonValue[" sourceList" ])
432
+ {
433
+ Source source;
434
+ source.charStream = make_shared<CharStream>(item.asString (), " " );
435
+ m_sources.emplace (make_pair (item.asString (), source));
436
+ m_sourceOrder.push_back (&m_sources[item.asString ()]);
437
+ }
438
+ m_sourceJsons[_sources.begin ()->first ] = move (jsonValue);
439
+ m_compilationSourceType = CompilationSourceType::EvmAssemblyJson;
440
+ m_stackState = SourcesSet;
441
+ }
442
+
419
443
bool CompilerStack::analyze ()
420
444
{
421
445
if (m_stackState != ParsedAndImported || m_stackState >= AnalysisPerformed)
@@ -605,6 +629,9 @@ bool CompilerStack::parseAndAnalyze(State _stopAfter)
605
629
{
606
630
m_stopAfter = _stopAfter;
607
631
632
+ if (m_compilationSourceType == CompilationSourceType::EvmAssemblyJson)
633
+ return true ;
634
+
608
635
bool success = parse ();
609
636
if (m_stackState >= m_stopAfter)
610
637
return success;
@@ -654,53 +681,73 @@ bool CompilerStack::compile(State _stopAfter)
654
681
// Only compile contracts individually which have been requested.
655
682
map<ContractDefinition const *, shared_ptr<Compiler const >> otherCompilers;
656
683
657
- for (Source const * source: m_sourceOrder)
658
- for (ASTPointer<ASTNode> const & node: source->ast ->nodes ())
659
- if (auto contract = dynamic_cast <ContractDefinition const *>(node.get ()))
660
- if (isRequestedContract (*contract))
661
- {
662
- try
684
+ if (m_compilationSourceType == CompilationSourceType::EvmAssemblyJson)
685
+ {
686
+ solAssert (m_sourceJsons.size () == 1 );
687
+
688
+ string const evmSourceName = m_sourceJsons.begin ()->first ;
689
+ Json::Value const evmJson = m_sourceJsons.begin ()->second ;
690
+
691
+ evmasm::Assembly::OptimiserSettings optimiserSettings =
692
+ evmasm::Assembly::OptimiserSettings::translateSettings (m_optimiserSettings, m_evmVersion);
693
+
694
+ m_contracts[evmSourceName].evmAssembly = evmasm::Assembly::loadFromAssemblyJSON (m_sourceJsons[evmSourceName]);
695
+ if (m_optimiserSettings.enabled )
696
+ m_contracts[evmSourceName].evmAssembly ->optimise (optimiserSettings);
697
+ m_contracts[evmSourceName].object = m_contracts[evmSourceName].evmAssembly ->assemble ();
698
+
699
+ m_contracts[evmSourceName].evmRuntimeAssembly = make_shared<evmasm::Assembly>(m_contracts[evmSourceName].evmAssembly ->sub (0 ));
700
+ solAssert (m_contracts[evmSourceName].evmRuntimeAssembly ->isCreation () == false );
701
+ if (m_optimiserSettings.enabled )
702
+ m_contracts[evmSourceName].evmRuntimeAssembly ->optimise (optimiserSettings);
703
+ m_contracts[evmSourceName].runtimeObject = m_contracts[evmSourceName].evmRuntimeAssembly ->assemble ();
704
+ }
705
+ else
706
+ {
707
+ for (Source const * source: m_sourceOrder)
708
+ for (ASTPointer<ASTNode> const & node: source->ast ->nodes ())
709
+ if (auto contract = dynamic_cast <ContractDefinition const *>(node.get ()))
710
+ if (isRequestedContract (*contract))
663
711
{
664
- if (m_viaIR || m_generateIR || m_generateEwasm)
665
- generateIR (*contract);
666
- if (m_generateEvmBytecode)
712
+ try
667
713
{
668
- if (m_viaIR)
669
- generateEVMFromIR (*contract);
670
- else
671
- compileContract (*contract, otherCompilers);
714
+ if (m_viaIR || m_generateIR || m_generateEwasm)
715
+ generateIR (*contract);
716
+ if (m_generateEvmBytecode)
717
+ {
718
+ if (m_viaIR)
719
+ generateEVMFromIR (*contract);
720
+ else
721
+ compileContract (*contract, otherCompilers);
722
+ }
723
+ if (m_generateEwasm)
724
+ generateEwasm (*contract);
672
725
}
673
- if (m_generateEwasm)
674
- generateEwasm (*contract);
675
- }
676
- catch (Error const & _error)
677
- {
678
- if (_error.type () != Error::Type::CodeGenerationError)
679
- throw ;
680
- m_errorReporter.error (_error.errorId (), _error.type (), SourceLocation (), _error.what ());
681
- return false ;
682
- }
683
- catch (UnimplementedFeatureError const & _unimplementedError)
684
- {
685
- if (
686
- SourceLocation const * sourceLocation =
687
- boost::get_error_info<langutil::errinfo_sourceLocation>(_unimplementedError)
688
- )
726
+ catch (Error const & _error)
689
727
{
690
- string const * comment = _unimplementedError.comment ();
691
- m_errorReporter.error (
692
- 1834_error,
693
- Error::Type::CodeGenerationError,
694
- *sourceLocation,
695
- " Unimplemented feature error" +
696
- ((comment && !comment->empty ()) ? " : " + *comment : string{}) +
697
- " in " +
698
- _unimplementedError.lineInfo ()
699
- );
728
+ if (_error.type () != Error::Type::CodeGenerationError)
729
+ throw ;
730
+ m_errorReporter.error (_error.errorId (), _error.type (), SourceLocation (), _error.what ());
700
731
return false ;
701
732
}
702
- else
703
- throw ;
733
+ catch (UnimplementedFeatureError const & _unimplementedError)
734
+ {
735
+ if (SourceLocation const * sourceLocation
736
+ = boost::get_error_info<langutil::errinfo_sourceLocation>(_unimplementedError))
737
+ {
738
+ string const * comment = _unimplementedError.comment ();
739
+ m_errorReporter.error (
740
+ 1834_error,
741
+ Error::Type::CodeGenerationError,
742
+ *sourceLocation,
743
+ " Unimplemented feature error"
744
+ + ((comment && !comment->empty ()) ? " : " + *comment : string{}) + " in "
745
+ + _unimplementedError.lineInfo ());
746
+ return false ;
747
+ }
748
+ else
749
+ throw ;
750
+ }
704
751
}
705
752
}
706
753
m_stackState = CompilationSuccessful;
@@ -794,7 +841,7 @@ Json::Value CompilerStack::generatedSources(string const& _contractName, bool _r
794
841
sources[0 ][" name" ] = sourceName;
795
842
sources[0 ][" id" ] = sourceIndex;
796
843
sources[0 ][" language" ] = " Yul" ;
797
- sources[0 ][" contents" ] = std:: move (source);
844
+ sources[0 ][" contents" ] = move (source);
798
845
799
846
}
800
847
}
@@ -832,7 +879,7 @@ string const* CompilerStack::runtimeSourceMapping(string const& _contractName) c
832
879
return c.runtimeSourceMapping ? &*c.runtimeSourceMapping : nullptr ;
833
880
}
834
881
835
- std:: string const CompilerStack::filesystemFriendlyName (string const & _contractName) const
882
+ string const CompilerStack::filesystemFriendlyName (string const & _contractName) const
836
883
{
837
884
if (m_stackState < AnalysisPerformed)
838
885
solThrow (CompilerError, " No compiled contracts found." );
@@ -846,7 +893,7 @@ std::string const CompilerStack::filesystemFriendlyName(string const& _contractN
846
893
contract.second .contract != matchContract.contract )
847
894
{
848
895
// If it does, then return its fully-qualified name, made fs-friendly
849
- std:: string friendlyName = boost::algorithm::replace_all_copy (_contractName, " /" , " _" );
896
+ string friendlyName = boost::algorithm::replace_all_copy (_contractName, " /" , " _" );
850
897
boost::algorithm::replace_all (friendlyName, " :" , " _" );
851
898
boost::algorithm::replace_all (friendlyName, " ." , " _" );
852
899
return friendlyName;
@@ -943,9 +990,10 @@ map<string, unsigned> CompilerStack::sourceIndices() const
943
990
map<string, unsigned > indices;
944
991
unsigned index = 0 ;
945
992
for (auto const & s: m_sources)
946
- indices[s.first ] = index++;
947
- solAssert (!indices.count (CompilerContext::yulUtilityFileName ()), " " );
948
- indices[CompilerContext::yulUtilityFileName ()] = index++;
993
+ if (s.first != CompilerContext::yulUtilityFileName ())
994
+ indices[s.first ] = index++;
995
+ if (indices.find (CompilerContext::yulUtilityFileName ()) == indices.end ())
996
+ indices[CompilerContext::yulUtilityFileName ()] = index++;
949
997
return indices;
950
998
}
951
999
@@ -1098,7 +1146,7 @@ ContractDefinition const& CompilerStack::contractDefinition(string const& _contr
1098
1146
}
1099
1147
1100
1148
size_t CompilerStack::functionEntryPoint (
1101
- std:: string const & _contractName,
1149
+ string const & _contractName,
1102
1150
FunctionDefinition const & _function
1103
1151
) const
1104
1152
{
@@ -1240,8 +1288,8 @@ bool onlySafeExperimentalFeaturesActivated(set<ExperimentalFeature> const& featu
1240
1288
1241
1289
void CompilerStack::assemble (
1242
1290
ContractDefinition const & _contract,
1243
- std:: shared_ptr<evmasm::Assembly> _assembly,
1244
- std:: shared_ptr<evmasm::Assembly> _runtimeAssembly
1291
+ shared_ptr<evmasm::Assembly> _assembly,
1292
+ shared_ptr<evmasm::Assembly> _runtimeAssembly
1245
1293
)
1246
1294
{
1247
1295
solAssert (m_stackState >= AnalysisPerformed, " " );
@@ -1435,8 +1483,8 @@ void CompilerStack::generateEwasm(ContractDefinition const& _contract)
1435
1483
1436
1484
// Turn into Ewasm text representation.
1437
1485
auto result = stack.assemble (yul::YulStack::Machine::Ewasm);
1438
- compiledContract.ewasm = std:: move (result.assembly );
1439
- compiledContract.ewasmObject = std:: move (*result.bytecode );
1486
+ compiledContract.ewasm = move (result.assembly );
1487
+ compiledContract.ewasmObject = move (*result.bytecode );
1440
1488
}
1441
1489
1442
1490
CompilerStack::Contract const & CompilerStack::contract (string const & _contractName) const
@@ -1492,6 +1540,11 @@ string CompilerStack::createMetadata(Contract const& _contract, bool _forIR) con
1492
1540
case CompilationSourceType::SolidityAST:
1493
1541
sourceType = " SolidityAST" ;
1494
1542
break ;
1543
+ case CompilationSourceType::EvmAssemblyJson:
1544
+ sourceType = " EvmAssemblyJson" ;
1545
+ break ;
1546
+ default :
1547
+ solAssert (false );
1495
1548
}
1496
1549
meta[" language" ] = sourceType;
1497
1550
meta[" compiler" ][" version" ] = VersionStringStrict;
@@ -1523,7 +1576,7 @@ string CompilerStack::createMetadata(Contract const& _contract, bool _forIR) con
1523
1576
}
1524
1577
1525
1578
static_assert (sizeof (m_optimiserSettings.expectedExecutionsPerDeployment ) <= sizeof (Json::LargestUInt), " Invalid word size." );
1526
- solAssert (static_cast <Json::LargestUInt>(m_optimiserSettings.expectedExecutionsPerDeployment ) < std:: numeric_limits<Json::LargestUInt>::max (), " " );
1579
+ solAssert (static_cast <Json::LargestUInt>(m_optimiserSettings.expectedExecutionsPerDeployment ) < numeric_limits<Json::LargestUInt>::max (), " " );
1527
1580
meta[" settings" ][" optimizer" ][" runs" ] = Json::Value (Json::LargestUInt (m_optimiserSettings.expectedExecutionsPerDeployment ));
1528
1581
1529
1582
// / Backwards compatibility: If set to one of the default settings, do not provide details.
@@ -1553,7 +1606,7 @@ string CompilerStack::createMetadata(Contract const& _contract, bool _forIR) con
1553
1606
details[" yulDetails" ][" optimizerSteps" ] = m_optimiserSettings.yulOptimiserSteps + " :" + m_optimiserSettings.yulOptimiserCleanupSteps ;
1554
1607
}
1555
1608
1556
- meta[" settings" ][" optimizer" ][" details" ] = std:: move (details);
1609
+ meta[" settings" ][" optimizer" ][" details" ] = move (details);
1557
1610
}
1558
1611
1559
1612
if (m_revertStrings != RevertStrings::Default)
0 commit comments