summaryrefslogtreecommitdiffstats
path: root/lib/handlebars/compiler/compiler.js
diff options
context:
space:
mode:
authorkpdecker <kpdecker@gmail.com>2013-01-21 00:26:08 -0600
committerkpdecker <kpdecker@gmail.com>2013-01-21 00:49:28 -0600
commitb66197796615f49f3009800b401df2597f118e58 (patch)
treee7bbcf7358425cc6d4b0767ac61ad821a8db7be9 /lib/handlebars/compiler/compiler.js
parent969b418291af1fa4f32820ee0d36ab00b4b55db1 (diff)
downloadhandlebars.js-b66197796615f49f3009800b401df2597f118e58.zip
handlebars.js-b66197796615f49f3009800b401df2597f118e58.tar.gz
handlebars.js-b66197796615f49f3009800b401df2597f118e58.tar.bz2
Merge duplicate programs
Diffstat (limited to 'lib/handlebars/compiler/compiler.js')
-rw-r--r--lib/handlebars/compiler/compiler.js49
1 files changed, 43 insertions, 6 deletions
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js
index d4b7d0f..7541051 100644
--- a/lib/handlebars/compiler/compiler.js
+++ b/lib/handlebars/compiler/compiler.js
@@ -38,6 +38,26 @@ Handlebars.JavaScriptCompiler = function() {};
return out.join("\n");
},
+ equals: function(other) {
+ var len = this.opcodes.length;
+ if (other.opcodes.length !== len) {
+ return false;
+ }
+
+ for (var i = 0; i < len; i++) {
+ var opcode = this.opcodes[i],
+ otherOpcode = other.opcodes[i];
+ if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
+ return false;
+ }
+ for (var j = 0; j < opcode.args.length; j++) {
+ if (opcode.args[j] !== otherOpcode.args[j]) {
+ return false;
+ }
+ }
+ }
+ return true;
+ },
guid: 0,
@@ -417,6 +437,7 @@ Handlebars.JavaScriptCompiler = function() {};
this.isChild = !!context;
this.context = context || {
programs: [],
+ environments: [],
aliases: { }
};
@@ -452,7 +473,7 @@ Handlebars.JavaScriptCompiler = function() {};
return opcodes[this.i + 1];
},
- eat: function(opcode) {
+ eat: function() {
this.i = this.i + 1;
},
@@ -905,11 +926,27 @@ Handlebars.JavaScriptCompiler = function() {};
child = children[i];
compiler = new this.compiler();
- this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
- var index = this.context.programs.length;
- child.index = index;
- child.name = 'program' + index;
- this.context.programs[index] = compiler.compile(child, options, this.context);
+ var index = this.matchExistingProgram(child);
+
+ if (index == null) {
+ this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
+ index = this.context.programs.length;
+ child.index = index;
+ child.name = 'program' + index;
+ this.context.programs[index] = compiler.compile(child, options, this.context);
+ this.context.environments[index] = child;
+ } else {
+ child.index = index;
+ child.name = 'program' + index;
+ }
+ }
+ },
+ matchExistingProgram: function(child) {
+ for (var i = 0, len = this.context.environments.length; i < len; i++) {
+ var environment = this.context.environments[i];
+ if (environment && environment.equals(child)) {
+ return i;
+ }
}
},