[pure-lang-svn] SF.net SVN: pure-lang:[443] pure/trunk
Status: Beta
Brought to you by:
agraef
|
From: <ag...@us...> - 2008-08-02 07:07:35
|
Revision: 443
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=443&view=rev
Author: agraef
Date: 2008-08-02 07:07:44 +0000 (Sat, 02 Aug 2008)
Log Message:
-----------
Move map of local function environments to separate class.
Modified Paths:
--------------
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
pure/trunk/lexer.ll
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-07-31 12:16:17 UTC (rev 442)
+++ pure/trunk/interpreter.cc 2008-08-02 07:07:44 UTC (rev 443)
@@ -1942,8 +1942,7 @@
args = e.args; envs = e.envs;
b = e.b; local = e.local; parent = e.parent;
}
- fmap = e.fmap; fmap_idx = e.fmap_idx;
- xmap = e.xmap; xtab = e.xtab; prop = e.prop; m = e.m;
+ fmap = e.fmap; xmap = e.xmap; xtab = e.xtab; prop = e.prop; m = e.m;
return *this;
}
@@ -1961,7 +1960,7 @@
interp.JIT->freeMachineCodeForFunction(f);
f->dropAllReferences(); if (h != f) h->dropAllReferences();
fp = 0;
- fmap.clear(); fmap_idx = 0;
+ fmap.clear();
to_be_deleted.push_back(f); if (h != f) to_be_deleted.push_back(h);
} else {
#if DEBUG>2
@@ -1978,8 +1977,7 @@
}
fp = 0;
// delete all nested environments and reinitialize other body-related data
- fmap.clear(); fmap_idx = 0;
- xmap.clear(); xtab.clear(); prop.clear(); m = 0;
+ fmap.clear(); xmap.clear(); xtab.clear(); prop.clear(); m = 0;
// now that all references have been removed, delete the function pointers
for (list<Function*>::iterator fi = to_be_deleted.begin();
fi != to_be_deleted.end(); fi++) {
@@ -2130,7 +2128,7 @@
fenv = *ei++;
}
assert(fenv->act_fmap().find(x.vtag()) != fenv->act_fmap().end());
- fenv = &fenv->act_fmap()[x.vtag()];
+ fenv = &fenv->fmap.act()[x.vtag()];
if (!fenv->local) break;
// fenv now points to the environment of the (local) function
assert(fenv != this && fenv->tag == x.vtag());
@@ -2190,7 +2188,7 @@
if (n == 2 && f.tag() == interp.symtab.catch_sym().f) {
expr h = x.xval1().xval2(), y = x.xval2();
push("catch");
- Env& e = act_fmap()[-x.hash()] = Env(0, 0, y, true, true);
+ Env& e = fmap.act()[-x.hash()] = Env(0, 0, y, true, true);
e.build_map(y); e.promote_map();
pop();
build_map(h);
@@ -2207,14 +2205,14 @@
break;
case EXPR::LAMBDA: {
push("lambda");
- Env& e = act_fmap()[-x.hash()] = Env(0, 1, x.xval2(), true, true);
+ Env& e = fmap.act()[-x.hash()] = Env(0, 1, x.xval2(), true, true);
e.build_map(x.xval2()); e.promote_map();
pop();
break;
}
case EXPR::CASE: {
push("case");
- Env& e = act_fmap()[-x.hash()] = Env(0, 1, x.xval(), true, true);
+ Env& e = fmap.act()[-x.hash()] = Env(0, 1, x.xval(), true, true);
e.build_map(*x.rules()); e.promote_map();
pop();
build_map(x.xval());
@@ -2231,13 +2229,13 @@
for (env::const_iterator p = fe->begin(); p != fe->end(); p++) {
int32_t ftag = p->first;
const env_info& info = p->second;
- act_fmap()[ftag] = Env(ftag, info, false, true);
+ fmap.act()[ftag] = Env(ftag, info, false, true);
}
// Now recursively build the maps for the child environments.
for (env::const_iterator p = fe->begin(); p != fe->end(); p++) {
int32_t ftag = p->first;
const env_info& info = p->second;
- Env& e = act_fmap()[ftag];
+ Env& e = fmap.act()[ftag];
e.build_map(info); e.promote_map();
}
pop();
@@ -2261,7 +2259,7 @@
rulel::const_iterator s = r;
expr y = (++s == end)?x:s->rhs;
push("when");
- Env& e = act_fmap()[-y.hash()] = Env(0, 1, y, true, true);
+ Env& e = fmap.act()[-y.hash()] = Env(0, 1, y, true, true);
e.build_map(x, s, end); e.promote_map();
pop();
build_map(r->rhs);
@@ -2288,9 +2286,9 @@
while (r != info.rules->end()) {
build_map(r->rhs);
if (!r->qual.is_null()) build_map(r->qual);
- r++; fmap_idx++;
+ r++; fmap.next();
}
- fmap_idx = 0;
+ fmap.first();
#if DEBUG>1
if (!local) print_map(std::cerr, this);
#endif
@@ -3120,8 +3118,8 @@
Env& act = act_env();
rulel::const_iterator s = r;
expr y = (++s == end)?x:s->rhs;
- assert(act.act_fmap().find(-y.hash()) != act.act_fmap().end());
- Env& e = act.act_fmap()[-y.hash()];
+ assert(act.fmap.act().find(-y.hash()) != act.fmap.act().end());
+ Env& e = act.fmap.act()[-y.hash()];
push("when", &e);
fun_prolog("anonymous");
BasicBlock *bodybb = BasicBlock::Create("body");
@@ -3548,7 +3546,7 @@
int offs = idx-1;
if (idx == 0) {
// function in current environment ('with'-bound)
- f = &act_env().act_fmap()[tag];
+ f = &act_env().fmap.act()[tag];
} else {
// function in an outer environment, the de Bruijn index idx tells us
// where on the current environment stack it's at
@@ -3556,7 +3554,7 @@
size_t i = idx;
for (; i > 0; e++, i--) assert(e != envstk.end());
// look up the function in the environment
- f = &(*e)->act_fmap()[tag];
+ f = &(*e)->fmap.act()[tag];
}
if (f->n == n) {
// bingo! saturated call
@@ -3694,8 +3692,8 @@
// through pure_catch()
expr h = x.xval1().xval2(), y = x.xval2();
Env& act = act_env();
- assert(act.act_fmap().find(-x.hash()) != act.act_fmap().end());
- Env& e = act.act_fmap()[-x.hash()];
+ assert(act.fmap.act().find(-x.hash()) != act.fmap.act().end());
+ Env& e = act.fmap.act()[-x.hash()];
push("catch", &e);
fun_prolog("anonymous");
e.CreateRet(codegen(y));
@@ -3735,8 +3733,8 @@
// anonymous closure:
case EXPR::LAMBDA: {
Env& act = act_env();
- assert(act.act_fmap().find(-x.hash()) != act.act_fmap().end());
- Env& e = act.act_fmap()[-x.hash()];
+ assert(act.fmap.act().find(-x.hash()) != act.fmap.act().end());
+ Env& e = act.fmap.act()[-x.hash()];
push("lambda", &e);
fun("anonymous", x.pm(), true);
pop(&e);
@@ -3747,8 +3745,8 @@
// case expression: treated like an anonymous closure (see the lambda case
// above) which gets applied to the subject term to be matched
Env& act = act_env();
- assert(act.act_fmap().find(-x.hash()) != act.act_fmap().end());
- Env& e = act.act_fmap()[-x.hash()];
+ assert(act.fmap.act().find(-x.hash()) != act.fmap.act().end());
+ Env& e = act.fmap.act()[-x.hash()];
push("case", &e);
fun("anonymous", x.pm(), true);
pop(&e);
@@ -3774,16 +3772,16 @@
// mutually recursive definitions
for (p = fe->begin(); p != fe->end(); p++) {
int32_t ftag = p->first;
- assert(act.act_fmap().find(ftag) != act.act_fmap().end());
- Env& e = act.act_fmap()[ftag];
+ assert(act.fmap.act().find(ftag) != act.fmap.act().end());
+ Env& e = act.fmap.act()[ftag];
push("with", &e);
- act.act_fmap()[ftag].f = fun_prolog(symtab.sym(ftag).s);
+ act.fmap.act()[ftag].f = fun_prolog(symtab.sym(ftag).s);
pop(&e);
}
for (p = fe->begin(); p != fe->end(); p++) {
int32_t ftag = p->first;
const env_info& info = p->second;
- Env& e = act.act_fmap()[ftag];
+ Env& e = act.fmap.act()[ftag];
push("with", &e);
fun_body(info.m);
pop(&e);
@@ -4078,7 +4076,7 @@
assert(!envstk.empty());
if (idx == 0) {
// function in current environment ('with'-bound)
- Env& f = act_env().act_fmap()[tag];
+ Env& f = act_env().fmap.act()[tag];
return fbox(f, thunked);
}
// If we come here, the function is defined in an outer environment. Locate
@@ -4088,7 +4086,7 @@
size_t i = idx;
for (; i > 0; e++, i--) assert(e != envstk.end());
// look up the function in the environment
- Env& f = (*e)->act_fmap()[tag];
+ Env& f = (*e)->fmap.act()[tag];
assert(f.f);
// Now create the closure. This is essentially just like fbox(), but we are
// called inside a nested environment here, and hence the de Bruijn indices
@@ -5062,7 +5060,7 @@
while (r != rl.end()) {
const rule& rr = rules[*r];
reduced.insert(*r);
- if (f.fmap.size() > 1) f.fmap_idx = *r;
+ if (f.fmap.size() > 1) f.fmap.set(*r);
f.f->getBasicBlockList().push_back(rulebb);
f.builder.SetInsertPoint(rulebb);
#if DEBUG>1
@@ -5120,5 +5118,5 @@
toplevel_codegen(rr.rhs);
rulebb = nextbb;
}
- if (f.fmap.size() > 1) f.fmap_idx = 0;
+ if (f.fmap.size() > 1) f.fmap.first();
}
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-07-31 12:16:17 UTC (rev 442)
+++ pure/trunk/interpreter.hh 2008-08-02 07:07:44 UTC (rev 443)
@@ -88,6 +88,33 @@
typedef list<Env*> EnvStack;
typedef pair<int32_t,uint8_t> xmap_key;
+class FMap {
+ // manage local function environments
+ vector< map<int32_t,Env> > fmap;
+ // current map index
+ size_t idx;
+public:
+ // constructor (create one empty map by default)
+ FMap() : fmap(1), idx(0) {}
+ // assignment
+ FMap& operator= (const FMap& f)
+ { fmap = f.fmap; idx = f.idx; return *this; }
+ // clear local environments
+ void clear() { fmap.clear(); idx = 0; }
+ // resize (set number of maps)
+ void resize(size_t n) { fmap.resize(n); }
+ // current size (number of maps)
+ size_t size() const { return fmap.size(); }
+ // set index to first, next and given map
+ void first() { idx = 0; }
+ void next() { idx++; }
+ void set(size_t n) { idx = n; }
+ // access the current map
+ map<int32_t,Env>& act() { return fmap[idx]; }
+ // access the given map (read-only)
+ const map<int32_t,Env>& act(size_t n) const { return fmap[n]; }
+};
+
struct Env {
// function environment
int32_t tag; // function id, zero for anonymous functions
@@ -106,14 +133,8 @@
map<xmap_key,uint32_t > xmap;
// info about captured variables
list<VarInfo> xtab;
- // local function environments; note that there's actually a separate child
- // environment for each rule of the parent function (this gets initialized
- // to a single empty environment)
- vector< map<int32_t,Env> > fmap;
- // the current fmap index; this gets updated each time a new rule is added
- size_t fmap_idx;
- // convenience function to access the current fmap
- map<int32_t,Env>& act_fmap() { return fmap[fmap_idx]; }
+ // local function environments
+ FMap fmap;
// propagation links for environment variables (pointers to call sites)
// e in prop means that there's a call with de Bruijn index prop[e] at e
map<Env*,uint8_t> prop;
@@ -162,11 +183,11 @@
// default constructor
Env()
: tag(0), n(0), m(0), f(0), h(0), fp(0), args(0), envs(0),
- fmap(1), fmap_idx(0), b(false), local(false), parent(0), refc(0) {}
+ b(false), local(false), parent(0), refc(0) {}
// environment for an anonymous closure with given body x
Env(int32_t _tag, uint32_t _n, expr x, bool _b, bool _local = false)
: tag(_tag), n(_n), m(0), f(0), h(0), fp(0), args(n), envs(0),
- fmap(1), fmap_idx(0), b(_b), local(_local), parent(0), refc(0)
+ b(_b), local(_local), parent(0), refc(0)
{
if (envstk.empty()) {
assert(!local);
@@ -180,7 +201,7 @@
// environment for a named closure with given definition info
Env(int32_t _tag, const env_info& info, bool _b, bool _local = false)
: tag(_tag), n(info.argc), m(0), f(0), h(0), fp(0), args(n), envs(0),
- fmap(1), fmap_idx(0), b(_b), local(_local), parent(0), refc(0)
+ b(_b), local(_local), parent(0), refc(0)
{
if (envstk.empty()) {
assert(!local);
Modified: pure/trunk/lexer.ll
===================================================================
--- pure/trunk/lexer.ll 2008-07-31 12:16:17 UTC (rev 442)
+++ pure/trunk/lexer.ll 2008-08-02 07:07:44 UTC (rev 443)
@@ -942,8 +942,8 @@
if (e.h && e.h != e.f) e.h->print(os);
e.f->print(os);
for (size_t i = 0, n = e.fmap.size(); i < n; i++) {
- map<int32_t,Env>::const_iterator f;
- for (f = e.fmap[i].begin(); f != e.fmap[i].end(); f++)
+ for (map<int32_t,Env>::const_iterator f = e.fmap.act(i).begin(),
+ end = e.fmap.act(i).end(); f != end; f++)
print_defs(os, f->second);
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|