English {#english}
Audit Deep Dive: RTL, Unicode, Properties
Series — Part 2 (Mintlify docs tour): Previous post: Audit Deep Dive: Parser, AST, Semantic (051-audit-parser-ast-semantic). Full audit index: technical-debt/audit-overview.
Helena's audit covers the layer where Delphi semantics meet CrabPascal's runtime: Unicode strings, OO properties, and RTL shims. These are not cosmetic gaps — they determine whether real Delphi libraries compile, run, and behave predictably. The detailed report lives at technical-debt/audit/03-helena-rtl-unicode-properties.
What Helena audited
The review traced four interconnected surfaces:
-
Unicode and strings —
src/pascal_strings.rs,src/stubs.c, and howValue::Stringflows throughsrc/complete_runtime.rs -
Properties —
read_object_property/write_object_property, backing fields, and method-based accessors -
RTL shims — especially
rtl/sys/System.Generics.Collections.pas - Runtime defaults — places where the interpreter returns placeholders instead of failing loudly
This sits downstream of Bruno's parser/semantic audit. Parser correctness means nothing if property getters silently fall back to built-ins.
Confirmed debt items
TD-UNICODE-001 — UTF-16 semantics without full wide buffers (P1)
Delphi string is UTF-16 with 1-based indexing. CrabPascal documents UTF-16 code units in pascal_strings.rs, but Value::String wraps Rust String (UTF-8). Stubs like pascal_strlen_utf16 exist in stubs.c, yet PChar, WideChar, TEncoding, and wide IO are still missing.
Impact: String-heavy code with emoji, combining characters, or interop with external APIs may diverge between run and future native builds.
Suggested sprint: S14 (IO/encoding) or follow-up Unicode work.
TD-RTL-IO-001 — IO and encoding RTL absent (P1)
Horse examples reference TFileStream.Create and file content streams. A search for System.IOUtils, TEncoding, and TFileStream shims under rtl/ found no matching units — blocking real file workflows.
Sprint 14 (v2.22.0) added a minimal System.IOUtils surface; the audit confirms how critical this area is for production adoption.
TD-PROPERTIES-001 — Accessors can fail silently (P1)
When a property declares read GetValue but GetValue is missing or has no body, execute_function may fall through to simulate_function_execution — returning a built-in default instead of a deterministic error.
Impact: Debugging OOP code becomes a guessing game. You think a getter ran; the runtime substituted a placeholder.
TD-PROPERTIES-002 — Codegen properties ≠ runtime properties (P0)
In src/codegen/mod.rs, property declarations generate backing fields and comments for accessors — not executable getter/setter functions. run executes properties correctly; build-exe does not.
This is the same class of parity gap Lucas flagged in the backend audit. Helena kept it here for OO traceability.
TD-GENERICS-001 — Collections without enumerators (P2)
System.Generics.Collections shims expose Add, Get, Count, Delete, Clear, and dictionary lookups — but no enumerator interfaces. for item in List do lacks RTL foundation.
TD-RUNTIME-DEFAULT-002 — Record access returns zero on error (P1)
evaluate_record_access returns Ok(Value::Integer(0)) for unexpected types instead of propagating an error — masking missing fields and metadata bugs.
Coherence observations
Properties do work in the runtime when accessors exist and are implemented. The weakness is twofold: silent fallbacks when they are not, and codegen that never emits real accessor functions.
Unicode is partially modeled — enough for many tutorials, not enough for Delphi parity on IO and pointer types.
What contributors can do now
-
Add a failing fixture for silent property fallback — property with missing
GetValuemust error incheckandrun. -
Expand RTL shims — pick one missing IO type (
TFileStream,TEncoding) and wire shim + intrinsic + test. -
Unicode fixtures — characters outside BMP in
Length,Copy,Pos; comparerunoutput against documented Delphi behavior. -
Track TD IDs in PR descriptions so the backlog in
technical-debt/backlogstays honest.
Reading order in Mintlify
-
technical-debt/audit-overview— executive summary and risk matrix -
technical-debt/audit/03-helena-rtl-unicode-properties— Helena's full table -
roadmap/sprints/sprint-14-review— IOUtils delivery context -
essentials/project-status— current v2.22.0 snapshot
Takeaway
RTL, Unicode, and properties are where Delphi developers feel compatibility. Helena's audit does not say "give up" — it maps exactly which surprises remain and which sprints should close them. Prefer run for OOP with method properties and exceptions until codegen parity catches up.
Next in series: Audit Deep Dive: Tests and Harness (053-audit-tests-harness).
Português {#portugus}
Auditoria: RTL, Unicode, properties
Série — Parte 2 (tour Mintlify): Post anterior: Auditoria: parser, AST, semântica (051-audit-parser-ast-semantic). Índice completo: technical-debt/audit-overview.
A auditoria da Helena cobre a camada onde a semântica Delphi encontra o runtime do CrabPascal: strings Unicode, properties OO e shims RTL. Não são gaps cosméticos — definem se bibliotecas Delphi reais compilam, rodam e se comportam de forma previsível. O relatório detalhado está em technical-debt/audit/03-helena-rtl-unicode-properties.
O que a Helena auditou
A revisão rastreou quatro superfícies interligadas:
-
Unicode e strings —
src/pascal_strings.rs,src/stubs.ce comoValue::Stringflui emsrc/complete_runtime.rs -
Properties —
read_object_property/write_object_property, backing fields e accessors por método -
Shims RTL — especialmente
rtl/sys/System.Generics.Collections.pas - Defaults no runtime — pontos onde o interpretador retorna placeholder em vez de falhar alto
Isso fica downstream da auditoria parser/semântica do Bruno. Parser correto não importa se getters de property caem silenciosamente em built-ins.
Débitos confirmados
TD-UNICODE-001 — Semântica UTF-16 sem buffers wide completos (P1)
string Delphi é UTF-16 com indexação 1-based. CrabPascal documenta code units UTF-16 em pascal_strings.rs, mas Value::String envolve Rust String (UTF-8). Stubs como pascal_strlen_utf16 existem em stubs.c, porém PChar, WideChar, TEncoding e IO wide ainda faltam.
Impacto: Código pesado em strings com emoji, caracteres combinantes ou interop com APIs externas pode divergir entre run e builds nativos futuros.
Sprint sugerida: S14 (IO/encoding) ou trabalho Unicode posterior.
TD-RTL-IO-001 — RTL de IO/encoding ausente (P1)
Exemplos Horse referenciam TFileStream.Create e streams de arquivo. Busca por shims System.IOUtils, TEncoding e TFileStream em rtl/ não encontrou units correspondentes — bloqueando fluxos reais de arquivo.
A Sprint 14 (v2.22.0) adicionou surface mínima de System.IOUtils; a auditoria confirma o quão crítica é essa área para adoção em produção.
TD-PROPERTIES-001 — Accessors podem falhar silenciosamente (P1)
Quando uma property declara read GetValue mas GetValue está ausente ou sem corpo, execute_function pode cair em simulate_function_execution — retornando default built-in em vez de erro determinístico.
Impacto: Debug de código OOP vira adivinhação. Você acha que o getter rodou; o runtime substituiu por placeholder.
TD-PROPERTIES-002 — Codegen de properties ≠ runtime (P0)
Em src/codegen/mod.rs, declarações de property geram backing fields e comentários para accessors — não funções getter/setter executáveis. run executa properties corretamente; build-exe não.
Mesma classe de gap de paridade que o Lucas sinalizou na auditoria de backend. Helena manteve aqui para rastreabilidade OO.
TD-GENERICS-001 — Collections sem enumerators (P2)
Shims de System.Generics.Collections expõem Add, Get, Count, Delete, Clear e lookups de dictionary — mas sem interfaces de enumerator. for item in List do não tem base RTL.
TD-RUNTIME-DEFAULT-002 — Acesso a record retorna zero em erro (P1)
evaluate_record_access retorna Ok(Value::Integer(0)) para tipos inesperados em vez de propagar erro — mascarando campos faltantes e bugs de metadados.
Observações de coerência
Properties funcionam no runtime quando accessors existem e estão implementados. A fraqueza é dupla: fallbacks silenciosos quando não estão, e codegen que nunca emite funções de accessor reais.
Unicode está parcialmente modelado — suficiente para muitos tutoriais, insuficiente para paridade Delphi em IO e tipos ponteiro.
O que contribuidores podem fazer agora
-
Adicionar fixture que falha para fallback silencioso de property — property com
GetValueausente deve dar erro emcheckerun. -
Expandir shims RTL — escolher um tipo IO faltante (
TFileStream,TEncoding) e ligar shim + intrinsic + teste. -
Fixtures Unicode — caracteres fora do BMP em
Length,Copy,Pos; comparar saída deruncom comportamento Delphi documentado. -
Rastrear IDs TD nas descrições de PR para o backlog em
technical-debt/backlogpermanecer honesto.
Ordem de leitura no Mintlify
-
technical-debt/audit-overview— sumário executivo e matriz de risco -
technical-debt/audit/03-helena-rtl-unicode-properties— tabela completa da Helena -
roadmap/sprints/sprint-14-review— contexto da entrega IOUtils -
essentials/project-status— snapshot atual v2.22.0
Conclusão
RTL, Unicode e properties são onde desenvolvedores Delphi sentem compatibilidade. A auditoria da Helena não diz "desista" — mapeia exatamente quais surpresas restam e quais sprints devem fechá-las. Prefira run para OOP com properties por método e exceptions até a paridade de codegen alcançar.
Próximo na série: Auditoria: testes e harness (053-audit-tests-harness).
Published on dev.to/@crabpascal · Código em CrabPascal
Top comments (0)