Experimental: Replace pony_error() with error-flag returns#5002
Experimental: Replace pony_error() with error-flag returns#5002SeanTAllen wants to merge 2 commits intomainfrom
Conversation
Partial functions now return {T, i1} tuples (or i1 for void-returning
class constructors) where the i1 flag indicates whether an error
occurred. This eliminates C++ exception overhead for Pony error
handling while keeping C++ exceptions only for FFI calls where C code
may call pony_error().
The key changes:
- Partial Pony functions return error flags instead of unwinding.
Call sites check the flag and branch to error handlers or propagate.
- Try blocks use a dual mechanism: invoke_target for error-flag
branches from Pony calls, landing_pad for C++ exception unwind
from FFI invoke instructions.
- Bare functions (@{...}) are excluded — they keep pony_error()
semantics since C callers don't understand error flags.
- Vtable consistency: when a non-partial concrete method (e.g.
Cons.head()) shares a vtable index with a partial dispatch method
(e.g. List.head()), a thin wrapper is generated that calls the
concrete method and wraps the result with {value, false}.
- C runtime functions (socket.c, time.c) that previously called
pony_error() now return sentinel values (SIZE_MAX, NULL). The
corresponding Pony callers check for sentinels and raise errors.
Design: #4997
Closes #4443
|
This isnt actually ready for review. I switched it to that to get CI to run. |
With error-flag returns replacing C++ exceptions for Pony-to-Pony error propagation (previous commit), the exception infrastructure is dead code. Removes: pony_error(), pony_try(), ponyint_personality_v0(), LSDA scanning, the except_try_catch.ll LLVM IR, and all landing pad / invoke / personality machinery from codegen. Bare functions that hit `error` outside a try block now call abort() instead of pony_error(). This means bare partial lambdas can no longer propagate errors across C frames — the mechanism they relied on (C++ exceptions) no longer exists. The Pony serialise package is the only stdlib user of this pattern, so it is removed along with its tests. The C-level serialise runtime used internally by the compiler is unaffected. Renames invoke_target to error_target in compile_frame_t to reflect its post-Phase-3 role as a branch target for error-flag checks rather than an invoke unwind destination.
|
Did an ensemble review of this (security, API, performance, correctness — four independent passes). The core codegen is correct across all paths I traced. A few things to address: Partial FFI declarations are silently accepted. The plan called for a compiler error when users write Brace style in
|
| ifdef windows then | ||
| try | ||
| @pony_os_recv( | ||
| let recv_len = @pony_os_recv( |
This is an experimental/draft PR to test CI and enable performance testing. Do not merge.
Implements the error-flag return approach from #4997 (Discussion) to address #4443.
Partial Pony functions now return
{T, i1}tuples instead of using C++ exception unwinding. Thei1flag isfalsefor normal returns andtruefor errors. C++ exceptions are retained only for FFI calls where C runtime code callspony_error().Key implementation details:
{T, i1}(value-returning) ori1(void class constructors). Call sites check the flag and branch to error handlers or propagate.invoke_targetfor error-flag branches from Pony calls;landing_padfor C++ exception unwind from FFI invoke instructions.@{...}bare functions keeppony_error()semantics since C callers don't understand error flags.socket.candtime.cthat calledpony_error()now return sentinel values (SIZE_MAX,NULL). Pony callers check sentinels and raise errors.All 377 stdlib tests pass locally on Linux x86_64. This PR is to verify CI across all platforms and enable performance benchmarking before further work (Phase 4: dead exception infrastructure cleanup).