Annotation of embedaddon/php/Zend/zend_opcode.c, revision 1.1.1.2
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:
1.1.1.2 ! misho 20: /* $Id$ */
1.1 misho 21:
22: #include <stdio.h>
23:
24: #include "zend.h"
25: #include "zend_alloc.h"
26: #include "zend_compile.h"
27: #include "zend_extensions.h"
28: #include "zend_API.h"
29:
30: #include "zend_vm.h"
31:
32: static void zend_extension_op_array_ctor_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
33: {
34: if (extension->op_array_ctor) {
35: extension->op_array_ctor(op_array);
36: }
37: }
38:
39: static void zend_extension_op_array_dtor_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
40: {
41: if (extension->op_array_dtor) {
42: extension->op_array_dtor(op_array);
43: }
44: }
45:
1.1.1.2 ! misho 46: static void op_array_alloc_ops(zend_op_array *op_array, zend_uint size)
1.1 misho 47: {
1.1.1.2 ! misho 48: op_array->opcodes = erealloc(op_array->opcodes, size * sizeof(zend_op));
1.1 misho 49: }
50:
51: void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size TSRMLS_DC)
52: {
53: op_array->type = type;
54:
55: if (CG(interactive)) {
56: /* We must avoid a realloc() on the op_array in interactive mode, since pointers to constants
57: * will become invalid
58: */
1.1.1.2 ! misho 59: initial_ops_size = INITIAL_INTERACTIVE_OP_ARRAY_SIZE;
1.1 misho 60: }
61:
62: op_array->refcount = (zend_uint *) emalloc(sizeof(zend_uint));
63: *op_array->refcount = 1;
64: op_array->last = 0;
65: op_array->opcodes = NULL;
1.1.1.2 ! misho 66: op_array_alloc_ops(op_array, initial_ops_size);
1.1 misho 67:
68: op_array->last_var = 0;
69: op_array->vars = NULL;
70:
71: op_array->T = 0;
72:
73: op_array->function_name = NULL;
74: op_array->filename = zend_get_compiled_filename(TSRMLS_C);
75: op_array->doc_comment = NULL;
76: op_array->doc_comment_len = 0;
77:
78: op_array->arg_info = NULL;
79: op_array->num_args = 0;
80: op_array->required_num_args = 0;
81:
82: op_array->scope = NULL;
83:
84: op_array->brk_cont_array = NULL;
85: op_array->try_catch_array = NULL;
86: op_array->last_brk_cont = 0;
87:
88: op_array->static_variables = NULL;
89: op_array->last_try_catch = 0;
90:
91: op_array->this_var = -1;
92:
93: op_array->fn_flags = CG(interactive)?ZEND_ACC_INTERACTIVE:0;
94:
95: op_array->early_binding = -1;
96:
1.1.1.2 ! misho 97: op_array->last_literal = 0;
! 98: op_array->literals = NULL;
! 99:
! 100: op_array->run_time_cache = NULL;
! 101: op_array->last_cache_slot = 0;
! 102:
1.1 misho 103: memset(op_array->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*));
104:
105: zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
106: }
107:
108: ZEND_API void destroy_zend_function(zend_function *function TSRMLS_DC)
109: {
110: switch (function->type) {
111: case ZEND_USER_FUNCTION:
112: destroy_op_array((zend_op_array *) function TSRMLS_CC);
113: break;
114: case ZEND_INTERNAL_FUNCTION:
115: /* do nothing */
116: break;
117: }
118: }
119:
120: ZEND_API void zend_function_dtor(zend_function *function)
121: {
122: TSRMLS_FETCH();
123:
124: destroy_zend_function(function TSRMLS_CC);
125: }
126:
127: static void zend_cleanup_op_array_data(zend_op_array *op_array)
128: {
129: if (op_array->static_variables) {
130: zend_hash_clean(op_array->static_variables);
131: }
132: }
133:
134: ZEND_API int zend_cleanup_function_data(zend_function *function TSRMLS_DC)
135: {
136: if (function->type == ZEND_USER_FUNCTION) {
137: zend_cleanup_op_array_data((zend_op_array *) function);
138: return ZEND_HASH_APPLY_KEEP;
139: } else {
140: return ZEND_HASH_APPLY_STOP;
141: }
142: }
143:
144: ZEND_API int zend_cleanup_function_data_full(zend_function *function TSRMLS_DC)
145: {
146: if (function->type == ZEND_USER_FUNCTION) {
147: zend_cleanup_op_array_data((zend_op_array *) function);
148: }
149: return 0;
150: }
151:
1.1.1.2 ! misho 152: static inline void cleanup_user_class_data(zend_class_entry *ce TSRMLS_DC)
1.1 misho 153: {
1.1.1.2 ! misho 154: /* Clean all parts that can contain run-time data */
! 155: /* Note that only run-time accessed data need to be cleaned up, pre-defined data can
! 156: not contain objects and thus are not probelmatic */
! 157: if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
! 158: zend_hash_apply(&ce->function_table, (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC);
! 159: }
! 160: if (ce->static_members_table) {
! 161: int i;
! 162:
! 163: for (i = 0; i < ce->default_static_members_count; i++) {
! 164: if (ce->static_members_table[i]) {
! 165: zval_ptr_dtor(&ce->static_members_table[i]);
! 166: ce->static_members_table[i] = NULL;
! 167: }
! 168: }
! 169: ce->static_members_table = NULL;
! 170: }
! 171: }
! 172:
! 173: static inline void cleanup_internal_class_data(zend_class_entry *ce TSRMLS_DC)
! 174: {
! 175: if (CE_STATIC_MEMBERS(ce)) {
! 176: int i;
! 177:
! 178: for (i = 0; i < ce->default_static_members_count; i++) {
! 179: zval_ptr_dtor(&CE_STATIC_MEMBERS(ce)[i]);
! 180: }
! 181: efree(CE_STATIC_MEMBERS(ce));
1.1 misho 182: #ifdef ZTS
1.1.1.2 ! misho 183: CG(static_members_table)[(zend_intptr_t)(ce->static_members_table)] = NULL;
1.1 misho 184: #else
1.1.1.2 ! misho 185: ce->static_members_table = NULL;
1.1 misho 186: #endif
187: }
1.1.1.2 ! misho 188: }
! 189:
! 190: ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce TSRMLS_DC)
! 191: {
! 192: cleanup_internal_class_data(ce TSRMLS_CC);
! 193: }
! 194:
! 195: ZEND_API int zend_cleanup_user_class_data(zend_class_entry **pce TSRMLS_DC)
! 196: {
! 197: if ((*pce)->type == ZEND_USER_CLASS) {
! 198: cleanup_user_class_data(*pce TSRMLS_CC);
! 199: return ZEND_HASH_APPLY_KEEP;
! 200: } else {
! 201: return ZEND_HASH_APPLY_STOP;
! 202: }
! 203: }
! 204:
! 205: ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC)
! 206: {
! 207: if ((*pce)->type == ZEND_USER_CLASS) {
! 208: cleanup_user_class_data(*pce TSRMLS_CC);
! 209: } else {
! 210: cleanup_internal_class_data(*pce TSRMLS_CC);
! 211: }
1.1 misho 212: return 0;
213: }
214:
1.1.1.2 ! misho 215: void _destroy_zend_class_traits_info(zend_class_entry *ce)
! 216: {
! 217: if (ce->num_traits > 0 && ce->traits) {
! 218: efree(ce->traits);
! 219: }
! 220:
! 221: if (ce->trait_aliases) {
! 222: size_t i = 0;
! 223: while (ce->trait_aliases[i]) {
! 224: if (ce->trait_aliases[i]->trait_method) {
! 225: if (ce->trait_aliases[i]->trait_method->method_name) {
! 226: efree((char*)ce->trait_aliases[i]->trait_method->method_name);
! 227: }
! 228: if (ce->trait_aliases[i]->trait_method->class_name) {
! 229: efree((char*)ce->trait_aliases[i]->trait_method->class_name);
! 230: }
! 231: efree(ce->trait_aliases[i]->trait_method);
! 232: }
! 233:
! 234: if (ce->trait_aliases[i]->alias) {
! 235: efree((char*)ce->trait_aliases[i]->alias);
! 236: }
! 237:
! 238: efree(ce->trait_aliases[i]);
! 239: i++;
! 240: }
! 241:
! 242: efree(ce->trait_aliases);
! 243: }
! 244:
! 245: if (ce->trait_precedences) {
! 246: size_t i = 0;
! 247:
! 248: while (ce->trait_precedences[i]) {
! 249: efree((char*)ce->trait_precedences[i]->trait_method->method_name);
! 250: efree((char*)ce->trait_precedences[i]->trait_method->class_name);
! 251: efree(ce->trait_precedences[i]->trait_method);
! 252:
! 253: if (ce->trait_precedences[i]->exclude_from_classes) {
! 254: efree(ce->trait_precedences[i]->exclude_from_classes);
! 255: }
! 256:
! 257: efree(ce->trait_precedences[i]);
! 258: i++;
! 259: }
! 260: efree(ce->trait_precedences);
! 261: }
! 262: }
! 263:
1.1 misho 264: ZEND_API void destroy_zend_class(zend_class_entry **pce)
265: {
266: zend_class_entry *ce = *pce;
267:
268: if (--ce->refcount > 0) {
269: return;
270: }
271: switch (ce->type) {
272: case ZEND_USER_CLASS:
1.1.1.2 ! misho 273: if (ce->default_properties_table) {
! 274: int i;
! 275:
! 276: for (i = 0; i < ce->default_properties_count; i++) {
! 277: if (ce->default_properties_table[i]) {
! 278: zval_ptr_dtor(&ce->default_properties_table[i]);
! 279: }
! 280: }
! 281: efree(ce->default_properties_table);
! 282: }
! 283: if (ce->default_static_members_table) {
! 284: int i;
! 285:
! 286: for (i = 0; i < ce->default_static_members_count; i++) {
! 287: if (ce->default_static_members_table[i]) {
! 288: zval_ptr_dtor(&ce->default_static_members_table[i]);
! 289: }
! 290: }
! 291: efree(ce->default_static_members_table);
! 292: }
1.1 misho 293: zend_hash_destroy(&ce->properties_info);
1.1.1.2 ! misho 294: str_efree(ce->name);
1.1 misho 295: zend_hash_destroy(&ce->function_table);
296: zend_hash_destroy(&ce->constants_table);
297: if (ce->num_interfaces > 0 && ce->interfaces) {
298: efree(ce->interfaces);
299: }
1.1.1.2 ! misho 300: if (ce->info.user.doc_comment) {
! 301: efree((char*)ce->info.user.doc_comment);
1.1 misho 302: }
1.1.1.2 ! misho 303:
! 304: _destroy_zend_class_traits_info(ce);
! 305:
1.1 misho 306: efree(ce);
307: break;
308: case ZEND_INTERNAL_CLASS:
1.1.1.2 ! misho 309: if (ce->default_properties_table) {
! 310: int i;
! 311:
! 312: for (i = 0; i < ce->default_properties_count; i++) {
! 313: if (ce->default_properties_table[i]) {
! 314: zval_internal_ptr_dtor(&ce->default_properties_table[i]);
! 315: }
! 316: }
! 317: free(ce->default_properties_table);
! 318: }
! 319: if (ce->default_static_members_table) {
! 320: int i;
! 321:
! 322: for (i = 0; i < ce->default_static_members_count; i++) {
! 323: zval_internal_ptr_dtor(&ce->default_static_members_table[i]);
! 324: }
! 325: free(ce->default_static_members_table);
! 326: }
1.1 misho 327: zend_hash_destroy(&ce->properties_info);
1.1.1.2 ! misho 328: str_free(ce->name);
1.1 misho 329: zend_hash_destroy(&ce->function_table);
330: zend_hash_destroy(&ce->constants_table);
331: if (ce->num_interfaces > 0) {
332: free(ce->interfaces);
333: }
334: free(ce);
335: break;
336: }
337: }
338:
339: void zend_class_add_ref(zend_class_entry **ce)
340: {
341: (*ce)->refcount++;
342: }
343:
344: ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC)
345: {
1.1.1.2 ! misho 346: zend_literal *literal = op_array->literals;
! 347: zend_literal *end;
1.1 misho 348: zend_uint i;
349:
350: if (op_array->static_variables) {
351: zend_hash_destroy(op_array->static_variables);
352: FREE_HASHTABLE(op_array->static_variables);
353: }
354:
1.1.1.2 ! misho 355: if (op_array->run_time_cache) {
! 356: efree(op_array->run_time_cache);
! 357: }
! 358:
1.1 misho 359: if (--(*op_array->refcount)>0) {
360: return;
361: }
362:
363: efree(op_array->refcount);
364:
365: if (op_array->vars) {
366: i = op_array->last_var;
367: while (i > 0) {
368: i--;
1.1.1.2 ! misho 369: str_efree(op_array->vars[i].name);
1.1 misho 370: }
371: efree(op_array->vars);
372: }
373:
1.1.1.2 ! misho 374: if (literal) {
! 375: end = literal + op_array->last_literal;
! 376: while (literal < end) {
! 377: zval_dtor(&literal->constant);
! 378: literal++;
1.1 misho 379: }
1.1.1.2 ! misho 380: efree(op_array->literals);
1.1 misho 381: }
382: efree(op_array->opcodes);
383:
384: if (op_array->function_name) {
1.1.1.2 ! misho 385: efree((char*)op_array->function_name);
1.1 misho 386: }
387: if (op_array->doc_comment) {
1.1.1.2 ! misho 388: efree((char*)op_array->doc_comment);
1.1 misho 389: }
390: if (op_array->brk_cont_array) {
391: efree(op_array->brk_cont_array);
392: }
393: if (op_array->try_catch_array) {
394: efree(op_array->try_catch_array);
395: }
1.1.1.2 ! misho 396: if (op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO) {
1.1 misho 397: zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_dtor_handler, op_array TSRMLS_CC);
398: }
399: if (op_array->arg_info) {
400: for (i=0; i<op_array->num_args; i++) {
1.1.1.2 ! misho 401: str_efree(op_array->arg_info[i].name);
1.1 misho 402: if (op_array->arg_info[i].class_name) {
1.1.1.2 ! misho 403: str_efree(op_array->arg_info[i].class_name);
1.1 misho 404: }
405: }
406: efree(op_array->arg_info);
407: }
408: }
409:
410: void init_op(zend_op *op TSRMLS_DC)
411: {
412: memset(op, 0, sizeof(zend_op));
413: op->lineno = CG(zend_lineno);
414: SET_UNUSED(op->result);
415: }
416:
417: zend_op *get_next_op(zend_op_array *op_array TSRMLS_DC)
418: {
419: zend_uint next_op_num = op_array->last++;
420: zend_op *next_op;
421:
1.1.1.2 ! misho 422: if (next_op_num >= CG(context).opcodes_size) {
1.1 misho 423: if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) {
424: /* we messed up */
425: zend_printf("Ran out of opcode space!\n"
426: "You should probably consider writing this huge script into a file!\n");
427: zend_bailout();
428: }
1.1.1.2 ! misho 429: CG(context).opcodes_size *= 4;
! 430: op_array_alloc_ops(op_array, CG(context).opcodes_size);
1.1 misho 431: }
432:
433: next_op = &(op_array->opcodes[next_op_num]);
434:
435: init_op(next_op TSRMLS_CC);
436:
437: return next_op;
438: }
439:
440: int get_next_op_number(zend_op_array *op_array)
441: {
442: return op_array->last;
443: }
444:
445: zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array)
446: {
447: op_array->last_brk_cont++;
448: op_array->brk_cont_array = erealloc(op_array->brk_cont_array, sizeof(zend_brk_cont_element)*op_array->last_brk_cont);
449: return &op_array->brk_cont_array[op_array->last_brk_cont-1];
450: }
451:
452: static void zend_update_extended_info(zend_op_array *op_array TSRMLS_DC)
453: {
454: zend_op *opline = op_array->opcodes, *end=opline+op_array->last;
455:
456: while (opline<end) {
457: if (opline->opcode == ZEND_EXT_STMT) {
458: if (opline+1<end) {
459: if ((opline+1)->opcode == ZEND_EXT_STMT) {
460: opline->opcode = ZEND_NOP;
461: opline++;
462: continue;
463: }
464: if (opline+1<end) {
465: opline->lineno = (opline+1)->lineno;
466: }
467: } else {
468: opline->opcode = ZEND_NOP;
469: }
470: }
471: opline++;
472: }
473: }
474:
475: static void zend_extension_op_array_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
476: {
477: if (extension->op_array_handler) {
478: extension->op_array_handler(op_array);
479: }
480: }
481:
482: ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
483: {
484: zend_op *opline, *end;
485:
486: if (op_array->type!=ZEND_USER_FUNCTION && op_array->type!=ZEND_EVAL_CODE) {
487: return 0;
488: }
489: if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
490: zend_update_extended_info(op_array TSRMLS_CC);
491: }
492: if (CG(compiler_options) & ZEND_COMPILE_HANDLE_OP_ARRAY) {
493: zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_handler, op_array TSRMLS_CC);
494: }
495:
1.1.1.2 ! misho 496: if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && CG(context).vars_size != op_array->last_var) {
! 497: op_array->vars = (zend_compiled_variable *) erealloc(op_array->vars, sizeof(zend_compiled_variable)*op_array->last_var);
! 498: CG(context).vars_size = op_array->last_var;
! 499: }
! 500: if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && CG(context).opcodes_size != op_array->last) {
1.1 misho 501: op_array->opcodes = (zend_op *) erealloc(op_array->opcodes, sizeof(zend_op)*op_array->last);
1.1.1.2 ! misho 502: CG(context).opcodes_size = op_array->last;
! 503: }
! 504: if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && CG(context).literals_size != op_array->last_literal) {
! 505: op_array->literals = (zend_literal*)erealloc(op_array->literals, sizeof(zend_literal) * op_array->last_literal);
! 506: CG(context).literals_size = op_array->last_literal;
1.1 misho 507: }
508:
509: opline = op_array->opcodes;
510: end = opline + op_array->last;
511: while (opline < end) {
1.1.1.2 ! misho 512: if (opline->op1_type == IS_CONST) {
! 513: opline->op1.zv = &op_array->literals[opline->op1.constant].constant;
! 514: }
! 515: if (opline->op2_type == IS_CONST) {
! 516: opline->op2.zv = &op_array->literals[opline->op2.constant].constant;
1.1 misho 517: }
518: switch (opline->opcode) {
519: case ZEND_GOTO:
1.1.1.2 ! misho 520: if (Z_TYPE_P(opline->op2.zv) != IS_LONG) {
1.1 misho 521: zend_resolve_goto_label(op_array, opline, 1 TSRMLS_CC);
522: }
523: /* break omitted intentionally */
524: case ZEND_JMP:
1.1.1.2 ! misho 525: opline->op1.jmp_addr = &op_array->opcodes[opline->op1.opline_num];
1.1 misho 526: break;
527: case ZEND_JMPZ:
528: case ZEND_JMPNZ:
529: case ZEND_JMPZ_EX:
530: case ZEND_JMPNZ_EX:
531: case ZEND_JMP_SET:
1.1.1.2 ! misho 532: case ZEND_JMP_SET_VAR:
! 533: opline->op2.jmp_addr = &op_array->opcodes[opline->op2.opline_num];
1.1 misho 534: break;
535: }
536: ZEND_VM_SET_OPCODE_HANDLER(opline);
537: opline++;
538: }
1.1.1.2 ! misho 539:
! 540: op_array->fn_flags |= ZEND_ACC_DONE_PASS_TWO;
1.1 misho 541: return 0;
542: }
543:
544: int print_class(zend_class_entry *class_entry TSRMLS_DC)
545: {
546: printf("Class %s:\n", class_entry->name);
547: zend_hash_apply(&class_entry->function_table, (apply_func_t) pass_two TSRMLS_CC);
548: printf("End of class %s.\n\n", class_entry->name);
549: return 0;
550: }
551:
552: ZEND_API unary_op_type get_unary_op(int opcode)
553: {
554: switch (opcode) {
555: case ZEND_BW_NOT:
556: return (unary_op_type) bitwise_not_function;
557: break;
558: case ZEND_BOOL_NOT:
559: return (unary_op_type) boolean_not_function;
560: break;
561: default:
562: return (unary_op_type) NULL;
563: break;
564: }
565: }
566:
567: ZEND_API binary_op_type get_binary_op(int opcode)
568: {
569: switch (opcode) {
570: case ZEND_ADD:
571: case ZEND_ASSIGN_ADD:
572: return (binary_op_type) add_function;
573: break;
574: case ZEND_SUB:
575: case ZEND_ASSIGN_SUB:
576: return (binary_op_type) sub_function;
577: break;
578: case ZEND_MUL:
579: case ZEND_ASSIGN_MUL:
580: return (binary_op_type) mul_function;
581: break;
582: case ZEND_DIV:
583: case ZEND_ASSIGN_DIV:
584: return (binary_op_type) div_function;
585: break;
586: case ZEND_MOD:
587: case ZEND_ASSIGN_MOD:
588: return (binary_op_type) mod_function;
589: break;
590: case ZEND_SL:
591: case ZEND_ASSIGN_SL:
592: return (binary_op_type) shift_left_function;
593: break;
594: case ZEND_SR:
595: case ZEND_ASSIGN_SR:
596: return (binary_op_type) shift_right_function;
597: break;
598: case ZEND_CONCAT:
599: case ZEND_ASSIGN_CONCAT:
600: return (binary_op_type) concat_function;
601: break;
602: case ZEND_IS_IDENTICAL:
603: return (binary_op_type) is_identical_function;
604: break;
605: case ZEND_IS_NOT_IDENTICAL:
606: return (binary_op_type) is_not_identical_function;
607: break;
608: case ZEND_IS_EQUAL:
609: return (binary_op_type) is_equal_function;
610: break;
611: case ZEND_IS_NOT_EQUAL:
612: return (binary_op_type) is_not_equal_function;
613: break;
614: case ZEND_IS_SMALLER:
615: return (binary_op_type) is_smaller_function;
616: break;
617: case ZEND_IS_SMALLER_OR_EQUAL:
618: return (binary_op_type) is_smaller_or_equal_function;
619: break;
620: case ZEND_BW_OR:
621: case ZEND_ASSIGN_BW_OR:
622: return (binary_op_type) bitwise_or_function;
623: break;
624: case ZEND_BW_AND:
625: case ZEND_ASSIGN_BW_AND:
626: return (binary_op_type) bitwise_and_function;
627: break;
628: case ZEND_BW_XOR:
629: case ZEND_ASSIGN_BW_XOR:
630: return (binary_op_type) bitwise_xor_function;
631: break;
632: case ZEND_BOOL_XOR:
633: return (binary_op_type) boolean_xor_function;
634: break;
635: default:
636: return (binary_op_type) NULL;
637: break;
638: }
639: }
640:
641: /*
642: * Local variables:
643: * tab-width: 4
644: * c-basic-offset: 4
645: * indent-tabs-mode: t
646: * End:
647: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>