I'm trying to call a method on an object from inside my compiled llvm JIT code.
I've read the answer here ( Can I bind an existing method to a LLVM Function* and use it from JIT-compiled code? ) but my case is slightly different, as my method requires an argument.
If I'm understanding everything correctly, I need to wrap my method with a function, but how can I store the pointer to my instance to use as the first argument when calling?
Here's a short example (omited some irrelevant parts)
class Foo:
{
public:
Foo();
float getValue(char * name);
};
float fooWrap(Foo *foo, char * name)
{
foo->getValue(name);
}
Foo::Foo()
{
// snipped llvm init stuff
std::vector<llvm::Type*> fun_args;
fun_args.push_back(llvm::Type::getInt8Ty(context)); // Pointer to this instance (pretty sure is wrong)
fun_args.push_back(llvm::Type::getInt8PtrTy(context)); // char array *
llvm::FunctionType *FT = llvm::FunctionType::get(llvm::Type::getFloatTy(context), fun_args, false);
llvm::Function * F = llvm::Function::Create(FT, llvm::Function::ExternalLinkage, "foo", module);
engine->addGlobalMapping(F, &fooWrap);
// later
llvm::Value *instance = llvm::ConstantInt::get(context, llvm::APInt((intptr_t) &this)); // wont compile, can't construct APInt from intptr_t
std::vector<llvm::Value*> args;
args.push_back(instance);
args.push_back(builder.CreateGlobalStringPtr("test"));
builder.CreateCall(F, args);
}
Any help would be greatly appreciated.
The argument type ended up being:
llvm::Type::getIntNTy(context, sizeof(uintptr_t)*8)
And the value was set with:
llvm::Value *instance = llvm::ConstantInt::get(llvm::Type::getIntNTy(context, sizeof(uintptr_t)*8), (uintptr_t) this);
This ensured that the pointer size was always correct for the compiled platform.
Seems to me like your question can be summed up by:
How to convert some object pointer in my code to an LLVM Value?
And your approach is correct - create a constant int with the value of the pointer as casted to an integer. Your error is just an incorrect usage of APInt's constructor - and in fact you don't need an APInt to start with, you can just do ConstantInt::get(context, (uintptr_t)this) (which works by constructing an APInt itself, as you can see in its implementation).
Related
The Goal:
decide during runtime which templated function to use and then use it later without needing the type information.
A Partial Solution:
for functions where the parameter itself is not templated we can do:
int (*func_ptr)(void*) = &my_templated_func<type_a,type_b>;
this line of code can be modified for use in an if statement with different types for type_a and type_b thus giving us a templated function whose types are determined during runtime:
int (*func_ptr)(void*) = NULL;
if (/* case 1*/)
func_ptr = &my_templated_func<int, float>;
else
func_ptr = &my_templated_func<float, float>;
The Remaining Problem:
How do I do this when the parameter is a templated pointer?
for example, this is something along the lines of what I would like to do:
int (*func_ptr)(templated_struct<type_a,type_b>*); // This won't work cause I don't know type_a or type_b yet
if (/* case 1 */) {
func_ptr = &my_templated_func<int,float>;
arg = calloc(sizeof(templated_struct<int,float>, 1);
}
else {
func_ptr = &my_templated_func<float,float>;
arg = calloc(sizeof(templated_struct<float,float>, 1);
}
func_ptr(arg);
except I would like type_a, and type_b to be determined during runtime. I see to parts to the problem.
What is the function pointers type?
How do I call this function?
I think I have the answer for (2): simply cast the parameter to void* and the template function should do an implicit cast using the function definition (lease correct me if this won't work as I think it will).
(1) is where I am getting stuck since the function pointer must include the parameter types. This is different from the partial solution because for the function pointer definition we were able to "ignore" the template aspect of the function since all we really need is the address of the function.
Alternatively there might be a much better way to accomplish my goal and if so I am all ears.
Thanks to the answer by #Jeffrey I was able to come up with this short example of what I am trying to accomplish:
template <typename A, typename B>
struct args_st {
A argA;
B argB;
}
template<typename A, typename B>
void f(struct args_st<A,B> *args) {}
template<typename A, typename B>
void g(struct args_st<A,B> *args) {}
int someFunction() {
void *args;
// someType needs to know that an args_st struct is going to be passed
// in but doesn't need to know the type of A or B those are compiled
// into the function and with this code, A and B are guaranteed to match
// between the function and argument.
someType func_ptr;
if (/* some runtime condition */) {
args = calloc(sizeof(struct args_st<int,float>), 1);
f((struct args_st<int,float> *) args); // this works
func_ptr = &g<int,float>; // func_ptr should know that it takes an argument of struct args_st<int,float>
}
else {
args = calloc(sizeof(struct args_st<float,float>), 1);
f((struct args_st<float,float> *) args); // this also works
func_ptr = &g<float,float>; // func_ptr should know that it takes an argument of struct args_st<float,float>
}
/* other code that does stuff with args */
// note that I could do another if statement here to decide which
// version of g to use (like I did for f) I am just trying to figure out
// a way to avoid that because the if statement could have a lot of
// different cases similarly I would like to be able to just write one
// line of code that calls f because that could eliminate many lines of
// (sort of) duplicate code
func_ptr(args);
return 0; // Arbitrary value
}
Can't you use a std::function, and use lambdas to capture everything you need? It doesn't appear that your functions take parameters, so this would work.
ie
std::function<void()> callIt;
if(/*case 1*/)
{
callIt = [](){ myTemplatedFunction<int, int>(); }
}
else
{
callIt = []() {myTemplatedFunction<float, float>(); }
}
callIt();
If I understand correctly, What you want to do boils down to:
template<typename T>
void f(T)
{
}
int somewhere()
{
someType func_ptr;
int arg = 0;
if (/* something known at runtime */)
{
func_ptr = &f<float>;
}
else
{
func_ptr = &f<int>;
}
func_ptr(arg);
}
You cannot do that in C++. C++ is statically typed, the template types are all resolved at compile time. If a construct allowed you to do this, the compiler could not know which templates must be instanciated with which types.
The alternatives are:
inheritance for runtime polymorphism
C-style void* everywhere if you want to deal yourself with the underlying types
Edit:
Reading the edited question:
func_ptr should know that it takes an argument of struct args_st<float,float>
func_ptr should know that it takes an argument of struct args_st<int,float>
Those are incompatible. The way this is done in C++ is by typing func_ptr accordingly to the types it takes. It cannot be both/all/any.
If there existed a type for func_ptr so that it could take arguments of arbitrary types, then you could pass it around between functions and compilation units and your language would suddenly not be statically typed. You'd end up with Python ;-p
Maybe you want something like this:
#include <iostream>
template <typename T>
void foo(const T& t) {
std::cout << "foo";
}
template <typename T>
void bar(const T& t) {
std::cout << "bar";
}
template <typename T>
using f_ptr = void (*)(const T&);
int main() {
f_ptr<int> a = &bar<int>;
f_ptr<double> b = &foo<double>;
a(1);
b(4.2);
}
Functions taking different parameters are of different type, hence you cannot have a f_ptr<int> point to bar<double>. Otherwise, functions you get from instantiating a function template can be stored in function pointers just like other functions, eg you can have a f_ptr<int> holding either &foo<int> or &bar<int>.
Disclaimer: I have already provided an answer that directly addresses the question. In this answer, I would like to side-step the question and render it moot.
As a rule of thumb, the following code structure is an inferior design in most procedural languages (not just C++).
if ( conditionA ) {
// Do task 1A
}
else {
// Do task 1B
}
// Do common tasks
if ( conditionA ) {
// Do task 2A
}
else {
// Do task 2B
}
You seem to have recognized the drawbacks in this design, as you are trying to eliminate the need for a second if-else in someFunction(). However, your solution is not as clean as it could be.
It is usually better (for code readability and maintainability) to move the common tasks to a separate function, rather than trying to do everything in one function. This gives a code structure more like the following, where the common tasks have been moved to the function foo().
if ( conditionA ) {
// Do task 1A
foo( /* arguments might be needed */ );
// Do task 2A
}
else {
// Do task 1B
foo( /* arguments might be needed */ );
// Do task 2B
}
As a demonstration of the utility of this rule of thumb, let's apply it to someFunction(). ... and eliminate the need for dynamic memory allocation ... and a bit of cleanup ... unfortunately, addressing that nasty void* is out-of-scope ... I'll leave it up to the reader to evaluate the end result. The one feature I will point out is that there is no longer a reason to consider storing a "generic templated function pointer", rendering the asked question moot.
// Ideally, the parameter's type would not be `void*`.
// I leave that for a future refinement.
void foo(void * args) {
/* other code that does stuff with args */
}
int someFunction(bool condition) {
if (/* some runtime condition */) {
args_st<int,float> args;
foo(&args);
f(&args); // Next step: pass by reference instead of passing a pointer
}
else {
args_st<float,float> args;
foo(&args);
f(&args); // Next step: pass by reference instead of passing a pointer
}
return 0;
}
Your choice of manual memory management and over-use of the keyword struct suggests you come from a C background and have not yet really converted to C++ programming. As a result, there are many areas for improvement, and you might find that your current approach should be tossed. However, that is a future step. There is a learning process involved, and incremental improvements to your current code is one way to get there.
First, I'd like to get rid of the C-style memory management. Most of the time, using calloc in C++ code is wrong. Let's replace the raw pointer with a smart pointer. A shared_ptr looks like it will help the process along.
// Instead of a raw pointer to void, use a smart pointer to void.
std::shared_ptr<void> args;
// Use C++ memory management, not calloc.
args = std::make_shared<args_st<int,float>>();
// or
args = std::make_shared<args_st<float,float>>();
This is still not great, as it still uses a pointer to void, which is rarely needed in C++ code unless interfacing with a library written in C. It is, though, an improvement. One side effect of using a pointer to void is the need for casts to get back to the original type. This should be avoided. I can address this in your code by defining correctly-typed variables inside the if statement. The args variable will still be used to hold your pointer once the correctly-typed variables go out of scope.
More improvements along this vein can come later.
The key improvement I would make is to use the functional std::function instead of a function pointer. A std::function is a generalization of a function pointer, able to do more albeit with more overhead. The overhead is warranted here in the interest of robust code.
An advantage of std::function is that the parameter to g() does not need to be known by the code that invokes the std::function. The old style of doing this was std::bind, but lambdas provide a more readable approach. Not only do you not have to worry about the type of args when it comes time to call your function, you don't even need to worry about args.
int someFunction() {
// Use a smart pointer so you do not have to worry about releasing the memory.
std::shared_ptr<void> args;
// Use a functional as a more convenient alternative to a function pointer.
// Note the lack of parameters (nothing inside the parentheses).
std::function<void()> func;
if ( /* some runtime condition */ ) {
// Start with a pointer to something other than void.
auto real_args = std::make_shared<args_st<int,float>>();
// An immediate function call:
f(real_args.get());
// Choosing a function to be called later:
// Note that this captures a pointer to the data, not a copy of the data.
// Hence changes to the data will be reflected when this is invoked.
func = [real_args]() { g(real_args.get()); };
// It's only here, as real_args is about to go out of scope, where
// we lose the type information.
args = real_args;
}
else {
// Similar to the above, so I'll reduce the commentary.
auto real_args = std::make_shared<args_st<float,float>>();
func = [real_args]() { g(real_args.get()); };
args = real_args;
}
/* other code that does stuff with args */
/* This code is probably poor C++ style, but that can be addressed later. */
// Invoke the function.
func();
return 0;
}
Your next step probably should be to do some reading on these features so you understand what this code does. Then you should be in a better position to leverage the power of C++.
The below given code is taken from LevelDB. I am giving two blocks of code for better understanding. I am unable to understand what is happening.
ThreadState is a structure and I have written here to make it easy for the reader.
struct ThreadState {
int tid; // 0..n-1 when running in n threads
Random rand; // Has different seeds for different threads
Stats stats;
SharedState* shared;
ThreadState(int index)
: tid(index),
rand(1000 + index) {
}
};
Is the marked code below an object instantiation of class Benchmark? What is happening in the marked code below?
void Run() {
PrintHeader();
Open();
const char* benchmarks = FLAGS_benchmarks;
while (benchmarks != NULL) {
{
//code ommitted
}
// Reset parameters that may be overriddden bwlow
***void (Benchmark::*method)(ThreadState*) = NULL;*** // What does this code line mean? // Benchmark is a class.
bool fresh_db = false;
int num_threads = FLAGS_threads;
if (name == Slice("fillseq")) {
fresh_db = true;
method = &Benchmark::WriteSeq;
}
If required, I can give detailed implementation of Benchmark as well.
Thanks a lot for the help!
void (Benchmark::*method)(ThreadState*) = NULL;
// What does this code line mean?
// Benchmark is a class.
The above is a pointer to a member function. Since member functions are not like regular functions (they can only be called on a valid object), you cannot take their address it the same way you would for a free function.
Therefore the above syntax is introduced. It is similar to a regular function pointer except the class specifier Benchmark::. This is essentially the type of the implicit this pointer.
In your case, method is a pointer to a member function that takes ThreadState* as a parameter, and has a void return type. The reason for using it is most probably to simplify the call. First, and based on various parameters, a member function is chosen to be called, and its "address" stored in method. After all the checks are done, there is only a single call to the chosen function via the pointer to member.
Incidentally, &Benchmark::WriteSeq is how the code obtains the "address" of the member function WriteSeq. You must use the address-of operator on the qualified function name.
I have a structure and it has a pointer to function as follows.
typedef struct
{
void (*p)();
int n;
} myStruct;
I used it as folllowing:
myStruct * a = malloc( sizeof(myStruct));
a->n=88;
a->p = &booooo;
a->p()
In LLVM, How can I get the name of function (booooo) and struct element (a->p) to save it in symbol table and print it later.
I could find the name of the function in StoreInst.
When I print its value I got this result:
void (...)* bitcast (void ()* #booooo to void (...)*)
How can I get only the name (booooo) from the value.
There are (at least) two kinds of casts in LLVM IR: BitCastInst and bitcast values. You have the later. Fortunately, there is a method for retrieving the original value within the bitcast: stripPointerCasts(). It took me sometime to figure out this distinction.
Here is my usage of the routine, where I was trying to identify the function called (BasicBlock::iterator I):
if (CallInst *ci = dyn_cast<CallInst>(&*I)) {
Function *f = ci->getCalledFunction();
if (f == NULL)
{
Value* v = ci->getCalledValue();
f = dyn_cast<Function>(v->stripPointerCasts());
if (f == NULL)
{
continue;
}
}
const char* fname = f->getName().data();
As explained in the previous question asking the same thing [marginally different], you are better off using the AST form that the Clang compiler produces, rather than the LLVM IR form. It is a much more direct representation of the C or C++ code than the LLVM IR, and easier to work with in general.
But from the StoreInst you can use getValueOperand to get the value that is being stored, and then getName of the value. Of course, like I also said in comments the previous answer, it's not very hard to make the code hard to derive what the original value stored was.
In otherwords, if we have an llvm::Instruction *inst, we could do this:
if (llvm::StoreInst* si = llvm::dyn_cast<llvm::StoreInst>(inst))
{
std::string name = si->getValueOperand()->getName();
}
[Code is not tested, not compiled, no guarantee provided, I just wrote it as part of this answer with the intention that it may work]
I need a help on converting some Objective C "code block" methods to the equivalent in C++.
Please advise.
A is being used as code block...
Defined in .h file..
typedef void (^A)(void*); //argument is ptr to B
Used in one .mm file..
[[hello getInstance] getB]->queueLoadImageWithBlock([self.str UTF8String], (A
)^(void* img)
{
//some code...
});
The most direct analogy is std::function. This is a value type that is given a signature (e.g. std::function<int(int)> and can be any function object of the appropriate signature. A lambda can be used in place of the block at the call site.
obj->queueLoadImageWithBlock(self.url, [](void* img)
{
UIImage* img2 = (UIImage*)img;
UIImageView* iv = [[UIImageView alloc] initWithImage:img2];
iv.backgroundColor = [UIColor clearColor];
[self.iconSlot addSubview:iv];
iconLoaded(iv);
[iv release];
});
With Apple's version of clang you can use blocks in C and C++ as well as Objective-C. This is non-standard C++, obviously, but it works.
You can use C++ lambdas without changing the called function since lambdas are assignable to blocks (but not the other way around). See this question for more information.
As long as the requirement for a block is yours as opposed to system.
Like I said, there are several approaches. The function pointers require the least boilerplate, but they need an extra argument to pass the context from the caller (the self stuff in your case). Functors and pointer-to-members typically require template machinery to work, let's not go there. So with a function pointer, here's how it would go:
//Let's define a callback datatype
typedef void (*ResourceLoadObjFuncPtr)(void *, void*);
//argument 1 is ptr to ResourceLoadDescriptor, argument 2 is iconSlot, whatever it is
//Function that implements that type:
void MyLoad(void *img, void *iconSlot)
{
UIImage* img2 = (UIImage*)img;
UIImageView* iv = [[UIImageView alloc] initWithImage:img2];
iv.backgroundColor = [UIColor clearColor];
[(TheTypeOfIconslot*)iconSlot addSubview:iv];
iconLoaded(iv);
[iv release];
}
And you'd have to modify the prototype of queueLoadImageWithBlock to accept a ResourceLoadObjFuncPtr parameter instead of ResourceLoadObjCBlockCB, and another parameter for the context (just the iconSlot in our case).
And invoke:
[[GameViewController getInstance] getResourceLoadMediator]->
queueLoadImageWithFunction([self.url UTF8String], MyLoad, self.iconSlot);
Blocks are closures - they capture the variables of the function where they're declared. C++ provides no closures that GCC on iOS supports (other than, well, blocks). So you'd have to pass the variables from the function scope to the function parameter by hand. In our case, if my assumptions are right, there's just one variable; in a more complex case, you'd have to wrap them in a structure and pass a pointer to one.
An alternative to that would be using an abstract base class and a concrete implementation that captures the context via its constructor. This would go like this:
//Callback type
class ResourceLoader
{
public:
virtual void Load(void *) = 0;
};
//A callback implementation - not a function, but a class
class MyResourceLoader : public ResourceLoader
{
IconSlotType *iconSlot;
void Load(void *img)
{
//Same loader stuff as above
}
public:
MyResourceLoader(IconSlotType *isl)
:iconSlot(isl)
{}
};
The queueLoadImageWithBlock equivalent would now take a second parameter of type ResourceLoader* and no third parameter. As for the invokation, there's the issue of callback object lifetime. Is queueLoadImageWithBlock asynchronous - that is, does it return before invoking the callback? If so, then a local instance of MyResourceLoader won't do, you'd have to create one dynamically and somehow dispose it. Assuming it's synchronous (i. e. does not invoke the callback after it returns):
MyResourceLoader ResLoader(self.iconSlot);
[[GameViewController getInstance] getResourceLoadMediator]->
queueLoadImageWithLoader([self.url UTF8String], &ResLoader);
If it's not:
[[GameViewController getInstance] getResourceLoadMediator]->
queueLoadImageWithLoader([self.url UTF8String], new MyResourceLoader(self.iconSlot));
I'm new on C++ and I'm trying to make some testing with C++ and SDL and in SDL we have a function:
SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param);
which I can pass a callback for the timer created.
But apparently it converts my instance this to *void so I can't retrieve it again on the update method which is static, and it's interesting but the the SDL_AddTime doesn't work on a non static callback function.
Well, so my problem is that when trying to call the public method render through the void* param argument It complains about not being a pointer-to-object-type...
Is there any way I can get the Character instance again inside the update method since I don't have control over the SDL_AddTime function and I have to pass the required parameters?
Thanks
#include "Character.h"
Character::Character(void)
{
timer = SDL_AddTimer(33, update, this);
this->render(); // is called without problem
}
//static method
Uint32 Character::update(Uint32 interval,void* param)
{
param->render(); // yields: 'void*' is not a pointer-to-object type;
SDL_Event event;
event.type = SDL_USEREVENT;
event.user.code = 1020;
event.user.data1 = param;
SDL_PushEvent(&event);
return interval;
}
void Character::render(void)
{
printf("rendering character \n");
}
You don't need a reinterpret_cast - a static_cast should be OK:
Character * cp = static_cast <Character *>( param );
You should avoid reinterpret_cast - it is almost always implementation specific, and may hide problems - just like old-style C casts.
Cast your param pointer to a Character:
Character * charPtr = reinterpret_cast<Character *>(param);
charPtr->render();
The reason is that C++ is a strong typed language. To change one type to another, you need to cast it first:
Uint32 Character::update(Uint32 interval, void* param)
{
reinterpret_cast<Character* >(param)->render();
/* ... */
}
Just for reference, if you were to call a lot of stuff in a function, to save all the nasty reinterpret_cast stuff everywhere you can do
Character * myCharacter = reinterpret_cast<Character* >(param);
Which then lets you do 'myCharacter->render();' or whathaveyou...