Skip to content

Shadow the object, array, callable and composite types natively - #6503

Merged
ondrejmirtes merged 8 commits into
2.3.xfrom
turbo-type-kernel-objects
Sep 21, 2026
Merged

ondrejmirtes merged 8 commits into
2.3.xfrom
turbo-type-kernel-objects

Conversation

@ondrejmirtes

Copy link
Copy Markdown
Member

Moves the object, array, callable and composite half of the Type kernel into the native extension.

What goes native

  • StaticType, ThisType, GenericStaticType, ObjectWithoutClassType, ObjectShapeType, NonexistentParentClassType. StaticType delegates to its ObjectType through the object's class entry, so the ThisType and GenericStaticType overrides hold.
  • ArrayType and the array accessories NonEmptyArrayType, AccessoryArrayListType, OversizedArrayType, HasOffsetType, HasOffsetValueType. This covers every array operation and template inference. The closures the twins hand to TypeTraverser::map() become a native callback holder running a C body.
  • The string accessories (numeric, non-empty, non-falsy, literal, lowercase, uppercase, decimal-integer), plus HasMethodType and HasPropertyType.
  • ObjectType, GenericObjectType, EnumCaseObjectType. The per-instance memo slots are included, and the bounded static caches are declared as real static properties, because ObjectTypeTest reflects into them. Every $this-> call dispatches through the object's class entry, so the PHP TemplateObjectType and TemplateGenericObjectType overrides keep holding.
  • IterableType, CallableType, ClosureType. The twins' full state lives in declared slots, and the bodies the two callable types share verbatim live once in TypeTraits.cpp.
  • ConstantArrayType, the largest single port, mirrored method by method. It covers shape bookkeeping, optional keys, lists, unsealed shapes, every description form, generalization and toPhpDocNode(). It declares the twin's twelve properties in order, the $optionalKeySet memo included, so its slots are the generated ones.
  • UnionType, BenevolentUnionType, IntersectionType. This covers member operations, normalization, the sorted description, the finite-set memo, and the accessory-aware intersection description. PHP subclasses that override member operations (TemplateUnionType, anonymous test subclasses) are honoured through the object's class entry.

Each family adds its trait registrars to turbo-ext/src/TypeTraits.cpp, one per PHP trait, declared by the twin's signatures.

Tests

turbo-ext/tests/type-family.php gains the subjects of every family, including the PHP subclasses over the native parents and real class reflections. That's about 1.5M observations, compared between the PHP twins and the activated extension by smoke.php.

Verification

On this commit, with the extension loaded and active:

  • side-by-side.php, signature-parity.php and smoke.php pass.
  • make tests, make phpstan, make cs and make lint are clean.
  • A strict clang build and a strict g++-15 build (-Wall -Wextra -Werror) both pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_017MvPby652L7wUqGAHEiEcN

ondrejmirtes and others added 8 commits September 21, 2026 20:49
…e, ObjectShapeType and NonexistentParentClassType natively

StaticType (TypeWithClassName + SubtractableType, delegating to its
ObjectType through the object's class entry so the GenericStaticType and
ThisType overrides hold), its two children, ObjectWithoutClassType,
ObjectShapeType and NonexistentParentClassType. Four more trait
registrars; the twins' closures become Closures over internal holder
classes. The type-family differential gains the object-ish subjects over
real reflections (68k observations). The Windows source list in
config.w32, duplicated by the previous merge, is regenerated from src/.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FSCEwuXjDzsNw2wSNsDW6D
ArrayType (implements Type: key/item types, every array operation,
template inference) and the five array accessories NonEmptyArrayType,
AccessoryArrayListType, OversizedArrayType, HasOffsetType and
HasOffsetValueType (CompoundType + AccessoryType). Six more trait
registrars; a union-typed property builder; the closures the
twins hand to TypeTraverser::map() become an internal NativeCallback
holder running a C body. The type-family differential gains 44 subjects
(246k observations).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FSCEwuXjDzsNw2wSNsDW6D
…natively

AccessoryNumericStringType, AccessoryNonEmptyStringType,
AccessoryNonFalsyStringType, AccessoryLiteralStringType,
AccessoryLowercaseStringType, AccessoryUppercaseStringType,
AccessoryDecimalIntegerStringType, HasMethodType and HasPropertyType
(CompoundType + AccessoryType). The ports that created them through the
class-reference table instantiate them directly now.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FSCEwuXjDzsNw2wSNsDW6D
The core object family: ObjectType (TypeWithClassName + SubtractableType,
with its per-instance memo slots and the bounded static caches declared
as real static properties, since ObjectTypeTest reflects into them), and
its native children GenericObjectType and EnumCaseObjectType. Every
$this-> call dispatches through the object's class entry so the PHP
TemplateObjectType/TemplateGenericObjectType overrides keep holding. The
type-family differential gains 90k observations over real reflections.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FSCEwuXjDzsNw2wSNsDW6D
The callable family: IterableType (CompoundType), CallableType
(CompoundType + CallableParametersAcceptor) and ClosureType
(TypeWithClassName + CallableParametersAcceptor) with the twins' full
state in declared slots. The bodies the two callable types share verbatim
live once in TypeTraits.cpp; the type-family differential gains 46
subjects (110k observations).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FSCEwuXjDzsNw2wSNsDW6D
The array-shape type: key/value/optional-key/next-auto-index bookkeeping,
every array operation with shape precision, isSuperTypeOf/accepts over
optional keys, list handling, unsealed shapes, describe in all forms,
generalize, template inference and toPhpDocNode, mirrored method by
method (the largest single port). The native class declares the twin's
twelve properties in its order, the $optionalKeySet memo included, so
its slots are the generated ones. The type-family differential gains 48
subjects (439k observations).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FSCEwuXjDzsNw2wSNsDW6D
The composite types: UnionType (CompoundType, with its member operations,
normalization, sorted description and finite-set memo), its native child
BenevolentUnionType, and IntersectionType (CompoundType with the
accessory-aware description and array-shape handling). The member
operations the twins express as closures are native ops; PHP subclasses
overriding them (TemplateUnionType, anonymous test subclasses) are
honoured through the object's class entry. The type-family differential
gains 48 subjects (482k observations).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FSCEwuXjDzsNw2wSNsDW6D
@ondrejmirtes
ondrejmirtes merged commit 1227228 into 2.3.x Sep 21, 2026
526 of 530 checks passed
@ondrejmirtes
ondrejmirtes deleted the turbo-type-kernel-objects branch September 21, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant