-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[clang-repl] Reimplement value printing using MemoryAccess to support in-process and out-of-process #156649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@vgvassilev This is still a draft — some parts are not implemented yet (e.g. record and function types), but I shared it so you can see the idea and check if the approach looks feasible. |
And also I need a way to detect whether the interpreter is running in-process or out-of-process. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we have to cast the data when we know its type? If that's needed for out-of-process where the host and target architectures do not match, we should probably somehow do it in a separate facility because getX
is much faster on matching architectures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m working on a new design inspired by clang::APValue
, intended to replace Value
so it can support both execution environments:https://gist.github.com/SahilPatidar/9ba885fb29aebc68b6cf788b8937a204
33a530c
to
a5d7d9e
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
@vgvassilev Introduce new Value class design inspired by APValue. This design also supports array element access via index. Currently, only record types trigger issues during AST conversion of |
Added |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This header is intended to be used at Interpreter's runtime and it needs to be quick to include. Can we achieve the same goals with less tokens here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed two headers, but ExecutorAddr
is still directly used by ValueCleanup
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any chance to rely on forward declarations and move everything out of line?
… in-process and out-of-process
f3cd017
to
e56b4f3
Compare
@vgvassilev Since I don’t have much experience with AST conversion, I’m not very confident about the |
class Value; | ||
|
||
/// \struct ValueCleanup | ||
/// \brief Encapsulates destructor invocation for REPL values. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The destructor calls are currently handled by CompileDtorCall
and then called subsequently when the refcount of the Value goes to zero provided it contained a non-trivial type. Is that not sufficient?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To support this both out-of-process and in-process, we need to call the destructor using the ORC callWrapper
. We can obtain the address of the destructor, but it must be invoked in a way that works consistently across different execution environments.
Currently, ValueCleanup
only applies to Record
-type PRValues. In the previous design, calling the destructor in-process was straightforward, but it’s unclear how that would work out-of-process. The old design allocated memory directly on the Value
(controller) side, which isn’t possible in an OOP context, and the same limitation applies to arrays.
Here, ValueCleanup
does two things. First, it uses a runtime call via the rundtor
wrapper function, which handles destructor calls. We have the *_destroyObj
call that deallocates memory in both environments. Second, it makes the individual destructor call for the object: we obtain the destructor’s address using CompileDtorCall
and pass Value::getAddr
(the object’s address), similar to how we previously used Value::getPtr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can move ValueResultManager
elsewhere since it’s related to interpreter functionality, but we still need a similar solution to what ValueCleanup
provides. ValueCleanup
is essentially just a wrapper around the old approach: previously we made direct calls, but now we use orc::Wrapper
calls.
Reimplement value printing on top of ORC MemoryAccess. The previous
implementation only supported in-process evaluation; with this new
design it now works in both in-process and out-of-process modes.
The implementation introduces a new
Value
class design inspired byAPValue
(This design also supports array element access via index) for capturing evaluated
values, a ReaderDispatcher for reading values from MemoryAccess, and a
ValueToString
printer for converting buffers back to strings.