Skip to content

Commit

Permalink
Remove support for classes without class entries
Browse files Browse the repository at this point in the history
get_class_entry must be non-NULL and return non-NULL.
  • Loading branch information
nikic committed Oct 9, 2014
1 parent 43f1c94 commit ee5b30f
Show file tree
Hide file tree
Showing 14 changed files with 77 additions and 161 deletions.
8 changes: 1 addition & 7 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,7 @@ ZEND_API char *zend_zval_type_name(const zval *arg) /* {{{ */

ZEND_API zend_class_entry *zend_get_class_entry(const zend_object *zobject TSRMLS_DC) /* {{{ */
{
if (zobject->handlers->get_class_entry) {
return zobject->handlers->get_class_entry(zobject TSRMLS_CC);
} else {
zend_error(E_ERROR, "Class entry requested for an object without PHP class");
return NULL;
}
return zobject->handlers->get_class_entry(zobject TSRMLS_CC);
}
/* }}} */

Expand Down Expand Up @@ -3100,7 +3095,6 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
retval = 1;
call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
if (call_via_handler && !fcc->object && EG(current_execute_data) && Z_OBJ(EG(current_execute_data)->This) &&
Z_OBJ_HT(EG(current_execute_data)->This)->get_class_entry &&
instanceof_function(Z_OBJCE(EG(current_execute_data)->This), fcc->calling_scope TSRMLS_CC)) {
fcc->object = Z_OBJ(EG(current_execute_data)->This);
}
Expand Down
6 changes: 1 addition & 5 deletions Zend/zend_builtin_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass) /*
if (!instance_ce) {
RETURN_FALSE;
}
} else if (Z_TYPE_P(obj) == IS_OBJECT && HAS_CLASS_ENTRY(*obj)) {
} else if (Z_TYPE_P(obj) == IS_OBJECT) {
instance_ce = Z_OBJCE_P(obj);
} else {
RETURN_FALSE;
Expand Down Expand Up @@ -1089,10 +1089,6 @@ ZEND_FUNCTION(get_class_methods)
}

if (Z_TYPE_P(klass) == IS_OBJECT) {
/* TBI!! new object handlers */
if (!HAS_CLASS_ENTRY(*klass)) {
RETURN_FALSE;
}
ce = Z_OBJCE_P(klass);
} else if (Z_TYPE_P(klass) == IS_STRING) {
ce = zend_lookup_class(Z_STR_P(klass) TSRMLS_CC);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_closures.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ ZEND_METHOD(Closure, bind)
}

if (scope_arg != NULL) { /* scope argument was given */
if (IS_ZEND_STD_OBJECT(*scope_arg)) {
if (Z_TYPE_P(scope_arg) == IS_OBJECT) {
ce = Z_OBJCE_P(scope_arg);
} else if (Z_TYPE_P(scope_arg) == IS_NULL) {
ce = NULL;
Expand Down
36 changes: 17 additions & 19 deletions Zend/zend_execute.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,24 +98,22 @@ static zend_always_inline int i_zend_is_true(zval *op TSRMLS_DC)
result = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
break;
case IS_OBJECT:
if (IS_ZEND_STD_OBJECT(*op)) {
if (Z_OBJ_HT_P(op)->cast_object) {
zval tmp;
if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, _IS_BOOL TSRMLS_CC) == SUCCESS) {
result = Z_TYPE(tmp) == IS_TRUE;
break;
}
zend_error(E_RECOVERABLE_ERROR, "Object of class %s could not be converted to boolean", Z_OBJ_P(op)->ce->name->val);
} else if (Z_OBJ_HT_P(op)->get) {
zval rv;
zval *tmp = Z_OBJ_HT_P(op)->get(op, &rv TSRMLS_CC);
if (Z_TYPE_P(tmp) != IS_OBJECT) {
/* for safety - avoid loop */
convert_to_boolean(tmp);
result = Z_TYPE_P(tmp) == IS_TRUE;
zval_ptr_dtor(tmp);
break;
}
if (Z_OBJ_HT_P(op)->cast_object) {
zval tmp;
if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, _IS_BOOL TSRMLS_CC) == SUCCESS) {
result = Z_TYPE(tmp) == IS_TRUE;
break;
}
zend_error(E_RECOVERABLE_ERROR, "Object of class %s could not be converted to boolean", Z_OBJ_P(op)->ce->name->val);
} else if (Z_OBJ_HT_P(op)->get) {
zval rv;
zval *tmp = Z_OBJ_HT_P(op)->get(op, &rv TSRMLS_CC);
if (Z_TYPE_P(tmp) != IS_OBJECT) {
/* for safety - avoid loop */
convert_to_boolean(tmp);
result = Z_TYPE_P(tmp) == IS_TRUE;
zval_ptr_dtor(tmp);
break;
}
}
result = 1;
Expand Down Expand Up @@ -289,7 +287,7 @@ void zend_shutdown_timeout_thread(void);
/* The following tries to resolve the classname of a zval of type object.
* Since it is slow it should be only used in error messages.
*/
#define Z_OBJ_CLASS_NAME_P(obj) (((obj) && (obj)->handlers->get_class_entry != NULL && (obj)->handlers->get_class_entry) ? (obj)->handlers->get_class_entry(obj TSRMLS_CC)->name->val : "")
#define Z_OBJ_CLASS_NAME_P(obj) ((obj) ? (obj)->handlers->get_class_entry(obj TSRMLS_CC)->name->val : "")

ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, uint32_t var);

Expand Down
3 changes: 1 addition & 2 deletions Zend/zend_interfaces.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,7 @@ ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *c
zend_class_entry *ce_it;

zend_user_it_new_iterator(ce, object, &iterator TSRMLS_CC);
ce_it = (Z_TYPE(iterator) == IS_OBJECT &&
Z_OBJ_HT(iterator)->get_class_entry) ? Z_OBJCE(iterator) : NULL;
ce_it = (Z_TYPE(iterator) == IS_OBJECT) ? Z_OBJCE(iterator) : NULL;

if (!ce_it || !ce_it->get_iterator || (ce_it->get_iterator == zend_user_it_get_new_iterator && Z_OBJ(iterator) == Z_OBJ_P(object))) {
if (!EG(exception)) {
Expand Down
1 change: 0 additions & 1 deletion Zend/zend_object_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,6 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
}
if (ce->__call &&
Z_OBJ(EG(current_execute_data)->This) &&
Z_OBJ_HT(EG(current_execute_data)->This)->get_class_entry &&
instanceof_function(Z_OBJCE(EG(current_execute_data)->This), ce TSRMLS_CC)) {
return zend_get_user_call_function(ce, function_name);
} else if (ce->__callstatic) {
Expand Down
4 changes: 0 additions & 4 deletions Zend/zend_object_handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,6 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty
ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, void **cache_slot TSRMLS_DC);
ZEND_API void rebuild_object_properties(zend_object *zobj);


#define IS_ZEND_STD_OBJECT(z) (Z_TYPE(z) == IS_OBJECT && (Z_OBJ_HT((z))->get_class_entry != NULL))
#define HAS_CLASS_ENTRY(z) (Z_OBJ_HT(z)->get_class_entry != NULL)

ZEND_API int zend_check_private(union _zend_function *fbc, zend_class_entry *ce, zend_string *function_name TSRMLS_DC);

ZEND_API int zend_check_protected(zend_class_entry *ce, zend_class_entry *scope);
Expand Down
28 changes: 9 additions & 19 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -2310,8 +2310,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS
GC_REFCOUNT(object)++;
}
if (!object ||
(object->handlers->get_class_entry &&
!instanceof_function(zend_get_class_entry(object TSRMLS_CC), ce TSRMLS_CC))) {
!instanceof_function(zend_get_class_entry(object TSRMLS_CC), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
Expand Down Expand Up @@ -4436,13 +4435,8 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
}
if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
if(Z_OBJ_HT_P(array_ptr)->get_class_entry == NULL) {
zend_error(E_WARNING, "foreach() cannot iterate over objects without PHP class");
ZEND_VM_JMP(opline->op2.jmp_addr);
}

ce = Z_OBJCE_P(array_ptr);
if (!ce || ce->get_iterator == NULL) {
if (ce->get_iterator == NULL) {
Z_ADDREF_P(array_ptr);
}
array_ref = array_ptr;
Expand All @@ -4466,7 +4460,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
}
} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
ce = Z_OBJCE_P(array_ptr);
if (!ce || !ce->get_iterator) {
if (!ce->get_iterator) {
if (OP1_TYPE == IS_CV) {
Z_ADDREF_P(array_ref);
}
Expand Down Expand Up @@ -5342,7 +5336,7 @@ ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|VAR|CV, ANY)
SAVE_OPLINE();
expr = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);

if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
if (Z_TYPE_P(expr) == IS_OBJECT) {
result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
} else {
result = 0;
Expand Down Expand Up @@ -5977,16 +5971,12 @@ ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY)
break;
case IS_OBJECT:
if (Z_TYPE_P(value) == opline->extended_value) {
if (Z_OBJ_HT_P(value)->get_class_entry == NULL) {
ZVAL_TRUE(EX_VAR(opline->result.var));
zend_class_entry *ce = Z_OBJCE_P(value);
if (ce->name->len == sizeof("__PHP_Incomplete_Class") - 1
&& !strncmp(ce->name->val, "__PHP_Incomplete_Class", ce->name->len)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
} else {
zend_class_entry *ce = Z_OBJCE_P(value);
if (ce->name->len == sizeof("__PHP_Incomplete_Class") - 1
&& !strncmp(ce->name->val, "__PHP_Incomplete_Class", ce->name->len)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
} else {
ZVAL_TRUE(EX_VAR(opline->result.var));
}
ZVAL_TRUE(EX_VAR(opline->result.var));
}
} else {
ZVAL_FALSE(EX_VAR(opline->result.var));
Expand Down
Loading

0 comments on commit ee5b30f

Please sign in to comment.