@@ -181,25 +181,47 @@ bool isZendAstListKind( zend_ast_kind kind )
181
181
}
182
182
183
183
/* *
184
- * zend_ast_create and zend_ast_create_ex allowed up to 4 child* parameters for version before PHP v8
185
- * and the limit was increased to 5 in PHP v8
184
+ * Max number of children for AST nodes is
185
+ * 4 for PHP before 8.0
186
+ * 5 for PHP from 8.0 but before 8.4
187
+ * 6 for PHP from 8.4
186
188
*
187
189
* @see ZEND_AST_SPEC_CALL_EX
190
+ *
191
+ * When adding support for a new PHP version:
192
+ * - Make sure g_astNodeMaxChildCount is correct
193
+ * - If g_astNodeMaxChildCount changed then update createAstEx()
194
+ * - Make sure zendAstKindToString() in AST_debug.cpp includes all the enum cases from enum _zend_ast_kind in <php-src>/Zend/zend_ast.h
195
+ * - Increment minor part of PHP version in static_assert below
188
196
*/
189
- static size_t g_maxCreateAstChildCount =
197
+ static_assert (
198
+ PHP_VERSION_ID < ELASTIC_APM_BUILD_PHP_VERSION_ID( 8 , 5 , 0 ),
199
+ "Make sure g_astNodeMaxChildCount is correct. See max number of children in enum _zend_ast_kind in <php-src>/Zend/zend_ast.h"
200
+ );
201
+ static constexpr size_t g_astNodeMaxChildCount =
202
+ #if PHP_VERSION_ID < ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 0, 0 )
203
+ 4 // PHP before 8.0
204
+ #elif PHP_VERSION_ID < ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 4, 0 )
205
+ 5 // PHP from 8.0 but before 8.4
206
+ #else
207
+ 6 // PHP from 8.4
208
+ #endif
209
+ ;
210
+ static constexpr size_t g_zendKindWithLargestChildNodesCount =
190
211
#if PHP_VERSION_ID < ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 0, 0 )
191
- 4
212
+ ZEND_AST_FOR // PHP before 8.0
192
213
#else
193
- 5
214
+ ZEND_AST_PARAM // PHP from 8.0
194
215
#endif
195
216
;
217
+ static_assert (g_zendKindWithLargestChildNodesCount == (g_astNodeMaxChildCount << ZEND_AST_NUM_CHILDREN_SHIFT));
196
218
197
219
zend_ast* createAstEx ( zend_ast_kind kind, zend_ast_attr attr, ZendAstPtrArrayView children )
198
220
{
199
221
char txtOutStreamBuf[ELASTIC_APM_TEXT_OUTPUT_STREAM_ON_STACK_BUFFER_SIZE];
200
222
TextOutputStream txtOutStream = ELASTIC_APM_TEXT_OUTPUT_STREAM_FROM_STATIC_BUFFER ( txtOutStreamBuf );
201
223
202
- ELASTIC_APM_ASSERT_LE_UINT64 ( children.count , g_maxCreateAstChildCount );
224
+ ELASTIC_APM_ASSERT_LE_UINT64 ( children.count , g_astNodeMaxChildCount );
203
225
ELASTIC_APM_ASSERT ( ! isZendAstListKind ( kind ), " kind: %s" , streamZendAstKind ( kind, &txtOutStream ) );
204
226
205
227
switch ( children.count )
@@ -218,6 +240,10 @@ zend_ast* createAstEx( zend_ast_kind kind, zend_ast_attr attr, ZendAstPtrArrayVi
218
240
case 5 :
219
241
return zend_ast_create_ex ( kind, attr, children.values [ 0 ], children.values [ 1 ], children.values [ 2 ], children.values [ 3 ], children.values [ 4 ] );
220
242
#endif
243
+ #if PHP_VERSION_ID >= ELASTIC_APM_BUILD_PHP_VERSION_ID( 8, 4, 0 )
244
+ case 6 :
245
+ return zend_ast_create_ex ( kind, attr, children.values [ 0 ], children.values [ 1 ], children.values [ 2 ], children.values [ 3 ], children.values [ 4 ], children.values [ 5 ] );
246
+ #endif
221
247
default : // silence compiler warning
222
248
return nullptr ;
223
249
}
@@ -227,9 +253,9 @@ ResultCode createAstExCheckChildrenCount( zend_ast_kind kind, zend_ast_attr attr
227
253
{
228
254
ResultCode resultCode;
229
255
230
- if ( children.count > g_maxCreateAstChildCount )
256
+ if ( children.count > g_astNodeMaxChildCount )
231
257
{
232
- ELASTIC_APM_LOG_ERROR ( " Number of children is larger than max; children.count: %u, g_maxCreateAstChildCount : %u" , (unsigned )children.count , (unsigned )g_maxCreateAstChildCount );
258
+ ELASTIC_APM_LOG_ERROR ( " Number of children is larger than max; children.count: %u, g_astNodeMaxChildCount : %u" , (unsigned )children.count , (unsigned )g_astNodeMaxChildCount );
233
259
ELASTIC_APM_SET_RESULT_CODE_AND_GOTO_FAILURE_EX ( resultFailure );
234
260
}
235
261
0 commit comments