Coverage Report

Created: 2025-12-14 06:09

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