diff options
author | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2016-02-18 18:18:54 +0900 |
---|---|---|
committer | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2016-02-22 16:19:42 +0900 |
commit | c9b9e5eea8b477a103cdec951ef2a299f9cd49ba (patch) | |
tree | e28f4e11d2e0e15a01082c10f05038f67d298946 | |
parent | a67fba3bf217ece75b66cb9adb6539e9d098ce9c (diff) | |
download | kati-c9b9e5eea8b477a103cdec951ef2a299f9cd49ba.tar.gz |
[C++] Associate global variables with Symbols directly
-rw-r--r-- | command.cc | 7 | ||||
-rw-r--r-- | dep.cc | 3 | ||||
-rw-r--r-- | eval.cc | 9 | ||||
-rw-r--r-- | eval.h | 4 | ||||
-rw-r--r-- | func.cc | 10 | ||||
-rw-r--r-- | main.cc | 21 | ||||
-rw-r--r-- | symtab.cc | 49 | ||||
-rw-r--r-- | symtab.h | 14 | ||||
-rw-r--r-- | var.cc | 4 | ||||
-rw-r--r-- | var.h | 2 |
10 files changed, 91 insertions, 32 deletions
@@ -171,12 +171,11 @@ void ParseCommandPrefixes(StringPiece* s, bool* echo, bool* ignore_error) { CommandEvaluator::CommandEvaluator(Evaluator* ev) : ev_(ev) { - Vars* vars = ev_->mutable_vars(); #define INSERT_AUTO_VAR(name, sym) do { \ Var* v = new name(this, sym); \ - (*vars)[Intern(sym)] = v; \ - (*vars)[Intern(sym"D")] = new AutoSuffixDVar(this, sym"D", v); \ - (*vars)[Intern(sym"F")] = new AutoSuffixFVar(this, sym"F", v); \ + Intern(sym).SetGlobalVar(v); \ + Intern(sym"D").SetGlobalVar(new AutoSuffixDVar(this, sym"D", v)); \ + Intern(sym"F").SetGlobalVar(new AutoSuffixFVar(this, sym"F", v)); \ } while (0) INSERT_AUTO_VAR(AutoAtVar, "@"); INSERT_AUTO_VAR(AutoLessVar, "<"); @@ -244,7 +244,8 @@ class DepBuilder { depfile_var_name_(Intern(".KATI_DEPFILE")) { ScopedTimeReporter tr("make dep (populate)"); PopulateRules(rules); - LOG_STAT("%zu variables", ev->mutable_vars()->size()); + // TODO? + //LOG_STAT("%zu variables", ev->mutable_vars()->size()); LOG_STAT("%zu explicit rules", rules_.size()); LOG_STAT("%zu implicit rules", implicit_rules_->size()); LOG_STAT("%zu suffix rules", suffix_rules_.size()); @@ -30,9 +30,8 @@ #include "symtab.h" #include "var.h" -Evaluator::Evaluator(const Vars* vars) - : vars_(new Vars(*vars)), - last_rule_(NULL), +Evaluator::Evaluator() + : last_rule_(NULL), current_scope_(NULL), avoid_io_(false), eval_depth_(0) { @@ -102,7 +101,7 @@ void Evaluator::EvalAssign(const AssignStmt* stmt) { Var* rhs = EvalRHS(lhs, stmt->rhs, stmt->orig_rhs, stmt->op, stmt->directive == AssignDirective::OVERRIDE); if (rhs) - vars_->Assign(lhs, rhs); + lhs.SetGlobalVar(rhs); } void Evaluator::EvalRule(const RuleStmt* stmt) { @@ -284,7 +283,7 @@ void Evaluator::EvalExport(const ExportStmt* stmt) { } Var* Evaluator::LookupVarGlobal(Symbol name) { - Var* v = vars_->Lookup(name); + Var* v = name.GetGlobalVar(); if (v->IsDefined()) return v; used_undefined_vars_.insert(name); @@ -33,7 +33,7 @@ class Vars; class Evaluator { public: - Evaluator(const Vars* vars); + Evaluator(); ~Evaluator(); void EvalAssign(const AssignStmt* stmt); @@ -56,7 +56,6 @@ class Evaluator { const unordered_map<Symbol, Vars*>& rule_vars() const { return rule_vars_; } - Vars* mutable_vars() { return vars_; } const unordered_map<Symbol, bool>& exports() const { return exports_; } void Error(const string& msg); @@ -97,7 +96,6 @@ class Evaluator { Var* LookupVarGlobal(Symbol name); - Vars* vars_; unordered_map<Symbol, Vars*> rule_vars_; vector<const Rule*> rules_; unordered_map<Symbol, bool> exports_; @@ -595,7 +595,7 @@ void CallFunc(const vector<Value*>& args, Evaluator* ev, string* s) { new SimpleVar(args[i]->Eval(ev), VarOrigin::AUTOMATIC)); av.push_back(move(s)); } - vector<unique_ptr<ScopedVar>> sv; + vector<unique_ptr<ScopedGlobalVar>> sv; for (size_t i = 1; ; i++) { string s; Symbol tmpvar_name_sym(Symbol::IsUninitialized{}); @@ -606,8 +606,7 @@ void CallFunc(const vector<Value*>& args, Evaluator* ev, string* s) { tmpvar_name_sym = Intern(s); } if (i < args.size()) { - sv.emplace_back(new ScopedVar(ev->mutable_vars(), - tmpvar_name_sym, av[i-1].get())); + sv.emplace_back(new ScopedGlobalVar(tmpvar_name_sym, av[i-1].get())); } else { // We need to blank further automatic vars Var *v = ev->LookupVar(tmpvar_name_sym); @@ -615,8 +614,7 @@ void CallFunc(const vector<Value*>& args, Evaluator* ev, string* s) { if (v->Origin() != VarOrigin::AUTOMATIC) break; av.emplace_back(new SimpleVar("", VarOrigin::AUTOMATIC)); - sv.emplace_back(new ScopedVar(ev->mutable_vars(), - tmpvar_name_sym, av[i-1].get())); + sv.emplace_back(new ScopedGlobalVar(tmpvar_name_sym, av[i-1].get())); } } @@ -633,7 +631,7 @@ void ForeachFunc(const vector<Value*>& args, Evaluator* ev, string* s) { for (StringPiece tok : WordScanner(list)) { unique_ptr<SimpleVar> v(new SimpleVar( tok.as_string(), VarOrigin::AUTOMATIC)); - ScopedVar sv(ev->mutable_vars(), Intern(varname), v.get()); + ScopedGlobalVar sv(Intern(varname), v.get()); ww.MaybeAddWhitespace(); args[2]->Eval(ev, s); } @@ -105,13 +105,13 @@ static void ReadBootstrapMakefile(const vector<Symbol>& targets, Parse(Intern(bootstrap).str(), Loc("*bootstrap*", 0), stmts); } -static void SetVar(StringPiece l, VarOrigin origin, Vars* vars) { +static void SetVar(StringPiece l, VarOrigin origin) { size_t found = l.find('='); CHECK(found != string::npos); Symbol lhs = Intern(l.substr(0, found)); StringPiece rhs = l.substr(found + 1); - vars->Assign(lhs, - new RecursiveVar(NewLiteral(rhs.data()), origin, rhs.data())); + lhs.SetGlobalVar( + new RecursiveVar(NewLiteral(rhs.data()), origin, rhs.data())); } extern "C" char** environ; @@ -138,14 +138,12 @@ static int Run(const vector<Symbol>& targets, MakefileCacheManager* cache_mgr = NewMakefileCacheManager(); - Vars* vars = new Vars(); - vars->Assign(Intern("MAKEFILE_LIST"), - new SimpleVar(StringPrintf(" %s", g_flags.makefile), - VarOrigin::FILE)); + Intern("MAKEFILE_LIST").SetGlobalVar( + new SimpleVar(StringPrintf(" %s", g_flags.makefile), VarOrigin::FILE)); for (char** p = environ; *p; p++) { - SetVar(*p, VarOrigin::ENVIRONMENT, vars); + SetVar(*p, VarOrigin::ENVIRONMENT); } - Evaluator* ev = new Evaluator(vars); + Evaluator* ev = new Evaluator(); vector<Stmt*> bootstrap_asts; ReadBootstrapMakefile(targets, &bootstrap_asts); @@ -157,7 +155,7 @@ static int Run(const vector<Symbol>& targets, ev->set_is_bootstrap(false); for (StringPiece l : cl_vars) { - SetVar(l, VarOrigin::COMMAND_LINE, ev->mutable_vars()); + SetVar(l, VarOrigin::COMMAND_LINE); } { @@ -210,9 +208,6 @@ static int Run(const vector<Symbol>& targets, for (Stmt* stmt : bootstrap_asts) delete stmt; delete ev; - // Each Var will be deleted by |ev|. - vars->clear(); - delete vars; delete cache_mgr; return 0; @@ -27,8 +27,18 @@ #include "log.h" #include "strutil.h" +#include "var.h" + +struct SymbolData { + SymbolData() + : gv(kUndefined) { + } + + Var* gv; +}; vector<string*>* g_symbols; +static vector<SymbolData> g_symbol_data; Symbol kEmptySym = Symbol(Symbol::IsUninitialized()); Symbol kShellSym = Symbol(Symbol::IsUninitialized()); @@ -37,6 +47,45 @@ Symbol::Symbol(int v) : v_(v) { } +Var* Symbol::GetGlobalVar() const { + if (static_cast<size_t>(v_) >= g_symbol_data.size()) { + g_symbol_data.resize(v_ + 1); + } + Var* v = g_symbol_data[v_].gv; + if (v->Origin() == VarOrigin::ENVIRONMENT || + v->Origin() == VarOrigin::ENVIRONMENT_OVERRIDE) { + Vars::add_used_env_vars(*this); + } + return v; +} + +void Symbol::SetGlobalVar(Var* v) const { + if (static_cast<size_t>(v_) >= g_symbol_data.size()) { + g_symbol_data.resize(v_ + 1); + } + Var* orig = g_symbol_data[v_].gv; + if (orig->Origin() == VarOrigin::OVERRIDE || + orig->Origin() == VarOrigin::ENVIRONMENT_OVERRIDE) { + return; + } + if (orig->Origin() == VarOrigin::AUTOMATIC) { + ERROR("overriding automatic variable is not implemented yet"); + } + if (orig->IsDefined()) + delete orig; + g_symbol_data[v_].gv = v; +} + +ScopedGlobalVar::ScopedGlobalVar(Symbol name, Var* var) + : name_(name), orig_(NULL) { + orig_ = name.GetGlobalVar(); + g_symbol_data[name_.val()].gv = var; +} + +ScopedGlobalVar::~ScopedGlobalVar() { + g_symbol_data[name_.val()].gv = orig_; +} + class Symtab { public: Symtab() { @@ -25,6 +25,7 @@ using namespace std; extern vector<string*>* g_symbols; class Symtab; +class Var; class Symbol { public: @@ -54,6 +55,9 @@ class Symbol { bool IsValid() const { return v_ >= 0; } + Var* GetGlobalVar() const; + void SetGlobalVar(Var* v) const; + private: explicit Symbol(int v); @@ -62,6 +66,16 @@ class Symbol { friend class Symtab; }; +class ScopedGlobalVar { + public: + ScopedGlobalVar(Symbol name, Var* var); + ~ScopedGlobalVar(); + + private: + Symbol name_; + Var* orig_; +}; + inline bool operator==(const Symbol& x, const Symbol& y) { return x.val() == y.val(); } @@ -112,6 +112,10 @@ Vars::~Vars() { } } +void Vars::add_used_env_vars(Symbol v) { + used_env_vars_.insert(v); +} + Var* Vars::Lookup(Symbol name) const { auto found = find(name); if (found == end()) @@ -179,6 +179,8 @@ class Vars : public unordered_map<Symbol, Var*> { void Assign(Symbol name, Var* v); + static void add_used_env_vars(Symbol v); + static const unordered_set<Symbol>& used_env_vars() { return used_env_vars_; } |