Annotation of embedaddon/php/Zend/zend_execute.h, revision 1.1.1.1
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | Zend Engine |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
6: +----------------------------------------------------------------------+
7: | This source file is subject to version 2.00 of the Zend license, |
8: | that is bundled with this package in the file LICENSE, and is |
9: | available through the world-wide-web at the following url: |
10: | http://www.zend.com/license/2_00.txt. |
11: | If you did not receive a copy of the Zend license and are unable to |
12: | obtain it through the world-wide-web, please send a note to |
13: | license@zend.com so we can mail you a copy immediately. |
14: +----------------------------------------------------------------------+
15: | Authors: Andi Gutmans <andi@zend.com> |
16: | Zeev Suraski <zeev@zend.com> |
17: +----------------------------------------------------------------------+
18: */
19:
20: /* $Id: zend_execute.h 321634 2012-01-01 13:15:04Z felipe $ */
21:
22: #ifndef ZEND_EXECUTE_H
23: #define ZEND_EXECUTE_H
24:
25: #include "zend_compile.h"
26: #include "zend_hash.h"
27: #include "zend_operators.h"
28: #include "zend_variables.h"
29:
30: typedef union _temp_variable {
31: zval tmp_var;
32: struct {
33: zval **ptr_ptr;
34: zval *ptr;
35: zend_bool fcall_returned_reference;
36: } var;
37: struct {
38: zval **ptr_ptr;
39: zval *ptr;
40: zend_bool fcall_returned_reference;
41: zval *str;
42: zend_uint offset;
43: } str_offset;
44: struct {
45: zval **ptr_ptr;
46: zval *ptr;
47: zend_bool fcall_returned_reference;
48: HashPointer fe_pos;
49: } fe;
50: zend_class_entry *class_entry;
51: } temp_variable;
52:
53:
54: BEGIN_EXTERN_C()
55: ZEND_API extern void (*zend_execute)(zend_op_array *op_array TSRMLS_DC);
56: ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
57:
58: void init_executor(TSRMLS_D);
59: void shutdown_executor(TSRMLS_D);
60: void shutdown_destructors(TSRMLS_D);
61: ZEND_API void execute(zend_op_array *op_array TSRMLS_DC);
62: ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
63: ZEND_API int zend_is_true(zval *op);
64: #define safe_free_zval_ptr(p) safe_free_zval_ptr_rel(p ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
65: static inline void safe_free_zval_ptr_rel(zval *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
66: {
67: TSRMLS_FETCH();
68:
69: if (p!=EG(uninitialized_zval_ptr)) {
70: FREE_ZVAL_REL(p);
71: }
72: }
73: ZEND_API int zend_lookup_class(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
74: ZEND_API int zend_lookup_class_ex(const char *name, int name_length, int use_autoload, zend_class_entry ***ce TSRMLS_DC);
75: ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
76: ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *string_name TSRMLS_DC);
77: ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
78: ZEND_API int zend_eval_stringl_ex(char *str, int str_len, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
79:
80: static inline int i_zend_is_true(zval *op)
81: {
82: int result;
83:
84: switch (Z_TYPE_P(op)) {
85: case IS_NULL:
86: result = 0;
87: break;
88: case IS_LONG:
89: case IS_BOOL:
90: case IS_RESOURCE:
91: result = (Z_LVAL_P(op)?1:0);
92: break;
93: case IS_DOUBLE:
94: result = (Z_DVAL_P(op) ? 1 : 0);
95: break;
96: case IS_STRING:
97: if (Z_STRLEN_P(op) == 0
98: || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
99: result = 0;
100: } else {
101: result = 1;
102: }
103: break;
104: case IS_ARRAY:
105: result = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
106: break;
107: case IS_OBJECT:
108: if(IS_ZEND_STD_OBJECT(*op)) {
109: TSRMLS_FETCH();
110:
111: if (Z_OBJ_HT_P(op)->cast_object) {
112: zval tmp;
113: if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_BOOL TSRMLS_CC) == SUCCESS) {
114: result = Z_LVAL(tmp);
115: break;
116: }
117: } else if (Z_OBJ_HT_P(op)->get) {
118: zval *tmp = Z_OBJ_HT_P(op)->get(op TSRMLS_CC);
119: if(Z_TYPE_P(tmp) != IS_OBJECT) {
120: /* for safety - avoid loop */
121: convert_to_boolean(tmp);
122: result = Z_LVAL_P(tmp);
123: zval_ptr_dtor(&tmp);
124: break;
125: }
126: }
127: }
128: result = 1;
129: break;
130: default:
131: result = 0;
132: break;
133: }
134: return result;
135: }
136:
137: ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC);
138: ZEND_API int zval_update_constant_inline_change(zval **pp, void *arg TSRMLS_DC);
139: ZEND_API int zval_update_constant_no_inline_change(zval **pp, void *arg TSRMLS_DC);
140: ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC);
141:
142: /* dedicated Zend executor functions - do not use! */
143: #define ZEND_VM_STACK_PAGE_SIZE ((64 * 1024) - 64)
144:
145: struct _zend_vm_stack {
146: void **top;
147: void **end;
148: zend_vm_stack prev;
149: };
150:
151: #define ZEND_VM_STACK_ELEMETS(stack) \
152: ((void**)(((char*)(stack)) + ZEND_MM_ALIGNED_SIZE(sizeof(struct _zend_vm_stack))))
153:
154: #define ZEND_VM_STACK_GROW_IF_NEEDED(count) \
155: do { \
156: if (UNEXPECTED((count) > \
157: EG(argument_stack)->end - EG(argument_stack)->top)) { \
158: zend_vm_stack_extend((count) TSRMLS_CC); \
159: } \
160: } while (0)
161:
162: static inline zend_vm_stack zend_vm_stack_new_page(int count) {
163: zend_vm_stack page = (zend_vm_stack)emalloc(ZEND_MM_ALIGNED_SIZE(sizeof(*page)) + sizeof(void*) * count);
164:
165: page->top = ZEND_VM_STACK_ELEMETS(page);
166: page->end = page->top + count;
167: page->prev = NULL;
168: return page;
169: }
170:
171: static inline void zend_vm_stack_init(TSRMLS_D)
172: {
173: EG(argument_stack) = zend_vm_stack_new_page(ZEND_VM_STACK_PAGE_SIZE);
174: }
175:
176: static inline void zend_vm_stack_destroy(TSRMLS_D)
177: {
178: zend_vm_stack stack = EG(argument_stack);
179:
180: while (stack != NULL) {
181: zend_vm_stack p = stack->prev;
182: efree(stack);
183: stack = p;
184: }
185: }
186:
187: static inline void zend_vm_stack_extend(int count TSRMLS_DC)
188: {
189: zend_vm_stack p = zend_vm_stack_new_page(count >= ZEND_VM_STACK_PAGE_SIZE ? count : ZEND_VM_STACK_PAGE_SIZE);
190: p->prev = EG(argument_stack);
191: EG(argument_stack) = p;
192: }
193:
194: static inline void **zend_vm_stack_top(TSRMLS_D)
195: {
196: return EG(argument_stack)->top;
197: }
198:
199: static inline void zend_vm_stack_push(void *ptr TSRMLS_DC)
200: {
201: ZEND_VM_STACK_GROW_IF_NEEDED(1);
202: *(EG(argument_stack)->top++) = ptr;
203: }
204:
205: static inline void zend_vm_stack_push_nocheck(void *ptr TSRMLS_DC)
206: {
207: *(EG(argument_stack)->top++) = ptr;
208: }
209:
210: static inline void *zend_vm_stack_pop(TSRMLS_D)
211: {
212: void *el = *(--EG(argument_stack)->top);
213:
214: if (UNEXPECTED(EG(argument_stack)->top == ZEND_VM_STACK_ELEMETS(EG(argument_stack)))) {
215: zend_vm_stack p = EG(argument_stack);
216: EG(argument_stack) = p->prev;
217: efree(p);
218: }
219: return el;
220: }
221:
222: static inline void *zend_vm_stack_alloc(size_t size TSRMLS_DC)
223: {
224: void *ret;
225:
226: size = (size + (sizeof(void*) - 1)) / sizeof(void*);
227:
228: /* the following comparison must be optimized out at compile time */
229: if (ZEND_MM_ALIGNMENT > sizeof(void*)) {
230: int extra = (ZEND_MM_ALIGNMENT - ((zend_uintptr_t)EG(argument_stack)->top & (ZEND_MM_ALIGNMENT - 1))) / sizeof(void*);
231:
232: if (UNEXPECTED(size + extra + ZEND_MM_ALIGNED_SIZE(sizeof(void*)) / sizeof(void*) >
233: (zend_uintptr_t)(EG(argument_stack)->end - EG(argument_stack)->top))) {
234: zend_vm_stack_extend(size TSRMLS_CC);
235: } else {
236: void **old_top = EG(argument_stack)->top;
237:
238: EG(argument_stack)->top += extra;
239: /* store old top on the stack */
240: *EG(argument_stack)->top = (void*)old_top;
241: EG(argument_stack)->top += ZEND_MM_ALIGNED_SIZE(sizeof(void*)) / sizeof(void*);
242: }
243: } else {
244: ZEND_VM_STACK_GROW_IF_NEEDED((int)size);
245: }
246: ret = (void*)EG(argument_stack)->top;
247: EG(argument_stack)->top += size;
248: return ret;
249: }
250:
251: static inline void zend_vm_stack_free_int(void *ptr TSRMLS_DC)
252: {
253: if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) {
254: zend_vm_stack p = EG(argument_stack);
255:
256: EG(argument_stack) = p->prev;
257: efree(p);
258: } else {
259: EG(argument_stack)->top = (void**)ptr;
260: }
261: }
262:
263: static inline void zend_vm_stack_free(void *ptr TSRMLS_DC)
264: {
265: if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) {
266: zend_vm_stack p = EG(argument_stack);
267:
268: EG(argument_stack) = p->prev;
269: efree(p);
270: } else {
271: /* the following comparison must be optimized out at compile time */
272: if (ZEND_MM_ALIGNMENT > sizeof(void*)) {
273: ptr = (void*)(((char*)ptr) - ZEND_MM_ALIGNED_SIZE(sizeof(void*)));
274: EG(argument_stack)->top = *(void***)ptr;
275: } else {
276: EG(argument_stack)->top = (void**)ptr;
277: }
278: }
279: }
280:
281: static inline void** zend_vm_stack_push_args(int count TSRMLS_DC)
282: {
283:
284: if (UNEXPECTED(EG(argument_stack)->top - ZEND_VM_STACK_ELEMETS(EG(argument_stack)) < count) ||
285: UNEXPECTED(EG(argument_stack)->top == EG(argument_stack)->end)) {
286: zend_vm_stack p = EG(argument_stack);
287:
288: zend_vm_stack_extend(count + 1 TSRMLS_CC);
289:
290: EG(argument_stack)->top += count;
291: *(EG(argument_stack)->top) = (void*)(zend_uintptr_t)count;
292: while (count-- > 0) {
293: void *data = *(--p->top);
294:
295: if (UNEXPECTED(p->top == ZEND_VM_STACK_ELEMETS(p))) {
296: zend_vm_stack r = p;
297:
298: EG(argument_stack)->prev = p->prev;
299: p = p->prev;
300: efree(r);
301: }
302: *(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) + count) = data;
303: }
304: return EG(argument_stack)->top++;
305: }
306: *(EG(argument_stack)->top) = (void*)(zend_uintptr_t)count;
307: return EG(argument_stack)->top++;
308: }
309:
310: static inline void zend_vm_stack_clear_multiple(TSRMLS_D)
311: {
312: void **p = EG(argument_stack)->top - 1;
313: int delete_count = (int)(zend_uintptr_t) *p;
314:
315: while (--delete_count>=0) {
316: zval *q = *(zval **)(--p);
317: *p = NULL;
318: zval_ptr_dtor(&q);
319: }
320: zend_vm_stack_free_int(p TSRMLS_CC);
321: }
322:
323: static inline zval** zend_vm_stack_get_arg(int requested_arg TSRMLS_DC)
324: {
325: void **p = EG(current_execute_data)->prev_execute_data->function_state.arguments;
326: int arg_count = (int)(zend_uintptr_t) *p;
327:
328: if (UNEXPECTED(requested_arg > arg_count)) {
329: return NULL;
330: }
331: return (zval**)p - arg_count + requested_arg - 1;
332: }
333:
334: static inline void zend_arg_types_stack_2_pop(zend_ptr_stack *stack, zval **object, zend_function **fbc)
335: {
336: void *a, *b;
337:
338: zend_ptr_stack_2_pop(stack, &a, &b);
339:
340: *object = (zval *) a;
341: *fbc = (zend_function *) b;
342: }
343:
344: static inline void zend_arg_types_stack_3_pop(zend_ptr_stack *stack, zend_class_entry **called_scope, zval **object, zend_function **fbc)
345: {
346: void *a, *b, *c;
347:
348: zend_ptr_stack_3_pop(stack, &a, &b, &c);
349:
350: *called_scope = (zend_class_entry *) a;
351: *object = (zval *) b;
352: *fbc = (zend_function *) c;
353: }
354:
355: void execute_new_code(TSRMLS_D);
356:
357:
358: /* services */
359: ZEND_API char *get_active_class_name(char **space TSRMLS_DC);
360: ZEND_API char *get_active_function_name(TSRMLS_D);
361: ZEND_API char *zend_get_executed_filename(TSRMLS_D);
362: ZEND_API uint zend_get_executed_lineno(TSRMLS_D);
363: ZEND_API zend_bool zend_is_executing(TSRMLS_D);
364:
365: ZEND_API void zend_set_timeout(long seconds, int reset_signals);
366: ZEND_API void zend_unset_timeout(TSRMLS_D);
367: ZEND_API void zend_timeout(int dummy);
368: ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len, int fetch_type TSRMLS_DC);
369: void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC);
370:
371: #ifdef ZEND_WIN32
372: void zend_init_timeout_thread(void);
373: void zend_shutdown_timeout_thread(void);
374: #define WM_REGISTER_ZEND_TIMEOUT (WM_USER+1)
375: #define WM_UNREGISTER_ZEND_TIMEOUT (WM_USER+2)
376: #endif
377:
378: #define zendi_zval_copy_ctor(p) zval_copy_ctor(&(p))
379: #define zendi_zval_dtor(p) zval_dtor(&(p))
380:
381: #define active_opline (*EG(opline_ptr))
382:
383: /* The following tries to resolve the classname of a zval of type object.
384: * Since it is slow it should be only used in error messages.
385: */
386: #define Z_OBJ_CLASS_NAME_P(zval) ((zval) && Z_TYPE_P(zval) == IS_OBJECT && Z_OBJ_HT_P(zval)->get_class_entry != NULL && Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC) ? Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC)->name : "")
387:
388: ZEND_API zval** zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, zend_uint var);
389:
390: #define ZEND_USER_OPCODE_CONTINUE 0 /* execute next opcode */
391: #define ZEND_USER_OPCODE_RETURN 1 /* exit from executor (return from function) */
392: #define ZEND_USER_OPCODE_DISPATCH 2 /* call original opcode handler */
393: #define ZEND_USER_OPCODE_ENTER 3 /* enter into new op_array without recursion */
394: #define ZEND_USER_OPCODE_LEAVE 4 /* return to calling op_array within the same executor */
395:
396: #define ZEND_USER_OPCODE_DISPATCH_TO 0x100 /* call original handler of returned opcode */
397:
398: ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler);
399: ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode);
400:
401: /* former zend_execute_locks.h */
402: typedef struct _zend_free_op {
403: zval* var;
404: /* int is_var; */
405: } zend_free_op;
406:
407: ZEND_API zval *zend_get_zval_ptr(znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC);
408: ZEND_API zval **zend_get_zval_ptr_ptr(const znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC);
409:
410: ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS);
411:
412: END_EXTERN_C()
413:
414: #endif /* ZEND_EXECUTE_H */
415:
416: /*
417: * Local variables:
418: * tab-width: 4
419: * c-basic-offset: 4
420: * indent-tabs-mode: t
421: * End:
422: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>