DEV Community

CrabPascal
CrabPascal

Posted on

Honest Build: No Fake Exception Codegen | Build honesto: sem codegen falso de exceptions

Bilingual post · Post bilíngue

Jump to: English · Português


English {#english}

Honest Build: No Fake Exception Codegen

CrabPascal offers two execution paths: run (internal runtime interpreter) and build-exe (C code generation + native compiler). For a long time, the codegen path pretended to support exceptions — emitting stub blocks that compiled but did not behave like Delphi or like run. v2.21.0 (Sprint 13) ends that charade.

The problem with simulated exceptions

Consider typical Delphi error handling:

try
  ProcessOrder(OrderId);
except
  on E: Exception do
    LogError(E.Message);
end;
Enter fullscreen mode Exit fullscreen mode

In the runtime, try/except unwinds the stack and matches exception types. The old C backend generated placeholder code — enough to pass a compile step, not enough to run correctly. Worse, it hid parity gaps: developers thought native build worked until production crashed differently than run.

That violates a core CrabPascal principle: honest tooling. If we cannot do it correctly yet, say so loudly.

What changed in v2.21.0

The codegen module now refuses to generate C for:

  • try / except / finally blocks
  • raise statements

Instead you get an explicit error pointing to run:

crab-pascal build-exe MyApp.dpr
# error: exception handling not supported in native codegen yet; use `crab-pascal run`
Enter fullscreen mode Exit fullscreen mode

This aligns expectations immediately. CI pipelines fail for the right reason, not silently.

When to use each path

Command Best for
run Development, Horse APIs, OOP with exceptions, rapid iteration
check IDE feedback, CI static analysis
build-exe Performance-sensitive code without exception constructs
crab-pascal check examples/crud/crud.dpr
crab-pascal run examples/crud/crud.dpr
Enter fullscreen mode Exit fullscreen mode

The CRUD example uses JSON and HTTP — exception-free hot paths compile fine with build-exe where supported.

Regression test

Sprint 13 added codegen::tests::test_codegen_errors_on_try_raise, locking the behavior:

// Pseudocode intent: codegen must Err on try/raise, not emit fake C
assert!(codegen_result.is_err());
assert!(message.contains("use `run`"));
Enter fullscreen mode Exit fullscreen mode

Future work on real exception lowering (setjmp/longjmp, table-based handlers, or LLVM) will flip specific tests green — not reintroduce silent stubs.

Roadmap for real native exceptions

Honest failure is step one. Step two is implementing Delphi-compatible exception tables in codegen — likely coordinated with RTL types in System.SysUtils and runtime object layout. Until then, document the split clearly (this article, release notes, check hints).

Developer takeaway

If your project relies on structured exception handling — and most Delphi code does — run is the supported path today. Native build is for subsets of the language where parity is proven. Sprint 13 chose trust over checkbox features. That makes CrabPascal safer to adopt incrementally.

Questions? @crabpascal on Dev.to or issues on Bitbucket.


Português {#portugus}

Build honesto: sem codegen falso de exceptions

O CrabPascal oferece dois caminhos de execução: run (interpretador/runtime interno) e build-exe (geração de C + compilador nativo). Por muito tempo, o codegen fingia suportar exceptions — emitindo blocos stub que compilavam mas não se comportavam como Delphi nem como run. O v2.21.0 (Sprint 13) acaba com essa farsa.

O problema das exceptions simuladas

Considere tratamento de erro típico em Delphi:

try
  ProcessOrder(OrderId);
except
  on E: Exception do
    LogError(E.Message);
end;
Enter fullscreen mode Exit fullscreen mode

No runtime, try/except desempilha a stack e casa tipos de exception. O backend C antigo gerava código placeholder — bastava para passar compilação, não para rodar certo. Pior: escondia gaps de paridade — desenvolvedores achavam que o build nativo funcionava até produção falhar diferente de run.

Isso viola um princípio central do CrabPascal: ferramentas honestas. Se ainda não dá para fazer certo, diga alto.

O que mudou no v2.21.0

O módulo codegen agora recusa gerar C para:

  • blocos try / except / finally
  • instruções raise

Em vez disso, você recebe erro explícito apontando para run:

crab-pascal build-exe MyApp.dpr
# error: exception handling not supported in native codegen yet; use `crab-pascal run`
Enter fullscreen mode Exit fullscreen mode

Expectativas alinhadas na hora. Pipelines CI falham pelo motivo certo, não silenciosamente.

Quando usar cada caminho

Comando Melhor para
run Desenvolvimento, APIs Horse, OOP com exceptions, iteração rápida
check Feedback IDE, análise estática em CI
build-exe Código sensível a performance sem construtos de exception
crab-pascal check examples/crud/crud.dpr
crab-pascal run examples/crud/crud.dpr
Enter fullscreen mode Exit fullscreen mode

O exemplo CRUD usa JSON e HTTP — hot paths sem exception compilam com build-exe onde suportado.

Teste de regressão

O Sprint 13 adicionou codegen::tests::test_codegen_errors_on_try_raise, fixando o comportamento:

// Intenção: codegen deve Err em try/raise, não emitir C falso
assert!(codegen_result.is_err());
assert!(message.contains("use `run`"));
Enter fullscreen mode Exit fullscreen mode

Trabalho futuro em lowering real de exceptions (setjmp/longjmp, handlers tabulares ou LLVM) fará testes específicos passarem — sem reintroduzir stubs silenciosos.

Roadmap para exceptions nativas reais

Falhar honestamente é o passo um. O passo dois é implementar tabelas de exception compatíveis com Delphi no codegen — provavelmente coordenado com tipos RTL em System.SysUtils e layout de objetos no runtime. Até lá, documentar a divisão claramente (este artigo, release notes, hints do check).

Conclusão para desenvolvedores

Se seu projeto depende de exception handling estruturado — e a maioria do código Delphi depende — run é o caminho suportado hoje. Build nativo é para subconjuntos da linguagem onde a paridade está comprovada. O Sprint 13 escolheu confiança em vez de checkbox de feature. Isso torna o CrabPascal mais seguro para adoção incremental.

Dúvidas? @crabpascal no Dev.to ou issues no Bitbucket.


Published on dev.to/@crabpascal · Código em CrabPascal

Top comments (0)