From 271106d43fae96fc1287898568d000b871f19084 Mon Sep 17 00:00:00 2001 From: kpdecker Date: Sat, 12 Jul 2014 12:50:54 -0500 Subject: [PATCH] Do not lookup pathed helpers on the helper stack Fixes #764 --- lib/handlebars/compiler/compiler.js | 2 +- lib/handlebars/compiler/javascript-compiler.js | 9 ++++----- spec/helpers.js | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js index fbbb390b5..3e83a62e6 100644 --- a/lib/handlebars/compiler/compiler.js +++ b/lib/handlebars/compiler/compiler.js @@ -280,7 +280,7 @@ Compiler.prototype = { id.falsy = true; this.ID(id); - this.opcode('invokeHelper', params.length, id.original, sexpr.isRoot); + this.opcode('invokeHelper', params.length, id.original, id.isSimple, sexpr.isRoot); } }, diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js index 2d4b11569..c4f3c2758 100644 --- a/lib/handlebars/compiler/javascript-compiler.js +++ b/lib/handlebars/compiler/javascript-compiler.js @@ -369,7 +369,7 @@ JavaScriptCompiler.prototype = { return ' != null ? ' + lookup + ' : ' + current; } else { // Otherwise we can use generic falsy handling - return ' != null && ' + lookup; + return (falsy ? ' && ' : ' != null && ') + lookup; } }, true); } @@ -527,19 +527,18 @@ 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, isRoot) { + invokeHelper: function(paramSize, name, isSimple, isRoot) { this.aliases.helperMissing = 'helpers.helperMissing'; - this.useRegister('helper'); var nonHelper = this.popStack(); var helper = this.setupHelper(paramSize, name); - var lookup = 'helper = ' + helper.name + ' || ' + nonHelper + ' || helperMissing'; + var lookup = (isSimple ? helper.name + ' || ' : '') + nonHelper + ' || helperMissing'; if (helper.paramsInit) { lookup += ',' + helper.paramsInit; } - this.push('(' + lookup + ',helper.call(' + helper.callParams + '))'); + this.push('((' + lookup + ').call(' + helper.callParams + '))'); // 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 diff --git a/spec/helpers.js b/spec/helpers.js index 6ba368e4d..d686b6461 100644 --- a/spec/helpers.js +++ b/spec/helpers.js @@ -158,6 +158,22 @@ describe('helpers', function() { shouldCompileTo(messageString, [rootMessage, { list: list }], "

Nobody's here

", "the context of an inverse is the parent of the block"); }); + it('pathed lambas with parameters', function() { + var hash = { + helper: function() { + return 'winning'; + } + }; + hash.hash = hash; + var helpers = { + './helper': function() { + return 'fail'; + } + }; + shouldCompileTo('{{./helper 1}}', [hash, helpers], 'winning'); + shouldCompileTo('{{hash/helper 1}}', [hash, helpers], 'winning'); + }); + describe("helpers hash", function() { it("providing a helpers hash", function() { shouldCompileTo("Goodbye {{cruel}} {{world}}!", [{cruel: "cruel"}, {world: function() { return "world"; }}], "Goodbye cruel world!",