Coverage Report

Created: 2026-04-01 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/Zend/zend_execute_API.c
Line
Count
Source
1
/*
2
   +----------------------------------------------------------------------+
3
   | Zend Engine                                                          |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 2.00 of the Zend license,     |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available through the world-wide-web at the following url:           |
10
   | http://www.zend.com/license/2_00.txt.                                |
11
   | If you did not receive a copy of the Zend license and are unable to  |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@zend.com so we can mail you a copy immediately.              |
14
   +----------------------------------------------------------------------+
15
   | Authors: Andi Gutmans <andi@php.net>                                 |
16
   |          Zeev Suraski <zeev@php.net>                                 |
17
   |          Dmitry Stogov <dmitry@php.net>                              |
18
   +----------------------------------------------------------------------+
19
*/
20
21
#include <stdio.h>
22
#include <signal.h>
23
24
#include "zend.h"
25
#include "zend_compile.h"
26
#include "zend_execute.h"
27
#include "zend_API.h"
28
#include "zend_stack.h"
29
#include "zend_constants.h"
30
#include "zend_extensions.h"
31
#include "zend_exceptions.h"
32
#include "zend_closures.h"
33
#include "zend_generators.h"
34
#include "zend_vm.h"
35
#include "zend_float.h"
36
#include "zend_fibers.h"
37
#include "zend_weakrefs.h"
38
#include "zend_inheritance.h"
39
#include "zend_observer.h"
40
#include "zend_call_stack.h"
41
#include "zend_frameless_function.h"
42
#ifdef HAVE_SYS_TIME_H
43
#include <sys/time.h>
44
#endif
45
#ifdef HAVE_UNISTD_H
46
#include <unistd.h>
47
#endif
48
#ifdef ZEND_MAX_EXECUTION_TIMERS
49
#include <sys/syscall.h>
50
#endif
51
52
ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data);
53
ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value);
54
ZEND_API zend_class_entry *(*zend_autoload)(zend_string *name, zend_string *lc_name);
55
56
#ifdef ZEND_WIN32
57
ZEND_TLS HANDLE tq_timer = NULL;
58
#endif
59
60
#if 0&&ZEND_DEBUG
61
static void (*original_sigsegv_handler)(int);
62
static void zend_handle_sigsegv(void) /* {{{ */
63
{
64
  fflush(stdout);
65
  fflush(stderr);
66
  if (original_sigsegv_handler == zend_handle_sigsegv) {
67
    signal(SIGSEGV, original_sigsegv_handler);
68
  } else {
69
    signal(SIGSEGV, SIG_DFL);
70
  }
71
  {
72
73
    fprintf(stderr, "SIGSEGV caught on opcode %d on opline %d of %s() at %s:%d\n\n",
74
        active_opline->opcode,
75
        active_opline-EG(active_op_array)->opcodes,
76
        get_active_function_name(),
77
        zend_get_executed_filename(),
78
        zend_get_executed_lineno());
79
/* See http://support.microsoft.com/kb/190351 */
80
#ifdef ZEND_WIN32
81
    fflush(stderr);
82
#endif
83
  }
84
  if (original_sigsegv_handler!=zend_handle_sigsegv) {
85
    original_sigsegv_handler(dummy);
86
  }
87
}
88
/* }}} */
89
#endif
90
91
static void zend_extension_activator(const zend_extension *extension) /* {{{ */
92
224k
{
93
224k
  if (extension->activate) {
94
224k
    extension->activate();
95
224k
  }
96
224k
}
97
/* }}} */
98
99
static void zend_extension_deactivator(const zend_extension *extension) /* {{{ */
100
224k
{
101
224k
  if (extension->deactivate) {
102
224k
    extension->deactivate();
103
224k
  }
104
224k
}
105
/* }}} */
106
107
static int clean_non_persistent_constant_full(zval *zv) /* {{{ */
108
0
{
109
0
  zend_constant *c = Z_PTR_P(zv);
110
0
  return (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
111
0
}
112
/* }}} */
113
114
static int clean_non_persistent_function_full(zval *zv) /* {{{ */
115
0
{
116
0
  const zend_function *function = Z_PTR_P(zv);
117
0
  return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
118
0
}
119
/* }}} */
120
121
static int clean_non_persistent_class_full(zval *zv) /* {{{ */
122
0
{
123
0
  const zend_class_entry *ce = Z_PTR_P(zv);
124
0
  return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
125
0
}
126
/* }}} */
127
128
void init_executor(void) /* {{{ */
129
224k
{
130
224k
  zend_init_fpu();
131
132
224k
  ZVAL_NULL(&EG(uninitialized_zval));
133
224k
  ZVAL_ERROR(&EG(error_zval));
134
/* destroys stack frame, therefore makes core dumps worthless */
135
#if 0&&ZEND_DEBUG
136
  original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv);
137
#endif
138
139
224k
  ZVAL_UNDEF(&EG(last_fatal_error_backtrace));
140
141
224k
  EG(symtable_cache_ptr) = EG(symtable_cache);
142
224k
  EG(symtable_cache_limit) = EG(symtable_cache) + SYMTABLE_CACHE_SIZE;
143
224k
  EG(no_extensions) = 0;
144
145
224k
  EG(function_table) = CG(function_table);
146
224k
  EG(class_table) = CG(class_table);
147
148
224k
  EG(error_handling) = EH_NORMAL;
149
224k
  EG(flags) = EG_FLAGS_INITIAL;
150
151
224k
  zend_vm_stack_init();
152
153
224k
  zend_hash_init(&EG(symbol_table), 64, NULL, ZVAL_PTR_DTOR, 0);
154
155
224k
  zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator);
156
157
224k
  zend_hash_init(&EG(included_files), 8, NULL, NULL, 0);
158
224k
  zend_hash_init(&EG(autoload_current_classnames), 8, NULL, NULL, 0);
159
160
224k
  EG(ticks_count) = 0;
161
162
224k
  ZVAL_UNDEF(&EG(user_error_handler));
163
224k
  ZVAL_UNDEF(&EG(user_exception_handler));
164
165
224k
  EG(current_execute_data) = NULL;
166
167
224k
  zend_stack_init(&EG(user_error_handlers_error_reporting), sizeof(int));
168
224k
  zend_stack_init(&EG(user_error_handlers), sizeof(zval));
169
224k
  zend_stack_init(&EG(user_exception_handlers), sizeof(zval));
170
171
224k
  zend_objects_store_init(&EG(objects_store), 1024);
172
224k
  zend_lazy_objects_init(&EG(lazy_objects_store));
173
174
224k
  EG(full_tables_cleanup) = 0;
175
224k
  ZEND_ATOMIC_BOOL_INIT(&EG(vm_interrupt), false);
176
224k
  ZEND_ATOMIC_BOOL_INIT(&EG(timed_out), false);
177
178
224k
  EG(exception) = NULL;
179
180
224k
  EG(fake_scope) = NULL;
181
224k
  EG(trampoline).common.function_name = NULL;
182
183
224k
  EG(ht_iterators_count) = sizeof(EG(ht_iterators_slots)) / sizeof(HashTableIterator);
184
224k
  EG(ht_iterators_used) = 0;
185
224k
  EG(ht_iterators) = EG(ht_iterators_slots);
186
224k
  memset(EG(ht_iterators), 0, sizeof(EG(ht_iterators_slots)));
187
188
224k
  EG(persistent_constants_count) = EG(zend_constants)->nNumUsed;
189
224k
  EG(persistent_functions_count) = EG(function_table)->nNumUsed;
190
224k
  EG(persistent_classes_count)   = EG(class_table)->nNumUsed;
191
192
224k
  EG(get_gc_buffer).start = EG(get_gc_buffer).end = EG(get_gc_buffer).cur = NULL;
193
194
224k
  EG(record_errors) = false;
195
224k
  memset(&EG(errors), 0, sizeof(EG(errors)));
196
197
224k
  EG(filename_override) = NULL;
198
224k
  EG(lineno_override) = -1;
199
200
224k
  zend_max_execution_timer_init();
201
224k
  zend_fiber_init();
202
224k
  zend_weakrefs_init();
203
204
224k
  zend_hash_init(&EG(callable_convert_cache), 8, NULL, ZVAL_PTR_DTOR, 0);
205
206
224k
  EG(active) = 1;
207
224k
}
208
/* }}} */
209
210
static int zval_call_destructor(zval *zv) /* {{{ */
211
1.48M
{
212
1.48M
  if (Z_TYPE_P(zv) == IS_INDIRECT) {
213
250k
    zv = Z_INDIRECT_P(zv);
214
250k
  }
215
1.48M
  if (Z_TYPE_P(zv) == IS_OBJECT && Z_REFCOUNT_P(zv) == 1) {
216
37.3k
    return ZEND_HASH_APPLY_REMOVE;
217
1.44M
  } else {
218
1.44M
    return ZEND_HASH_APPLY_KEEP;
219
1.44M
  }
220
1.48M
}
221
/* }}} */
222
223
static void zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */
224
224k
{
225
224k
  if (Z_TYPE_P(zv) == IS_INDIRECT) {
226
141k
    zv = Z_INDIRECT_P(zv);
227
141k
  }
228
224k
  i_zval_ptr_dtor(zv);
229
224k
}
230
/* }}} */
231
232
static ZEND_COLD void zend_throw_or_error(uint32_t fetch_type, zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
233
1.01k
{
234
1.01k
  va_list va;
235
1.01k
  char *message = NULL;
236
237
1.01k
  va_start(va, format);
238
1.01k
  zend_vspprintf(&message, 0, format, va);
239
240
1.01k
  if (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) {
241
1.01k
    zend_throw_error(exception_ce, "%s", message);
242
1.01k
  } else {
243
0
    zend_error_noreturn(E_ERROR, "%s", message);
244
0
  }
245
246
1.01k
  efree(message);
247
1.01k
  va_end(va);
248
1.01k
}
249
/* }}} */
250
251
void shutdown_destructors(void) /* {{{ */
252
224k
{
253
224k
  if (CG(unclean_shutdown)) {
254
19.9k
    EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
255
19.9k
  }
256
224k
  zend_try {
257
224k
    uint32_t symbols;
258
252k
    do {
259
252k
      symbols = zend_hash_num_elements(&EG(symbol_table));
260
252k
      zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor);
261
252k
    } while (symbols != zend_hash_num_elements(&EG(symbol_table)));
262
224k
    zend_objects_store_call_destructors(&EG(objects_store));
263
224k
  } zend_catch {
264
    /* if we couldn't destruct cleanly, mark all objects as destructed anyway */
265
0
    zend_objects_store_mark_destructed(&EG(objects_store));
266
0
  } zend_end_try();
267
224k
}
268
/* }}} */
269
270
/* Free values held by the executor. */
271
ZEND_API void zend_shutdown_executor_values(bool fast_shutdown)
272
224k
{
273
224k
  EG(flags) |= EG_FLAGS_IN_RESOURCE_SHUTDOWN;
274
224k
  zend_close_rsrc_list(&EG(regular_list));
275
276
  /* No PHP callback functions should be called after this point. */
277
224k
  EG(active) = 0;
278
279
224k
  if (!fast_shutdown) {
280
224k
    zval *zv;
281
282
224k
    zend_hash_graceful_reverse_destroy(&EG(symbol_table));
283
284
    /* Constants may contain objects, destroy them before the object store. */
285
224k
    if (EG(full_tables_cleanup)) {
286
0
      zend_hash_reverse_apply(EG(zend_constants), clean_non_persistent_constant_full);
287
224k
    } else {
288
224k
      zend_string *key;
289
902k
      ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(EG(zend_constants), key, zv) {
290
902k
        zend_constant *c = Z_PTR_P(zv);
291
902k
        if (_idx == EG(persistent_constants_count)) {
292
224k
          break;
293
224k
        }
294
2.26k
        zval_ptr_dtor_nogc(&c->value);
295
2.26k
        if (c->name) {
296
2.26k
          zend_string_release_ex(c->name, 0);
297
2.26k
        }
298
2.26k
        if (c->filename) {
299
2.17k
          zend_string_release_ex(c->filename, 0);
300
2.17k
        }
301
2.26k
        if (c->attributes) {
302
195
          zend_hash_release(c->attributes);
303
195
        }
304
2.26k
        efree(c);
305
2.26k
        zend_string_release_ex(key, 0);
306
2.26k
      } ZEND_HASH_MAP_FOREACH_END_DEL();
307
224k
    }
308
309
224k
    zval_ptr_dtor(&EG(last_fatal_error_backtrace));
310
224k
    ZVAL_UNDEF(&EG(last_fatal_error_backtrace));
311
312
    /* Release static properties and static variables prior to the final GC run,
313
     * as they may hold GC roots. */
314
934k
    ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(function_table), zv) {
315
934k
      zend_op_array *op_array = Z_PTR_P(zv);
316
934k
      if (op_array->type == ZEND_INTERNAL_FUNCTION) {
317
224k
        break;
318
224k
      }
319
17.9k
      if (ZEND_MAP_PTR(op_array->static_variables_ptr)) {
320
314
        HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
321
314
        if (ht) {
322
264
          zend_array_destroy(ht);
323
264
          ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
324
264
        }
325
314
      }
326
17.9k
    } ZEND_HASH_FOREACH_END();
327
74.9M
    ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) {
328
74.9M
      zend_class_entry *ce = Z_PTR_P(zv);
329
330
74.9M
      if (ce->default_static_members_count) {
331
2.51k
        zend_cleanup_internal_class_data(ce);
332
2.51k
      }
333
334
74.9M
      if (ZEND_MAP_PTR(ce->mutable_data)) {
335
1.12M
        if (ZEND_MAP_PTR_GET_IMM(ce->mutable_data)) {
336
633
          zend_cleanup_mutable_class_data(ce);
337
633
        }
338
36.1M
      } else if (ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_IMMUTABLE)) {
339
        /* Constants may contain objects, destroy the values before the object store. */
340
150k
        zend_class_constant *c;
341
332k
        ZEND_HASH_MAP_FOREACH_PTR(&ce->constants_table, c) {
342
332k
          if (c->ce == ce) {
343
10.9k
            zval_ptr_dtor_nogc(&c->value);
344
10.9k
            ZVAL_UNDEF(&c->value);
345
10.9k
          }
346
332k
        } ZEND_HASH_FOREACH_END();
347
348
        /* properties may contain objects as well */
349
150k
        if (ce->default_properties_table) {
350
17.1k
          zval *p = ce->default_properties_table;
351
17.1k
          zval *end = p + ce->default_properties_count;
352
353
39.6k
          while (p != end) {
354
22.5k
            i_zval_ptr_dtor(p);
355
22.5k
            ZVAL_UNDEF(p);
356
22.5k
            p++;
357
22.5k
          }
358
17.1k
        }
359
150k
      }
360
361
74.9M
      if (ce->type == ZEND_USER_CLASS && ce->backed_enum_table) {
362
218
        ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_IMMUTABLE));
363
218
        zend_hash_release(ce->backed_enum_table);
364
218
        ce->backed_enum_table = NULL;
365
218
      }
366
367
37.2M
      if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
368
13.4k
        zend_op_array *op_array;
369
54.1k
        ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) {
370
54.1k
          if (op_array->type == ZEND_USER_FUNCTION) {
371
13.6k
            if (ZEND_MAP_PTR(op_array->static_variables_ptr)) {
372
260
              HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
373
260
              if (ht) {
374
178
                zend_array_destroy(ht);
375
178
                ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
376
178
              }
377
260
            }
378
13.6k
          }
379
54.1k
        } ZEND_HASH_FOREACH_END();
380
381
13.4k
        if (ce->num_hooked_props) {
382
49
          zend_property_info *prop_info;
383
238
          ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop_info) {
384
238
            if (prop_info->ce == ce) {
385
70
              if (prop_info->hooks) {
386
147
                for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
387
98
                  if (prop_info->hooks[i]) {
388
49
                    ZEND_ASSERT(ZEND_USER_CODE(prop_info->hooks[i]->type));
389
49
                    op_array = &prop_info->hooks[i]->op_array;
390
49
                    if (ZEND_MAP_PTR(op_array->static_variables_ptr)) {
391
22
                      HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
392
22
                      if (ht) {
393
20
                        zend_array_destroy(ht);
394
20
                        ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
395
20
                      }
396
22
                    }
397
49
                  }
398
98
                }
399
49
              }
400
70
            }
401
238
          } ZEND_HASH_FOREACH_END();
402
49
        }
403
13.4k
      }
404
37.2M
    } ZEND_HASH_FOREACH_END();
405
406
    /* Also release error and exception handlers, which may hold objects. */
407
224k
    if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
408
0
      zval_ptr_dtor(&EG(user_error_handler));
409
0
      ZVAL_UNDEF(&EG(user_error_handler));
410
0
    }
411
412
224k
    if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
413
68
      zval_ptr_dtor(&EG(user_exception_handler));
414
68
      ZVAL_UNDEF(&EG(user_exception_handler));
415
68
    }
416
417
224k
    zend_stack_clean(&EG(user_error_handlers_error_reporting), NULL, 1);
418
224k
    zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
419
224k
    zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
420
421
224k
    zend_hash_clean(&EG(callable_convert_cache));
422
423
224k
#if ZEND_DEBUG
424
224k
    if (!CG(unclean_shutdown)) {
425
204k
      gc_collect_cycles();
426
204k
    }
427
224k
#endif
428
224k
  } else {
429
0
    zend_hash_discard(EG(zend_constants), EG(persistent_constants_count));
430
0
  }
431
432
224k
  zend_objects_store_free_object_storage(&EG(objects_store), fast_shutdown);
433
224k
}
434
435
void shutdown_executor(void) /* {{{ */
436
224k
{
437
224k
#if ZEND_DEBUG
438
224k
  bool fast_shutdown = 0;
439
#elif defined(__SANITIZE_ADDRESS__)
440
  char *force_fast_shutdown = getenv("ZEND_ASAN_FORCE_FAST_SHUTDOWN");
441
  bool fast_shutdown = (
442
    is_zend_mm()
443
    || (force_fast_shutdown && ZEND_ATOL(force_fast_shutdown))
444
  ) && !EG(full_tables_cleanup);
445
#else
446
  bool fast_shutdown = is_zend_mm() && !EG(full_tables_cleanup);
447
#endif
448
449
224k
  zend_try {
450
224k
    zend_stream_shutdown();
451
224k
  } zend_end_try();
452
453
224k
  zend_shutdown_executor_values(fast_shutdown);
454
455
224k
  zend_weakrefs_shutdown();
456
224k
  zend_max_execution_timer_shutdown();
457
224k
  zend_fiber_shutdown();
458
459
224k
  zend_try {
460
224k
    zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator);
461
224k
  } zend_end_try();
462
463
224k
  if (fast_shutdown) {
464
    /* Fast Request Shutdown
465
     * =====================
466
     * Zend Memory Manager frees memory by its own. We don't have to free
467
     * each allocated block separately.
468
     */
469
0
    zend_hash_discard(EG(function_table), EG(persistent_functions_count));
470
0
    zend_hash_discard(EG(class_table), EG(persistent_classes_count));
471
224k
  } else {
472
224k
    zend_vm_stack_destroy();
473
474
224k
    if (EG(full_tables_cleanup)) {
475
0
      zend_hash_reverse_apply(EG(function_table), clean_non_persistent_function_full);
476
0
      zend_hash_reverse_apply(EG(class_table), clean_non_persistent_class_full);
477
224k
    } else {
478
224k
      zend_string *key;
479
224k
      zval *zv;
480
934k
      ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(EG(function_table), key, zv) {
481
934k
        zend_function *func = Z_PTR_P(zv);
482
934k
        if (_idx == EG(persistent_functions_count)) {
483
224k
          break;
484
224k
        }
485
17.9k
        destroy_op_array(&func->op_array);
486
17.9k
        zend_string_release_ex(key, 0);
487
17.9k
      } ZEND_HASH_MAP_FOREACH_END_DEL();
488
489
1.25M
      ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(EG(class_table), key, zv) {
490
1.25M
        if (_idx == EG(persistent_classes_count)) {
491
224k
          break;
492
224k
        }
493
176k
        destroy_zend_class(zv);
494
176k
        zend_string_release_ex(key, 0);
495
176k
      } ZEND_HASH_MAP_FOREACH_END_DEL();
496
224k
    }
497
498
225k
    while (EG(symtable_cache_ptr) > EG(symtable_cache)) {
499
1.30k
      EG(symtable_cache_ptr)--;
500
1.30k
      zend_hash_destroy(*EG(symtable_cache_ptr));
501
1.30k
      FREE_HASHTABLE(*EG(symtable_cache_ptr));
502
1.30k
    }
503
504
224k
    zend_hash_destroy(&EG(included_files));
505
224k
    zend_hash_destroy(&EG(autoload_current_classnames));
506
507
224k
    zend_stack_destroy(&EG(user_error_handlers_error_reporting));
508
224k
    zend_stack_destroy(&EG(user_error_handlers));
509
224k
    zend_stack_destroy(&EG(user_exception_handlers));
510
224k
    zend_lazy_objects_destroy(&EG(lazy_objects_store));
511
224k
    zend_objects_store_destroy(&EG(objects_store));
512
513
224k
    if (EG(ht_iterators) != EG(ht_iterators_slots)) {
514
13
      efree(EG(ht_iterators));
515
13
    }
516
517
224k
    zend_hash_destroy(&EG(callable_convert_cache));
518
224k
  }
519
520
224k
#if ZEND_DEBUG
521
224k
  if (EG(ht_iterators_used) && !CG(unclean_shutdown)) {
522
0
    zend_error(E_WARNING, "Leaked %" PRIu32 " hashtable iterators", EG(ht_iterators_used));
523
0
  }
524
224k
#endif
525
526
  /* Check whether anyone is hogging the trampoline. */
527
224k
  ZEND_ASSERT(EG(trampoline).common.function_name == NULL || CG(unclean_shutdown));
528
529
224k
  EG(ht_iterators_used) = 0;
530
531
224k
  zend_shutdown_fpu();
532
224k
}
533
/* }}} */
534
535
/* return class name and "::" or "". */
536
ZEND_API const char *get_active_class_name(const char **space) /* {{{ */
537
29
{
538
29
  const zend_function *func;
539
540
29
  if (!zend_is_executing()) {
541
0
    if (space) {
542
0
      *space = "";
543
0
    }
544
0
    return "";
545
0
  }
546
547
29
  func = zend_active_function();
548
549
29
  switch (func->type) {
550
0
    case ZEND_USER_FUNCTION:
551
29
    case ZEND_INTERNAL_FUNCTION:
552
29
    {
553
29
      const zend_class_entry *ce = func->common.scope;
554
555
29
      if (space) {
556
29
        *space = ce ? "::" : "";
557
29
      }
558
29
      return ce ? ZSTR_VAL(ce->name) : "";
559
0
    }
560
0
    default:
561
0
      if (space) {
562
0
        *space = "";
563
0
      }
564
0
      return "";
565
29
  }
566
29
}
567
/* }}} */
568
569
ZEND_API const char *get_active_function_name(void) /* {{{ */
570
110
{
571
110
  const zend_function *func;
572
573
110
  if (!zend_is_executing()) {
574
0
    return NULL;
575
0
  }
576
577
110
  func = zend_active_function();
578
579
110
  switch (func->type) {
580
0
    case ZEND_USER_FUNCTION: {
581
0
        const zend_string *function_name = func->common.function_name;
582
583
0
        if (function_name) {
584
0
          return ZSTR_VAL(function_name);
585
0
        } else {
586
0
          return "main";
587
0
        }
588
0
      }
589
0
      break;
590
110
    case ZEND_INTERNAL_FUNCTION:
591
110
      return ZSTR_VAL(func->common.function_name);
592
0
      break;
593
0
    default:
594
0
      return NULL;
595
110
  }
596
110
}
597
/* }}} */
598
599
ZEND_API const zend_function *zend_active_function_ex(const zend_execute_data *execute_data)
600
1.35k
{
601
1.35k
  const zend_function *func = EX(func);
602
603
  /* Resolve function if op is a frameless call. */
604
1.35k
  if (ZEND_USER_CODE(func->type)) {
605
1.35k
    const zend_op *op = EX(opline);
606
1.35k
    if (ZEND_OP_IS_FRAMELESS_ICALL(op->opcode)) {
607
0
      func = ZEND_FLF_FUNC(op);
608
0
    }
609
1.35k
  }
610
611
1.35k
  return func;
612
1.35k
}
613
614
ZEND_API zend_string *get_active_function_or_method_name(void) /* {{{ */
615
7.23k
{
616
7.23k
  ZEND_ASSERT(zend_is_executing());
617
618
7.23k
  return get_function_or_method_name(zend_active_function());
619
7.23k
}
620
/* }}} */
621
622
ZEND_API zend_string *get_function_or_method_name(const zend_function *func) /* {{{ */
623
8.49k
{
624
8.49k
  if (func->common.scope && func->common.function_name) {
625
3.81k
    return zend_create_member_string(func->common.scope->name, func->common.function_name);
626
3.81k
  }
627
628
4.67k
  return func->common.function_name ? zend_string_copy(func->common.function_name) : ZSTR_INIT_LITERAL("main", 0);
629
8.49k
}
630
/* }}} */
631
632
ZEND_API const char *get_active_function_arg_name(uint32_t arg_num) /* {{{ */
633
6.76k
{
634
6.76k
  if (!zend_is_executing()) {
635
0
    return NULL;
636
0
  }
637
638
6.76k
  const zend_function *func = zend_active_function();
639
640
6.76k
  return get_function_arg_name(func, arg_num);
641
6.76k
}
642
/* }}} */
643
644
ZEND_API const char *get_function_arg_name(const zend_function *func, uint32_t arg_num) /* {{{ */
645
7.22k
{
646
7.22k
  if (!func || arg_num == 0 || func->common.num_args < arg_num) {
647
42
    return NULL;
648
42
  }
649
650
7.18k
  return ZSTR_VAL(func->common.arg_info[arg_num - 1].name);
651
7.22k
}
652
/* }}} */
653
654
ZEND_API const char *zend_get_executed_filename(void) /* {{{ */
655
755k
{
656
755k
  const zend_string *filename = zend_get_executed_filename_ex();
657
755k
  return filename != NULL ? ZSTR_VAL(filename) : "[no active file]";
658
755k
}
659
/* }}} */
660
661
ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */
662
3.16M
{
663
3.16M
  zend_string *filename_override = EG(filename_override);
664
3.16M
  if (filename_override != NULL) {
665
184
    return filename_override;
666
184
  }
667
668
3.16M
  const zend_execute_data *ex = EG(current_execute_data);
669
670
4.66M
  while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
671
1.50M
    ex = ex->prev_execute_data;
672
1.50M
  }
673
3.16M
  if (ex) {
674
2.12M
    return ex->func->op_array.filename;
675
2.12M
  } else {
676
1.03M
    return NULL;
677
1.03M
  }
678
3.16M
}
679
/* }}} */
680
681
ZEND_API uint32_t zend_get_executed_lineno(void) /* {{{ */
682
3.10M
{
683
3.10M
  zend_long lineno_override = EG(lineno_override);
684
3.10M
  if (lineno_override != -1) {
685
184
    return lineno_override;
686
184
  }
687
688
3.10M
  const zend_execute_data *ex = EG(current_execute_data);
689
690
4.60M
  while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
691
1.50M
    ex = ex->prev_execute_data;
692
1.50M
  }
693
3.10M
  if (ex) {
694
2.07M
    if (!ex->opline) {
695
      /* Missing SAVE_OPLINE()? Falling back to first line of function */
696
0
      return ex->func->op_array.opcodes[0].lineno;
697
0
    }
698
2.07M
    if (EG(exception) && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
699
66
        ex->opline->lineno == 0 && EG(opline_before_exception)) {
700
66
      return EG(opline_before_exception)->lineno;
701
66
    }
702
2.07M
    return ex->opline->lineno;
703
2.07M
  } else {
704
1.03M
    return 0;
705
1.03M
  }
706
3.10M
}
707
/* }}} */
708
709
ZEND_API zend_class_entry *zend_get_executed_scope(void) /* {{{ */
710
12.4k
{
711
12.4k
  const zend_execute_data *ex = EG(current_execute_data);
712
713
13.6k
  while (1) {
714
13.6k
    if (!ex) {
715
20
      return NULL;
716
13.6k
    } else if (ex->func && (ZEND_USER_CODE(ex->func->type) || ex->func->common.scope)) {
717
12.3k
      return ex->func->common.scope;
718
12.3k
    }
719
1.26k
    ex = ex->prev_execute_data;
720
1.26k
  }
721
12.4k
}
722
/* }}} */
723
724
ZEND_API bool zend_is_executing(void) /* {{{ */
725
2.67M
{
726
2.67M
  return EG(current_execute_data) != 0;
727
2.67M
}
728
/* }}} */
729
730
ZEND_API zend_result ZEND_FASTCALL zval_update_constant_with_ctx(zval *p, zend_class_entry *scope, zend_ast_evaluate_ctx *ctx)
731
4.78k
{
732
4.78k
  if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
733
4.78k
    zend_ast *ast = Z_ASTVAL_P(p);
734
735
4.78k
    if (ast->kind == ZEND_AST_CONSTANT) {
736
549
      zend_string *name = zend_ast_get_constant_name(ast);
737
549
      const zval *zv = zend_get_constant_ex(name, scope, ast->attr);
738
549
      if (UNEXPECTED(zv == NULL)) {
739
80
        return FAILURE;
740
80
      }
741
742
469
      zval_ptr_dtor_nogc(p);
743
469
      ZVAL_COPY_OR_DUP(p, zv);
744
4.23k
    } else {
745
4.23k
      zval tmp;
746
4.23k
      bool short_circuited;
747
748
      // Increase the refcount during zend_ast_evaluate to avoid releasing the ast too early
749
      // on nested calls to zval_update_constant_ex which can happen when retriggering ast
750
      // evaluation during autoloading.
751
4.23k
      zend_ast_ref *ast_ref = Z_AST_P(p);
752
4.23k
      bool ast_is_refcounted = !(GC_FLAGS(ast_ref) & GC_IMMUTABLE);
753
4.23k
      if (ast_is_refcounted) {
754
554
        GC_ADDREF(ast_ref);
755
554
      }
756
4.23k
      zend_result result = zend_ast_evaluate_ex(&tmp, ast, scope, &short_circuited, ctx) != SUCCESS;
757
4.23k
      if (ast_is_refcounted && !GC_DELREF(ast_ref)) {
758
8
        rc_dtor_func((zend_refcounted *)ast_ref);
759
8
      }
760
4.23k
      if (UNEXPECTED(result != SUCCESS)) {
761
457
        return FAILURE;
762
457
      }
763
3.78k
      zval_ptr_dtor_nogc(p);
764
3.78k
      ZVAL_COPY_VALUE(p, &tmp);
765
3.78k
    }
766
4.78k
  }
767
4.24k
  return SUCCESS;
768
4.78k
}
769
/* }}} */
770
771
ZEND_API zend_result ZEND_FASTCALL zval_update_constant_ex(zval *p, zend_class_entry *scope)
772
4.02k
{
773
4.02k
  zend_ast_evaluate_ctx ctx = {0};
774
4.02k
  return zval_update_constant_with_ctx(p, scope, &ctx);
775
4.02k
}
776
777
ZEND_API zend_result ZEND_FASTCALL zval_update_constant(zval *pp) /* {{{ */
778
0
{
779
0
  return zval_update_constant_ex(pp, EG(current_execute_data) ? zend_get_executed_scope() : CG(active_class_entry));
780
0
}
781
/* }}} */
782
783
zend_result _call_user_function_impl(zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[], HashTable *named_params) /* {{{ */
784
73
{
785
73
  zend_fcall_info fci;
786
787
73
  fci.size = sizeof(fci);
788
73
  if (object) {
789
44
    ZEND_ASSERT(Z_TYPE_P(object) == IS_OBJECT);
790
44
    fci.object = Z_OBJ_P(object);
791
44
  } else {
792
29
    fci.object = NULL;
793
29
  }
794
73
  ZVAL_COPY_VALUE(&fci.function_name, function_name);
795
73
  fci.retval = retval_ptr;
796
73
  fci.param_count = param_count;
797
73
  fci.params = params;
798
73
  fci.named_params = named_params;
799
800
73
  return zend_call_function(&fci, NULL);
801
73
}
802
/* }}} */
803
804
zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /* {{{ */
805
781k
{
806
781k
  zend_execute_data *call;
807
781k
  zend_fcall_info_cache fci_cache_local;
808
781k
  zend_function *func;
809
781k
  uint32_t call_info;
810
781k
  void *object_or_called_scope;
811
812
781k
  ZVAL_UNDEF(fci->retval);
813
814
781k
  if (!EG(active)) {
815
0
    return FAILURE; /* executor is already inactive */
816
0
  }
817
818
781k
  if (EG(exception)) {
819
623
    if (fci_cache) {
820
623
      zend_release_fcall_info_cache(fci_cache);
821
623
    }
822
623
    return SUCCESS; /* we would result in an unstable executor otherwise */
823
623
  }
824
825
780k
  ZEND_ASSERT(ZEND_FCI_INITIALIZED(*fci));
826
827
780k
  if (!fci_cache || !fci_cache->function_handler) {
828
98
    char *error = NULL;
829
830
98
    if (!fci_cache) {
831
73
      fci_cache = &fci_cache_local;
832
73
    }
833
834
98
    if (!zend_is_callable_ex(&fci->function_name, fci->object, 0, NULL, fci_cache, &error)) {
835
7
      ZEND_ASSERT(error && "Should have error if not callable");
836
7
      zend_string *callable_name
837
7
        = zend_get_callable_name_ex(&fci->function_name, fci->object);
838
7
      zend_throw_error(NULL, "Invalid callback %s, %s", ZSTR_VAL(callable_name), error);
839
7
      efree(error);
840
7
      zend_string_release_ex(callable_name, 0);
841
7
      return SUCCESS;
842
7
    }
843
844
91
    ZEND_ASSERT(!error);
845
91
  }
846
847
780k
  func = fci_cache->function_handler;
848
780k
  if ((func->common.fn_flags & ZEND_ACC_STATIC) || !fci_cache->object) {
849
68.5k
    object_or_called_scope = fci_cache->called_scope;
850
68.5k
    call_info = ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC;
851
711k
  } else {
852
711k
    object_or_called_scope = fci_cache->object;
853
711k
    call_info = ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC | ZEND_CALL_HAS_THIS;
854
711k
  }
855
856
780k
  if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_DEPRECATED)) {
857
17
    zend_deprecated_function(func);
858
859
17
    if (UNEXPECTED(EG(exception))) {
860
0
      return SUCCESS;
861
0
    }
862
17
  }
863
864
780k
  call = zend_vm_stack_push_call_frame(call_info,
865
780k
    func, fci->param_count, object_or_called_scope);
866
867
1.53M
  for (uint32_t i = 0; i < fci->param_count; i++) {
868
757k
    zval *param = ZEND_CALL_ARG(call, i+1);
869
757k
    zval *arg = &fci->params[i];
870
757k
    bool must_wrap = false;
871
757k
    if (UNEXPECTED(Z_ISUNDEF_P(arg))) {
872
      /* Allow forwarding undef slots. This is only used by Closure::__invoke(). */
873
5
      ZVAL_UNDEF(param);
874
5
      ZEND_ADD_CALL_FLAG(call, ZEND_CALL_MAY_HAVE_UNDEF);
875
5
      continue;
876
5
    }
877
878
757k
    if (ARG_SHOULD_BE_SENT_BY_REF(func, i + 1)) {
879
456
      if (UNEXPECTED(!Z_ISREF_P(arg))) {
880
100
        if (!ARG_MAY_BE_SENT_BY_REF(func, i + 1)) {
881
          /* By-value send is not allowed -- emit a warning,
882
           * and perform the call with the value wrapped in a reference. */
883
76
          zend_param_must_be_ref(func, i + 1);
884
76
          must_wrap = true;
885
76
          if (UNEXPECTED(EG(exception))) {
886
0
            ZEND_CALL_NUM_ARGS(call) = i;
887
24
cleanup_args:
888
24
            zend_vm_stack_free_args(call);
889
24
            if (ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
890
5
              zend_free_extra_named_params(call->extra_named_params);
891
5
            }
892
24
            zend_vm_stack_free_call_frame(call);
893
24
            zend_release_fcall_info_cache(fci_cache);
894
24
            return SUCCESS;
895
0
          }
896
76
        }
897
100
      }
898
757k
    } else {
899
757k
      if (Z_ISREF_P(arg) &&
900
734
          !(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
901
        /* don't separate references for __call */
902
734
        arg = Z_REFVAL_P(arg);
903
734
      }
904
757k
    }
905
906
757k
    if (EXPECTED(!must_wrap)) {
907
757k
      ZVAL_COPY(param, arg);
908
757k
    } else {
909
76
      Z_TRY_ADDREF_P(arg);
910
76
      ZVAL_NEW_REF(param, arg);
911
76
    }
912
757k
  }
913
914
780k
  if (fci->named_params) {
915
517
    zend_string *name;
916
517
    zval *arg;
917
517
    uint32_t arg_num = ZEND_CALL_NUM_ARGS(call) + 1;
918
517
    bool have_named_params = false;
919
2.04k
    ZEND_HASH_FOREACH_STR_KEY_VAL(fci->named_params, name, arg) {
920
2.04k
      bool must_wrap = false;
921
2.04k
      zval *target;
922
2.04k
      if (name) {
923
607
        void *cache_slot[2] = {NULL, NULL};
924
607
        have_named_params = true;
925
607
        target = zend_handle_named_arg(&call, name, &arg_num, cache_slot);
926
607
        if (!target) {
927
14
          goto cleanup_args;
928
14
        }
929
607
      } else {
930
155
        if (have_named_params) {
931
10
          zend_throw_error(NULL,
932
10
            "Cannot use positional argument after named argument");
933
10
          goto cleanup_args;
934
10
        }
935
936
145
        zend_vm_stack_extend_call_frame(&call, arg_num - 1, 1);
937
145
        target = ZEND_CALL_ARG(call, arg_num);
938
145
      }
939
940
738
      if (ARG_SHOULD_BE_SENT_BY_REF(func, arg_num)) {
941
33
        if (UNEXPECTED(!Z_ISREF_P(arg))) {
942
32
          if (!ARG_MAY_BE_SENT_BY_REF(func, arg_num)) {
943
            /* By-value send is not allowed -- emit a warning,
944
             * and perform the call with the value wrapped in a reference. */
945
22
            zend_param_must_be_ref(func, arg_num);
946
22
            must_wrap = true;
947
22
            if (UNEXPECTED(EG(exception))) {
948
0
              goto cleanup_args;
949
0
            }
950
22
          }
951
32
        }
952
705
      } else {
953
705
        if (Z_ISREF_P(arg) &&
954
0
          !(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
955
          /* don't separate references for __call */
956
0
          arg = Z_REFVAL_P(arg);
957
0
        }
958
705
      }
959
960
738
      if (EXPECTED(!must_wrap)) {
961
716
        ZVAL_COPY(target, arg);
962
716
      } else {
963
22
        Z_TRY_ADDREF_P(arg);
964
22
        ZVAL_NEW_REF(target, arg);
965
22
      }
966
738
      if (!name) {
967
145
        ZEND_CALL_NUM_ARGS(call)++;
968
145
        arg_num++;
969
145
      }
970
738
    } ZEND_HASH_FOREACH_END();
971
517
  }
972
973
780k
  if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_MAY_HAVE_UNDEF)) {
974
    /* zend_handle_undef_args assumes prev_execute_data is initialized. */
975
293
    call->prev_execute_data = NULL;
976
293
    if (zend_handle_undef_args(call) == FAILURE) {
977
12
      zend_vm_stack_free_args(call);
978
12
      zend_vm_stack_free_call_frame(call);
979
12
      return SUCCESS;
980
12
    }
981
293
  }
982
983
780k
  if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
984
7.17k
    uint32_t call_info;
985
986
7.17k
    GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
987
7.17k
    call_info = ZEND_CALL_CLOSURE;
988
7.17k
    if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
989
53
      call_info |= ZEND_CALL_FAKE_CLOSURE;
990
53
    }
991
7.17k
    ZEND_ADD_CALL_FLAG(call, call_info);
992
7.17k
  }
993
994
780k
  if (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
995
1.40k
    fci_cache->function_handler = NULL;
996
1.40k
  }
997
998
780k
  const zend_class_entry *orig_fake_scope = EG(fake_scope);
999
780k
  EG(fake_scope) = NULL;
1000
780k
  if (func->type == ZEND_USER_FUNCTION) {
1001
88.0k
    uint32_t orig_jit_trace_num = EG(jit_trace_num);
1002
1003
88.0k
    zend_init_func_execute_data(call, &func->op_array, fci->retval);
1004
88.0k
    ZEND_OBSERVER_FCALL_BEGIN(call);
1005
88.0k
    zend_execute_ex(call);
1006
88.0k
    EG(jit_trace_num) = orig_jit_trace_num;
1007
692k
  } else {
1008
692k
    ZEND_ASSERT(func->type == ZEND_INTERNAL_FUNCTION);
1009
692k
    ZVAL_NULL(fci->retval);
1010
692k
    call->prev_execute_data = EG(current_execute_data);
1011
692k
    EG(current_execute_data) = call;
1012
692k
#if ZEND_DEBUG
1013
692k
    bool should_throw = zend_internal_call_should_throw(func, call);
1014
692k
#endif
1015
692k
    ZEND_OBSERVER_FCALL_BEGIN(call);
1016
692k
    if (EXPECTED(zend_execute_internal == NULL)) {
1017
      /* saves one function call if zend_execute_internal is not used */
1018
621k
      func->internal_function.handler(call, fci->retval);
1019
621k
    } else {
1020
70.5k
      zend_execute_internal(call, fci->retval);
1021
70.5k
    }
1022
1023
692k
#if ZEND_DEBUG
1024
692k
    if (!EG(exception) && call->func) {
1025
627k
      if (should_throw) {
1026
0
        zend_internal_call_arginfo_violation(call->func);
1027
0
      }
1028
627k
      ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
1029
627k
        zend_verify_internal_return_type(call->func, fci->retval));
1030
627k
      ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
1031
627k
        ? Z_ISREF_P(fci->retval) : !Z_ISREF_P(fci->retval));
1032
627k
    }
1033
692k
#endif
1034
692k
    ZEND_OBSERVER_FCALL_END(call, fci->retval);
1035
692k
    EG(current_execute_data) = call->prev_execute_data;
1036
692k
    zend_vm_stack_free_args(call);
1037
692k
    if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
1038
5
      zend_array_release(call->extra_named_params);
1039
5
    }
1040
1041
692k
    if (EG(exception)) {
1042
62.4k
      zval_ptr_dtor(fci->retval);
1043
62.4k
      ZVAL_UNDEF(fci->retval);
1044
62.4k
    }
1045
1046
    /* This flag is regularly checked while running user functions, but not internal
1047
     * So see whether interrupt flag was set while the function was running... */
1048
692k
    if (zend_atomic_bool_exchange_ex(&EG(vm_interrupt), false)) {
1049
0
      if (zend_atomic_bool_load_ex(&EG(timed_out))) {
1050
0
        zend_timeout();
1051
0
      } else if (zend_interrupt_function) {
1052
0
        zend_interrupt_function(EG(current_execute_data));
1053
0
      }
1054
0
    }
1055
1056
692k
    if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) {
1057
12
      OBJ_RELEASE(Z_OBJ(call->This));
1058
12
    }
1059
692k
  }
1060
780k
  EG(fake_scope) = orig_fake_scope;
1061
1062
780k
  zend_vm_stack_free_call_frame(call);
1063
1064
780k
  if (UNEXPECTED(EG(exception))) {
1065
66.5k
    if (UNEXPECTED(!EG(current_execute_data))) {
1066
916
      zend_throw_exception_internal(NULL);
1067
65.6k
    } else if (EG(current_execute_data)->func &&
1068
65.6k
               ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
1069
2.06k
      zend_rethrow_exception(EG(current_execute_data));
1070
2.06k
    }
1071
66.5k
  }
1072
1073
780k
  return SUCCESS;
1074
780k
}
1075
/* }}} */
1076
1077
ZEND_API void zend_call_known_function(
1078
    zend_function *fn, zend_object *object, zend_class_entry *called_scope, zval *retval_ptr,
1079
    uint32_t param_count, zval *params, HashTable *named_params)
1080
760k
{
1081
760k
  zval retval;
1082
760k
  zend_fcall_info fci;
1083
760k
  zend_fcall_info_cache fcic;
1084
1085
760k
  ZEND_ASSERT(fn && "zend_function must be passed!");
1086
1087
760k
  fci.size = sizeof(fci);
1088
760k
  fci.object = object;
1089
760k
  fci.retval = retval_ptr ? retval_ptr : &retval;
1090
760k
  fci.param_count = param_count;
1091
760k
  fci.params = params;
1092
760k
  fci.named_params = named_params;
1093
760k
  ZVAL_UNDEF(&fci.function_name); /* Unused */
1094
1095
760k
  fcic.function_handler = fn;
1096
760k
  fcic.object = object;
1097
760k
  fcic.called_scope = called_scope;
1098
1099
760k
  zend_result result = zend_call_function(&fci, &fcic);
1100
760k
  if (UNEXPECTED(result == FAILURE)) {
1101
0
    if (!EG(exception)) {
1102
0
      zend_error_noreturn(E_CORE_ERROR, "Couldn't execute method %s%s%s",
1103
0
        fn->common.scope ? ZSTR_VAL(fn->common.scope->name) : "",
1104
0
        fn->common.scope ? "::" : "", ZSTR_VAL(fn->common.function_name));
1105
0
    }
1106
0
  }
1107
1108
760k
  if (!retval_ptr) {
1109
618k
    zval_ptr_dtor(&retval);
1110
618k
  }
1111
760k
}
1112
1113
ZEND_API void zend_call_known_instance_method_with_2_params(
1114
    zend_function *fn, zend_object *object, zval *retval_ptr, zval *param1, zval *param2)
1115
306
{
1116
306
  zval params[2];
1117
306
  ZVAL_COPY_VALUE(&params[0], param1);
1118
306
  ZVAL_COPY_VALUE(&params[1], param2);
1119
306
  zend_call_known_instance_method(fn, object, retval_ptr, 2, params);
1120
306
}
1121
1122
ZEND_API zend_result zend_call_method_if_exists(
1123
    zend_object *object, zend_string *method_name, zval *retval,
1124
    uint32_t param_count, zval *params)
1125
7.14k
{
1126
7.14k
  zval zval_method;
1127
7.14k
  zend_fcall_info_cache fcc;
1128
1129
7.14k
  ZVAL_STR(&zval_method, method_name);
1130
1131
7.14k
  if (UNEXPECTED(!zend_is_callable_ex(&zval_method, object, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &fcc, NULL))) {
1132
211
    ZVAL_UNDEF(retval);
1133
211
    return FAILURE;
1134
211
  }
1135
1136
6.93k
  zend_call_known_fcc(&fcc, retval, param_count, params, NULL);
1137
  /* Need to free potential trampoline (__call/__callStatic) copied function handler before releasing the closure */
1138
6.93k
  zend_release_fcall_info_cache(&fcc);
1139
6.93k
  return SUCCESS;
1140
7.14k
}
1141
1142
/* 0-9 a-z A-Z _ \ 0x80-0xff */
1143
static const uint32_t valid_chars[8] = {
1144
  0x00000000,
1145
  0x03ff0000,
1146
  0x97fffffe,
1147
  0x07fffffe,
1148
  0xffffffff,
1149
  0xffffffff,
1150
  0xffffffff,
1151
  0xffffffff,
1152
};
1153
1154
178k
ZEND_API bool zend_is_valid_class_name(const zend_string *name) {
1155
2.06M
  for (size_t i = 0; i < ZSTR_LEN(name); i++) {
1156
1.88M
    unsigned char c = ZSTR_VAL(name)[i];
1157
1.88M
    if (!ZEND_BIT_TEST(valid_chars, c)) {
1158
3.19k
      return 0;
1159
3.19k
    }
1160
1.88M
  }
1161
175k
  return 1;
1162
178k
}
1163
1164
ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *key, uint32_t flags) /* {{{ */
1165
769k
{
1166
769k
  zend_class_entry *ce = NULL;
1167
769k
  zval *zv;
1168
769k
  zend_string *lc_name;
1169
769k
  zend_string *autoload_name;
1170
769k
  uint32_t ce_cache = 0;
1171
1172
769k
  if (ZSTR_HAS_CE_CACHE(name) && ZSTR_VALID_CE_CACHE(name)) {
1173
274k
    ce_cache = GC_REFCOUNT(name);
1174
274k
    ce = GET_CE_CACHE(ce_cache);
1175
274k
    if (EXPECTED(ce)) {
1176
215k
      return ce;
1177
215k
    }
1178
274k
  }
1179
1180
553k
  if (key) {
1181
321k
    lc_name = key;
1182
321k
  } else {
1183
231k
    if (!ZSTR_LEN(name)) {
1184
88
      return NULL;
1185
88
    }
1186
1187
231k
    if (ZSTR_VAL(name)[0] == '\\') {
1188
115
      lc_name = zend_string_alloc(ZSTR_LEN(name) - 1, 0);
1189
115
      zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1);
1190
231k
    } else {
1191
231k
      lc_name = zend_string_tolower(name);
1192
231k
    }
1193
231k
  }
1194
1195
553k
  zv = zend_hash_find(EG(class_table), lc_name);
1196
553k
  if (zv) {
1197
83.2k
    if (!key) {
1198
27.3k
      zend_string_release_ex(lc_name, 0);
1199
27.3k
    }
1200
83.2k
    ce = (zend_class_entry*)Z_PTR_P(zv);
1201
83.2k
    if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_LINKED))) {
1202
5.10k
      if ((flags & ZEND_FETCH_CLASS_ALLOW_UNLINKED) ||
1203
78
        ((flags & ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED) &&
1204
5.06k
          (ce->ce_flags & ZEND_ACC_NEARLY_LINKED))) {
1205
5.06k
        if (!CG(unlinked_uses)) {
1206
224
          ALLOC_HASHTABLE(CG(unlinked_uses));
1207
224
          zend_hash_init(CG(unlinked_uses), 0, NULL, NULL, 0);
1208
224
        }
1209
5.06k
        zend_hash_index_add_empty_element(CG(unlinked_uses), (zend_long)(uintptr_t)ce);
1210
5.06k
        return ce;
1211
5.06k
      }
1212
38
      return NULL;
1213
5.10k
    }
1214
    /* Don't populate CE_CACHE for mutable classes during compilation.
1215
     * The class may be freed while persisting. */
1216
78.1k
    if (ce_cache &&
1217
52.5k
        (!CG(in_compilation) || (ce->ce_flags & ZEND_ACC_IMMUTABLE))) {
1218
49.3k
      SET_CE_CACHE(ce_cache, ce);
1219
49.3k
    }
1220
78.1k
    return ce;
1221
83.2k
  }
1222
1223
  /* The compiler is not-reentrant. Make sure we autoload only during run-time. */
1224
470k
  if ((flags & ZEND_FETCH_CLASS_NO_AUTOLOAD) || zend_is_compiling()) {
1225
289k
    if (!key) {
1226
199k
      zend_string_release_ex(lc_name, 0);
1227
199k
    }
1228
289k
    return NULL;
1229
289k
  }
1230
1231
180k
  if (!zend_autoload) {
1232
0
    if (!key) {
1233
0
      zend_string_release_ex(lc_name, 0);
1234
0
    }
1235
0
    return NULL;
1236
0
  }
1237
1238
  /* Verify class name before passing it to the autoloader. */
1239
180k
  if (!key && !ZSTR_HAS_CE_CACHE(name) && !zend_is_valid_class_name(name)) {
1240
3.11k
    zend_string_release_ex(lc_name, 0);
1241
3.11k
    return NULL;
1242
3.11k
  }
1243
1244
177k
  if (zend_hash_add_empty_element(&EG(autoload_current_classnames), lc_name) == NULL) {
1245
47
    if (!key) {
1246
44
      zend_string_release_ex(lc_name, 0);
1247
44
    }
1248
47
    return NULL;
1249
47
  }
1250
1251
177k
  if (ZSTR_VAL(name)[0] == '\\') {
1252
63
    autoload_name = zend_string_init(ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1, 0);
1253
176k
  } else {
1254
176k
    autoload_name = zend_string_copy(name);
1255
176k
  }
1256
1257
177k
  zend_string *previous_filename = EG(filename_override);
1258
177k
  zend_long previous_lineno = EG(lineno_override);
1259
177k
  EG(filename_override) = NULL;
1260
177k
  EG(lineno_override) = -1;
1261
177k
  ce = zend_autoload(autoload_name, lc_name);
1262
177k
  EG(filename_override) = previous_filename;
1263
177k
  EG(lineno_override) = previous_lineno;
1264
1265
177k
  zend_string_release_ex(autoload_name, 0);
1266
177k
  zend_hash_del(&EG(autoload_current_classnames), lc_name);
1267
1268
177k
  if (!key) {
1269
1.17k
    zend_string_release_ex(lc_name, 0);
1270
1.17k
  }
1271
177k
  if (ce) {
1272
513
    ZEND_ASSERT(!CG(in_compilation));
1273
513
    if (ce_cache) {
1274
401
      SET_CE_CACHE(ce_cache, ce);
1275
401
    }
1276
513
  }
1277
177k
  return ce;
1278
177k
}
1279
/* }}} */
1280
1281
ZEND_API zend_class_entry *zend_lookup_class(zend_string *name) /* {{{ */
1282
12.9k
{
1283
12.9k
  return zend_lookup_class_ex(name, NULL, 0);
1284
12.9k
}
1285
/* }}} */
1286
1287
ZEND_API zend_class_entry *zend_get_called_scope(const zend_execute_data *ex) /* {{{ */
1288
90.6k
{
1289
90.7k
  while (ex) {
1290
2.83k
    if (Z_TYPE(ex->This) == IS_OBJECT) {
1291
1.38k
      return Z_OBJCE(ex->This);
1292
1.44k
    } else if (Z_CE(ex->This)) {
1293
935
      return Z_CE(ex->This);
1294
935
    } else if (ex->func) {
1295
512
      if (ex->func->type != ZEND_INTERNAL_FUNCTION || ex->func->common.scope) {
1296
455
        return NULL;
1297
455
      }
1298
512
    }
1299
57
    ex = ex->prev_execute_data;
1300
57
  }
1301
87.8k
  return NULL;
1302
90.6k
}
1303
/* }}} */
1304
1305
ZEND_API zend_object *zend_get_this_object(const zend_execute_data *ex) /* {{{ */
1306
89.9k
{
1307
90.1k
  while (ex) {
1308
2.21k
    if (Z_TYPE(ex->This) == IS_OBJECT) {
1309
1.45k
      return Z_OBJ(ex->This);
1310
1.45k
    } else if (ex->func) {
1311
761
      if (ex->func->type != ZEND_INTERNAL_FUNCTION || ex->func->common.scope) {
1312
654
        return NULL;
1313
654
      }
1314
761
    }
1315
107
    ex = ex->prev_execute_data;
1316
107
  }
1317
87.8k
  return NULL;
1318
89.9k
}
1319
/* }}} */
1320
1321
ZEND_API zend_result zend_eval_stringl(const char *str, size_t str_len, zval *retval_ptr, const char *string_name) /* {{{ */
1322
0
{
1323
0
  zend_op_array *new_op_array;
1324
0
  uint32_t original_compiler_options;
1325
0
  zend_result retval;
1326
0
  zend_string *code_str;
1327
1328
0
  if (retval_ptr) {
1329
0
    code_str = zend_string_concat3(
1330
0
      "return ", sizeof("return ")-1, str, str_len, ";", sizeof(";")-1);
1331
0
  } else {
1332
0
    code_str = zend_string_init(str, str_len, 0);
1333
0
  }
1334
1335
  /*printf("Evaluating '%s'\n", pv.value.str.val);*/
1336
1337
0
  original_compiler_options = CG(compiler_options);
1338
0
  CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
1339
0
  new_op_array = zend_compile_string(code_str, string_name, ZEND_COMPILE_POSITION_AFTER_OPEN_TAG);
1340
0
  CG(compiler_options) = original_compiler_options;
1341
1342
0
  if (new_op_array) {
1343
0
    zval local_retval;
1344
1345
0
    EG(no_extensions)=1;
1346
1347
0
    new_op_array->scope = zend_get_executed_scope();
1348
1349
0
    zend_try {
1350
0
      ZVAL_UNDEF(&local_retval);
1351
0
      zend_execute(new_op_array, &local_retval);
1352
0
    } zend_catch {
1353
0
      destroy_op_array(new_op_array);
1354
0
      efree_size(new_op_array, sizeof(zend_op_array));
1355
0
      zend_bailout();
1356
0
    } zend_end_try();
1357
1358
0
    if (Z_TYPE(local_retval) != IS_UNDEF) {
1359
0
      if (retval_ptr) {
1360
0
        ZVAL_COPY_VALUE(retval_ptr, &local_retval);
1361
0
      } else {
1362
0
        zval_ptr_dtor(&local_retval);
1363
0
      }
1364
0
    } else {
1365
0
      if (retval_ptr) {
1366
0
        ZVAL_NULL(retval_ptr);
1367
0
      }
1368
0
    }
1369
1370
0
    EG(no_extensions)=0;
1371
0
    zend_destroy_static_vars(new_op_array);
1372
0
    destroy_op_array(new_op_array);
1373
0
    efree_size(new_op_array, sizeof(zend_op_array));
1374
0
    retval = SUCCESS;
1375
0
  } else {
1376
0
    retval = FAILURE;
1377
0
  }
1378
0
  zend_string_release(code_str);
1379
0
  return retval;
1380
0
}
1381
/* }}} */
1382
1383
ZEND_API zend_result zend_eval_string(const char *str, zval *retval_ptr, const char *string_name) /* {{{ */
1384
0
{
1385
0
  return zend_eval_stringl(str, strlen(str), retval_ptr, string_name);
1386
0
}
1387
/* }}} */
1388
1389
ZEND_API zend_result zend_eval_stringl_ex(const char *str, size_t str_len, zval *retval_ptr, const char *string_name, bool handle_exceptions) /* {{{ */
1390
0
{
1391
0
  zend_result result;
1392
1393
0
  result = zend_eval_stringl(str, str_len, retval_ptr, string_name);
1394
0
  if (handle_exceptions && EG(exception)) {
1395
0
    result = zend_exception_error(EG(exception), E_ERROR);
1396
0
  }
1397
0
  return result;
1398
0
}
1399
/* }}} */
1400
1401
ZEND_API zend_result zend_eval_string_ex(const char *str, zval *retval_ptr, const char *string_name, bool handle_exceptions) /* {{{ */
1402
0
{
1403
0
  return zend_eval_stringl_ex(str, strlen(str), retval_ptr, string_name, handle_exceptions);
1404
0
}
1405
/* }}} */
1406
1407
static void zend_set_timeout_ex(zend_long seconds, bool reset_signals);
1408
1409
ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */
1410
0
{
1411
#if defined(PHP_WIN32)
1412
# ifndef ZTS
1413
  /* No action is needed if we're timed out because zero seconds are
1414
     just ignored. Also, the hard timeout needs to be respected. If the
1415
     timer is not restarted properly, it could hang in the shutdown
1416
     function. */
1417
  if (EG(hard_timeout) > 0) {
1418
    zend_atomic_bool_store_ex(&EG(timed_out), false);
1419
    zend_set_timeout_ex(EG(hard_timeout), true);
1420
    /* XXX Abused, introduce an additional flag if the value needs to be kept. */
1421
    EG(hard_timeout) = 0;
1422
  }
1423
# endif
1424
#else
1425
0
  zend_atomic_bool_store_ex(&EG(timed_out), false);
1426
0
  zend_set_timeout_ex(0, true);
1427
0
#endif
1428
1429
0
  zend_error_noreturn(E_ERROR, "Maximum execution time of " ZEND_LONG_FMT " second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
1430
0
}
1431
/* }}} */
1432
1433
#ifndef ZEND_WIN32
1434
# ifdef ZEND_MAX_EXECUTION_TIMERS
1435
static void zend_timeout_handler(int dummy, siginfo_t *si, void *uc) /* {{{ */
1436
{
1437
#ifdef ZTS
1438
  if (!tsrm_is_managed_thread()) {
1439
    fprintf(stderr, "zend_timeout_handler() called in a thread not managed by PHP. The expected signal handler will not be called. This is probably a bug.\n");
1440
1441
    return;
1442
  }
1443
#endif
1444
1445
  if (si->si_value.sival_ptr != &EG(max_execution_timer_timer)) {
1446
#ifdef MAX_EXECUTION_TIMERS_DEBUG
1447
    fprintf(stderr, "Executing previous handler (if set) for unexpected signal SIGRTMIN received on thread %d\n", (pid_t) syscall(SYS_gettid));
1448
#endif
1449
1450
    if (EG(oldact).sa_sigaction) {
1451
      EG(oldact).sa_sigaction(dummy, si, uc);
1452
1453
      return;
1454
    }
1455
    if (EG(oldact).sa_handler) EG(oldact).sa_handler(dummy);
1456
1457
    return;
1458
  }
1459
# else
1460
static void zend_timeout_handler(int dummy) /* {{{ */
1461
0
{
1462
0
# endif
1463
#ifdef ZTS
1464
  if (!tsrm_is_managed_thread()) {
1465
    fprintf(stderr, "zend_timeout_handler() called in a thread not managed by PHP. The expected signal handler will not be called. This is probably a bug.\n");
1466
1467
    return;
1468
  }
1469
#else
1470
0
  if (zend_atomic_bool_load_ex(&EG(timed_out))) {
1471
    /* Die on hard timeout */
1472
0
    const char *error_filename = NULL;
1473
0
    uint32_t error_lineno = 0;
1474
0
    char log_buffer[2048];
1475
0
    int output_len = 0;
1476
1477
0
    if (zend_is_compiling()) {
1478
0
      error_filename = ZSTR_VAL(zend_get_compiled_filename());
1479
0
      error_lineno = zend_get_compiled_lineno();
1480
0
    } else if (zend_is_executing()) {
1481
0
      error_filename = zend_get_executed_filename();
1482
0
      if (error_filename[0] == '[') { /* [no active file] */
1483
0
        error_filename = NULL;
1484
0
        error_lineno = 0;
1485
0
      } else {
1486
0
        error_lineno = zend_get_executed_lineno();
1487
0
      }
1488
0
    }
1489
0
    if (!error_filename) {
1490
0
      error_filename = "Unknown";
1491
0
    }
1492
1493
0
    output_len = snprintf(log_buffer, sizeof(log_buffer), "\nFatal error: Maximum execution time of " ZEND_LONG_FMT "+" ZEND_LONG_FMT " seconds exceeded (terminated) in %s on line %d\n", EG(timeout_seconds), EG(hard_timeout), error_filename, error_lineno);
1494
0
    if (output_len > 0) {
1495
0
      zend_quiet_write(2, log_buffer, MIN(output_len, sizeof(log_buffer)));
1496
0
    }
1497
0
    _exit(124);
1498
0
  }
1499
0
#endif
1500
1501
0
  if (zend_on_timeout) {
1502
0
    zend_on_timeout(EG(timeout_seconds));
1503
0
  }
1504
1505
0
  zend_atomic_bool_store_ex(&EG(timed_out), true);
1506
0
  zend_atomic_bool_store_ex(&EG(vm_interrupt), true);
1507
1508
0
#ifndef ZTS
1509
0
  if (EG(hard_timeout) > 0) {
1510
    /* Set hard timeout */
1511
0
    zend_set_timeout_ex(EG(hard_timeout), true);
1512
0
  }
1513
0
#endif
1514
0
}
1515
/* }}} */
1516
#endif
1517
1518
#ifdef ZEND_WIN32
1519
VOID CALLBACK tq_timer_cb(PVOID arg, BOOLEAN timed_out)
1520
{
1521
  zend_executor_globals *eg;
1522
1523
  /* The doc states it'll be always true, however it theoretically
1524
    could be FALSE when the thread was signaled. */
1525
  if (!timed_out) {
1526
    return;
1527
  }
1528
1529
  eg = (zend_executor_globals *)arg;
1530
  zend_atomic_bool_store_ex(&eg->timed_out, true);
1531
  zend_atomic_bool_store_ex(&eg->vm_interrupt, true);
1532
}
1533
#endif
1534
1535
/* This one doesn't exists on QNX */
1536
#ifndef SIGPROF
1537
#define SIGPROF 27
1538
#endif
1539
1540
static void zend_set_timeout_ex(zend_long seconds, bool reset_signals) /* {{{ */
1541
224k
{
1542
#ifdef ZEND_WIN32
1543
  zend_executor_globals *eg;
1544
1545
  if (!seconds) {
1546
    return;
1547
  }
1548
1549
  /* Don't use ChangeTimerQueueTimer() as it will not restart an expired
1550
   * timer, so we could end up with just an ignored timeout. Instead
1551
   * delete and recreate. */
1552
  if (NULL != tq_timer) {
1553
    if (!DeleteTimerQueueTimer(NULL, tq_timer, INVALID_HANDLE_VALUE)) {
1554
      tq_timer = NULL;
1555
      zend_error_noreturn(E_ERROR, "Could not delete queued timer");
1556
    }
1557
    tq_timer = NULL;
1558
  }
1559
1560
  /* XXX passing NULL means the default timer queue provided by the system is used */
1561
  eg = ZEND_MODULE_GLOBALS_BULK(executor);
1562
  if (!CreateTimerQueueTimer(&tq_timer, NULL, (WAITORTIMERCALLBACK)tq_timer_cb, (VOID*)eg, seconds*1000, 0, WT_EXECUTEONLYONCE)) {
1563
    tq_timer = NULL;
1564
    zend_error_noreturn(E_ERROR, "Could not queue new timer");
1565
  }
1566
#elif defined(ZEND_MAX_EXECUTION_TIMERS)
1567
  if (seconds > 0) {
1568
    zend_max_execution_timer_settime(seconds);
1569
  }
1570
1571
  if (reset_signals) {
1572
    sigset_t sigset;
1573
    struct sigaction act;
1574
1575
    act.sa_sigaction = zend_timeout_handler;
1576
    sigemptyset(&act.sa_mask);
1577
    act.sa_flags = SA_ONSTACK | SA_SIGINFO;
1578
    sigaction(SIGRTMIN, &act, NULL);
1579
    sigemptyset(&sigset);
1580
    sigaddset(&sigset, SIGRTMIN);
1581
    sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1582
  }
1583
#elif defined(HAVE_SETITIMER)
1584
  {
1585
224k
    struct itimerval t_r;   /* timeout requested */
1586
224k
    int signo;
1587
1588
    // Prevent EINVAL error
1589
224k
    if (seconds < 0 || seconds > 999999999) {
1590
0
      seconds = 0;
1591
0
    }
1592
1593
224k
    if(seconds) {
1594
11
      t_r.it_value.tv_sec = seconds;
1595
11
      t_r.it_value.tv_usec = t_r.it_interval.tv_sec = t_r.it_interval.tv_usec = 0;
1596
1597
# if defined(__CYGWIN__) || defined(__PASE__) || (defined(__aarch64__) && defined(__APPLE__))
1598
      // ITIMER_PROF is broken in Apple Silicon system with MacOS >= 14
1599
      // See https://openradar.appspot.com/radar?id=5583058442911744.
1600
      setitimer(ITIMER_REAL, &t_r, NULL);
1601
    }
1602
    signo = SIGALRM;
1603
# else
1604
11
      setitimer(ITIMER_PROF, &t_r, NULL);
1605
11
    }
1606
224k
    signo = SIGPROF;
1607
224k
# endif
1608
1609
224k
    if (reset_signals) {
1610
224k
# ifdef ZEND_SIGNALS
1611
224k
      zend_signal(signo, zend_timeout_handler);
1612
# else
1613
      sigset_t sigset;
1614
#  ifdef HAVE_SIGACTION
1615
      struct sigaction act;
1616
1617
      act.sa_handler = zend_timeout_handler;
1618
      sigemptyset(&act.sa_mask);
1619
      act.sa_flags = SA_ONSTACK | SA_RESETHAND | SA_NODEFER;
1620
      sigaction(signo, &act, NULL);
1621
#  else
1622
      signal(signo, zend_timeout_handler);
1623
#  endif /* HAVE_SIGACTION */
1624
      sigemptyset(&sigset);
1625
      sigaddset(&sigset, signo);
1626
      sigprocmask(SIG_UNBLOCK, &sigset, NULL);
1627
# endif /* ZEND_SIGNALS */
1628
224k
    }
1629
224k
  }
1630
224k
#endif /* HAVE_SETITIMER */
1631
224k
}
1632
/* }}} */
1633
1634
void zend_set_timeout(zend_long seconds, bool reset_signals) /* {{{ */
1635
224k
{
1636
1637
224k
  EG(timeout_seconds) = seconds;
1638
224k
  zend_set_timeout_ex(seconds, reset_signals);
1639
224k
  zend_atomic_bool_store_ex(&EG(timed_out), false);
1640
224k
}
1641
/* }}} */
1642
1643
void zend_unset_timeout(void) /* {{{ */
1644
224k
{
1645
#ifdef ZEND_WIN32
1646
  if (NULL != tq_timer) {
1647
    if (!DeleteTimerQueueTimer(NULL, tq_timer, INVALID_HANDLE_VALUE)) {
1648
      zend_atomic_bool_store_ex(&EG(timed_out), false);
1649
      tq_timer = NULL;
1650
      zend_error_noreturn(E_ERROR, "Could not delete queued timer");
1651
    }
1652
    tq_timer = NULL;
1653
  }
1654
#elif defined(ZEND_MAX_EXECUTION_TIMERS)
1655
  if (EG(timeout_seconds)) {
1656
    zend_max_execution_timer_settime(0);
1657
  }
1658
#elif defined(HAVE_SETITIMER)
1659
224k
  if (EG(timeout_seconds)) {
1660
22
    struct itimerval no_timeout;
1661
1662
22
    no_timeout.it_value.tv_sec = no_timeout.it_value.tv_usec = no_timeout.it_interval.tv_sec = no_timeout.it_interval.tv_usec = 0;
1663
1664
# if defined(__CYGWIN__) || defined(__PASE__) || (defined(__aarch64__) && defined(__APPLE__))
1665
    setitimer(ITIMER_REAL, &no_timeout, NULL);
1666
# else
1667
22
    setitimer(ITIMER_PROF, &no_timeout, NULL);
1668
22
# endif
1669
22
  }
1670
224k
#endif
1671
224k
  zend_atomic_bool_store_ex(&EG(timed_out), false);
1672
224k
}
1673
/* }}} */
1674
1675
static ZEND_COLD void report_class_fetch_error(const zend_string *class_name, uint32_t fetch_type)
1676
91.3k
{
1677
91.3k
  if (fetch_type & ZEND_FETCH_CLASS_SILENT) {
1678
90.2k
    return;
1679
90.2k
  }
1680
1681
1.13k
  if (EG(exception)) {
1682
228
    if (!(fetch_type & ZEND_FETCH_CLASS_EXCEPTION)) {
1683
0
      zend_exception_uncaught_error("During class fetch");
1684
0
    }
1685
228
    return;
1686
228
  }
1687
1688
902
  if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) {
1689
33
    zend_throw_or_error(fetch_type, NULL, "Interface \"%s\" not found", ZSTR_VAL(class_name));
1690
869
  } else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) {
1691
24
    zend_throw_or_error(fetch_type, NULL, "Trait \"%s\" not found", ZSTR_VAL(class_name));
1692
845
  } else {
1693
845
    zend_throw_or_error(fetch_type, NULL, "Class \"%s\" not found", ZSTR_VAL(class_name));
1694
845
  }
1695
902
}
1696
1697
zend_class_entry *zend_fetch_class(zend_string *class_name, uint32_t fetch_type) /* {{{ */
1698
5.67k
{
1699
5.67k
  zend_class_entry *ce, *scope;
1700
5.67k
  uint32_t fetch_sub_type = fetch_type & ZEND_FETCH_CLASS_MASK;
1701
1702
5.77k
check_fetch_type:
1703
5.77k
  switch (fetch_sub_type) {
1704
2.12k
    case ZEND_FETCH_CLASS_SELF:
1705
2.12k
      scope = zend_get_executed_scope();
1706
2.12k
      if (UNEXPECTED(!scope)) {
1707
51
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"self\" when no class scope is active");
1708
51
      }
1709
2.12k
      return scope;
1710
987
    case ZEND_FETCH_CLASS_PARENT:
1711
987
      scope = zend_get_executed_scope();
1712
987
      if (UNEXPECTED(!scope)) {
1713
12
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when no class scope is active");
1714
12
        return NULL;
1715
12
      }
1716
975
      if (UNEXPECTED(!scope->parent)) {
1717
0
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when current class scope has no parent");
1718
0
      }
1719
975
      return scope->parent;
1720
822
    case ZEND_FETCH_CLASS_STATIC:
1721
822
      ce = zend_get_called_scope(EG(current_execute_data));
1722
822
      if (UNEXPECTED(!ce)) {
1723
35
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"static\" when no class scope is active");
1724
35
        return NULL;
1725
35
      }
1726
787
      return ce;
1727
154
    case ZEND_FETCH_CLASS_AUTO: {
1728
154
        fetch_sub_type = zend_get_class_fetch_type(class_name);
1729
154
        if (UNEXPECTED(fetch_sub_type != ZEND_FETCH_CLASS_DEFAULT)) {
1730
102
          goto check_fetch_type;
1731
102
        }
1732
154
      }
1733
52
      break;
1734
5.77k
  }
1735
1736
1.74k
  ce = zend_lookup_class_ex(class_name, NULL, fetch_type);
1737
1.74k
  if (!ce) {
1738
119
    report_class_fetch_error(class_name, fetch_type);
1739
119
    return NULL;
1740
119
  }
1741
1.62k
  return ce;
1742
1.74k
}
1743
/* }}} */
1744
1745
zend_class_entry *zend_fetch_class_with_scope(
1746
    zend_string *class_name, uint32_t fetch_type, zend_class_entry *scope)
1747
575
{
1748
575
  zend_class_entry *ce;
1749
575
  switch (fetch_type & ZEND_FETCH_CLASS_MASK) {
1750
27
    case ZEND_FETCH_CLASS_SELF:
1751
27
      if (UNEXPECTED(!scope)) {
1752
5
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"self\" when no class scope is active");
1753
5
      }
1754
27
      return scope;
1755
10
    case ZEND_FETCH_CLASS_PARENT:
1756
10
      if (UNEXPECTED(!scope)) {
1757
0
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when no class scope is active");
1758
0
        return NULL;
1759
0
      }
1760
10
      if (UNEXPECTED(!scope->parent)) {
1761
5
        zend_throw_or_error(fetch_type, NULL, "Cannot access \"parent\" when current class scope has no parent");
1762
5
      }
1763
10
      return scope->parent;
1764
538
    case 0:
1765
538
      break;
1766
    /* Other fetch types are not supported by this function. */
1767
575
    EMPTY_SWITCH_DEFAULT_CASE()
1768
575
  }
1769
1770
538
  ce = zend_lookup_class_ex(class_name, NULL, fetch_type);
1771
538
  if (!ce) {
1772
17
    report_class_fetch_error(class_name, fetch_type);
1773
17
    return NULL;
1774
17
  }
1775
521
  return ce;
1776
538
}
1777
1778
zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *key, uint32_t fetch_type) /* {{{ */
1779
352k
{
1780
352k
  zend_class_entry *ce = zend_lookup_class_ex(class_name, key, fetch_type);
1781
352k
  if (!ce) {
1782
91.2k
    report_class_fetch_error(class_name, fetch_type);
1783
91.2k
    return NULL;
1784
91.2k
  }
1785
260k
  return ce;
1786
352k
}
1787
/* }}} */
1788
1789
ZEND_API zend_result zend_delete_global_variable(zend_string *name) /* {{{ */
1790
0
{
1791
0
  return zend_hash_del_ind(&EG(symbol_table), name);
1792
0
}
1793
/* }}} */
1794
1795
ZEND_API zend_array *zend_rebuild_symbol_table(void) /* {{{ */
1796
4.28k
{
1797
4.28k
  zend_execute_data *ex;
1798
4.28k
  zend_array *symbol_table;
1799
1800
  /* Search for last called user function */
1801
4.28k
  ex = EG(current_execute_data);
1802
4.43k
  while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->common.type))) {
1803
146
    ex = ex->prev_execute_data;
1804
146
  }
1805
4.28k
  if (!ex) {
1806
0
    return NULL;
1807
0
  }
1808
4.28k
  if (ZEND_CALL_INFO(ex) & ZEND_CALL_HAS_SYMBOL_TABLE) {
1809
54
    return ex->symbol_table;
1810
54
  }
1811
1812
4.23k
  ZEND_ADD_CALL_FLAG(ex, ZEND_CALL_HAS_SYMBOL_TABLE);
1813
4.23k
  if (EG(symtable_cache_ptr) > EG(symtable_cache)) {
1814
997
    symbol_table = ex->symbol_table = *(--EG(symtable_cache_ptr));
1815
997
    if (!ex->func->op_array.last_var) {
1816
90
      return symbol_table;
1817
90
    }
1818
907
    zend_hash_extend(symbol_table, ex->func->op_array.last_var, 0);
1819
3.23k
  } else {
1820
3.23k
    symbol_table = ex->symbol_table = zend_new_array(ex->func->op_array.last_var);
1821
3.23k
    if (!ex->func->op_array.last_var) {
1822
88
      return symbol_table;
1823
88
    }
1824
3.14k
    zend_hash_real_init_mixed(symbol_table);
1825
    /*printf("Cache miss!  Initialized %x\n", EG(active_symbol_table));*/
1826
3.14k
  }
1827
4.05k
  if (EXPECTED(ex->func->op_array.last_var)) {
1828
4.05k
    zend_string **str = ex->func->op_array.vars;
1829
4.05k
    zend_string **end = str + ex->func->op_array.last_var;
1830
4.05k
    zval *var = ZEND_CALL_VAR_NUM(ex, 0);
1831
1832
18.1k
    do {
1833
18.1k
      _zend_hash_append_ind(symbol_table, *str, var);
1834
18.1k
      str++;
1835
18.1k
      var++;
1836
18.1k
    } while (str != end);
1837
4.05k
  }
1838
4.05k
  return symbol_table;
1839
4.23k
}
1840
/* }}} */
1841
1842
ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ */
1843
115k
{
1844
115k
  const zend_op_array *op_array = &execute_data->func->op_array;
1845
115k
  HashTable *ht = execute_data->symbol_table;
1846
1847
  /* copy real values from symbol table into CV slots and create
1848
     INDIRECT references to CV in symbol table  */
1849
115k
  if (EXPECTED(op_array->last_var)) {
1850
115k
    zend_string **str = op_array->vars;
1851
115k
    zend_string **end = str + op_array->last_var;
1852
115k
    zval *var = EX_VAR_NUM(0);
1853
1854
909k
    do {
1855
909k
      zval *zv = zend_hash_find_known_hash(ht, *str);
1856
1857
909k
      if (zv) {
1858
581k
        if (Z_TYPE_P(zv) == IS_INDIRECT) {
1859
580k
          const zval *val = Z_INDIRECT_P(zv);
1860
1861
580k
          ZVAL_COPY_VALUE(var, val);
1862
580k
        } else {
1863
97
          ZVAL_COPY_VALUE(var, zv);
1864
97
        }
1865
581k
      } else {
1866
328k
        ZVAL_UNDEF(var);
1867
328k
        zv = zend_hash_add_new(ht, *str, var);
1868
328k
      }
1869
909k
      ZVAL_INDIRECT(zv, var);
1870
909k
      str++;
1871
909k
      var++;
1872
909k
    } while (str != end);
1873
115k
  }
1874
115k
}
1875
/* }}} */
1876
1877
ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ */
1878
35.9k
{
1879
35.9k
  const zend_op_array *op_array = &execute_data->func->op_array;
1880
35.9k
  HashTable *ht = execute_data->symbol_table;
1881
1882
  /* copy real values from CV slots into symbol table */
1883
35.9k
  if (EXPECTED(op_array->last_var)) {
1884
35.9k
    zend_string **str = op_array->vars;
1885
35.9k
    zend_string **end = str + op_array->last_var;
1886
35.9k
    zval *var = EX_VAR_NUM(0);
1887
1888
186k
    do {
1889
186k
      if (Z_TYPE_P(var) == IS_UNDEF) {
1890
50.2k
        zend_hash_del(ht, *str);
1891
135k
      } else {
1892
135k
        zend_hash_update(ht, *str, var);
1893
135k
        ZVAL_UNDEF(var);
1894
135k
      }
1895
186k
      str++;
1896
186k
      var++;
1897
186k
    } while (str != end);
1898
35.9k
  }
1899
35.9k
}
1900
/* }}} */
1901
1902
ZEND_API zend_result zend_set_local_var(zend_string *name, zval *value, bool force) /* {{{ */
1903
0
{
1904
0
  zend_execute_data *execute_data = EG(current_execute_data);
1905
1906
0
  while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
1907
0
    execute_data = execute_data->prev_execute_data;
1908
0
  }
1909
1910
0
  if (execute_data) {
1911
0
    if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) {
1912
0
      zend_ulong h = zend_string_hash_val(name);
1913
0
      const zend_op_array *op_array = &execute_data->func->op_array;
1914
1915
0
      if (EXPECTED(op_array->last_var)) {
1916
0
        zend_string **str = op_array->vars;
1917
0
        zend_string **end = str + op_array->last_var;
1918
1919
0
        do {
1920
0
          if (ZSTR_H(*str) == h &&
1921
0
              zend_string_equal_content(*str, name)) {
1922
0
            zval *var = EX_VAR_NUM(str - op_array->vars);
1923
0
            ZVAL_COPY_VALUE(var, value);
1924
0
            return SUCCESS;
1925
0
          }
1926
0
          str++;
1927
0
        } while (str != end);
1928
0
      }
1929
0
      if (force) {
1930
0
        zend_array *symbol_table = zend_rebuild_symbol_table();
1931
0
        if (symbol_table) {
1932
0
          zend_hash_update(symbol_table, name, value);
1933
0
          return SUCCESS;
1934
0
        }
1935
0
      }
1936
0
    } else {
1937
0
      zend_hash_update_ind(execute_data->symbol_table, name, value);
1938
0
      return SUCCESS;
1939
0
    }
1940
0
  }
1941
0
  return FAILURE;
1942
0
}
1943
/* }}} */
1944
1945
ZEND_API zend_result zend_set_local_var_str(const char *name, size_t len, zval *value, bool force) /* {{{ */
1946
0
{
1947
0
  zend_execute_data *execute_data = EG(current_execute_data);
1948
1949
0
  while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
1950
0
    execute_data = execute_data->prev_execute_data;
1951
0
  }
1952
1953
0
  if (execute_data) {
1954
0
    if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) {
1955
0
      zend_ulong h = zend_hash_func(name, len);
1956
0
      const zend_op_array *op_array = &execute_data->func->op_array;
1957
0
      if (EXPECTED(op_array->last_var)) {
1958
0
        zend_string **str = op_array->vars;
1959
0
        zend_string **end = str + op_array->last_var;
1960
1961
0
        do {
1962
0
          if (ZSTR_H(*str) == h &&
1963
0
              zend_string_equals_cstr(*str, name, len)) {
1964
0
            zval *var = EX_VAR_NUM(str - op_array->vars);
1965
0
            zval_ptr_dtor(var);
1966
0
            ZVAL_COPY_VALUE(var, value);
1967
0
            return SUCCESS;
1968
0
          }
1969
0
          str++;
1970
0
        } while (str != end);
1971
0
      }
1972
0
      if (force) {
1973
0
        zend_array *symbol_table = zend_rebuild_symbol_table();
1974
0
        if (symbol_table) {
1975
0
          zend_hash_str_update(symbol_table, name, len, value);
1976
0
          return SUCCESS;
1977
0
        }
1978
0
      }
1979
0
    } else {
1980
0
      zend_hash_str_update_ind(execute_data->symbol_table, name, len, value);
1981
0
      return SUCCESS;
1982
0
    }
1983
0
  }
1984
0
  return FAILURE;
1985
0
}
1986
/* }}} */