mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-05-03 03:00:14 -04:00
satyr 4e39e2e -- efficient closures in loops -- pulling them out.
This commit is contained in:
37
lib/nodes.js
37
lib/nodes.js
@@ -1600,6 +1600,9 @@
|
||||
if (namePart) {
|
||||
varPart = idt + namePart + ';\n';
|
||||
}
|
||||
if (!this.pattern) {
|
||||
defPart += this.pluckDirectCall(o, body, name, index);
|
||||
}
|
||||
code = guardPart + varPart;
|
||||
if (!body.isEmpty()) {
|
||||
if (o.level > LEVEL_TOP || this.returns) {
|
||||
@@ -1619,6 +1622,40 @@
|
||||
}
|
||||
return defPart + this.tab + ("for (" + forPart + ") {" + code + "}") + retPart;
|
||||
};
|
||||
For.prototype.pluckDirectCall = function(o, body, name, index) {
|
||||
var arg, args, base, defs, expr, fn, i, idx, ref, val, _len, _len2, _ref, _ref2, _ref3;
|
||||
defs = '';
|
||||
_ref = body.expressions;
|
||||
for (idx = 0, _len = _ref.length; idx < _len; idx++) {
|
||||
expr = _ref[idx];
|
||||
expr = expr.unwrapAll();
|
||||
if (!(expr instanceof Call)) {
|
||||
continue;
|
||||
}
|
||||
val = expr.variable.unwrapAll();
|
||||
if (!(val instanceof Code && !expr.args.length || val instanceof Value && val.base instanceof Code && val.properties.length === 1 && ((_ref2 = val.properties[0].name) != null ? _ref2.value : void 0) === 'call')) {
|
||||
continue;
|
||||
}
|
||||
fn = val.base || val;
|
||||
ref = new Literal(o.scope.freeVariable('fn'));
|
||||
base = new Value(ref);
|
||||
args = compact([name, index]);
|
||||
if (this.object) {
|
||||
args.reverse();
|
||||
}
|
||||
for (i = 0, _len2 = args.length; i < _len2; i++) {
|
||||
arg = args[i];
|
||||
fn.params.push(new Param(args[i] = new Literal(arg)));
|
||||
}
|
||||
if (val.base) {
|
||||
_ref3 = [base, val], val.base = _ref3[0], base = _ref3[1];
|
||||
args.unshift(new Literal('this'));
|
||||
}
|
||||
body.expressions[idx] = new Call(base, args);
|
||||
defs += this.tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n';
|
||||
}
|
||||
return defs;
|
||||
};
|
||||
return For;
|
||||
})();
|
||||
exports.Switch = (function() {
|
||||
|
||||
@@ -1335,6 +1335,7 @@ exports.For = class For extends Base
|
||||
when -1 then '--'
|
||||
else (if pvar < 0 then ' -= ' + pvar.slice 1 else ' += ' + pvar)
|
||||
varPart = idt + namePart + ';\n' if namePart
|
||||
defPart += @pluckDirectCall o, body, name, index unless @pattern
|
||||
code = guardPart + varPart
|
||||
unless body.isEmpty()
|
||||
if o.level > LEVEL_TOP or @returns
|
||||
@@ -1348,6 +1349,30 @@ exports.For = class For extends Base
|
||||
code = '\n' + code + '\n' + @tab if code
|
||||
defPart + @tab + "for (#{forPart}) {#{code}}" + retPart
|
||||
|
||||
pluckDirectCall: (o, body, name, index) ->
|
||||
defs = ''
|
||||
for expr, idx in body.expressions
|
||||
expr = expr.unwrapAll()
|
||||
continue unless expr instanceof Call
|
||||
val = expr.variable.unwrapAll()
|
||||
continue unless val instanceof Code and not expr.args.length or
|
||||
val instanceof Value and val.base instanceof Code and
|
||||
val.properties.length is 1 and
|
||||
val.properties[0].name?.value is 'call'
|
||||
fn = val.base or val
|
||||
ref = new Literal o.scope.freeVariable 'fn'
|
||||
base = new Value ref
|
||||
args = compact [name, index]
|
||||
args.reverse() if @object
|
||||
for arg, i in args
|
||||
fn.params.push new Param args[i] = new Literal arg
|
||||
if val.base
|
||||
[val.base, base] = [base, val]
|
||||
args.unshift new Literal 'this'
|
||||
body.expressions[idx] = new Call base, args
|
||||
defs += @tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n'
|
||||
defs
|
||||
|
||||
#### Switch
|
||||
|
||||
# A JavaScript *switch* statement. Converts into a returnable expression on-demand.
|
||||
|
||||
Reference in New Issue
Block a user