@@ -176,7 +176,7 @@ private function BlockStatement(BlockStatement $block): string
176176 $ var = "\$in[ $ escapedKey] ?? " . $ this ->missValue ($ literalKey );
177177
178178 if ($ block ->program === null ) {
179- return $ this ->compileInvertedSection ($ block , $ var , null );
179+ return $ this ->compileInvertedSection ($ block , $ var , $ escapedKey );
180180 }
181181
182182 return $ this ->compileSection ($ block , $ var , $ escapedKey );
@@ -227,14 +227,11 @@ private function compileSection(BlockStatement $block, string $var, string $esca
227227
228228 private function compileInvertedSection (BlockStatement $ block , string $ var , ?string $ escapedName ): string
229229 {
230- $ body = $ this -> compileProgramOrEmpty ($ block ->inverse );
230+ assert ($ block ->inverse !== null );
231231
232- if ($ escapedName !== null ) {
233- $ blockFn = self ::blockClosure ($ body , inheritsBp: $ this ->lastCompileProgramHadDirectBpRef );
234- return self ::getRuntimeFunc ('isech ' , "\$cx, $ var, \$in, $ blockFn, $ escapedName " );
235- }
236-
237- return "( " . self ::getRuntimeFunc ('isec ' , $ var ) . " ? $ body : '') " ;
232+ $ blockFn = $ this ->compileProgramWithBlockParams ($ block ->inverse );
233+ $ name = ($ escapedName !== null && !$ this ->context ->options ->knownHelpersOnly ) ? ", $ escapedName " : '' ;
234+ return self ::getRuntimeFunc ('sec ' , "\$cx, $ var, \$in, null, $ blockFn$ name " );
238235 }
239236
240237 /** Returns '$blockParams' when inside a block-param scope (for use() capture), '' otherwise. */
@@ -262,6 +259,8 @@ private function outerBlockParamsExpr(): string
262259
263260 /**
264261 * Compile a block program, pushing/popping its block params around the compilation.
262+ * Returns a PHP closure string: the signature varies based on whether the program declares or
263+ * inherits block params, and a $sc preamble is added when depths are accessed multiple times.
265264 */
266265 private function compileProgramWithBlockParams (Program $ program ): string
267266 {
@@ -273,7 +272,20 @@ private function compileProgramWithBlockParams(Program $program): string
273272 if ($ bp ) {
274273 array_shift ($ this ->blockParamValues );
275274 }
276- return self ::blockClosure ($ body , (bool ) $ bp , $ this ->lastCompileProgramHadDirectBpRef );
275+
276+ $ declaresBp = (bool ) $ bp ;
277+ $ inheritsBp = $ this ->lastCompileProgramHadDirectBpRef ;
278+ $ preamble = '' ;
279+ if (str_contains ($ body , '$cx->depths[count($cx->depths)- ' )) {
280+ $ preamble = '$sc=count($cx->depths); ' ;
281+ $ body = str_replace ('$cx->depths[count($cx->depths)- ' , '$cx->depths[$sc- ' , $ body );
282+ }
283+ $ sig = match (true ) {
284+ $ declaresBp => "function( \$cx, \$in, array \$blockParams = []) " ,
285+ $ inheritsBp => "function( \$cx, \$in) use ( \$blockParams) " ,
286+ default => "function( \$cx, \$in) " ,
287+ };
288+ return "$ sig { {$ preamble }return $ body;} " ;
277289 }
278290
279291 private function compileBlockHelper (BlockStatement $ block , string $ name ): string
@@ -359,7 +371,7 @@ private function compileDynamicBlockHelper(BlockStatement $block, string $name,
359371 $ params = $ this ->compileParams ($ block ->params , $ block ->hash );
360372 $ blockFn = $ block ->program !== null
361373 ? $ this ->compileProgramWithBlockParams ($ block ->program )
362- : self :: blockClosure ( " '' " ) ;
374+ : ' null ' ;
363375 $ else = $ this ->compileElseClause ($ block );
364376 $ outerBp = $ this ->outerBlockParamsExpr ();
365377 $ helperName = self ::quote ($ name );
@@ -905,26 +917,6 @@ private static function getRuntimeFunc(string $name, string $args): string
905917 return "LR:: $ name( $ args) " ;
906918 }
907919
908- /**
909- * @param bool $declaresBp true when this closure receives new block param values as its third argument
910- * @param bool $inheritsBp true when this closure must capture $blockParams from the enclosing scope
911- */
912- private static function blockClosure (string $ body , bool $ declaresBp = false , bool $ inheritsBp = false ): string
913- {
914- $ preamble = '' ;
915- if (str_contains ($ body , '$cx->depths[count($cx->depths)- ' )) {
916- $ preamble = '$sc=count($cx->depths); ' ;
917- $ body = str_replace ('$cx->depths[count($cx->depths)- ' , '$cx->depths[$sc- ' , $ body );
918- }
919- // Inherits block params from the enclosing closure's $blockParams variable when $inheritsBp.
920- $ sig = match (true ) {
921- $ declaresBp => "function( \$cx, \$in, array \$blockParams = []) " ,
922- $ inheritsBp => "function( \$cx, \$in) use ( \$blockParams) " ,
923- default => "function( \$cx, \$in) " ,
924- };
925- return "$ sig { {$ preamble }return $ body;} " ;
926- }
927-
928920 private static function quote (string $ string ): string
929921 {
930922 return "' " . addcslashes ($ string , "' \\" ) . "' " ;
0 commit comments