Avoid eval when running in VM+Compiler mode

This commit is contained in:
kpdecker
2011-07-30 16:55:26 -05:00
parent f8edc59025
commit 993c793565
2 changed files with 39 additions and 22 deletions
+29 -21
View File
@@ -315,7 +315,7 @@ Handlebars.JavaScriptCompiler = function() {};
},
// END PUBLIC API
compile: function(environment, options) {
compile: function(environment, options, asObject) {
this.environment = environment;
this.options = options || {};
@@ -325,9 +325,7 @@ Handlebars.JavaScriptCompiler = function() {};
this.stackVars = [];
this.registers = {list: []};
this.compileChildren(environment, options);
Handlebars.log(Handlebars.logger.DEBUG, environment.disassemble() + "\n\n");
this.compileChildren(environment, options, asObject);
var opcodes = environment.opcodes, opcode, name, declareName, declareVal;
@@ -345,7 +343,7 @@ Handlebars.JavaScriptCompiler = function() {};
}
}
return this.createFunctionContext();
return this.createFunctionContext(asObject);
},
nextOpcode: function(n) {
@@ -388,7 +386,7 @@ Handlebars.JavaScriptCompiler = function() {};
this.source = out;
},
createFunctionContext: function() {
createFunctionContext: function(asObject) {
var locals = this.stackVars.concat(this.registers.list);
if(locals.length > 0) {
@@ -409,19 +407,28 @@ Handlebars.JavaScriptCompiler = function() {};
if(params.length === 4 && !this.environment.usePartial) { params.pop(); }
var functionSource = 'function(' + params.join(',') + ') {\n ' + this.source.join("\n ") + '}';
if (asObject) {
params.push(this.source.join("\n "));
Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
return {
fn: Function.apply(this, params),
children: this.environment.children
};
} else {
var functionSource = 'function(' + params.join(',') + ') {\n ' + this.source.join("\n ") + '}';
var script = ['{\n fn: ', functionSource, ',\n children: [\n '],
children = this.environment.children;
for (var i = 0, len = children.length; i < len; i++) {
script.push(children[i]);
if (i < len-1) { script.push(',\n'); }
Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
var script = ['{\n fn: ', functionSource, ',\n children: [\n '],
children = this.environment.children;
for (var i = 0, len = children.length; i < len; i++) {
script.push(children[i]);
if (i < len-1) { script.push(',\n'); }
}
script.push('\n ]\n}');
return script.join('');
}
script.push('\n ]\n}');
return script.join('');
},
appendContent: function(content) {
@@ -574,7 +581,7 @@ Handlebars.JavaScriptCompiler = function() {};
compiler: JavaScriptCompiler,
compileChildren: function(environment, options) {
compileChildren: function(environment, options, asObject) {
var children = environment.children, child, compiler;
var compiled = [];
@@ -582,7 +589,7 @@ Handlebars.JavaScriptCompiler = function() {};
child = children[i];
compiler = new this.compiler();
compiled[i] = compiler.compile(child, options);
compiled[i] = compiler.compile(child, options, asObject);
}
environment.rawChildren = children;
@@ -679,10 +686,11 @@ Handlebars.precompile = function(string, options) {
return new Handlebars.JavaScriptCompiler().compile(environment, options);
};
// TODO : Testing
// TODO : Do this without the eval requirement
Handlebars.compile = function(string, options) {
return Handlebars.template(eval('(' + Handlebars.precompile(string, options) + ')'));
var ast = Handlebars.parse(string);
var environment = new Handlebars.Compiler().compile(ast, options);
var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, true);
return Handlebars.template(templateSpec);
};
// END(BROWSER)