Stream: cranelift

Topic: How to support meaningful runtime errors with a line number?


view this post on Zulip Shi Yan (Jan 26 2021 at 17:46):

Hello there,

I'm implementing a toy programming language similar to javascript. being dynamically typed means more errors can only be detected during runtime. I want to be able to support meaningful error messages, including line number, token position, call stacks etc. But looking at the jit example, I don't know how this should be implemented.

I have 2 naive ideas. The first is defining a global function in rust and exposing it to my language. The purpose of the function is to report the current line number and token position. When generating the IR code, as soon as line number has changed, I insert a call to the above function to report such change to my runtime. In my runtime, I maintain a storage for these meta data. When an issue happens, I pull and print out the current line number.

But this must be very inefficient.

Another idea I have is when I generate the IR code, if the builder.ins().xxx functions could generate a location id, I can then maintain a mapping from the location id to line number. When IR code fails, I can know the location id and use it to look for the line number? like symbol files.

I'm not sure how this is implemented in a real programming language?

on a side note, I'm also interested in knowing how to implement break point.

view this post on Zulip Benjamin Bouvier (Jan 27 2021 at 17:29):

Hi! There's actually a way to do this more efficiently, as you've guessed. The location id already exists, it's called SourceLoc in Cranelift (you can also grep for srcloc, which is the recurring variable name for those): you basically feed it with an index (which can be an index into a map with more metadata, like token pos, line number; or it can be a straightforward line number, for instance). Then, I don't quite know how it is passed in the JIT crate, but the CodeSink impls get information about source location + the event to which they're associated (trap => trap code, for instance), and when recovering on error, you can map from the trap code offset to the source location. (Since my understanding of the JIT crate is a bit limited, there might be other ways to do this in a simpler way!)

view this post on Zulip bjorn3 (Jan 27 2021 at 17:32):

When using cranelift-module for SourceLoc you will need to access the context after being passed into define_function like so: https://github.com/bjorn3/rustc_codegen_cranelift/blob/ae6daf77ba9762f4f118b2342298ce5fa2e32a7a/src/debuginfo/line_info.rs#L205-L240 For TrapCode the last argument of define_function is an implementor of the TrapSink trait.

Cranelift based backend for rustc. Contribute to bjorn3/rustc_codegen_cranelift development by creating an account on GitHub.

view this post on Zulip Shi Yan (Jan 28 2021 at 18:31):

Thank you very much!


Last updated: Dec 23 2024 at 12:05 UTC