(slot)[1] = (ptr); \
} while (0)
+#define CACHE_SPECIAL (1<<0)
+
+#define IS_SPECIAL_CACHE_VAL(ptr) \
+ (((uintptr_t)(ptr)) & CACHE_SPECIAL)
+
+#define ENCODE_SPECIAL_CACHE_NUM(num) \
+ ((void*)((((uintptr_t)(num)) << 1) | CACHE_SPECIAL))
+
+#define DECODE_SPECIAL_CACHE_NUM(ptr) \
+ (((uintptr_t)(ptr)) >> 1)
+
+#define ENCODE_SPECIAL_CACHE_PTR(ptr) \
+ ((void*)(((uintptr_t)(ptr)) | CACHE_SPECIAL))
+
+#define DECODE_SPECIAL_CACHE_PTR(ptr) \
+ ((void*)(((uintptr_t)(ptr)) & ~CACHE_SPECIAL))
+
#define SKIP_EXT_OPLINE(opline) do { \
while (UNEXPECTED((opline)->opcode >= ZEND_EXT_STMT \
&& (opline)->opcode <= ZEND_TICKS)) { \
USE_OPLINE
zend_constant *c;
- if (EXPECTED(CACHED_PTR(opline->extended_value))) {
- c = CACHED_PTR(opline->extended_value);
+ c = CACHED_PTR(opline->extended_value);
+ if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) {
+ /* pass */
} else if (UNEXPECTED((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num)) == NULL)) {
SAVE_OPLINE();
zend_constant *c;
int result;
- if (EXPECTED(CACHED_PTR(opline->extended_value))) {
- result = 1;
- } else if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) {
- result = 0;
- } else {
- CACHE_PTR(opline->extended_value, c);
- result = 1;
- }
+ c = CACHED_PTR(opline->extended_value);
+ do {
+ if (EXPECTED(c != NULL)) {
+ if (!IS_SPECIAL_CACHE_VAL(c)) {
+ result = 1;
+ break;
+ } else if (EXPECTED(zend_hash_num_elements(EG(zend_constants)) == DECODE_SPECIAL_CACHE_NUM(c))) {
+ result = 0;
+ break;
+ }
+ }
+ if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) {
+ CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants))));
+ result = 0;
+ } else {
+ CACHE_PTR(opline->extended_value, c);
+ result = 1;
+ }
+ } while (0);
ZEND_VM_SMART_BRANCH(result, 0);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
ZEND_VM_NEXT_OPCODE();
zend_constant *c;
int result;
- if (EXPECTED(CACHED_PTR(opline->extended_value))) {
- result = 1;
- } else if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) {
- result = 0;
- } else {
- CACHE_PTR(opline->extended_value, c);
- result = 1;
- }
+ c = CACHED_PTR(opline->extended_value);
+ do {
+ if (EXPECTED(c != NULL)) {
+ if (!IS_SPECIAL_CACHE_VAL(c)) {
+ result = 1;
+ break;
+ } else if (EXPECTED(zend_hash_num_elements(EG(zend_constants)) == DECODE_SPECIAL_CACHE_NUM(c))) {
+ result = 0;
+ break;
+ }
+ }
+ if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) {
+ CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants))));
+ result = 0;
+ } else {
+ CACHE_PTR(opline->extended_value, c);
+ result = 1;
+ }
+ } while (0);
ZEND_VM_SMART_BRANCH(result, 0);
ZVAL_BOOL(EX_VAR(opline->result.var), result);
ZEND_VM_NEXT_OPCODE();
USE_OPLINE
zend_constant *c;
- if (EXPECTED(CACHED_PTR(opline->extended_value))) {
- c = CACHED_PTR(opline->extended_value);
+ c = CACHED_PTR(opline->extended_value);
+ if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) {
+ /* pass */
} else if (UNEXPECTED((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num)) == NULL)) {
SAVE_OPLINE();