mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Issue #897 ... fixed leaking direct-call-plucked comprehension variables, due to shared scope.
This commit is contained in:
parent
c0bbc609be
commit
2decb30d4e
6 changed files with 41 additions and 23 deletions
|
@ -56,7 +56,7 @@
|
||||||
return compileScripts();
|
return compileScripts();
|
||||||
};
|
};
|
||||||
compileScripts = function() {
|
compileScripts = function() {
|
||||||
var base, compile, _fn, _i, _len, _results;
|
var base, compile, source, _fn, _i, _len, _results;
|
||||||
_fn = function(source) {
|
_fn = function(source) {
|
||||||
base = path.join(source);
|
base = path.join(source);
|
||||||
compile = function(source, topLevel) {
|
compile = function(source, topLevel) {
|
||||||
|
|
11
lib/nodes.js
11
lib/nodes.js
|
@ -1204,9 +1204,12 @@
|
||||||
return !!this.ctor;
|
return !!this.ctor;
|
||||||
};
|
};
|
||||||
Code.prototype.compileNode = function(o) {
|
Code.prototype.compileNode = function(o) {
|
||||||
var code, exprs, i, idt, lit, p, param, ref, scope, sharedScope, splats, v, val, vars, wasEmpty, _i, _j, _k, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4, _results;
|
var code, exprs, i, idt, lit, p, param, ref, sharedScope, splats, v, val, vars, wasEmpty, _i, _j, _k, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4, _results;
|
||||||
sharedScope = del(o, 'sharedScope');
|
sharedScope = del(o, 'sharedScope');
|
||||||
o.scope = scope = sharedScope || new Scope(o.scope, this.body, this);
|
o.scope = sharedScope || new Scope(o.scope, this.body, this);
|
||||||
|
if (sharedScope) {
|
||||||
|
o.scope.shared = true;
|
||||||
|
}
|
||||||
o.indent += TAB;
|
o.indent += TAB;
|
||||||
delete o.bare;
|
delete o.bare;
|
||||||
delete o.globals;
|
delete o.globals;
|
||||||
|
@ -1259,7 +1262,7 @@
|
||||||
if (!splats) {
|
if (!splats) {
|
||||||
for (i = 0, _len4 = vars.length; i < _len4; i++) {
|
for (i = 0, _len4 = vars.length; i < _len4; i++) {
|
||||||
v = vars[i];
|
v = vars[i];
|
||||||
scope.parameter(vars[i] = v.compile(o));
|
o.scope.parameter(vars[i] = v.compile(o));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(wasEmpty || this.noReturn)) {
|
if (!(wasEmpty || this.noReturn)) {
|
||||||
|
@ -1769,7 +1772,6 @@
|
||||||
scope = o.scope;
|
scope = o.scope;
|
||||||
name = this.name && this.name.compile(o, LEVEL_LIST);
|
name = this.name && this.name.compile(o, LEVEL_LIST);
|
||||||
index = this.index && this.index.compile(o, LEVEL_LIST);
|
index = this.index && this.index.compile(o, LEVEL_LIST);
|
||||||
if (!hasCode) {
|
|
||||||
if (name && !this.pattern) {
|
if (name && !this.pattern) {
|
||||||
scope.find(name, {
|
scope.find(name, {
|
||||||
immediate: true
|
immediate: true
|
||||||
|
@ -1780,7 +1782,6 @@
|
||||||
immediate: true
|
immediate: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (this.returns && !hasPure) {
|
if (this.returns && !hasPure) {
|
||||||
rvar = scope.freeVariable('results');
|
rvar = scope.freeVariable('results');
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,9 @@
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
Scope.prototype.parameter = function(name) {
|
Scope.prototype.parameter = function(name) {
|
||||||
|
if (this.shared && this.check(name, true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
return this.add(name, 'param');
|
return this.add(name, 'param');
|
||||||
};
|
};
|
||||||
Scope.prototype.check = function(name, immediate) {
|
Scope.prototype.check = function(name, immediate) {
|
||||||
|
|
|
@ -983,7 +983,8 @@ exports.Code = class Code extends Base
|
||||||
# a closure.
|
# a closure.
|
||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
sharedScope = del o, 'sharedScope'
|
sharedScope = del o, 'sharedScope'
|
||||||
o.scope = scope = sharedScope or new Scope o.scope, @body, this
|
o.scope = sharedScope or new Scope o.scope, @body, this
|
||||||
|
o.scope.shared = yes if sharedScope
|
||||||
o.indent += TAB
|
o.indent += TAB
|
||||||
delete o.bare
|
delete o.bare
|
||||||
delete o.globals
|
delete o.globals
|
||||||
|
@ -1008,7 +1009,7 @@ exports.Code = class Code extends Base
|
||||||
wasEmpty = @body.isEmpty()
|
wasEmpty = @body.isEmpty()
|
||||||
exprs.unshift splats if splats
|
exprs.unshift splats if splats
|
||||||
@body.expressions.unshift exprs... if exprs.length
|
@body.expressions.unshift exprs... if exprs.length
|
||||||
scope.parameter vars[i] = v.compile o for v, i in vars unless splats
|
o.scope.parameter vars[i] = v.compile o for v, i in vars unless splats
|
||||||
@body.makeReturn() unless wasEmpty or @noReturn
|
@body.makeReturn() unless wasEmpty or @noReturn
|
||||||
idt = o.indent
|
idt = o.indent
|
||||||
code = 'function'
|
code = 'function'
|
||||||
|
@ -1425,7 +1426,6 @@ exports.For = class For extends Base
|
||||||
scope = o.scope
|
scope = o.scope
|
||||||
name = @name and @name.compile o, LEVEL_LIST
|
name = @name and @name.compile o, LEVEL_LIST
|
||||||
index = @index and @index.compile o, LEVEL_LIST
|
index = @index and @index.compile o, LEVEL_LIST
|
||||||
unless hasCode
|
|
||||||
scope.find(name, immediate: yes) if name and not @pattern
|
scope.find(name, immediate: yes) if name and not @pattern
|
||||||
scope.find(index, immediate: yes) if index
|
scope.find(index, immediate: yes) if index
|
||||||
rvar = scope.freeVariable 'results' if @returns and not hasPure
|
rvar = scope.freeVariable 'results' if @returns and not hasPure
|
||||||
|
|
|
@ -44,6 +44,7 @@ exports.Scope = class Scope
|
||||||
# Reserve a variable name as originating from a function parameter for this
|
# Reserve a variable name as originating from a function parameter for this
|
||||||
# scope. No `var` required for internal references.
|
# scope. No `var` required for internal references.
|
||||||
parameter: (name) ->
|
parameter: (name) ->
|
||||||
|
return if @shared and @check name, yes
|
||||||
@add name, 'param'
|
@add name, 'param'
|
||||||
|
|
||||||
# Just check to see if a variable has already been declared, without reserving,
|
# Just check to see if a variable has already been declared, without reserving,
|
||||||
|
|
|
@ -228,3 +228,16 @@ foo = ->
|
||||||
-> i + j
|
-> i + j
|
||||||
|
|
||||||
eq foo()[3][4](), 7
|
eq foo()[3][4](), 7
|
||||||
|
|
||||||
|
|
||||||
|
# Issue #897: Ensure that plucked function variables aren't leaked.
|
||||||
|
facets = {}
|
||||||
|
list = ['one', 'two']
|
||||||
|
|
||||||
|
(->
|
||||||
|
for entity in list
|
||||||
|
facets[entity] = -> entity
|
||||||
|
)()
|
||||||
|
|
||||||
|
eq typeof entity, 'undefined'
|
||||||
|
eq facets['two'](), 'two'
|
||||||
|
|
Loading…
Add table
Reference in a new issue