Refactor switch compiler factories
This commit is contained in:
parent
6fef1c5444
commit
b9b66b9244
7 changed files with 25 additions and 50 deletions
|
@ -43,9 +43,9 @@ CodeGenerator::CodeGenerator(
|
||||||
const SimpleDwarf& dwarf,
|
const SimpleDwarf& dwarf,
|
||||||
std::ostream& os,
|
std::ostream& os,
|
||||||
NamingScheme naming_scheme,
|
NamingScheme naming_scheme,
|
||||||
AbstractSwitchCompilerFactory* factory) :
|
AbstractSwitchCompiler* sw_compiler) :
|
||||||
dwarf(dwarf), os(os), pc_list(nullptr),
|
dwarf(dwarf), os(os), pc_list(nullptr),
|
||||||
naming_scheme(naming_scheme), switch_factory(factory)
|
naming_scheme(naming_scheme), switch_compiler(sw_compiler)
|
||||||
{
|
{
|
||||||
if(!settings::pc_list.empty()) {
|
if(!settings::pc_list.empty()) {
|
||||||
pc_list = make_unique<PcListReader>(settings::pc_list);
|
pc_list = make_unique<PcListReader>(settings::pc_list);
|
||||||
|
@ -122,8 +122,7 @@ void CodeGenerator::gen_of_dwarf() {
|
||||||
SwitchStatement sw_stmt = gen_fresh_switch();
|
SwitchStatement sw_stmt = gen_fresh_switch();
|
||||||
for(const auto& fde: dwarf.fde_list)
|
for(const auto& fde: dwarf.fde_list)
|
||||||
switch_append_fde(sw_stmt, fde);
|
switch_append_fde(sw_stmt, fde);
|
||||||
auto sw_compiler = (*switch_factory)(sw_stmt);
|
(*switch_compiler)(os, sw_stmt);
|
||||||
(*sw_compiler)(os);
|
|
||||||
gen_unwind_func_footer();
|
gen_unwind_func_footer();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -150,8 +149,7 @@ void CodeGenerator::gen_function_of_fde(const SimpleDwarf::Fde& fde) {
|
||||||
|
|
||||||
SwitchStatement sw_stmt = gen_fresh_switch();
|
SwitchStatement sw_stmt = gen_fresh_switch();
|
||||||
switch_append_fde(sw_stmt, fde);
|
switch_append_fde(sw_stmt, fde);
|
||||||
auto sw_compiler = (*switch_factory)(sw_stmt);
|
(*switch_compiler)(os, sw_stmt);
|
||||||
(*sw_compiler)(os);
|
|
||||||
|
|
||||||
gen_unwind_func_footer();
|
gen_unwind_func_footer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ class CodeGenerator {
|
||||||
* given std::ostream object (eg. cout). */
|
* given std::ostream object (eg. cout). */
|
||||||
CodeGenerator(const SimpleDwarf& dwarf, std::ostream& os,
|
CodeGenerator(const SimpleDwarf& dwarf, std::ostream& os,
|
||||||
NamingScheme naming_scheme,
|
NamingScheme naming_scheme,
|
||||||
AbstractSwitchCompilerFactory* factory);
|
AbstractSwitchCompiler* sw_compiler);
|
||||||
|
|
||||||
/// Actually generate the code on the given stream
|
/// Actually generate the code on the given stream
|
||||||
void generate();
|
void generate();
|
||||||
|
@ -64,5 +64,5 @@ class CodeGenerator {
|
||||||
|
|
||||||
NamingScheme naming_scheme;
|
NamingScheme naming_scheme;
|
||||||
|
|
||||||
std::unique_ptr<AbstractSwitchCompilerFactory> switch_factory;
|
std::unique_ptr<AbstractSwitchCompiler> switch_compiler;
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
NativeSwitchCompiler::NativeSwitchCompiler(
|
NativeSwitchCompiler::NativeSwitchCompiler(
|
||||||
const SwitchStatement& sw, int indent):
|
int indent):
|
||||||
AbstractSwitchCompiler(sw, indent)
|
AbstractSwitchCompiler(indent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void NativeSwitchCompiler::to_stream(ostream& os) {
|
void NativeSwitchCompiler::to_stream(ostream& os, const SwitchStatement& sw) {
|
||||||
os << indent() << "switch(" << sw.switch_var << ") {\n";
|
os << indent() << "switch(" << sw.switch_var << ") {\n";
|
||||||
indent_count++;
|
indent_count++;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
class NativeSwitchCompiler: public AbstractSwitchCompiler {
|
class NativeSwitchCompiler: public AbstractSwitchCompiler {
|
||||||
public:
|
public:
|
||||||
NativeSwitchCompiler(const SwitchStatement& sw, int indent=0);
|
NativeSwitchCompiler(int indent=0);
|
||||||
private:
|
private:
|
||||||
virtual void to_stream(std::ostream& os);
|
virtual void to_stream(std::ostream& os, const SwitchStatement& sw);
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,19 +5,20 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
AbstractSwitchCompiler::AbstractSwitchCompiler(
|
AbstractSwitchCompiler::AbstractSwitchCompiler(
|
||||||
const SwitchStatement& sw,
|
|
||||||
int indent)
|
int indent)
|
||||||
: sw(sw), indent_count(indent)
|
: indent_count(indent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractSwitchCompiler::operator()(ostream& os) {
|
void AbstractSwitchCompiler::operator()(
|
||||||
to_stream(os);
|
ostream& os, const SwitchStatement& sw)
|
||||||
|
{
|
||||||
|
to_stream(os, sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
string AbstractSwitchCompiler::operator()() {
|
string AbstractSwitchCompiler::operator()(const SwitchStatement& sw) {
|
||||||
ostringstream os;
|
ostringstream os;
|
||||||
(*this)(os);
|
(*this)(os, sw);
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ std::string AbstractSwitchCompiler::indent_str(const std::string& str) {
|
||||||
<< str.substr(last_find + 1, find_pos - last_find); // includes \n
|
<< str.substr(last_find + 1, find_pos - last_find); // includes \n
|
||||||
last_find = find_pos;
|
last_find = find_pos;
|
||||||
}
|
}
|
||||||
if(last_find + 1 < (int)str.size()) {
|
if(last_find + 1 < (ssize_t)str.size()) {
|
||||||
out << indent()
|
out << indent()
|
||||||
<< str.substr(last_find + 1)
|
<< str.substr(last_find + 1)
|
||||||
<< '\n';
|
<< '\n';
|
||||||
|
@ -45,5 +46,3 @@ std::string AbstractSwitchCompiler::indent() const {
|
||||||
std::string AbstractSwitchCompiler::endcl() const {
|
std::string AbstractSwitchCompiler::endcl() const {
|
||||||
return string("\n") + indent();
|
return string("\n") + indent();
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractSwitchCompilerFactory::AbstractSwitchCompilerFactory() {}
|
|
||||||
|
|
|
@ -21,38 +21,16 @@ struct SwitchStatement {
|
||||||
|
|
||||||
class AbstractSwitchCompiler {
|
class AbstractSwitchCompiler {
|
||||||
public:
|
public:
|
||||||
AbstractSwitchCompiler(const SwitchStatement& sw,
|
AbstractSwitchCompiler(int indent=0);
|
||||||
int indent=0);
|
void operator()(std::ostream& os, const SwitchStatement& sw);
|
||||||
void operator()(std::ostream& os);
|
std::string operator()(const SwitchStatement& sw);
|
||||||
std::string operator()();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void to_stream(std::ostream& os) = 0;
|
virtual void to_stream(
|
||||||
|
std::ostream& os, const SwitchStatement& sw) = 0;
|
||||||
std::string indent_str(const std::string& str) ;
|
std::string indent_str(const std::string& str) ;
|
||||||
std::string indent() const;
|
std::string indent() const;
|
||||||
std::string endcl() const;
|
std::string endcl() const;
|
||||||
|
|
||||||
|
|
||||||
SwitchStatement sw;
|
|
||||||
int indent_count;
|
int indent_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AbstractSwitchCompilerFactory {
|
|
||||||
public:
|
|
||||||
AbstractSwitchCompilerFactory();
|
|
||||||
virtual std::shared_ptr<AbstractSwitchCompiler> operator()(
|
|
||||||
const SwitchStatement& sw,
|
|
||||||
int indent=0) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Compiler>
|
|
||||||
class SwitchCompilerFactory : public AbstractSwitchCompilerFactory {
|
|
||||||
public:
|
|
||||||
virtual std::shared_ptr<AbstractSwitchCompiler> operator()(
|
|
||||||
const SwitchStatement& sw,
|
|
||||||
int indent=0)
|
|
||||||
{
|
|
||||||
return std::shared_ptr<AbstractSwitchCompiler>(
|
|
||||||
new Compiler(sw, indent));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ int main(int argc, char** argv) {
|
||||||
ss << "_fde_" << fde.beg_ip;
|
ss << "_fde_" << fde.beg_ip;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
},
|
},
|
||||||
new SwitchCompilerFactory<NativeSwitchCompiler>());
|
new NativeSwitchCompiler());
|
||||||
code_gen.generate();
|
code_gen.generate();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue