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)

ClassFileDescription
zpp::*zpp/base.cppAll low level classes in zpp namespace
dump_infozpp/show_zpp.cppDump explict insides of Zend structures
Replacewcc/replace.cppReplace variable names in a string with properties in object
Configwcc/config.cppInstances store dynamic property values
Finderwcc/finder.cppSearch namespace name indexed paths for class source files
Hmapwcc/hmap.cppInstances store properties in an array.
ReflectCachewcc/reflect_cache.cppCreate objects from their reflection class
Serviceswcc/services.cppStore and retrieve callable dynamic properties and objects
ServiceAccesswcc/service_access.cppCached service access by magic __get
Strwcc/strfnsA 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.

ClassFileDescription
ICachewcc/icache.cppBase class for access to data/file cache
ICacheDatawcc/icachedata.cppA managed package of serialized cached data
CacheMgrwcc/cachemgr.cppManaged mamed caches with different properties
GlobalResponsewcc/global_response.cppInterface to setup HTML response and send
Pairwcc/pair.cppHold two properties as "key" and "value"
RequestGlobalswcc/request_globals.cppAccess to the "SuperGlobals" data for HTML
Routewcc/route.cppA URL, verb, and target object - method details
RouteMatchwcc/route_match.cppOne of these to hold reorganised route details for dispatch
RouteSetA collection fixed URL and Regular expression routes to match
TargetA 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.

ClassFileDescription
Assetswcc/assets.cppInsert links, css, javascript, html blobs into views
HtmlGemwcc/htmlgem.cppGenerate various Html elements from array parameters
HtmlPlateswcc/htmlplates.cppOrganise views in layers, from inside to outer
MoneyFmtwcc/money_fmt.cppSimple interface to PHP currency formats.
Platewcc/plate.cppShort for template. Hold location and data for a template
PlateEnginewcc/plate_engine.cppManage templates, their data and cache outputs
SearchListwcc/search_list.cppOrdered list of folders and search for files

wccm (wcc-more.git)

ClassFileDescription
XmlReadwcc/xmlread.cppRead xml format specifying PHP data, objects and arrays
Tomltoml/toml_php.cppA 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}