-
Notifications
You must be signed in to change notification settings - Fork 50
/
zap.h
480 lines (401 loc) · 14.3 KB
/
zap.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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
/**
* Zend Abstractions for Php
*/
#ifndef ZAP_H_
#define ZAP_H_
#include <php.h>
typedef struct _zap_class_entry {
#if PHP_VERSION_ID >= 70000
zend_object* (*create_obj)(zend_class_entry *class_type);
zend_object_free_obj_t free_obj;
zend_object_dtor_obj_t dtor_obj;
zend_object_clone_obj_t clone_obj;
#else
zend_object_value (*create_obj)(zend_class_entry *type TSRMLS_DC);
zend_objects_free_object_storage_t free_obj;
zend_objects_store_dtor_t dtor_obj;
zend_objects_store_clone_t clone_obj;
#endif
struct {
zend_class_entry ce;
zend_object_handlers handlers;
} _internal;
} zap_class_entry;
#define zap_init_class_entry(cls, name, methods) \
memset((cls), 0, sizeof(zap_class_entry));\
INIT_CLASS_ENTRY((cls)->_internal.ce, name, methods)
#if PHP_VERSION_ID >= 70000
static zend_class_entry * _zap_register_internal_class(zap_class_entry *cls, int offset TSRMLS_DC) {
zend_class_entry *ce;
memcpy(&cls->_internal.handlers,
zend_get_std_object_handlers(), sizeof(zend_object_handlers));
cls->_internal.handlers.offset = offset;
if (cls->free_obj != NULL) {
cls->_internal.handlers.free_obj = cls->free_obj;
}
if (cls->dtor_obj != NULL) {
cls->_internal.handlers.dtor_obj = cls->dtor_obj;
}
if (cls->clone_obj != NULL) {
cls->_internal.handlers.clone_obj = cls->clone_obj;
}
cls->_internal.ce.create_object = cls->create_obj;
ce = zend_register_internal_class(&cls->_internal.ce TSRMLS_CC);
return ce;
}
#define zap_register_internal_class(cls, Type) \
_zap_register_internal_class(cls, XtOffsetOf(struct Type, std) TSRMLS_CC)
static inline zend_object * _zap_finalize_object(zend_object *std, zap_class_entry* cls) {
std->handlers = &(cls)->_internal.handlers;
return std;
}
#define zap_finalize_object(obj, cls) \
_zap_finalize_object(&obj->std, cls)
#else
static zend_class_entry * _zap_register_internal_class(zap_class_entry *cls TSRMLS_DC) {
zend_class_entry *ce;
memcpy(&cls->_internal.handlers,
zend_get_std_object_handlers(), sizeof(zend_object_handlers));
cls->_internal.ce.create_object = cls->create_obj;
ce = zend_register_internal_class(&cls->_internal.ce TSRMLS_CC);
return ce;
}
#define zap_register_internal_class(cls, Type) \
_zap_register_internal_class(cls TSRMLS_CC)
static inline zend_object_value _zap_finalize_object(void *obj, zap_class_entry* cls TSRMLS_DC) {
zend_object_value retval;
retval.handle = zend_objects_store_put(
obj, cls->dtor_obj, cls->free_obj, cls->clone_obj TSRMLS_CC);
retval.handlers = &(cls)->_internal.handlers;
return retval;
}
#define zap_finalize_object(obj, cls) \
_zap_finalize_object(obj, cls TSRMLS_CC)
#endif
#if PHP_VERSION_ID >= 70000
#define zap_DTORRES_FUNC(name) \
void name(zend_resource *rsrc TSRMLS_DC)
#define zap_fetch_resource(z, name, le) \
zend_fetch_resource_ex(z, name, le)
#else
#define zap_DTORRES_FUNC(name) \
void name(zend_rsrc_list_entry *rsrc TSRMLS_DC)
#define zap_fetch_resource(z, name, le) \
zend_fetch_resource(&z TSRMLS_CC, -1, name, NULL, 1, le)
#endif
#if PHP_VERSION_ID >= 70000
#define zap_ZEND_OBJECT_START
#define zap_ZEND_OBJECT_END zend_object std;
#define zap_get_object(Type, object) ((struct Type *)((char*)(object) - XtOffsetOf(struct Type, std)))
#define zap_fetch_this(Type) zap_get_object(Type, Z_OBJ_P(getThis()))
#define zap_CREATEOBJ_FUNC(name) \
zend_object * name(zend_class_entry *type TSRMLS_DC)
#define zap_FREEOBJ_FUNC(name) \
void name(zend_object *object TSRMLS_DC)
#define zap_alloc_object_storage(Type, type) \
((Type *)ecalloc(1, sizeof(Type) + zend_object_properties_size(type)))
#define zap_free_object_storage(o)
#else
#define zap_ZEND_OBJECT_START zend_object std;
#define zap_ZEND_OBJECT_END
#define zap_get_object(Type, object) ((Type*)object)
#define zap_fetch_this(Type) ((Type*)zend_object_store_get_object(getThis() TSRMLS_CC))
#define zap_CREATEOBJ_FUNC(name) \
zend_object_value name(zend_class_entry *type TSRMLS_DC)
#define zap_FREEOBJ_FUNC(name) \
void name(void *object TSRMLS_DC)
#define zap_alloc_object_storage(Type, type) \
((Type *)ecalloc(1, sizeof(Type)))
#define zap_free_object_storage(o) efree(o)
#endif
#if PHP_VERSION_ID >= 70000
typedef zval zapval;
#define zapval_zvalptr(v) (&v)
#define zapval_zvalptr_p(v) (v)
#define zapvalptr_from_zvalptr(v) (v)
#define zapval_from_zvalptr(v) (*v)
// These all set a zval* to something
#define zap_zval_undef_p(v) \
ZVAL_UNDEF(v)
#define zap_zval_null_p(v) \
ZVAL_NULL(v)
#define zap_zval_bool_p(v, b) \
if (b) { ZVAL_TRUE(v); } else { ZVAL_FALSE(v); }
#define zap_zval_empty_string_p(v) \
ZVAL_EMPTY_STRING(v)
#define zap_zval_stringl_p(v, b, nb) \
if (b != NULL || nb > 0) { ZVAL_STRINGL(v, b, nb); } \
else { ZVAL_EMPTY_STRING(v); }
#define zap_zval_long_p(v, n) \
ZVAL_LONG(v, n)
#define zap_zval_array_p(v) \
array_init(v)
#define zap_zval_zval_p(v, z, copy, dtor) \
ZVAL_ZVAL(v, z, copy, dtor)
#define zap_zval_res_p(v, ptr, type) \
ZVAL_RES(v, zend_register_resource(ptr, type))
#define zap_zval_is_undef(v) \
(Z_TYPE_P(v) == IS_UNDEF)
#define zap_zval_is_bool(v) \
(Z_TYPE_P(v) == IS_TRUE || Z_TYPE_P(v) == IS_FALSE)
#define zap_zval_is_array(v) \
(Z_TYPE_P(v) == IS_ARRAY)
#define zap_zval_boolval(v) \
(Z_TYPE_P(v) == IS_TRUE ? 1 : 0)
// These all set a zapval to something
#define zapval_undef(v) \
zap_zval_undef_p(&v)
#define zapval_null(v) \
zap_zval_null_p(&v)
#define zapval_empty_string(v) \
zap_zval_empty_string_p(&v)
#define zapval_stringl(v, b, nb) \
zap_zval_stringl_p(&v, b, nb)
#define zapval_long(v, n) \
zap_zval_long_p(&v, n)
#define zapval_array(v) \
zap_zval_array_p(&v)
#define zapval_zval(v, z, copy, dtor) \
zap_zval_zval_p(&v, z, copy, dtor)
#define zapval_res(v, ptr, type) \
zap_zval_res_p(&v, ptr, type)
// These all allocate and set a zapval to something
#define zapval_alloc(v) \
zapval_undef(v)
#define zapval_addref(v) \
Z_TRY_ADDREF(v)
#define zapval_destroy(v) \
zval_ptr_dtor(&v)
#define zapval_is_undef(v) (Z_TYPE(v) == IS_UNDEF)
#define zapval_is_bool(v) (Z_TYPE(v) == IS_TRUE || Z_TYPE(v) == IS_FALSE)
#define zapval_is_string(v) (Z_TYPE(v) == IS_STRING)
#define zapval_is_long(v) (Z_TYPE(v) == IS_LONG)
#define zapval_is_array(v) (Z_TYPE(v) == IS_ARRAY)
#define zapval_arrval(v) Z_ARRVAL(v)
#define zapval_strlen_p(v) Z_STRLEN_P(v)
#define zapval_strval_p(v) Z_STRVAL_P(v)
#define zapval_lval_p(v) Z_LVAL_P(v)
#define zap_throw_exception_object(o) zend_throw_exception_object(&o TSRMLS_CC)
// int param_count, zapval *args
#define zap_get_parameters_array_ex(param_count, args) \
_zend_get_parameters_array_ex(param_count, args TSRMLS_CC)
#define zap_call_user_function(o, f, r, np, p) \
call_user_function(CG(function_table), o, &f, r, np, p TSRMLS_CC)
#define zap_hash_str_add(ht, k, nk, hv) \
zend_hash_str_add(ht, k, nk, hv)
#define zap_hash_next_index_insert(ht, hv) \
zend_hash_next_index_insert(ht, hv)
#define zap_hash_str_find(ht, k, nk) \
zend_hash_str_find(ht, k, nk)
#define zap_hash_index_find(ht, i) \
zend_hash_index_find(ht, i)
#define zap_hash_get_current_data_ex(ht, pos) \
zend_hash_get_current_data_ex(ht, pos)
static inline int zap_hash_str_get_current_key_ex(HashTable *ht, char **str,
uint *len, zend_ulong *num_index, HashPosition *pos) {
zend_string *zstr = NULL;
int key_type = zend_hash_get_current_key_ex(ht, &zstr, num_index, pos);
if (zstr != NULL) {
*str = zstr->val;
*len = zstr->len;
} else {
*str = NULL;
*len = 0;
}
return key_type;
}
#else
typedef zval* zapval;
#define zapval_zvalptr(v) (v)
#define zapval_zvalptr_p(v) (*v)
#define zapvalptr_from_zvalptr(v) (&v)
#define zapval_from_zvalptr(v) (v)
// TODO: v=NULL will leak memory!
// These all set a zval* to something
#define zap_zval_undef_p(v) \
v = NULL;
#define zap_zval_null_p(v) \
ZVAL_NULL(v)
#define zap_zval_bool_p(v, b) \
if (b) { ZVAL_TRUE(v); } else { ZVAL_FALSE(v); }
#define zap_zval_empty_string_p(v) \
ZVAL_EMPTY_STRING(v)
#define zap_zval_stringl_p(v, b, nb) \
if (b != NULL || nb > 0) { ZVAL_STRINGL(v, b, nb, 1); } \
else { ZVAL_EMPTY_STRING(v); }
#define zap_zval_long_p(v, n) \
ZVAL_LONG(v, n)
#define zap_zval_array_p(v) \
array_init(v)
#define zap_zval_zval_p(v, z, copy, dtor) \
ZVAL_ZVAL(v, z, copy, dtor)
#define zap_zval_res_p(v, ptr, type) \
ZEND_REGISTER_RESOURCE(v, ptr, type)
#define zap_zval_is_undef(v) \
(v == NULL)
#define zap_zval_is_bool(v) \
(Z_TYPE_P(v) == IS_BOOL)
#define zap_zval_is_array(v) \
(Z_TYPE_P(v) == IS_ARRAY)
#define zap_zval_boolval(v) \
Z_BVAL_P(v)
// These all set a zapval to something
#define zapval_undef(v) \
zap_zval_undef_p(v)
#define zapval_null(v) \
zap_zval_null_p(v)
#define zapval_empty_string(v) \
zap_zval_empty_string_p(v)
#define zapval_stringl(v, b, nb) \
zap_zval_stringl_p(v, b, nb)
#define zapval_long(v, n) \
zap_zval_long_p(v, n)
#define zapval_array(v) \
zap_zval_array_p(v)
#define zapval_zval(v, z, copy, dtor) \
zap_zval_zval_p(v, z, copy, dtor)
#define zapval_res(v, ptr, type) \
zap_zval_res_p(v, ptr, type)
// These all allocate and set a zapval to something
#define zapval_alloc(v) \
MAKE_STD_ZVAL(v)
#define zapval_addref(v) \
Z_ADDREF_P(v)
#define zapval_destroy(v) \
zval_ptr_dtor(&v)
#define zapval_is_undef(v) (v == NULL)
#define zapval_is_bool(v) (Z_TYPE_P(v) == IS_BOOL)
#define zapval_is_string(v) (Z_TYPE_P(v) == IS_STRING)
#define zapval_is_long(v) (Z_TYPE_P(v) == IS_LONG)
#define zapval_is_array(v) (Z_TYPE_P(v) == IS_ARRAY)
#define zapval_arrval(v) Z_ARRVAL_P(v)
#define zapval_strlen_p(v) Z_STRLEN_PP(v)
#define zapval_strval_p(v) Z_STRVAL_PP(v)
#define zapval_lval_p(v) Z_LVAL_PP(v)
#define zap_throw_exception_object(o) zend_throw_exception_object(o TSRMLS_CC)
static inline int _zap_get_parameters_array_ex(int param_count, zapval *args TSRMLS_DC)
{
if (param_count <= 16) {
int i;
zval **_args[16];
int retval = _zend_get_parameters_array_ex(param_count, _args TSRMLS_CC);
for (i = 0; i < param_count; ++i) {
args[i] = *_args[i];
}
return retval;
} else {
int i;
zval ***_args = emalloc(param_count * sizeof(zval**));
int retval = _zend_get_parameters_array_ex(param_count, _args TSRMLS_CC);
for (i = 0; i < param_count; ++i) {
args[i] = *_args[i];
}
efree(_args);
return retval;
}
}
#define zap_get_parameters_array_ex(param_count, args) \
_zap_get_parameters_array_ex(param_count, args TSRMLS_CC)
#define zap_call_user_function(o, f, r, np, p) \
call_user_function(CG(function_table), o, f, r, np, p TSRMLS_CC)
static inline zval * _zap_hash_str_add(HashTable *ht, char *key, size_t len, zval *pData) {
if (zend_hash_add(ht, key, len + 1, (void*)&pData, sizeof(zval**), NULL) != SUCCESS) {
return NULL;
}
return pData;
}
#define zap_hash_str_add(ht, k, nk, hv) \
_zap_hash_str_add(ht, k, nk, hv)
static inline zval * _zap_hash_next_index_insert(HashTable *ht, zval *pData) {
if (zend_hash_next_index_insert(
ht, (void*)&pData, sizeof(zval**), NULL) != SUCCESS) {
return NULL;
}
return pData;
}
#define zap_hash_next_index_insert(ht, hv) \
_zap_hash_next_index_insert(ht, hv)
static inline zval * _zap_hash_str_find(HashTable *ht, char *key, size_t len) {
zval **result = NULL;
if (zend_hash_find(ht, key, len+1, (void**)&result) != SUCCESS) {
return NULL;
}
return *result;
}
#define zap_hash_str_find(ht, k, nk) \
_zap_hash_str_find(ht, k, nk)
static inline zapval * _zap_hash_index_find(HashTable *ht, ulong i) {
zval **result;
if (zend_hash_index_find(ht, i, (void**)&result) != SUCCESS) {
return NULL;
}
return result;
}
#define zap_hash_index_find(ht, i) \
_zap_hash_index_find(ht, i)
static inline zapval * _zap_hash_get_current_data_ex(HashTable *ht, HashPosition *pos) {
zval **result;
if (zend_hash_get_current_data_ex(ht, (void**)&result, pos) != SUCCESS) {
return NULL;
}
return result;
}
#define zap_hash_get_current_data_ex(ht, pos) \
_zap_hash_get_current_data_ex(ht, pos)
static inline int zap_hash_str_get_current_key_ex(HashTable *ht, char **str,
uint *len, zend_ulong *num_index, HashPosition *pos) {
uint len_out = 0;
int key_type = zend_hash_get_current_key_ex(ht, str, &len_out, num_index, 0, pos);
if (len != NULL) {
*len = len_out - 1;
}
return key_type;
}
#endif
#define zapval_alloc_null(v) \
zapval_alloc(v); \
zapval_null(v)
#define zapval_alloc_empty_string(v) \
zapval_alloc(v); \
zapval_empty_string(v)
#define zapval_alloc_stringl(v, b, nb) \
zapval_alloc(v); \
zapval_stringl(v, b, nb)
#define zapval_alloc_long(v, n) \
zapval_alloc(v); \
zapval_long(v, n)
#define zapval_alloc_array(v) \
zapval_alloc(v); \
zapval_array(v)
#define zapval_alloc_zval(v, z, copy, dtor) \
zapval_alloc(v); \
zapval_zval(v, z, copy, dtor)
#define zapval_alloc_res(v, ptr, type) \
zapval_alloc(v); \
zapval_res(v, ptr, type)
#define zapval_is_undef_p(v) zapval_is_undef(*v)
#define zapval_is_bool_p(v) zapval_is_bool(*v)
#define zapval_is_string_p(v) zapval_is_string(*v)
#define zapval_is_long_p(v) zapval_is_long(*v)
#if PHP_VERSION_ID >= 50400
#define zap_object_properties_init object_properties_init
#else
static void zap_object_properties_init(zend_object *obj, zend_class_entry* type) {
zval *tmp;
ALLOC_HASHTABLE(obj->properties);
zend_hash_init(obj->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_copy(obj->properties, &type->default_properties,
(copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
}
#endif
#if ZEND_MODULE_API_NO >= 20151012
#define zap_zend_register_internal_class_ex(ce, parent_ce) zend_register_internal_class_ex(ce, parent_ce TSRMLS_CC)
#else
#define zap_zend_register_internal_class_ex(ce, parent_ce) zend_register_internal_class_ex(ce, parent_ce, NULL TSRMLS_CC)
#endif
#if ZEND_MODULE_API_NO >= 20060613
#define zap_zend_exception_get_default() zend_exception_get_default(TSRMLS_C)
#else
#define zap_zend_exception_get_default() zend_exception_get_default()
#endif
#endif // ZAP_H_