diff --git a/Makefile b/Makefile index cbd04ce4..e00244b6 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,7 @@ endif # you want to leave that flag out on production servers). # -COMPILER_FLAGS = -Wall -c -std=c++11 -fvisibility=hidden -DBUILDING_PHPCPP -Wno-write-strings -MD +COMPILER_FLAGS = -Wall -c -std=c++11 -fvisibility=hidden -DBUILDING_PHPCPP -Wno-write-strings -MD -pedantic SHARED_COMPILER_FLAGS = -fpic STATIC_COMPILER_FLAGS = PHP_COMPILER_FLAGS = ${COMPILER_FLAGS} `${PHP_CONFIG} --includes` diff --git a/zend/classimpl.cpp b/zend/classimpl.cpp index 2228eb81..4ed6ddc4 100644 --- a/zend/classimpl.cpp +++ b/zend/classimpl.cpp @@ -327,7 +327,7 @@ int ClassImpl::getClosure(zval *object, zend_class_entry **entry_ptr, zend_funct // done return SUCCESS; -}; +} /** * Retrieve pointer to our own object handlers @@ -1175,7 +1175,7 @@ zend_object_iterator *ClassImpl::getIterator(zend_class_entry *entry, zval *obje // retrieve the traversable object Traversable *traversable = dynamic_cast(ObjectImpl::find(object)->object()); - + // use might throw an exception in the getIterator() function try { @@ -1186,10 +1186,10 @@ zend_object_iterator *ClassImpl::getIterator(zend_class_entry *entry, zval *obje // the iteraters itself, we can no longer let c++ allocate the buffer + object // directly, so we first allocate the buffer, which is going to be cleaned up by php) auto *buffer = emalloc(sizeof(IteratorImpl)); - + // and then we use placement-new to allocate the implementation auto *wrapper = new(buffer)IteratorImpl(object, userspace); - + // done return wrapper->implementation(); } @@ -1351,7 +1351,7 @@ zend_class_entry *ClassImpl::initialize(ClassBase *base, const std::string &pref entry.get_static_method = &ClassImpl::getStaticMethod; // for traversable classes we install a special method to get the iterator - if (_base->traversable()) + if (_base->traversable()) { // install iterator functions entry.get_iterator = &ClassImpl::getIterator; @@ -1406,10 +1406,10 @@ zend_class_entry *ClassImpl::initialize(ClassBase *base, const std::string &pref // otherwise report an error else std::cerr << "Derived class " << name() << " is initialized before base class " << interface->name() << ": interface is ignored" << std::endl; } - + // we may have to expose the Traversable or Serializable interfaces - if (_base->traversable()) zend_class_implements(_entry, 1, zend_ce_traversable); - if (_base->serializable()) zend_class_implements(_entry, 1, zend_ce_serializable); + if (_base->traversable()) zend_class_implements(_entry, 1, zend_ce_traversable); + if (_base->serializable()) zend_class_implements(_entry, 1, zend_ce_serializable); // this pointer has to be copied to temporary pointer, as &this causes compiler error ClassImpl *impl = this; diff --git a/zend/includes.h b/zend/includes.h index fd914611..182ba923 100644 --- a/zend/includes.h +++ b/zend/includes.h @@ -116,6 +116,7 @@ /** * Specific zend implementation files for internal use only */ +#include "smallvector.h" #include "init.h" #include "callable.h" #include "nativefunction.h" diff --git a/zend/parametersimpl.h b/zend/parametersimpl.h index fa58d9fa..400fec7b 100644 --- a/zend/parametersimpl.h +++ b/zend/parametersimpl.h @@ -29,10 +29,10 @@ class ParametersImpl : public Parameters reserve(argc); // array to store all the arguments in - zval arguments[argc]; + SmallVector arguments{argc}; // retrieve the arguments - zend_get_parameters_array_ex(argc, arguments); + zend_get_parameters_array_ex(argc, &arguments[0]); // loop through the arguments for (uint32_t i=0; i +class SmallVector +{ +private: + std::vector _vector; + TElement *_data; + TElement _buffer[InlineCapacity]; + +public: + SmallVector(uint32_t size) : SmallVector((int) size) {} + SmallVector(int size) + { + if (size > InlineCapacity) + { + _vector.resize(size); + _data = &_vector[0]; + } + else + { + _data = &_buffer[0]; + } + } + + TElement &operator[](int i) + { + return _data[i]; + }; +}; + +} \ No newline at end of file diff --git a/zend/value.cpp b/zend/value.cpp index 5f43dcc1..eabe4d6f 100644 --- a/zend/value.cpp +++ b/zend/value.cpp @@ -763,7 +763,7 @@ static Value do_exec(const zval *object, zval *method, int argc, zval *argv) // remember current state of the PHP engine State state; - + // call the function // we're casting the const away here, object is only const so we can call this method // from const methods after all.. @@ -892,13 +892,13 @@ Value Value::call(const char *name) Value Value::exec(int argc, Value *argv) const { // array of zvals to execute - zval params[argc]; + SmallVector params{argc}; // convert all the values for(int i = 0; i < argc; i++) { params[i] = *argv[i]._val; } // call helper function - return do_exec(nullptr, _val, argc, params); + return do_exec(nullptr, _val, argc, ¶ms[0]); } /** @@ -914,13 +914,13 @@ Value Value::exec(const char *name, int argc, Value *argv) const Value method(name); // array of zvals to execute - zval params[argc]; + SmallVector params{argc}; // convert all the values for(int i = 0; i < argc; i++) { params[i] = *argv[i]._val; } // call helper function - return do_exec(_val, method._val, argc, params); + return do_exec(_val, method._val, argc, ¶ms[0]); } /** @@ -936,13 +936,13 @@ Value Value::exec(const char *name, int argc, Value *argv) Value method(name); // array of zvals to execute - zval params[argc]; + SmallVector params{argc}; // convert all the values for(int i = 0; i < argc; i++) { params[i] = *argv[i]._val; } // call helper function - return do_exec(_val, method._val, argc, params); + return do_exec(_val, method._val, argc, ¶ms[0]); } /**