Skip to content

Fix #199: Register generated formatters without relying on [MRubyObject] attribute instances - #200

Closed
hadashiA wants to merge 1 commit into
mainfrom
claude/fix-199-preserve-attribute-stripping
Closed

Fix #199: Register generated formatters without relying on [MRubyObject] attribute instances#200
hadashiA wants to merge 1 commit into
mainfrom
claude/fix-199-preserve-attribute-stripping

Conversation

@hadashiA

@hadashiA hadashiA commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes #199.

Unity 6000.5's UnityLinker unconditionally removes custom attribute instances of PreserveAttribute and anything inheriting from it (matched by name, walking base types). Since MRubyObjectAttribute : PreserveAttribute, the [MRubyObject] instances disappear from stripped assemblies, and the runtime gate in GeneratedResolver.TryInvokeRegisterFormatter (GetCustomAttribute<MRubyObjectAttribute>() == null) made every registration fail on Unity 6000.5 IL2CPP builds — every Deserialize<T> then threw MRubySerializationException.

This takes suggested fix (1) from the issue: drop the attribute gate and rely on the __RegisterMRubyValueFormatter method lookup alone. Only generated types have that method, and it survives stripping thanks to its own [Preserve], so it is a sufficient and stripping-proof signal.

The PreserveAttribute inheritance on MRubyObjectAttribute is kept as-is: per the issue's analysis, 6000.5 still honors the preserve semantics (annotated types/members are kept); only the runtime-visible attribute instance is removed, and nothing else reads it at runtime anymore.

Test

Added RegisterFormatterWithoutAttributeInstance, using a hand-written type that mimics a generated type after attribute stripping (has __RegisterMRubyValueFormatter, lacks [MRubyObject]). Verified it fails against the previous resolver and passes with this change; all 22 serializer tests pass.

🤖 Generated with Claude Code

Unity 6000.5's linker unconditionally strips attribute instances of
PreserveAttribute-derived attributes from player builds, so
type.GetCustomAttribute<MRubyObjectAttribute>() returns null for
generated types on IL2CPP builds and no formatter was ever registered.

The __RegisterMRubyValueFormatter method lookup alone is a sufficient
and stripping-proof signal, since only generated types have that method.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

[MRubyObject] instances are stripped by Unity 6000.5's linker (PreserveAttribute inheritance), breaking GeneratedResolver registration in IL2CPP builds

1 participant