@@ -41,6 +41,8 @@ class ExceptionCaster
41
41
E_STRICT => 'E_STRICT ' ,
42
42
);
43
43
44
+ private static $ framesCache = array ();
45
+
44
46
public static function castError (\Error $ e , array $ a , Stub $ stub , $ isNested , $ filter = 0 )
45
47
{
46
48
return self ::filterExceptionArray ($ stub ->class , $ a , "\0Error \0" , $ filter );
@@ -142,43 +144,52 @@ public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $is
142
144
$ prefix = Caster::PREFIX_VIRTUAL ;
143
145
144
146
if (isset ($ f ['file ' ], $ f ['line ' ])) {
145
- if (preg_match ('/\((\d+)\)(?:\([\da-f]{32}\))? : (?:eval\(\) \'d code|runtime-created function)$/ ' , $ f ['file ' ], $ match )) {
146
- $ f ['file ' ] = substr ($ f ['file ' ], 0 , -strlen ($ match [0 ]));
147
- $ f ['line ' ] = (int ) $ match [1 ];
148
- }
149
- $ caller = isset ($ f ['function ' ]) ? sprintf ('in %s() on line %d ' , (isset ($ f ['class ' ]) ? $ f ['class ' ].$ f ['type ' ] : '' ).$ f ['function ' ], $ f ['line ' ]) : null ;
150
- $ src = $ f ['line ' ];
151
- $ srcKey = $ f ['file ' ];
152
- $ ellipsis = explode (DIRECTORY_SEPARATOR , $ srcKey );
153
- $ ellipsis = 3 < count ($ ellipsis ) ? 2 + strlen (implode (array_slice ($ ellipsis , -2 ))) : 0 ;
154
-
155
- if (file_exists ($ f ['file ' ]) && 0 <= self ::$ srcContext ) {
156
- if (!empty ($ f ['class ' ]) && is_subclass_of ($ f ['class ' ], 'Twig_Template ' ) && method_exists ($ f ['class ' ], 'getDebugInfo ' )) {
157
- $ template = isset ($ f ['object ' ]) ? $ f ['object ' ] : unserialize (sprintf ('O:%d:"%s":0:{} ' , strlen ($ f ['class ' ]), $ f ['class ' ]));
158
-
159
- $ ellipsis = 0 ;
160
- $ templateSrc = method_exists ($ template , 'getSourceContext ' ) ? $ template ->getSourceContext ()->getCode () : (method_exists ($ template , 'getSource ' ) ? $ template ->getSource () : '' );
161
- $ templateInfo = $ template ->getDebugInfo ();
162
- if (isset ($ templateInfo [$ f ['line ' ]])) {
163
- $ templatePath = method_exists ($ template , 'getSourceContext ' ) ? $ template ->getSourceContext ()->getPath () : null ;
164
-
165
- if ($ templateSrc ) {
166
- $ templateSrc = explode ("\n" , $ templateSrc );
167
- $ src = self ::extractSource ($ templateSrc , $ templateInfo [$ f ['line ' ]], self ::$ srcContext , $ caller , 'twig ' , $ templatePath );
168
- $ srcKey = ($ templatePath ?: $ template ->getTemplateName ()).': ' .$ templateInfo [$ f ['line ' ]];
147
+ $ cacheKey = $ f ;
148
+ unset($ cacheKey ['object ' ], $ cacheKey ['args ' ]);
149
+ $ cacheKey [] = self ::$ srcContext ;
150
+ $ cacheKey = implode ('- ' , $ cacheKey );
151
+
152
+ if (isset (self ::$ framesCache [$ cacheKey ])) {
153
+ $ a [$ prefix .'src ' ] = self ::$ framesCache [$ cacheKey ];
154
+ } else {
155
+ if (preg_match ('/\((\d+)\)(?:\([\da-f]{32}\))? : (?:eval\(\) \'d code|runtime-created function)$/ ' , $ f ['file ' ], $ match )) {
156
+ $ f ['file ' ] = substr ($ f ['file ' ], 0 , -strlen ($ match [0 ]));
157
+ $ f ['line ' ] = (int ) $ match [1 ];
158
+ }
159
+ $ caller = isset ($ f ['function ' ]) ? sprintf ('in %s() on line %d ' , (isset ($ f ['class ' ]) ? $ f ['class ' ].$ f ['type ' ] : '' ).$ f ['function ' ], $ f ['line ' ]) : null ;
160
+ $ src = $ f ['line ' ];
161
+ $ srcKey = $ f ['file ' ];
162
+ $ ellipsis = explode (DIRECTORY_SEPARATOR , $ srcKey );
163
+ $ ellipsis = 3 < count ($ ellipsis ) ? 2
F42D
span> + strlen (implode (array_slice ($ ellipsis , -2 ))) : 0 ;
164
+
165
+ if (file_exists ($ f ['file ' ]) && 0 <= self ::$ srcContext ) {
166
+ if (!empty ($ f ['class ' ]) && is_subclass_of ($ f ['class ' ], 'Twig_Template ' ) && method_exists ($ f ['class ' ], 'getDebugInfo ' )) {
167
+ $ template = isset ($ f ['object ' ]) ? $ f ['object ' ] : unserialize (sprintf ('O:%d:"%s":0:{} ' , strlen ($ f ['class ' ]), $ f ['class ' ]));
168
+
169
+ $ ellipsis = 0 ;
170
+ $ templateSrc = method_exists ($ template , 'getSourceContext ' ) ? $ template ->getSourceContext ()->getCode () : (method_exists ($ template , 'getSource ' ) ? $ template ->getSource () : '' );
171
+ $ templateInfo = $ template ->getDebugInfo ();
172
+ if (isset ($ templateInfo [$ f ['line ' ]])) {
173
+ if (!method_exists ($ template , 'getSourceContext ' ) || !file_exists ($ templatePath = $ template ->getSourceContext ()->getPath ())) {
174
+ $ templatePath = null ;
175
+ }
176
+ if ($ templateSrc ) {
177
+ $ src = self ::extractSource ($ templateSrc , $ templateInfo [$ f ['line ' ]], self ::$ srcContext , $ caller , 'twig ' , $ templatePath );
178
+ $ srcKey = ($ templatePath ?: $ template ->getTemplateName ()).': ' .$ templateInfo [$ f ['line ' ]];
179
+ }
169
180
}
170
181
}
171
- }
172
- if ( $ srcKey == $ f ['file ' ]) {
173
- $ src = self :: extractSource ( explode ( "\n" , file_get_contents ( $ f [ ' file ' ])), $ f [ ' line ' ], self :: $ srcContext , $ caller , ' php ' , $ f ['file ' ]) ;
174
- $ srcKey .= ' : ' . $ f [ ' line ' ];
175
- if ( $ ellipsis) {
176
- $ ellipsis += 1 + strlen ( $ f [ ' line ' ]);
182
+ if ( $ srcKey == $ f [ ' file ' ]) {
183
+ $ src = self :: extractSource ( file_get_contents ( $ f ['file ' ]), $ f [ ' line ' ], self :: $ srcContext , $ caller , ' php ' , $ f [ ' file ' ]);
184
+ $ srcKey .= ' : ' . $ f ['line ' ] ;
185
+ if ( $ ellipsis ) {
186
+ $ ellipsis += 1 + strlen ( $ f [ ' line ' ]);
187
+
179B
}
177
188
}
178
189
}
190
+ $ srcAttr = $ ellipsis ? 'ellipsis= ' .$ ellipsis : '' ;
191
+ self ::$ framesCache [$ cacheKey ] = $ a [$ prefix .'src ' ] = new EnumStub (array ("\0~ $ srcAttr \0$ srcKey " => $ src ));
179
192
}
180
- $ srcAttr = $ ellipsis ? 'ellipsis= ' .$ ellipsis : '' ;
181
- $ a [$ prefix .'src ' ] = new EnumStub (array ("\0~ $ srcAttr \0$ srcKey " => $ src ));
182
193
}
183
194
184
195
unset($ a [$ prefix .'args ' ], $ a [$ prefix .'line ' ], $ a [$ prefix .'file ' ]);
@@ -232,14 +243,16 @@ private static function traceUnshift(&$trace, $class, $file, $line)
232
243
));
233
244
}
234
245
235
- private static function extractSource (array $ srcArray , $ line , $ srcContext , $ title , $ lang , $ file = null )
246
+ private static function extractSource ($ srcLines , $ line , $ srcContext , $ title , $ lang , $ file = null )
236
247
{
248
+ $ srcLines = explode ("\n" , $ srcLines );
237
249
$ src = array ();
238
250
239
251
for ($ i = $ line - 1 - $ srcContext ; $ i <= $ line - 1 + $ srcContext ; ++$ i ) {
240
- $ src [] = (isset ($ srcArray [$ i ]) ? $ srcArray [$ i ] : '' )."\n" ;
252
+ $ src [] = (isset ($ srcLines [$ i ]) ? $ srcLines [$ i ] : '' )."\n" ;
241
253
}
242
254
255
+ $ srcLines = array ();
243
256
$ ltrim = 0 ;
244
257
do {
245
258
$ pad = null ;
@@ -257,7 +270,6 @@ private static function extractSource(array $srcArray, $line, $srcContext, $titl
257
270
} while (0 > $ i && null !== $ pad );
258
271
259
272
--$ ltrim ;
260
- $ srcArray = array ();
261
273
262
274
foreach ($ src as $ i => $ c ) {
263
275
if ($ ltrim ) {
@@ -274,9 +286,9 @@ private static function extractSource(array $srcArray, $line, $srcContext, $titl
274
286
}
275
287
}
276
288
$ c ->attr ['lang ' ] = $ lang ;
277
- $ srcArray [sprintf ("\0~%d \0" , $ i + $ line - $ srcContext )] = $ c ;
289
+ $ srcLines [sprintf ("\0~%d \0" , $ i + $ line - $ srcContext )] = $ c ;
278
290
}
279
291
280
- return new EnumStub ($ srcArray );
292
+ return new EnumStub ($ srcLines );
281
293
}
282
294
}
0 commit comments