1999-04-08 02:10:10 +08:00
|
|
|
/*
|
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
| Zend Engine |
|
|
|
|
+----------------------------------------------------------------------+
|
2014-01-03 11:08:10 +08:00
|
|
|
| Copyright (c) 1998-2014 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, |
|
2006-05-28 02:39:53 +08:00
|
|
|
| that is bundled with this package in the file LICENSE, and is |
|
2003-06-11 04:04:29 +08:00
|
|
|
| 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@zend.com> |
|
|
|
|
| Zeev Suraski <zeev@zend.com> |
|
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
*/
|
|
|
|
|
2003-02-01 09:49:15 +08:00
|
|
|
/* $Id$ */
|
1999-07-16 22:58:16 +08:00
|
|
|
|
2000-07-03 08:55:36 +08:00
|
|
|
#ifndef ZEND_COMPILE_H
|
|
|
|
#define ZEND_COMPILE_H
|
1999-04-08 02:10:10 +08:00
|
|
|
|
|
|
|
#include "zend.h"
|
2013-10-31 15:57:12 +08:00
|
|
|
#include "zend_ast.h"
|
1999-04-15 05:03:25 +08:00
|
|
|
|
1999-09-07 00:14:08 +08:00
|
|
|
#ifdef HAVE_STDARG_H
|
|
|
|
# include <stdarg.h>
|
1999-04-15 05:03:25 +08:00
|
|
|
#endif
|
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
#include "zend_llist.h"
|
|
|
|
|
|
|
|
#define DEBUG_ZEND 0
|
1999-05-03 03:07:46 +08:00
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
#define FREE_PNODE(znode) zval_dtor(&znode->u.constant);
|
|
|
|
|
2010-04-20 18:57:45 +08:00
|
|
|
#define SET_UNUSED(op) op ## _type = IS_UNUSED
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2010-09-15 15:38:52 +08:00
|
|
|
#define INC_BPC(op_array) if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) { (CG(context).backpatch_count++); }
|
|
|
|
#define DEC_BPC(op_array) if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) { (CG(context).backpatch_count--); }
|
2007-02-15 18:38:28 +08:00
|
|
|
#define HANDLE_INTERACTIVE() if (CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE) { execute_new_code(TSRMLS_C); }
|
2011-06-12 09:43:10 +08:00
|
|
|
#define DO_TICKS() if (Z_LVAL(CG(declarables).ticks)) { zend_do_ticks(TSRMLS_C); }
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2005-06-08 02:11:56 +08:00
|
|
|
#define RESET_DOC_COMMENT() \
|
|
|
|
{ \
|
|
|
|
if (CG(doc_comment)) { \
|
2014-02-10 14:04:30 +08:00
|
|
|
STR_RELEASE(CG(doc_comment)); \
|
2005-06-08 02:11:56 +08:00
|
|
|
CG(doc_comment) = NULL; \
|
|
|
|
} \
|
2003-04-03 02:15:08 +08:00
|
|
|
}
|
2003-04-03 00:51:49 +08:00
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
typedef struct _zend_op_array zend_op_array;
|
2002-10-25 02:04:12 +08:00
|
|
|
typedef struct _zend_op zend_op;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2010-09-15 15:38:52 +08:00
|
|
|
typedef struct _zend_compiler_context {
|
|
|
|
zend_uint opcodes_size;
|
|
|
|
int vars_size;
|
|
|
|
int literals_size;
|
|
|
|
int current_brk_cont;
|
|
|
|
int backpatch_count;
|
2012-12-13 06:48:51 +08:00
|
|
|
int in_finally;
|
2010-09-15 15:38:52 +08:00
|
|
|
HashTable *labels;
|
|
|
|
} zend_compiler_context;
|
|
|
|
|
2013-11-09 08:14:58 +08:00
|
|
|
typedef union _znode_op {
|
2010-04-20 18:57:45 +08:00
|
|
|
zend_uint constant;
|
|
|
|
zend_uint var;
|
|
|
|
zend_uint num;
|
|
|
|
zend_ulong hash;
|
|
|
|
zend_uint opline_num; /* Needs to be signed */
|
|
|
|
zend_op *jmp_addr;
|
|
|
|
zval *zv;
|
2012-08-18 11:57:53 +08:00
|
|
|
void *ptr; /* Used for passing pointers from the compile to execution phase, currently used for traits */
|
2010-04-20 18:57:45 +08:00
|
|
|
} znode_op;
|
|
|
|
|
2013-11-09 08:14:58 +08:00
|
|
|
typedef struct _znode { /* used only during compilation */
|
1999-04-08 02:10:10 +08:00
|
|
|
int op_type;
|
|
|
|
union {
|
2010-04-20 18:57:45 +08:00
|
|
|
znode_op op;
|
|
|
|
zval constant; /* replaced by literal/zv */
|
1999-04-08 02:10:10 +08:00
|
|
|
zend_op_array *op_array;
|
2013-11-07 02:21:07 +08:00
|
|
|
zend_ast *ast;
|
1999-04-08 02:10:10 +08:00
|
|
|
} u;
|
2010-04-20 18:57:45 +08:00
|
|
|
zend_uint EA; /* extended attributes */
|
1999-04-08 02:10:10 +08:00
|
|
|
} znode;
|
|
|
|
|
2002-10-19 17:45:51 +08:00
|
|
|
typedef struct _zend_execute_data zend_execute_data;
|
|
|
|
|
2004-08-20 04:03:06 +08:00
|
|
|
#define ZEND_OPCODE_HANDLER_ARGS zend_execute_data *execute_data TSRMLS_DC
|
|
|
|
#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU execute_data TSRMLS_CC
|
2002-10-19 17:45:51 +08:00
|
|
|
|
2008-06-11 21:18:41 +08:00
|
|
|
typedef int (*user_opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);
|
|
|
|
typedef int (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);
|
2002-10-19 17:45:51 +08:00
|
|
|
|
2004-09-24 05:43:32 +08:00
|
|
|
extern ZEND_API opcode_handler_t *zend_opcode_handlers;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2002-10-25 02:04:12 +08:00
|
|
|
struct _zend_op {
|
2002-11-06 05:35:05 +08:00
|
|
|
opcode_handler_t handler;
|
2010-04-20 18:57:45 +08:00
|
|
|
znode_op op1;
|
|
|
|
znode_op op2;
|
|
|
|
znode_op result;
|
1999-04-13 02:29:09 +08:00
|
|
|
ulong extended_value;
|
1999-04-08 02:10:10 +08:00
|
|
|
uint lineno;
|
2002-11-06 05:35:05 +08:00
|
|
|
zend_uchar opcode;
|
2010-04-20 18:57:45 +08:00
|
|
|
zend_uchar op1_type;
|
|
|
|
zend_uchar op2_type;
|
|
|
|
zend_uchar result_type;
|
2002-10-25 02:04:12 +08:00
|
|
|
};
|
1999-04-08 02:10:10 +08:00
|
|
|
|
|
|
|
|
1999-05-23 00:10:51 +08:00
|
|
|
typedef struct _zend_brk_cont_element {
|
2006-09-20 05:36:54 +08:00
|
|
|
int start;
|
1999-04-08 02:10:10 +08:00
|
|
|
int cont;
|
|
|
|
int brk;
|
|
|
|
int parent;
|
|
|
|
} zend_brk_cont_element;
|
|
|
|
|
2008-03-28 22:35:01 +08:00
|
|
|
typedef struct _zend_label {
|
|
|
|
int brk_cont;
|
|
|
|
zend_uint opline_num;
|
|
|
|
} zend_label;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2004-02-03 20:17:09 +08:00
|
|
|
typedef struct _zend_try_catch_element {
|
|
|
|
zend_uint try_op;
|
|
|
|
zend_uint catch_op; /* ketchup! */
|
2012-08-18 00:16:34 +08:00
|
|
|
zend_uint finally_op;
|
|
|
|
zend_uint finally_end;
|
2004-02-03 20:17:09 +08:00
|
|
|
} zend_try_catch_element;
|
|
|
|
|
2011-06-21 06:59:55 +08:00
|
|
|
#if SIZEOF_LONG == 8
|
2014-03-14 19:35:57 +08:00
|
|
|
#define THIS_HASHVAL 6385726429UL
|
2011-06-21 06:59:55 +08:00
|
|
|
#else
|
2014-03-14 19:35:57 +08:00
|
|
|
#define THIS_HASHVAL 2090759133UL
|
2011-06-21 06:59:55 +08:00
|
|
|
#endif
|
2004-02-03 20:17:09 +08:00
|
|
|
|
2004-03-10 00:38:37 +08:00
|
|
|
/* method flags (types) */
|
2003-03-07 06:53:23 +08:00
|
|
|
#define ZEND_ACC_STATIC 0x01
|
|
|
|
#define ZEND_ACC_ABSTRACT 0x02
|
|
|
|
#define ZEND_ACC_FINAL 0x04
|
2004-03-10 00:38:37 +08:00
|
|
|
#define ZEND_ACC_IMPLEMENTED_ABSTRACT 0x08
|
2004-01-24 06:04:42 +08:00
|
|
|
|
2004-03-10 00:38:37 +08:00
|
|
|
/* class flags (types) */
|
|
|
|
/* ZEND_ACC_IMPLICIT_ABSTRACT_CLASS is used for abstract classes (since it is set by any abstract method even interfaces MAY have it set, too). */
|
|
|
|
/* ZEND_ACC_EXPLICIT_ABSTRACT_CLASS denotes that a class was explicitly defined as abstract by using the keyword. */
|
|
|
|
#define ZEND_ACC_IMPLICIT_ABSTRACT_CLASS 0x10
|
|
|
|
#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS 0x20
|
|
|
|
#define ZEND_ACC_FINAL_CLASS 0x40
|
|
|
|
#define ZEND_ACC_INTERFACE 0x80
|
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
|
|
|
#define ZEND_ACC_TRAIT 0x120
|
2002-11-24 04:44:12 +08:00
|
|
|
|
2007-02-15 18:38:28 +08:00
|
|
|
/* op_array flags */
|
|
|
|
#define ZEND_ACC_INTERACTIVE 0x10
|
|
|
|
|
2004-03-10 00:38:37 +08:00
|
|
|
/* method flags (visibility) */
|
2002-12-09 20:10:17 +08:00
|
|
|
/* The order of those must be kept - public < protected < private */
|
2003-03-07 06:53:23 +08:00
|
|
|
#define ZEND_ACC_PUBLIC 0x100
|
|
|
|
#define ZEND_ACC_PROTECTED 0x200
|
|
|
|
#define ZEND_ACC_PRIVATE 0x400
|
2002-12-08 22:09:43 +08:00
|
|
|
#define ZEND_ACC_PPP_MASK (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE)
|
2002-12-07 01:09:44 +08:00
|
|
|
|
2003-03-07 06:53:23 +08:00
|
|
|
#define ZEND_ACC_CHANGED 0x800
|
|
|
|
#define ZEND_ACC_IMPLICIT_PUBLIC 0x1000
|
2003-01-02 21:58:08 +08:00
|
|
|
|
2004-03-10 00:38:37 +08:00
|
|
|
/* method flags (special method detection) */
|
2003-08-23 23:38:58 +08:00
|
|
|
#define ZEND_ACC_CTOR 0x2000
|
2004-01-24 04:52:39 +08:00
|
|
|
#define ZEND_ACC_DTOR 0x4000
|
|
|
|
#define ZEND_ACC_CLONE 0x8000
|
2003-08-24 19:09:45 +08:00
|
|
|
|
2004-03-10 00:38:37 +08:00
|
|
|
/* method flag (bc only), any method that has this flag can be used statically and non statically. */
|
|
|
|
#define ZEND_ACC_ALLOW_STATIC 0x10000
|
|
|
|
|
2005-06-10 01:20:44 +08:00
|
|
|
/* shadow of parent's private method/property */
|
|
|
|
#define ZEND_ACC_SHADOW 0x20000
|
|
|
|
|
2006-02-26 02:25:45 +08:00
|
|
|
/* deprecation flag */
|
|
|
|
#define ZEND_ACC_DEPRECATED 0x40000
|
|
|
|
|
2008-03-12 17:46:42 +08:00
|
|
|
/* class implement interface(s) flag */
|
|
|
|
#define ZEND_ACC_IMPLEMENT_INTERFACES 0x80000
|
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
|
|
|
#define ZEND_ACC_IMPLEMENT_TRAITS 0x400000
|
2008-03-12 17:46:42 +08:00
|
|
|
|
2010-09-15 15:38:52 +08:00
|
|
|
/* class constants updated */
|
|
|
|
#define ZEND_ACC_CONSTANTS_UPDATED 0x100000
|
|
|
|
|
2010-07-06 19:40:17 +08:00
|
|
|
/* user class has methods with static variables */
|
|
|
|
#define ZEND_HAS_STATIC_IN_METHODS 0x800000
|
|
|
|
|
|
|
|
|
2008-07-14 17:49:03 +08:00
|
|
|
#define ZEND_ACC_CLOSURE 0x100000
|
2012-05-19 20:18:20 +08:00
|
|
|
#define ZEND_ACC_GENERATOR 0x800000
|
2008-07-14 17:49:03 +08:00
|
|
|
|
2008-07-26 21:14:04 +08:00
|
|
|
/* function flag for internal user call handlers __call, __callstatic */
|
|
|
|
#define ZEND_ACC_CALL_VIA_HANDLER 0x200000
|
2008-03-12 17:46:42 +08:00
|
|
|
|
2011-11-08 18:11:25 +08:00
|
|
|
/* disable inline caching */
|
|
|
|
#define ZEND_ACC_NEVER_CACHE 0x400000
|
|
|
|
|
2013-09-27 00:39:17 +08:00
|
|
|
#define ZEND_ACC_VARIADIC 0x1000000
|
2010-09-15 15:38:52 +08:00
|
|
|
|
|
|
|
#define ZEND_ACC_RETURN_REFERENCE 0x4000000
|
|
|
|
#define ZEND_ACC_DONE_PASS_TWO 0x8000000
|
|
|
|
|
2013-11-28 15:44:14 +08:00
|
|
|
/* function has arguments with type hinting */
|
|
|
|
#define ZEND_ACC_HAS_TYPE_HINTS 0x10000000
|
|
|
|
|
2002-12-07 01:09:44 +08:00
|
|
|
char *zend_visibility_string(zend_uint fn_flags);
|
2002-11-24 04:44:12 +08:00
|
|
|
|
2003-02-04 20:12:34 +08:00
|
|
|
|
|
|
|
typedef struct _zend_property_info {
|
|
|
|
zend_uint flags;
|
2014-02-10 14:04:30 +08:00
|
|
|
zend_string *name;
|
2003-02-04 20:12:34 +08:00
|
|
|
ulong h;
|
2010-05-24 22:11:39 +08:00
|
|
|
int offset;
|
2014-02-10 14:04:30 +08:00
|
|
|
zend_string *doc_comment;
|
2006-05-28 02:39:53 +08:00
|
|
|
zend_class_entry *ce;
|
2003-02-04 20:12:34 +08:00
|
|
|
} zend_property_info;
|
|
|
|
|
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
|
|
|
typedef struct _zend_arg_info {
|
2014-04-15 19:40:40 +08:00
|
|
|
const char *name; // TODO: convert into zend_string ???
|
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
|
|
|
zend_uint name_len;
|
2014-04-15 19:40:40 +08:00
|
|
|
const char *class_name; // TODO: convert into zend_string ???
|
2014-02-21 23:02:24 +08:00
|
|
|
zend_uint class_name_len;
|
2010-07-01 16:58:14 +08:00
|
|
|
zend_uchar type_hint;
|
2013-09-27 00:39:17 +08:00
|
|
|
zend_uchar pass_by_reference;
|
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
|
|
|
zend_bool allow_null;
|
2013-09-27 00:39:17 +08:00
|
|
|
zend_bool is_variadic;
|
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
|
|
|
} zend_arg_info;
|
|
|
|
|
2010-09-15 15:38:52 +08:00
|
|
|
/* the following structure repeats the layout of zend_arg_info,
|
2013-11-09 08:14:58 +08:00
|
|
|
* but its fields have different meaning. It's used as the first element of
|
2010-09-15 15:38:52 +08:00
|
|
|
* arg_info array to define properties of internal functions.
|
|
|
|
*/
|
|
|
|
typedef struct _zend_internal_function_info {
|
|
|
|
const char *_name;
|
|
|
|
zend_uint _name_len;
|
|
|
|
const char *_class_name;
|
|
|
|
zend_uint required_num_args;
|
|
|
|
zend_uchar _type_hint;
|
|
|
|
zend_bool return_reference;
|
2013-09-27 00:39:17 +08:00
|
|
|
zend_bool _allow_null;
|
|
|
|
zend_bool _is_variadic;
|
2010-09-15 15:38:52 +08:00
|
|
|
} zend_internal_function_info;
|
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
struct _zend_op_array {
|
2003-03-29 19:19:38 +08:00
|
|
|
/* Common elements */
|
|
|
|
zend_uchar type;
|
2014-02-10 14:04:30 +08:00
|
|
|
zend_string *function_name;
|
2003-03-29 19:19:38 +08:00
|
|
|
zend_class_entry *scope;
|
|
|
|
zend_uint fn_flags;
|
2014-02-10 14:04:30 +08:00
|
|
|
zend_function *prototype;
|
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
|
|
|
zend_uint num_args;
|
2004-02-25 17:25:37 +08:00
|
|
|
zend_uint required_num_args;
|
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
|
|
|
zend_arg_info *arg_info;
|
2003-03-29 19:19:38 +08:00
|
|
|
/* END of common elements */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2000-03-13 23:43:40 +08:00
|
|
|
zend_uint *refcount;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
|
|
|
zend_op *opcodes;
|
2010-09-15 15:38:52 +08:00
|
|
|
zend_uint last;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
zend_string **vars;
|
2010-09-15 15:38:52 +08:00
|
|
|
int last_var;
|
2004-10-05 03:54:35 +08:00
|
|
|
|
2000-03-13 23:43:40 +08:00
|
|
|
zend_uint T;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
|
|
|
zend_brk_cont_element *brk_cont_array;
|
2008-03-29 19:52:10 +08:00
|
|
|
int last_brk_cont;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2004-02-03 20:17:09 +08:00
|
|
|
zend_try_catch_element *try_catch_array;
|
|
|
|
int last_try_catch;
|
2012-08-22 18:32:03 +08:00
|
|
|
zend_bool has_finally_block;
|
2004-02-03 20:17:09 +08:00
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
/* static variables support */
|
|
|
|
HashTable *static_variables;
|
|
|
|
|
2008-05-07 20:04:39 +08:00
|
|
|
zend_uint this_var;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
zend_string *filename;
|
2003-04-01 04:42:01 +08:00
|
|
|
zend_uint line_start;
|
|
|
|
zend_uint line_end;
|
2014-02-10 14:04:30 +08:00
|
|
|
zend_string *doc_comment;
|
2008-03-18 16:36:30 +08:00
|
|
|
zend_uint early_binding; /* the linked list of delayed declarations */
|
2000-08-10 03:22:35 +08:00
|
|
|
|
2014-04-17 19:40:45 +08:00
|
|
|
zval *literals;
|
2010-09-15 15:38:52 +08:00
|
|
|
int last_literal;
|
2010-04-20 18:57:45 +08:00
|
|
|
|
2010-05-24 22:11:39 +08:00
|
|
|
void **run_time_cache;
|
|
|
|
int last_cache_slot;
|
|
|
|
|
1999-08-16 03:29:39 +08:00
|
|
|
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
1999-04-08 02:10:10 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2004-02-12 21:49:55 +08:00
|
|
|
#define ZEND_RETURN_VALUE 0
|
|
|
|
#define ZEND_RETURN_REFERENCE 1
|
|
|
|
|
1999-05-23 00:10:51 +08:00
|
|
|
typedef struct _zend_internal_function {
|
2003-03-29 19:19:38 +08:00
|
|
|
/* Common elements */
|
|
|
|
zend_uchar type;
|
2014-02-10 14:04:30 +08:00
|
|
|
zend_string* function_name;
|
2003-03-29 19:19:38 +08:00
|
|
|
zend_class_entry *scope;
|
2006-05-10 07:53:23 +08:00
|
|
|
zend_uint fn_flags;
|
2014-02-10 14:04:30 +08:00
|
|
|
zend_function *prototype;
|
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
|
|
|
zend_uint num_args;
|
2004-02-25 17:25:37 +08:00
|
|
|
zend_uint required_num_args;
|
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
|
|
|
zend_arg_info *arg_info;
|
2003-03-29 19:19:38 +08:00
|
|
|
/* END of common elements */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
|
|
|
void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
|
2006-05-10 07:53:23 +08:00
|
|
|
struct _zend_module_entry *module;
|
1999-04-08 02:10:10 +08:00
|
|
|
} zend_internal_function;
|
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
#define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? (function)->common.scope->name->val : "")
|
2002-11-24 04:44:12 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
union _zend_function {
|
2000-03-13 23:43:40 +08:00
|
|
|
zend_uchar type; /* MUST be the first element of this struct! */
|
2002-03-01 22:04:51 +08:00
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
struct {
|
2000-03-13 23:43:40 +08:00
|
|
|
zend_uchar type; /* never used */
|
2014-02-10 14:04:30 +08:00
|
|
|
zend_string *function_name;
|
2002-03-01 22:04:51 +08:00
|
|
|
zend_class_entry *scope;
|
2002-11-24 04:46:39 +08:00
|
|
|
zend_uint fn_flags;
|
2003-03-29 19:19:38 +08:00
|
|
|
union _zend_function *prototype;
|
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
|
|
|
zend_uint num_args;
|
2004-02-25 17:25:37 +08:00
|
|
|
zend_uint required_num_args;
|
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
|
|
|
zend_arg_info *arg_info;
|
1999-04-08 02:10:10 +08:00
|
|
|
} common;
|
2006-05-10 07:53:23 +08:00
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
zend_op_array op_array;
|
|
|
|
zend_internal_function internal_function;
|
2014-02-10 14:04:30 +08:00
|
|
|
};
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-02-26 06:39:50 +08:00
|
|
|
typedef struct _zend_function_call_entry {
|
|
|
|
zend_function *fbc;
|
2014-06-30 19:43:45 +08:00
|
|
|
zend_uint op_number;
|
2014-02-26 07:14:50 +08:00
|
|
|
zend_uint arg_num;
|
Disallow use of positional args after unpacking
This commit disallows the use of trailing positional arguments
after argument unpacking was used. The following calls are no
longer valid:
fn(...$array, $var);
fn(...$array1, $var, ...$array2);
However, all of the following continue to be valid:
fn($var, ...$array);
fn(...$array1, ...$array2);
fn($var, ...$array1, ...$array2);
The reason behind this change is a stack allocation issue pointed
out by Dmitry: As of PHP 5.5 the stack necessary for pushing
arguments is precomputed and preallocated, as such the individual
SEND opcodes no longer verify that there is enough stack space.
The unpacked arguments will occupy some of that preallocated
space and as such following positional arguments could write past
a stack page boundary.
An alternative resolution for this issue is to ensure that there
is enough space for the remaining arguments in the UNPACK opcode.
However making this allocation precise (rather than using a
conversative over-estimate) would require some effort. Given that
this particular aspect of the feature wasn't very popular in the
first place, it doesn't seem worth the effort.
2014-02-26 23:08:58 +08:00
|
|
|
zend_bool uses_argument_unpacking;
|
2014-02-26 06:39:50 +08:00
|
|
|
} zend_function_call_entry;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
1999-05-23 00:10:51 +08:00
|
|
|
typedef struct _zend_switch_entry {
|
1999-04-08 02:10:10 +08:00
|
|
|
znode cond;
|
|
|
|
int default_case;
|
|
|
|
int control_var;
|
|
|
|
} zend_switch_entry;
|
|
|
|
|
|
|
|
|
1999-05-23 00:10:51 +08:00
|
|
|
typedef struct _list_llist_element {
|
1999-04-08 02:10:10 +08:00
|
|
|
znode var;
|
|
|
|
zend_llist dimensions;
|
|
|
|
znode value;
|
|
|
|
} list_llist_element;
|
|
|
|
|
2014-04-18 17:46:36 +08:00
|
|
|
typedef enum _vm_frame_kind {
|
|
|
|
VM_FRAME_NESTED_FUNCTION, /* stackless VM call to function */
|
|
|
|
VM_FRAME_NESTED_CODE, /* stackless VM call to include/require/eval */
|
|
|
|
VM_FRAME_TOP_FUNCTION, /* direct VM call to function from external C code */
|
|
|
|
VM_FRAME_TOP_CODE /* direct VM call to "main" code from external C code */
|
|
|
|
} vm_frame_kind;
|
|
|
|
|
2002-10-20 04:57:15 +08:00
|
|
|
struct _zend_execute_data {
|
2014-04-24 19:53:20 +08:00
|
|
|
struct _zend_op *opline; /* executed opline */
|
2014-06-30 19:43:45 +08:00
|
|
|
zend_execute_data *call; /* current call */
|
2014-04-24 19:53:20 +08:00
|
|
|
void **run_time_cache;
|
2014-06-30 19:43:45 +08:00
|
|
|
zend_function *func; /* executed op_array */
|
|
|
|
zend_uint num_args;
|
|
|
|
zend_uchar flags;
|
|
|
|
zend_uchar frame_kind;
|
|
|
|
zend_class_entry *called_scope;
|
|
|
|
zend_object *object;
|
|
|
|
zend_execute_data *prev_nested_call;
|
2014-04-24 19:53:20 +08:00
|
|
|
zend_execute_data *prev_execute_data;
|
|
|
|
zval *return_value;
|
2014-06-30 19:43:45 +08:00
|
|
|
zend_class_entry *scope; /* function scope (self) */
|
|
|
|
zend_array *symbol_table;
|
|
|
|
struct _zend_op *fast_ret; /* used by FAST_CALL/FAST_RET (finally keyword) */
|
|
|
|
zend_object *delayed_exception;
|
|
|
|
zval old_error_reporting;
|
2002-10-20 04:57:15 +08:00
|
|
|
};
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-06-30 19:43:45 +08:00
|
|
|
#define ZEND_CALL_CTOR (1 << 0)
|
|
|
|
#define ZEND_CALL_CTOR_RESULT_UNUSED (1 << 1)
|
|
|
|
|
|
|
|
#define ZEND_CALL_FRAME_SLOT \
|
|
|
|
((ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval)))
|
|
|
|
|
|
|
|
#define ZEND_CALL_ARG(call, n) \
|
|
|
|
(((zval*)(call)) + ((n) + (ZEND_CALL_FRAME_SLOT - 1)))
|
|
|
|
|
2002-05-08 02:42:13 +08:00
|
|
|
#define EX(element) execute_data.element
|
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
#define EX_VAR_2(ex, n) ((zval*)(((char*)(ex)) + ((int)(n))))
|
2014-06-30 19:43:45 +08:00
|
|
|
#define EX_VAR_NUM_2(ex, n) (((zval*)(ex)) + (ZEND_CALL_FRAME_SLOT + ((int)(n))))
|
2012-12-04 14:14:39 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
#define EX_VAR(n) EX_VAR_2(execute_data, n)
|
|
|
|
#define EX_VAR_NUM(n) EX_VAR_NUM_2(execute_data, n)
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-03-27 20:00:25 +08:00
|
|
|
#define EX_VAR_TO_NUM(n) (EX_VAR_2(NULL, n) - EX_VAR_NUM_2(NULL, 0))
|
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
#define IS_CONST (1<<0)
|
|
|
|
#define IS_TMP_VAR (1<<1)
|
|
|
|
#define IS_VAR (1<<2)
|
|
|
|
#define IS_UNUSED (1<<3) /* Unused variable */
|
2004-10-05 03:54:35 +08:00
|
|
|
#define IS_CV (1<<4) /* Compiled variable */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2010-04-20 18:57:45 +08:00
|
|
|
#define EXT_TYPE_UNUSED (1<<5)
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2000-06-14 01:58:33 +08:00
|
|
|
#include "zend_globals.h"
|
|
|
|
|
2000-01-30 01:19:47 +08:00
|
|
|
BEGIN_EXTERN_C()
|
|
|
|
|
2001-07-28 18:51:54 +08:00
|
|
|
void init_compiler(TSRMLS_D);
|
|
|
|
void shutdown_compiler(TSRMLS_D);
|
|
|
|
void zend_init_compiler_data_structures(TSRMLS_D);
|
2010-09-15 15:38:52 +08:00
|
|
|
void zend_init_compiler_context(TSRMLS_D);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2001-07-28 18:51:54 +08:00
|
|
|
extern ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
|
2006-06-13 20:57:48 +08:00
|
|
|
extern ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, char *filename TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2002-02-10 20:54:02 +08:00
|
|
|
ZEND_API int lex_scan(zval *zendlval TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
void startup_scanner(TSRMLS_D);
|
|
|
|
void shutdown_scanner(TSRMLS_D);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
ZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filename TSRMLS_DC);
|
|
|
|
ZEND_API void zend_restore_compiled_filename(zend_string *original_compiled_filename TSRMLS_DC);
|
|
|
|
ZEND_API zend_string *zend_get_compiled_filename(TSRMLS_D);
|
2001-07-28 18:51:54 +08:00
|
|
|
ZEND_API int zend_get_compiled_lineno(TSRMLS_D);
|
2008-07-28 13:59:17 +08:00
|
|
|
ZEND_API size_t zend_get_scanned_file_offset(TSRMLS_D);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2013-08-30 23:55:43 +08:00
|
|
|
void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace, zend_bool case_sensitive, HashTable *current_import_sub TSRMLS_DC);
|
|
|
|
void zend_resolve_function_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC);
|
|
|
|
void zend_resolve_const_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC);
|
2013-09-13 18:18:39 +08:00
|
|
|
void zend_resolve_class_name(znode *class_name TSRMLS_DC);
|
2014-02-10 14:04:30 +08:00
|
|
|
ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var);
|
2005-01-22 10:29:18 +08:00
|
|
|
|
1999-04-23 11:32:33 +08:00
|
|
|
#ifdef ZTS
|
2001-07-28 18:51:54 +08:00
|
|
|
const char *zend_get_zendtext(TSRMLS_D);
|
|
|
|
int zend_get_zendleng(TSRMLS_D);
|
1999-04-23 11:32:33 +08:00
|
|
|
#endif
|
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
|
|
|
|
/* parser-driven code generators */
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_binary_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
|
|
|
void zend_do_unary_op(zend_uchar op, znode *result, znode *op1 TSRMLS_DC);
|
|
|
|
void zend_do_binary_assign_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
2010-04-20 18:57:45 +08:00
|
|
|
void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_assign_ref(znode *result, znode *lvar, znode *rvar TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
void fetch_simple_variable(znode *result, znode *varname, int bp TSRMLS_DC);
|
2002-04-24 02:06:54 +08:00
|
|
|
void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar op TSRMLS_DC);
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_indirect_references(znode *result, const znode *num_references, znode *variable TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_fetch_static_variable(znode *varname, znode *static_assignment, int fetch_type TSRMLS_DC);
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_fetch_global_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
|
|
|
|
void fetch_array_begin(znode *result, znode *varname, znode *first_dim TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void fetch_array_dim(znode *result, znode *parent, znode *dim TSRMLS_DC);
|
|
|
|
void fetch_string_offset(znode *result, znode *parent, znode *offset TSRMLS_DC);
|
2004-10-05 03:54:35 +08:00
|
|
|
void zend_do_fetch_static_member(znode *result, znode *class_znode TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_print(znode *result, znode *arg TSRMLS_DC);
|
|
|
|
void zend_do_echo(znode *arg TSRMLS_DC);
|
2008-08-30 02:12:47 +08:00
|
|
|
typedef int (*unary_op_type)(zval *, zval * TSRMLS_DC);
|
|
|
|
typedef int (*binary_op_type)(zval *, zval *, zval * TSRMLS_DC);
|
1999-05-30 21:28:56 +08:00
|
|
|
ZEND_API unary_op_type get_unary_op(int opcode);
|
2008-08-30 02:12:47 +08:00
|
|
|
ZEND_API binary_op_type get_binary_op(int opcode);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_while_cond(znode *expr, znode *close_bracket_token TSRMLS_DC);
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_while_end(const znode *while_token, const znode *close_bracket_token TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_do_while_begin(TSRMLS_D);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_do_while_end(const znode *do_token, const znode *expr_open_bracket, znode *expr TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_if_cond(znode *cond, znode *closing_bracket_token TSRMLS_DC);
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_if_after_statement(const znode *closing_bracket_token, unsigned char initialize TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_if_end(TSRMLS_D);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_for_cond(znode *expr, znode *second_semicolon_token TSRMLS_DC);
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_for_before_statement(const znode *cond_start, const znode *second_semicolon_token TSRMLS_DC);
|
|
|
|
void zend_do_for_end(const znode *second_semicolon_token TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_pre_incdec(znode *result, znode *op1, zend_uchar op TSRMLS_DC);
|
|
|
|
void zend_do_post_incdec(znode *result, znode *op1, zend_uchar op TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_begin_variable_parse(TSRMLS_D);
|
2008-05-07 20:04:39 +08:00
|
|
|
void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_check_writable_variable(const znode *variable);
|
2001-12-17 03:45:49 +08:00
|
|
|
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_free(znode *op1 TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_add_string(znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
|
|
|
void zend_do_add_variable(znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2008-08-13 01:20:25 +08:00
|
|
|
int zend_do_verify_access_types(const znode *current_access_type, const znode *new_modifier);
|
2003-03-05 19:14:44 +08:00
|
|
|
void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC);
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_receive_param(zend_uchar op, znode *varname, znode *initialization, znode *class_type, zend_bool pass_by_reference, zend_bool is_variadic TSRMLS_DC);
|
2007-09-29 03:52:53 +08:00
|
|
|
int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace TSRMLS_DC);
|
2001-12-27 01:49:22 +08:00
|
|
|
void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_clone(znode *result, znode *expr TSRMLS_DC);
|
2007-09-29 03:52:53 +08:00
|
|
|
void zend_do_begin_dynamic_function_call(znode *function_name, int prefix_len TSRMLS_DC);
|
2003-06-02 20:13:11 +08:00
|
|
|
void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC);
|
2008-11-04 23:58:55 +08:00
|
|
|
void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_class_member TSRMLS_DC);
|
2007-11-20 16:53:02 +08:00
|
|
|
int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC);
|
2014-02-26 07:14:50 +08:00
|
|
|
void zend_do_end_function_call(znode *function_name, znode *result, int is_method, int is_dynamic_fcall TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_yield(znode *result, znode *value, znode *key, zend_bool is_variable TSRMLS_DC);
|
2004-02-03 20:17:09 +08:00
|
|
|
void zend_do_handle_exception(TSRMLS_D);
|
2001-08-30 23:26:30 +08:00
|
|
|
|
2010-04-20 03:45:03 +08:00
|
|
|
void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference, int is_static TSRMLS_DC);
|
2008-07-14 17:49:03 +08:00
|
|
|
void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC);
|
|
|
|
|
2001-08-31 01:27:43 +08:00
|
|
|
void zend_do_try(znode *try_token TSRMLS_DC);
|
2010-04-20 19:05:54 +08:00
|
|
|
void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var, znode *first_catch TSRMLS_DC);
|
2012-08-27 10:23:23 +08:00
|
|
|
void zend_do_bind_catch(znode *try_token, znode *catch_token TSRMLS_DC);
|
2012-08-13 21:48:39 +08:00
|
|
|
void zend_do_end_catch(znode *catch_token TSRMLS_DC);
|
2012-08-14 08:59:40 +08:00
|
|
|
void zend_do_finally(znode *finally_token TSRMLS_DC);
|
|
|
|
void zend_do_end_finally(znode *try_token, znode* catch_token, znode *finally_token TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_throw(znode *expr TSRMLS_DC);
|
2001-08-30 23:26:30 +08:00
|
|
|
|
2014-07-05 20:12:20 +08:00
|
|
|
ZEND_API int do_bind_function(const zend_op_array *op_array, zend_op *opline, HashTable *function_table, zend_bool compile_time TSRMLS_DC);
|
2010-04-20 18:57:45 +08:00
|
|
|
ZEND_API zend_class_entry *do_bind_class(const zend_op_array *op_array, const zend_op *opline, HashTable *class_table, zend_bool compile_time TSRMLS_DC);
|
|
|
|
ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array, const zend_op *opline, HashTable *class_table, zend_class_entry *parent_ce, zend_bool compile_time TSRMLS_DC);
|
2008-08-13 01:20:25 +08:00
|
|
|
ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_entry *iface TSRMLS_DC);
|
2003-10-23 03:59:58 +08:00
|
|
|
ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC);
|
2003-03-05 19:14:44 +08:00
|
|
|
void zend_do_implements_interface(znode *interface_znode TSRMLS_DC);
|
2002-09-25 03:05:53 +08:00
|
|
|
|
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
|
|
|
/* Trait related functions */
|
2012-12-25 14:23:08 +08:00
|
|
|
void zend_do_use_trait(znode *trait_znode TSRMLS_DC);
|
|
|
|
void zend_prepare_reference(znode *result, znode *class_name, znode *method_name TSRMLS_DC);
|
|
|
|
void zend_add_trait_precedence(znode *method_reference, znode *trait_list TSRMLS_DC);
|
|
|
|
void zend_add_trait_alias(znode *method_reference, znode *modifiers, znode *alias TSRMLS_DC);
|
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
|
|
|
|
|
|
|
ZEND_API void zend_do_implement_trait(zend_class_entry *ce, zend_class_entry *trait TSRMLS_DC);
|
|
|
|
ZEND_API void zend_do_bind_traits(zend_class_entry *ce TSRMLS_DC);
|
|
|
|
|
2005-05-28 18:24:56 +08:00
|
|
|
ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_early_binding(TSRMLS_D);
|
2008-08-13 01:20:25 +08:00
|
|
|
ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-02-26 07:14:50 +08:00
|
|
|
void zend_do_pass_param(znode *param, zend_uchar op TSRMLS_DC);
|
|
|
|
void zend_do_unpack_params(znode *params TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
|
|
|
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_boolean_or_begin(znode *expr1, znode *op_token TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_boolean_or_end(znode *result, znode *expr1, znode *expr2, const znode *op_token TSRMLS_DC);
|
2003-02-01 09:49:15 +08:00
|
|
|
void zend_do_boolean_and_begin(znode *expr1, znode *op_token TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_boolean_and_end(znode *result, znode *expr1, znode *expr2, const znode *op_token TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_brk_cont(zend_uchar op, znode *expr TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_switch_cond(const znode *cond TSRMLS_DC);
|
|
|
|
void zend_do_switch_end(const znode *case_list TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_case_before_statement(const znode *case_list, znode *case_token, znode *case_expr TSRMLS_DC);
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_case_after_statement(znode *result, const znode *case_token TSRMLS_DC);
|
|
|
|
void zend_do_default_before_statement(const znode *case_list, znode *default_token TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_begin_class_declaration(const znode *class_token, znode *class_name, const znode *parent_class_name TSRMLS_DC);
|
|
|
|
void zend_do_end_class_declaration(const znode *class_token, const znode *parent_token TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_declare_property(znode *var_name, znode *value, zend_uint access_type TSRMLS_DC);
|
|
|
|
void zend_do_declare_class_constant(znode *var_name, znode *value TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_fetch_property(znode *result, znode *object, znode *property TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2007-04-04 08:42:42 +08:00
|
|
|
void zend_do_halt_compiler_register(TSRMLS_D);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_push_object(const znode *object TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_pop_object(znode *object TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
|
|
|
|
2001-11-05 03:30:49 +08:00
|
|
|
void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC);
|
2014-02-26 07:14:50 +08:00
|
|
|
void zend_do_end_new_object(znode *result, const znode *new_token TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2007-09-29 03:52:53 +08:00
|
|
|
void zend_do_fetch_constant(znode *result, znode *constant_container, znode *constant_name, int mode, zend_bool check_namespace TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_shell_exec(znode *result, znode *cmd TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_init_array(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC);
|
|
|
|
void zend_do_add_array_element(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC);
|
2014-04-22 23:54:34 +08:00
|
|
|
void zend_do_end_array(znode *result, const znode *array_node TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_list_init(TSRMLS_D);
|
|
|
|
void zend_do_list_end(znode *result, znode *expr TSRMLS_DC);
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_add_list_element(const znode *element TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_new_list_begin(TSRMLS_D);
|
|
|
|
void zend_do_new_list_end(TSRMLS_D);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
|
|
|
/* Functions for a null terminated pointer list, used for traits parsing and compilation */
|
|
|
|
void zend_init_list(void *result, void *item TSRMLS_DC);
|
|
|
|
void zend_add_to_list(void *result, void *item TSRMLS_DC);
|
|
|
|
|
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_cast(znode *result, znode *expr, int type TSRMLS_DC);
|
|
|
|
void zend_do_include_or_eval(int type, znode *result, znode *op1 TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_unset(znode *variable TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_instanceof(znode *result, znode *expr, znode *class_znode, int type TSRMLS_DC);
|
2002-07-30 12:07:15 +08:00
|
|
|
|
2007-01-10 23:58:08 +08:00
|
|
|
void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, znode *array, znode *as_token, int variable TSRMLS_DC);
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token, const znode *as_token, znode *value, znode *key TSRMLS_DC);
|
|
|
|
void zend_do_foreach_end(const znode *foreach_token, const znode *as_token TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_declare_begin(TSRMLS_D);
|
|
|
|
void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC);
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_declare_end(const znode *declare_token TSRMLS_DC);
|
2000-01-25 03:00:30 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_exit(znode *result, znode *message TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_begin_silence(znode *strudel_token TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_end_silence(znode *strudel_token TSRMLS_DC);
|
2007-11-21 17:41:35 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_jmp_set(znode *value, znode *jmp_token, znode *colon_token TSRMLS_DC);
|
|
|
|
void zend_do_jmp_set_else(znode *result, znode *false_value, const znode *jmp_token, znode *colon_token TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_begin_qm_op(znode *cond, znode *qm_token TSRMLS_DC);
|
|
|
|
void zend_do_qm_true(znode *true_value, znode *qm_token, znode *colon_token TSRMLS_DC);
|
|
|
|
void zend_do_qm_false(znode *result, znode *false_value, znode *qm_token, const znode *colon_token TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_extended_info(TSRMLS_D);
|
|
|
|
void zend_do_extended_fcall_begin(TSRMLS_D);
|
|
|
|
void zend_do_extended_fcall_end(TSRMLS_D);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2001-07-28 18:51:54 +08:00
|
|
|
void zend_do_ticks(TSRMLS_D);
|
2000-01-25 03:00:30 +08:00
|
|
|
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_abstract_method(const znode *function_name, znode *modifiers, const znode *body TSRMLS_DC);
|
2002-11-21 02:00:23 +08:00
|
|
|
|
2007-09-29 03:52:53 +08:00
|
|
|
void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC);
|
|
|
|
void zend_do_build_namespace_name(znode *result, znode *prefix, znode *name TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_begin_namespace(znode *name, zend_bool with_brackets TSRMLS_DC);
|
2008-11-25 17:56:32 +08:00
|
|
|
void zend_do_end_namespace(TSRMLS_D);
|
|
|
|
void zend_verify_namespace(TSRMLS_D);
|
2007-12-13 18:02:03 +08:00
|
|
|
void zend_do_use(znode *name, znode *new_name, int is_global TSRMLS_DC);
|
2013-11-09 10:37:38 +08:00
|
|
|
void zend_do_use_non_class(znode *ns_name, znode *new_name, int is_global, int is_function, zend_bool case_sensitive, HashTable *current_import_sub, HashTable *lookup_table TSRMLS_DC);
|
2013-07-17 02:39:33 +08:00
|
|
|
void zend_do_use_function(znode *name, znode *new_name, int is_global TSRMLS_DC);
|
2013-07-24 02:21:48 +08:00
|
|
|
void zend_do_use_const(znode *name, znode *new_name, int is_global TSRMLS_DC);
|
2007-09-29 03:52:53 +08:00
|
|
|
void zend_do_end_compilation(TSRMLS_D);
|
2013-11-07 02:21:07 +08:00
|
|
|
void zend_do_constant_expression(znode *result, zend_ast *ast TSRMLS_DC);
|
2007-09-29 03:52:53 +08:00
|
|
|
|
2013-01-19 08:00:47 +08:00
|
|
|
void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static TSRMLS_DC);
|
|
|
|
|
2008-03-28 22:35:01 +08:00
|
|
|
void zend_do_label(znode *label TSRMLS_DC);
|
2014-04-22 22:52:59 +08:00
|
|
|
void zend_do_goto(znode *label TSRMLS_DC);
|
2008-03-28 22:35:01 +08:00
|
|
|
void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 TSRMLS_DC);
|
2013-03-28 04:03:40 +08:00
|
|
|
void zend_release_labels(int temporary TSRMLS_DC);
|
2008-03-28 22:35:01 +08:00
|
|
|
|
2000-06-14 03:01:22 +08:00
|
|
|
ZEND_API void function_add_ref(zend_function *function);
|
2000-06-03 09:49:49 +08:00
|
|
|
|
1999-04-26 22:10:42 +08:00
|
|
|
#define INITIAL_OP_ARRAY_SIZE 64
|
2010-09-15 15:38:52 +08:00
|
|
|
#define INITIAL_INTERACTIVE_OP_ARRAY_SIZE 8192
|
1999-04-26 22:10:42 +08:00
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2000-10-29 22:35:34 +08:00
|
|
|
/* helper functions in zend_language_scanner.l */
|
2001-07-28 18:51:54 +08:00
|
|
|
ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC);
|
2006-05-10 07:53:23 +08:00
|
|
|
ZEND_API zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
ZEND_API zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC);
|
2014-02-10 14:04:30 +08:00
|
|
|
ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval *retval, int file_count, ...);
|
2001-07-28 18:51:54 +08:00
|
|
|
ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC);
|
2002-04-24 02:06:54 +08:00
|
|
|
ZEND_API void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size TSRMLS_DC);
|
2003-03-26 15:44:11 +08:00
|
|
|
ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC);
|
2001-07-28 18:51:54 +08:00
|
|
|
ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle TSRMLS_DC);
|
2014-04-21 17:55:25 +08:00
|
|
|
ZEND_API void zend_cleanup_user_class_data(zend_class_entry *ce TSRMLS_DC);
|
2010-07-06 19:40:17 +08:00
|
|
|
ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce TSRMLS_DC);
|
2010-07-06 23:52:39 +08:00
|
|
|
ZEND_API void zend_cleanup_internal_classes(TSRMLS_D);
|
2014-04-21 17:55:25 +08:00
|
|
|
ZEND_API void zend_cleanup_op_array_data(zend_op_array *op_array);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2003-03-26 15:44:11 +08:00
|
|
|
ZEND_API void destroy_zend_function(zend_function *function TSRMLS_DC);
|
2014-02-17 21:59:18 +08:00
|
|
|
ZEND_API void zend_function_dtor(zval *zv);
|
|
|
|
ZEND_API void destroy_zend_class(zval *zv);
|
|
|
|
void zend_class_add_ref(zval *zv);
|
1999-04-26 22:10:42 +08:00
|
|
|
|
2014-02-17 21:59:18 +08:00
|
|
|
ZEND_API zend_string *zend_mangle_property_name(const char *src1, int src1_length, const char *src2, int src2_length, int internal);
|
2013-01-14 16:23:22 +08:00
|
|
|
#define zend_unmangle_property_name(mangled_property, mangled_property_len, class_name, prop_name) \
|
2013-11-09 08:14:58 +08:00
|
|
|
zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL)
|
2013-01-14 16:23:22 +08:00
|
|
|
ZEND_API int zend_unmangle_property_name_ex(const char *mangled_property, int mangled_property_len, const char **class_name, const char **prop_name, int *prop_len);
|
2003-02-04 20:12:34 +08:00
|
|
|
|
2014-02-17 21:59:18 +08:00
|
|
|
#define ZEND_FUNCTION_DTOR zend_function_dtor
|
|
|
|
#define ZEND_CLASS_DTOR destroy_zend_class
|
1999-07-10 01:24:47 +08:00
|
|
|
|
2001-07-28 18:51:54 +08:00
|
|
|
zend_op *get_next_op(zend_op_array *op_array TSRMLS_DC);
|
|
|
|
void init_op(zend_op *op TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
int get_next_op_number(zend_op_array *op_array);
|
2001-07-31 12:53:54 +08:00
|
|
|
int print_class(zend_class_entry *class_entry TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
void print_op_array(zend_op_array *op_array, int optimizations);
|
2009-06-06 07:20:59 +08:00
|
|
|
ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array);
|
2004-02-03 20:17:09 +08:00
|
|
|
void zend_do_first_catch(znode *open_parentheses TSRMLS_DC);
|
2012-08-13 21:48:39 +08:00
|
|
|
void zend_initialize_try_catch_element(znode *catch_token TSRMLS_DC);
|
2008-08-13 01:20:25 +08:00
|
|
|
void zend_do_mark_last_catch(const znode *first_catch, const znode *last_additional_catch TSRMLS_DC);
|
2001-07-30 15:43:02 +08:00
|
|
|
ZEND_API zend_bool zend_is_compiling(TSRMLS_D);
|
2008-08-13 01:20:25 +08:00
|
|
|
ZEND_API char *zend_make_compiled_string_description(const char *name TSRMLS_DC);
|
2003-12-16 19:44:19 +08:00
|
|
|
ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers TSRMLS_DC);
|
2007-09-28 02:00:48 +08:00
|
|
|
int zend_get_class_fetch_type(const char *class_name, uint class_name_len);
|
2003-02-11 00:11:24 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
typedef zend_bool (*zend_auto_global_callback)(zend_string *name TSRMLS_DC);
|
2003-03-02 18:04:53 +08:00
|
|
|
typedef struct _zend_auto_global {
|
2014-02-10 14:04:30 +08:00
|
|
|
zend_string *name;
|
2003-03-02 18:04:53 +08:00
|
|
|
zend_auto_global_callback auto_global_callback;
|
2010-07-08 22:05:11 +08:00
|
|
|
zend_bool jit;
|
2003-03-02 18:04:53 +08:00
|
|
|
zend_bool armed;
|
|
|
|
} zend_auto_global;
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-02-10 14:04:30 +08:00
|
|
|
ZEND_API int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global_callback auto_global_callback TSRMLS_DC);
|
2010-07-08 22:05:11 +08:00
|
|
|
ZEND_API void zend_activate_auto_globals(TSRMLS_D);
|
2014-02-10 14:04:30 +08:00
|
|
|
ZEND_API zend_bool zend_is_auto_global(zend_string *name TSRMLS_DC);
|
2008-02-12 08:21:15 +08:00
|
|
|
ZEND_API size_t zend_dirname(char *path, size_t len);
|
2001-08-09 01:18:16 +08:00
|
|
|
|
2001-07-28 18:51:54 +08:00
|
|
|
int zendlex(znode *zendlval TSRMLS_DC);
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-04-22 22:52:59 +08:00
|
|
|
int zend_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC);
|
2010-04-20 18:57:45 +08:00
|
|
|
|
2003-04-08 05:48:17 +08:00
|
|
|
/* BEGIN: OPCODES */
|
2003-06-02 20:13:11 +08:00
|
|
|
|
2004-10-28 01:58:46 +08:00
|
|
|
#include "zend_vm_opcodes.h"
|
2003-02-16 19:12:43 +08:00
|
|
|
|
2004-10-28 01:58:46 +08:00
|
|
|
#define ZEND_OP_DATA 137
|
2004-02-03 20:17:09 +08:00
|
|
|
|
2003-04-08 05:48:17 +08:00
|
|
|
/* END: OPCODES */
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2001-12-13 01:38:37 +08:00
|
|
|
/* class fetches */
|
|
|
|
#define ZEND_FETCH_CLASS_DEFAULT 0
|
|
|
|
#define ZEND_FETCH_CLASS_SELF 1
|
2001-12-27 21:12:45 +08:00
|
|
|
#define ZEND_FETCH_CLASS_PARENT 2
|
2014-08-08 17:47:34 +08:00
|
|
|
#define ZEND_FETCH_CLASS_STATIC 3
|
|
|
|
#define ZEND_FETCH_CLASS_AUTO 4
|
|
|
|
#define ZEND_FETCH_CLASS_INTERFACE 5
|
|
|
|
#define ZEND_FETCH_CLASS_TRAIT 6
|
2007-10-03 18:33:02 +08:00
|
|
|
#define ZEND_FETCH_CLASS_MASK 0x0f
|
2005-09-09 14:48:49 +08:00
|
|
|
#define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80
|
2007-10-03 18:33:02 +08:00
|
|
|
#define ZEND_FETCH_CLASS_SILENT 0x0100
|
2001-12-13 01:38:37 +08:00
|
|
|
|
2001-12-17 03:18:19 +08:00
|
|
|
/* variable parsing type (compile-time) */
|
2003-07-24 20:38:33 +08:00
|
|
|
#define ZEND_PARSED_MEMBER (1<<0)
|
|
|
|
#define ZEND_PARSED_METHOD_CALL (1<<1)
|
|
|
|
#define ZEND_PARSED_STATIC_MEMBER (1<<2)
|
|
|
|
#define ZEND_PARSED_FUNCTION_CALL (1<<3)
|
|
|
|
#define ZEND_PARSED_VARIABLE (1<<4)
|
|
|
|
#define ZEND_PARSED_REFERENCE_VARIABLE (1<<5)
|
2008-07-24 19:47:51 +08:00
|
|
|
#define ZEND_PARSED_NEW (1<<6)
|
2012-08-25 22:23:14 +08:00
|
|
|
#define ZEND_PARSED_LIST_EXPR (1<<7)
|
2001-12-17 03:18:19 +08:00
|
|
|
|
2001-08-07 11:17:33 +08:00
|
|
|
/* unset types */
|
|
|
|
#define ZEND_UNSET_REG 0
|
|
|
|
|
1999-04-08 02:10:10 +08:00
|
|
|
/* var status for backpatching */
|
1999-09-30 01:18:36 +08:00
|
|
|
#define BP_VAR_R 0
|
|
|
|
#define BP_VAR_W 1
|
|
|
|
#define BP_VAR_RW 2
|
|
|
|
#define BP_VAR_IS 3
|
|
|
|
#define BP_VAR_NA 4 /* if not applicable */
|
|
|
|
#define BP_VAR_FUNC_ARG 5
|
2000-02-15 04:31:01 +08:00
|
|
|
#define BP_VAR_UNSET 6
|
1999-04-08 02:10:10 +08:00
|
|
|
|
|
|
|
|
2003-08-19 06:31:11 +08:00
|
|
|
#define ZEND_INTERNAL_FUNCTION 1
|
|
|
|
#define ZEND_USER_FUNCTION 2
|
|
|
|
#define ZEND_OVERLOADED_FUNCTION 3
|
|
|
|
#define ZEND_EVAL_CODE 4
|
|
|
|
#define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5
|
1999-04-08 02:10:10 +08:00
|
|
|
|
2014-06-30 19:43:45 +08:00
|
|
|
/* A quick check (type == ZEND_USER_FUNCTION || type == ZEND_EVAL_CODE) */
|
|
|
|
#define ZEND_USER_CODE(type) ((type & 1) == 0)
|
|
|
|
|
2003-04-02 03:37:04 +08:00
|
|
|
#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)
|
1999-12-23 23:03:25 +08:00
|
|
|
#define ZEND_REQUIRE (1<<3)
|
2000-08-10 03:22:35 +08:00
|
|
|
#define ZEND_REQUIRE_ONCE (1<<4)
|
1999-04-08 02:10:10 +08:00
|
|
|
|
|
|
|
#define ZEND_CT (1<<0)
|
|
|
|
#define ZEND_RT (1<<1)
|
|
|
|
|
2010-04-20 18:57:45 +08:00
|
|
|
/* global/local fetches */
|
|
|
|
#define ZEND_FETCH_GLOBAL 0x00000000
|
|
|
|
#define ZEND_FETCH_LOCAL 0x10000000
|
|
|
|
#define ZEND_FETCH_STATIC 0x20000000
|
|
|
|
#define ZEND_FETCH_STATIC_MEMBER 0x30000000
|
|
|
|
#define ZEND_FETCH_GLOBAL_LOCK 0x40000000
|
|
|
|
#define ZEND_FETCH_LEXICAL 0x50000000
|
|
|
|
|
|
|
|
#define ZEND_FETCH_TYPE_MASK 0x70000000
|
|
|
|
|
|
|
|
#define ZEND_FETCH_STANDARD 0x00000000
|
|
|
|
#define ZEND_FETCH_ADD_LOCK 0x08000000
|
|
|
|
#define ZEND_FETCH_MAKE_REF 0x04000000
|
|
|
|
|
|
|
|
#define ZEND_ISSET 0x02000000
|
|
|
|
#define ZEND_ISEMPTY 0x01000000
|
|
|
|
#define ZEND_ISSET_ISEMPTY_MASK (ZEND_ISSET | ZEND_ISEMPTY)
|
|
|
|
#define ZEND_QUICK_SET 0x00800000
|
|
|
|
|
|
|
|
#define ZEND_FETCH_ARG_MASK 0x000fffff
|
1999-05-23 00:10:51 +08:00
|
|
|
|
2004-08-12 13:54:11 +08:00
|
|
|
#define ZEND_FE_FETCH_BYREF 1
|
|
|
|
#define ZEND_FE_FETCH_WITH_KEY 2
|
|
|
|
|
2010-04-20 18:57:45 +08:00
|
|
|
#define ZEND_FE_RESET_VARIABLE (1<<0)
|
|
|
|
#define ZEND_FE_RESET_REFERENCE (1<<1)
|
|
|
|
#define EXT_TYPE_FREE_ON_RETURN (1<<2)
|
2006-05-12 05:07:39 +08:00
|
|
|
|
1999-05-28 20:06:59 +08:00
|
|
|
#define ZEND_MEMBER_FUNC_CALL 1<<0
|
|
|
|
|
2000-11-28 02:46:23 +08:00
|
|
|
#define ZEND_ARG_SEND_BY_REF (1<<0)
|
|
|
|
#define ZEND_ARG_COMPILE_TIME_BOUND (1<<1)
|
2005-06-22 16:33:00 +08:00
|
|
|
#define ZEND_ARG_SEND_FUNCTION (1<<2)
|
2009-01-20 21:21:52 +08:00
|
|
|
#define ZEND_ARG_SEND_SILENT (1<<3)
|
1999-07-10 02:19:48 +08:00
|
|
|
|
2005-08-10 20:02:52 +08:00
|
|
|
#define ZEND_SEND_BY_VAL 0
|
|
|
|
#define ZEND_SEND_BY_REF 1
|
|
|
|
#define ZEND_SEND_PREFER_REF 2
|
|
|
|
|
2013-09-27 00:39:17 +08:00
|
|
|
#define CHECK_ARG_SEND_TYPE(zf, arg_num, m) \
|
2014-04-22 16:33:00 +08:00
|
|
|
(EXPECTED((zf)->common.arg_info != NULL) && \
|
|
|
|
(EXPECTED(arg_num <= (zf)->common.num_args) \
|
2013-09-27 00:39:17 +08:00
|
|
|
? ((zf)->common.arg_info[arg_num-1].pass_by_reference & (m)) \
|
2014-04-22 16:33:00 +08:00
|
|
|
: (UNEXPECTED((zf)->common.fn_flags & ZEND_ACC_VARIADIC) != 0) && \
|
|
|
|
((zf)->common.arg_info[(zf)->common.num_args-1].pass_by_reference & (m))))
|
2006-09-26 18:30:51 +08:00
|
|
|
|
|
|
|
#define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \
|
2013-09-27 00:39:17 +08:00
|
|
|
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF)
|
2006-09-26 18:30:51 +08:00
|
|
|
|
|
|
|
#define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \
|
2013-09-27 00:39:17 +08:00
|
|
|
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF)
|
2006-09-26 18:30:51 +08:00
|
|
|
|
|
|
|
#define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \
|
2013-09-27 00:39:17 +08:00
|
|
|
CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_PREFER_REF)
|
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
|
|
|
|
1999-12-16 04:15:32 +08:00
|
|
|
#define ZEND_RETURN_VAL 0
|
|
|
|
#define ZEND_RETURN_REF 1
|
|
|
|
|
2003-12-15 00:09:07 +08:00
|
|
|
|
|
|
|
#define ZEND_RETURNS_FUNCTION 1<<0
|
2008-07-24 19:47:51 +08:00
|
|
|
#define ZEND_RETURNS_NEW 1<<1
|
2013-11-28 00:30:35 +08:00
|
|
|
#define ZEND_RETURNS_VALUE 1<<2
|
2003-12-15 00:09:07 +08:00
|
|
|
|
2012-11-22 19:17:05 +08:00
|
|
|
#define ZEND_FAST_RET_TO_CATCH 1
|
|
|
|
#define ZEND_FAST_RET_TO_FINALLY 2
|
|
|
|
|
2014-07-19 17:19:01 +08:00
|
|
|
#define ZEND_FAST_CALL_FROM_CATCH 1
|
|
|
|
#define ZEND_FAST_CALL_FROM_FINALLY 2
|
2014-07-18 15:45:31 +08:00
|
|
|
|
2014-04-23 06:47:41 +08:00
|
|
|
#define ZEND_ARRAY_ELEMENT_REF (1<<0)
|
|
|
|
#define ZEND_ARRAY_NOT_PACKED (1<<1)
|
|
|
|
#define ZEND_ARRAY_SIZE_SHIFT 2
|
|
|
|
|
2000-01-30 01:19:47 +08:00
|
|
|
END_EXTERN_C()
|
|
|
|
|
2002-09-04 17:07:58 +08:00
|
|
|
#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"
|
2006-05-10 07:53:23 +08:00
|
|
|
#define ZEND_UNSET_FUNC_NAME "__unset"
|
|
|
|
#define ZEND_ISSET_FUNC_NAME "__isset"
|
2002-09-04 17:07:58 +08:00
|
|
|
#define ZEND_CALL_FUNC_NAME "__call"
|
2007-09-29 16:52:40 +08:00
|
|
|
#define ZEND_CALLSTATIC_FUNC_NAME "__callstatic"
|
2006-05-10 07:53:23 +08:00
|
|
|
#define ZEND_TOSTRING_FUNC_NAME "__tostring"
|
2004-08-02 16:27:57 +08:00
|
|
|
#define ZEND_AUTOLOAD_FUNC_NAME "__autoload"
|
2013-03-08 10:34:17 +08:00
|
|
|
#define ZEND_INVOKE_FUNC_NAME "__invoke"
|
2014-02-18 11:13:00 +08:00
|
|
|
#define ZEND_DEBUGINFO_FUNC_NAME "__debuginfo"
|
2002-09-04 17:07:58 +08:00
|
|
|
|
2008-03-18 16:36:30 +08:00
|
|
|
/* The following constants may be combined in CG(compiler_options)
|
|
|
|
* to change the default compiler behavior */
|
|
|
|
|
|
|
|
/* generate extended debug information */
|
|
|
|
#define ZEND_COMPILE_EXTENDED_INFO (1<<0)
|
|
|
|
|
|
|
|
/* call op_array handler of extendions */
|
|
|
|
#define ZEND_COMPILE_HANDLE_OP_ARRAY (1<<1)
|
|
|
|
|
2014-06-30 19:43:45 +08:00
|
|
|
/* generate ZEND_INIT_FCALL_BY_NAME for internal functions instead of ZEND_INIT_FCALL */
|
2008-03-18 16:36:30 +08:00
|
|
|
#define ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS (1<<2)
|
|
|
|
|
|
|
|
/* 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<<3)
|
|
|
|
|
|
|
|
/* generate ZEND_DECLARE_INHERITED_CLASS_DELAYED opcode to delay early binding */
|
|
|
|
#define ZEND_COMPILE_DELAYED_BINDING (1<<4)
|
|
|
|
|
2008-07-25 12:54:08 +08:00
|
|
|
/* disable constant substitution at compile-time */
|
|
|
|
#define ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION (1<<5)
|
|
|
|
|
2014-07-11 22:52:27 +08:00
|
|
|
/* disable usage of builtin instruction for strlen() */
|
|
|
|
#define ZEND_COMPILE_NO_BUILTIN_STRLEN (1<<6)
|
|
|
|
|
2008-03-18 16:36:30 +08:00
|
|
|
/* 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
|
|
|
|
|
2000-07-03 08:55:36 +08:00
|
|
|
#endif /* ZEND_COMPILE_H */
|
2003-02-01 09:49:15 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Local variables:
|
|
|
|
* tab-width: 4
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* indent-tabs-mode: t
|
|
|
|
* End:
|
|
|
|
*/
|