summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2014-08-13 14:11:53 -0500
committerkpdecker <kpdecker@gmail.com>2014-08-13 14:11:53 -0500
commitb695aaec7c493ae992bfc1560e5153a9eddaa385 (patch)
tree0e45904fd54a0e8781df6c730d8df23d6602cb00
parentf6dc5ad7163b8b7c51d9816afa39741f47313602 (diff)
downloadhandlebars.js-b695aaec7c493ae992bfc1560e5153a9eddaa385.zip
handlebars.js-b695aaec7c493ae992bfc1560e5153a9eddaa385.tar.gz
handlebars.js-b695aaec7c493ae992bfc1560e5153a9eddaa385.tar.bz2
Use depths array rather than passing array args
Approximately doubles the throughput performance of depthed templates and clears the way for doing recursive path lookups in pathed mode.
-rw-r--r--lib/handlebars/compiler/javascript-compiler.js29
-rw-r--r--lib/handlebars/runtime.js40
2 files changed, 36 insertions, 33 deletions
diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js
index 0472dbb..f1b6d36 100644
--- a/lib/handlebars/compiler/javascript-compiler.js
+++ b/lib/handlebars/compiler/javascript-compiler.js
@@ -69,6 +69,8 @@ JavaScriptCompiler.prototype = {
this.compileChildren(environment, options);
+ this.useDepths = this.useDepths || environment.depths.list.length;
+
var opcodes = environment.opcodes,
opcode,
i,
@@ -115,6 +117,9 @@ JavaScriptCompiler.prototype = {
if (this.options.data) {
ret.useData = true;
}
+ if (this.useDepths) {
+ ret.depths = true;
+ }
if (!asObject) {
ret.compiler = JSON.stringify(ret.compiler);
@@ -151,8 +156,8 @@ JavaScriptCompiler.prototype = {
var params = ["depth0", "helpers", "partials", "data"];
- for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
- params.push("depth" + this.environment.depths.list[i]);
+ if (this.useDepths) {
+ params.push('depths');
}
// Perform a second pass over the output to merge content when possible
@@ -668,6 +673,8 @@ JavaScriptCompiler.prototype = {
child.name = 'program' + index;
this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);
this.context.environments[index] = child;
+
+ this.useDepths = this.useDepths || compiler.useDepths;
} else {
child.index = index;
child.name = 'program' + index;
@@ -689,17 +696,17 @@ JavaScriptCompiler.prototype = {
}
var child = this.environment.children[guid],
- depths = child.depths.list, depth;
+ depths = child.depths.list,
+ useDepths = this.useDepths,
+ depth;
var programParams = [child.index, 'data'];
- for(var i=0, l = depths.length; i<l; i++) {
- depth = depths[i];
-
- programParams.push('depth' + (depth - 1));
+ if (useDepths) {
+ programParams.push('depths');
}
- return (depths.length === 0 ? 'this.program(' : 'this.programWithDepth(') + programParams.join(', ') + ')';
+ return 'this.program(' + programParams.join(', ') + ')';
},
useRegister: function(name) {
@@ -847,7 +854,11 @@ JavaScriptCompiler.prototype = {
},
contextName: function(context) {
- return 'depth' + context;
+ if (this.useDepths && context) {
+ return 'depths[' + context + ']';
+ } else {
+ return 'depth' + context;
+ }
},
quotedString: function(str) {
diff --git a/lib/handlebars/runtime.js b/lib/handlebars/runtime.js
index 9b61afe..cbd5398 100644
--- a/lib/handlebars/runtime.js
+++ b/lib/handlebars/runtime.js
@@ -75,17 +75,16 @@ export function template(templateSpec, env) {
},
programs: [],
- program: function(i, data) {
+ program: function(i, data, depths) {
var programWrapper = this.programs[i],
fn = this.fn(i);
- if(data) {
- programWrapper = program(this, i, fn, data);
+ if (data || depths) {
+ programWrapper = program(this, i, fn, data, depths);
} else if (!programWrapper) {
programWrapper = this.programs[i] = program(this, i, fn);
}
return programWrapper;
},
- programWithDepth: env.VM.programWithDepth,
data: function(data, depth) {
while (data && depth--) {
@@ -117,7 +116,12 @@ export function template(templateSpec, env) {
if (!options.partial && templateSpec.useData) {
data = initData(context, data);
}
- return templateSpec.main.call(container, context, container.helpers, container.partials, data);
+ var depths;
+ if (templateSpec.depths) {
+ depths = [context];
+ }
+
+ return templateSpec.main.call(container, context, container.helpers, container.partials, data, depths);
};
ret._setup = function(options) {
@@ -134,35 +138,23 @@ export function template(templateSpec, env) {
};
ret._child = function(i) {
+ if (templateSpec.depth) {
+ throw new Exception('_child can not be used with depthed methods');
+ }
+
return container.programWithDepth(i);
};
return ret;
}
-export function programWithDepth(i, data /*, $depth */) {
- /*jshint -W040 */
- var args = Array.prototype.slice.call(arguments, 2),
- container = this,
- fn = container.fn(i);
-
- var prog = function(context, options) {
- options = options || {};
-
- return fn.apply(container, [context, container.helpers, container.partials, options.data || data].concat(args));
- };
- prog.program = i;
- prog.depth = args.length;
- return prog;
-}
-
-export function program(container, i, fn, data) {
+export function program(container, i, fn, data, depths) {
var prog = function(context, options) {
options = options || {};
- return fn.call(container, context, container.helpers, container.partials, options.data || data);
+ return fn.call(container, context, container.helpers, container.partials, options.data || data, [context].concat(depths));
};
prog.program = i;
- prog.depth = 0;
+ prog.depth = depths ? depths.length : 0;
return prog;
}