php运算符opcode 1

原创
2012/08/31 15:48
阅读数 274

php版本 PHP 5.3.14

1. ==(调用is_equal_function->compare_function ),!=(调用is_not_equal_function->compare_function)

<?php
$i = 1;
$j = 1.0;
echo $i == $j;

//opcode 

 

line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   3     0  >   ASSIGN                                                   !0, 1
   4     1      ASSIGN                                                   !1, 1
   6     2      IS_EQUAL                                         ~2      !0, !1
         3      ECHO                                                     ~2
   7     4    > RETURN                                                   1

 

 调用Zend/zend_operators.c  is_equal_function

 

if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
   return FAILURE;
}
ZVAL_BOOL(result, (Z_LVAL_P(result) == 0));
return SUCCESS;

//compare_function,比较两个zval,op1,op2,结果记录到result,

switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
            case TYPE_PAIR(IS_LONG, IS_LONG)://两个整形比较
                ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
                return SUCCESS;

            case TYPE_PAIR(IS_DOUBLE, IS_LONG)://一个double,一个整形,会将整形转化为double,相减,
                Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
                ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
                return SUCCESS;

            case TYPE_PAIR(IS_LONG, IS_DOUBLE)://同上,
                Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
                ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
                return SUCCESS;

            case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE)://同上
                Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
                ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
                return SUCCESS;

            case TYPE_PAIR(IS_ARRAY, IS_ARRAY)://数组比较,todo
                zend_compare_arrays(result, op1, op2 TSRMLS_CC);
                return SUCCESS;

            case TYPE_PAIR(IS_NULL, IS_NULL)://null
                ZVAL_LONG(result, 0);
                return SUCCESS;

            case TYPE_PAIR(IS_NULL, IS_BOOL)://null bool
                ZVAL_LONG(result, Z_LVAL_P(op2) ? -1 : 0);
                return SUCCESS;

            case TYPE_PAIR(IS_BOOL, IS_NULL)://同上
                ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0);
                return SUCCESS;

            case TYPE_PAIR(IS_BOOL, IS_BOOL)://bool,相减
                ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
                return SUCCESS;

            case TYPE_PAIR(IS_STRING, IS_STRING)://两个字符串 todo
                zendi_smart_strcmp(result, op1, op2);
                return SUCCESS;

            case TYPE_PAIR(IS_NULL, IS_STRING)://字符串 null
                ZVAL_LONG(result, zend_binary_strcmp("", 0, Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
                return SUCCESS;

            case TYPE_PAIR(IS_STRING, IS_NULL)://同上
                ZVAL_LONG(result, zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), "", 0));
                return SUCCESS;

            case TYPE_PAIR(IS_OBJECT, IS_NULL)://object  null,
                ZVAL_LONG(result, 1);
                return SUCCESS;

            case TYPE_PAIR(IS_NULL, IS_OBJECT)://同上
                ZVAL_LONG(result, -1);
                return SUCCESS;

            case TYPE_PAIR(IS_OBJECT, IS_OBJECT)://object todo
                /* If both are objects sharing the same comparision handler then use is */
                if (Z_OBJ_HANDLER_P(op1,compare_objects) == Z_OBJ_HANDLER_P(op2,compare_objects)) {
                    if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) {
                        /* object handles are identical, apprently this is the same object */
                        ZVAL_LONG(result, 0);
                        return SUCCESS;
                    }
                    ZVAL_LONG(result, Z_OBJ_HT_P(op1)->compare_objects(op1, op2 TSRMLS_CC));
                    return SUCCESS;
                }
                /* break missing intentionally */

            default:
                if (Z_TYPE_P(op1) == IS_OBJECT) {
                    if (Z_OBJ_HT_P(op1)->get) {
                        op_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
                        ret = compare_function(result, op_free, op2 TSRMLS_CC);
                        zend_free_obj_get_result(op_free TSRMLS_CC);
                        return ret;
                    } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
                        ALLOC_INIT_ZVAL(op_free);
                        if (Z_OBJ_HT_P(op1)->cast_object(op1, op_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) {
                            ZVAL_LONG(result, 1);
                            zend_free_obj_get_result(op_free TSRMLS_CC);
                            return SUCCESS;
                        }
                        ret = compare_function(result, op_free, op2 TSRMLS_CC);
                        zend_free_obj_get_result(op_free TSRMLS_CC);
                        return ret;
                    }
                }
                if (Z_TYPE_P(op2) == IS_OBJECT) {
                    if (Z_OBJ_HT_P(op2)->get) {
                        op_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC);
                        ret = compare_function(result, op1, op_free TSRMLS_CC);
                        zend_free_obj_get_result(op_free TSRMLS_CC);
                        return ret;
                    } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
                        ALLOC_INIT_ZVAL(op_free);
                        if (Z_OBJ_HT_P(op2)->cast_object(op2, op_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) {
                            ZVAL_LONG(result, -1);
                            zend_free_obj_get_result(op_free TSRMLS_CC);
                            return SUCCESS;
                        }
                        ret = compare_function(result, op1, op_free TSRMLS_CC);
                        zend_free_obj_get_result(op_free TSRMLS_CC);
                        return ret;
                    } else if (Z_TYPE_P(op1) == IS_OBJECT) {
                        ZVAL_LONG(result, 1);
                        return SUCCESS;
                    }
                }
                if (!converted) {
                    if (Z_TYPE_P(op1) == IS_NULL) {
                        zendi_convert_to_boolean(op2, op2_copy, result);
                        ZVAL_LONG(result, Z_LVAL_P(op2) ? -1 : 0);
                        return SUCCESS;
                    } else if (Z_TYPE_P(op2) == IS_NULL) {
                        zendi_convert_to_boolean(op1, op1_copy, result);
                        ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0);
                        return SUCCESS;
                    } else if (Z_TYPE_P(op1) == IS_BOOL) {
                        zendi_convert_to_boolean(op2, op2_copy, result);
                        ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
                        return SUCCESS;
                    } else if (Z_TYPE_P(op2) == IS_BOOL) {
                        zendi_convert_to_boolean(op1, op1_copy, result);
                        ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
                        return SUCCESS;
                    } else {
                        zendi_convert_scalar_to_number(op1, op1_copy, result);
                        zendi_convert_scalar_to_number(op2, op2_copy, result);
                        converted = 1;
                    }
                } else if (Z_TYPE_P(op1)==IS_ARRAY) {
                    ZVAL_LONG(result, 1);
                    return SUCCESS;
                } else if (Z_TYPE_P(op2)==IS_ARRAY) {
                    ZVAL_LONG(result, -1);
                    return SUCCESS;
                } else if (Z_TYPE_P(op1)==IS_OBJECT) {
                    ZVAL_LONG(result, 1);
                    return SUCCESS;
                } else if (Z_TYPE_P(op2)==IS_OBJECT) {
                    ZVAL_LONG(result, -1);
                    return SUCCESS;
                } else {
                    ZVAL_LONG(result, 0);
                    return FAILURE;
                }
        }

 

 

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部