DEV Community

CrabPascal
CrabPascal

Posted on

Audit Deep Dive: RTL, Unicode, Properties | Auditoria: RTL, Unicode, properties

Bilingual post · Post bilíngue

Jump to: English · Português


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 stringssrc/pascal_strings.rs, src/stubs.c, and how Value::String flows through src/complete_runtime.rs
  • Propertiesread_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

  1. Add a failing fixture for silent property fallback — property with missing GetValue must error in check and run.
  2. Expand RTL shims — pick one missing IO type (TFileStream, TEncoding) and wire shim + intrinsic + test.
  3. Unicode fixtures — characters outside BMP in Length, Copy, Pos; compare run output against documented Delphi behavior.
  4. Track TD IDs in PR descriptions so the backlog in technical-debt/backlog stays honest.

Reading order in Mintlify

  1. technical-debt/audit-overview — executive summary and risk matrix
  2. technical-debt/audit/03-helena-rtl-unicode-properties — Helena's full table
  3. roadmap/sprints/sprint-14-review — IOUtils delivery context
  4. 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 stringssrc/pascal_strings.rs, src/stubs.c e como Value::String flui em src/complete_runtime.rs
  • Propertiesread_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

  1. Adicionar fixture que falha para fallback silencioso de property — property com GetValue ausente deve dar erro em check e run.
  2. Expandir shims RTL — escolher um tipo IO faltante (TFileStream, TEncoding) e ligar shim + intrinsic + teste.
  3. Fixtures Unicode — caracteres fora do BMP em Length, Copy, Pos; comparar saída de run com comportamento Delphi documentado.
  4. Rastrear IDs TD nas descrições de PR para o backlog em technical-debt/backlog permanecer honesto.

Ordem de leitura no Mintlify

  1. technical-debt/audit-overview — sumário executivo e matriz de risco
  2. technical-debt/audit/03-helena-rtl-unicode-properties — tabela completa da Helena
  3. roadmap/sprints/sprint-14-review — contexto da entrega IOUtils
  4. 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)