Hello!
I have a question how about JIT-ed code and the C++ compiler compatibily. My project (www.baadengine.org) will use
llvm and we will provide integration of JIT-ed code directly into C++ code. This means that C++ code can call JIT code just
like any other code and JIT-ed code can call C++ code. We will compile to your bytecode from our BSF format.
The question is if it is possible this to works. I am concerned with calling conversions (especially member call and the return values.
Thankfully, we only have to ensure that our internal string type, all native types and boost::smart_ptr type is returned correctly.
First the calling conversion. The so called __thiscall conversion on VC++ passes arguments on stack, while this pointer is passed
into ECX register. For GCC, as far as I am aware, the this pointer is pushed as if it were a special (first) argument. The fix would
be preaty simple but we want the bytecode to be OS independant, so we cannot change the bytecode.
The other thing are the return types. I don't know (it is probably even not documented) how VC++ returns smart pointer (boost::smart_ptr),
or any other type (other basics types, such as int, float, ... are probably returned into EAX as with GCC). Once again, we may
need specific return values per arhitecture.
I would be thankful for any suggestion,
®iga Osolin
It is possible, but it would be extremely ugly. I strongly recommend sticking to C features when JITing code.
-Chris
The problem is this is not possible, because what I would compile to JIT are actual classes. The integration of C++ and JIT code is very important; for example we would create our own vtbls with JIT-ed code addresses as the function call target.
There is one quite simple approach that I might take (I just came up with it). I could create special really small wrappers for each of these JIT-ed function, that would make the conversion to the common format (being either GCC or VC++). This wrapper could also extract all return values correctly and pass them to native C++ code as required. I think this would be the neatest solution, but would require a speed penalty. The actual wrapper code could be OS dependant:)
Is there any interest for llvm to have such features, such as integration directly to GCC compiled code, or VC++ compiled code (at the same time)? Because maybe it could be the part of llvm instead of baadengine, if you wish of course.
Regards,
®iga
The problem is this is not possible, because what I would compile to JIT
are actual classes. The integration of C++ and JIT code is very
important; for example we would create our own vtbls with JIT-ed code
addresses as the function call target.
Ok. Realize that this ties you to a specific compiler version though.
There is one quite simple approach that I might take (I just came up with it). I could create special really small wrappers for each of these JIT-ed function, that would make the conversion to the common format (being either GCC or VC++). This wrapper could also extract all return values correctly and pass them to native C++ code as required. I think this would be the neatest solution, but would require a speed penalty. The actual wrapper code could be OS dependant:)
Seems feasible.
Is there any interest for llvm to have such features, such as
integration directly to GCC compiled code, or VC++ compiled code (at the
same time)? Because maybe it could be the part of llvm instead of
baadengine, if you wish of course.
It depends on precisely how it integrates with llvm and how separated it is from other components.
-Chris
Chris Lattner pravi:
The problem is this is not possible, because what I would compile to JIT
are actual classes. The integration of C++ and JIT code is very
important; for example we would create our own vtbls with JIT-ed code
addresses as the function call target.
Ok. Realize that this ties you to a specific compiler version though.
As I am aware, the compiler is either GCC or VC++. Each of them has specific code generation (hopefully not too specific) that must be analyzed and act upon accordingly. The compiler versions do not change the output format, or at least I hope they do not (the binaries of VC6, VC7.1 and VC8 can be combined as much as you wish, I don't know how this is handled by GCC).
There is one quite simple approach that I might take (I just came up with it). I could create special really small wrappers for each of these JIT-ed function, that would make the conversion to the common format (being either GCC or VC++). This wrapper could also extract all return values correctly and pass them to native C++ code as required. I think this would be the neatest solution, but would require a speed penalty. The actual wrapper code could be OS dependant:)
Seems feasible.
Is there any interest for llvm to have such features, such as
integration directly to GCC compiled code, or VC++ compiled code (at the
same time)? Because maybe it could be the part of llvm instead of
baadengine, if you wish of course.
It depends on precisely how it integrates with llvm and how separated it is from other components.
I was thinking of providing an optional module to handle integration into C++. This module would only provide some sort of void* pointer for JIT-ed method. This
would actually be a small method that would pack the this pointer somehow and then call the actual underlaying method. It would of course need to be provided for
any type of JIT arhitecture ... But I don't know if this should be the part of llvm.
®iga