Skip to content

Commit aa75835

Browse files
committed
Merge remote-tracking branch 'noblet/php80' into v2
2 parents f06b1ab + f232a33 commit aa75835

File tree

10 files changed

+179
-53
lines changed

10 files changed

+179
-53
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ php:
1111
- 7.1
1212
- 7.2
1313
- 7.3
14-
- nightly # doesn't work yet on PHP 7.4! not building.
14+
- 7.4
15+
- 8.0
16+
- nightly
1517

1618

1719
# setting the env is the easiest, because it will mix with all the separate php versions (travis does this)

zend/callable.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,12 @@ void Callable::invoke(INTERNAL_FUNCTION_PARAMETERS)
3636
#else
3737
// Sanity check
3838
assert(info[argc].type != 0 && info[argc].name == nullptr);
39-
4039
// the callable we are retrieving
40+
#if PHP_VERSION_ID < 80000
4141
Callable *callable = reinterpret_cast<Callable*>(info[argc].type);
42+
#else
43+
Callable *callable = reinterpret_cast<Callable*>(info[argc].type.ptr);
44+
#endif
4245
#endif
4346

4447
// check if sufficient parameters were passed (for some reason this check
@@ -99,10 +102,10 @@ void Callable::initialize(zend_function_entry *entry, const char *classname, int
99102
_argv[_argc + 1].class_name = reinterpret_cast<const char*>(this);
100103
#else
101104
// @todo this is broken. the zend engine, from 7.2 onwards copies over
102-
// the struct and slices of the last element, because the num_args
105+
// the struct and slices off the last element, because the num_args
103106
// is incorrect in their view. another place to put this may be
104107
// hiding it behind the fname
105-
_argv[_argc + 1].type = reinterpret_cast<zend_type>(this);
108+
// _argv[_argc + 1].type = reinterpret_cast<zend_type>(this);
106109
#endif
107110

108111
// we use our own invoke method, which does a lookup
@@ -129,8 +132,10 @@ void Callable::initialize(zend_internal_function_info *info, const char *classna
129132
{
130133
// initialize all common elements
131134
info->required_num_args = _required;
135+
#if PHP_VERSION_ID < 80000
132136
info->return_reference = false;
133137
info->_is_variadic = false;
138+
#endif
134139

135140
// the structure has been slightly altered since php7.2
136141
#if PHP_VERSION_ID < 70200
@@ -147,10 +152,12 @@ void Callable::initialize(zend_internal_function_info *info, const char *classna
147152
#else
148153
// the properties that are available on php 7.2 and higher
149154
info->required_num_args = _required;
155+
#if PHP_VERSION_ID < 80000
150156
info->return_reference = false;
151157
info->_is_variadic = false;
152158
info->type = ZEND_TYPE_ENCODE((int)_return, true);
153159
#endif
160+
#endif
154161
}
155162

156163
/**

zend/callable.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,14 @@ class Callable
5353

5454
// initialize all elements to null
5555
_argv[i].name = nullptr;
56+
#if PHP_VERSION_ID < 80000
5657
_argv[i].is_variadic = false;
5758
_argv[i].pass_by_reference = false;
58-
59+
#endif
5960
// initialize the extra argument prior to 7.2
6061
#if PHP_VERSION_ID < 70200
6162
_argv[i].class_name = nullptr;
62-
#else
63+
#elif PHP_VERSION_ID < 80000
6364
_argv[i].type = 0;
6465
#endif
6566
}
@@ -198,6 +199,23 @@ class Callable
198199
case Type::Object: info->type_hint = IS_OBJECT; break; // must be an object of the given classname
199200
case Type::Callable: info->type_hint = IS_CALLABLE; break; // anything that can be invoked
200201
default: info->type_hint = IS_UNDEF; break; // if not specified we allow anything
202+
#elif PHP_VERSION_ID >= 80000
203+
case Type::Undefined: info->type = (zend_type) ZEND_TYPE_INIT_CODE(IS_UNDEF, arg.allowNull(), 0); break; // undefined means we'll accept any type
204+
case Type::Null: info->type = (zend_type) ZEND_TYPE_INIT_CODE(IS_UNDEF, arg.allowNull(), 0); break; // this is likely an error, what good would accepting NULL be? accept anything
205+
case Type::False: info->type = (zend_type) ZEND_TYPE_INIT_CODE(_IS_BOOL, arg.allowNull(), 0); break; // accept true as well ;)
206+
case Type::True: info->type = (zend_type) ZEND_TYPE_INIT_CODE(_IS_BOOL, arg.allowNull(), 0); break; // accept false as well
207+
case Type::Bool: info->type = (zend_type) ZEND_TYPE_INIT_CODE(_IS_BOOL, arg.allowNull(), 0); break; // any bool will do, true, false, the options are limitless
208+
case Type::Numeric: info->type = (zend_type) ZEND_TYPE_INIT_CODE(IS_LONG, arg.allowNull(), 0); break; // accept integers here
209+
case Type::Float: info->type = (zend_type) ZEND_TYPE_INIT_CODE(IS_DOUBLE, arg.allowNull(), 0); break; // floating-point values welcome too
210+
case Type::String: info->type = (zend_type) ZEND_TYPE_INIT_CODE(IS_STRING, arg.allowNull(), 0); break; // accept strings, should auto-cast objects with __toString as well
211+
case Type::Array: info->type = (zend_type) ZEND_TYPE_INIT_CODE(IS_ARRAY, arg.allowNull(), 0); break; // array of anything (individual members cannot be restricted)
212+
case Type::Object: // if there is a classname and the argument is not nullable, it's simply the classname
213+
if (!arg.classname()) info->type = (zend_type) ZEND_TYPE_INIT_CODE(IS_OBJECT, arg.allowNull(), 0);
214+
// else info->type = (zend_type)arg.encoded();
215+
break;
216+
case Type::Callable: info->type = (zend_type) ZEND_TYPE_INIT_CODE(IS_CALLABLE, arg.allowNull(), 0); break; // anything that can be invoke
217+
218+
default: info->type = ZEND_TYPE_INIT_CODE(IS_UNDEF, 0, 0); break; // if not specified we allow anything
201219
#else
202220
case Type::Undefined: info->type = ZEND_TYPE_ENCODE(IS_UNDEF, arg.allowNull()); break; // undefined means we'll accept any type
203221
case Type::Null: info->type = ZEND_TYPE_ENCODE(IS_UNDEF, arg.allowNull()); break; // this is likely an error, what good would accepting NULL be? accept anything
@@ -216,7 +234,7 @@ class Callable
216234
default: info->type = ZEND_TYPE_ENCODE(IS_UNDEF, arg.allowNull()); break; // if not specified we allow anything
217235
#endif
218236
}
219-
237+
#if PHP_VERSION_ID < 80000
220238
// from PHP 5.6 and onwards, an is_variadic property can be set, this
221239
// specifies whether this argument is the first argument that specifies
222240
// the type for a variable length list of arguments. For now we only
@@ -225,6 +243,7 @@ class Callable
225243

226244
// whether or not to pass the argument by reference
227245
info->pass_by_reference = arg.byReference();
246+
#endif
228247
}
229248

230249
/**

zend/classimpl.cpp

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ zend_function *ClassImpl::getStaticMethod(zend_class_entry *entry, zend_string *
284284
* @param object_ptr
285285
* @return int
286286
*/
287-
int ClassImpl::getClosure(zval *object, zend_class_entry **entry_ptr, zend_function **func, zend_object **object_ptr)
287+
int ClassImpl::getClosure(ZEND_OBJECT_OR_ZVAL object, zend_class_entry **entry_ptr, zend_function **func, zend_object **object_ptr, zend_bool check_only)
288288
{
289289
// it is really unbelievable how the Zend engine manages to implement every feature
290290
// in a complete different manner. You would expect the __invoke() and the
@@ -314,7 +314,11 @@ int ClassImpl::getClosure(zval *object, zend_class_entry **entry_ptr, zend_funct
314314

315315
// store pointer to ourselves (note that the entry_ptr is useless
316316
// inside this function as it is always uninitialized for some reason)
317+
#if PHP_VERSION_ID < 80000
317318
data->self = self(Z_OBJCE_P(object));
319+
#else
320+
data->self = self(object->ce);
321+
#endif
318322

319323
// assign this dynamically allocated variable to the func parameter
320324
// the cast is ok, because zend_internal_function is a member of the
@@ -323,7 +327,11 @@ int ClassImpl::getClosure(zval *object, zend_class_entry **entry_ptr, zend_funct
323327

324328
// the object_ptr should be filled with the object on which the method is
325329
// called (otherwise the Zend engine tries to call the method statically)
330+
#if PHP_VERSION_ID < 80000
326331
*object_ptr = Z_OBJ_P(object);
332+
#else
333+
*object_ptr = object;
334+
#endif
327335

328336
// done
329337
return SUCCESS;
@@ -374,7 +382,11 @@ zend_object_handlers *ClassImpl::objectHandlers()
374382
_handlers.cast_object = &ClassImpl::cast;
375383

376384
// method to compare two objects
385+
#if PHP_VERSION_ID < 80000
377386
_handlers.compare_objects = &ClassImpl::compare;
387+
#else
388+
_handlers.compare = &ClassImpl::compare;
389+
#endif
378390

379391
// set the offset between our class implementation and
380392
// the zend_object member in the allocated structure
@@ -427,10 +439,17 @@ int ClassImpl::compare(zval *val1, zval *val2)
427439
catch (const NotImplemented &exception)
428440
{
429441
// it was not implemented, do we have a default?
442+
#if PHP_VERSION_ID < 80000
430443
if (!std_object_handlers.compare_objects) return 1;
431444

432445
// call default
433446
return std_object_handlers.compare_objects(val1, val2);
447+
#else
448+
if (!std_object_handlers.compare) return 1;
449+
450+
// call default
451+
return std_object_handlers.compare(val1, val2);
452+
#endif
434453
}
435454
catch (Throwable &throwable)
436455
{
@@ -449,14 +468,17 @@ int ClassImpl::compare(zval *val1, zval *val2)
449468
* @param type
450469
* @return int
451470
*/
452-
int ClassImpl::cast(zval *val, zval *retval, int type)
471+
int ClassImpl::cast(ZEND_OBJECT_OR_ZVAL val, zval *retval, int type)
453472
{
454473
// get the base c++ object
455474
Base *object = ObjectImpl::find(val)->object();
456475

457476
// retrieve the class entry linked to this object
477+
#if PHP_VERSION_ID < 80000
458478
auto *entry = Z_OBJCE_P(val);
459-
479+
#else
480+
auto *entry = val->ce;
481+
#endif
460482
// we need the C++ class meta-information object
461483
ClassBase *meta = self(entry)->_base;
462484

@@ -509,11 +531,14 @@ int ClassImpl::cast(zval *val, zval *retval, int type)
509531
* @param val The object to be cloned
510532
* @return zend_object The object to be created
511533
*/
512-
zend_object *ClassImpl::cloneObject(zval *val)
534+
zend_object *ClassImpl::cloneObject(ZEND_OBJECT_OR_ZVAL val)
513535
{
514536
// retrieve the class entry linked to this object
537+
#if PHP_VERSION_ID < 80000
515538
auto *entry = Z_OBJCE_P(val);
516-
539+
#else
540+
auto *entry = val->ce;
541+
#endif
517542
// we need the C++ class meta-information object
518543
ClassImpl *impl = self(entry);
519544
ClassBase *meta = impl->_base;
@@ -555,7 +580,7 @@ zend_object *ClassImpl::cloneObject(zval *val)
555580
* @param count
556581
* @return int
557582
*/
558-
int ClassImpl::countElements(zval *object, zend_long *count)
583+
int ClassImpl::countElements(ZEND_OBJECT_OR_ZVAL object, zend_long *count)
559584
{
560585
// does it implement the countable interface?
561586
Countable *countable = dynamic_cast<Countable*>(ObjectImpl::find(object)->object());
@@ -603,7 +628,7 @@ int ClassImpl::countElements(zval *object, zend_long *count)
603628
* @param rv Pointer to where to store the data
604629
* @return zval
605630
*/
606-
zval *ClassImpl::readDimension(zval *object, zval *offset, int type, zval *rv)
631+
zval *ClassImpl::readDimension(ZEND_OBJECT_OR_ZVAL object, zval *offset, int type, zval *rv)
607632
{
608633
// what to do with the type?
609634
//
@@ -705,7 +730,7 @@ zval *ClassImpl::getPropertyPtrPtr(zval *object, zval *member, int type, void **
705730
* @param value The new value
706731
* @return zval
707732
*/
708-
void ClassImpl::writeDimension(zval *object, zval *offset, zval *value)
733+
void ClassImpl::writeDimension(ZEND_OBJECT_OR_ZVAL object, zval *offset, zval *value)
709734
{
710735
// does it implement the arrayaccess interface?
711736
ArrayAccess *arrayaccess = dynamic_cast<ArrayAccess*>(ObjectImpl::find(object)->object());
@@ -746,7 +771,7 @@ void ClassImpl::writeDimension(zval *object, zval *offset, zval *value)
746771
* @param check_empty Was this an isset() call, or an empty() call?
747772
* @return bool
748773
*/
749-
int ClassImpl::hasDimension(zval *object, zval *member, int check_empty)
774+
int ClassImpl::hasDimension(ZEND_OBJECT_OR_ZVAL object, zval *member, int check_empty)
750775
{
751776
// does it implement the arrayaccess interface?
752777
ArrayAccess *arrayaccess = dynamic_cast<ArrayAccess*>(ObjectImpl::find(object)->object());
@@ -795,7 +820,7 @@ int ClassImpl::hasDimension(zval *object, zval *member, int check_empty)
795820
* @param object The object on which it is called
796821
* @param member The member to remove
797822
*/
798-
void ClassImpl::unsetDimension(zval *object, zval *member)
823+
void ClassImpl::unsetDimension(ZEND_OBJECT_OR_ZVAL object, zval *member)
799824
{
800825
// does it implement the arrayaccess interface?
801826
ArrayAccess *arrayaccess = dynamic_cast<ArrayAccess*>(ObjectImpl::find(object)->object());
@@ -876,7 +901,7 @@ zval *ClassImpl::toZval(Value &&value, int type, zval *rv)
876901
* @param rv Pointer to where to store the data
877902
* @return val
878903
*/
879-
zval *ClassImpl::readProperty(zval *object, zval *name, int type, void **cache_slot, zval *rv)
904+
zval *ClassImpl::readProperty(ZEND_OBJECT_OR_ZVAL object, ZEND_STRING_OR_ZVAL name, int type, void **cache_slot, zval *rv)
880905
{
881906
// what to do with the type?
882907
//
@@ -899,7 +924,11 @@ zval *ClassImpl::readProperty(zval *object, zval *name, int type, void **cache_s
899924
Base *base = ObjectImpl::find(object)->object();
900925

901926
// retrieve the class entry linked to this object
927+
#if PHP_VERSION_ID < 80000
902928
auto *entry = Z_OBJCE_P(object);
929+
#else
930+
auto *entry = object->ce;
931+
#endif
903932

904933
// we need the C++ class meta-information object
905934
ClassImpl *impl = self(entry);
@@ -957,13 +986,17 @@ zval *ClassImpl::readProperty(zval *object, zval *name, int type, void **cache_s
957986
* @param cache_slot The cache slot used
958987
* @return zval
959988
*/
960-
PHP_WRITE_PROP_HANDLER_TYPE ClassImpl::writeProperty(zval *object, zval *name, zval *value, void **cache_slot)
989+
PHP_WRITE_PROP_HANDLER_TYPE ClassImpl::writeProperty(ZEND_OBJECT_OR_ZVAL object, ZEND_STRING_OR_ZVAL name, zval *value, void **cache_slot)
961990
{
962991
// retrieve the object and class
963992
Base *base = ObjectImpl::find(object)->object();
964993

965994
// retrieve the class entry linked to this object
995+
#if PHP_VERSION_ID < 80000
966996
auto *entry = Z_OBJCE_P(object);
997+
#else
998+
auto *entry = object->ce;
999+
#endif
9671000

9681001
// we need the C++ class meta-information object
9691002
ClassImpl *impl = self(entry);
@@ -1048,7 +1081,7 @@ PHP_WRITE_PROP_HANDLER_TYPE ClassImpl::writeProperty(zval *object, zval *name, z
10481081
* @param cache_slot The cache slot used
10491082
* @return bool
10501083
*/
1051-
int ClassImpl::hasProperty(zval *object, zval *name, int has_set_exists, void **cache_slot)
1084+
int ClassImpl::hasProperty(ZEND_OBJECT_OR_ZVAL object, ZEND_STRING_OR_ZVAL name, int has_set_exists, void **cache_slot)
10521085
{
10531086
// the default implementation throws an exception, if we catch that
10541087
// we know for sure that the user has not overridden the __isset method
@@ -1058,7 +1091,11 @@ int ClassImpl::hasProperty(zval *object, zval *name, int has_set_exists, void **
10581091
Base *base = ObjectImpl::find(object)->object();
10591092

10601093
// retrieve the class entry linked to this object
1094+
#if PHP_VERSION_ID < 80000
10611095
auto *entry = Z_OBJCE_P(object);
1096+
#else
1097+
auto *entry = object->ce;
1098+
#endif
10621099

10631100
// we need the C++ class meta-information object
10641101
ClassImpl *impl = self(entry);
@@ -1112,15 +1149,18 @@ int ClassImpl::hasProperty(zval *object, zval *name, int has_set_exists, void **
11121149
* @param member The member to remove
11131150
* @param cache_slot The cache slot used
11141151
*/
1115-
void ClassImpl::unsetProperty(zval *object, zval *member, void **cache_slot)
1152+
void ClassImpl::unsetProperty(ZEND_OBJECT_OR_ZVAL object, ZEND_STRING_OR_ZVAL member, void **cache_slot)
11161153
{
11171154
// the default implementation throws an exception, if we catch that
11181155
// we know for sure that the user has not overridden the __unset method
11191156
try
11201157
{
11211158
// retrieve the class entry linked to this object
1159+
#if PHP_VERSION_ID < 80000
11221160
auto *entry = Z_OBJCE_P(object);
1123-
1161+
#else
1162+
auto *entry = object->ce;
1163+
#endif
11241164
// we need the C++ class meta-information object
11251165
ClassImpl *impl = self(entry);
11261166

0 commit comments

Comments
 (0)