How to insert a GlobalVariable at the end of the module? - llvm

There's a constructor that seems to match my needs :
00055 /// GlobalVariable ctor - If a parent module is specified, the global is
00056 /// automatically inserted into the end of the specified modules global list.
00057 GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,
00058 Constant *Initializer = nullptr, const Twine &Name = "",
00059 ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
00060 bool isExternallyInitialized = false);
According to the documentation below, if a parent module is specified the gv is inserted at the end of it. How to specifiy the module ?

It looks like the comment is wrong. You can use this constructor, which takes a Module& as the first parameter. You can specify a GlobalVariable for the new one to be inserted before, but it's optional and without it the new global gets inserted at the end.
Alternatively (going by the title of your question), if you already have a GlobalVariable, you can call getGlobalList on the Module and push_back your global variable onto it.

Related

Pointer in function argument seems not working

I'm developing in C++. I have 2 objects : which are the StandaloneAgent and the ConfigManager.
I want from the Standalone Agent to reach a char * variable in the ConfigManager with a function .
int32_t StandaloneAgent::getConfigFile(char * file){
int32_t code = mConfigMgr->getConfigFile(file);
return code;
}
int32_t ConfigManager::getConfigFile(char * file){
file = mConfigFile;
return 0;
}
Here, the ConfigManager objet is an attribute of the StandaloneAgent with the
ConfigManager * mConfigMgr; variable.
And the file I want to reach is located in the mConfigFile attribute of the ConfigManager.
The problem is :
While putting std::cout,
the mConfigFile in the is OK and
the file variable after the
file = mConfigFile;
is OK
But when I return in the getConfigFile() function of the standalone agent, the file variable is a null pointer and I don't know why.
Is there a C++ specification that I am missing ?
Arguments to functions are either passed by-value or by-reference. Any variable passed by-value will be local to the function and any changes made to it is local to the function too. This means that when to assign a new value to the pointer (file = mConfigFile) you only change the pointer in the function. The pointer you passed as an argument is unaffected.
When taking arguments by-reference, the variable inside the function references the variable used to call the function. Any changes made to that variable will be directly made to the variable used in the call to the function.
In your case, that means that you need to change the ConfigManager::getConfigFile function:
int32_t ConfigManager::getConfigFile(char*& file){
file = mConfigFile; // the change is made to the variable used as an argument
return 0;
}
If the pointer passed to StandaloneAgent::getConfigFile is also supposed to be changed (I assume it is), you need the same change there:
int32_t StandaloneAgent::getConfigFile(char*& file){
int32_t code = mConfigMgr->getConfigFile(file);
return code;
}

Can one print the QualType of function pointers with a name using Clang AST?

Is there any easy and reliable way (a.k.a. not regex) to get the QualType of a function pointer declaration as a string but with a name attached to it? I tried looking into leveraging QualType::getAsString(const PrintingPolicy &Policy), but unfortunately, there is no option with that configuration.
e.g.
int (*)(void) ----> int (*whatever_name_here)(void)
You can create VarDecl and print that.
Assuming ctx is your ASTContext and type is your QualType, here is what you can do:
// Create identifier.
IdentifierInfo id = ctx.Idents.get("whatever_name_here");
// Create variable declaration.
VarDecl *vd = VarDecl::Create(ctx, ctx.getTranslationUnitDecl(),
SourceLocation(), SourceLocation(), &id, type, nullptr, StorageClass:SC_None);
// Print it.
vd->print(/* put your llvm::raw_stream here */, ctx.getPrintingPolicy());

In the V8 javascript engine, how to make a constructor function that re-uses an ObjectTemplate for each instance?

I have working code where I can create as many Point objects as I want, but it re-creates the object template each time the constructor is called, which seems like it's probably wrong.
Local<ObjectTemplate> global_templ = ObjectTemplate::New(isolate);
// make the Point constructor function available to JS
global_templ->Set(v8::String::NewFromUtf8(isolate, "Point"), FunctionTemplate::New(isolate, v8_Point));
and then the constructor itself:
void v8_Point(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(args.GetIsolate());
// this bit should probably be cached somehow
Local<ObjectTemplate> point_template = ObjectTemplate::New(args.GetIsolate());
point_template->SetInternalFieldCount(1);
point_template->SetAccessor(String::NewFromUtf8(args.GetIsolate(), "x"), GetPointX, SetPointX);
point_template->SetAccessor(String::NewFromUtf8(args.GetIsolate(), "y"), GetPointY, SetPointY);
// end section to be cached
Local<Object> obj = point_template->NewInstance();
Point * p = new Point(1,1);
obj->SetInternalField(0, External::New(args.GetIsolate(), p));
args.GetReturnValue().Set(obj);
}
But it seems like I should be able to pass in the point_template object instead of re-creating it each time. I saw that there's a Data() field in args, but that only allows for a Value type and an ObjectTemplate is of type Template, not Value.
Any help on the right way to do this would be greatly appreciated.
I figured it out finally.
In javascript, when you add a function via a FunctionTemplate and then call it as a constructor (e.g. new MyFunction), then in your c++ callback the args.This() will be a new object created by the using the FunctionTemplate's InstanceTemplate object template.
// Everything has to go in a single global template (as I understand)
Local<ObjectTemplate> global_templ = ObjectTemplate::New(isolate);
// create the function template and tell it the callback to use
Local<FunctionTemplate> point_constructor = FunctionTemplate::New(isolate, v8_Point);
// set the internal field count so our actual c++ object can tag along
// with the javascript object so our accessors can use it
point_constructor->InstanceTemplate()->SetInternalFieldCount(1);
// associate getters and setters for the 'x' field on point
point_constructor->InstanceTemplate()->SetAccessor(String::NewFromUtf8(isolate, "x"), GetPointX, SetPointX);
... add any other function and object templates to the global template ...
// add the global template to the context our javascript will run in
Local<Context> x_context = Context::New(isolate, NULL, global_templ);
Then, for the actual function:
void v8_Point(const v8::FunctionCallbackInfo<v8::Value>& args) {
// (just an example of a handy utility function)
// whether or not it was called as "new Point()" or just "Point()"
printf("Is constructor call: %s\n", args.IsConstructCall()?"yes":"no");
// create your c++ object that will follow the javascript object around
// make sure not to make it on the stack or it won't be around later when you need it
Point * p = new Point();
// another handy helper function example
// see how the internal field count is what it was set to earlier
// in the InstanceTemplate
printf("Internal field count: %d\n",args.This()->InternalFieldCount()); // this prints the value '1'
// put the new Point object into the internal field
args.This()->SetInternalField(0, External::New(args.GetIsolate(), p));
// return the new object back to the javascript caller
args.GetReturnValue().Set(args.This());
}
Now, when you write the getter and setter, you have access to your actual c++ object in the body of them:
void GetPointX(Local<String> property,
const PropertyCallbackInfo<Value>& info) {
Local<Object> self = info.Holder();
// This is where we take the actual c++ object that was embedded
// into the javascript object and get it back to a useable c++ object
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
int value = static_cast<Point*>(ptr)->x_; //x_ is the name of the field in the c++ object
// return the value back to javascript
info.GetReturnValue().Set(value);
}
void SetPointX(Local<String> property, Local<Value> value,
const PropertyCallbackInfo<void>& info) {
Local<Object> self = info.Holder();
// same concept here as in the "getter" above where you get access
// to the actual c++ object and then set the value from javascript
// into the actual c++ object field
Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));
void* ptr = wrap->Value();
static_cast<Point*>(ptr)->x_ = value->Int32Value();
}
Almost all of this came from here: https://developers.google.com/v8/embed?hl=en#accessing-dynamic-variables
except it doesn't talk about the proper way to make your objects in a repeatable fashion.
I figured out how to clean up the c++ object in the internal field, but I don't have time to put the whole answer here. You have to pass in a Global object into your weak callback by creating a hybrid field (a struct works well) on the heap that has both the global object and a pointer to your c++ object. You can then delete your c++ object, call Reset() on your Global and then delete the whole thing. I'll try to add actual code, but may forget.
Here is a good source: https://code.google.com/p/chromium/codesearch#chromium/src/v8/src/d8.cc&l=1064 lines 1400-1441 are what you want. (edit: line numbers seem to be wrong now - maybe the link above has changed?)
Remember, v8 won't garbage collect small amounts of memory, so you may never see it. Also, just because your program ends doesn't mean the GC will run. You can use isolate->AdjustAmountOfExternalAllocatedMemory(length); to tell v8 about the size of the memory you've allocated (it includes this in its calculations about when there's too much memory in use and GC needs to run) and you can use isolate->IdleNotificationDeadline(1); to give the GC a chance to run (though it may choose not to).

Address of strcuture member variable changed when passed by reference

I encountered a problem when debugging my model (written in C++) in Eclipse CDT. The problem is that when I pass a structure variable, who contains various member variables such as string or vector, to a function by reference, the value of certain member variables are not updated in the scope of that function. More details are provided as below:
struct ModelConfig {
//... here are some other variables and constructors
vector<int> crop_list;
string path_to_input;
//....
};
Say now I start debugging in GDB, and here is the first function call :
void modelMain::setupModel( const ModelConfig & sim_setting ){
//... some operations to configure the model using 'sim_setting'
/* 1.3 - Initialize the land */
Set_Environment(k_farm_land, sim_setting);
// breakpoint here, printing out the value of 'sim_etting' shows 'sim_setting.path_to_input = "data/"' ; Then I enter into 'Set_Environment' function ...
//...
}
void Set_Environment(vector<Soil> & farm_land, const ModelConfig & sim_setting) {
int EXP_ID = sim_setting.EXP_ID;
string strTmp_a;
strTmp_a = sim_setting.path_to_input + "soil/parameters.txt"; // Problem is here: the GDB shows here that sim_setting.path_to_input = " ". I am expecting strTmp_a = "data/soil/parameters.txt" which now is "soil/parameters.txt" ;
//... operations for reading data
}
The sim_setting.path_to_input variable should hold the string value named data/, which is correct during the call in setupModel(...), but the value is lost (or the address is changed actually) during the call in Set_Environment(...)...
When using the GDB debug in Eclipse to trace the address of the variables, I notice that the address of sim_setting seems correct in both setupModel and Set_Environment, but the member variable of path_to_input and crop_list changed into other place, which cause the lost of data. The value of crop_list is created using .push_back().
I did not get the point since I am passing the variable by reference. The only thing that I can imagine is due to the value assignment of string and vector. Anyone have theory for this ? Thank you very much in advance !

Google V8: access local variables in C++

Does someone know how I could look up local variables in a nested function call from C++?
Consider the following example:
// e.g. a global variable in the browser
var global = "global_value";
function foo(){
var global = "local_value";
myCppFunction("global", global);
}
foo();
My question now is how in the implementation of myCppFunction I could access the function local variable "global" (NOT value, this would be given by the 2nd parameter) from 'foo'?
Handle<Value> MyCppFunction(const Arguments& args){
Local<String> varName = args[0]->ToString();
Local<String> varValue = args[1]->ToString(); // this holds "local_value"
// how to access the variable "global" in the scope of 'foo' ?
}
I managed to find it out by myself. See the example below for how to find the value on the stack (and also replace it - here by the example of a string variable).
Two remarks beforehand:
I have not tested this for undesired behavior except from my very use cases where I use this in my master thesis - there (may) be dragons.
I don't know exactly why in my tests sfl.FindJavaScriptFrame(0) yields the desired stack frame - but, as it works independently of the calling depth, I suspect the stack frame indexed by 0 to always be the immediate caller's frame (in my case I know that I want exactly that).
And the code:
// Prepare identification of the variable,assuming varName as in the question
// More convenient conversions would be appreciated, at least by me
Local<String> varName = args[0]->ToString();
std::string varStr = *String::AsciiValue(varName);
// I'm using 'namespace i = internal;' (within v8-namespace)
i::Vector<const char> tmpVar(varStr.data(), varStr.length());
i::Handle<i::String> varIStr = i::Isolate::Current()->factory()->NewStringFromAscii(tmpVar, i::TENURED);
// Now hunt down the stack frame of interest, be sure to consider my remarks above
i::StackFrameLocator sfl;
// Comment from the code: The caller must guarantee that such a frame exists.
i::JavaScriptFrame* jsf = sfl.FindJavaScriptFrame(0);
// create some replacement
i::Vector<const char> tmp("there you go", 12);
i::Handle<i::String> insert = i::Isolate::Current()->factory()->NewStringFromAscii(tmp, i::TENURED);
i::Object* insertObj = insert->ToObjectChecked();
// by the help of JavaScriptFrame::Print I came up with this:
i::Object* fun = jsf->function();
if (fun->IsJSFunction()){
i::Handle<i::ScopeInfo> scope_info(i::ScopeInfo::Empty());
i::Handle<i::SharedFunctionInfo> shared((i::JSFunction::cast(fun))->shared());
scope_info = i::Handle<i::ScopeInfo>(shared->scope_info());
i::Object* script_obj = shared->script();
if (script_obj->IsScript()) {
int stack_locals_count = scope_info->StackLocalCount();
for (int i = 0; i < stack_locals_count; i++) {
if (scope_info->StackLocalName(i)->Equals(*varIStr)){
// replace the value on the stack
jsf->SetExpression(i,insertObj);
}
}
}
}