php-src/Zend/zend_compile.h

1125 lines
43 KiB
C
Raw Normal View History

1999-04-08 02:10:10 +08:00
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
2019-01-30 17:23:29 +08:00
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
1999-04-08 02:10:10 +08:00
+----------------------------------------------------------------------+
2001-12-11 23:16:21 +08:00
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
2001-12-11 23:16:21 +08:00
| http://www.zend.com/license/2_00.txt. |
1999-07-16 22:58:16 +08:00
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
1999-04-08 02:10:10 +08:00
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@php.net> |
| Zeev Suraski <zeev@php.net> |
1999-04-08 02:10:10 +08:00
+----------------------------------------------------------------------+
*/
#ifndef ZEND_COMPILE_H
#define ZEND_COMPILE_H
1999-04-08 02:10:10 +08:00
#include "zend.h"
#include "zend_ast.h"
1999-04-15 05:03:25 +08:00
#include <stdarg.h>
1999-04-15 05:03:25 +08:00
1999-04-08 02:10:10 +08:00
#include "zend_llist.h"
#define SET_UNUSED(op) op ## _type = IS_UNUSED
1999-04-08 02:10:10 +08:00
#define MAKE_NOP(opline) do { \
2015-08-06 20:40:40 +08:00
(opline)->op1.num = 0; \
(opline)->op2.num = 0; \
(opline)->result.num = 0; \
(opline)->opcode = ZEND_NOP; \
(opline)->op1_type = IS_UNUSED; \
(opline)->op2_type = IS_UNUSED; \
(opline)->result_type = IS_UNUSED; \
} while (0)
2014-07-28 21:23:00 +08:00
#define RESET_DOC_COMMENT() do { \
if (CG(doc_comment)) { \
zend_string_release_ex(CG(doc_comment), 0); \
2014-07-28 21:23:00 +08:00
CG(doc_comment) = NULL; \
} \
} while (0)
1999-04-08 02:10:10 +08:00
typedef struct _zend_op_array zend_op_array;
typedef struct _zend_op zend_op;
1999-04-08 02:10:10 +08:00
/* On 64-bit systems less optimal, but more compact VM code leads to better
* performance. So on 32-bit systems we use absolute addresses for jump
* targets and constants, but on 64-bit systems relative 32-bit offsets */
#if SIZEOF_SIZE_T == 4
# define ZEND_USE_ABS_JMP_ADDR 1
# define ZEND_USE_ABS_CONST_ADDR 1
#else
# define ZEND_USE_ABS_JMP_ADDR 0
# define ZEND_USE_ABS_CONST_ADDR 0
#endif
typedef union _znode_op {
2014-08-26 01:28:33 +08:00
uint32_t constant;
uint32_t var;
uint32_t num;
uint32_t opline_num; /* Needs to be signed */
#if ZEND_USE_ABS_JMP_ADDR
zend_op *jmp_addr;
#else
uint32_t jmp_offset;
#endif
#if ZEND_USE_ABS_CONST_ADDR
zval *zv;
#endif
} znode_op;
typedef struct _znode { /* used only during compilation */
Fix "forech" statemt behaviour according to https://wiki.php.net/rfc/php7_foreach Squashed commit of the following: commit 1e41295097576dbce6c197ddb7507c07ccae3cbe Author: Dmitry Stogov <dmitry@zend.com> Date: Sat Jan 31 07:28:58 2015 +0300 Generalize HashTableIterator API to allows its usage without involvement of HashTable.nInternalPonter commit 5406f21b11e563069d64045e599693b51c444b63 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jan 30 18:08:43 2015 +0300 Reduced alghorithms complexity commit b37f1d58d2a141b6e1d980a461ccb588d4317d2e Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jan 30 18:08:30 2015 +0300 Fixed test name commit fb2d079645829b12ed4e55a461034df6400bc430 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jan 30 18:08:05 2015 +0300 API cleanup commit 08302c0d6d1cab279b9f2129df03a057baddf2ff Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jan 30 14:20:46 2015 +0300 Make array_splice() to preserve foreach hash position commit cc4b7be41e2e2b9b0d7a3c8e98466b8886692e6e Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jan 30 12:24:31 2015 +0300 Make internal function, operation on array passed by reference, to preserve foreach hash position commit 5aa9712b0a30303aadfe3bdd8ae1f072ca3e6ba1 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jan 30 09:49:35 2015 +0300 Implement consistent behavior for foreach by value over plain object commit 4c5b385ff53ae9f0b52572e98c4db801f56603b0 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jan 30 07:56:37 2015 +0300 More careful iterators update. commit 721fc9e80d2ee8f2cd79c8c3cdceffae2c72de92 Author: Dmitry Stogov <dmitry@zend.com> Date: Thu Jan 29 21:43:28 2015 +0300 Added new test commit 15a23b1218b3e38630d677751a975907daa2cd54 Author: Dmitry Stogov <dmitry@zend.com> Date: Thu Jan 29 21:05:02 2015 +0300 Reimplement iteration magic with HashTableIterators (see https://wiki.php.net/rfc/php7_foreach#implementation_details) commit 10a3260b1f16b6075fd8140f673dfef4d5efea91 Author: Dmitry Stogov <dmitry@zend.com> Date: Thu Jan 29 21:04:44 2015 +0300 New test commit eef80c583762d1e98d177cdbb27e3a8a6b0c4539 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Jan 28 16:52:21 2015 +0300 Fixed foreach by reference iteration over constant array commit 61e739187391661e2d541947bec25d7dcc4479f3 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Jan 28 14:59:54 2015 +0300 Fixed temporary variable re-allocation pass commit 92e90c09f085c22707ff4a59201f016f56e0ef8b Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Jan 28 12:44:57 2015 +0300 Fixed operand destruction in case of exceptions in iterator commit dd2a36a2074bbb0cb31de00b66dcf2812d6d753f Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Jan 28 10:02:34 2015 +0300 Use GET_OP1_ZVAL_PTR_DEREF() (IS_TMP_VAR and IS_CONST can't be IS_REFERENCE) commit 4638f7b91407c48710007af82a68da0007c820f2 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Jan 28 07:43:28 2015 +0300 Change "foreach" statement behavior (this is just a PoC yet) - "foreach by value" don't relay on internal array/object pointer and doesnt perform array duplication. It just locks it incrementing reference counter. If the original array is modified by some code, the copy on write is performed and "foreach" still work with the old copy. - it makes no difference if array given to "foreach by value" is reference itself - "foreach by reference" still use internal array/object pointer and should work similar to PHP-5. (This id not completely implemented)
2015-02-12 18:57:12 +08:00
zend_uchar op_type;
zend_uchar flag;
1999-04-08 02:10:10 +08:00
union {
znode_op op;
zval constant; /* replaced by literal/zv */
1999-04-08 02:10:10 +08:00
} u;
} znode;
2014-06-07 19:06:53 +08:00
/* Temporarily defined here, to avoid header ordering issues */
typedef struct _zend_ast_znode {
zend_ast_kind kind;
zend_ast_attr attr;
uint32_t lineno;
2014-06-07 19:06:53 +08:00
znode node;
} zend_ast_znode;
2018-03-15 20:40:04 +08:00
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node);
static zend_always_inline znode *zend_ast_get_znode(zend_ast *ast) {
2014-06-07 19:06:53 +08:00
return &((zend_ast_znode *) ast)->node;
}
typedef struct _zend_declarables {
zend_long ticks;
} zend_declarables;
/* Compilation context that is different for each file, but shared between op arrays. */
typedef struct _zend_file_context {
zend_declarables declarables;
zend_string *current_namespace;
zend_bool in_namespace;
zend_bool has_bracketed_namespaces;
HashTable *imports;
HashTable *imports_function;
HashTable *imports_const;
HashTable seen_symbols;
} zend_file_context;
typedef struct {
uint32_t offset;
uint32_t len;
} zend_lexer_ident_ref;
2014-07-27 18:45:38 +08:00
typedef union _zend_parser_stack_elem {
zend_ast *ast;
zend_string *str;
zend_ulong num;
unsigned char *ptr;
zend_lexer_ident_ref ident;
2014-07-27 18:45:38 +08:00
} zend_parser_stack_elem;
2014-12-14 06:06:14 +08:00
void zend_compile_top_stmt(zend_ast *ast);
void zend_compile_stmt(zend_ast *ast);
void zend_compile_expr(znode *node, zend_ast *ast);
zend_op *zend_compile_var(znode *node, zend_ast *ast, uint32_t type, int by_ref);
2014-12-14 06:06:14 +08:00
void zend_eval_const_expr(zend_ast **ast_ptr);
void zend_const_expr_to_zval(zval *result, zend_ast *ast);
2014-06-07 19:06:53 +08:00
typedef int (*user_opcode_handler_t) (zend_execute_data *execute_data);
1999-04-08 02:10:10 +08:00
struct _zend_op {
const void *handler;
znode_op op1;
znode_op op2;
znode_op result;
uint32_t extended_value;
uint32_t lineno;
2002-11-06 05:35:05 +08:00
zend_uchar opcode;
zend_uchar op1_type;
zend_uchar op2_type;
zend_uchar result_type;
};
1999-04-08 02:10:10 +08:00
Squashed commit of the following: commit 03cf871f1576f08b2348c141b209894a7bf17a86 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:31 2015 +0300 Revert "Fixed bug #62210 (Exceptions can leak temporary variables. As a part of the fix serious refactoring was done. op_array->brk_cont_array was removed, and replaced with more general and speed efficient op_array->T_liveliness. ZEND_GOTO opcode is always replaced by ZEND_JMP at compile time). (Bob, Dmitry, Laruence)" This reverts commit 5ee841325901a4b040cfea56292a24702fe224d9. commit 285a68227ce3d380e821a24fa389aa5239bd3fe1 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:26 2015 +0300 Revert "Tuned off dubugging of live ranges" This reverts commit 404dc93d35f7061fc4b1b41ad6cb0721b9b52bcc. commit 93d9d11157301ee2ec99afb6f5744b126d17f637 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:17 2015 +0300 Revert "Remove loop_var_stack" This reverts commit b3a4c05071c3786e27e1326fa1b4d5acad62fccd. commit ede68ebbc284aec79e3f719f2c8dbf9da6907752 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:12 2015 +0300 Revert "ZEND_SEPARATE reuses temporaries" This reverts commit 1852f538b9f8d5e7d67fe5a4f6080396d8b10034. commit 96d8995dc1f517fb01b481736273767509f76c47 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:10 2015 +0300 Revert "Add assertion in liveliness computation" This reverts commit ed14019e8c0c852480eebc6fc552d8c3d939dce1. commit 0649d7bfef152e6cc8e67b922534e9946c634d9c Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:07 2015 +0300 Revert "Fixed invalid live-range detection" This reverts commit 54f367ee2a2e4cb7c952b17915c226fdc56038ab. commit dfe8f3851f6b04595eb089323e3492115a59363e Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:04 2015 +0300 Revert "Add test guaranteeing that loop vars are only freed after potential return type exceptions" This reverts commit f5db5a558d550bf441373febebbb02f3884209d1. commit 52a94aad6f48a199358cc07f7e4f56bb73050504 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:01 2015 +0300 Revert "Fixed exception habdling on "return" statement." This reverts commit 17c5315bdf8f8087979aeb55f6d3a512ba197cf5. commit 6e90ad7331901711e89c2ceb2bcab5023e5cee60 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:44:58 2015 +0300 Revert "Fix too early terminated temporary range with break/cont/goto" This reverts commit cc876c04b420589cb1f62b650d0c0e24975dd4af. commit 7b766e44b1970e4031f75109c302c07ead2c05cb Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:44:55 2015 +0300 Revert "Fixed exception catching on break/continue" This reverts commit 8c3f701eebfa92d761bb368cfa8c2d1ccf821b9d.
2015-07-10 08:31:52 +08:00
typedef struct _zend_brk_cont_element {
int start;
int cont;
int brk;
int parent;
zend_bool is_switch;
Squashed commit of the following: commit 03cf871f1576f08b2348c141b209894a7bf17a86 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:31 2015 +0300 Revert "Fixed bug #62210 (Exceptions can leak temporary variables. As a part of the fix serious refactoring was done. op_array->brk_cont_array was removed, and replaced with more general and speed efficient op_array->T_liveliness. ZEND_GOTO opcode is always replaced by ZEND_JMP at compile time). (Bob, Dmitry, Laruence)" This reverts commit 5ee841325901a4b040cfea56292a24702fe224d9. commit 285a68227ce3d380e821a24fa389aa5239bd3fe1 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:26 2015 +0300 Revert "Tuned off dubugging of live ranges" This reverts commit 404dc93d35f7061fc4b1b41ad6cb0721b9b52bcc. commit 93d9d11157301ee2ec99afb6f5744b126d17f637 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:17 2015 +0300 Revert "Remove loop_var_stack" This reverts commit b3a4c05071c3786e27e1326fa1b4d5acad62fccd. commit ede68ebbc284aec79e3f719f2c8dbf9da6907752 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:12 2015 +0300 Revert "ZEND_SEPARATE reuses temporaries" This reverts commit 1852f538b9f8d5e7d67fe5a4f6080396d8b10034. commit 96d8995dc1f517fb01b481736273767509f76c47 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:10 2015 +0300 Revert "Add assertion in liveliness computation" This reverts commit ed14019e8c0c852480eebc6fc552d8c3d939dce1. commit 0649d7bfef152e6cc8e67b922534e9946c634d9c Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:07 2015 +0300 Revert "Fixed invalid live-range detection" This reverts commit 54f367ee2a2e4cb7c952b17915c226fdc56038ab. commit dfe8f3851f6b04595eb089323e3492115a59363e Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:04 2015 +0300 Revert "Add test guaranteeing that loop vars are only freed after potential return type exceptions" This reverts commit f5db5a558d550bf441373febebbb02f3884209d1. commit 52a94aad6f48a199358cc07f7e4f56bb73050504 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:45:01 2015 +0300 Revert "Fixed exception habdling on "return" statement." This reverts commit 17c5315bdf8f8087979aeb55f6d3a512ba197cf5. commit 6e90ad7331901711e89c2ceb2bcab5023e5cee60 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:44:58 2015 +0300 Revert "Fix too early terminated temporary range with break/cont/goto" This reverts commit cc876c04b420589cb1f62b650d0c0e24975dd4af. commit 7b766e44b1970e4031f75109c302c07ead2c05cb Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Jul 10 02:44:55 2015 +0300 Revert "Fixed exception catching on break/continue" This reverts commit 8c3f701eebfa92d761bb368cfa8c2d1ccf821b9d.
2015-07-10 08:31:52 +08:00
} zend_brk_cont_element;
typedef struct _zend_label {
int brk_cont;
uint32_t opline_num;
} zend_label;
typedef struct _zend_try_catch_element {
uint32_t try_op;
uint32_t catch_op; /* ketchup! */
uint32_t finally_op;
uint32_t finally_end;
} zend_try_catch_element;
#define ZEND_LIVE_TMPVAR 0
#define ZEND_LIVE_LOOP 1
#define ZEND_LIVE_SILENCE 2
#define ZEND_LIVE_ROPE 3
#define ZEND_LIVE_NEW 4
#define ZEND_LIVE_MASK 7
typedef struct _zend_live_range {
uint32_t var; /* low bits are used for variable type (ZEND_LIVE_* macros) */
uint32_t start;
uint32_t end;
} zend_live_range;
/* Compilation context that is different for each op array. */
typedef struct _zend_oparray_context {
uint32_t opcodes_size;
int vars_size;
int literals_size;
uint32_t fast_call_var;
Fixed bug #72213 (Finally leaks on nested exceptions). Squashed commit of the following: commit 8461b0407fc9eab0869d43b84e6a92ba2fe06997 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed May 25 00:34:42 2016 +0300 Rmoved zend_try_catch_element.parent and walk through op_array.try_catch_array backward from the current try_cacth_offset. commit 0c71e249649bed178bfbef30bb3e63c57f07af05 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed May 25 00:04:53 2016 +0300 Move SAVE_OPLINE() to its original place commit 111432a4df738fcd65878a42f23194dc3c4983a2 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed May 25 00:01:10 2016 +0300 Separate the common part of ZEND_HANDLE_EXCEPTION and FAST_RET into zend_dispatch_try_catch_finally_helper. commit 4f21c06c2ec17819a708bc037f318784554a6ecd Author: Nikita Popov <nikic@php.net> Date: Tue May 24 14:55:27 2016 +0200 Improve finally fix commit da5c7274997b8308e682b5bf280124e3a1483086 Author: Dmitry Stogov <dmitry@zend.com> Date: Tue May 24 10:36:08 2016 +0300 Fixed Zend/tests/try/bug70228_3.phpt and Zend/tests/try/bug70228_4.phpt commit cfcedf2fb4f4fc1f7de9f7d53a3037fed7795f19 Author: Dmitry Stogov <dmitry@zend.com> Date: Tue May 24 02:59:27 2016 +0300 Added test commit 4c6aa93d43da941eb4fda15b48154bfb104bdc04 Author: Dmitry Stogov <dmitry@zend.com> Date: Tue May 24 00:38:20 2016 +0300 Added tests commit 8a8f4704b0eca2e460d42c1f253a363b0db8e510 Author: Dmitry Stogov <dmitry@zend.com> Date: Mon May 23 23:27:34 2016 +0300 Fixed bug #72213 (Finally leaks on nested exceptions)
2016-05-25 06:25:12 +08:00
uint32_t try_catch_offset;
int current_brk_cont;
int last_brk_cont;
zend_brk_cont_element *brk_cont_array;
HashTable *labels;
} zend_oparray_context;
/* Class, property and method flags class|meth.|prop.|const*/
/* | | | */
/* Common flags | | | */
/* ============ | | | */
/* | | | */
2018-09-11 22:21:17 +08:00
/* Visibility flags (public < protected < private) | | | */
#define ZEND_ACC_PUBLIC (1 << 0) /* | X | X | X */
#define ZEND_ACC_PROTECTED (1 << 1) /* | X | X | X */
#define ZEND_ACC_PRIVATE (1 << 2) /* | X | X | X */
/* | | | */
/* Property or method overrides private one | | | */
#define ZEND_ACC_CHANGED (1 << 3) /* | X | X | */
/* | | | */
2019-03-26 21:14:29 +08:00
/* Static method or property | | | */
2018-09-11 22:21:17 +08:00
#define ZEND_ACC_STATIC (1 << 4) /* | X | X | */
/* | | | */
/* Promoted property / parameter | | | */
#define ZEND_ACC_PROMOTED (1 << 5) /* | | X | X */
/* | | | */
/* Final class or method | | | */
2018-09-11 22:21:17 +08:00
#define ZEND_ACC_FINAL (1 << 5) /* X | X | | */
/* | | | */
/* Abstract method | | | */
2018-09-11 22:21:17 +08:00
#define ZEND_ACC_ABSTRACT (1 << 6) /* X | X | | */
#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS (1 << 6) /* X | | | */
/* | | | */
2018-10-02 20:38:55 +08:00
/* Immutable op_array and class_entries | | | */
/* (implemented only for lazy loading of op_arrays) | | | */
2018-10-17 21:56:32 +08:00
#define ZEND_ACC_IMMUTABLE (1 << 7) /* X | X | | */
/* | | | */
/* Function has typed arguments / class has typed props | | | */
#define ZEND_ACC_HAS_TYPE_HINTS (1 << 8) /* X | X | | */
/* | | | */
2018-10-19 18:22:29 +08:00
/* Top-level class or function declaration | | | */
#define ZEND_ACC_TOP_LEVEL (1 << 9) /* X | X | | */
/* | | | */
/* op_array or class is preloaded | | | */
#define ZEND_ACC_PRELOADED (1 << 10) /* X | X | | */
/* | | | */
/* Class Flags (unused: 13, 14, 15, 24...) | | | */
/* =========== | | | */
/* | | | */
2018-09-11 22:21:17 +08:00
/* Special class types | | | */
#define ZEND_ACC_INTERFACE (1 << 0) /* X | | | */
#define ZEND_ACC_TRAIT (1 << 1) /* X | | | */
#define ZEND_ACC_ANON_CLASS (1 << 2) /* X | | | */
/* | | | */
2019-03-26 21:14:29 +08:00
/* Class linked with parent, interfaces and traits | | | */
#define ZEND_ACC_LINKED (1 << 3) /* X | | | */
2018-09-11 22:21:17 +08:00
/* | | | */
2019-03-26 21:14:29 +08:00
/* Class is abstract, since it is set by any | | | */
/* abstract method | | | */
#define ZEND_ACC_IMPLICIT_ABSTRACT_CLASS (1 << 4) /* X | | | */
/* | | | */
2018-09-11 22:21:17 +08:00
/* Class has magic methods __get/__set/__unset/ | | | */
/* __isset that use guards | | | */
#define ZEND_ACC_USE_GUARDS (1 << 11) /* X | | | */
/* | | | */
2018-09-11 22:21:17 +08:00
/* Class constants updated | | | */
#define ZEND_ACC_CONSTANTS_UPDATED (1 << 12) /* X | | | */
/* | | | */
/* User class has methods with static variables | | | */
#define ZEND_HAS_STATIC_IN_METHODS (1 << 16) /* X | | | */
2018-10-17 21:12:46 +08:00
/* | | | */
/* Whether all property types are resolved to CEs | | | */
#define ZEND_ACC_PROPERTY_TYPES_RESOLVED (1 << 17) /* X | | | */
/* | | | */
/* Children must reuse parent get_iterator() | | | */
#define ZEND_ACC_REUSE_GET_ITERATOR (1 << 18) /* X | | | */
/* | | | */
Support full variance if autoloading is used Keep track of delayed variance obligations and check them after linking a class is otherwise finished. Obligations may either be unresolved method compatibility (because the necessecary classes aren't available yet) or open parent/interface dependencies. The latter occur because we allow the use of not fully linked classes as parents/interfaces now. An important aspect of the implementation is we do not require classes involved in variance checks to be fully linked in order for the class to be fully linked. Because the involved types do have to exist in the class table (as partially linked classes) and we do check these for correct variance, we have the guarantee that either those classes will successfully link lateron or generate an error, but there is no way to actually use them until that point and as such no possibility of violating the variance contract. This is important because it ensures that a class declaration always either errors or will produce an immediately usable class afterwards -- there are no cases where the finalization of the class declaration has to be delayed until a later time, as earlier variants of this patch did. Because variance checks deal with classes in various stages of linking, we need to use a special instanceof implementation that supports this, and also introduce finer-grained flags that tell us which parts have been linked already and which haven't. Class autoloading for variance checks is delayed into a separate stage after the class is otherwise linked and before delayed variance obligations are processed. This separation is needed to handle cases like A extends B extends C, where B is the autoload root, but C is required to check variance. This could end up loading C while the class structure of B is in an inconsistent state.
2019-05-27 17:39:56 +08:00
/* Parent class is resolved (CE). | | | */
#define ZEND_ACC_RESOLVED_PARENT (1 << 19) /* X | | | */
/* | | | */
/* Interfaces are resolved (CEs). | | | */
#define ZEND_ACC_RESOLVED_INTERFACES (1 << 20) /* X | | | */
/* | | | */
/* Class has unresolved variance obligations. | | | */
#define ZEND_ACC_UNRESOLVED_VARIANCE (1 << 21) /* X | | | */
2019-05-22 17:13:28 +08:00
/* | | | */
/* Class is linked apart from variance obligations. | | | */
#define ZEND_ACC_NEARLY_LINKED (1 << 22) /* X | | | */
/* | | | */
/* Whether this class was used in its unlinked state. | | | */
#define ZEND_ACC_HAS_UNLINKED_USES (1 << 23) /* X | | | */
/* | | | */
/* Function Flags (unused: 17, 23, 26, 29) | | | */
/* ============== | | | */
/* | | | */
2018-09-11 22:21:17 +08:00
/* deprecation flag | | | */
#define ZEND_ACC_DEPRECATED (1 << 11) /* | X | | */
/* | | | */
2018-09-11 22:21:17 +08:00
/* Function returning by reference | | | */
#define ZEND_ACC_RETURN_REFERENCE (1 << 12) /* | X | | */
2018-09-11 22:21:17 +08:00
/* | | | */
/* Function has a return type | | | */
#define ZEND_ACC_HAS_RETURN_TYPE (1 << 13) /* | X | | */
2018-09-11 22:21:17 +08:00
/* | | | */
/* Function with variable number of arguments | | | */
#define ZEND_ACC_VARIADIC (1 << 14) /* | X | | */
2018-09-11 22:21:17 +08:00
/* | | | */
/* op_array has finally blocks (user only) | | | */
#define ZEND_ACC_HAS_FINALLY_BLOCK (1 << 15) /* | X | | */
/* | | | */
/* "main" op_array with | | | */
/* ZEND_DECLARE_CLASS_DELAYED opcodes | | | */
#define ZEND_ACC_EARLY_BINDING (1 << 16) /* | X | | */
/* | | | */
/* call through user function trampoline. e.g. | | | */
/* __call, __callstatic | | | */
#define ZEND_ACC_CALL_VIA_TRAMPOLINE (1 << 18) /* | X | | */
/* | | | */
/* disable inline caching | | | */
#define ZEND_ACC_NEVER_CACHE (1 << 19) /* | X | | */
/* | | | */
2018-09-11 22:21:17 +08:00
/* Closure related | | | */
#define ZEND_ACC_CLOSURE (1 << 20) /* | X | | */
#define ZEND_ACC_FAKE_CLOSURE (1 << 21) /* | X | | */
/* | | | */
/* run_time_cache allocated on heap (user only) | | | */
#define ZEND_ACC_HEAP_RT_CACHE (1 << 22) /* | X | | */
/* | | | */
/* method flag used by Closure::__invoke() (int only) | | | */
#define ZEND_ACC_USER_ARG_INFO (1 << 22) /* | X | | */
/* | | | */
#define ZEND_ACC_GENERATOR (1 << 24) /* | X | | */
/* | | | */
/* function was processed by pass two (user only) | | | */
#define ZEND_ACC_DONE_PASS_TWO (1 << 25) /* | X | | */
/* | | | */
/* internal function is allocated at arena (int only) | | | */
#define ZEND_ACC_ARENA_ALLOCATED (1 << 25) /* | X | | */
/* | | | */
/* op_array is a clone of trait method | | | */
#define ZEND_ACC_TRAIT_CLONE (1 << 27) /* | X | | */
2018-12-03 21:57:27 +08:00
/* | | | */
/* functions is a constructor | | | */
#define ZEND_ACC_CTOR (1 << 28) /* | X | | */
/* | | | */
/* closure uses $this | | | */
#define ZEND_ACC_USES_THIS (1 << 30) /* | X | | */
/* | | | */
/* op_array uses strict mode types | | | */
#define ZEND_ACC_STRICT_TYPES (1U << 31) /* | X | | */
#define ZEND_ACC_PPP_MASK (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE)
Squashed commit of the following: commit 2399fc84c541da9c2176c5b7f6dd039a3c84dc64 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Apr 10 12:38:08 2015 +0300 Removed useless assignment commit 796b6338174348eee0d74a67706d77b7ce1a60c3 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Apr 10 12:35:31 2015 +0300 Fixed execution with overriden zend_execute_ex() commit 4a9fb125aa999059f8bc42ebb6ee573c7866b35b Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Apr 10 02:02:58 2015 +0300 Fixed executor without global registers commit d456c30e00589ccda35a4b57ae903ef2d3c07d95 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Apr 10 01:30:35 2015 +0300 Restored original behavior for tests/classes/__call_004.phpt commit 479646d37fef050536f1afb12b082618f1f1a3d0 Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Apr 10 00:32:17 2015 +0300 Fixed test. We don't keep stack frame for fake function anymore. commit 9ae61e33e24b2c811d4ab1ca4ab22847c64a780e Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Apr 10 00:30:09 2015 +0300 Use ZEND_ACC_CALL_VIA_TRAMPOLINE instead of ZEND_ACC_CALL_VIA_HANDLER. Keep ZEND_ACC_CALL_VIA_HANDLER for compatibility. commit 0a8403a2a0c27aa3db271774f8559739a6b8400e Author: Dmitry Stogov <dmitry@zend.com> Date: Fri Apr 10 00:05:43 2015 +0300 Rename PROXY_CALL into CALL_TRAMPLINE. Generalize API to allow reuse EG(trampline) for other purposes. commit 4ea0525c10554e36185a0b8b6303106813b6a1c2 Author: Dmitry Stogov <dmitry@zend.com> Date: Thu Apr 9 23:22:25 2015 +0300 Reuse EG(proxy_call_op) for all proxy. Move proxy related functions from zend_objects_API to zend_object_handlers. commit 529bf737ca388ad56fb4ae20ccb81e6276f25ec0 Author: Dmitry Stogov <dmitry@zend.com> Date: Thu Apr 9 21:42:23 2015 +0300 Accurate use of proxy_call commit 5d62837d5ba3855743fe1981786ebd65d9da0b63 Merge: 83e749f 690843f Author: Dmitry Stogov <dmitry@zend.com> Date: Thu Apr 9 19:40:00 2015 +0300 Merge branch 'master' into opcodefy-call * master: Fixed GOTO executor Fixed typo Changed ArrayIterator implementation using zend_hash_iterator_... API. Allowed modification of itterated ArrayObject using the same behavior as proposed in `Fix "foreach" behavior`. Removed "Array was modified outside object and internal position is no longer valid" hack. commit 83e749ff3b6623e39b236a72e9b907d5b788ae5e Author: Dmitry Stogov <dmitry@zend.com> Date: Thu Apr 9 19:39:10 2015 +0300 Improved ZEND_PROXY_CALL commit 0c829afc534e6d5ff27a0dea3a4815da303bd1ef Author: Dmitry Stogov <dmitry@zend.com> Date: Thu Apr 9 15:14:49 2015 +0300 Reverted white-space changes commit df65144488afa3e9020d75e1ada5529b138afc5a Merge: 5fd2f97 97756d9 Author: Dmitry Stogov <dmitry@zend.com> Date: Thu Apr 9 14:37:07 2015 +0300 Merge branch 'opcodefy-call' of github.com:laruence/php-src into opcodefy-call * 'opcodefy-call' of github.com:laruence/php-src: Ready for PR Fixed static call Improve performance by using prealloated op_arrray Respect called_scope Support internal magical __call/__callStatic opcode-fy magical __callStatic Opcode-fy magical __call commit 97756d9190e07a072a7b48135304dc25a964845f Author: Xinchen Hui <laruence@gmail.com> Date: Thu Apr 9 19:07:59 2015 +0800 Ready for PR commit 74f993084627061e783645a866390b68e2981698 Author: Xinchen Hui <laruence@gmail.com> Date: Thu Apr 9 19:03:00 2015 +0800 Fixed static call commit ec1d9eb592db0c3b7b0e3d21e7f445ed8bccfd4d Author: Xinchen Hui <laruence@gmail.com> Date: Thu Apr 9 18:23:17 2015 +0800 Improve performance by using prealloated op_arrray commit df7fbbf949c99f2c5ae3da2a1199235651c7cc82 Author: Xinchen Hui <laruence@gmail.com> Date: Thu Apr 9 15:10:02 2015 +0800 Respect called_scope commit 769d1d59fb48b6f7f93d7412eefbf26135fa3e59 Author: Xinchen Hui <laruence@gmail.com> Date: Thu Apr 9 12:19:23 2015 +0800 Support internal magical __call/__callStatic commit a980fedd5b0e0683713dd4f6eaad62adf4b4732f Author: Xinchen Hui <laruence@gmail.com> Date: Wed Apr 8 18:35:41 2015 +0800 opcode-fy magical __callStatic commit 73855f7d53baa2efc2b8a88314f51c784c81b59d Author: Xinchen Hui <laruence@gmail.com> Date: Wed Apr 8 14:21:55 2015 +0800 Opcode-fy magical __call
2015-04-11 04:01:00 +08:00
/* call through internal function handler. e.g. Closure::invoke() */
#define ZEND_ACC_CALL_VIA_HANDLER ZEND_ACC_CALL_VIA_TRAMPOLINE
char *zend_visibility_string(uint32_t fn_flags);
2003-02-04 20:12:34 +08:00
typedef struct _zend_property_info {
2014-11-06 19:50:03 +08:00
uint32_t offset; /* property offset for object properties or
property index for static properties */
2014-08-26 01:28:33 +08:00
uint32_t flags;
zend_string *name;
zend_string *doc_comment;
HashTable *attributes;
zend_class_entry *ce;
zend_type type;
2003-02-04 20:12:34 +08:00
} zend_property_info;
2014-11-06 19:50:03 +08:00
#define OBJ_PROP(obj, offset) \
((zval*)((char*)(obj) + offset))
#define OBJ_PROP_NUM(obj, num) \
(&(obj)->properties_table[(num)])
#define OBJ_PROP_TO_OFFSET(num) \
((uint32_t)(XtOffsetOf(zend_object, properties_table) + sizeof(zval) * (num)))
2014-11-06 19:50:03 +08:00
#define OBJ_PROP_TO_NUM(offset) \
((offset - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval))
typedef struct _zend_class_constant {
zval value; /* access flags are stored in reserved: zval.u2.access_flags */
zend_string *doc_comment;
HashTable *attributes;
zend_class_entry *ce;
} zend_class_constant;
/* arg_info for internal functions */
2015-01-03 17:22:58 +08:00
typedef struct _zend_internal_arg_info {
const char *name;
zend_type type;
const char *default_value;
} zend_internal_arg_info;
/* arg_info for user functions */
typedef struct _zend_arg_info {
zend_string *name;
zend_type type;
zend_string *default_value;
} zend_arg_info;
/* the following structure repeats the layout of zend_internal_arg_info,
* but its fields have different meaning. It's used as the first element of
* arg_info array to define properties of internal functions.
* It's also used for the return type.
*/
typedef struct _zend_internal_function_info {
zend_uintptr_t required_num_args;
zend_type type;
const char *default_value;
} zend_internal_function_info;
1999-04-08 02:10:10 +08:00
struct _zend_op_array {
/* Common elements */
zend_uchar type;
zend_uchar arg_flags[3]; /* bitset of arg_info.pass_by_reference */
uint32_t fn_flags;
zend_string *function_name;
zend_class_entry *scope;
zend_function *prototype;
2014-08-26 01:28:33 +08:00
uint32_t num_args;
uint32_t required_num_args;
zend_arg_info *arg_info;
HashTable *attributes;
/* END of common elements */
1999-04-08 02:10:10 +08:00
int cache_size; /* number of run_time_cache_slots * sizeof(void*) */
int last_var; /* number of CV variables */
2018-06-25 13:26:38 +08:00
uint32_t T; /* number of temporary variables */
uint32_t last; /* number of opcodes */
1999-04-08 02:10:10 +08:00
zend_op *opcodes;
Immutable clases and op_arrays. Squashed commit of the following: commit cd0c36c3f943849e5b97a8dbe2dd029fbeab3df9 Merge: 4740dabb84 ad6738e886 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 14:43:38 2018 +0300 Merge branch 'master' into immutable * master: Remove the "auto" encoding Fixed bug #77025 Add vtbls for EUC-TW encoding commit 4740dabb843c6d4f7f866b4a2456073c9eaf4c77 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 14:12:28 2018 +0300 Reverted back ce->iterator_funcs_ptr. Initialize ce->iterator_funcs_ptr fields in immutable classes. commit ad7a78b253be970db70c2251e66f9297d8e7f829 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:46:30 2018 +0300 Added comment commit 0276ea51875bab37be01a4dc5e5a047c5698c571 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:42:43 2018 +0300 Added type cast commit c63fc5d5f19c58498108d1698055b2b442227eb3 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:36:51 2018 +0300 Moved static class members initialization into the proper place. commit b945548e9306b1826c881918858b5e5aa3eb3002 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:21:03 2018 +0300 Removed redundand assertion commit d5a41088401814c829847db212488f8aae39bcd2 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:19:13 2018 +0300 Removed duplicate code commit 8dadca8864e66de70a24bdf1181bcf7dd8fb27d7 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:05:43 2018 +0300 Hide offset encoding magic in ZEND_MAP_PTR_IS_OFFSET(), ZEND_MAP_PTR_OFFSET2PTR() and ZEND_MAP_PTR_PTR2OFFSET() macros. commit 9ef07c88bd76801e2d4fbfeab3ebfd6e6a67ac5f Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 10:48:29 2018 +0300 typo commit a06f0f3d3aba53e766046221ee44fb9720389ecc Merge: 94099586ec 3412345ffe Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 10:47:07 2018 +0300 Merge branch 'master' into immutable * master: Remove unused variable makefile_am_files Classify object handlers are required/optional Add support for getting SKIP_TAGSTART and SKIP_WHITE options Remove some obsolete config_vars.mk occurrences Remove bsd_converted from .gitignore Remove configuration parser and scanners ignores Remove obsolete buildconf.stamp from .gitignore [ci skip] Add magicdata.patch exception to .gitignore Remove outdated ext/spl/examples items from .gitignore Remove unused test.inc in ext/iconv/tests commit 94099586ec599117581ca01c15b1f6c5f749e23a Author: Dmitry Stogov <dmitry@zend.com> Date: Mon Oct 15 23:34:01 2018 +0300 Immutable clases and op_arrays
2018-10-17 20:52:50 +08:00
ZEND_MAP_PTR_DEF(void **, run_time_cache);
ZEND_MAP_PTR_DEF(HashTable *, static_variables_ptr);
HashTable *static_variables;
zend_string **vars; /* names of CV variables */
1999-04-08 02:10:10 +08:00
uint32_t *refcount;
1999-04-08 02:10:10 +08:00
int last_live_range;
int last_try_catch;
zend_live_range *live_range;
zend_try_catch_element *try_catch_array;
zend_string *filename;
2014-08-26 01:28:33 +08:00
uint32_t line_start;
uint32_t line_end;
zend_string *doc_comment;
int last_literal;
zval *literals;
1999-08-16 03:29:39 +08:00
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
1999-04-08 02:10:10 +08:00
};
#define ZEND_RETURN_VALUE 0
#define ZEND_RETURN_REFERENCE 1
/* zend_internal_function_handler */
typedef void (ZEND_FASTCALL *zif_handler)(INTERNAL_FUNCTION_PARAMETERS);
typedef struct _zend_internal_function {
/* Common elements */
zend_uchar type;
zend_uchar arg_flags[3]; /* bitset of arg_info.pass_by_reference */
uint32_t fn_flags;
zend_string* function_name;
zend_class_entry *scope;
zend_function *prototype;
2014-08-26 01:28:33 +08:00
uint32_t num_args;
uint32_t required_num_args;
zend_internal_arg_info *arg_info;
HashTable *attributes;
/* END of common elements */
1999-04-08 02:10:10 +08:00
zif_handler handler;
struct _zend_module_entry *module;
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
1999-04-08 02:10:10 +08:00
} zend_internal_function;
#define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? ZSTR_VAL((function)->common.scope->name) : "")
union _zend_function {
zend_uchar type; /* MUST be the first element of this struct! */
2016-04-29 18:11:27 +08:00
uint32_t quick_arg_flags;
1999-04-08 02:10:10 +08:00
struct {
zend_uchar type; /* never used */
zend_uchar arg_flags[3]; /* bitset of arg_info.pass_by_reference */
uint32_t fn_flags;
zend_string *function_name;
zend_class_entry *scope;
zend_function *prototype;
2014-08-26 01:28:33 +08:00
uint32_t num_args;
uint32_t required_num_args;
zend_arg_info *arg_info; /* index -1 represents the return value info, if any */
HashTable *attributes;
1999-04-08 02:10:10 +08:00
} common;
1999-04-08 02:10:10 +08:00
zend_op_array op_array;
zend_internal_function internal_function;
};
1999-04-08 02:10:10 +08:00
2002-10-20 04:57:15 +08:00
struct _zend_execute_data {
const zend_op *opline; /* executed opline */
zend_execute_data *call; /* current call */
zval *return_value;
zend_function *func; /* executed function */
zval This; /* this + call_info + num_args */
zend_execute_data *prev_execute_data;
zend_array *symbol_table;
void **run_time_cache; /* cache op_array->run_time_cache */
2002-10-20 04:57:15 +08:00
};
1999-04-08 02:10:10 +08:00
2019-04-11 07:08:32 +08:00
#define ZEND_CALL_HAS_THIS IS_OBJECT_EX
/* Top 16 bits of Z_TYPE_INFO(EX(This)) are used as call_info flags */
#define ZEND_CALL_FUNCTION (0 << 16)
#define ZEND_CALL_CODE (1 << 16)
#define ZEND_CALL_NESTED (0 << 17)
#define ZEND_CALL_TOP (1 << 17)
#define ZEND_CALL_ALLOCATED (1 << 18)
#define ZEND_CALL_FREE_EXTRA_ARGS (1 << 19)
#define ZEND_CALL_HAS_SYMBOL_TABLE (1 << 20)
#define ZEND_CALL_RELEASE_THIS (1 << 21)
#define ZEND_CALL_CLOSURE (1 << 22)
#define ZEND_CALL_FAKE_CLOSURE (1 << 23)
#define ZEND_CALL_GENERATOR (1 << 24)
#define ZEND_CALL_DYNAMIC (1 << 25)
#define ZEND_CALL_SEND_ARG_BY_REF (1u << 31)
2019-04-11 07:08:32 +08:00
#define ZEND_CALL_NESTED_FUNCTION (ZEND_CALL_FUNCTION | ZEND_CALL_NESTED)
#define ZEND_CALL_NESTED_CODE (ZEND_CALL_CODE | ZEND_CALL_NESTED)
#define ZEND_CALL_TOP_FUNCTION (ZEND_CALL_TOP | ZEND_CALL_FUNCTION)
#define ZEND_CALL_TOP_CODE (ZEND_CALL_CODE | ZEND_CALL_TOP)
#define ZEND_CALL_INFO(call) \
2019-04-11 07:08:32 +08:00
Z_TYPE_INFO((call)->This)
#define ZEND_CALL_KIND_EX(call_info) \
(call_info & (ZEND_CALL_CODE | ZEND_CALL_TOP))
#define ZEND_CALL_KIND(call) \
ZEND_CALL_KIND_EX(ZEND_CALL_INFO(call))
#define ZEND_ADD_CALL_FLAG_EX(call_info, flag) do { \
2019-04-11 07:08:32 +08:00
call_info |= (flag); \
} while (0)
#define ZEND_DEL_CALL_FLAG_EX(call_info, flag) do { \
2019-04-11 07:08:32 +08:00
call_info &= ~(flag); \
} while (0)
#define ZEND_ADD_CALL_FLAG(call, flag) do { \
ZEND_ADD_CALL_FLAG_EX(Z_TYPE_INFO((call)->This), flag); \
} while (0)
#define ZEND_DEL_CALL_FLAG(call, flag) do { \
ZEND_DEL_CALL_FLAG_EX(Z_TYPE_INFO((call)->This), flag); \
} while (0)
#define ZEND_CALL_NUM_ARGS(call) \
(call)->This.u2.num_args
#define ZEND_CALL_FRAME_SLOT \
((int)((ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval))))
#define ZEND_CALL_VAR(call, n) \
((zval*)(((char*)(call)) + ((int)(n))))
#define ZEND_CALL_VAR_NUM(call, n) \
(((zval*)(call)) + (ZEND_CALL_FRAME_SLOT + ((int)(n))))
#define ZEND_CALL_ARG(call, n) \
ZEND_CALL_VAR_NUM(call, ((int)(n)) - 1)
#define EX(element) ((execute_data)->element)
#define EX_CALL_INFO() ZEND_CALL_INFO(execute_data)
#define EX_CALL_KIND() ZEND_CALL_KIND(execute_data)
#define EX_NUM_ARGS() ZEND_CALL_NUM_ARGS(execute_data)
#define ZEND_CALL_USES_STRICT_TYPES(call) \
(((call)->func->common.fn_flags & ZEND_ACC_STRICT_TYPES) != 0)
#define EX_USES_STRICT_TYPES() \
ZEND_CALL_USES_STRICT_TYPES(execute_data)
#define ZEND_ARG_USES_STRICT_TYPES() \
(EG(current_execute_data)->prev_execute_data && \
EG(current_execute_data)->prev_execute_data->func && \
ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)->prev_execute_data))
#define ZEND_RET_USES_STRICT_TYPES() \
ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data))
#define EX_VAR(n) ZEND_CALL_VAR(execute_data, n)
#define EX_VAR_NUM(n) ZEND_CALL_VAR_NUM(execute_data, n)
1999-04-08 02:10:10 +08:00
#define EX_VAR_TO_NUM(n) ((uint32_t)((n) / sizeof(zval) - ZEND_CALL_FRAME_SLOT))
2020-02-27 21:48:43 +08:00
#define EX_NUM_TO_VAR(n) ((uint32_t)(((n) + ZEND_CALL_FRAME_SLOT) * sizeof(zval)))
#define ZEND_OPLINE_TO_OFFSET(opline, target) \
((char*)(target) - (char*)(opline))
#define ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline_num) \
((char*)&(op_array)->opcodes[opline_num] - (char*)(opline))
#define ZEND_OFFSET_TO_OPLINE(base, offset) \
((zend_op*)(((char*)(base)) + (int)offset))
#define ZEND_OFFSET_TO_OPLINE_NUM(op_array, base, offset) \
(ZEND_OFFSET_TO_OPLINE(base, offset) - op_array->opcodes)
#if ZEND_USE_ABS_JMP_ADDR
/* run-time jump target */
# define OP_JMP_ADDR(opline, node) \
(node).jmp_addr
# define ZEND_SET_OP_JMP_ADDR(opline, node, val) do { \
(node).jmp_addr = (val); \
} while (0)
/* convert jump target from compile-time to run-time */
# define ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, node) do { \
(node).jmp_addr = (op_array)->opcodes + (node).opline_num; \
} while (0)
/* convert jump target back from run-time to compile-time */
# define ZEND_PASS_TWO_UNDO_JMP_TARGET(op_array, opline, node) do { \
(node).opline_num = (node).jmp_addr - (op_array)->opcodes; \
} while (0)
#else
/* run-time jump target */
# define OP_JMP_ADDR(opline, node) \
ZEND_OFFSET_TO_OPLINE(opline, (node).jmp_offset)
# define ZEND_SET_OP_JMP_ADDR(opline, node, val) do { \
(node).jmp_offset = ZEND_OPLINE_TO_OFFSET(opline, val); \
} while (0)
/* convert jump target from compile-time to run-time */
# define ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, node) do { \
(node).jmp_offset = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, (node).opline_num); \
} while (0)
/* convert jump target back from run-time to compile-time */
# define ZEND_PASS_TWO_UNDO_JMP_TARGET(op_array, opline, node) do { \
(node).opline_num = ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, (node).jmp_offset); \
2015-01-03 17:22:58 +08:00
} while (0)
#endif
/* constant-time constant */
# define CT_CONSTANT_EX(op_array, num) \
((op_array)->literals + (num))
# define CT_CONSTANT(node) \
CT_CONSTANT_EX(CG(active_op_array), (node).constant)
#if ZEND_USE_ABS_CONST_ADDR
/* run-time constant */
# define RT_CONSTANT(opline, node) \
(node).zv
/* convert constant from compile-time to run-time */
# define ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, node) do { \
(node).zv = CT_CONSTANT_EX(op_array, (node).constant); \
} while (0)
#else
/* At run-time, constants are allocated together with op_array->opcodes
* and addressed relatively to current opline.
*/
/* run-time constant */
# define RT_CONSTANT(opline, node) \
((zval*)(((char*)(opline)) + (int32_t)(node).constant))
/* convert constant from compile-time to run-time */
# define ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, node) do { \
(node).constant = \
(((char*)CT_CONSTANT_EX(op_array, (node).constant)) - \
((char*)opline)); \
} while (0)
#endif
/* convert constant back from run-time to compile-time */
#define ZEND_PASS_TWO_UNDO_CONSTANT(op_array, opline, node) do { \
(node).constant = RT_CONSTANT(opline, node) - (op_array)->literals; \
} while (0)
Immutable clases and op_arrays. Squashed commit of the following: commit cd0c36c3f943849e5b97a8dbe2dd029fbeab3df9 Merge: 4740dabb84 ad6738e886 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 14:43:38 2018 +0300 Merge branch 'master' into immutable * master: Remove the "auto" encoding Fixed bug #77025 Add vtbls for EUC-TW encoding commit 4740dabb843c6d4f7f866b4a2456073c9eaf4c77 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 14:12:28 2018 +0300 Reverted back ce->iterator_funcs_ptr. Initialize ce->iterator_funcs_ptr fields in immutable classes. commit ad7a78b253be970db70c2251e66f9297d8e7f829 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:46:30 2018 +0300 Added comment commit 0276ea51875bab37be01a4dc5e5a047c5698c571 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:42:43 2018 +0300 Added type cast commit c63fc5d5f19c58498108d1698055b2b442227eb3 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:36:51 2018 +0300 Moved static class members initialization into the proper place. commit b945548e9306b1826c881918858b5e5aa3eb3002 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:21:03 2018 +0300 Removed redundand assertion commit d5a41088401814c829847db212488f8aae39bcd2 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:19:13 2018 +0300 Removed duplicate code commit 8dadca8864e66de70a24bdf1181bcf7dd8fb27d7 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:05:43 2018 +0300 Hide offset encoding magic in ZEND_MAP_PTR_IS_OFFSET(), ZEND_MAP_PTR_OFFSET2PTR() and ZEND_MAP_PTR_PTR2OFFSET() macros. commit 9ef07c88bd76801e2d4fbfeab3ebfd6e6a67ac5f Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 10:48:29 2018 +0300 typo commit a06f0f3d3aba53e766046221ee44fb9720389ecc Merge: 94099586ec 3412345ffe Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 10:47:07 2018 +0300 Merge branch 'master' into immutable * master: Remove unused variable makefile_am_files Classify object handlers are required/optional Add support for getting SKIP_TAGSTART and SKIP_WHITE options Remove some obsolete config_vars.mk occurrences Remove bsd_converted from .gitignore Remove configuration parser and scanners ignores Remove obsolete buildconf.stamp from .gitignore [ci skip] Add magicdata.patch exception to .gitignore Remove outdated ext/spl/examples items from .gitignore Remove unused test.inc in ext/iconv/tests commit 94099586ec599117581ca01c15b1f6c5f749e23a Author: Dmitry Stogov <dmitry@zend.com> Date: Mon Oct 15 23:34:01 2018 +0300 Immutable clases and op_arrays
2018-10-17 20:52:50 +08:00
#define RUN_TIME_CACHE(op_array) \
ZEND_MAP_PTR_GET((op_array)->run_time_cache)
#define ZEND_OP_ARRAY_EXTENSION(op_array, handle) \
((void**)RUN_TIME_CACHE(op_array))[handle]
2018-01-31 16:18:41 +08:00
#define IS_UNUSED 0 /* Unused operand */
1999-04-08 02:10:10 +08:00
#define IS_CONST (1<<0)
#define IS_TMP_VAR (1<<1)
#define IS_VAR (1<<2)
2018-01-31 16:18:41 +08:00
#define IS_CV (1<<3) /* Compiled variable */
1999-04-08 02:10:10 +08:00
/* Used for result.type of smart branch instructions */
#define IS_SMART_BRANCH_JMPZ (1<<4)
#define IS_SMART_BRANCH_JMPNZ (1<<5)
2018-07-03 06:09:58 +08:00
#define ZEND_EXTRA_VALUE 1
#include "zend_globals.h"
2000-01-30 01:19:47 +08:00
BEGIN_EXTERN_C()
2014-12-14 06:06:14 +08:00
void init_compiler(void);
void shutdown_compiler(void);
void zend_init_compiler_data_structures(void);
void zend_oparray_context_begin(zend_oparray_context *prev_context);
void zend_oparray_context_end(zend_oparray_context *prev_context);
void zend_file_context_begin(zend_file_context *prev_context);
void zend_file_context_end(zend_file_context *prev_context);
1999-04-08 02:10:10 +08:00
2014-12-14 06:06:14 +08:00
extern ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type);
extern ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, const char *filename);
1999-04-08 02:10:10 +08:00
ZEND_API int ZEND_FASTCALL lex_scan(zval *zendlval, zend_parser_stack_elem *elem);
2014-12-14 06:06:14 +08:00
void startup_scanner(void);
void shutdown_scanner(void);
1999-04-08 02:10:10 +08:00
2014-12-14 06:06:14 +08:00
ZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filename);
ZEND_API void zend_restore_compiled_filename(zend_string *original_compiled_filename);
ZEND_API zend_string *zend_get_compiled_filename(void);
ZEND_API int zend_get_compiled_lineno(void);
ZEND_API size_t zend_get_scanned_file_offset(void);
1999-04-08 02:10:10 +08:00
2014-08-26 01:28:33 +08:00
ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, uint32_t var);
#ifdef ZTS
2014-12-14 06:06:14 +08:00
const char *zend_get_zendtext(void);
int zend_get_zendleng(void);
#endif
typedef int (ZEND_FASTCALL *unary_op_type)(zval *, zval *);
typedef int (ZEND_FASTCALL *binary_op_type)(zval *, zval *, zval *);
1999-04-08 02:10:10 +08:00
ZEND_API unary_op_type get_unary_op(int opcode);
ZEND_API binary_op_type get_binary_op(int opcode);
1999-04-08 02:10:10 +08:00
2014-12-14 06:06:14 +08:00
void zend_stop_lexing(void);
void zend_emit_final_return(int return_one);
/* Used during AST construction */
2014-07-27 03:53:50 +08:00
zend_ast *zend_ast_append_str(zend_ast *left, zend_ast *right);
zend_ast *zend_negate_num_string(zend_ast *ast);
uint32_t zend_add_class_modifier(uint32_t flags, uint32_t new_flag);
uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag);
zend_bool zend_handle_encoding_declaration(zend_ast *ast);
2001-12-17 03:45:49 +08:00
2014-07-18 21:53:38 +08:00
/* parser-driven code generators */
2014-12-14 06:06:14 +08:00
void zend_do_free(znode *op1);
1999-04-08 02:10:10 +08:00
ZEND_API int do_bind_function(zval *lcname);
ZEND_API int do_bind_class(zval *lcname, zend_string *lc_parent_name);
2018-01-12 00:15:52 +08:00
ZEND_API uint32_t zend_build_delayed_early_binding_list(const zend_op_array *op_array);
ZEND_API void zend_do_delayed_early_binding(zend_op_array *op_array, uint32_t first_early_binding_opline);
1999-04-08 02:10:10 +08:00
2014-12-14 06:06:14 +08:00
void zend_do_extended_info(void);
void zend_do_extended_fcall_begin(void);
void zend_do_extended_fcall_end(void);
1999-04-08 02:10:10 +08:00
2014-12-14 06:06:14 +08:00
void zend_verify_namespace(void);
void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline);
2000-06-14 03:01:22 +08:00
ZEND_API void function_add_ref(zend_function *function);
#define INITIAL_OP_ARRAY_SIZE 64
1999-04-08 02:10:10 +08:00
/* helper functions in zend_language_scanner.l */
struct _zend_arena;
2014-12-14 06:06:14 +08:00
ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type);
ZEND_API zend_op_array *compile_string(zval *source_string, const char *filename);
2014-12-14 06:06:14 +08:00
ZEND_API zend_op_array *compile_filename(int type, zval *filename);
ZEND_API zend_ast *zend_compile_string_to_ast(
zend_string *code, struct _zend_arena **ast_arena, const char *filename);
2014-12-14 06:06:14 +08:00
ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...);
ZEND_API int open_file_for_scanning(zend_file_handle *file_handle);
ZEND_API void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size);
ZEND_API void destroy_op_array(zend_op_array *op_array);
2014-12-14 06:06:14 +08:00
ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle);
ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce);
ZEND_API void zend_cleanup_internal_classes(void);
ZEND_API void zend_type_release(zend_type type, zend_bool persistent);
ZEND_API zend_string *zend_create_member_string(zend_string *class_name, zend_string *member_name);
1999-04-08 02:10:10 +08:00
2019-05-31 17:09:06 +08:00
ZEND_API ZEND_COLD void zend_user_exception_handler(void);
#define zend_try_exception_handler() do { \
if (UNEXPECTED(EG(exception))) { \
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) { \
zend_user_exception_handler(); \
} \
} \
} while (0)
void zend_free_internal_arg_info(zend_internal_function *function);
2014-12-14 06:06:14 +08:00
ZEND_API void destroy_zend_function(zend_function *function);
ZEND_API void zend_function_dtor(zval *zv);
ZEND_API void destroy_zend_class(zval *zv);
void zend_class_add_ref(zval *zv);
ZEND_API zend_string *zend_mangle_property_name(const char *src1, size_t src1_length, const char *src2, size_t src2_length, int internal);
#define zend_unmangle_property_name(mangled_property, class_name, prop_name) \
zend_unmangle_property_name_ex(mangled_property, class_name, prop_name, NULL)
ZEND_API int zend_unmangle_property_name_ex(const zend_string *name, const char **class_name, const char **prop_name, size_t *prop_len);
2003-02-04 20:12:34 +08:00
static zend_always_inline const char *zend_get_unmangled_property_name(const zend_string *mangled_prop) {
const char *class_name, *prop_name;
zend_unmangle_property_name(mangled_prop, &class_name, &prop_name);
return prop_name;
}
#define ZEND_FUNCTION_DTOR zend_function_dtor
#define ZEND_CLASS_DTOR destroy_zend_class
typedef zend_bool (*zend_needs_live_range_cb)(zend_op_array *op_array, zend_op *opline);
ZEND_API void zend_recalc_live_ranges(
zend_op_array *op_array, zend_needs_live_range_cb needs_live_range);
2014-12-14 06:06:14 +08:00
ZEND_API int pass_two(zend_op_array *op_array);
ZEND_API zend_bool zend_is_compiling(void);
ZEND_API char *zend_make_compiled_string_description(const char *name);
ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers);
uint32_t zend_get_class_fetch_type(zend_string *name);
ZEND_API zend_uchar zend_get_call_op(const zend_op *init_op, zend_function *fbc);
2019-10-08 21:50:04 +08:00
ZEND_API int zend_is_smart_branch(const zend_op *opline);
2003-02-11 00:11:24 +08:00
2014-12-14 06:06:14 +08:00
typedef zend_bool (*zend_auto_global_callback)(zend_string *name);
typedef struct _zend_auto_global {
zend_string *name;
zend_auto_global_callback auto_global_callback;
zend_bool jit;
zend_bool armed;
} zend_auto_global;
1999-04-08 02:10:10 +08:00
2014-12-14 06:06:14 +08:00
ZEND_API int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global_callback auto_global_callback);
ZEND_API void zend_activate_auto_globals(void);
ZEND_API zend_bool zend_is_auto_global(zend_string *name);
ZEND_API zend_bool zend_is_auto_global_str(const char *name, size_t len);
ZEND_API size_t zend_dirname(char *path, size_t len);
2015-04-23 18:31:02 +08:00
ZEND_API void zend_set_function_arg_flags(zend_function *func);
int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem);
1999-04-08 02:10:10 +08:00
void zend_assert_valid_class_name(const zend_string *const_name);
2015-02-01 22:22:48 +08:00
zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scope);
ZEND_API zend_string *zend_type_to_string(zend_type type);
/* BEGIN: OPCODES */
2003-06-02 20:13:11 +08:00
2004-10-28 01:58:46 +08:00
#include "zend_vm_opcodes.h"
/* END: OPCODES */
1999-04-08 02:10:10 +08:00
/* class fetches */
#define ZEND_FETCH_CLASS_DEFAULT 0
#define ZEND_FETCH_CLASS_SELF 1
#define ZEND_FETCH_CLASS_PARENT 2
#define ZEND_FETCH_CLASS_STATIC 3
#define ZEND_FETCH_CLASS_AUTO 4
#define ZEND_FETCH_CLASS_INTERFACE 5
#define ZEND_FETCH_CLASS_TRAIT 6
#define ZEND_FETCH_CLASS_MASK 0x0f
#define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80
#define ZEND_FETCH_CLASS_SILENT 0x0100
#define ZEND_FETCH_CLASS_EXCEPTION 0x0200
Support full variance if autoloading is used Keep track of delayed variance obligations and check them after linking a class is otherwise finished. Obligations may either be unresolved method compatibility (because the necessecary classes aren't available yet) or open parent/interface dependencies. The latter occur because we allow the use of not fully linked classes as parents/interfaces now. An important aspect of the implementation is we do not require classes involved in variance checks to be fully linked in order for the class to be fully linked. Because the involved types do have to exist in the class table (as partially linked classes) and we do check these for correct variance, we have the guarantee that either those classes will successfully link lateron or generate an error, but there is no way to actually use them until that point and as such no possibility of violating the variance contract. This is important because it ensures that a class declaration always either errors or will produce an immediately usable class afterwards -- there are no cases where the finalization of the class declaration has to be delayed until a later time, as earlier variants of this patch did. Because variance checks deal with classes in various stages of linking, we need to use a special instanceof implementation that supports this, and also introduce finer-grained flags that tell us which parts have been linked already and which haven't. Class autoloading for variance checks is delayed into a separate stage after the class is otherwise linked and before delayed variance obligations are processed. This separation is needed to handle cases like A extends B extends C, where B is the autoload root, but C is required to check variance. This could end up loading C while the class structure of B is in an inconsistent state.
2019-05-27 17:39:56 +08:00
#define ZEND_FETCH_CLASS_ALLOW_UNLINKED 0x0400
#define ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED 0x0800
/* These should not clash with ZEND_ACC_(PUBLIC|PROTECTED|PRIVATE) */
#define ZEND_PARAM_REF (1<<3)
#define ZEND_PARAM_VARIADIC (1<<4)
2014-07-22 19:25:47 +08:00
#define ZEND_NAME_FQ 0
#define ZEND_NAME_NOT_FQ 1
#define ZEND_NAME_RELATIVE 2
2016-04-06 23:24:34 +08:00
#define ZEND_TYPE_NULLABLE (1<<8)
#define ZEND_ARRAY_SYNTAX_LIST 1 /* list() */
#define ZEND_ARRAY_SYNTAX_LONG 2 /* array() */
#define ZEND_ARRAY_SYNTAX_SHORT 3 /* [] */
1999-04-08 02:10:10 +08:00
/* var status for backpatching */
#define BP_VAR_R 0
#define BP_VAR_W 1
#define BP_VAR_RW 2
#define BP_VAR_IS 3
2014-06-07 19:06:53 +08:00
#define BP_VAR_FUNC_ARG 4
#define BP_VAR_UNSET 5
2019-02-08 03:08:51 +08:00
#define ZEND_INTERNAL_FUNCTION 1
#define ZEND_USER_FUNCTION 2
#define ZEND_EVAL_CODE 4
1999-04-08 02:10:10 +08:00
2019-02-08 03:08:51 +08:00
#define ZEND_USER_CODE(type) ((type) != ZEND_INTERNAL_FUNCTION)
#define ZEND_INTERNAL_CLASS 1
#define ZEND_USER_CLASS 2
1999-04-08 02:10:10 +08:00
#define ZEND_EVAL (1<<0)
#define ZEND_INCLUDE (1<<1)
2000-03-10 23:05:00 +08:00
#define ZEND_INCLUDE_ONCE (1<<2)
#define ZEND_REQUIRE (1<<3)
#define ZEND_REQUIRE_ONCE (1<<4)
1999-04-08 02:10:10 +08:00
/* global/local fetches */
2018-02-06 00:41:17 +08:00
#define ZEND_FETCH_GLOBAL (1<<1)
#define ZEND_FETCH_LOCAL (1<<2)
#define ZEND_FETCH_GLOBAL_LOCK (1<<3)
2018-02-06 00:41:17 +08:00
#define ZEND_FETCH_TYPE_MASK 0xe
/* Only one of these can ever be in use */
#define ZEND_FETCH_REF 1
#define ZEND_FETCH_DIM_WRITE 2
#define ZEND_FETCH_OBJ_FLAGS 3
#define ZEND_ISEMPTY (1<<0)
2018-02-06 00:41:17 +08:00
#define ZEND_LAST_CATCH (1<<0)
#define ZEND_FREE_ON_RETURN (1<<0)
#define ZEND_FREE_SWITCH (1<<1)
#define ZEND_SEND_BY_VAL 0u
#define ZEND_SEND_BY_REF 1u
#define ZEND_SEND_PREFER_REF 2u
#define ZEND_THROW_IS_EXPR 1u
/* The send mode and is_variadic flag are stored as part of zend_type */
#define _ZEND_SEND_MODE_SHIFT _ZEND_TYPE_EXTRA_FLAGS_SHIFT
#define _ZEND_IS_VARIADIC_BIT (1 << (_ZEND_TYPE_EXTRA_FLAGS_SHIFT + 2))
#define _ZEND_IS_PROMOTED_BIT (1 << (_ZEND_TYPE_EXTRA_FLAGS_SHIFT + 3))
#define ZEND_ARG_SEND_MODE(arg_info) \
((ZEND_TYPE_FULL_MASK((arg_info)->type) >> _ZEND_SEND_MODE_SHIFT) & 3)
#define ZEND_ARG_IS_VARIADIC(arg_info) \
((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_VARIADIC_BIT) != 0)
#define ZEND_ARG_IS_PROMOTED(arg_info) \
((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_PROMOTED_BIT) != 0)
#define ZEND_DIM_IS (1 << 0) /* isset fetch needed for null coalesce */
#define ZEND_DIM_ALTERNATIVE_SYNTAX (1 << 1) /* deprecated curly brace usage */
/* Make sure these don't clash with ZEND_FETCH_CLASS_* flags. */
#define IS_CONSTANT_CLASS 0x400 /* __CLASS__ in trait */
#define IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE 0x800
static zend_always_inline int zend_check_arg_send_type(const zend_function *zf, uint32_t arg_num, uint32_t mask)
{
arg_num--;
if (UNEXPECTED(arg_num >= zf->common.num_args)) {
if (EXPECTED((zf->common.fn_flags & ZEND_ACC_VARIADIC) == 0)) {
return 0;
}
arg_num = zf->common.num_args;
}
return UNEXPECTED((ZEND_ARG_SEND_MODE(&zf->common.arg_info[arg_num]) & mask) != 0);
}
#define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \
zend_check_arg_send_type(zf, arg_num, ZEND_SEND_BY_REF)
#define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \
zend_check_arg_send_type(zf, arg_num, ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF)
#define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \
zend_check_arg_send_type(zf, arg_num, ZEND_SEND_PREFER_REF)
2019-03-01 14:15:32 +08:00
/* Quick API to check first 12 arguments */
#define MAX_ARG_FLAG_NUM 12
#ifdef WORDS_BIGENDIAN
# define ZEND_SET_ARG_FLAG(zf, arg_num, mask) do { \
2016-04-29 18:11:27 +08:00
(zf)->quick_arg_flags |= ((mask) << ((arg_num) - 1) * 2); \
} while (0)
# define ZEND_CHECK_ARG_FLAG(zf, arg_num, mask) \
2016-04-29 18:11:27 +08:00
(((zf)->quick_arg_flags >> (((arg_num) - 1) * 2)) & (mask))
#else
# define ZEND_SET_ARG_FLAG(zf, arg_num, mask) do { \
2016-04-29 18:11:27 +08:00
(zf)->quick_arg_flags |= (((mask) << 6) << (arg_num) * 2); \
} while (0)
# define ZEND_CHECK_ARG_FLAG(zf, arg_num, mask) \
2016-04-29 18:11:27 +08:00
(((zf)->quick_arg_flags >> (((arg_num) + 3) * 2)) & (mask))
#endif
#define QUICK_ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \
ZEND_CHECK_ARG_FLAG(zf, arg_num, ZEND_SEND_BY_REF)
#define QUICK_ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \
ZEND_CHECK_ARG_FLAG(zf, arg_num, ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF)
#define QUICK_ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \
ZEND_CHECK_ARG_FLAG(zf, arg_num, ZEND_SEND_PREFER_REF)
#define ZEND_RETURN_VAL 0
#define ZEND_RETURN_REF 1
#define ZEND_BIND_VAL 0
#define ZEND_BIND_REF 1
#define ZEND_BIND_IMPLICIT 2
2018-06-22 17:04:23 +08:00
#define ZEND_RETURNS_FUNCTION (1<<0)
#define ZEND_RETURNS_VALUE (1<<1)
#define ZEND_ARRAY_ELEMENT_REF (1<<0)
#define ZEND_ARRAY_NOT_PACKED (1<<1)
#define ZEND_ARRAY_SIZE_SHIFT 2
/* Attribute for ternary inside parentheses */
#define ZEND_PARENTHESIZED_CONDITIONAL 1
/* For "use" AST nodes and the seen symbol table */
#define ZEND_SYMBOL_CLASS (1<<0)
#define ZEND_SYMBOL_FUNCTION (1<<1)
#define ZEND_SYMBOL_CONST (1<<2)
2019-07-03 15:33:03 +08:00
/* All increment opcodes are even (decrement are odd) */
#define ZEND_IS_INCREMENT(opcode) (((opcode) & 1) == 0)
#define ZEND_IS_BINARY_ASSIGN_OP_OPCODE(opcode) \
(((opcode) >= ZEND_ADD) && ((opcode) <= ZEND_POW))
/* Pseudo-opcodes that are used only temporarily during compilation */
#define ZEND_GOTO 253
#define ZEND_BRK 254
#define ZEND_CONT 255
2000-01-30 01:19:47 +08:00
END_EXTERN_C()
#define ZEND_CLONE_FUNC_NAME "__clone"
#define ZEND_CONSTRUCTOR_FUNC_NAME "__construct"
#define ZEND_DESTRUCTOR_FUNC_NAME "__destruct"
#define ZEND_GET_FUNC_NAME "__get"
#define ZEND_SET_FUNC_NAME "__set"
#define ZEND_UNSET_FUNC_NAME "__unset"
#define ZEND_ISSET_FUNC_NAME "__isset"
#define ZEND_CALL_FUNC_NAME "__call"
#define ZEND_CALLSTATIC_FUNC_NAME "__callstatic"
#define ZEND_TOSTRING_FUNC_NAME "__tostring"
#define ZEND_INVOKE_FUNC_NAME "__invoke"
#define ZEND_DEBUGINFO_FUNC_NAME "__debuginfo"
/* The following constants may be combined in CG(compiler_options)
* to change the default compiler behavior */
/* generate extended debug information */
#define ZEND_COMPILE_EXTENDED_STMT (1<<0)
#define ZEND_COMPILE_EXTENDED_FCALL (1<<1)
#define ZEND_COMPILE_EXTENDED_INFO (ZEND_COMPILE_EXTENDED_STMT|ZEND_COMPILE_EXTENDED_FCALL)
/* call op_array handler of extendions */
#define ZEND_COMPILE_HANDLE_OP_ARRAY (1<<2)
/* generate ZEND_INIT_FCALL_BY_NAME for internal functions instead of ZEND_INIT_FCALL */
#define ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS (1<<3)
/* don't perform early binding for classes inherited form internal ones;
* in namespaces assume that internal class that doesn't exist at compile-time
* may apper in run-time */
#define ZEND_COMPILE_IGNORE_INTERNAL_CLASSES (1<<4)
/* generate ZEND_DECLARE_CLASS_DELAYED opcode to delay early binding */
#define ZEND_COMPILE_DELAYED_BINDING (1<<5)
/* disable constant substitution at compile-time */
#define ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION (1<<6)
/* disable substitution of persistent constants at compile-time */
#define ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION (1<<8)
/* generate ZEND_INIT_FCALL_BY_NAME for userland functions instead of ZEND_INIT_FCALL */
#define ZEND_COMPILE_IGNORE_USER_FUNCTIONS (1<<9)
/* force ZEND_ACC_USE_GUARDS for all classes */
#define ZEND_COMPILE_GUARDS (1<<10)
2015-09-20 13:23:36 +08:00
/* disable builtin special case function calls */
#define ZEND_COMPILE_NO_BUILTINS (1<<11)
/* result of compilation may be stored in file cache */
#define ZEND_COMPILE_WITH_FILE_CACHE (1<<12)
/* ignore functions and classes declared in other files */
#define ZEND_COMPILE_IGNORE_OTHER_FILES (1<<13)
/* this flag is set when compiler invoked by opcache_compile_file() */
#define ZEND_COMPILE_WITHOUT_EXECUTION (1<<14)
/* this flag is set when compiler invoked during preloading */
#define ZEND_COMPILE_PRELOAD (1<<15)
/* disable jumptable optimization for switch statements */
#define ZEND_COMPILE_NO_JUMPTABLES (1<<16)
/* this flag is set when compiler invoked during preloading in separate process */
#define ZEND_COMPILE_PRELOAD_IN_CHILD (1<<17)
/* The default value for CG(compiler_options) */
#define ZEND_COMPILE_DEFAULT ZEND_COMPILE_HANDLE_OP_ARRAY
/* The default value for CG(compiler_options) during eval() */
#define ZEND_COMPILE_DEFAULT_FOR_EVAL 0
ZEND_API zend_bool zend_binary_op_produces_error(uint32_t opcode, zval *op1, zval *op2);
Warn about invalid strings in arithmetic Squashed commit of the following: commit e05d3b67325d4521418483ed924ac9211a188919 Author: Andrea Faulds <ajf@ajf.me> Date: Wed Mar 30 01:43:35 2016 +0100 UPGRADING and NEWS commit 6caf1d4585207d1b02fb06a216cd7da1a1f5e12d Author: Andrea Faulds <ajf@ajf.me> Date: Sun Mar 20 21:18:33 2016 +0000 Fixes commit 6dadb1b0efe5e2ed071e95a55c806519e61377ac Author: Andrea Faulds <ajf@ajf.me> Date: Sun Feb 14 02:15:01 2016 +0000 Add test for numeric string errors in assignment commit bd5f04e8dd576f92a48d25546f4f9a0f57f374de Author: Andrea Faulds <ajf@ajf.me> Date: Sat Feb 13 23:53:05 2016 +0000 Add test for numeric string errors commit c72e92f16d512bcae30cc9639c89bcb08d971742 Author: Andrea Faulds <ajf@ajf.me> Date: Tue Jan 26 23:28:33 2016 +0000 Add test for scientific notation in integer operations commit d94c08852d405b3a7ef6c84d24bf7915c890ce78 Author: Andrea Faulds <ajf@ajf.me> Date: Sun Feb 14 01:25:57 2016 +0000 Disable optimiser evaluation for numeric string errors commit 30ee954ed13d933e766c68605d683c8ebae3d8ee Author: Andrea Faulds <ajf@ajf.me> Date: Sun Feb 14 01:46:25 2016 +0000 fixup commit a6403b79e054c95e2b7345d787f3092b261eed27 Author: Andrea Faulds <ajf@ajf.me> Date: Sat Feb 13 22:00:27 2016 +0000 Do not convert error-causing numeric strings ahead-of-time commit f9dc35401471ef3035954cb6f171826769297548 Author: Andrea Faulds <ajf@ajf.me> Date: Sat Feb 13 19:15:38 2016 +0000 Disable compile-time evaluation for numeric string errors commit e05b0cc8496ea082c6db27efd8b8277ef1f785b5 Author: Andrea Faulds <ajf@ajf.me> Date: Fri Feb 5 11:42:26 2016 +0000 Make _zval_get_long_func_noisy function for inlining commit 84d66321a57e579759109650c8bb7e3d5002854a Author: Andrea Faulds <ajf@ajf.me> Date: Tue Jan 26 23:10:00 2016 +0000 Update tests commit 5ac4a0cc4bff282e3a15eaa8ab44b67391881a6d Author: Andrea Faulds <ajf@ajf.me> Date: Tue Jan 26 22:08:19 2016 +0000 Use is_numeric_string_ex for zval_get_long etc. commit c21f08848533723331012a62a153de3577731d6a Author: Andrea Faulds <ajf@ajf.me> Date: Thu Jan 7 21:13:04 2016 +0000 Update tests commit 63e214cf8160420bfc51c6a2b4ae32f09ad8e8af Author: Andrea Faulds <ajf@ajf.me> Date: Wed Jan 6 00:28:01 2016 +0000 Warn on non-/bad numeric strings in arithmetic
2016-03-30 08:44:27 +08:00
#endif /* ZEND_COMPILE_H */