Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
a693494
docs: update Java static serializer ownership guidance
chaokunyang Jun 5, 2026
1c84438
optimize compatible read performance
chaokunyang Jun 6, 2026
88b37f2
perf(rust): optimize compatible TypeInfo reads
chaokunyang Jun 6, 2026
49c7ba5
perf(java): use typed compatible scalar reads
chaokunyang Jun 6, 2026
2cca6f6
fix(kotlin): preserve compatible unsigned arrays
chaokunyang Jun 6, 2026
ce93b10
fix(dart): accept compatible manual user fields
chaokunyang Jun 6, 2026
90ace2c
fix(rust): set xlang peer test stack size
chaokunyang Jun 6, 2026
1e0a9b8
perf: optimize compatible reads across runtimes
chaokunyang Jun 6, 2026
718f1a8
bench: add schema mismatch benchmark mode
chaokunyang Jun 6, 2026
d5555c0
style: satisfy format checks
chaokunyang Jun 6, 2026
7971971
fix(java): initialize static compatible readers
chaokunyang Jun 6, 2026
7eb22e5
fix(dart): keep compatible generated arms remote-owned
chaokunyang Jun 6, 2026
66723f3
fix: harden compatible read fast caches
chaokunyang Jun 6, 2026
0922f8c
fix: keep compatible read cold paths noinline
chaokunyang Jun 6, 2026
dcea113
fix: reject incompatible matched fields
chaokunyang Jun 6, 2026
32feec0
fix: hide compatible read internals
chaokunyang Jun 6, 2026
082aaaa
fix: remove compatible read shortcuts
chaokunyang Jun 7, 2026
a4c9654
perf(java): slim compatible scalar generated callsites
chaokunyang Jun 7, 2026
64b1356
test: update compatible mismatch expectations
chaokunyang Jun 7, 2026
4872958
perf: pass descriptors to scalar converters
chaokunyang Jun 7, 2026
1b197a5
perf(js): inline compatible scalar generated reads
chaokunyang Jun 7, 2026
d9d5703
docs: record regenerated compatible scalar owner model
chaokunyang Jun 7, 2026
3a65fcc
fix(js): reject nested scalar compatibility mismatches
chaokunyang Jun 7, 2026
8de8a03
fix(dart): reject nested scalar compatibility conversions
chaokunyang Jun 7, 2026
c0bdb76
perf(java): remove boxed compatible scalar fallback
chaokunyang Jun 7, 2026
587f054
docs: define immediate scalar conversion scope
chaokunyang Jun 7, 2026
1c4cd43
fix(java): keep static records constructor-owned
chaokunyang Jun 7, 2026
0161501
fix(dart): reject nested scalar nullable drift
chaokunyang Jun 7, 2026
ebcee2e
fix: address compatible read CI regressions
chaokunyang Jun 7, 2026
047b435
fix(java): reject matched incompatible compatible fields
chaokunyang Jun 7, 2026
e4f8262
test(java): reject nested compatible schema drift
chaokunyang Jun 7, 2026
829f41b
fix(java): accept fieldless compatible scalar descriptors
chaokunyang Jun 7, 2026
ea22bab
fix(xlang): reject nested compatible schema drift
chaokunyang Jun 7, 2026
7a2c5fc
refactor(java): clarify compatible field info order
chaokunyang Jun 7, 2026
9ecfdf0
fix(java): reject nested compatible schema drift
chaokunyang Jun 7, 2026
2acd43e
refactor(dart): clean generated serializer descriptors
chaokunyang Jun 7, 2026
67a4aff
fix: tighten compatible schema classification
chaokunyang Jun 7, 2026
13a6be6
perf: preclassify compatible scalar reads
chaokunyang Jun 7, 2026
d897caa
perf: preclassify generated scalar reads
chaokunyang Jun 7, 2026
7bd39ec
perf: tighten compatible read classification
chaokunyang Jun 7, 2026
e6d07d0
update AGENTS.md
chaokunyang Jun 7, 2026
e670ed9
test: cover swift encoded exact compatible reads
chaokunyang Jun 7, 2026
f9bb64c
update fieldinfo
chaokunyang Jun 7, 2026
b1e47dc
perf(js): simplify compatible read serializer cache
chaokunyang Jun 7, 2026
20d3ce8
refactor(js): use switch for canonical type ids
chaokunyang Jun 7, 2026
ed00fce
fix(xlang): classify compatible nested schemas
chaokunyang Jun 7, 2026
07f88da
fix(js): reject nested tracking-ref schema drift
chaokunyang Jun 7, 2026
7bcb31e
fix(java): accept nested user-defined xlang fields
chaokunyang Jun 7, 2026
d2222b6
fix(java): preserve static generated read failures
chaokunyang Jun 7, 2026
426606e
fix(js): emit nested ref metadata in idl registrations
chaokunyang Jun 7, 2026
37de5e2
fix(swift): reject nested scalar schema drift
chaokunyang Jun 7, 2026
abdc8dd
fix(swift): align xlang peer generic nullability
chaokunyang Jun 7, 2026
3a51ba6
fix(xlang): allow nullable list schema array reads
chaokunyang Jun 7, 2026
d9e558a
docs(xlang): document nullable list array compatibility
chaokunyang Jun 7, 2026
83eaa15
fix(xlang): repair compatible schema regressions
chaokunyang Jun 7, 2026
17434b5
fix(cpp): restore collection serializer read shape
chaokunyang Jun 7, 2026
a290b88
fix(cpp): remove speculative type meta fast path
chaokunyang Jun 7, 2026
e455e6e
fix(cpp): simplify compatible integer reads
chaokunyang Jun 7, 2026
5ad8758
fix(java): use trusted lookup for generated serializer constructors
chaokunyang Jun 7, 2026
c647c9a
chore(rust): clarify compatible type info schema state
chaokunyang Jun 7, 2026
303dbdb
refactor(rust): remove scalar read action metadata
chaokunyang Jun 7, 2026
44a7896
refactor(go): clarify remote field read actions
chaokunyang Jun 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .agents/languages/cpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Load this file when changing `cpp/`, Cython build plumbing, or C++ xlang behavio
- Put private methods last in class definitions, immediately before private fields.
- Do not redesign alias-based or low-level public type shapes to add convenience methods unless the user explicitly asks for that API change.
- For cross-language feature ports, match protocol behavior but use idiomatic C++ ownership and layering instead of mirroring Java structure literally.
- Compatible scalar, list-array, and binary/uint8-array adaptations are immediate-field-only. Recursive matched-field comparison for collection elements, array elements, map keys, and map values must require exact nullability, ref tracking, generic arity, and type shape except documented user-type family normalization.

## Key Paths

Expand Down
1 change: 1 addition & 0 deletions .agents/languages/csharp.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Load this file when changing `csharp/` or C# xlang behavior.
- C# code must build without compiler or analyzer warnings. Treat warnings as blockers in project, test, and generated code.
- Fory C# requires .NET SDK `8.0+` and C# `12+`.
- Use `dotnet format` to keep C# code style consistent.
- Compatible scalar, list-array, and binary/uint8-array adaptations are immediate-field-only. Recursive matched-field comparison for collection elements, array elements, map keys, and map values must require exact nullability, ref tracking, generic arity, and type shape except documented user-type family normalization.
- When extending C# tests from Java references, prioritize xlang spec behavior and the public C# contract before adding complex Java-specific parity cases.

## Commands
Expand Down
3 changes: 3 additions & 0 deletions .agents/languages/dart.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ Load this file when changing `dart/`.
- Codegen must support private fields through same-library `part` generation. If generated file naming changes from `*.fory.dart`, update builder config, source `part` directives, analysis exclusions, docs, CI snippets, and stale artifacts together.
- Keep generated Dart outputs (`*.fory.dart`) and Dart `pubspec.lock` files untracked in this repo.
- For generated numeric or xlang changes, test root values and generated required/nullable fields across schema-consistent and compatible serializers, metadata type IDs, rejection paths, and every affected encoding mode.
- Compatible scalar conversion is immediate-field-only. Recursive compatible schema comparison for list elements, typed-array elements, map keys, and map values must reject scalar mismatches instead of applying top-level scalar conversion.
- Generated compatible struct reads must consume per-remote-field read descriptors built before field dispatch. Exact doubled cases read directly from local field metadata and must not receive remote compatible metadata; compatible scalar cases use preclassified scalar read descriptors instead of layout-wide scalar source arrays or hot schema/type-pair eligibility helpers.
- Generated struct serializers should use serializer-owned field descriptors for runtime resolver decisions and emit direct field-specific write/read code for static schemas. Do not route generated hot writes through generic field-info value helpers such as `writeGeneratedStructFieldInfoValue`.
- Dart xlang or runtime ownership changes need local Dart package tests plus the Java-driven `DartXlangTest`; package-only smoke tests are not enough.
- When claiming non-VM Dart support, prove a relevant non-VM compile path such as `dart compile js` against active runtime or example code.

Expand Down
13 changes: 10 additions & 3 deletions .agents/languages/java.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ Load this file when changing anything under `java/` or when Java drives a cross-
`ObjectInstantiators.getObjectInstantiator(TypeResolver, Class)` or bypass the runtime-scoped owner; format
builders without a Fory runtime context may use the base `ObjectInstantiators.getObjectInstantiator(Class)`
construction default.
- Compatible scalar, list-array, and binary/uint8 adapters are immediate-field-only. For matched
nested field metadata, classify schema pairs before generated dispatch and require exact
nullable/ref/generic/type shape, except for user-defined type-family normalization.
- Root codegen and builder classes that still need Unsafe on JDK8-24 must route symbolic Unsafe
access through a helper with a Java 25 replacement. Do not leave `_JDKAccess.unsafe()` or
`sun.misc.Unsafe` references in JDK25-visible classes outside matching `java25` replacements.
Expand Down Expand Up @@ -230,9 +233,13 @@ Load this file when changing anything under `java/` or when Java drives a cross-
- Source-generated constructor serializers must own their constructor metadata at generation time
and call constructors directly. They must not depend on runtime `ObjectInstantiator` constructor-field
metadata or varargs constructor calls.
- Java annotation-processor static serializers do not own ordinary-class constructor metadata.
Reject ordinary non-record final fields instead of generating descriptor-based final-field
mutation; records and Kotlin KSP primary-constructor serializers are the constructor-owned paths.
- Java annotation-processor static serializers must support the same Java class surface as normal
Fory object serialization when compatible-read static generation needs it. Ordinary classes that
cannot be assigned directly should allocate through generated-subclass-owned
`ObjectInstantiator` state and write private, inaccessible, or final fields through
generated-subclass-owned cached `FieldAccessor`s. Do not add constructor-binding APIs, per-read
reflective lookup, descriptor-based varargs constructor calls, or shared-parent argument buffers.
Records and Kotlin KSP primary-constructor serializers remain constructor-owned paths.
- Generated JVM copy code may direct-copy immutable scalar values, but Java `Collection`/`Map`
subclasses must be copied through `CopyContext.copyObject(...)` so collection/map serializers own
concrete type, comparator, wrapper, and reference behavior.
Expand Down
3 changes: 3 additions & 0 deletions .agents/languages/javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ Load this file when changing `javascript/`.
- Runtime value carriers such as decimal or reduced-precision numeric types belong under the core `types/` ownership boundary, with imports, exports, and codegen externals updated together.
- Keep `TypeInfo` as schema metadata. Compatibility-sensitive decisions belong on `TypeResolver` or explicit operations, not as retained resolver state on metadata objects.
- Normalize optional boolean config values at config construction; do not carry `null` through runtime paths when it means `false`.
- Regenerated compatible read serializers are remote-schema-specific. After classification marks a field as direct, compatible scalar, or skip, generated JavaScript should emit straight-line remote-field-order code. Do not add an outer matched-id switch unless the current regenerated shape cannot preserve those semantics.
- Compatible scalar codegen must decide the exact remote/local scalar pair before emitting source. Generate the concrete `reader.readXxx()` call plus inline trivial conversions such as boolean-to-string or numeric widening, and keep helpers only for semantic validation such as range checks, exactness checks, decimal parsing/formatting, and string-to-bool. Do not call a generic hot-path converter that redispatches on `remoteTypeId`, `localTypeId`, field descriptors, or field names.
- Compatible scalar conversion is immediate-field-only. Recursive schema comparison for collection elements, array elements, map keys, and map values must reject scalar mismatches instead of applying the top-level scalar conversion matrix.

## Commands

Expand Down
1 change: 1 addition & 0 deletions .agents/languages/python.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Load this file when changing `python/`, Cython serialization, or Python xlang be
- For wheel or extension pipeline changes, derive extension-module paths from current build targets, packaging config, or wheel payload discovery rather than historical module names.
- Keep new Python test names compact and behavior-focused; avoid sentence-length names that restate setup details already obvious from the test body.
- `ENABLE_FORY_DEBUG_OUTPUT=1` enables detailed struct serialization and deserialization logs.
- Compatible scalar, list-array, and binary/uint8-array adaptations are immediate-field-only. Recursive matched-field comparison for collection elements, array elements, map keys, and map values must require exact nullability, ref tracking, generic arity, and type shape except documented user-type family normalization.

## Key Paths

Expand Down
3 changes: 2 additions & 1 deletion .agents/languages/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Load this file when changing `rust/` or Rust xlang behavior.
- Runtime carriers belong in `types/`, and schema or type-hash helpers belong with metadata hashing rather than generic wire/type-id modules.
- If breakage is explicitly acceptable during a Rust module refactor, rewire macros, tests, and sibling crates directly to the new boundaries instead of adding compatibility re-exports.
- For panic-safety in hot paths, preserve TLS context reuse. Add scoped guards or owned fallbacks rather than per-call context allocation, and reset reused contexts at entry and successful exit.
- Compatible scalar, list-array, and binary/uint8-array adaptations are immediate-field-only. Keep recursive matched-field shape classification owned by `fory-core/src/meta/type_meta.rs`; collection elements, array elements, map keys, and map values must require exact nullability, ref tracking, generic arity, and type shape except documented user-type family normalization.

## Key Paths

Expand Down Expand Up @@ -77,5 +78,5 @@ cargo bench
cd java
mvn -T16 install -DskipTests
cd fory-core
RUST_BACKTRACE=1 FORY_PANIC_ON_ERROR=1 FORY_RUST_JAVA_CI=1 ENABLE_FORY_DEBUG_OUTPUT=1 mvn test -Dtest=org.apache.fory.xlang.RustXlangTest
RUST_BACKTRACE=1 FORY_RUST_JAVA_CI=1 ENABLE_FORY_DEBUG_OUTPUT=1 mvn test -Dtest=org.apache.fory.xlang.RustXlangTest
```
1 change: 1 addition & 0 deletions .agents/languages/swift.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Load this file when changing `swift/` or Swift xlang behavior.
- Prefer the user-requested or existing Foundation public value type when it is the intended Swift surface; do not invent Fory-prefixed wrappers only to avoid import ambiguity.
- Preserve distinct temporal semantics. Timestamp values and day-only local dates should have protocol-accurate helper names and no stale aliases after a refactor.
- When temporal or public-type refactors touch generated Swift code, sweep message fields, union payloads, macros, xlang harnesses, and integration fixtures together.
- Compatible scalar, list-array, and binary/uint8-array adaptations are immediate-field-only. Recursive matched-field comparison for collection elements, array elements, map keys, and map values must require exact nullability, ref tracking, generic arity, and type shape except documented user-type family normalization.

## Commands

Expand Down
3 changes: 3 additions & 0 deletions .agents/testing/integration-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ Load this file when changing `integration_tests/`, xlang behavior, compiler-gene
- Run all commands from within `integration_tests/`.
- For Java-related integration tests, install the Java libraries first with `cd ../java && mvn -T16 install -DskipTests` if Java changed. If unsure, run it.
- On macOS, GraalVM is usually installed under `/Library/Java/JavaVirtualMachines/graalvm-xxx`.
- Do not set `FORY_PANIC_ON_ERROR` for normal tests, CI reproduction, or xlang validation. It is
only for focused debugging. Verification commands should omit it, while test harnesses must not
filter it when the user command provides it.
- For `integration_tests/idl_tests`:
- Always run `cd ../java && mvn -T16 install -DskipTests` before the test if Java changed since the last install. If unsure, run it.
- Always run `cd ../python && pip install -v -e .` before the test if Python or Cython code changed. Rebuild Cython if needed.
Expand Down
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ This is the entry point for AI guidance in Apache Fory. Read this file first, th
- Keep class registration enabled unless explicitly requested otherwise.
- Prefer schema-consistent mode unless compatibility work requires something else.
- When debugging test errors, always set `ENABLE_FORY_DEBUG_OUTPUT=1` to see debug output.
- Do not set `FORY_PANIC_ON_ERROR` for normal tests, CI reproduction, or xlang validation.
It is a focused debug knob only; omit it from verification commands, but do not filter it
from test harnesses when the user command provides it.
- Never work around failures. Find and fix the root cause. Do not hack, weaken, or bypass tests to make them pass.

## Source of Truth
Expand Down Expand Up @@ -131,6 +134,7 @@ This is the entry point for AI guidance in Apache Fory. Read this file first, th
## Shared Validation Expectations

- Run the relevant tests for every touched language or subsystem before finishing.
- A formatter-only pass after successful tests does not invalidate those test results. Do not rerun tests solely because formatting ran after the tests already passed.
- When multiple independent language test suites are required, run them concurrently when the environment has enough resources instead of running them one by one; keep each language's logs and results separate, and rerun any failed suite with focused diagnostics.
- Run applicable test commands in a subagent with a thinking budget one level lower than the main task budget, using medium when the current budget is unclear, unless the change is docs-only or the user explicitly asks to run them locally.
- Reuse the same test subagent for repeated runs within one task and subsystem so it keeps failure context; create a fresh subagent when switching unrelated subsystems or when prior context may be stale or misleading.
Expand Down
9 changes: 9 additions & 0 deletions benchmarks/cpp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ Examples:
./run.sh --data struct --serializer fory --duration 5
```

## Schema Mismatch Mode

Set `FORY_BENCH_SCHEMA_MISMATCH=1` to run the Fory-only compatible-read
schema-mismatch mode. This mode is off by default. When enabled, run with
`--serializer fory`; protobuf and MessagePack benchmark modes fail with a
configuration error. Fory serialization uses the normal v1 benchmark structs,
and Fory deserialization uses v2 structs registered with the same Fory type IDs
where one int32 field is widened to int64.

## Building

```bash
Expand Down
Loading
Loading