Thanks to visit codestin.com
Credit goes to github.com

Skip to content

What if we get rid of NLR stuff? #1245

Closed
@pfalcon

Description

@pfalcon

Exceptions are weird implementation-wise. Go and Rust folks hate them and go out of their way to force people to not use for a reason. The best architecture for handling exceptions is with single accumulator where all data is stored in memory (essentially, volatile). Alas, to get any performance, you need bunch of registers. But then you need to save and restore them properly on exceptions (also on interrupts, task switching, etc.), and that gets boring. With naive scheme like we have, it takes to save "all" registers, and cost to pay is bloated stack. With smarter runtime, the cost is less stack and them more complicated stack layouts, unwind procedure, and potentially performance.

Rust bans runtime exceptions, but at least tries to offer some macros to a similar effect (as they say, if someone trusts them). But with Go, it's just "if" ladders, or, well, exercises in creativity https://blog.golang.org/errors-are-values trying to emulate in runtime what decent exception-handling compiler does behind the scene.

So, what if, what if we rewrite uPy Go-style - with explicit, manual exception propagation instead of NLR? That would save us some stack. VM and bytecode already works like that, the crucial point lies in fun_bc_call() which converts status to an exception. Then we can skip raising an exception (note that stackless does that automagically), and NLR-wrap only calls to native functions. But next step is to question whether we need to raise exceptions in native functions either. Most cases are simple, and we can return status instead. Few other cases could be dealt with Go-style. So, @dpgeorge, are there any remaining cases where handling error propagation would be cumbersome?

Last issue with that is the fact that both Go and Rust requires return pair of values - error/success status and actual value. Well, we kinda do the same, but pass one of values by pointer, which is of course not ideal. Return a struct of 2 words or manually constructed int64_t would work with decent compiler but not ideal either. Well, taking into account that in Python only Exception subclasses can be raised, we can introduce a flag to differentiate exception-as-value and exception-as-raised, and then return just a single value, in register.

Metadata

Metadata

Assignees

No one assigned

    Labels

    rfcRequest for Comment

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions