LLVM: Passing a pointer to a struct, which holds a pointer to a function, to a JIT function - jit

I have an LLVM (version 2.7) module with a function that takes a pointer to a struct. That struct contains a function pointer to a C++ function. The module function is going to be JIT-compiled, and I need to build that struct in C++ using the LLVM API. I can't seem get the pointer to the function as an LLVM value, let alone pass a pointer to the ConstantStruct that I can't build.
I'm not sure if I'm even on the track, but this is what I have so far:
void print(char*);
vector<Constant*> functions;
functions.push_back(ConstantExpr::getIntToPtr(
ConstantInt::get(Type::getInt32Ty(context), (int)print),
/* function pointer type here, FunctionType::get(...) doesn't seem to work */
));
ConstantStruct* struct = cast<ConstantStruct>(ConstantStruct::get(
cast<StructType>(m->getTypeByName("printer")),
functions
));
Function* main = m->getFunction("main");
vector<GenericValue> args;
args[0].PointerVal = /* not sure what goes here */
ee->runFunction(main, args);

Actually, nevermind. I wouldn't use the LLVM API, just pass it a C++ struct that matches the LLVM struct type's layout. Ignore the first bit of that code and set args[0].PointerVal to a pointer to that struct.

Related

Scope and statically known namespaces in XQuery

consider a library module ctx
xquery version "3.1";
module namespace ctx="module/ctx";
declare function ctx:resolve (
$ctx as function(xs:string) as xs:QName
) as function(xs:string, xs:integer) as function(*)? {
function ($name as xs:string, $arity as xs:integer) as function(*)? {
function-lookup($ctx($name), $arity)
}
};
and a library module a
xquery version "3.1";
module namespace a="module/a";
declare function a:f () { "a:f" };
And a main module
xquery version "3.1";
import module namespace a="module/a" at "a.xqm";
import module namespace ctx="module/ctx" at "ctx.xqm";
ctx:resolve(xs:QName(?))("a:f", 0)()
Is it safe to assume that the function reference returned by xs:QName(?) will keep the context in which the namespace a is declared so that the main module will output "a:f"?
This does work in eXist-db (tested on 5.3.0) but I am not sure if this code is portable to other XQuery 3.1 processors.
---- UPDATE ----
What does not work in eXist-db 5.3.0 is
import module namespace ctx="module/ctx" at "ctx.xqm";
declare namespace app = "app";
declare function app:f () { "app:f" };
ctx:resolve(xs:QName(?))("app:f", 0)()
It's an excellent question.
If you used a named function reference xs:QName#1, then you would find the answer in §3.1.6:
Furthermore, if the function returned by the evaluation of a
NamedFunctionRef has an implementation-dependent implementation, then
the implementation of this function is associated with the static
context of this NamedFunctionRef expression and with the dynamic
context in which the NamedFunctionRef is evaluated.
That's rather arcane language, but what it means is that the function you get back uses the static and dynamic context of the named function reference itself (and not the context at the point where the function is actually called).
For a partial function application xs:QName(?) the language is even more impenetrable:
Implementation: The implementation of F. If this is not an XQuery 3.1
expression then the new function's implementation is associated with a
static context and a dynamic context in one of two ways: if F's
implementation is already associated with contexts, then those are
used; otherwise, SC and DC are used.
I think the spec is assuming (without justification) that built in functions like xs:QName will have an implementation that is not an XQuery 3.1 expression, so the second sentence applies. I really don't know quite what it intends by the phrase "already associated with contexts" - perhaps it's concerned with the case where F is already a partially applied function. But in any case, I'm reasonably sure that the intent is that "SC and DC are used" - that is, xs:QName(?) works exactly like xs:QName#1, it uses the static and dynamic context at the point where the expression xs:QName(?) is evaluated.
You're quite right to be concerned that you can't assume that what existing products do is what the spec says must happen. But in this case, I think they are getting it right.
Is it safe to assume that the function reference returned by xs:QName(?) will keep the context in which the namespace a is declared so that the main module will output "a:f"?
Tested successfully with BaseX 10.3.
Had to fix ctx as it was deemed syntactically incorrect by BaseX (missing as <Type>) for the result of ctx:resolve(). Just added as function(*)? . Here is the corrected code:
xquery version "3.1";
module namespace ctx="module/ctx";
declare function ctx:resolve (
$ctx as function(xs:string) as xs:QName
) as function(xs:string, xs:integer) as function(*)? {
function ($name as xs:string, $arity as xs:integer) as function(*)? {
function-lookup($ctx($name), $arity)
}
};

Converting a D object pointer to void* and passing to a callback

I want to convert a D class pointer into void*, pass this void* pointer together with the pointer to my callback extern(C) function to a C library routine.
The C library routine will call my callback extern(C) function, which will convert void* back to the class pointer and use the object of this class.
The trouble: I heard that GC objects may be moved to other locations (maybe not in current D version but in a future). Does this mean that my void* pointer may become invalid (no more point to my object)?
If the problem really exists, how to solve it?
You can tell the GC to hold on to the pointer as a root and furthermore, tell it not to move it on you with the import core.memory; GC.addRoot(ptr); function. This example shows it in full:
http://dpldocs.info/experimental-docs/core.memory.GC.addRoot.html#examples
// Typical C-style callback mechanism; the passed function
// is invoked with the user-supplied context pointer at a
// later point.
extern(C) void addCallback(void function(void*), void*);
// Allocate an object on the GC heap (this would usually be
// some application-specific context data).
auto context = new Object;
// Make sure that it is not collected even if it is no
// longer referenced from D code (stack, GC heap, …).
GC.addRoot(cast(void*)context);
// Also ensure that a moving collector does not relocate
// the object.
GC.setAttr(cast(void*)context, GC.BlkAttr.NO_MOVE);
// Now context can be safely passed to the C library.
addCallback(&myHandler, cast(void*)context);
extern(C) void myHandler(void* ctx)
{
// Assuming that the callback is invoked only once, the
// added root can be removed again now to allow the GC
// to collect it later.
GC.removeRoot(ctx);
GC.clrAttr(ctx, GC.BlkAttr.NO_MOVE);
auto context = cast(Object)ctx;
// Use context here…
}
Based on Adam D. Ruppe's answer but reorganized.
Even better OO code:
import core.memory : GC;
class UnmovableObject {
this() {
//GC.addRoot(cast(void*)this); // prevents finalization
GC.setAttr(cast(void*)this, GC.BlkAttr.NO_MOVE);
}
~this() {
//GC.removeRoot(cast(void*)this);
GC.clrAttr(cast(void*)this, GC.BlkAttr.NO_MOVE);
}
}

Google Closure Compiler Externs and Function Arguments

Consider a typical function extern:
var func = function(arg1, arg2) {};
Question: When declaring function externs like this, does the Google Closure Compiler care if we get the correct number of arguments? For example, we could replace the above with the following:
var func = function() {};
As an aside, I tried making my externs without any arguments, and the GCC didn't seem to care; however, I'm just making sure I'm not going to run into an unforseen problem going about things this way.
An extern function without any annotation is assumed to take a variable number of arguments of any type and can return any type. As soon as a single annotation is added, the behavior changes and the compiler will warn about the number and type of arguments.
/** #return {undefined} */
var func = function() {} ;
The compiler team will only accept externs that are completely typed because of this.

When and how to use a vector of references

This code correctly compiles. It has a few unused code warnings, but that's okay for now.
use std::collections::BTreeMap;
enum Object<'a> {
Str(String),
Int(i32),
Float(f32),
Vector(Vec<&'a Object<'a>>),
Prim(fn(State) -> State)
}
struct State<'a> {
named: BTreeMap<String, &'a Object<'a>>,
stack: Vec<Object<'a>>
}
impl<'a> State<'a> {
fn push_int(&mut self, x: i32) {
self.stack.push(Object::Int(x));
}
}
fn main() {
println!("Hello, world!");
let obj = Object::Str("this is a test".to_string());
}
The important part of this code is push_int and stack: Vec<Object<'a>>.
I'm sort of trying to make a stack-based VM.
I want to pass the state to functions, which can take stuff off the stack, manipulate the stuff, and then put some stuff back on the stack; the named field is going to hold named objects.
I have a hunch that it would be better to have the stack represented as a Vec<&'a Object<'a>> instead.
The way I have it now, I fear I'm committing some inefficiency error. Is my hunch correct?
The second part of the problem is that I don't know how to get the vector of references version to work. Creating new value with the right lifetimes to push onto the stack is not working for me.
I'm a bit vague about this issue, so if I've been unclear, ask me questions to clear stuff up.
The reason you could not get it to work is that structs cannot have fields that refer to other fields. (See supporting links at the bottom.)
What you can do, is put all the Objects into your Vec, and have the HashMap contain the indices of the named elements it references.
struct State {
named: BTreeMap<String, usize>,
stack: Vec<Object>
}
I'd also remove all lifetimes from your example, as this can be done completely with owned objects.
enum Object {
Str(String),
Int(i32),
Float(f32),
Vector(Vec<Object>),
Prim(fn(State) -> State)
}
You can try out a working implementation in the Playground
Supporting links:
How to initialize struct fields which reference each other
using self in new constructor
How to design a struct when I need to reference to itself
How to store HashMap and its Values iterator in the same struct?
What lifetimes do I use to create Rust structs that reference each other cyclically?
How to store a SqliteConnection and SqliteStatement objects in the same struct in Rust?
Why can't I store a value and a reference to that value in the same struct?
https://stackoverflow.com/questions/33123634/reference-inside-struct-to-object-it-owns

Why the "q_ptr" pointer is assigned to "this" pointer of QObject?

Like the title,why the "q_ptr" pointer is assigned to "this" pointer of QObject? in source code.
QObject::QObject(QObjectPrivate &dd, QObject *parent)
: d_ptr(&dd)
{
>>Q_D(QObject);
>>d_ptr->q_ptr = this;/*question*/
.......
Then,when use Q_Q() macro in source code like blow:
Q_Q(QWidget)
It will return the q pointer handled by the function q_fun():
QWidget*q_func() {return static_cast<QWidget*>(q_ptr);}
As all we know,static_castis not safe when cast from parent to child.
I am very frustrated about /*question*/ ,can any guy tell me the secret?Thanks!
d_ptr->q_ptr = this;/*question*/
This is where the private implementation object (PIMPL idiom) is told about the object it is working for/with (the non-private QObject). Here's a good link for info about Qt and d pointers (d_ptr).
Q_Q macro returns the pointer to the QObject, so you can emit signals from it (among other things). As for the static_cast bit, that is safe because the macro is defined differently for each class created by the Q_DECLARE_PRIVATE and Q_DECLARE_PUBLIC macros: the result being, static_cast is always casting to the correct type. Again, I recommend reading the link.

Resources