Coverage Report

Created: 2026-06-13 07:01

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