From 704961b37840a439d6576a0d8f0f595838ab0963 Mon Sep 17 00:00:00 2001 From: kpdecker Date: Sun, 6 Jul 2014 11:37:24 -0500 Subject: [PATCH 1/3] Add additional paths to path throughput test --- bench/templates/paths.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bench/templates/paths.js b/bench/templates/paths.js index 0a426dd83..d84e06152 100644 --- a/bench/templates/paths.js +++ b/bench/templates/paths.js @@ -1,7 +1,7 @@ module.exports = { - context: { person: { name: "Larry", age: 45 } }, - handlebars: "{{person.name}}{{person.age}}{{person.foo}}{{animal.age}}", - dust: "{person.name}{person.age}{person.foo}{animal.age}", - eco: "<%= @person.name %><%= @person.age %><%= @person.foo %><% if @animal: %><%= @animal.age %><% end %>", - mustache: "{{person.name}}{{person.age}}{{person.foo}}{{animal.age}}" + context: { person: { name: {bar: {baz: "Larry"}}, age: 45 } }, + handlebars: "{{person.name.bar.baz}}{{person.age}}{{person.foo}}{{animal.age}}", + dust: "{person.name.bar.baz}{person.age}{person.foo}{animal.age}", + eco: "<%= @person.name.bar.baz %><%= @person.age %><%= @person.foo %><% if @animal: %><%= @animal.age %><% end %>", + mustache: "{{person.name.bar.baz}}{{person.age}}{{person.foo}}{{animal.age}}" }; From 4aad72d2230a6eaaf242130c57ad1efa4d701f3c Mon Sep 17 00:00:00 2001 From: kpdecker Date: Sun, 6 Jul 2014 12:53:01 -0500 Subject: [PATCH 2/3] Move lambda resolution to runtime This has a very positive impact on precompiled output size, particularly for known-helpers cases, and little or no impact on the throughput numbers. --- lib/handlebars/compiler/javascript-compiler.js | 6 ++---- lib/handlebars/runtime.js | 4 ++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js index 4b9db9293..4d950d461 100644 --- a/lib/handlebars/compiler/javascript-compiler.js +++ b/lib/handlebars/compiler/javascript-compiler.js @@ -377,11 +377,9 @@ JavaScriptCompiler.prototype = { // If the `value` is a lambda, replace it on the stack by // the return value of the lambda resolvePossibleLambda: function() { - this.aliases.functionType = '"function"'; + this.aliases.lambda = 'this.lambda'; - this.replaceStack(function(current) { - return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current; - }); + this.push('lambda(' + this.popStack() + ', depth0)'); }, // [lookup] diff --git a/lib/handlebars/runtime.js b/lib/handlebars/runtime.js index d43f465e3..b9fc77d7d 100644 --- a/lib/handlebars/runtime.js +++ b/lib/handlebars/runtime.js @@ -50,6 +50,10 @@ export function template(templateSpec, env) { // Just add water var container = { + lambda: function(current, context) { + return typeof current === 'function' ? current.call(context) : current; + }, + escapeExpression: Utils.escapeExpression, invokePartial: invokePartialWrapper, From b5a5c76ceb85fee36340e14b79306a436d32ff72 Mon Sep 17 00:00:00 2001 From: kpdecker Date: Sun, 6 Jul 2014 23:40:46 -0500 Subject: [PATCH 3/3] Rework lookup null protector logic - Move the lookup null protection out of `nameLookup` and into that contexts that are aware of the needs for falsy vs. not displayed values. - Optimize lookup for nested path operations Fixes #731 --- lib/handlebars/compiler/compiler.js | 15 +-- .../compiler/javascript-compiler.js | 116 ++++++++++-------- 2 files changed, 67 insertions(+), 64 deletions(-) diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js index e5f2280ac..31176c9a3 100644 --- a/lib/handlebars/compiler/compiler.js +++ b/lib/handlebars/compiler/compiler.js @@ -275,6 +275,8 @@ Compiler.prototype = { } else if (this.options.knownHelpersOnly) { throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr); } else { + id.falsy = true; + this.ID(id); this.opcode('invokeHelper', params.length, id.original, sexpr.isRoot); } @@ -298,23 +300,16 @@ Compiler.prototype = { var name = id.parts[0]; if (!name) { + // Context reference, i.e. `{{foo .}}` or `{{foo ..}}` this.opcode('pushContext'); } else { - this.opcode('lookupOnContext', id.parts[0]); - } - - for(var i=1, l=id.parts.length; i