Skip to content

Conversation

@fredriss
Copy link

@fredriss fredriss commented Nov 9, 2021

This PR implements a rough Swift ScriptInterpreter that allows you to extend LLDB in Swift. It leverages the Orc JIT and Swift's C++ interop to achieve this.

There are a number of reasons this is not good enough:

  • The API doesn't feel like a Swift API at all and we'd need to invest into making it nicer. It feels like a lot of this could be done by generating code according to some heuristics (like creating collection properties for all the Get...AtIndex() methods).
  • Outside of purely aesthetic concerns, the API is also harder to use than it should because a bunch of const annotations are missing.
  • The first interaction with the Swift interpreter is unbearably slow (due to building the Clang modules). We'd need to prebuilt these for this solution to be workable.
  • There is a lot of semantics to figure out. For example, in Python command script import literally imports a Python module with its namespacing. This implementation doesn't do this.
  • Last but maybe most importantly, this implementation is very unsafe. Any runtime error (out-of-bound access, unwrapped nil optional, ...) will cause lldb to abort. We need to have a better story for these runtime errors in order to be able to embed Swift as a scripting language.

This uses the JIT to compile swift code on the fly and the Swift C++
interop feature to expose the LLDB SBAPI in the Swift language.
@fredriss
Copy link
Author

fredriss commented Nov 9, 2021

@swift-ci please test

@fredriss fredriss requested a review from lhames November 9, 2021 22:20
@kastiglione
Copy link

Really cool. What, if anything, do you plan to do next?

The API doesn't feel like a Swift API at all and we'd need to invest into making it nicer.

We essentially lose out on the extensions added in the SWIG .i definitions. Not that those would be Swifty either.

I would guess that most C++ interop will require some wrapper code (like overlays?) to expose a conventional Swift API, so this issue doesn't seem specific to this case.

Outside of purely aesthetic concerns, the API is also harder to use than it should because a bunch of const annotations are missing.

Can you give an example?

Last but maybe most importantly, this implementation is very unsafe. Any runtime error (out-of-bound access, unwrapped nil optional, ...)

It seems this could be mostly achieved by the boundary of the Swift wrappers that need to be created. At least for OOB/Optional handling.

@fredriss
Copy link
Author

Really cool. What, if anything, do you plan to do next?

Not necessarily anything. I might play with some Clang tooling to generate some of the wrapper code we talk about below, but from my PoV this was just an experience and I don't plan to personally put in the work to make it production-ready.

The API doesn't feel like a Swift API at all and we'd need to invest into making it nicer.

We essentially lose out on the extensions added in the SWIG .i definitions. Not that those would be Swifty either.

I would guess that most C++ interop will require some wrapper code (like overlays?) to expose a conventional Swift API, so this issue doesn't seem specific to this case.

Correct. I also fee like a lot of this can be autogenerated with a few heuristics.

Outside of purely aesthetic concerns, the API is also harder to use than it should because a bunch of const annotations are missing.

Can you give an example?

The patch has this piece:

    // GetSelectedTarget() is not const and lldb.debugger is immutable so
    // we need to copy it.
    static var target: lldb.SBTarget {
         get { var debugger = debugger; return debugger.GetSelectedTarget() }
    }

Last but maybe most importantly, this implementation is very unsafe. Any runtime error (out-of-bound access, unwrapped nil optional, ...)

It seems this could be mostly achieved by the boundary of the Swift wrappers that need to be created. At least for OOB/Optional handling.

I don't think so, but maybe I'm not understanding what you're saying. There's nothing preventing anyone from doing:

(lldb) script -l swift -- (nil as String?)!

and this will crash LLDB itself. Of course this example is contrived, but you can see how this can happen quite easily in really code (in other words, I'm not that concerned about SB API usage, but about the code wrapping it).

@fredriss
Copy link
Author

@swift-ci test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants