Coverage Report

Created: 2026-02-09 07:07

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