Do not copy variables for target specific variables
167.22user 131.10system 5:27.42elapsed 91%CPU (1355792maxresident)k =>
91.34user 122.72system 3:52.62elapsed 92%CPU (1180900maxresident)k
repo/android.sh time kati --kati_cpuprofile=kati.prof -n
diff --git a/exec.go b/exec.go
index 977cbaa..25c1559 100644
--- a/exec.go
+++ b/exec.go
@@ -245,9 +245,18 @@
}
return outputTs, fmt.Errorf("no rule to make target %q", output)
}
+
+ var olds []oldVar
if rule.vars != nil {
- vars = NewVars(vars)
- vars.Merge(rule.vars)
+ for k, v := range rule.vars {
+ olds = append(olds, newOldVar(vars, k))
+ vars[k] = v
+ }
+ defer func() {
+ for _, old := range olds {
+ old.restore(vars)
+ }
+ }()
}
latest := int64(-1)
diff --git a/func.go b/func.go
index 44dfa13..333ac92 100644
--- a/func.go
+++ b/func.go
@@ -12,27 +12,6 @@
"strings"
)
-// TODO(ukai): move in var.go?
-type oldVar struct {
- name string
- value Var
-}
-
-func newOldVar(ev *Evaluator, name string) oldVar {
- return oldVar{
- name: name,
- value: ev.outVars.Lookup(name),
- }
-}
-
-func (old oldVar) restore(ev *Evaluator) {
- if old.value.IsDefined() {
- ev.outVars.Assign(old.name, old.value)
- return
- }
- delete(ev.outVars, old.name)
-}
-
// Func is a make function.
// http://www.gnu.org/software/make/manual/make.html#Functions
@@ -585,7 +564,7 @@
var olds []oldVar
for i, arg := range args {
name := fmt.Sprintf("%d", i+1)
- olds = append(olds, newOldVar(ev, name))
+ olds = append(olds, newOldVar(ev.outVars, name))
ev.outVars.Assign(name,
SimpleVar{
value: arg,
@@ -596,7 +575,7 @@
var buf bytes.Buffer
v.Eval(&buf, ev)
for _, old := range olds {
- old.restore(ev)
+ old.restore(ev.outVars)
}
Log("call %q return %q", f.args[0], buf.Bytes())
w.Write(buf.Bytes())
@@ -690,7 +669,7 @@
varname := string(ev.Value(f.args[0]))
list := ev.Values(f.args[1])
text := f.args[2]
- old := newOldVar(ev, varname)
+ old := newOldVar(ev.outVars, varname)
space := false
for _, word := range list {
ev.outVars.Assign(varname,
@@ -704,5 +683,5 @@
w.Write(ev.Value(text))
space = true
}
- old.restore(ev)
+ old.restore(ev.outVars)
}
diff --git a/var.go b/var.go
index 72bb86a..d246b58 100644
--- a/var.go
+++ b/var.go
@@ -112,3 +112,23 @@
vt[k] = v
}
}
+
+type oldVar struct {
+ name string
+ value Var
+}
+
+func newOldVar(vars Vars, name string) oldVar {
+ return oldVar{
+ name: name,
+ value: vars.Lookup(name),
+ }
+}
+
+func (old oldVar) restore(vars Vars) {
+ if old.value.IsDefined() {
+ vars[old.name] = old.value
+ return
+ }
+ delete(vars, old.name)
+}