-
Notifications
You must be signed in to change notification settings - Fork 95
/
aop.h
267 lines (235 loc) · 9.35 KB
/
aop.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*
/+----------------------------------------------------------------------+
| AOP |
+----------------------------------------------------------------------+
| Copyright (c) 2012 Julien Salleyron, Gérald Croës |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Julien Salleyron <julien.salleyron@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef PHP_AOP_H
#define PHP_AOP_H 1
#ifndef ZVAL_COPY_VALUE
#define ZVAL_COPY_VALUE(z, v)\
do {\
(z)->value = (v)->value;\
Z_TYPE_P(z) = Z_TYPE_P(v);\
} while (0)
#endif
#define PHP_AOP_VERSION "0.2.0"
#define PHP_AOP_EXTNAME "aop"
//Resource
#define PHP_POINTCUT_RES_NAME "AOP Pointcut"
#define AOP_KIND_AROUND 1
#define AOP_KIND_BEFORE 2
#define AOP_KIND_AFTER 4
#define AOP_KIND_READ 8
#define AOP_KIND_WRITE 16
#define AOP_KIND_PROPERTY 32
#define AOP_KIND_METHOD 64
#define AOP_KIND_FUNCTION 128
#define AOP_KIND_CATCH 256
#define AOP_KIND_RETURN 512
#define AOP_KIND_AROUND_READ_PROPERTY (AOP_KIND_AROUND+AOP_KIND_READ+AOP_KIND_PROPERTY)
#define AOP_KIND_AROUND_WRITE_PROPERTY (AOP_KIND_AROUND+AOP_KIND_WRITE+AOP_KIND_PROPERTY)
#define AOP_KIND_BEFORE_READ_PROPERTY (AOP_KIND_BEFORE+AOP_KIND_READ+AOP_KIND_PROPERTY)
#define AOP_KIND_BEFORE_WRITE_PROPERTY (AOP_KIND_BEFORE+AOP_KIND_WRITE+AOP_KIND_PROPERTY)
#define AOP_KIND_AFTER_READ_PROPERTY (AOP_KIND_AFTER+AOP_KIND_READ+AOP_KIND_PROPERTY)
#define AOP_KIND_AFTER_WRITE_PROPERTY (AOP_KIND_AFTER+AOP_KIND_WRITE+AOP_KIND_PROPERTY)
#define AOP_KIND_AROUND_METHOD (AOP_KIND_AROUND+AOP_KIND_METHOD)
#define AOP_KIND_AROUND_FUNCTION (AOP_KIND_AROUND+AOP_KIND_FUNCTION)
#define AOP_KIND_BEFORE_METHOD (AOP_KIND_BEFORE+AOP_KIND_METHOD)
#define AOP_KIND_BEFORE_FUNCTION (AOP_KIND_BEFORE+AOP_KIND_FUNCTION)
#define AOP_KIND_AFTER_METHOD (AOP_KIND_AFTER+AOP_KIND_METHOD)
#define AOP_KIND_AFTER_FUNCTION (AOP_KIND_AFTER+AOP_KIND_FUNCTION)
#if ZEND_MODULE_API_NO >= 20100525
#define AOP_KEY_D , const zend_literal *key
#define AOP_KEY_C , key
#else
#define AOP_KEY_D
#define AOP_KEY_C
#endif
typedef struct {
zend_op_array *op;
zend_execute_data *ex;
zend_class_entry *scope;
zval *currentThis;
zval *ret;
zval *args;
zend_execute_data *current_execute_data;
int return_value_used;
int internal;
zval *property;
zval *value;
#if ZEND_MODULE_API_NO >= 20100525
const zend_literal *key;
#endif
} joinpoint_context;
typedef struct {
int scope;
int static_state;
char *class_name;
int class_jok;
char *method;
int method_jok;
char *selector;
int kind_of_advice;
zend_fcall_info fci;
zend_fcall_info_cache fcic;
pcre *re_method;
pcre *re_class;
} pointcut;
typedef struct {
HashTable *reads;
HashTable *writes;
HashTable *funcs;
} object_cache;
typedef struct {
int count;
pointcut **pointcuts_cache;
HashTable *ht;
int declare_count;
zend_class_entry *ce;
} pointcut_cache;
typedef struct {
pointcut *pc;
pointcut *previous_pc;
zval *object;
} instance_of_pointcut;
typedef struct {
HashTable *ht;
} handled_ht;
typedef struct {
zend_object std;
joinpoint_context *context;
instance_of_pointcut *pc;
instance_of_pointcut *current_pc;
pointcut *current_pointcut;
//Here because we want it different from pointcut resource
int kind_of_advice;
int current_pointcut_index;
HashTable *advice;
HashPosition pos;
zval *object;
zval *member;
zval *value;
int type;
#if ZEND_MODULE_API_NO >= 20100525
const zend_literal *key;
#endif
zend_execute_data *ex;
zend_class_entry *scope;
zend_class_entry *called_scope;
zval *args;
zval *exception;
int args_overloaded;
zval **to_return_ptr_ptr;
} AopJoinpoint_object;
#ifdef ZTS
#include "TSRM.h"
#endif
ZEND_BEGIN_MODULE_GLOBALS(aop)
int count_pcs;
int overloaded;
int count_write_property;
int lock_write_property;
pointcut **property_pointcuts_write;
int count_read_property;
int lock_read_property;
pointcut **property_pointcuts_read;
int count_aopJoinpoint_cache;
zval **aopJoinpoint_cache;
HashTable **object_cache_write;
int object_cache_write_size;
HashTable **object_cache_read;
int object_cache_read_size;
HashTable **object_cache_func;
int object_cache_func_size;
zend_bool aop_enable;
HashTable * pointcuts;
ZEND_END_MODULE_GLOBALS(aop)
#ifdef ZTS
#define aop_g(v) TSRMG(aop_globals_id, zend_aop_globals *, v)
#else
#define aop_g(v) (aop_globals.v)
#endif
PHP_MINIT_FUNCTION(aop);
PHP_RINIT_FUNCTION(aop);
PHP_RSHUTDOWN_FUNCTION(aop);
PHP_MSHUTDOWN_FUNCTION(aop);
PHP_FUNCTION(aop_add_around);
PHP_FUNCTION(aop_get_previous_joinpoint);
PHP_FUNCTION(aop_add_before);
PHP_FUNCTION(aop_add_after);
PHP_FUNCTION(aop_add_after_returning);
PHP_FUNCTION(aop_add_after_throwing);
PHP_METHOD(AopJoinpoint, getArguments);
PHP_METHOD(AopJoinpoint, getPropertyName);
PHP_METHOD(AopJoinpoint, setArguments);
PHP_METHOD(AopJoinpoint, getKindOfAdvice);
PHP_METHOD(AopJoinpoint, getReturnedValue);
PHP_METHOD(AopJoinpoint, getAssignedValue);
PHP_METHOD(AopJoinpoint, setReturnedValue);
PHP_METHOD(AopJoinpoint, setAssignedValue);
PHP_METHOD(AopJoinpoint, getPointcut);
PHP_METHOD(AopJoinpoint, getObject);
PHP_METHOD(AopJoinpoint, getClassName);
PHP_METHOD(AopJoinpoint, getMethodName);
PHP_METHOD(AopJoinpoint, getFunctionName);
PHP_METHOD(AopJoinpoint, getException);
PHP_METHOD(AopJoinpoint, process);
extern zend_module_entry aop_module_entry;
#define phpext_aop_ptr &aop_module_entry
#endif
static void (*_zend_execute) (zend_op_array *ops TSRMLS_DC);
#if ZEND_MODULE_API_NO < 20121113
static void (*_zend_execute_internal) (zend_execute_data *current_execute_data, int return_value_used TSRMLS_DC);
#else
static void (*_zend_execute_internal) (zend_execute_data *current_execute_data, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC);
#endif
static void add_pointcut (zend_fcall_info fci, zend_fcall_info_cache fcic, char *selector, int selector_len, int type, zval **return_value_ptr TSRMLS_DC);
static void parse_pointcut (pointcut **pc);
static void free_pointcut(void *);
static void free_pointcut_cache (void *);
ZEND_DLEXPORT void aop_execute (zend_op_array *ops TSRMLS_DC);
#if ZEND_MODULE_API_NO < 20121113
ZEND_DLEXPORT void aop_execute_internal (zend_execute_data *current_execute_data, int return_value_used TSRMLS_DC);
#else
ZEND_DLEXPORT void aop_execute_internal (zend_execute_data *current_execute_data, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC);
#endif
void joinpoint_execute (instance_of_pointcut *pc);
static zval *get_current_args (zend_execute_data *ex TSRMLS_DC);
void exec(AopJoinpoint_object *obj TSRMLS_DC);
static int strcmp_with_joker (char *str_with_jok, char *str);
static int strcmp_with_joker_case (char *str_with_jok, char *str, int case_sensitive);
static int is_static (char *str);
static int explode_scope_by_pipe (char *partial);
static int get_scope (char *str);
static char* get_class_part (char *str);
static char * get_method_part (char *str);
void aop_execute_global (int internal, zend_op_array *ops,zend_execute_data *current_execute_data, int return_value_used TSRMLS_DC);
static int pointcut_match_zend_class_entry (pointcut *pc, zend_class_entry *ce);
static int pointcut_match_zend_function (pointcut *pc, zend_function *curr_func, zend_execute_data *data);
#if ZEND_MODULE_API_NO < 20100525
static void (*zend_std_write_property)(zval *object, zval *member, zval *value TSRMLS_DC);
#endif
static zval * (*zend_std_read_property)(zval *object, zval *member, int type AOP_KEY_D TSRMLS_DC);
static zval ** (*zend_std_get_property_ptr_ptr)(zval *object, zval *member AOP_KEY_D TSRMLS_DC);
static void _test_write_pointcut_and_execute(HashPosition pos, HashTable *ht, zval *object, zval *member, zval *value, zend_class_entry *current_scope AOP_KEY_D);
static pointcut *aop_add_read (char *selector, zend_fcall_info fci, zend_fcall_info_cache fcic, int type);
static pointcut *aop_add_write (char *selector, zend_fcall_info fci, zend_fcall_info_cache fcic, int type);
static void execute_pointcut (pointcut *pointcut_to_execute, zval *arg);
static int test_property_scope (pointcut *current_pc, zend_class_entry *ce, zval *member AOP_KEY_D);
static void execute_context (zend_execute_data *ex, zval *object, zend_class_entry *calling_scope, zend_class_entry *called_scope, int args_overloaded, zval *args, zval ** to_return_ptr_ptr);
ZEND_DECLARE_MODULE_GLOBALS(aop)
HashTable *calculate_function_pointcuts (zval *object, zend_execute_data *ex);
HashTable *calculate_property_pointcuts (zval *object, zval *member, int kind AOP_KEY_D);
static zval *_test_read_pointcut_and_execute(HashPosition pos, HashTable *ht, zval *object, zval *member, int type, zend_class_entry *current_scope AOP_KEY_D);