php-5.6.26源代码 - opcode处理器,“乘法opcode”处理器
// opcode处理器 - 运算符怎么执行: “*” 乘法opcode处理器 static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE SAVE_OPLINE(); fast_mul_function(&EX_T(opline->result.var).tmp_var, opline->op1.zv, opline->op2.zv TSRMLS_CC); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } // “*” 乘法opcode处理器 - 展开 static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { // USE_OPLINE zend_op *opline = EX(opline); // SAVE_OPLINE(); ---> 空代码 // fast_mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) fast_mul_function(&EX_T(opline->result.var).tmp_var, opline->op1.zv, opline->op2.zv TSRMLS_CC);{ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { // op1是long类型 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { // op2是long类型 long overflow; ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); Z_TYPE_P(result) = overflow ? IS_DOUBLE : IS_LONG; return SUCCESS; } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { // op2是double类型 Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2); // 转成double类型,做乘法 Z_TYPE_P(result) = IS_DOUBLE; return SUCCESS; } } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { // op1是double类型 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { // op2是double类型 Z_DVAL_P(result) = Z_DVAL_P(op1) * Z_DVAL_P(op2); // 直接做乘法 Z_TYPE_P(result) = IS_DOUBLE; return SUCCESS; } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { // op2是long类型 Z_DVAL_P(result) = Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)); // 转成double类型,做乘法 Z_TYPE_P(result) = IS_DOUBLE; return SUCCESS; } } return mul_function(result, op1, op2 TSRMLS_CC);{ zval op1_copy, op2_copy; int converted = 0; while (1) { // 死循环 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) { case TYPE_PAIR(IS_LONG, IS_LONG): { long overflow; ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1),Z_LVAL_P(op2), Z_LVAL_P(result),Z_DVAL_P(result),overflow); Z_TYPE_P(result) = overflow ? IS_DOUBLE : IS_LONG; return SUCCESS; } case TYPE_PAIR(IS_LONG, IS_DOUBLE): ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2)); return SUCCESS; case TYPE_PAIR(IS_DOUBLE, IS_LONG): ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2))); return SUCCESS; case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE): ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); return SUCCESS; default: if (!converted) { // 自动转换类型 ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL); zendi_convert_scalar_to_number(op1, op1_copy, result); // 转换类型 zendi_convert_scalar_to_number(op2, op2_copy, result); // 转换类型 converted = 1; } else { zend_error(E_ERROR, "Unsupported operand types"); return FAILURE; /* unknown datatype */ } } } } } // CHECK_EXCEPTION() ---> 空代码 // ZEND_VM_NEXT_OPCODE() ---> CHECK_SYMBOL_TABLES() zend_hash_apply(&EG(symbol_table), (apply_func_t) zend_check_symbol TSRMLS_CC); if (&EG(symbol_table)!=EG(active_symbol_table)) { zend_hash_apply(EG(active_symbol_table), (apply_func_t) zend_check_symbol TSRMLS_CC); } // ZEND_VM_NEXT_OPCODE() ---> ZEND_VM_INC_OPCODE() OPLINE++; // 下一个操作行 // ZEND_VM_NEXT_OPCODE() ---> ZEND_VM_CONTINUE() return 0; }