}
}
-ZEND_VM_HANDLER(42, ZEND_JMP, JMP_ADDR, ANY)
+ZEND_VM_HOT_HANDLER(42, ZEND_JMP, JMP_ADDR, ANY)
{
USE_OPLINE
ZEND_VM_CONTINUE();
}
-ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR)
+ZEND_VM_HOT_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR)
{
USE_OPLINE
zend_free_op free_op1;
ZEND_VM_JMP(opline);
}
-ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR)
+ZEND_VM_HOT_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR)
{
USE_OPLINE
zend_free_op free_op1;
ZEND_VM_JMP(opline);
}
-ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, JMP_ADDR, JMP_ADDR)
+ZEND_VM_HOT_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, JMP_ADDR, JMP_ADDR)
{
USE_OPLINE
zend_free_op free_op1;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM)
+ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM)
{
USE_OPLINE
zend_function *fbc;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM)
+ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM)
{
USE_OPLINE
zend_free_op free_op2;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
+ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
{
USE_OPLINE
zend_execute_data *call = EX(call);
ZEND_VM_CONTINUE();
}
-ZEND_VM_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL))
+ZEND_VM_HOT_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL))
{
USE_OPLINE
zend_execute_data *call = EX(call);
ZEND_VM_ENTER();
}
-ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
+ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
{
USE_OPLINE
zend_execute_data *call = EX(call);
ZEND_VM_CONTINUE();
}
-ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
+ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
{
USE_OPLINE
zend_execute_data *call = EX(call);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
-ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
+ZEND_VM_HOT_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
{
USE_OPLINE
zval *retval_ptr;
}
}
-ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMPVAR, NUM)
+ZEND_VM_HOT_HANDLER(65, ZEND_SEND_VAL, CONST|TMPVAR, NUM)
{
USE_OPLINE
zval *value, *arg;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, NUM, SPEC(QUICK_ARG))
+ZEND_VM_HOT_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, NUM, SPEC(QUICK_ARG))
{
USE_OPLINE
zval *value, *arg;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, NUM)
+ZEND_VM_HOT_HANDLER(117, ZEND_SEND_VAR, VAR|CV, NUM)
{
USE_OPLINE
zval *varptr, *arg;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, NUM, SPEC(QUICK_ARG))
+ZEND_VM_HOT_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, NUM, SPEC(QUICK_ARG))
{
USE_OPLINE
zval *varptr, *arg;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(64, ZEND_RECV_INIT, NUM, CONST)
+ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST)
{
USE_OPLINE
uint32_t arg_num;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY)
+ZEND_VM_HOT_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY)
{
USE_OPLINE
zend_free_op free_op1;
ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper, try_catch_offset, current_try_catch_offset, op_num, current_op_num);
}
-ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
+ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
}
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_ADD, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_ADD, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2, *result;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_ADD, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_ADD, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2, *result;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_ADD, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_ADD_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_ADD, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_ADD_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2, *result;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SUB, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_SUB_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SUB, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_SUB_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
{
USE_OPLINE
zval *op1, *op2, *result;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SUB, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_SUB_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SUB, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_SUB_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
{
USE_OPLINE
zval *op1, *op2, *result;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SUB, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_SUB_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SUB, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_SUB_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
{
USE_OPLINE
zval *op1, *op2, *result;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_MUL, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_MUL_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_MUL, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_MUL_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2, *result;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_MUL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_MUL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_MUL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_MUL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2, *result;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_MUL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_MUL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_MUL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_MUL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2, *result;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_NOT_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_NOT_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_NOT_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_NOT_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_SMALLER_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_SMALLER_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
{
USE_OPLINE
zval *op1, *op2;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_SMALLER_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_SMALLER_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
{
USE_OPLINE
zval *op1, *op2;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER_OR_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_SMALLER_OR_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER_OR_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_SMALLER_OR_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
{
USE_OPLINE
zval *op1, *op2;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER_OR_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_SMALLER_OR_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER_OR_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_SMALLER_OR_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
{
USE_OPLINE
zval *op1, *op2;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_PRE_INC_LONG_NO_OVERFLOW, TMPVARCV, ANY, SPEC(RETVAL))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_PRE_INC_LONG_NO_OVERFLOW, TMPVARCV, ANY, SPEC(RETVAL))
{
USE_OPLINE
zval *var_ptr;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (op1_info == MAY_BE_LONG), ZEND_PRE_INC_LONG, TMPVARCV, ANY, SPEC(RETVAL))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (op1_info == MAY_BE_LONG), ZEND_PRE_INC_LONG, TMPVARCV, ANY, SPEC(RETVAL))
{
USE_OPLINE
zval *var_ptr;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_PRE_INC_LONG_OR_DOUBLE, TMPVARCV, ANY, SPEC(RETVAL))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_PRE_INC_LONG_OR_DOUBLE, TMPVARCV, ANY, SPEC(RETVAL))
{
USE_OPLINE
zval *var_ptr;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_PRE_DEC_LONG_NO_OVERFLOW, TMPVARCV, ANY, SPEC(RETVAL))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_PRE_DEC_LONG_NO_OVERFLOW, TMPVARCV, ANY, SPEC(RETVAL))
{
USE_OPLINE
zval *var_ptr;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (op1_info == MAY_BE_LONG), ZEND_PRE_DEC_LONG, TMPVARCV, ANY, SPEC(RETVAL))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (op1_info == MAY_BE_LONG), ZEND_PRE_DEC_LONG, TMPVARCV, ANY, SPEC(RETVAL))
{
USE_OPLINE
zval *var_ptr;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_PRE_DEC_LONG_OR_DOUBLE, TMPVARCV, ANY, SPEC(RETVAL))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_PRE_DEC_LONG_OR_DOUBLE, TMPVARCV, ANY, SPEC(RETVAL))
{
USE_OPLINE
zval *var_ptr;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_INC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_POST_INC_LONG_NO_OVERFLOW, TMPVARCV, ANY)
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_POST_INC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_POST_INC_LONG_NO_OVERFLOW, TMPVARCV, ANY)
{
USE_OPLINE
zval *var_ptr;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_INC, (op1_info == MAY_BE_LONG), ZEND_POST_INC_LONG, TMPVARCV, ANY)
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_POST_INC, (op1_info == MAY_BE_LONG), ZEND_POST_INC_LONG, TMPVARCV, ANY)
{
USE_OPLINE
zval *var_ptr;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_INC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_POST_INC_LONG_OR_DOUBLE, TMPVARCV, ANY)
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_POST_INC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_POST_INC_LONG_OR_DOUBLE, TMPVARCV, ANY)
{
USE_OPLINE
zval *var_ptr;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_POST_DEC_LONG_NO_OVERFLOW, TMPVARCV, ANY)
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_POST_DEC_LONG_NO_OVERFLOW, TMPVARCV, ANY)
{
USE_OPLINE
zval *var_ptr;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (op1_info == MAY_BE_LONG), ZEND_POST_DEC_LONG, TMPVARCV, ANY)
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (op1_info == MAY_BE_LONG), ZEND_POST_DEC_LONG, TMPVARCV, ANY)
{
USE_OPLINE
zval *var_ptr;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_POST_DEC_LONG_OR_DOUBLE, TMPVARCV, ANY)
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_POST_DEC_LONG_OR_DOUBLE, TMPVARCV, ANY)
{
USE_OPLINE
zval *var_ptr;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (op1_info == MAY_BE_DOUBLE), ZEND_QM_ASSIGN_DOUBLE, CONST|TMPVARCV, ANY)
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (op1_info == MAY_BE_DOUBLE), ZEND_QM_ASSIGN_DOUBLE, CONST|TMPVARCV, ANY)
{
USE_OPLINE
zend_free_op free_op1;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE)))), ZEND_QM_ASSIGN_NOREF, CONST|TMPVARCV, ANY)
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE)))), ZEND_QM_ASSIGN_NOREF, CONST|TMPVARCV, ANY)
{
USE_OPLINE
zend_free_op free_op1;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_FETCH_DIM_R, (!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))), ZEND_FETCH_DIM_R_INDEX, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_FETCH_DIM_R, (!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))), ZEND_FETCH_DIM_R_INDEX, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SEND_VAR, (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0, ZEND_SEND_VAR_SIMPLE, CV|VAR, NUM)
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SEND_VAR, (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0, ZEND_SEND_VAR_SIMPLE, CV|VAR, NUM)
{
USE_OPLINE
zval *varptr, *arg;
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SEND_VAR_EX, (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0, ZEND_SEND_VAR_EX_SIMPLE, CV|VAR, NUM, SPEC(QUICK_ARG))
+ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SEND_VAR_EX, (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0, ZEND_SEND_VAR_EX_SIMPLE, CV|VAR, NUM, SPEC(QUICK_ARG))
{
USE_OPLINE
zval *varptr, *arg;
const ZEND_VM_KIND_CALL = 1;
const ZEND_VM_KIND_SWITCH = 2;
const ZEND_VM_KIND_GOTO = 3;
+const ZEND_VM_KIND_HYBRID = 4;
$vm_op_flags = array(
"ZEND_VM_OP_SPEC" => 1<<0,
ZEND_VM_KIND_CALL => "ZEND_VM_KIND_CALL",
ZEND_VM_KIND_SWITCH => "ZEND_VM_KIND_SWITCH",
ZEND_VM_KIND_GOTO => "ZEND_VM_KIND_GOTO",
+ ZEND_VM_KIND_HYBRID => "ZEND_VM_KIND_HYBRID",
);
$op_types = array(
if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
return "execute_data";
} else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
- return "goto " . opcode_name($matches[1], $spec, $op1, $op2) . "_HANDLER";
+ return "goto " . opcode_name($matches[1], $spec, $op1, $op2) . "_LABEL";
} else {
// ZEND_VM_DISPATCH_TO_HELPER
if (isset($matches[2])) {
}
// Generates opcode handler
-function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno, $extra_spec = null, &$switch_labels = array()) {
+function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno, $opcode, $extra_spec = null, &$switch_labels = array()) {
global $definition_file, $prefix, $typecode, $opnames;
if ($spec && skip_extra_spec_function($op1, $op2, $extra_spec)) {
// Generate opcode handler's entry point according to selected threading model
$spec_name = $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].($spec?extra_spec_name($extra_spec):"");
switch($kind) {
+ case ZEND_VM_KIND_HYBRID:
+ out($f,"\t\t\tHYBRID_CASE({$spec_name}):\n");
+ out($f,"\t\t\t\t{$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+ out($f,"\t\t\t\tHYBRID_BREAK();\n");
+ return;
case ZEND_VM_KIND_CALL:
- out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+ if ($opcode["hot"] && ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
+ out($f,"static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+ } else {
+ out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+ }
break;
case ZEND_VM_KIND_SWITCH:
if ($spec) {
}
break;
case ZEND_VM_KIND_GOTO:
- out($f,"{$spec_name}_HANDLER: ZEND_VM_GUARD($spec_name);\n");
+ out($f,"{$spec_name}_LABEL: ZEND_VM_GUARD($spec_name);\n");
break;
}
function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno, $inline, $extra_spec = null) {
global $definition_file, $prefix;
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ return;
+ }
+
if ($spec && skip_extra_spec_function($op1, $op2, $extra_spec)) {
return;
}
out($f,$prolog."(void*)(uintptr_t)-1,\n");
break;
case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&ZEND_NULL_HANDLER,\n");
+ out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
break;
}
}
$label++;
break;
case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&{$spec_name}_HANDLER,\n");
+ out($f,$prolog."(void*)&&{$spec_name}_LABEL,\n");
$label++;
break;
}
out($f,$prolog."(void*)(uintptr_t)-1,\n");
break;
case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&ZEND_NULL_HANDLER,\n");
+ out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
break;
}
$next++;
out($f,$prolog."(void*)(uintptr_t)".((string)$num).",\n");
break;
case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&".$dsc["op"]."_HANDLER,\n");
+ out($f,$prolog."(void*)&&".$dsc["op"]."_LABEL,\n");
break;
}
} else {
out($f,$prolog."(void*)(uintptr_t)-1,\n");
break;
case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&ZEND_NULL_HANDLER,\n");
+ out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
break;
}
}
out($f,$prolog."(void*)(uintptr_t)-1\n");
break;
case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&ZEND_NULL_HANDLER\n");
+ out($f,$prolog."(void*)&&ZEND_NULL_LABEL\n");
break;
}
$specs[$num + 1] = "$label";
}
// Generates specialized offsets
-function gen_specs($f, $spec, $kind, $prolog, $specs) {
+function gen_specs($f, $prolog, $specs) {
$lastdef = array_pop($specs);
$last = 0;
foreach ($specs as $num => $def) {
if (isset($opcodes[$num]["op1"][$op1]) &&
isset($opcodes[$num]["op2"][$op2])) {
// Generate handler code
- gen_handler($f, 1, $kind, $opcodes[$num]["op"], $op1, $op2, isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno, $extra_spec, $switch_labels);
+ gen_handler($f, 1, $kind, $opcodes[$num]["op"], $op1, $op2, isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno, $opcodes[$num], $extra_spec, $switch_labels);
}
}
} else if (isset($dsc["helper"])) {
$num = $dsc["handler"];
// Generate handler code
if ($num < 256) {
- gen_handler($f, 0, $kind, $opcodes[$num]["op"], "ANY", "ANY", isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno);
+ gen_handler($f, 0, $kind, $opcodes[$num]["op"], "ANY", "ANY", isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno, $opcodes[$num]);
}
} else if (isset($dsc["helper"])) {
$num = $dsc["helper"];
out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
break;
case ZEND_VM_KIND_GOTO:
- out($f,"ZEND_NULL_HANDLER:\n");
+ out($f,"ZEND_NULL_LABEL:\n");
out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
break;
+ case ZEND_VM_KIND_HYBRID:
+ out($f,"\t\t\tHYBRID_CASE(HYBRID_RETURN):\n");
+ out($f,"\t\t\t\texecute_data = orig_execute_data;\n");
+ out($f,"\t\t\t\topline = orig_opline;\n");
+ out($f,"\t\t\t\treturn;\n");
+ out($f,"\t\t\tHYBRID_DEFAULT:\n");
+ out($f,"\t\t\t\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
+ out($f,"\t\t\t\tHYBRID_BREAK(); /* Never reached */\n");
+ break;
}
}
out($f,"static const uint32_t *zend_spec_handlers;\n");
out($f,"static const void **zend_opcode_handlers;\n");
out($f,"static int zend_handlers_count;\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f,"static const void **zend_opcode_real_handlers;\n");
+ out($f,"static zend_op hybrid_return_op;\n");
+ out($f,"#endif\n");
+ }
out($f,"static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op);\n\n");
switch ($kind) {
+ case ZEND_VM_KIND_HYBRID:
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f,"#define HYBRID_NEXT() goto *(void**)(OPLINE->handler)\n");
+ out($f,"#define HYBRID_SWITCH() HYBRID_NEXT();\n");
+ out($f,"#define HYBRID_CASE(op) op ## _LABEL\n");
+ out($f,"#define HYBRID_BREAK() HYBRID_NEXT()\n");
+ out($f,"#define HYBRID_DEFAULT ZEND_NULL_LABEL\n");
+ out($f,"#endif\n");
case ZEND_VM_KIND_CALL:
out($f,"\n");
out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n");
out($f,"# else\n");
out($f,"# define ZEND_VM_CONTINUE() return\n");
out($f,"# endif\n");
- out($f,"# define ZEND_VM_RETURN() opline = NULL; return\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"# if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f,"# define ZEND_VM_RETURN() opline = &hybrid_return_op; return\n");
+ out($f,"# define ZEND_VM_HOT zend_always_inline\n");
+ out($f,"# else\n");
+ out($f,"# define ZEND_VM_RETURN() opline = NULL; return\n");
+ out($f,"# define ZEND_VM_HOT\n");
+ out($f,"# endif\n");
+ } else {
+ out($f,"# define ZEND_VM_RETURN() opline = NULL; return\n");
+ }
out($f,"#else\n");
out($f,"# define ZEND_OPCODE_HANDLER_RET int\n");
out($f,"# define ZEND_VM_TAIL_CALL(call) return call\n");
out($f,"#undef HANDLE_EXCEPTION\n");
out($f,"#undef HANDLE_EXCEPTION_LEAVE\n");
if (ZEND_VM_SPEC) {
- out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n");
- out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n");
+ out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_SPEC_LABEL\n");
+ out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_SPEC_LABEL\n");
} else {
- out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_HANDLER\n");
- out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_HANDLER\n");
+ out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_LABEL\n");
+ out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_LABEL\n");
}
out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n");
out($f,"#define ZEND_VM_RETURN() return\n");
out($f,"\n");
break;
}
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ gen_executor_code($f, $spec, ZEND_VM_KIND_CALL, $m[1]);
+ }
break;
case "EXECUTOR_NAME":
out($f, $m[1].$executor_name.$m[3]."\n");
break;
case "HELPER_VARS":
- if ($kind != ZEND_VM_KIND_CALL) {
+ if ($kind != ZEND_VM_KIND_CALL && $kind != ZEND_VM_KIND_HYBRID) {
if ($kind == ZEND_VM_KIND_SWITCH) {
out($f,$m[1]."const void *dispatch_handler;\n");
}
}
break;
case "INTERNAL_LABELS":
- if ($kind == ZEND_VM_KIND_GOTO) {
+ if ($kind == ZEND_VM_KIND_GOTO || $kind == ZEND_VM_KIND_HYBRID) {
// Emit array of labels of opcode handlers and code for
// zend_opcode_handlers initialization
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ }
$prolog = $m[1];
out($f,$prolog."if (UNEXPECTED(execute_data == NULL)) {\n");
out($f,$prolog."\tstatic const void* labels[] = {\n");
- gen_labels($f, $spec, $kind, $prolog."\t\t", $specs);
+ gen_labels($f, $spec, ZEND_VM_KIND_GOTO, $prolog."\t\t", $specs);
out($f,$prolog."\t};\n");
- out($f,$prolog."static const uint32_t specs[] = {\n");
- gen_specs($f, $spec, $kind, $prolog."\t", $specs);
- out($f,$prolog."};\n");
out($f,$prolog."\tzend_opcode_handlers = (const void **) labels;\n");
out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n");
- out($f,$prolog."\tzend_spec_handlers = (const uint32_t *) specs;\n");
- out($f,$prolog."\treturn;\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,$prolog."\tmemset(&hybrid_return_op, 0, sizeof(hybrid_return_op));\n");
+ out($f,$prolog."\thybrid_return_op.handler = (void*)&&HYBRID_RETURN_LABEL;\n");
+ out($f,$prolog."\tgoto HYBRID_RETURN_LABEL;\n");
+ } else {
+ out($f,$prolog."\treturn;\n");
+ }
out($f,$prolog."}\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#endif\n");
+ }
} else {
skip_blanks($f, $m[1], $m[3]);
}
break;
case "ZEND_VM_CONTINUE_LABEL":
- if ($kind == ZEND_VM_KIND_CALL) {
+ if ($kind == ZEND_VM_KIND_CALL || $kind == ZEND_VM_KIND_HYBRID) {
// Only SWITCH dispatch method use it
out($f,"#if !defined(ZEND_VM_FP_GLOBAL_REG) || !defined(ZEND_VM_IP_GLOBAL_REG)\n");
out($f,$m[1]."\tint ret;".$m[3]."\n");
case "ZEND_VM_DISPATCH":
// Emit code that dispatches to opcode handler
switch ($kind) {
+ case ZEND_VM_KIND_SWITCH:
+ out($f, $m[1]."dispatch_handler = OPLINE->handler;\nzend_vm_dispatch:\n".$m[1]."switch ((int)(uintptr_t)dispatch_handler)".$m[3]."\n");
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f, $m[1]."goto *(void**)(OPLINE->handler);".$m[3]."\n");
+ break;
+ case ZEND_VM_KIND_HYBRID:
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f, $m[1]."HYBRID_SWITCH();".$m[3]."\n");
+ out($f,"#else\n");
case ZEND_VM_KIND_CALL:
out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
out($f, $m[1]."((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
out($f,"#else\n");
out($f, $m[1]."if (UNEXPECTED((ret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) != 0))".$m[3]."\n");
out($f,"#endif\n");
- break;
- case ZEND_VM_KIND_SWITCH:
- out($f, $m[1]."dispatch_handler = OPLINE->handler;\nzend_vm_dispatch:\n".$m[1]."switch ((int)(uintptr_t)dispatch_handler)".$m[3]."\n");
- break;
- case ZEND_VM_KIND_GOTO:
- out($f, $m[1]."goto *(void**)(OPLINE->handler);".$m[3]."\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#endif\n");
+ }
break;
}
break;
case "INTERNAL_EXECUTOR":
- if ($kind == ZEND_VM_KIND_CALL) {
- // Executor is defined as a set of functions
+ if ($kind != ZEND_VM_KIND_CALL) {
+ // Emit executor code
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ }
+ gen_executor_code($f, $spec, $kind, $m[1], $switch_labels);
+ }
+ if ($kind == ZEND_VM_KIND_CALL || $kind == ZEND_VM_KIND_HYBRID) {
+ // Executor is defined as a set of functions
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#else\n");
+ }
out($f,
"#ifdef ZEND_VM_FP_GLOBAL_REG\n" .
$m[1]."execute_data = orig_execute_data;\n" .
$m[1]."\treturn;\n".
$m[1]."}\n".
"#endif\n");
- } else {
- // Emit executor code
- gen_executor_code($f, $spec, $kind, $m[1], $switch_labels);
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#endif\n");
+ }
}
break;
case "EXTERNAL_EXECUTOR":
if ($kind == ZEND_VM_KIND_GOTO) {
// Labels are defined in the executor itself, so we call it
// with execute_data NULL and it sets zend_opcode_handlers array
- out($f,$prolog."");
+ out($f,$prolog."static const uint32_t specs[] = {\n");
+ gen_specs($f, $prolog."\t", $specs);
+ out($f,$prolog."};\n");
+ out($f,$prolog."zend_spec_handlers = specs;\n");
out($f,$prolog.$executor_name."_ex(NULL);\n");
} else {
out($f,$prolog."static const void *labels[] = {\n");
- gen_labels($f, $spec, $kind, $prolog."\t", $specs, $switch_labels);
+ gen_labels($f, $spec, ZEND_VM_KIND_CALL, $prolog."\t", $specs, $switch_labels);
out($f,$prolog."};\n");
out($f,$prolog."static const uint32_t specs[] = {\n");
- gen_specs($f, $spec, $kind, $prolog."\t", $specs);
+ gen_specs($f, $prolog."\t", $specs);
out($f,$prolog."};\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f,$prolog."zend_opcode_real_handlers = labels;\n");
+ out($f,$prolog."zend_spec_handlers = specs;\n");
+ out($f,$prolog.$executor_name."_ex(NULL);\n");
+ out($f,"#else\n");
+ }
out($f,$prolog."zend_opcode_handlers = labels;\n");
out($f,$prolog."zend_handlers_count = sizeof(labels) / sizeof(void*);\n");
out($f,$prolog."zend_spec_handlers = specs;\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#endif\n");
+ }
}
break;
default:
$export = array();
foreach ($in as $line) {
++$lineno;
- if (strpos($line,"ZEND_VM_HANDLER(") === 0) {
+ if (strpos($line,"ZEND_VM_HANDLER(") === 0 ||
+ strpos($line,"ZEND_VM_HOT_HANDLER(") === 0) {
// Parsing opcode handler's definition
if (preg_match(
- "/^ZEND_VM_HANDLER\(\s*([0-9]+)\s*,\s*([A-Z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
+ "/^ZEND_VM_(HOT_)?HANDLER\(\s*([0-9]+)\s*,\s*([A-Z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
$line,
$m) == 0) {
die("ERROR ($def:$lineno): Invalid ZEND_VM_HANDLER definition.\n");
}
- $code = (int)$m[1];
- $op = $m[2];
+ $hot = !empty($m[1]);
+ $code = (int)$m[2];
+ $op = $m[3];
$len = strlen($op);
- $op1 = parse_operand_spec($def, $lineno, $m[3], $flags1);
- $op2 = parse_operand_spec($def, $lineno, $m[4], $flags2);
+ $op1 = parse_operand_spec($def, $lineno, $m[4], $flags1);
+ $op2 = parse_operand_spec($def, $lineno, $m[5], $flags2);
$flags = $flags1 | ($flags2 << 8);
- if (!empty($m[6])) {
- $flags |= parse_ext_spec($def, $lineno, $m[6]);
+ if (!empty($m[7])) {
+ $flags |= parse_ext_spec($def, $lineno, $m[7]);
}
if ($len > $max_opcode_len) {
if (isset($opnames[$op])) {
die("ERROR ($def:$lineno): Opcode with name '$op' is already defined.\n");
}
- $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags);
- if (isset($m[8])) {
- $opcodes[$code]["spec"] = parse_spec_rules($def, $lineno, $m[8]);
+ $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags,"hot"=>$hot);
+ if (isset($m[9])) {
+ $opcodes[$code]["spec"] = parse_spec_rules($def, $lineno, $m[9]);
if (isset($opcodes[$code]["spec"]["NO_CONST_CONST"])) {
$opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_NO_CONST_CONST"];
}
$handler = $code;
$helper = null;
$list[$lineno] = array("handler"=>$handler);
- } else if (strpos($line,"ZEND_VM_TYPE_SPEC_HANDLER(") === 0) {
+ } else if (strpos($line,"ZEND_VM_TYPE_SPEC_HANDLER(") === 0 ||
+ strpos($line,"ZEND_VM_HOT_TYPE_SPEC_HANDLER(") === 0) {
// Parsing opcode handler's definition
if (preg_match(
- "/^ZEND_VM_TYPE_SPEC_HANDLER\(\s*([A-Z_]+)\s*,\s*([^,]+),\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
+ "/^ZEND_VM_(HOT_)?TYPE_SPEC_HANDLER\(\s*([A-Z_]+)\s*,\s*([^,]+),\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
$line,
$m) == 0) {
die("ERROR ($def:$lineno): Invalid ZEND_VM_TYPE_HANDLER_HANDLER definition.\n");
}
- $orig_op = $m[1];
+ $hot = !empty($m[1]);
+ $orig_op = $m[2];
if (!isset($opnames[$orig_op])) {
die("ERROR ($def:$lineno): Opcode with name '$orig_op' is not defined.\n");
}
$orig_code = $opnames[$orig_op];
- $condition = $m[2];
+ $condition = $m[3];
$code = $extra_num++;
- $op = $m[3];
- $op1 = parse_operand_spec($def, $lineno, $m[4], $flags1);
- $op2 = parse_operand_spec($def, $lineno, $m[5], $flags2);
+ $op = $m[4];
+ $op1 = parse_operand_spec($def, $lineno, $m[5], $flags1);
+ $op2 = parse_operand_spec($def, $lineno, $m[6], $flags2);
$flags = $flags1 | ($flags2 << 8);
- if (!empty($m[7])) {
- $flags |= parse_ext_spec($def, $lineno, $m[7]);
+ if (!empty($m[8])) {
+ $flags |= parse_ext_spec($def, $lineno, $m[8]);
}
if (isset($opcodes[$code])) {
}
$opcodes[$orig_code]['type_spec'][$code] = $condition;
$used_extra_spec["TYPE"] = 1;
- $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags);
- if (isset($m[9])) {
- $opcodes[$code]["spec"] = parse_spec_rules($def, $lineno, $m[9]);
+ $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags,"hot"=>$hot);
+ if (isset($m[10])) {
+ $opcodes[$code]["spec"] = parse_spec_rules($def, $lineno, $m[10]);
if (isset($opcodes[$code]["spec"]["NO_CONST_CONST"])) {
$opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_NO_CONST_CONST"];
}
fputs($f, "#define ZEND_VM_KIND_CALL\t" . ZEND_VM_KIND_CALL . "\n");
fputs($f, "#define ZEND_VM_KIND_SWITCH\t" . ZEND_VM_KIND_SWITCH . "\n");
fputs($f, "#define ZEND_VM_KIND_GOTO\t" . ZEND_VM_KIND_GOTO . "\n");
- fputs($f, "#define ZEND_VM_KIND\t\t" . $GLOBALS["vm_kind_name"][ZEND_VM_KIND] . "\n");
+ fputs($f, "#define ZEND_VM_KIND_HYBRID\t" . ZEND_VM_KIND_HYBRID . "\n");
+ if ($GLOBALS["vm_kind_name"][ZEND_VM_KIND] === "ZEND_VM_KIND_HYBRID") {
+ fputs($f, "/* HYBRID requires support for cmputed GOTO and global register variables*/\n");
+ fputs($f, "#if (defined(__GNUC__) && defined(HAVE_GCC_GLOBAL_REGS))\n");
+ fputs($f, "# define ZEND_VM_KIND\t\tZEND_VM_KIND_HYBRID\n");
+ fputs($f, "#else\n");
+ fputs($f, "# define ZEND_VM_KIND\t\tZEND_VM_KIND_CALL\n");
+ fputs($f, "#endif\n");
+ } else {
+ fputs($f, "#define ZEND_VM_KIND\t\t" . $GLOBALS["vm_kind_name"][ZEND_VM_KIND] . "\n");
+ }
fputs($f, "\n");
foreach($vm_op_flags as $name => $val) {
fprintf($f, "#define %-24s 0x%08x\n", $name, $val);
out($f, "}\n\n");
// Generate zend_vm_call_opcode_handler() function
- if (ZEND_VM_KIND == ZEND_VM_KIND_CALL) {
+ if (ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
out($f, "ZEND_API int zend_vm_call_opcode_handler(zend_execute_data* ex)\n");
out($f, "{\n");
+ if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f, "\topcode_handler_t handler;\n");
+ out($f,"#endif\n");
+ }
out($f, "\tint ret;\n");
out($f, "#ifdef ZEND_VM_IP_GLOBAL_REG\n");
out($f, "\tconst zend_op *orig_opline = opline;\n");
out($f, "#endif\n");
out($f, "\n");
out($f, "\tLOAD_OPLINE();\n");
- out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
+ if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f, "\thandler = (opcode_handler_t)zend_get_real_opcode_handler(opline);\n");
+ out($f, "\thandler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+ out($f,"#elif defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
+ } else {
+ out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
+ }
out($f, "\t((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
out($f, "\tif (EXPECTED(opline)) {\n");
out($f, "\t\tret = execute_data != ex ? (int)(execute_data->prev_execute_data != ex) + 1 : 0;\n");
function usage() {
echo("\nUsage: php zend_vm_gen.php [options]\n".
"\nOptions:".
- "\n --with-vm-kind=CALL|SWITCH|GOTO - select threading model (default is CALL)".
- "\n --without-specializer - disable executor specialization".
- "\n --with-lines - enable #line directives".
+ "\n --with-vm-kind=CALL|SWITCH|GOTO|HYBRID - select threading model (default is CALL)".
+ "\n --without-specializer - disable executor specialization".
+ "\n --with-lines - enable #line directives".
"\n\n");
}
case "GOTO":
define("ZEND_VM_KIND", ZEND_VM_KIND_GOTO);
break;
+ case "HYBRID":
+ define("ZEND_VM_KIND", ZEND_VM_KIND_HYBRID);
+ break;
default:
echo("ERROR: Invalid vm kind '$kind'\n");
usage();