Coverage Report

Created: 2025-12-14 06:09

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