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,     |
8493f39daSMarcus Boerger   | 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>                                 |
17573b4602SAndi Gutmans   +----------------------------------------------------------------------+
18573b4602SAndi Gutmans*/
19573b4602SAndi Gutmans
20a6172174SSascha Schumann#ifndef ZEND_COMPILE_H
21a6172174SSascha Schumann#define ZEND_COMPILE_H
22573b4602SAndi Gutmans
23573b4602SAndi Gutmans#include "zend.h"
2423617458SBob Weinand#include "zend_ast.h"
25fa76f0c9SZeev Suraski
26009025e0SStig S. Bakken#ifdef HAVE_STDARG_H
27009025e0SStig S. Bakken# include <stdarg.h>
28fa76f0c9SZeev Suraski#endif
29fa76f0c9SZeev Suraski
30573b4602SAndi Gutmans#include "zend_llist.h"
31573b4602SAndi Gutmans
3294dd8372SDmitry Stogov#define SET_UNUSED(op)  op ## _type = IS_UNUSED
33573b4602SAndi Gutmans
34c8576c5aSLevi Morrison#define MAKE_NOP(opline) do { \
356d681876SDmitry Stogov	(opline)->op1.num = 0; \
366d681876SDmitry Stogov	(opline)->op2.num = 0; \
376d681876SDmitry Stogov	(opline)->result.num = 0; \
386d681876SDmitry Stogov	(opline)->opcode = ZEND_NOP; \
396d681876SDmitry Stogov	(opline)->op1_type =  IS_UNUSED; \
406d681876SDmitry Stogov	(opline)->op2_type = IS_UNUSED; \
416d681876SDmitry Stogov	(opline)->result_type = IS_UNUSED; \
42c8576c5aSLevi Morrison} while (0)
43c8576c5aSLevi Morrison
4438c4125cSNikita Popov#define RESET_DOC_COMMENT() do { \
4538c4125cSNikita Popov	if (CG(doc_comment)) { \
465eb1f92fSDmitry Stogov		zend_string_release_ex(CG(doc_comment), 0); \
4738c4125cSNikita Popov		CG(doc_comment) = NULL; \
4838c4125cSNikita Popov	} \
4938c4125cSNikita Popov} while (0)
50bdd3b604SAndrei Zmievski
51573b4602SAndi Gutmanstypedef struct _zend_op_array zend_op_array;
5280109314SAndi Gutmanstypedef struct _zend_op zend_op;
53573b4602SAndi Gutmans
540381c1b7SNikita Popov/* On 64-bit systems less optimal, but more compact VM code leads to better
5514e29f51SDmitry Stogov * performance. So on 32-bit systems we use absolute addresses for jump
5614e29f51SDmitry Stogov * targets and constants, but on 64-bit systems realtive 32-bit offsets */
5714e29f51SDmitry Stogov#if SIZEOF_SIZE_T == 4
5814e29f51SDmitry Stogov# define ZEND_USE_ABS_JMP_ADDR      1
5914e29f51SDmitry Stogov# define ZEND_USE_ABS_CONST_ADDR    1
6014e29f51SDmitry Stogov# define ZEND_EX_USE_RUN_TIME_CACHE 1
6114e29f51SDmitry Stogov#else
6214e29f51SDmitry Stogov# define ZEND_USE_ABS_JMP_ADDR      0
6314e29f51SDmitry Stogov# define ZEND_USE_ABS_CONST_ADDR    0
6414e29f51SDmitry Stogov# define ZEND_EX_USE_RUN_TIME_CACHE 1
6514e29f51SDmitry Stogov#endif
6614e29f51SDmitry Stogov
6724e0b991SIgor Wiedlertypedef union _znode_op {
686f9f0bf2SAnatol Belski	uint32_t      constant;
696f9f0bf2SAnatol Belski	uint32_t      var;
706f9f0bf2SAnatol Belski	uint32_t      num;
716f9f0bf2SAnatol Belski	uint32_t      opline_num; /*  Needs to be signed */
7214e29f51SDmitry Stogov#if ZEND_USE_ABS_JMP_ADDR
7394dd8372SDmitry Stogov	zend_op       *jmp_addr;
7414e29f51SDmitry Stogov#else
7514e29f51SDmitry Stogov	uint32_t      jmp_offset;
7614e29f51SDmitry Stogov#endif
7714e29f51SDmitry Stogov#if ZEND_USE_ABS_CONST_ADDR
7894dd8372SDmitry Stogov	zval          *zv;
7914e29f51SDmitry Stogov#endif
8094dd8372SDmitry Stogov} znode_op;
8194dd8372SDmitry Stogov
8224e0b991SIgor Wiedlertypedef struct _znode { /* used only during compilation */
8397fe15dbSDmitry Stogov	zend_uchar op_type;
8497fe15dbSDmitry Stogov	zend_uchar flag;
85573b4602SAndi Gutmans	union {
8694dd8372SDmitry Stogov		znode_op op;
8794dd8372SDmitry Stogov		zval constant; /* replaced by literal/zv */
88573b4602SAndi Gutmans	} u;
89573b4602SAndi Gutmans} znode;
90573b4602SAndi Gutmans
91258a733eSNikita Popov/* Temporarily defined here, to avoid header ordering issues */
92258a733eSNikita Popovtypedef struct _zend_ast_znode {
9355ab55c4SNikita Popov	zend_ast_kind kind;
9455ab55c4SNikita Popov	zend_ast_attr attr;
956db293d5SNikita Popov	uint32_t lineno;
96258a733eSNikita Popov	znode node;
97258a733eSNikita Popov} zend_ast_znode;
984bbf200bSDmitry Stogov
994bbf200bSDmitry StogovZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node);
100258a733eSNikita Popov
1015185baabSDmitry Stogovstatic zend_always_inline znode *zend_ast_get_znode(zend_ast *ast) {
102258a733eSNikita Popov	return &((zend_ast_znode *) ast)->node;
103258a733eSNikita Popov}
104258a733eSNikita Popov
105d2607a01SNikita Popovtypedef struct _zend_declarables {
106d2607a01SNikita Popov	zend_long ticks;
107d2607a01SNikita Popov} zend_declarables;
108d2607a01SNikita Popov
109d2607a01SNikita Popov/* Compilation context that is different for each file, but shared between op arrays. */
110d2607a01SNikita Popovtypedef struct _zend_file_context {
111d2607a01SNikita Popov	zend_declarables declarables;
112d2607a01SNikita Popov	znode implementing_class;
113d2607a01SNikita Popov
114d2607a01SNikita Popov	zend_string *current_namespace;
115d2607a01SNikita Popov	zend_bool in_namespace;
116d2607a01SNikita Popov	zend_bool has_bracketed_namespaces;
117d2607a01SNikita Popov
118d2607a01SNikita Popov	HashTable *imports;
119d2607a01SNikita Popov	HashTable *imports_function;
120d2607a01SNikita Popov	HashTable *imports_const;
1218754b191SNikita Popov
1228754b191SNikita Popov	HashTable seen_symbols;
123d2607a01SNikita Popov} zend_file_context;
124d2607a01SNikita Popov
125bea85f58SNikita Popovtypedef union _zend_parser_stack_elem {
126bea85f58SNikita Popov	zend_ast *ast;
127bea85f58SNikita Popov	zend_string *str;
128bea85f58SNikita Popov	zend_ulong num;
129bea85f58SNikita Popov} zend_parser_stack_elem;
130bea85f58SNikita Popov
131bdeb220fSAnatol Belskivoid zend_compile_top_stmt(zend_ast *ast);
132bdeb220fSAnatol Belskivoid zend_compile_stmt(zend_ast *ast);
133bdeb220fSAnatol Belskivoid zend_compile_expr(znode *node, zend_ast *ast);
134bdeb220fSAnatol Belskivoid zend_compile_var(znode *node, zend_ast *ast, uint32_t type);
135bdeb220fSAnatol Belskivoid zend_eval_const_expr(zend_ast **ast_ptr);
136bdeb220fSAnatol Belskivoid zend_const_expr_to_zval(zval *result, zend_ast *ast);
137258a733eSNikita Popov
1386289f7e5SDmitry Stogovtypedef int (*user_opcode_handler_t) (zend_execute_data *execute_data);
139573b4602SAndi Gutmans
14080109314SAndi Gutmansstruct _zend_op {
1416289f7e5SDmitry Stogov	const void *handler;
14294dd8372SDmitry Stogov	znode_op op1;
14394dd8372SDmitry Stogov	znode_op op2;
14494dd8372SDmitry Stogov	znode_op result;
14514e29f51SDmitry Stogov	uint32_t extended_value;
14614e29f51SDmitry Stogov	uint32_t lineno;
1476f9bfe5cSAndi Gutmans	zend_uchar opcode;
14894dd8372SDmitry Stogov	zend_uchar op1_type;
14994dd8372SDmitry Stogov	zend_uchar op2_type;
15094dd8372SDmitry Stogov	zend_uchar result_type;
15180109314SAndi Gutmans};
152573b4602SAndi Gutmans
153549e8c49SDmitry Stogov
154549e8c49SDmitry Stogovtypedef struct _zend_brk_cont_element {
155549e8c49SDmitry Stogov	int start;
156549e8c49SDmitry Stogov	int cont;
157549e8c49SDmitry Stogov	int brk;
158549e8c49SDmitry Stogov	int parent;
15904e3523bSNikita Popov	zend_bool is_switch;
160549e8c49SDmitry Stogov} zend_brk_cont_element;
161549e8c49SDmitry Stogov
162549e8c49SDmitry Stogovtypedef struct _zend_label {
163549e8c49SDmitry Stogov	int brk_cont;
164549e8c49SDmitry Stogov	uint32_t opline_num;
165549e8c49SDmitry Stogov} zend_label;
166549e8c49SDmitry Stogov
167549e8c49SDmitry Stogovtypedef struct _zend_try_catch_element {
168549e8c49SDmitry Stogov	uint32_t try_op;
169549e8c49SDmitry Stogov	uint32_t catch_op;  /* ketchup! */
170549e8c49SDmitry Stogov	uint32_t finally_op;
171549e8c49SDmitry Stogov	uint32_t finally_end;
172549e8c49SDmitry Stogov} zend_try_catch_element;
173549e8c49SDmitry Stogov
1743a5fa926SDmitry Stogov#define ZEND_LIVE_TMPVAR  0
1753a5fa926SDmitry Stogov#define ZEND_LIVE_LOOP    1
1763a5fa926SDmitry Stogov#define ZEND_LIVE_SILENCE 2
1773a5fa926SDmitry Stogov#define ZEND_LIVE_ROPE    3
1783a5fa926SDmitry Stogov#define ZEND_LIVE_MASK    3
1793a5fa926SDmitry Stogov
180baf97b1fSDmitry Stogovtypedef struct _zend_live_range {
1813a5fa926SDmitry Stogov	uint32_t var; /* low bits are used for variable type (ZEND_LIVE_* macros) */
182baf97b1fSDmitry Stogov	uint32_t start;
183baf97b1fSDmitry Stogov	uint32_t end;
184baf97b1fSDmitry Stogov} zend_live_range;
185baf97b1fSDmitry Stogov
186baf97b1fSDmitry Stogov/* Compilation context that is different for each op array. */
187baf97b1fSDmitry Stogovtypedef struct _zend_oparray_context {
188baf97b1fSDmitry Stogov	uint32_t   opcodes_size;
189baf97b1fSDmitry Stogov	int        vars_size;
190baf97b1fSDmitry Stogov	int        literals_size;
191baf97b1fSDmitry Stogov	int        backpatch_count;
192baf97b1fSDmitry Stogov	uint32_t   fast_call_var;
1932ae21abdSDmitry Stogov	uint32_t   try_catch_offset;
194baf97b1fSDmitry Stogov	int        current_brk_cont;
195baf97b1fSDmitry Stogov	int        last_brk_cont;
196baf97b1fSDmitry Stogov	zend_brk_cont_element *brk_cont_array;
197baf97b1fSDmitry Stogov	HashTable *labels;
198baf97b1fSDmitry Stogov} zend_oparray_context;
199baf97b1fSDmitry Stogov
2007a41e4c0SDmitry Stogov/* Class, property and method flags                  class|meth.|prop.|const*/
2017a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2027a41e4c0SDmitry Stogov/* Common flags                                           |     |     |     */
2037a41e4c0SDmitry Stogov/* ============                                           |     |     |     */
2047a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2057a41e4c0SDmitry Stogov/* Staic method or property                               |     |     |     */
2067a41e4c0SDmitry Stogov#define ZEND_ACC_STATIC                  (1 <<  0) /*     |  X  |  X  |     */
2077a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2087a41e4c0SDmitry Stogov/* Final class or method                                  |     |     |     */
2097a41e4c0SDmitry Stogov#define ZEND_ACC_FINAL                   (1 <<  2) /*  X  |  X  |     |     */
2107a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2117a41e4c0SDmitry Stogov/* Visibility flags (public < protected < private)        |     |     |     */
2127a41e4c0SDmitry Stogov#define ZEND_ACC_PUBLIC                  (1 <<  8) /*     |  X  |  X  |  X  */
2137a41e4c0SDmitry Stogov#define ZEND_ACC_PROTECTED               (1 <<  9) /*     |  X  |  X  |  X  */
2147a41e4c0SDmitry Stogov#define ZEND_ACC_PRIVATE                 (1 << 10) /*     |  X  |  X  |  X  */
2157a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2167a41e4c0SDmitry Stogov/* TODO: explain the name ???                             |     |     |     */
2177a41e4c0SDmitry Stogov#define ZEND_ACC_CHANGED                 (1 << 11) /*     |  X  |  X  |     */
2187a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2197a41e4c0SDmitry Stogov/* TODO: used only by ext/reflection ???                  |     |     |     */
2207a41e4c0SDmitry Stogov#define ZEND_ACC_IMPLICIT_PUBLIC         (1 << 12) /*     |  ?  |  ?  |  ?  */
2217a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2227a41e4c0SDmitry Stogov/* Shadow of parent's private method/property             |     |     |     */
2237a41e4c0SDmitry Stogov#define ZEND_ACC_SHADOW                  (1 << 17) /*     |  ?  |  X  |     */
2247a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2257a41e4c0SDmitry Stogov/* Class Flags (unused: 0, 1, 3, 11-18, 21, 25...)        |     |     |     */
2267a41e4c0SDmitry Stogov/* ===========                                            |     |     |     */
2277a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2287a41e4c0SDmitry Stogov/* class is abstarct, since it is set by any              |     |     |     */
2297a41e4c0SDmitry Stogov/* abstract method                                        |     |     |     */
2307a41e4c0SDmitry Stogov#define ZEND_ACC_IMPLICIT_ABSTRACT_CLASS (1 <<  4) /*  X  |     |     |     */
2317a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2327a41e4c0SDmitry Stogov/* Class is explicitly defined as abstract by using       |     |     |     */
2337a41e4c0SDmitry Stogov/* the keyword.                                           |     |     |     */
2347a41e4c0SDmitry Stogov#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS (1 <<  5) /*  X  |     |     |     */
2357a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2367a41e4c0SDmitry Stogov/* Special class types                                    |     |     |     */
2377a41e4c0SDmitry Stogov#define ZEND_ACC_INTERFACE               (1 <<  6) /*  X  |     |     |     */
2387a41e4c0SDmitry Stogov#define ZEND_ACC_TRAIT                   (1 <<  7) /*  X  |     |     |     */
2397a41e4c0SDmitry Stogov#define ZEND_ACC_ANON_CLASS              (1 <<  8) /*  X  |     |     |     */
2407a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2417a41e4c0SDmitry Stogov/* Bound anonymous class                                  |     |     |     */
2427a41e4c0SDmitry Stogov#define ZEND_ACC_ANON_BOUND              (1 <<  9) /*  X  |     |     |     */
2437a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2447a41e4c0SDmitry Stogov/* Class extends another class                            |     |     |     */
2457a41e4c0SDmitry Stogov#define ZEND_ACC_INHERITED               (1 << 10) /*  X  |     |     |     */
2467a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2477a41e4c0SDmitry Stogov/* Class implements interface(s)                          |     |     |     */
2487a41e4c0SDmitry Stogov#define ZEND_ACC_IMPLEMENT_INTERFACES    (1 << 19) /*  X  |     |     |     */
2497a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2507a41e4c0SDmitry Stogov/* Class constants updated                                |     |     |     */
2517a41e4c0SDmitry Stogov#define ZEND_ACC_CONSTANTS_UPDATED       (1 << 20) /*  X  |     |     |     */
2527a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2537a41e4c0SDmitry Stogov/* Class uses trait(s)                                    |     |     |     */
2547a41e4c0SDmitry Stogov#define ZEND_ACC_IMPLEMENT_TRAITS        (1 << 22) /*  X  |     |     |     */
2557a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2567a41e4c0SDmitry Stogov/* User class has methods with static variables           |     |     |     */
2577a41e4c0SDmitry Stogov#define ZEND_HAS_STATIC_IN_METHODS       (1 << 23) /*  X  |     |     |     */
2587a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2597a41e4c0SDmitry Stogov/* Class has magic methods __get/__set/__unset/           |     |     |     */
2607a41e4c0SDmitry Stogov/* __isset that use guards                                |     |     |     */
2617a41e4c0SDmitry Stogov#define ZEND_ACC_USE_GUARDS              (1 << 24) /*  X  |     |     |     */
2627a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2637a41e4c0SDmitry Stogov/* Function Flags (unused: 4, 5, 17?)                     |     |     |     */
2647a41e4c0SDmitry Stogov/* ==============                                         |     |     |     */
2657a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2667a41e4c0SDmitry Stogov/* Abstarct method                                        |     |     |     */
2677a41e4c0SDmitry Stogov#define ZEND_ACC_ABSTRACT                (1 <<  1) /*     |  X  |     |     */
2687a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2697a41e4c0SDmitry Stogov/* TODO: used only during inheritance ???                 |     |     |     */
2707a41e4c0SDmitry Stogov#define ZEND_ACC_IMPLEMENTED_ABSTRACT    (1 <<  3) /*     |  X  |     |     */
2717a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2727a41e4c0SDmitry Stogov#define ZEND_ACC_FAKE_CLOSURE            (1 <<  6) /*     |  X  |     |     */
2737a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2747a41e4c0SDmitry Stogov/* method flag used by Closure::__invoke()                |     |     |     */
2757a41e4c0SDmitry Stogov#define ZEND_ACC_USER_ARG_INFO           (1 <<  7) /*     |  X  |     |     */
2767a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2777a41e4c0SDmitry Stogov/* method flags (special method detection)                |     |     |     */
2787a41e4c0SDmitry Stogov#define ZEND_ACC_CTOR                    (1 << 13) /*     |  X  |     |     */
2797a41e4c0SDmitry Stogov#define ZEND_ACC_DTOR                    (1 << 14) /*     |  X  |     |     */
2807a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2817a41e4c0SDmitry Stogov/* "main" op_array with                                   |     |     |     */
2827a41e4c0SDmitry Stogov/* ZEND_DECLARE_INHERITED_CLASS_DELAYED opcodes           |     |     |     */
2837a41e4c0SDmitry Stogov#define ZEND_ACC_EARLY_BINDING           (1 << 15) /*     |  X  |     |     */
2847a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2857a41e4c0SDmitry Stogov/* method flag (bc only), any method that has this        |     |     |     */
2867a41e4c0SDmitry Stogov/* flag can be used statically and non statically.        |     |     |     */
2877a41e4c0SDmitry Stogov#define ZEND_ACC_ALLOW_STATIC            (1 << 16) /*     |  X  |     |     */
2887a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2897a41e4c0SDmitry Stogov/* deprecation flag                                       |     |     |     */
2907a41e4c0SDmitry Stogov#define ZEND_ACC_DEPRECATED              (1 << 18) /*     |  X  |     |     */
2917a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2927a41e4c0SDmitry Stogov#define ZEND_ACC_NO_RT_ARENA             (1 << 19) /*     |  X  |     |     */
2937a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2947a41e4c0SDmitry Stogov#define ZEND_ACC_CLOSURE                 (1 << 20) /*     |  X  |     |     */
2957a41e4c0SDmitry Stogov/*                                                        |     |     |     */
2967a41e4c0SDmitry Stogov/* call through user function trampoline. e.g.            |     |     |     */
2977a41e4c0SDmitry Stogov/* __call, __callstatic                                   |     |     |     */
2987a41e4c0SDmitry Stogov#define ZEND_ACC_CALL_VIA_TRAMPOLINE     (1 << 21) /*     |  X  |     |     */
2997a41e4c0SDmitry Stogov/*                                                        |     |     |     */
3007a41e4c0SDmitry Stogov/* disable inline caching                                 |     |     |     */
3017a41e4c0SDmitry Stogov#define ZEND_ACC_NEVER_CACHE             (1 << 22) /*     |  X  |     |     */
3027a41e4c0SDmitry Stogov/*                                                        |     |     |     */
3037a41e4c0SDmitry Stogov#define ZEND_ACC_GENERATOR               (1 << 23) /*     |  X  |     |     */
3047a41e4c0SDmitry Stogov/*                                                        |     |     |     */
3057a41e4c0SDmitry Stogov/* Function with varable number of arguments              |     |     |     */
3067a41e4c0SDmitry Stogov#define ZEND_ACC_VARIADIC                (1 << 24) /*     |  X  |     |     */
3077a41e4c0SDmitry Stogov/*                                                        |     |     |     */
3087a41e4c0SDmitry Stogov/* Immutable op_array (lazy loading)                      |     |     |     */
3097a41e4c0SDmitry Stogov#define ZEND_ACC_IMMUTABLE               (1 << 25) /*     |  X  |     |     */
3107a41e4c0SDmitry Stogov/*                                                        |     |     |     */
3117a41e4c0SDmitry Stogov/* Function returning by reference                        |     |     |     */
3127a41e4c0SDmitry Stogov#define ZEND_ACC_RETURN_REFERENCE        (1 << 26) /*     |  X  |     |     */
3137a41e4c0SDmitry Stogov/*                                                        |     |     |     */
3147a41e4c0SDmitry Stogov#define ZEND_ACC_DONE_PASS_TWO           (1 << 27) /*     |  X  |     |     */
3157a41e4c0SDmitry Stogov/*                                                        |     |     |     */
3167a41e4c0SDmitry Stogov/* Function has typed arguments                           |     |     |     */
3177a41e4c0SDmitry Stogov#define ZEND_ACC_HAS_TYPE_HINTS          (1 << 28) /*     |  X  |     |     */
3187a41e4c0SDmitry Stogov/*                                                        |     |     |     */
3197a41e4c0SDmitry Stogov/* op_array has finally blocks (user only)                |     |     |     */
3207a41e4c0SDmitry Stogov#define ZEND_ACC_HAS_FINALLY_BLOCK       (1 << 29) /*     |  X  |     |     */
3217a41e4c0SDmitry Stogov/*                                                        |     |     |     */
3227a41e4c0SDmitry Stogov/* internal function is allocated at arena (int only)     |     |     |     */
3237a41e4c0SDmitry Stogov#define ZEND_ACC_ARENA_ALLOCATED         (1 << 29) /*     |  X  |     |     */
3247a41e4c0SDmitry Stogov/*                                                        |     |     |     */
3257a41e4c0SDmitry Stogov/* Function has a return type                             |     |     |     */
3267a41e4c0SDmitry Stogov#define ZEND_ACC_HAS_RETURN_TYPE         (1 << 30) /*     |  X  |     |     */
3277a41e4c0SDmitry Stogov/*                                                        |     |     |     */
3287a41e4c0SDmitry Stogov/* op_array uses strict mode types                        |     |     |     */
3297a41e4c0SDmitry Stogov#define ZEND_ACC_STRICT_TYPES            (1 << 31) /*     |  X  |     |     */
330ed84bff4SDmitry Stogov
33150ee116fSMarcus Boerger
3327a41e4c0SDmitry Stogov#define ZEND_ACC_PPP_MASK  (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE)
3335e8133f4SDmitry Stogov
3345e8133f4SDmitry Stogov/* call through internal function handler. e.g. Closure::invoke() */
3355e8133f4SDmitry Stogov#define ZEND_ACC_CALL_VIA_HANDLER     ZEND_ACC_CALL_VIA_TRAMPOLINE
3360f2247aeSDmitry Stogov
3376db293d5SNikita Popovchar *zend_visibility_string(uint32_t fn_flags);
338471947b1SZeev Suraski
339471947b1SZeev Suraskitypedef struct _zend_property_info {
34075041379SDmitry Stogov	uint32_t offset; /* property offset for object properties or
34175041379SDmitry Stogov	                      property index for static properties */
3426f9f0bf2SAnatol Belski	uint32_t flags;
343ee552b62SDmitry Stogov	zend_string *name;
344f4cfaf36SDmitry Stogov	zend_string *doc_comment;
345493f39daSMarcus Boerger	zend_class_entry *ce;
346471947b1SZeev Suraski} zend_property_info;
347471947b1SZeev Suraski
34875041379SDmitry Stogov#define OBJ_PROP(obj, offset) \
34975041379SDmitry Stogov	((zval*)((char*)(obj) + offset))
35075041379SDmitry Stogov#define OBJ_PROP_NUM(obj, num) \
35175041379SDmitry Stogov	(&(obj)->properties_table[(num)])
35275041379SDmitry Stogov#define OBJ_PROP_TO_OFFSET(num) \
35375041379SDmitry Stogov	((uint32_t)(zend_uintptr_t)OBJ_PROP_NUM(((zend_object*)NULL), num))
35475041379SDmitry Stogov#define OBJ_PROP_TO_NUM(offset) \
35575041379SDmitry Stogov	((offset - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval))
35675041379SDmitry Stogov
357a75c1950SDmitry Stogovtypedef struct _zend_class_constant {
358a75c1950SDmitry Stogov	zval value; /* access flags are stored in reserved: zval.u2.access_flags */
359a75c1950SDmitry Stogov	zend_string *doc_comment;
360a75c1950SDmitry Stogov	zend_class_entry *ce;
361a75c1950SDmitry Stogov} zend_class_constant;
362a75c1950SDmitry Stogov
3635dd427eaSDmitry Stogov/* arg_info for internal functions */
364b7a7b1a6SStanislav Malyshevtypedef struct _zend_internal_arg_info {
36525cd356eSXinchen Hui	const char *name;
366141d1ba9SDmitry Stogov	zend_type type;
36725cd356eSXinchen Hui	zend_uchar pass_by_reference;
36825cd356eSXinchen Hui	zend_bool is_variadic;
3695dd427eaSDmitry Stogov} zend_internal_arg_info;
3705dd427eaSDmitry Stogov
3715dd427eaSDmitry Stogov/* arg_info for user functions */
372f8bbafd6SZeev Suraskitypedef struct _zend_arg_info {
3735dd427eaSDmitry Stogov	zend_string *name;
374141d1ba9SDmitry Stogov	zend_type type;
37525cd356eSXinchen Hui	zend_uchar pass_by_reference;
37625cd356eSXinchen Hui	zend_bool is_variadic;
377f8bbafd6SZeev Suraski} zend_arg_info;
378f8bbafd6SZeev Suraski
3795dd427eaSDmitry Stogov/* the following structure repeats the layout of zend_internal_arg_info,
38024e0b991SIgor Wiedler * but its fields have different meaning. It's used as the first element of
381f2df6a4aSDmitry Stogov * arg_info array to define properties of internal functions.
3822a7eeff3SLevi Morrison * It's also used for the return type.
383f2df6a4aSDmitry Stogov */
384f2df6a4aSDmitry Stogovtypedef struct _zend_internal_function_info {
3855dd427eaSDmitry Stogov	zend_uintptr_t required_num_args;
386141d1ba9SDmitry Stogov	zend_type type;
387f2df6a4aSDmitry Stogov	zend_bool return_reference;
3880d7a6388SNikita Popov	zend_bool _is_variadic;
389f2df6a4aSDmitry Stogov} zend_internal_function_info;
390f2df6a4aSDmitry Stogov
391573b4602SAndi Gutmansstruct _zend_op_array {
3925097be30SZeev Suraski	/* Common elements */
3935097be30SZeev Suraski	zend_uchar type;
39415a5f61cSDmitry Stogov	zend_uchar arg_flags[3]; /* bitset of arg_info.pass_by_reference */
395ee552b62SDmitry Stogov	uint32_t fn_flags;
396f4cfaf36SDmitry Stogov	zend_string *function_name;
3975097be30SZeev Suraski	zend_class_entry *scope;
398f4cfaf36SDmitry Stogov	zend_function *prototype;
3996f9f0bf2SAnatol Belski	uint32_t num_args;
4006f9f0bf2SAnatol Belski	uint32_t required_num_args;
401f8bbafd6SZeev Suraski	zend_arg_info *arg_info;
4025097be30SZeev Suraski	/* END of common elements */
403573b4602SAndi Gutmans
40470aa967dSDmitry Stogov	int cache_size;     /* number of run_time_cache_slots * sizeof(void*) */
40570aa967dSDmitry Stogov	int last_var;       /* number of CV variables */
40619b42bd6SCOFFEE	uint32_t T;         /* number of temporary variables */
40770aa967dSDmitry Stogov	uint32_t last;      /* number of opcodes */
408573b4602SAndi Gutmans
409ee552b62SDmitry Stogov	zend_op *opcodes;
41070aa967dSDmitry Stogov	void **run_time_cache;
41170aa967dSDmitry Stogov	HashTable *static_variables;
41270aa967dSDmitry Stogov	zend_string **vars; /* names of CV variables */
413573b4602SAndi Gutmans
41470aa967dSDmitry Stogov	uint32_t *refcount;
415573b4602SAndi Gutmans
416baf97b1fSDmitry Stogov	int last_live_range;
4179e60cb55SZeev Suraski	int last_try_catch;
418baf97b1fSDmitry Stogov	zend_live_range *live_range;
419ee552b62SDmitry Stogov	zend_try_catch_element *try_catch_array;
4209e60cb55SZeev Suraski
421f4cfaf36SDmitry Stogov	zend_string *filename;
4226f9f0bf2SAnatol Belski	uint32_t line_start;
4236f9f0bf2SAnatol Belski	uint32_t line_end;
424f4cfaf36SDmitry Stogov	zend_string *doc_comment;
425c06692e9SZeev Suraski
426f2df6a4aSDmitry Stogov	int last_literal;
427ee552b62SDmitry Stogov	zval *literals;
42894dd8372SDmitry Stogov
429b5f5e9a6SAndi Gutmans	void *reserved[ZEND_MAX_RESERVED_RESOURCES];
430573b4602SAndi Gutmans};
431573b4602SAndi Gutmans
432573b4602SAndi Gutmans
433e7e0f7d4SZeev Suraski#define ZEND_RETURN_VALUE				0
434e7e0f7d4SZeev Suraski#define ZEND_RETURN_REFERENCE			1
435e7e0f7d4SZeev Suraski
436db4561bfSDmitry Stogov/* zend_internal_function_handler */
4370673aa7fSAnatol Belskitypedef void (ZEND_FASTCALL *zif_handler)(INTERNAL_FUNCTION_PARAMETERS);
438db4561bfSDmitry Stogov
4391250c43aSZeev Suraskitypedef struct _zend_internal_function {
4405097be30SZeev Suraski	/* Common elements */
4415097be30SZeev Suraski	zend_uchar type;
44215a5f61cSDmitry Stogov	zend_uchar arg_flags[3]; /* bitset of arg_info.pass_by_reference */
443ee552b62SDmitry Stogov	uint32_t fn_flags;
444f4cfaf36SDmitry Stogov	zend_string* function_name;
4455097be30SZeev Suraski	zend_class_entry *scope;
446f4cfaf36SDmitry Stogov	zend_function *prototype;
4476f9f0bf2SAnatol Belski	uint32_t num_args;
4486f9f0bf2SAnatol Belski	uint32_t required_num_args;
4495dd427eaSDmitry Stogov	zend_internal_arg_info *arg_info;
4505097be30SZeev Suraski	/* END of common elements */
451573b4602SAndi Gutmans
452db4561bfSDmitry Stogov	zif_handler handler;
453637a4042SMarcus Boerger	struct _zend_module_entry *module;
454ca36b7bcSDmitry Stogov	void *reserved[ZEND_MAX_RESERVED_RESOURCES];
455573b4602SAndi Gutmans} zend_internal_function;
456573b4602SAndi Gutmans
4577aa76271SDmitry Stogov#define ZEND_FN_SCOPE_NAME(function)  ((function) && (function)->common.scope ? ZSTR_VAL((function)->common.scope->name) : "")
458e8214a33SAndi Gutmans
459f4cfaf36SDmitry Stogovunion _zend_function {
460e92f6f15SAndi Gutmans	zend_uchar type;	/* MUST be the first element of this struct! */
46171842c28SDmitry Stogov	uint32_t   quick_arg_flags;
462d1eea3deSAndi Gutmans
463573b4602SAndi Gutmans	struct {
464e92f6f15SAndi Gutmans		zend_uchar type;  /* never used */
46515a5f61cSDmitry Stogov		zend_uchar arg_flags[3]; /* bitset of arg_info.pass_by_reference */
466ee552b62SDmitry Stogov		uint32_t fn_flags;
467f4cfaf36SDmitry Stogov		zend_string *function_name;
468d1eea3deSAndi Gutmans		zend_class_entry *scope;
4695097be30SZeev Suraski		union _zend_function *prototype;
4706f9f0bf2SAnatol Belski		uint32_t num_args;
4716f9f0bf2SAnatol Belski		uint32_t required_num_args;
472f8bbafd6SZeev Suraski		zend_arg_info *arg_info;
473573b4602SAndi Gutmans	} common;
474637a4042SMarcus Boerger
475573b4602SAndi Gutmans	zend_op_array op_array;
476573b4602SAndi Gutmans	zend_internal_function internal_function;
477f4cfaf36SDmitry Stogov};
478573b4602SAndi Gutmans
4791da14c9fSDmitry Stogovtypedef enum _zend_call_kind {
4801da14c9fSDmitry Stogov	ZEND_CALL_NESTED_FUNCTION,	/* stackless VM call to function */
4811da14c9fSDmitry Stogov	ZEND_CALL_NESTED_CODE,		/* stackless VM call to include/require/eval */
4821da14c9fSDmitry Stogov	ZEND_CALL_TOP_FUNCTION,		/* direct VM call to function from external C code */
4831da14c9fSDmitry Stogov	ZEND_CALL_TOP_CODE			/* direct VM call to "main" code from external C code */
4841da14c9fSDmitry Stogov} zend_call_kind;
485ea2e1bb1SDmitry Stogov
48613274801SAndi Gutmansstruct _zend_execute_data {
487f2b03701SDmitry Stogov	const zend_op       *opline;           /* executed opline                */
488b7715c7eSDmitry Stogov	zend_execute_data   *call;             /* current call                   */
48914e29f51SDmitry Stogov	zval                *return_value;
490194ffefbSJoey	zend_function       *func;             /* executed function              */
49164a79817SDmitry Stogov	zval                 This;             /* this + call_info + num_args    */
49264a79817SDmitry Stogov	zend_execute_data   *prev_execute_data;
49364a79817SDmitry Stogov	zend_array          *symbol_table;
49414e29f51SDmitry Stogov#if ZEND_EX_USE_RUN_TIME_CACHE
49564a79817SDmitry Stogov	void               **run_time_cache;   /* cache op_array->run_time_cache */
49614e29f51SDmitry Stogov#endif
49713274801SAndi Gutmans};
498573b4602SAndi Gutmans
4991da14c9fSDmitry Stogov#define ZEND_CALL_FUNCTION           (0 << 0)
5001da14c9fSDmitry Stogov#define ZEND_CALL_CODE               (1 << 0)
5011da14c9fSDmitry Stogov#define ZEND_CALL_NESTED             (0 << 1)
5021da14c9fSDmitry Stogov#define ZEND_CALL_TOP                (1 << 1)
5039a6100f9SDmitry Stogov#define ZEND_CALL_FREE_EXTRA_ARGS    (1 << 2)
504ab0b15b8SDmitry Stogov#define ZEND_CALL_CTOR               (1 << 3)
505747a482bSDmitry Stogov#define ZEND_CALL_HAS_SYMBOL_TABLE   (1 << 4)
506a759967dSDmitry Stogov#define ZEND_CALL_CLOSURE            (1 << 5)
507ab4ccffcSDmitry Stogov#define ZEND_CALL_RELEASE_THIS       (1 << 6)
5080586702dSDmitry Stogov#define ZEND_CALL_ALLOCATED          (1 << 7)
50997bf4e0bSDmitry Stogov#define ZEND_CALL_GENERATOR          (1 << 8)
51091f59403SNikita Popov#define ZEND_CALL_DYNAMIC            (1 << 9)
51197628da2SDmitry Stogov#define ZEND_CALL_FAKE_CLOSURE       (1 << 10)
5123a794d39SDmitry Stogov#define ZEND_CALL_SEND_ARG_BY_REF    (1 << 11)
513427ecdc5SAnthony Ferrara
514054446a2SDmitry Stogov#define ZEND_CALL_INFO_SHIFT         16
515ccf18da4SDmitry Stogov
5161da14c9fSDmitry Stogov#define ZEND_CALL_INFO(call) \
517ccf18da4SDmitry Stogov	(Z_TYPE_INFO((call)->This) >> ZEND_CALL_INFO_SHIFT)
51833e137d4SDmitry Stogov
519a759967dSDmitry Stogov#define ZEND_CALL_KIND_EX(call_info) \
520a759967dSDmitry Stogov	(call_info & (ZEND_CALL_CODE | ZEND_CALL_TOP))
521a759967dSDmitry Stogov
5221da14c9fSDmitry Stogov#define ZEND_CALL_KIND(call) \
523a759967dSDmitry Stogov	ZEND_CALL_KIND_EX(ZEND_CALL_INFO(call))
5241da14c9fSDmitry Stogov
5257abfaac9SDmitry Stogov#define ZEND_SET_CALL_INFO(call, object, info) do { \
526ccf18da4SDmitry Stogov		Z_TYPE_INFO((call)->This) = ((object) ? IS_OBJECT_EX : IS_UNDEF) | ((info) << ZEND_CALL_INFO_SHIFT); \
5271da14c9fSDmitry Stogov	} while (0)
528b7a7b1a6SStanislav Malyshev
529a759967dSDmitry Stogov#define ZEND_ADD_CALL_FLAG_EX(call_info, flag) do { \
530ccf18da4SDmitry Stogov		call_info |= ((flag) << ZEND_CALL_INFO_SHIFT); \
531a759967dSDmitry Stogov	} while (0)
532a759967dSDmitry Stogov
5333a794d39SDmitry Stogov#define ZEND_DEL_CALL_FLAG_EX(call_info, flag) do { \
5343a794d39SDmitry Stogov		call_info &= ~((flag) << ZEND_CALL_INFO_SHIFT); \
5353a794d39SDmitry Stogov	} while (0)
5363a794d39SDmitry Stogov
537a759967dSDmitry Stogov#define ZEND_ADD_CALL_FLAG(call, flag) do { \
538a759967dSDmitry Stogov		ZEND_ADD_CALL_FLAG_EX(Z_TYPE_INFO((call)->This), flag); \
5391da14c9fSDmitry Stogov	} while (0)
5401da14c9fSDmitry Stogov
5413a794d39SDmitry Stogov#define ZEND_DEL_CALL_FLAG(call, flag) do { \
5423a794d39SDmitry Stogov		ZEND_DEL_CALL_FLAG_EX(Z_TYPE_INFO((call)->This), flag); \
5433a794d39SDmitry Stogov	} while (0)
5443a794d39SDmitry Stogov
5451da14c9fSDmitry Stogov#define ZEND_CALL_NUM_ARGS(call) \
5461da14c9fSDmitry Stogov	(call)->This.u2.num_args
547b7715c7eSDmitry Stogov
548b7715c7eSDmitry Stogov#define ZEND_CALL_FRAME_SLOT \
54979354ba6SAnatol Belski	((int)((ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval))))
550b7715c7eSDmitry Stogov
551dcfe5877SDmitry Stogov#define ZEND_CALL_VAR(call, n) \
552dcfe5877SDmitry Stogov	((zval*)(((char*)(call)) + ((int)(n))))
553dcfe5877SDmitry Stogov
554dcfe5877SDmitry Stogov#define ZEND_CALL_VAR_NUM(call, n) \
555dcfe5877SDmitry Stogov	(((zval*)(call)) + (ZEND_CALL_FRAME_SLOT + ((int)(n))))
556dcfe5877SDmitry Stogov
557b7715c7eSDmitry Stogov#define ZEND_CALL_ARG(call, n) \
558dcfe5877SDmitry Stogov	ZEND_CALL_VAR_NUM(call, ((int)(n)) - 1)
559b7715c7eSDmitry Stogov
560bd9a2346SDmitry Stogov#define EX(element) 			((execute_data)->element)
561b66c89c4SAndi Gutmans
5621da14c9fSDmitry Stogov#define EX_CALL_INFO()			ZEND_CALL_INFO(execute_data)
5631da14c9fSDmitry Stogov#define EX_CALL_KIND()			ZEND_CALL_KIND(execute_data)
5641da14c9fSDmitry Stogov#define EX_NUM_ARGS()			ZEND_CALL_NUM_ARGS(execute_data)
5657044f9c6SAnthony Ferrara
56659356126SDmitry Stogov#define ZEND_CALL_USES_STRICT_TYPES(call) \
56759356126SDmitry Stogov	(((call)->func->common.fn_flags & ZEND_ACC_STRICT_TYPES) != 0)
56859356126SDmitry Stogov
56959356126SDmitry Stogov#define EX_USES_STRICT_TYPES() \
57059356126SDmitry Stogov	ZEND_CALL_USES_STRICT_TYPES(execute_data)
57159356126SDmitry Stogov
57259356126SDmitry Stogov#define ZEND_ARG_USES_STRICT_TYPES() \
57359356126SDmitry Stogov	(EG(current_execute_data)->prev_execute_data && \
57459356126SDmitry Stogov	 EG(current_execute_data)->prev_execute_data->func && \
57559356126SDmitry Stogov	 ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)->prev_execute_data))
57659356126SDmitry Stogov
57759356126SDmitry Stogov#define ZEND_RET_USES_STRICT_TYPES() \
57859356126SDmitry Stogov	ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data))
5791da14c9fSDmitry Stogov
580dcfe5877SDmitry Stogov#define EX_VAR(n)				ZEND_CALL_VAR(execute_data, n)
581dcfe5877SDmitry Stogov#define EX_VAR_NUM(n)			ZEND_CALL_VAR_NUM(execute_data, n)
582573b4602SAndi Gutmans
583e603769cSDmitry Stogov#define EX_VAR_TO_NUM(n)		((uint32_t)(ZEND_CALL_VAR(NULL, n) - ZEND_CALL_VAR_NUM(NULL, 0)))
5849a8fbdf2SDmitry Stogov
585843c1657SDmitry Stogov#define ZEND_OPLINE_TO_OFFSET(opline, target) \
586843c1657SDmitry Stogov	((char*)(target) - (char*)(opline))
587843c1657SDmitry Stogov
58814e29f51SDmitry Stogov#define ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline_num) \
58914e29f51SDmitry Stogov	((char*)&(op_array)->opcodes[opline_num] - (char*)(opline))
59014e29f51SDmitry Stogov
59114e29f51SDmitry Stogov#define ZEND_OFFSET_TO_OPLINE(base, offset) \
59214e29f51SDmitry Stogov	((zend_op*)(((char*)(base)) + (int)offset))
59314e29f51SDmitry Stogov
59414e29f51SDmitry Stogov#define ZEND_OFFSET_TO_OPLINE_NUM(op_array, base, offset) \
59514e29f51SDmitry Stogov	(ZEND_OFFSET_TO_OPLINE(base, offset) - op_array->opcodes)
59614e29f51SDmitry Stogov
59714e29f51SDmitry Stogov#if ZEND_USE_ABS_JMP_ADDR
59814e29f51SDmitry Stogov
59914e29f51SDmitry Stogov/* run-time jump target */
60014e29f51SDmitry Stogov# define OP_JMP_ADDR(opline, node) \
60114e29f51SDmitry Stogov	(node).jmp_addr
60214e29f51SDmitry Stogov
603843c1657SDmitry Stogov# define ZEND_SET_OP_JMP_ADDR(opline, node, val) do { \
604843c1657SDmitry Stogov		(node).jmp_addr = (val); \
605843c1657SDmitry Stogov	} while (0)
606843c1657SDmitry Stogov
60714e29f51SDmitry Stogov/* convert jump target from compile-time to run-time */
60814e29f51SDmitry Stogov# define ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, node) do { \
60914e29f51SDmitry Stogov		(node).jmp_addr = (op_array)->opcodes + (node).opline_num; \
61014e29f51SDmitry Stogov	} while (0)
61114e29f51SDmitry Stogov
61214e29f51SDmitry Stogov/* convert jump target back from run-time to compile-time */
61314e29f51SDmitry Stogov# define ZEND_PASS_TWO_UNDO_JMP_TARGET(op_array, opline, node) do { \
61414e29f51SDmitry Stogov		(node).opline_num = (node).jmp_addr - (op_array)->opcodes; \
61514e29f51SDmitry Stogov	} while (0)
61614e29f51SDmitry Stogov
61714e29f51SDmitry Stogov#else
61814e29f51SDmitry Stogov
61914e29f51SDmitry Stogov/* run-time jump target */
62014e29f51SDmitry Stogov# define OP_JMP_ADDR(opline, node) \
62114e29f51SDmitry Stogov	ZEND_OFFSET_TO_OPLINE(opline, (node).jmp_offset)
62214e29f51SDmitry Stogov
623843c1657SDmitry Stogov# define ZEND_SET_OP_JMP_ADDR(opline, node, val) do { \
624843c1657SDmitry Stogov		(node).jmp_offset = ZEND_OPLINE_TO_OFFSET(opline, val); \
625843c1657SDmitry Stogov	} while (0)
626843c1657SDmitry Stogov
62714e29f51SDmitry Stogov/* convert jump target from compile-time to run-time */
62814e29f51SDmitry Stogov# define ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, node) do { \
62914e29f51SDmitry Stogov		(node).jmp_offset = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, (node).opline_num); \
63014e29f51SDmitry Stogov	} while (0)
63114e29f51SDmitry Stogov
63214e29f51SDmitry Stogov/* convert jump target back from run-time to compile-time */
63314e29f51SDmitry Stogov# define ZEND_PASS_TWO_UNDO_JMP_TARGET(op_array, opline, node) do { \
63414e29f51SDmitry Stogov		(node).opline_num = ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, (node).jmp_offset); \
635b7a7b1a6SStanislav Malyshev	} while (0)
63614e29f51SDmitry Stogov
63714e29f51SDmitry Stogov#endif
63814e29f51SDmitry Stogov
63914e29f51SDmitry Stogov/* constant-time constant */
64014e29f51SDmitry Stogov# define CT_CONSTANT_EX(op_array, num) \
64114e29f51SDmitry Stogov	((op_array)->literals + (num))
64214e29f51SDmitry Stogov
64314e29f51SDmitry Stogov# define CT_CONSTANT(node) \
64414e29f51SDmitry Stogov	CT_CONSTANT_EX(CG(active_op_array), (node).constant)
64514e29f51SDmitry Stogov
64614e29f51SDmitry Stogov#if ZEND_USE_ABS_CONST_ADDR
64714e29f51SDmitry Stogov
64814e29f51SDmitry Stogov/* run-time constant */
649e70618afSDmitry Stogov# define RT_CONSTANT(opline, node) \
650