1573b4602SAndi Gutmans/*
2573b4602SAndi Gutmans   +----------------------------------------------------------------------+
3573b4602SAndi Gutmans   | Zend Engine                                                          |
4573b4602SAndi Gutmans   +----------------------------------------------------------------------+
5a6519d05SXinchen Hui   | Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
6573b4602SAndi Gutmans   +----------------------------------------------------------------------+
7d863d52aSSebastian Bergmann   | This source file is subject to version 2.00 of the Zend license,     |
8184db665SStanislav Malyshev   | that is bundled with this package in the file LICENSE, and is        |
9f68c7ff2SJames Cox   | available through the world-wide-web at the following url:           |
10d863d52aSSebastian Bergmann   | http://www.zend.com/license/2_00.txt.                                |
11b5b11177SZeev Suraski   | If you did not receive a copy of the Zend license and are unable to  |
12b5b11177SZeev Suraski   | obtain it through the world-wide-web, please send a note to          |
13b5b11177SZeev Suraski   | license@zend.com so we can mail you a copy immediately.              |
14573b4602SAndi Gutmans   +----------------------------------------------------------------------+
159afce019SZeev Suraski   | Authors: Andi Gutmans <andi@php.net>                                 |
169afce019SZeev Suraski   |          Zeev Suraski <zeev@php.net>                                 |
1721eb6807SNikita Popov   |          Nikita Popov <nikic@php.net>                                |
18573b4602SAndi Gutmans   +----------------------------------------------------------------------+
19573b4602SAndi Gutmans*/
20573b4602SAndi Gutmans
214cf9d270Sfoobar#include <zend_language_parser.h>
22573b4602SAndi Gutmans#include "zend.h"
23573b4602SAndi Gutmans#include "zend_compile.h"
24974f406eSSebastian Bergmann#include "zend_constants.h"
25573b4602SAndi Gutmans#include "zend_llist.h"
26573b4602SAndi Gutmans#include "zend_API.h"
2750ea2676SMarcus Boerger#include "zend_exceptions.h"
2849608e06Skrakjoe#include "zend_interfaces.h"
29e30b2aaeSAnatol Belski#include "zend_virtual_cwd.h"
30c3286f32SRui Hirokawa#include "zend_multibyte.h"
31770a4629SXinchen Hui#include "zend_language_scanner.h"
32c343ca4eSNikita Popov#include "zend_inheritance.h"
33ef1b588fSDmitry Stogov#include "zend_vm.h"
34c3286f32SRui Hirokawa
3594dd8372SDmitry Stogov#define SET_NODE(target, src) do { \
3694dd8372SDmitry Stogov		target ## _type = (src)->op_type; \
3794dd8372SDmitry Stogov		if ((src)->op_type == IS_CONST) { \
38bdeb220fSAnatol Belski			target.constant = zend_add_literal(CG(active_op_array), &(src)->u.constant); \
3994dd8372SDmitry Stogov		} else { \
4094dd8372SDmitry Stogov			target = (src)->u.op; \
4194dd8372SDmitry Stogov		} \
4294dd8372SDmitry Stogov	} while (0)
4394dd8372SDmitry Stogov
4494dd8372SDmitry Stogov#define GET_NODE(target, src) do { \
4594dd8372SDmitry Stogov		(target)->op_type = src ## _type; \
4694dd8372SDmitry Stogov		if ((target)->op_type == IS_CONST) { \
4714e29f51SDmitry Stogov			ZVAL_COPY_VALUE(&(target)->u.constant, CT_CONSTANT(src)); \
4894dd8372SDmitry Stogov		} else { \
4994dd8372SDmitry Stogov			(target)->u.op = src; \
5094dd8372SDmitry Stogov		} \
5194dd8372SDmitry Stogov	} while (0)
5294dd8372SDmitry Stogov
53d2607a01SNikita Popov#define FC(member) (CG(file_context).member)
54d2607a01SNikita Popov
5574380105SNikita Popovtypedef struct _zend_loop_var {
5674380105SNikita Popov	zend_uchar opcode;
57a16aa4c4SDmitry Stogov	zend_uchar var_type;
58a16aa4c4SDmitry Stogov	uint32_t   var_num;
59948b7f54SDmitry Stogov	union {
60948b7f54SDmitry Stogov		uint32_t try_catch_offset;
61948b7f54SDmitry Stogov		uint32_t live_range_offset;
62948b7f54SDmitry Stogov	} u;
6374380105SNikita Popov} zend_loop_var;
6474380105SNikita Popov
65ca035f26SDmitry Stogovstatic inline uint32_t zend_alloc_cache_slot(void) {
66c4460dd1SNikita Popov	zend_op_array *op_array = CG(active_op_array);
67ca035f26SDmitry Stogov	uint32_t ret = op_array->cache_size;
685f278e4dSDmitry Stogov	op_array->cache_size += sizeof(void*);
69ca035f26SDmitry Stogov	return ret;
70c4460dd1SNikita Popov}
71c5237d82SDmitry Stogov
72c5237d82SDmitry Stogov#define POLYMORPHIC_CACHE_SLOT_SIZE 2
73c5237d82SDmitry Stogov
74ca035f26SDmitry Stogovstatic inline uint32_t zend_alloc_polymorphic_cache_slot(void) {
75c4460dd1SNikita Popov	zend_op_array *op_array = CG(active_op_array);
76ca035f26SDmitry Stogov	uint32_t ret = op_array->cache_size;
775f278e4dSDmitry Stogov	op_array->cache_size += POLYMORPHIC_CACHE_SLOT_SIZE * sizeof(void*);
78ca035f26SDmitry Stogov	return ret;
79c4460dd1SNikita Popov}
80c5237d82SDmitry Stogov
81bdeb220fSAnatol BelskiZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type);
82bdeb220fSAnatol BelskiZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, char *filename);
83573b4602SAndi Gutmans
84573b4602SAndi Gutmans#ifndef ZTS
85573b4602SAndi GutmansZEND_API zend_compiler_globals compiler_globals;
86573b4602SAndi GutmansZEND_API zend_executor_globals executor_globals;
87573b4602SAndi Gutmans#endif
88573b4602SAndi Gutmans
893a5fa926SDmitry Stogovstatic zend_op *zend_emit_op(znode *result, zend_uchar opcode, znode *op1, znode *op2);
907c738306SDmitry Stogovstatic zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast);
913a5fa926SDmitry Stogov
92c7045174SDmitry Stogovstatic void init_op(zend_op *op)
93c7045174SDmitry Stogov{
94c7045174SDmitry Stogov	MAKE_NOP(op);
95c7045174SDmitry Stogov	op->extended_value = 0;
96c7045174SDmitry Stogov	op->lineno = CG(zend_lineno);
97c7045174SDmitry Stogov}
98c7045174SDmitry Stogov
99c7045174SDmitry Stogovstatic zend_op *get_next_op(zend_op_array *op_array)
100c7045174SDmitry Stogov{
101c7045174SDmitry Stogov	uint32_t next_op_num = op_array->last++;
102c7045174SDmitry Stogov	zend_op *next_op;
103c7045174SDmitry Stogov
104c7045174SDmitry Stogov	if (UNEXPECTED(next_op_num >= CG(context).opcodes_size)) {
105c7045174SDmitry Stogov		CG(context).opcodes_size *= 4;
106c7045174SDmitry Stogov		op_array->opcodes = erealloc(op_array->opcodes, CG(context).opcodes_size * sizeof(zend_op));
107c7045174SDmitry Stogov	}
108c7045174SDmitry Stogov
109c7045174SDmitry Stogov	next_op = &(op_array->opcodes[next_op_num]);
110c7045174SDmitry Stogov
111c7045174SDmitry Stogov	init_op(next_op);
112c7045174SDmitry Stogov
113c7045174SDmitry Stogov	return next_op;
114c7045174SDmitry Stogov}
115c7045174SDmitry Stogov
116c7045174SDmitry Stogovstatic zend_brk_cont_element *get_next_brk_cont_element(void)
117c7045174SDmitry Stogov{
118c7045174SDmitry Stogov	CG(context).last_brk_cont++;
119c7045174SDmitry Stogov	CG(context).brk_cont_array = erealloc(CG(context).brk_cont_array, sizeof(zend_brk_cont_element) * CG(context).last_brk_cont);
120c7045174SDmitry Stogov	return &CG(context).brk_cont_array[CG(context).last_brk_cont-1];
121c7045174SDmitry Stogov}
122c7045174SDmitry Stogov
1230e425121SDmitry Stogovstatic void zend_destroy_property_info_internal(zval *zv) /* {{{ */
124baaa4c90SMarcus Boerger{
1250e425121SDmitry Stogov	zend_property_info *property_info = Z_PTR_P(zv);
1260e425121SDmitry Stogov
1275eb1f92fSDmitry Stogov	zend_string_release_ex(property_info->name, 1);
1282b9b9afaSDmitry Stogov	free(property_info);
129baaa4c90SMarcus Boerger}
13028add3cbSFelipe Pena/* }}} */
131baaa4c90SMarcus Boerger
132bdeb220fSAnatol Belskistatic zend_string *zend_build_runtime_definition_key(zend_string *name, unsigned char *lex_pos) /* {{{ */
13349bd049bSXinchen Hui{
134438b1e3dSNikita Popov	zend_string *result;
135e69f4f6fSAndi Gutmans	char char_pos_buf[32];
13621a29b4bSNikita Popov	size_t char_pos_len = zend_sprintf(char_pos_buf, "%p", lex_pos);
13721a29b4bSNikita Popov	zend_string *filename = CG(active_op_array)->filename;
138a3f77686SZeev Suraski
139e69f4f6fSAndi Gutmans	/* NULL, name length, filename length, last accepting char position length */
1407aa76271SDmitry Stogov	result = zend_string_alloc(1 + ZSTR_LEN(name) + ZSTR_LEN(filename) + char_pos_len, 0);
1417aa76271SDmitry Stogov 	sprintf(ZSTR_VAL(result), "%c%s%s%s", '\0', ZSTR_VAL(name), ZSTR_VAL(filename), char_pos_buf);
142bdeb220fSAnatol Belski	return zend_new_interned_string(result);
143a3f77686SZeev Suraski}
14449bd049bSXinchen Hui/* }}} */
145a3f77686SZeev Suraski
146ab288b01SNikita Popovstatic zend_bool zend_get_unqualified_name(const zend_string *name, const char **result, size_t *result_len) /* {{{ */
147ab288b01SNikita Popov{
1487aa76271SDmitry Stogov	const char *ns_separator = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
149ab288b01SNikita Popov	if (ns_separator != NULL) {
150ab288b01SNikita Popov		*result = ns_separator + 1;
1517aa76271SDmitry Stogov		*result_len = ZSTR_VAL(name) + ZSTR_LEN(name) - *result;
152ab288b01SNikita Popov		return 1;
153ab288b01SNikita Popov	}
154ab288b01SNikita Popov
155ab288b01SNikita Popov	return 0;
156ab288b01SNikita Popov}
157ab288b01SNikita Popov/* }}} */
158ab288b01SNikita Popov
15953a40386SNikita Popovstruct reserved_class_name {
16053a40386SNikita Popov	const char *name;
16153a40386SNikita Popov	size_t len;
16253a40386SNikita Popov};
16353a40386SNikita Popovstatic const struct reserved_class_name reserved_class_names[] = {
16453a40386SNikita Popov	{ZEND_STRL("bool")},
16553a40386SNikita Popov	{ZEND_STRL("false")},
16653a40386SNikita Popov	{ZEND_STRL("float")},
16753a40386SNikita Popov	{ZEND_STRL("int")},
16853a40386SNikita Popov	{ZEND_STRL("null")},
16953a40386SNikita Popov	{ZEND_STRL("parent")},
17053a40386SNikita Popov	{ZEND_STRL("self")},
17153a40386SNikita Popov	{ZEND_STRL("static")},
17253a40386SNikita Popov	{ZEND_STRL("string")},
17353a40386SNikita Popov	{ZEND_STRL("true")},
174366ba413SAndrea Faulds	{ZEND_STRL("void")},
17572692e9aSAaron Piotrowski	{ZEND_STRL("iterable")},
1768e10c9d3SMichał Brzuchalski	{ZEND_STRL("object")},
17753a40386SNikita Popov	{NULL, 0}
17853a40386SNikita Popov};
17953a40386SNikita Popov
18053a40386SNikita Popovstatic zend_bool zend_is_reserved_class_name(const zend_string *name) /* {{{ */
18153a40386SNikita Popov{
18253a40386SNikita Popov	const struct reserved_class_name *reserved = reserved_class_names;
18353a40386SNikita Popov
1847aa76271SDmitry Stogov	const char *uqname = ZSTR_VAL(name);
1857aa76271SDmitry Stogov	size_t uqname_len = ZSTR_LEN(name);
18653a40386SNikita Popov	zend_get_unqualified_name(name, &uqname, &uqname_len);
18753a40386SNikita Popov
18853a40386SNikita Popov	for (; reserved->name; ++reserved) {
18953a40386SNikita Popov		if (uqname_len == reserved->len
19053a40386SNikita Popov			&& zend_binary_strcasecmp(uqname, uqname_len, reserved->name, reserved->len) == 0
19153a40386SNikita Popov		) {
19253a40386SNikita Popov			return 1;
19353a40386SNikita Popov		}
19453a40386SNikita Popov	}
19553a40386SNikita Popov
19653a40386SNikita Popov	return 0;
19753a40386SNikita Popov}
19853a40386SNikita Popov/* }}} */
19953a40386SNikita Popov
20044156b31SAndrea Fauldsvoid zend_assert_valid_class_name(const zend_string *name) /* {{{ */
20153a40386SNikita Popov{
20253a40386SNikita Popov	if (zend_is_reserved_class_name(name)) {
20353a40386SNikita Popov		zend_error_noreturn(E_COMPILE_ERROR,
2047aa76271SDmitry Stogov			"Cannot use '%s' as class name as it is reserved", ZSTR_VAL(name));
20553a40386SNikita Popov	}
20653a40386SNikita Popov}
20753a40386SNikita Popov/* }}} */
20853a40386SNikita Popov
209339283c5SLevi Morrisontypedef struct _builtin_type_info {
210c7719ab4SAndrea Faulds	const char* name;
211c7719ab4SAndrea Faulds	const size_t name_len;
212c7719ab4SAndrea Faulds	const zend_uchar type;
213339283c5SLevi Morrison} builtin_type_info;
214c7719ab4SAndrea Faulds
215339283c5SLevi Morrisonstatic const builtin_type_info builtin_types[] = {
216dae37661SAndrea Faulds	{ZEND_STRL("int"), IS_LONG},
217dae37661SAndrea Faulds	{ZEND_STRL("float"), IS_DOUBLE},
218dae37661SAndrea Faulds	{ZEND_STRL("string"), IS_STRING},
219dae37661SAndrea Faulds	{ZEND_STRL("bool"), _IS_BOOL},
220366ba413SAndrea Faulds	{ZEND_STRL("void"), IS_VOID},
22172692e9aSAaron Piotrowski	{ZEND_STRL("iterable"), IS_ITERABLE},
2228e10c9d3SMichał Brzuchalski	{ZEND_STRL("object"), IS_OBJECT},
223c7719ab4SAndrea Faulds	{NULL, 0, IS_UNDEF}
224c7719ab4SAndrea Faulds};
225c7719ab4SAndrea Faulds
226e13803d1SLevi Morrison
227e13803d1SLevi Morrisonstatic zend_always_inline zend_uchar zend_lookup_builtin_type_by_name(const zend_string *name) /* {{{ */
228c7719ab4SAndrea Faulds{
229339283c5SLevi Morrison	const builtin_type_info *info = &builtin_types[0];
230aaf0c8b5SAnthony Ferrara
23153a40386SNikita Popov	for (; info->name; ++info) {
2327aa76271SDmitry Stogov		if (ZSTR_LEN(name) == info->name_len
2337aa76271SDmitry Stogov			&& zend_binary_strcasecmp(ZSTR_VAL(name), ZSTR_LEN(name), info->name, info->name_len) == 0
23453a40386SNikita Popov		) {
235e13803d1SLevi Morrison			return info->type;
236c7719ab4SAndrea Faulds		}
237c7719ab4SAndrea Faulds	}
238c7719ab4SAndrea Faulds
239e13803d1SLevi Morrison	return 0;
240c7719ab4SAndrea Faulds}
241c7719ab4SAndrea Faulds/* }}} */
242c7719ab4SAndrea Faulds
243c7719ab4SAndrea Faulds
2440381c1b7SNikita Popovvoid zend_oparray_context_begin(zend_oparray_context *prev_context) /* {{{ */
245f2df6a4aSDmitry Stogov{
2460381c1b7SNikita Popov	*prev_context = CG(context);
24759848e3fSNikita Popov	CG(context).opcodes_size = INITIAL_OP_ARRAY_SIZE;
248f2df6a4aSDmitry Stogov	CG(context).vars_size = 0;
249f2df6a4aSDmitry Stogov	CG(context).literals_size = 0;
250f2df6a4aSDmitry Stogov	CG(context).backpatch_count = 0;
251216ef321SDmitry Stogov	CG(context).fast_call_var = -1;
2522ae21abdSDmitry Stogov	CG(context).try_catch_offset = -1;
253baf97b1fSDmitry Stogov	CG(context).current_brk_cont = -1;
254baf97b1fSDmitry Stogov	CG(context).last_brk_cont = 0;
255baf97b1fSDmitry Stogov	CG(context).brk_cont_array = NULL;
256f2df6a4aSDmitry Stogov	CG(context).labels = NULL;
257f2df6a4aSDmitry Stogov}
258f2df6a4aSDmitry Stogov/* }}} */
259fafbf6d8SZeev Suraski
2600381c1b7SNikita Popovvoid zend_oparray_context_end(zend_oparray_context *prev_context) /* {{{ */
2610381c1b7SNikita Popov{
262baf97b1fSDmitry Stogov	if (CG(context).brk_cont_array) {
263baf97b1fSDmitry Stogov		efree(CG(context).brk_cont_array);
264baf97b1fSDmitry Stogov		CG(context).brk_cont_array = NULL;
265baf97b1fSDmitry Stogov	}
2660381c1b7SNikita Popov	if (CG(context).labels) {
2670381c1b7SNikita Popov		zend_hash_destroy(CG(context).labels);
2680381c1b7SNikita Popov		FREE_HASHTABLE(CG(context).labels);
2690381c1b7SNikita Popov		CG(context).labels = NULL;
2700381c1b7SNikita Popov	}
2710381c1b7SNikita Popov	CG(context) = *prev_context;
2720381c1b7SNikita Popov}
2730381c1b7SNikita Popov/* }}} */
2740381c1b7SNikita Popov
2750381c1b7SNikita Popovstatic void zend_reset_import_tables(void) /* {{{ */
2760381c1b7SNikita Popov{
277d2607a01SNikita Popov	if (FC(imports)) {
278d2607a01SNikita Popov		zend_hash_destroy(FC(imports));
279d2607a01SNikita Popov		efree(FC(imports));
280d2607a01SNikita Popov		FC(imports) = NULL;
2810381c1b7SNikita Popov	}
2820381c1b7SNikita Popov
283d2607a01SNikita Popov	if (FC(imports_function)) {
284d2607a01SNikita Popov		zend_hash_destroy(FC(imports_function));
285d2607a01SNikita Popov		efree(FC(imports_function));
286d2607a01SNikita Popov		FC(imports_function) = NULL;
2870381c1b7SNikita Popov	}
2880381c1b7SNikita Popov
289d2607a01SNikita Popov	if (FC(imports_const)) {
290d2607a01SNikita Popov		zend_hash_destroy(FC(imports_const));
291d2607a01SNikita Popov		efree(FC(imports_const));
292d2607a01SNikita Popov		FC(imports_const) = NULL;
293d2607a01SNikita Popov	}
294d2607a01SNikita Popov}
295d2607a01SNikita Popov/* }}} */
296d2607a01SNikita Popov
297d2607a01SNikita Popovstatic void zend_end_namespace(void) /* {{{ */ {
298d2607a01SNikita Popov	FC(in_namespace) = 0;
299d2607a01SNikita Popov	zend_reset_import_tables();
300d2607a01SNikita Popov	if (FC(current_namespace)) {
3015eb1f92fSDmitry Stogov		zend_string_release_ex(FC(current_namespace), 0);
302d2607a01SNikita Popov		FC(current_namespace) = NULL;
3030381c1b7SNikita Popov	}
3040381c1b7SNikita Popov}
3050381c1b7SNikita Popov/* }}} */
3060381c1b7SNikita Popov
3070381c1b7SNikita Popovvoid zend_file_context_begin(zend_file_context *prev_context) /* {{{ */
3080381c1b7SNikita Popov{
3090381c1b7SNikita Popov	*prev_context = CG(file_context);
310d2607a01SNikita Popov	FC(imports) = NULL;
311d2607a01SNikita Popov	FC(imports_function) = NULL;
312d2607a01SNikita Popov	FC(imports_const) = NULL;
313d2607a01SNikita Popov	FC(current_namespace) = NULL;
314d2607a01SNikita Popov	FC(in_namespace) = 0;
315d2607a01SNikita Popov	FC(has_bracketed_namespaces) = 0;
316d2607a01SNikita Popov	FC(declarables).ticks = 0;
3178754b191SNikita Popov	zend_hash_init(&FC(seen_symbols), 8, NULL, NULL, 0);
3180381c1b7SNikita Popov}
3190381c1b7SNikita Popov/* }}} */
3200381c1b7SNikita Popov
3210381c1b7SNikita Popovvoid zend_file_context_end(zend_file_context *prev_context) /* {{{ */
3220381c1b7SNikita Popov{
323d2607a01SNikita Popov	zend_end_namespace();
3248754b191SNikita Popov	zend_hash_destroy(&FC(seen_symbols));
3250381c1b7SNikita Popov	CG(file_context) = *prev_context;
3260381c1b7SNikita Popov}
3270381c1b7SNikita Popov/* }}} */
3280381c1b7SNikita Popov
329bdeb220fSAnatol Belskivoid zend_init_compiler_data_structures(void) /* {{{ */
330573b4602SAndi Gutmans{
33174380105SNikita Popov	zend_stack_init(&CG(loop_var_stack), sizeof(zend_loop_var));
332c4460dd1SNikita Popov	zend_stack_init(&CG(delayed_oplines_stack), sizeof(zend_op));
333573b4602SAndi Gutmans	CG(active_class_entry) = NULL;
334b6197bcfSZeev Suraski	CG(in_compilation) = 0;
335cf05f34cSZeev Suraski	CG(start_lineno) = 0;
336c3286f32SRui Hirokawa
337c8faf7e1SFelipe Pena	CG(encoding_declared) = 0;
338af316021SMarcus Boerger}
33928add3cbSFelipe Pena/* }}} */
340af316021SMarcus Boerger
3418754b191SNikita Popovstatic void zend_register_seen_symbol(zend_string *name, uint32_t kind) {
3428754b191SNikita Popov	zval *zv = zend_hash_find(&FC(seen_symbols), name);
3438754b191SNikita Popov	if (zv) {
3448754b191SNikita Popov		Z_LVAL_P(zv) |= kind;
3458754b191SNikita Popov	} else {
3468754b191SNikita Popov		zval tmp;
3478754b191SNikita Popov		ZVAL_LONG(&tmp, kind);
3488754b191SNikita Popov		zend_hash_add_new(&FC(seen_symbols), name, &tmp);
3498754b191SNikita Popov	}
3508754b191SNikita Popov}
3518754b191SNikita Popov
3528754b191SNikita Popovstatic zend_bool zend_have_seen_symbol(zend_string *name, uint32_t kind) {
3538754b191SNikita Popov	zval *zv = zend_hash_find(&FC(seen_symbols), name);
3548754b191SNikita Popov	return zv && (Z_LVAL_P(zv) & kind) != 0;
3558754b191SNikita Popov}
3568754b191SNikita Popov
35728add3cbSFelipe PenaZEND_API void file_handle_dtor(zend_file_handle *fh) /* {{{ */
358af316021SMarcus Boerger{
359c00424e4SAnatol Belski
360bdeb220fSAnatol Belski	zend_file_handle_dtor(fh);
361bda9c83aSZeev Suraski}
36228add3cbSFelipe Pena/* }}} */
363bda9c83aSZeev Suraski
364bdeb220fSAnatol Belskivoid init_compiler(void) /* {{{ */
365bda9c83aSZeev Suraski{
366e1b18e59SDmitry Stogov	CG(arena) = zend_arena_create(64 * 1024);
367ab5a8b2aSDmitry Stogov	CG(active_op_array) = NULL;
36865585b3aSDmitry Stogov	memset(&CG(context), 0, sizeof(CG(context)));
369bdeb220fSAnatol Belski	zend_init_compiler_data_structures();
370bdeb220fSAnatol Belski	zend_init_rsrc_list();
3714ddeeb49SXinchen Hui	zend_hash_init(&CG(filenames_table), 8, NULL, ZVAL_PTR_DTOR, 0);
372af316021SMarcus Boerger	zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0);
373bda9c83aSZeev Suraski	CG(unclean_shutdown) = 0;
374573b4602SAndi Gutmans}
37528add3cbSFelipe Pena/* }}} */
376573b4602SAndi Gutmans
377bdeb220fSAnatol Belskivoid shutdown_compiler(void) /* {{{ */
378573b4602SAndi Gutmans{
379549e8c49SDmitry Stogov	zend_stack_destroy(&CG(loop_var_stack));
380c4460dd1SNikita Popov	zend_stack_destroy(&CG(delayed_oplines_stack));
381c34f41b7SZeev Suraski	zend_hash_destroy(&CG(filenames_table));
382e1b18e59SDmitry Stogov	zend_arena_destroy(CG(arena));
383573b4602SAndi Gutmans}
38428add3cbSFelipe Pena/* }}} */
385573b4602SAndi Gutmans
386bdeb220fSAnatol BelskiZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filename) /* {{{ */
387573b4602SAndi Gutmans{
3884ddeeb49SXinchen Hui	zval *p, rv;
389573b4602SAndi Gutmans
3904ddeeb49SXinchen Hui	if ((p = zend_hash_find(&CG(filenames_table), new_compiled_filename))) {
3914ddeeb49SXinchen Hui		ZEND_ASSERT(Z_TYPE_P(p) == IS_STRING);
3924ddeeb49SXinchen Hui		CG(compiled_filename) = Z_STR_P(p);
3934ddeeb49SXinchen Hui		return Z_STR_P(p);
394c34f41b7SZeev Suraski	}
3954ddeeb49SXinchen Hui
3965dbdc382SDmitry Stogov	new_compiled_filename = zend_new_interned_string(zend_string_copy(new_compiled_filename));
3975dbdc382SDmitry Stogov	ZVAL_STR(&rv, new_compiled_filename);
3985dbdc382SDmitry Stogov	zend_hash_add_new(&CG(filenames_table), new_compiled_filename, &rv);
3994ddeeb49SXinchen Hui
4004ddeeb49SXinchen Hui	CG(compiled_filename) = new_compiled_filename;
4014ddeeb49SXinchen Hui	return new_compiled_filename;
402573b4602SAndi Gutmans}
40328add3cbSFelipe Pena/* }}} */
404573b4602SAndi Gutmans
405bdeb220fSAnatol BelskiZEND_API void zend_restore_compiled_filename(zend_string *original_compiled_filename) /* {{{ */
406573b4602SAndi Gutmans{
407573b4602SAndi Gutmans	CG(compiled_filename) = original_compiled_filename;
408573b4602SAndi Gutmans}
40928add3cbSFelipe Pena/* }}} */
410573b4602SAndi Gutmans
411bdeb220fSAnatol BelskiZEND_API zend_string *zend_get_compiled_filename(void) /* {{{ */
412b6197bcfSZeev Suraski{
413b6197bcfSZeev Suraski	return CG(compiled_filename);
414b6197bcfSZeev Suraski}
41528add3cbSFelipe Pena/* }}} */
416b6197bcfSZeev Suraski
417bdeb220fSAnatol BelskiZEND_API int zend_get_compiled_lineno(void) /* {{{ */
418b6197bcfSZeev Suraski{
419b6197bcfSZeev Suraski	return CG(zend_lineno);
420b6197bcfSZeev Suraski}
42128add3cbSFelipe Pena/* }}} */
422b6197bcfSZeev Suraski
423bdeb220fSAnatol BelskiZEND_API zend_bool zend_is_compiling(void) /* {{{ */
424573b4602SAndi Gutmans{
425b6197bcfSZeev Suraski	return CG(in_compilation);
426573b4602SAndi Gutmans}
42728add3cbSFelipe Pena/* }}} */
428573b4602SAndi Gutmans
4296f9f0bf2SAnatol Belskistatic uint32_t get_temporary_variable(zend_op_array *op_array) /* {{{ */
430573b4602SAndi Gutmans{
4316f9f0bf2SAnatol Belski	return (uint32_t)op_array->T++;
432573b4602SAndi Gutmans}
43328add3cbSFelipe Pena/* }}} */
434573b4602SAndi Gutmans
435d481d495SDmitry Stogovstatic int lookup_cv(zend_op_array *op_array, zend_string *name) /* {{{ */{
436db507dd1SAndi Gutmans	int i = 0;
437c3e3c98eSAnatol Belski	zend_ulong hash_value = zend_string_hash_val(name);
438db507dd1SAndi Gutmans
439db507dd1SAndi Gutmans	while (i < op_array->last_var) {
4407aa76271SDmitry Stogov		if (ZSTR_VAL(op_array->vars[i]) == ZSTR_VAL(name) ||
4417aa76271SDmitry Stogov		    (ZSTR_H(op_array->vars[i]) == hash_value &&
44274c84cd7SDmitry Stogov		     zend_string_equal_content(op_array->vars[i], name))) {
443dcfe5877SDmitry Stogov			return (int)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, i);
444db507dd1SAndi Gutmans		}
445db507dd1SAndi Gutmans		i++;
446db507dd1SAndi Gutmans	}
447db507dd1SAndi Gutmans	i = op_array->last_var;
448db507dd1SAndi Gutmans	op_array->last_var++;
449f2df6a4aSDmitry Stogov	if (op_array->last_var > CG(context).vars_size) {
450f2df6a4aSDmitry Stogov		CG(context).vars_size += 16; /* FIXME */
451f4cfaf36SDmitry Stogov		op_array->vars = erealloc(op_array->vars, CG(context).vars_size * sizeof(zend_string*));
452db507dd1SAndi Gutmans	}
453f4cfaf36SDmitry Stogov
454d481d495SDmitry Stogov	op_array->vars[i] = zend_string_copy(name);
455dcfe5877SDmitry Stogov	return (int)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, i);
456db507dd1SAndi Gutmans}
45728add3cbSFelipe Pena/* }}} */
458db507dd1SAndi Gutmans
45994dd8372SDmitry Stogovvoid zend_del_literal(zend_op_array *op_array, int n) /* {{{ */
46094dd8372SDmitry Stogov{
4614a475a49SDmitry Stogov	zval_ptr_dtor_nogc(CT_CONSTANT_EX(op_array, n));
46294dd8372SDmitry Stogov	if (n + 1 == op_array->last_literal) {
46394dd8372SDmitry Stogov		op_array->last_literal--;
46494dd8372SDmitry Stogov	} else {
46514e29f51SDmitry Stogov		ZVAL_UNDEF(CT_CONSTANT_EX(op_array, n));
46694dd8372SDmitry Stogov	}
46794dd8372SDmitry Stogov}
46894dd8372SDmitry Stogov/* }}} */
469573b4602SAndi Gutmans
470d481d495SDmitry Stogovstatic inline zend_string *zval_make_interned_string(zval *zv) /* {{{ */
4715dbdc382SDmitry Stogov{
4725dbdc382SDmitry Stogov	ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
4735dbdc382SDmitry Stogov	Z_STR_P(zv) = zend_new_interned_string(Z_STR_P(zv));
4745dbdc382SDmitry Stogov	if (ZSTR_IS_INTERNED(Z_STR_P(zv))) {
4755c77bac9SDmitry Stogov		Z_TYPE_FLAGS_P(zv) = 0;
4765dbdc382SDmitry Stogov	}
477d481d495SDmitry Stogov	return Z_STR_P(zv);
4785dbdc382SDmitry Stogov}
4795dbdc382SDmitry Stogov
480f2ed1242SStefan Marr/* Common part of zend_add_literal and zend_append_individual_literal */
481bdeb220fSAnatol Belskistatic inline void zend_insert_literal(zend_op_array *op_array, zval *zv, int literal_position) /* {{{ */
482f2ed1242SStefan Marr{
48393aabf15SNikita Popov	zval *lit = CT_CONSTANT_EX(op_array, literal_position);
484ef5ea487SDmitry Stogov	if (Z_TYPE_P(zv) == IS_STRING) {
4855dbdc382SDmitry Stogov		zval_make_interned_string(zv);
486f2ed1242SStefan Marr	}
48793aabf15SNikita Popov	ZVAL_COPY_VALUE(lit, zv);
48893aabf15SNikita Popov	Z_EXTRA_P(lit) = 0;
489f2ed1242SStefan Marr}
490f2ed1242SStefan Marr/* }}} */
491f2ed1242SStefan Marr
492f2ed1242SStefan Marr/* Is used while compiling a function, using the context to keep track
493f2ed1242SStefan Marr   of an approximate size to avoid to relocate to often.
494f2ed1242SStefan Marr   Literals are truncated to actual size in the second compiler pass (pass_two()). */
495bdeb220fSAnatol Belskiint zend_add_literal(zend_op_array *op_array, zval *zv) /* {{{ */
49694dd8372SDmitry Stogov{
49794dd8372SDmitry Stogov	int i = op_array->last_literal;
49894dd8372SDmitry Stogov	op_array->last_literal++;
499f2df6a4aSDmitry Stogov	if (i >= CG(context).literals_size) {
500f2ed1242SStefan Marr		while (i >= CG(context).literals_size) {
501f2ed1242SStefan Marr			CG(context).literals_size += 16; /* FIXME */
502f2ed1242SStefan Marr		}
503e96073b1SDmitry Stogov		op_array->literals = (zval*)erealloc(op_array->literals, CG(context).literals_size * sizeof(zval));
50494dd8372SDmitry Stogov	}
505bdeb220fSAnatol Belski	zend_insert_literal(op_array, zv, i);
506f2ed1242SStefan Marr	return i;
507f2ed1242SStefan Marr}
508f2ed1242SStefan Marr/* }}} */
509dd5c478bSDmitry Stogov
510bdeb220fSAnatol Belskistatic inline int zend_add_literal_string(zend_op_array *op_array, zend_string **str) /* {{{ */
5117a2fd62cSDmitry Stogov{
5127a2fd62cSDmitry Stogov	int ret;
513182ddfeaSNikita Popov	zval zv;
514182ddfeaSNikita Popov	ZVAL_STR(&zv, *str);
515bdeb220fSAnatol Belski	ret = zend_add_literal(op_array, &zv);
516182ddfeaSNikita Popov	*str = Z_STR(zv);
517182ddfeaSNikita Popov	return ret;
518182ddfeaSNikita Popov}
5195f80df0dSXinchen Hui/* }}} */
5207a2fd62cSDmitry Stogov
521bdeb220fSAnatol Belskistatic int zend_add_func_name_literal(zend_op_array *op_array, zend_string *name) /* {{{ */
522182ddfeaSNikita Popov{
523ab288b01SNikita Popov	/* Original name */
524bdeb220fSAnatol Belski	int ret = zend_add_literal_string(op_array, &name);
525184db665SStanislav Malyshev
526ab288b01SNikita Popov	/* Lowercased name */
527c42ac095SDmitry Stogov	zend_string *lc_name = zend_string_tolower(name);
528bdeb220fSAnatol Belski	zend_add_literal_string(op_array, &lc_name);
5297a2fd62cSDmitry Stogov
5307a2fd62cSDmitry Stogov	return ret;
5317a2fd62cSDmitry Stogov}
5327a2fd62cSDmitry Stogov/* }}} */
5337a2fd62cSDmitry Stogov
534bdeb220fSAnatol Belskistatic int zend_add_ns_func_name_literal(zend_op_array *op_array, zend_string *name) /* {{{ */
535c58b131eSDmitry Stogov{
536ab288b01SNikita Popov	const char *unqualified_name;
537ab288b01SNikita Popov	size_t unqualified_name_len;
538c58b131eSDmitry Stogov
539ab288b01SNikita Popov	/* Original name */
540bdeb220fSAnatol Belski	int ret = zend_add_literal_string(op_array, &name);
541c58b131eSDmitry Stogov
542ab288b01SNikita Popov	/* Lowercased name */
543c42ac095SDmitry Stogov	zend_string *lc_name = zend_string_tolower(name);
544bdeb220fSAnatol Belski	zend_add_literal_string(op_array, &lc_name);
5456b385ebcSDanack
546ab288b01SNikita Popov	/* Lowercased unqualfied name */
547ab288b01SNikita Popov	if (zend_get_unqualified_name(name, &unqualified_name, &unqualified_name_len)) {
548ab288b01SNikita Popov		lc_name = zend_string_alloc(unqualified_name_len, 0);
5497aa76271SDmitry Stogov		zend_str_tolower_copy(ZSTR_VAL(lc_name), unqualified_name, unqualified_name_len);
550bdeb220fSAnatol Belski		zend_add_literal_string(op_array, &lc_name);
5516b385ebcSDanack	}
552c58b131eSDmitry Stogov
553c58b131eSDmitry Stogov	return ret;
554c58b131eSDmitry Stogov}
555c58b131eSDmitry Stogov/* }}} */
5567a2fd62cSDmitry Stogov
557bdeb220fSAnatol Belskistatic int zend_add_class_name_literal(zend_op_array *op_array, zend_string *name) /* {{{ */
5584571271dSNikita Popov{
559ab288b01SNikita Popov	/* Original name */
560bdeb220fSAnatol Belski	int ret = zend_add_literal_string(op_array, &name);
56186f1004cSNikita Popov
562ab288b01SNikita Popov	/* Lowercased name */
563c42ac095SDmitry Stogov	zend_string *lc_name = zend_string_tolower(name);
564bdeb220fSAnatol Belski	zend_add_literal_string(op_array, &lc_name);
5657a2fd62cSDmitry Stogov
5667a2fd62cSDmitry Stogov	return ret;
5677a2fd62cSDmitry Stogov}
5687a2fd62cSDmitry Stogov/* }}} */
5697a2fd62cSDmitry Stogov
570bdeb220fSAnatol Belskistatic int zend_add_const_name_literal(zend_op_array *op_array, zend_string *name, zend_bool unqualified) /* {{{ */
571e87d7200SDmitry Stogov{
572f4cfaf36SDmitry Stogov	zend_string *tmp_name;
573e87d7200SDmitry Stogov
574bdeb220fSAnatol Belski	int ret = zend_add_literal_string(op_array, &name);
575e87d7200SDmitry Stogov
5767aa76271SDmitry Stogov	size_t ns_len = 0, after_ns_len = ZSTR_LEN(name);
5777aa76271SDmitry Stogov	const char *after_ns = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
578182ddfeaSNikita Popov	if (after_ns) {
579182ddfeaSNikita Popov		after_ns += 1;
5807aa76271SDmitry Stogov		ns_len = after_ns - ZSTR_VAL(name) - 1;
5817aa76271SDmitry Stogov		after_ns_len = ZSTR_LEN(name) - ns_len - 1;
582e87d7200SDmitry Stogov
583e87d7200SDmitry Stogov		/* lowercased namespace name & original constant name */
5847aa76271SDmitry Stogov		tmp_name = zend_string_init(ZSTR_VAL(name), ZSTR_LEN(name), 0);
5857aa76271SDmitry Stogov		zend_str_tolower(ZSTR_VAL(tmp_name), ns_len);
586bdeb220fSAnatol Belski		zend_add_literal_string(op_array, &tmp_name);
587e87d7200SDmitry Stogov
588e87d7200SDmitry Stogov		/* lowercased namespace name & lowercased constant name */
589c42ac095SDmitry Stogov		tmp_name = zend_string_tolower(name);
590bdeb220fSAnatol Belski		zend_add_literal_string(op_array, &tmp_name);
591e87d7200SDmitry Stogov
592e87d7200SDmitry Stogov		if (!unqualified) {
593e87d7200SDmitry Stogov			return ret;
594e87d7200SDmitry Stogov		}
595182ddfeaSNikita Popov	} else {
5967aa76271SDmitry Stogov		after_ns = ZSTR_VAL(name);
597e87d7200SDmitry Stogov	}
598e87d7200SDmitry Stogov
599182ddfeaSNikita Popov	/* original unqualified constant name */
600182ddfeaSNikita Popov	tmp_name = zend_string_init(after_ns, after_ns_len, 0);
601bdeb220fSAnatol Belski	zend_add_literal_string(op_array, &tmp_name);
602e87d7200SDmitry Stogov
603182ddfeaSNikita Popov	/* lowercased unqualified constant name */
604182ddfeaSNikita Popov	tmp_name = zend_string_alloc(after_ns_len, 0);
6057aa76271SDmitry Stogov	zend_str_tolower_copy(ZSTR_VAL(tmp_name), after_ns, after_ns_len);
606bdeb220fSAnatol Belski	zend_add_literal_string(op_array, &tmp_name);
607e87d7200SDmitry Stogov
608e87d7200SDmitry Stogov	return ret;
609e87d7200SDmitry Stogov}
610e87d7200SDmitry Stogov/* }}} */
611e87d7200SDmitry Stogov
612f4cfaf36SDmitry Stogov#define LITERAL_STR(op, str) do { \
61394dd8372SDmitry Stogov		zval _c; \
614f4cfaf36SDmitry Stogov		ZVAL_STR(&_c, str); \
615bdeb220fSAnatol Belski		op.constant = zend_add_literal(CG(active_op_array), &_c); \
616f4cfaf36SDmitry Stogov	} while (0)
617f4cfaf36SDmitry Stogov
61811075938SMárcio Almadavoid zend_stop_lexing(void)
61911075938SMárcio Almada{
620f4d1af79SNikita Popov	if (LANG_SCNG(on_event)) {
621f4d1af79SNikita Popov		LANG_SCNG(on_event)(ON_STOP, END, 0, LANG_SCNG(on_event_context));
622f4d1af79SNikita Popov	}
62311075938SMárcio Almada
6242653b8b5SNikita Popov	LANG_SCNG(yy_cursor) = LANG_SCNG(yy_limit);
6252653b8b5SNikita Popov}
6267a2fd62cSDmitry Stogov
627948b7f54SDmitry Stogovstatic uint32_t zend_start_live_range(zend_op_array *op_array, uint32_t start) /* {{{ */
628baf97b1fSDmitry Stogov{
629baf97b1fSDmitry Stogov	zend_live_range *range;
630baf97b1fSDmitry Stogov
631948b7f54SDmitry Stogov	op_array->last_live_range++;
632948b7f54SDmitry Stogov	op_array->live_range = erealloc(op_array->live_range, sizeof(zend_live_range) * op_array->last_live_range);
633948b7f54SDmitry Stogov	range = op_array->live_range + op_array->last_live_range - 1;
634948b7f54SDmitry Stogov	range->start = start;
635948b7f54SDmitry Stogov	return op_array->last_live_range - 1;
636948b7f54SDmitry Stogov}
637948b7f54SDmitry Stogov/* }}} */
638948b7f54SDmitry Stogov
6393a5fa926SDmitry Stogovstatic void zend_end_live_range(zend_op_array *op_array, uint32_t offset, uint32_t end, uint32_t kind, uint32_t var) /* {{{ */
640948b7f54SDmitry Stogov{
641948b7f54SDmitry Stogov	zend_live_range *range = op_array->live_range + offset;
642948b7f54SDmitry Stogov
643ebb99a1aSDmitry Stogov	if (range->start == end && offset == (uint32_t)op_array->last_live_range - 1) {
644948b7f54SDmitry Stogov		op_array->last_live_range--;
645948b7f54SDmitry Stogov	} else {
646baf97b1fSDmitry Stogov		range->end = end;
6473a5fa926SDmitry Stogov		range->var = (var * sizeof(zval)) | kind;
648baf97b1fSDmitry Stogov	}
649baf97b1fSDmitry Stogov}
650baf97b1fSDmitry Stogov/* }}} */
651baf97b1fSDmitry Stogov
65204e3523bSNikita Popovstatic inline void zend_begin_loop(
65304e3523bSNikita Popov		zend_uchar free_opcode, const znode *loop_var, zend_bool is_switch) /* {{{ */
6542188f26cSDmitry Stogov{
655573b4602SAndi Gutmans	zend_brk_cont_element *brk_cont_element;
6563cbe3903SNikita Popov	int parent = CG(context).current_brk_cont;
65774380105SNikita Popov	zend_loop_var info = {0};
6582188f26cSDmitry Stogov
659baf97b1fSDmitry Stogov	CG(context).current_brk_cont = CG(context).last_brk_cont;
660baf97b1fSDmitry Stogov	brk_cont_element = get_next_brk_cont_element();
661573b4602SAndi Gutmans	brk_cont_element->parent = parent;
66204e3523bSNikita Popov	brk_cont_element->is_switch = is_switch;
663549e8c49SDmitry Stogov
66474380105SNikita Popov	if (loop_var && (loop_var->op_type & (IS_VAR|IS_TMP_VAR))) {
665948b7f54SDmitry Stogov		uint32_t start = get_next_op_number(CG(active_op_array));
666948b7f54SDmitry Stogov
667a16aa4c4SDmitry Stogov		info.opcode = free_opcode;
668a16aa4c4SDmitry Stogov		info.var_type = loop_var->op_type;
669a16aa4c4SDmitry Stogov		info.var_num = loop_var->u.op.var;
670948b7f54SDmitry Stogov		info.u.live_range_offset = zend_start_live_range(CG(active_op_array), start);
671948b7f54SDmitry Stogov		brk_cont_element->start = start;
6723cbe3903SNikita Popov	} else {
67374380105SNikita Popov		info.opcode = ZEND_NOP;
674549e8c49SDmitry Stogov		/* The start field is used to free temporary variables in case of exceptions.
675549e8c49SDmitry Stogov		 * We won't try to free something of we don't have loop variable.  */
676549e8c49SDmitry Stogov		brk_cont_element->start = -1;
6773cbe3903SNikita Popov	}
67874380105SNikita Popov
67974380105SNikita Popov	zend_stack_push(&CG(loop_var_stack), &info);
6802188f26cSDmitry Stogov}
6812188f26cSDmitry Stogov/* }}} */
6822188f26cSDmitry Stogov
6833a5fa926SDmitry Stogovstatic inline void zend_end_loop(int cont_addr, const znode *var_node) /* {{{ */
684573b4602SAndi Gutmans{
685948b7f54SDmitry Stogov	uint32_t end = get_next_op_number(CG(active_op_array));
6863cbe3903SNikita Popov	zend_brk_cont_element *brk_cont_element
687baf97b1fSDmitry Stogov		= &CG(context).brk_cont_array[CG(context).current_brk_cont];
6883cbe3903SNikita Popov	brk_cont_element->cont = cont_addr;
689948b7f54SDmitry Stogov	brk_cont_element->brk = end;
6903cbe3903SNikita Popov	CG(context).current_brk_cont = brk_cont_element->parent;
691549e8c49SDmitry Stogov
692948b7f54SDmitry Stogov	if (brk_cont_element->start != -1) {
693948b7f54SDmitry Stogov		zend_loop_var *loop_var = zend_stack_top(&CG(loop_var_stack));
6943a5fa926SDmitry Stogov		zend_end_live_range(CG(active_op_array), loop_var->u.live_range_offset, end,
6953a5fa926SDmitry Stogov			loop_var->opcode == ZEND_FE_FREE ? ZEND_LIVE_LOOP : ZEND_LIVE_TMPVAR,
6963a5fa926SDmitry Stogov			var_node->u.op.var);
697948b7f54SDmitry Stogov	}
698948b7f54SDmitry Stogov
69974380105SNikita Popov	zend_stack_del_top(&CG(loop_var_stack));
700573b4602SAndi Gutmans}
70128add3cbSFelipe Pena/* }}} */
702573b4602SAndi Gutmans
703bdeb220fSAnatol Belskivoid zend_do_free(znode *op1) /* {{{ */
704573b4602SAndi Gutmans{
705910e6dc6SXinchen Hui	if (op1->op_type == IS_TMP_VAR) {
706573b4602SAndi Gutmans		zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
70704ed2b52SStanislav Malyshev
708910e6dc6SXinchen Hui		while (opline->opcode == ZEND_END_SILENCE) {
709910e6dc6SXinchen Hui			opline--;
710910e6dc6SXinchen Hui		}
711910e6dc6SXinchen Hui
712910e6dc6SXinchen Hui		if (opline->result_type == IS_TMP_VAR && opline->result.var == op1->u.op.var) {
713910e6dc6SXinchen Hui			if (opline->opcode == ZEND_BOOL || opline->opcode == ZEND_BOOL_NOT) {
714910e6dc6SXinchen Hui				return;
715910e6dc6SXinchen Hui			}
716910e6dc6SXinchen Hui		}
717910e6dc6SXinchen Hui
71824f63b1cSNikita Popov		zend_emit_op(NULL, ZEND_FREE, op1, NULL);
719910e6dc6SXinchen Hui	} else if (op1->op_type == IS_VAR) {
720573b4602SAndi Gutmans		zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
721910e6dc6SXinchen Hui		while (opline->opcode == ZEND_END_SILENCE ||
722910e6dc6SXinchen Hui				opline->opcode == ZEND_EXT_FCALL_END ||
723910e6dc6SXinchen Hui				opline->opcode == ZEND_OP_DATA) {
724a2cc070fSZeev Suraski			opline--;
725a2cc070fSZeev Suraski		}
72694dd8372SDmitry Stogov		if (opline->result_type == IS_VAR
72794dd8372SDmitry Stogov			&& opline->result.var == op1->u.op.var) {
7281b80de93SDmitry Stogov			if (opline->opcode == ZEND_FETCH_THIS) {
729a9512af8SDmitry Stogov				opline->opcode = ZEND_NOP;
730a9512af8SDmitry Stogov				opline->result_type = IS_UNUSED;
731ca4de03eSDmitry Stogov			} else {
7325faedf5bSNikita Popov				opline->result_type = IS_UNUSED;
733ca4de03eSDmitry Stogov			}
734573b4602SAndi Gutmans		} else {
7354fd435abSDmitry Stogov			while (opline >= CG(active_op_array)->opcodes) {
7366d4de4cfSDavid Walker				if ((opline->opcode == ZEND_FETCH_LIST_R ||
7376d4de4cfSDavid Walker                     opline->opcode == ZEND_FETCH_LIST_W) &&
7387c7b9184SDmitry Stogov				    opline->op1_type == IS_VAR &&
7397c7b9184SDmitry Stogov				    opline->op1.var == op1->u.op.var) {
7403a5fa926SDmitry Stogov					zend_emit_op(NULL, ZEND_FREE, op1, NULL);
7417c7b9184SDmitry Stogov					return;
7427c7b9184SDmitry Stogov				}
743910e6dc6SXinchen Hui				if (opline->result_type == IS_VAR
74494dd8372SDmitry Stogov					&& opline->result.var == op1->u.op.var) {
7456efa17c2SDmitry Stogov					if (opline->opcode == ZEND_NEW) {
74644ed1cb5SNikita Popov						zend_emit_op(NULL, ZEND_FREE, op1, NULL);
7476efa17c2SDmitry Stogov					}
748b3ec6d5dSZeev Suraski					break;
749573b4602SAndi Gutmans				}
750573b4602SAndi Gutmans				opline--;
751573b4602SAndi Gutmans			}
752573b4602SAndi Gutmans		}
75343adbdccSAndi Gutmans	} else if (op1->op_type == IS_CONST) {
7542a26cbb7SNikita Popov		/* Destroy value without using GC: When opcache moves arrays into SHM it will
7552a26cbb7SNikita Popov		 * free the zend_array structure, so references to it from outside the op array
7562a26cbb7SNikita Popov		 * become invalid. GC would cause such a reference in the root buffer. */
7579e753531SNikita Popov		zval_ptr_dtor_nogc(&op1->u.constant);
758637a4042SMarcus Boerger	}
75904ed2b52SStanislav Malyshev}
76028add3cbSFelipe Pena/* }}} */
761573b4602SAndi Gutmans
762f48c2327SGuilherme Blancouint32_t zend_add_class_modifier(uint32_t flags, uint32_t new_flag) /* {{{ */
763f48c2327SGuilherme Blanco{
764f48c2327SGuilherme Blanco	uint32_t new_flags = flags | new_flag;
765f48c2327SGuilherme Blanco	if ((flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) && (new_flag & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
766d04917c7SNikita Popov		zend_throw_exception(zend_ce_compile_error,
767d04917c7SNikita Popov			"Multiple abstract modifiers are not allowed", 0);
768d04917c7SNikita Popov		return 0;
769f48c2327SGuilherme Blanco	}
770f48c2327SGuilherme Blanco	if ((flags & ZEND_ACC_FINAL) && (new_flag & ZEND_ACC_FINAL)) {
771d04917c7SNikita Popov		zend_throw_exception(zend_ce_compile_error, "Multiple final modifiers are not allowed", 0);
772d04917c7SNikita Popov		return 0;
773f48c2327SGuilherme Blanco	}
774f48c2327SGuilherme Blanco	if ((new_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) && (new_flags & ZEND_ACC_FINAL)) {
775d04917c7SNikita Popov		zend_throw_exception(zend_ce_compile_error,
776d04917c7SNikita Popov			"Cannot use the final modifier on an abstract class", 0);
777d04917c7SNikita Popov		return 0;
778f48c2327SGuilherme Blanco	}
779f48c2327SGuilherme Blanco	return new_flags;
780f48c2327SGuilherme Blanco}
781f48c2327SGuilherme Blanco/* }}} */
782f48c2327SGuilherme Blanco
78349bd049bSXinchen Huiuint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag) /* {{{ */
78449bd049bSXinchen Hui{
7856db293d5SNikita Popov	uint32_t new_flags = flags | new_flag;
7861ea9a2d9SNikita Popov	if ((flags & ZEND_ACC_PPP_MASK) && (new_flag & ZEND_ACC_PPP_MASK)) {
787d04917c7SNikita Popov		zend_throw_exception(zend_ce_compile_error,
788d04917c7SNikita Popov			"Multiple access type modifiers are not allowed", 0);
789d04917c7SNikita Popov		return 0;
790e062dffeSZeev Suraski	}
7911ea9a2d9SNikita Popov	if ((flags & ZEND_ACC_ABSTRACT) && (new_flag & ZEND_ACC_ABSTRACT)) {
792d04917c7SNikita Popov		zend_throw_exception(zend_ce_compile_error, "Multiple abstract modifiers are not allowed", 0);
793d04917c7SNikita Popov		return 0;
794714aad97SAntony Dovgal	}
7951ea9a2d9SNikita Popov	if ((flags & ZEND_ACC_STATIC) && (new_flag & ZEND_ACC_STATIC)) {
796d04917c7SNikita Popov		zend_throw_exception(zend_ce_compile_error, "Multiple static modifiers are not allowed", 0);
797d04917c7SNikita Popov		return 0;
798714aad97SAntony Dovgal	}
7991ea9a2d9SNikita Popov	if ((flags & ZEND_ACC_FINAL) && (new_flag & ZEND_ACC_FINAL)) {
800d04917c7SNikita Popov		zend_throw_exception(zend_ce_compile_error, "Multiple final modifiers are not allowed", 0);
801d04917c7SNikita Popov		return 0;
802714aad97SAntony Dovgal	}
8031ea9a2d9SNikita Popov	if ((new_flags & ZEND_ACC_ABSTRACT) && (new_flags & ZEND_ACC_FINAL)) {
804d04917c7SNikita Popov		zend_throw_exception(zend_ce_compile_error,
805d04917c7SNikita Popov			"Cannot use the final modifier on an abstract class member", 0);
806d04917c7SNikita Popov		return 0;
8071a7c0d52SAndi Gutmans	}
8081ea9a2d9SNikita Popov	return new_flags;
809e062dffeSZeev Suraski}
81049bd049bSXinchen Hui/* }}} */
811637a4042SMarcus Boerger
81249bd049bSXinchen Huizend_string *zend_concat3(char *str1, size_t str1_len, char *str2, size_t str2_len, char *str3, size_t str3_len) /* {{{ */
81349bd049bSXinchen Hui{
81464a71321SNikita Popov	size_t len = str1_len + str2_len + str3_len;
8156db293d5SNikita Popov	zend_string *res = zend_string_alloc(len, 0);
81655cdb7c0SDmitry Stogov
8177aa76271SDmitry Stogov	memcpy(ZSTR_VAL(res), str1, str1_len);
8187aa76271SDmitry Stogov	memcpy(ZSTR_VAL(res) + str1_len, str2, str2_len);
8197aa76271SDmitry Stogov	memcpy(ZSTR_VAL(res) + str1_len + str2_len, str3, str3_len);
8207aa76271SDmitry Stogov	ZSTR_VAL(res)[len] = '\0';
82155cdb7c0SDmitry Stogov
822fb98dd31SNikita Popov	return res;
823573b4602SAndi Gutmans}
824573b4602SAndi Gutmans
82564a71321SNikita Popovzend_string *zend_concat_names(char *name1, size_t name1_len, char *name2, size_t name2_len) {
82664a71321SNikita Popov	return zend_concat3(name1, name1_len, "\\", 1, name2, name2_len);
82764a71321SNikita Popov}
828db507dd1SAndi Gutmans
829bdeb220fSAnatol Belskizend_string *zend_prefix_with_ns(zend_string *name) {
830d2607a01SNikita Popov	if (FC(current_namespace)) {
831d2607a01SNikita Popov		zend_string *ns = FC(current_namespace);
8327aa76271SDmitry Stogov		return zend_concat_names(ZSTR_VAL(ns), ZSTR_LEN(ns), ZSTR_VAL(name), ZSTR_LEN(name));
833babad269SAndi Gutmans	} else {
8346db293d5SNikita Popov		return zend_string_copy(name);
835babad269SAndi Gutmans	}
836130b6340SNikita Popov}
837babad269SAndi Gutmans
838ab288b01SNikita Popovvoid *zend_hash_find_ptr_lc(HashTable *ht, const char *str, size_t len) {
83977fddc0cSNikita Popov	void *result;
840ab288b01SNikita Popov	zend_string *lcname;
841ab288b01SNikita Popov	ALLOCA_FLAG(use_heap);
842ab288b01SNikita Popov
843