summaryrefslogtreecommitdiffstats
path: root/lib/handlebars/compiler/javascript-compiler.js
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2014-01-01 18:59:21 -0600
committerkpdecker <kpdecker@gmail.com>2014-01-01 18:59:21 -0600
commit3c85720137c039cefc38046541f05731d151a506 (patch)
tree997f9d2330e90920f8c7978a98e5016f291efc44 /lib/handlebars/compiler/javascript-compiler.js
parent4713abc8f1cbb3910cac878bbea1e14e329f6110 (diff)
downloadhandlebars.js-3c85720137c039cefc38046541f05731d151a506.zip
handlebars.js-3c85720137c039cefc38046541f05731d151a506.tar.gz
handlebars.js-3c85720137c039cefc38046541f05731d151a506.tar.bz2
Remove duplication from generated subexpressions
Diffstat (limited to 'lib/handlebars/compiler/javascript-compiler.js')
-rw-r--r--lib/handlebars/compiler/javascript-compiler.js50
1 files changed, 38 insertions, 12 deletions
diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js
index dc77ef6..cd75af9 100644
--- a/lib/handlebars/compiler/javascript-compiler.js
+++ b/lib/handlebars/compiler/javascript-compiler.js
@@ -496,18 +496,31 @@ JavaScriptCompiler.prototype = {
// and pushes the helper's return value onto the stack.
//
// If the helper is not found, `helperMissing` is called.
- invokeHelper: function(paramSize, name) {
+ invokeHelper: function(paramSize, name, isRoot) {
this.context.aliases.helperMissing = 'helpers.helperMissing';
+ this.useRegister('helper');
var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
- this.push(helper.name + ' || ' + nonHelper);
- this.replaceStack(function(name) {
- return name + ' ? '
- + name + '.call(' + helper.callParams + ") "
- + " : helperMissing.call(" + helper.helperMissingParams + ")";
- });
+ var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
+ if (helper.paramsInit) {
+ lookup += ',' + helper.paramsInit;
+ }
+
+ this.push(
+ '('
+ + lookup
+ + ',helper '
+ + '? helper.call(' + helper.callParams + ') '
+ + ': helperMissing.call(' + helper.helperMissingParams + '))');
+
+ // Always flush subexpressions. This is both to prevent the compounding size issue that
+ // occurs when the code has to be duplicated for inlining and also to prevent errors
+ // due to the incorrect options object being passed due to the shared register.
+ if (!isRoot) {
+ this.flushInline();
+ }
},
// [invokeKnownHelper]
@@ -536,6 +549,7 @@ JavaScriptCompiler.prototype = {
// `knownHelpersOnly` flags at compile-time.
invokeAmbiguous: function(name, helperCall) {
this.context.aliases.functionType = '"function"';
+ this.useRegister('helper');
this.emptyHash();
var helper = this.setupHelper(0, name, helperCall);
@@ -545,8 +559,11 @@ JavaScriptCompiler.prototype = {
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
var nextStack = this.nextStack();
- this.pushSource('if (' + nextStack + ' = ' + helperName + ') { ' + nextStack + ' = ' + nextStack + '.call(' + helper.callParams + '); }');
- this.pushSource('else { ' + nextStack + ' = ' + nonHelper + '; ' + nextStack + ' = typeof ' + nextStack + ' === functionType ? ' + nextStack + '.call(' + helper.callParams + ') : ' + nextStack + '; }');
+ if (helper.paramsInit) {
+ this.pushSource(helper.paramsInit);
+ }
+ this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
+ this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
},
// [invokePartial]
@@ -807,12 +824,13 @@ JavaScriptCompiler.prototype = {
},
setupHelper: function(paramSize, name, missingParams) {
- var params = [];
- this.setupParams(paramSize, params, missingParams);
+ var params = [],
+ paramsInit = this.setupParams(paramSize, params, missingParams);
var foundHelper = this.nameLookup('helpers', name, 'helper');
return {
params: params,
+ paramsInit: paramsInit,
name: foundHelper,
callParams: ["depth0"].concat(params).join(", "),
helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
@@ -870,7 +888,15 @@ JavaScriptCompiler.prototype = {
options.push("data:data");
}
- params.push("{" + options.join(",") + "}");
+ options = "{" + options.join(",") + "}";
+ if (useRegister) {
+ this.useRegister('options');
+ params.push('options');
+ return 'options=' + options;
+ } else {
+ params.push(options);
+ return '';
+ }
}
};