After testing with Run::construct
The test environment case now encountered is that the Wcc extension is loaded prior to Runsa, and Runsa now accesses the zpp functions only through its header files. This reduces the size of Runsa binary by a lot (to just 48120 bytes), and seems to work. After all, the extension is a shared library. But the test script for new Run($path) runs, but gives an error called double free.
After putting in a debug show statement in the state_init::init() it is obvious is a double assign as well. This is because both extensions call state_init::init_all(). This double inits the FTAB, of which there is only one copy in Wcc, as Runsa, only references the (mangled) C++ function names, in the Wcc shared library, which it is able to call successfully.
Interesting enough, running the Wcc also shows the Run_i static variable which only in the Runsa extension. Maybe no surprise that they are in the same PHP process, and both call the static function state_init::init_all() in the MINIT, and they must needs by sharing the same memory pools from calling malloc and emalloc.
The obvious try to fix is here to remove the MINIT event calls from Runsa, and let the primary big Wcc do it by itself.
After making this change, both extensions now run a simple test script without reporting error.
Sharing the zpp repository
zpp folder is now a submodule of both projects, meaning updating zpp also requires each using repository to update its submodule status. It is almost worth writing a script to do the commit updates for three repositories when zpp gets updated, then recompile both extensions. It's important as sharing headers need to refer to the same functions.
Try a better division of labor
Having proved that a zpp shared extension is possible, maybe it is now time consider a refactor to have the Wcc and Wcd as separate extensions, both dependent on a core Zpp extension, and investigate how this affects peformance.
nm --demangle modules/wcc.so | grep FTAB
00000000001650a0 B zpp::FTAB
PHP extensions share their memory and callable addresses with each other. So I split up a large collection of objects that used zpp arbitrarily into 5 seperate, yet sharing extensions.
To keep both a single source for a combined single extension, and create multiple extensions as parts, skeleton extension folders where created in sibling folders to the main wcc folder. Each included the wcc sources by C++ include path specified in their config.m4 file.
CXXFLAGS="$CXXFLAGS -Wall -O2 --std=c++23 -I./include -I../wcc"
It is only neccessary to include the header files for zpp , and source files for the classes, in the extension source, and one extension contains the source files for zpp. The principle a binary version of a callable function only needs to exist in one extension and be callable from the others.
The build files were put in seperate repositories. The wccz which contains the zpp binaries must always be loaded first. Each extension registers its own classes.
wccz (wcc-zero.git)
| Class | File | Description |
|---|---|---|
| zpp::* | zpp/base.cpp | All low level classes in zpp namespace |
| dump_info | zpp/show_zpp.cpp | Dump explict insides of Zend structures |
| Replace | wcc/replace.cpp | Replace variable names in a string with properties in object |
| Config | wcc/config.cpp | Instances store dynamic property values |
| Finder | wcc/finder.cpp | Search namespace name indexed paths for class source files |
| Hmap | wcc/hmap.cpp | Instances store properties in an array. |
| ReflectCache | wcc/reflect_cache.cpp | Create objects from their reflection class |
| Services | wcc/services.cpp | Store and retrieve callable dynamic properties and objects |
| ServiceAccess | wcc/service_access.cpp | Cached service access by magic __get |
| Str | wcc/strfns | A few utility string static functions |
wccr (wcc-route.git)
These wcc classes also use some of the wcc classes in wccz, as well as zpp, by including their header files.
| Class | File | Description |
|---|---|---|
| ICache | wcc/icache.cpp | Base class for access to data/file cache |
| ICacheData | wcc/icachedata.cpp | A managed package of serialized cached data |
| CacheMgr | wcc/cachemgr.cpp | Managed mamed caches with different properties |
| GlobalResponse | wcc/global_response.cpp | Interface to setup HTML response and send |
| Pair | wcc/pair.cpp | Hold two properties as "key" and "value" |
| RequestGlobals | wcc/request_globals.cpp | Access to the "SuperGlobals" data for HTML |
| Route | wcc/route.cpp | A URL, verb, and target object - method details |
| RouteMatch | wcc/route_match.cpp | One of these to hold reorganised route details for dispatch |
| RouteSet | A collection fixed URL and Regular expression routes to match | |
| Target | A simple 3-tuple of Class name, method name, and module name for a route |
wcch (wcc-html.git)
Generally classes for organising template html views, and generating html elements.
| Class | File | Description |
|---|---|---|
| Assets | wcc/assets.cpp | Insert links, css, javascript, html blobs into views |
| HtmlGem | wcc/htmlgem.cpp | Generate various Html elements from array parameters |
| HtmlPlates | wcc/htmlplates.cpp | Organise views in layers, from inside to outer |
| MoneyFmt | wcc/money_fmt.cpp | Simple interface to PHP currency formats. |
| Plate | wcc/plate.cpp | Short for template. Hold location and data for a template |
| PlateEngine | wcc/plate_engine.cpp | Manage templates, their data and cache outputs |
| SearchList | wcc/search_list.cpp | Ordered list of folders and search for files |
wccm (wcc-more.git)
| Class | File | Description |
|---|---|---|
| XmlRead | wcc/xmlread.cpp | Read xml format specifying PHP data, objects and arrays |
| Toml | toml/toml_php.cpp | A fast toml format reader in C code by https://github.com/cktan/tomlcpp |
The toml read implementation uses source from https://github.com/cktan/tomlc99 - Copyright (c) CK Tan. It is mostly C source code, and its C memory allocator function pointers are switched to using emalloc and efree. This makes its memory C allocations in request memory.
wccd (wcc-database.git)
These may be specified later, theses classes have some complexities, sources in wcd/*.{h, cpp}