Given a llvm.dbg.declare, how can I get its llvm value?
e.g.
call void #llvm.dbg.declare(metadata !{i32** %r}, metadata !23), !dbg !24
I want get the Value i32** %r, not the metadata !{i32** %r}.
Please give me the code!
Thanks!
In later versions of LLVM, it is not allowed to cast Metadata from Value (I was on LLVM 7.0.1). Special classes MetadataAsValue and ValueAsMetadata are required for the cast.
CallInst *CI; /* Call to llvm.dbg.declare */
AllocaInst *AI; /* AllocaInst is the result */
Metadata *Meta = cast<MetadataAsValue>(CI->getOperand(0))->getMetadata();
if (isa<ValueAsMetadata>(Meta)) {
Value *V = cast <ValueAsMetadata>(Meta)->getValue();
AI = cast<AllocaInst>(V);
}
As you can see, the AllocaInst is wrapped inside ValueAsMetadata and then MetadataAsValue.
If you also want the get the DIVariable from this call.
DIVariable *V = cast<DIVariable>(cast<MetadataAsValue>(CI->getOperand(1))->getMetadata());
metadata !{i32** %r} is the 1st operand of the call instruction, and i32** %r is the 1st operand of the metadata. So something like this should work:
CallInst I = ... // get the #llvm.dbg.declare call
Value* referredValue = cast<MDNode>(I->getOperand(0))->getOperand(0);
Related
I'm using CLR profiling API and trying to get arguments info (COR_PRF_FUNCTION_ARGUMENT_INFO) from COR_PRF_ELT_INFO using GetFunctionEnter3Info function.
Below is my code. It seems GetFunctionEnter3Info function is not setting the value for pArgumentInfo. It always has null value. However, the function returns S_OK, which is a success.
I may be missing something. How should I get COR_PRF_FUNCTION_ARGUMENT_INFO from COR_PRF_ELT_INFO ?
PROFILER_STUB EnterStub(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo)
{
COR_PRF_FRAME_INFO *pFrameInfo = 0;
ULONG *pcbArgumentInfo = 0;
COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo = NULL;
corProfilerInfo->GetFunctionEnter3Info(functionId.functionID, eltInfo, pFrameInfo, pcbArgumentInfo, pArgumentInfo);
if(pArgumentInfo) {
//
}
}
It is a little bit tricky,
By msdn doc:
pcbArgumentInfo
[in, out] A pointer to the total size, in bytes, of the COR_PRF_FUNCTION_ARGUMENT_INFO structure (plus any additional COR_PRF_FUNCTION_ARGUMENT_RANGE structures for the argument ranges pointed to by pArgumentInfo). If the specified size is not enough, ERROR_INSUFFICIENT_BUFFER is returned and the expected size is stored in pcbArgumentInfo. To call GetFunctionEnter3Info just to retrieve the expected value for *pcbArgumentInfo, set *pcbArgumentInfo=0 and pArgumentInfo=NULL
In other words, you have a single COR_PRF_FUNCTION_ARGUMENT_INFO structure, which references multiple COR_PRF_FUNCTION_ARGUMENT_RANGE.
First of all, get a number of bytes of pcbArgumentInfo, after that allocate bytes and pass the pointer to GetFunctionEnter3Info as COR_PRF_FUNCTION_ARGUMENT_INFO.
Here is an example
PROFILER_STUB EnterStub(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo)
{
ULONG pcbArgumentInfo = 0;
COR_PRF_FRAME_INFO frameInfo;
corProfilerInfo3->GetFunctionEnter3Info(functionIDOrClientID.functionID, eltInfo, &frameInfo, &pcbArgumentInfo, NULL);
char* pArgumentInfo = new char[pcbArgumentInfo];
corProfilerInfo3->GetFunctionEnter3Info(functionIDOrClientID.functionID, eltInfo, &frameInfo, &pcbArgumentInfo, (COR_PRF_FUNCTION_ARGUMENT_INFO*)pArgumentInfo);
COR_PRF_FUNCTION_ARGUMENT_INFO* ptr = (COR_PRF_FUNCTION_ARGUMENT_INFO*)pArgumentInfo;
}
To access the second argument info block of COR_PRF_FUNCTION_ARGUMENT_RANGE use
prt->ranges[1]
The number of blocks is written in ptr->numRanges
I got a persistent class on a custom table. Now with GET_PERSISTENT_BY_QUERY I can get a list of objects. How can I now get those Objects with all of their atributes printed to the user (e.g as ALV)?
Can I call an instance function if i click on it somehow?
Here is a dynamic solution, query_data is the result returned from the call to get_persistent_by_query( ). In the end the data will be stored in structured table <table>, you can use this to display in your ALV. Note that there is little control over the order of the field. For real use you'd have to add some error handling as well.
DATA: pers_obj_desc TYPE REF TO cl_abap_classdescr,
pers_query_data TYPE REF TO data,
field_cat TYPE lvc_t_fcat.
FIELD-SYMBOLS: <table> TYPE STANDARD TABLE.
LOOP AT query_data ASSIGNING FIELD-SYMBOL(<pers_data>).
AT FIRST.
pers_obj_desc ?= cl_abap_typedescr=>describe_by_object_ref( p_object_ref = <pers_data> ).
LOOP AT pers_obj_desc->attributes ASSIGNING FIELD-SYMBOL(<attr_desc>).
APPEND INITIAL LINE TO field_cat ASSIGNING FIELD-SYMBOL(<field_cat>).
<field_cat>-fieldname = <attr_desc>-name.
<field_cat>-intlen = <attr_desc>-length.
<field_cat>-datatype = <attr_desc>-type_kind.
ENDLOOP.
cl_alv_table_create=>create_dynamic_table(
EXPORTING
it_fieldcatalog = field_cat
IMPORTING
ep_table = pers_query_data
).
ASSIGN pers_query_data->* TO <table>.
ENDAT. " first
APPEND INITIAL LINE TO <table> ASSIGNING FIELD-SYMBOL(<line>).
LOOP AT pers_obj_desc->attributes ASSIGNING <attr_desc>.
ASSIGN COMPONENT <attr_desc>-name OF STRUCTURE <line> TO FIELD-SYMBOL(<field>).
data(getter) = 'GET_' && <attr_desc>-name.
CALL METHOD <pers_data>->(getter) RECEIVING result = <field>.
ENDLOOP.
ENDLOOP.
One (i do not think good) way is to define a instance atribute called list. Then, the generated getter can be overwritten as following, which is addresed from anywhere.
DATA: WA TYPE ZMM_SMATERIAL.
WA-ERNAM = GET_ERNAM( ).
wa-ERSDA = GET_ERSDA( ).
WA-LAEDA = GET_LAEDA( ).
WA-MATNR = GET_MATNR( ).
WA-MTART = GET_MTART( ).
.
.
.
result = WA.
" GET_LIST
endmethod.
The ... stands for each attribute I want in the List.
The CONS to this solution:
on every call there is very much logic to do
the attribute is not used
An other (I do not think good) way is to define a instance atribute called list. Then, on the initialize, the list gets prepared.
DATA: WA TYPE ZMM_SMATERIAL.
WA-ERNAM = GET_ERNAM( ).
wa-ERSDA = GET_ERSDA( ).
WA-LAEDA = GET_LAEDA( ).
WA-MATNR = GET_MATNR( ).
WA-MTART = GET_MTART( ).
.
.
.
LIST = WA.
endmethod.
The ... stands for each attribute I want in the List.
Then, on every setter, also in this list it gets changed
The CONS to this solution:
Everything is redundant,
each setter has to get changed
One more way is to define a instance atribute called list. Then, the generated getter can be overwritten as following, which is addresed from anywhere.
if me->list is initial.
DATA: WA TYPE ZMM_SMATERIAL.
WA-ERNAM = GET_ERNAM( ).
wa-ERSDA = GET_ERSDA( ).
WA-LAEDA = GET_LAEDA( ).
WA-MATNR = GET_MATNR( ).
WA-MTART = GET_MTART( ).
.
.
.
me->list = WA.
endif.
result = me->list
" GET_LIST
endmethod.
The ... stands for each attribute I want in the List.
Additionaly to that, I need to CLEAR the list on every setter.
The big con to that is that the generator overwrites everything. (Without any warning.)
Based on the answer of gert beukema I have written a helper class (with major improvements like accepting more than public simple atributes without failing).
class ZCL_PS_OBJECT_TO_STRUCTURE_HLP definition
public
create private .
public section.
class-methods REFTAB_TO_STRUCTURE_LIST
importing
!IT_REFRENCE_TABLE type OSREFTAB
returning
value(RR_OBJECT_ATTRIBUTES_TABLE) type ref to DATA .
class-methods CREATE_FIELDCAT
importing
!IR_OBJ_DESC type ref to CL_ABAP_CLASSDESCR
returning
value(RO_FIELD_CAT) type LVC_T_FCAT .
protected section.
private section.
ENDCLASS.
CLASS ZCL_PS_OBJECT_TO_STRUCTURE_HLP IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_PS_OBJECT_TO_STRUCTURE_HLP=>CREATE_FIELDCAT
* +-------------------------------------------------------------------------------------------------+
* | [--->] IR_OBJ_DESC TYPE REF TO CL_ABAP_CLASSDESCR
* | [<-()] RO_FIELD_CAT TYPE LVC_T_FCAT
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD CREATE_FIELDCAT.
LOOP AT IR_obj_desc->attributes ASSIGNING FIELD-SYMBOL(<fs_attr_desc>).
APPEND INITIAL LINE TO ro_field_cat ASSIGNING FIELD-SYMBOL(<fs_field_cat>).
<fs_field_cat>-fieldname = <fs_attr_desc>-name.
<fs_field_cat>-intlen = <fs_attr_desc>-length.
<fs_field_cat>-datatype = <fs_attr_desc>-type_kind.
<fs_field_cat>-outputlen = calculate a good outputlength (double when hex)
ENDLOOP.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_PS_OBJECT_TO_STRUCTURE_HLP=>REFTAB_TO_STRUCTURE_LIST
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_REFRENCE_TABLE TYPE OSREFTAB
* | [<-()] RR_OBJECT_ATTRIBUTES_TABLE TYPE REF TO DATA
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD reftab_to_structure_list.
DATA: lr_obj_desc TYPE REF TO cl_abap_classdescr,
lr_query_data TYPE REF TO data,
lt_fieldcat TYPE lvc_t_fcat.
FIELD-SYMBOLS: <fs_table> TYPE STANDARD TABLE.
LOOP AT it_refrence_table ASSIGNING FIELD-SYMBOL(<fs_object>).
AT FIRST.
lr_obj_desc ?= cl_abap_typedescr=>describe_by_object_ref( p_object_ref = <fs_object> ).
lt_fieldcat = create_fieldcat( ir_obj_desc = lr_obj_desc ).
CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
* i_style_table =
it_fieldcatalog = lt_fieldcat
* i_length_in_byte =
IMPORTING
ep_table = rr_object_attributes_table
* ep_table = lr_query_data
* e_style_fname =
EXCEPTIONS
generate_subpool_dir_full = 1
OTHERS = 2.
* IF sy-subrc <> 0.
* do some errorhandling here
* ENDIF.
ASSIGN rr_object_attributes_table->* TO <fs_table>.
* ASSIGN lr_query_data->* TO <fs_table>.
ENDAT. "first
APPEND INITIAL LINE TO <fs_table> ASSIGNING FIELD-SYMBOL(<fs_line>).
LOOP AT lr_obj_desc->attributes ASSIGNING FIELD-SYMBOL(<fs_attr_desc>).
ASSIGN COMPONENT <fs_attr_desc>-name OF STRUCTURE <fs_line> TO FIELD-SYMBOL(<fs_attr_value>).
DATA(getter) = 'GET_' && <fs_attr_desc>-name.
TRY .
CALL METHOD <fs_object>->(getter) RECEIVING result = <fs_attr_value>.
CATCH cx_sy_dyn_call_illegal_method. "get_method is protected or private
CLEAR <fs_attr_value>.
CATCH cx_sy_dyn_call_illegal_type.
"what to do with a list?
ENDTRY.
ENDLOOP.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
Now with that helperclass I do not have to recode it always I want a list out of a Object.
In a programm the call is e.G like this:
DATA: lt_query_data TYPE osreftab,
lt_query_table TYPE REF TO data.
FIELD-SYMBOLS <fs_table>.
lt_query_data = zca_ps_user=>agent->if_os_ca_persistency~get_persistent_by_query(
i_query = cl_os_system=>get_query_manager( )->create_query( )
).
CALL METHOD zcl_ps_object_to_structure_hlp=>reftab_to_structure_list
EXPORTING
it_refrence_table = lt_query_data
RECEIVING
rr_object_attributes_table = lt_query_table.
IF lt_query_table IS INITIAL.
LEAVE.
ENDIF.
ASSIGN lt_query_table->* TO <fs_table>.
*Create a ALV
DATA: lr_alv TYPE REF TO cl_salv_table .
cl_salv_table=>factory( IMPORTING r_salv_table = lr_alv
CHANGING t_table = <fs_table> )
.
lr_alv->display( ).
Ps: I wanted to edit the answer, but it was not accepted.
I have an instance of ByteString. To read data from it I should use it's iterator() method.
I read some data and then I decide than I need to create a view (separate iterator of some chunk of data).
I can't use slice() of original iterator, because that would make it unusable, because docs says that:
After calling this method, one should discard the iterator it was called on, and use only the iterator that was returned. Using the old
iterator is undefined, subject to change, and may result in changes to
the new iterator as well.
So, it seems that I need to call slice() on ByteString. But slice() has from and until parameters and I don't know from. I need something like this:
ByteString originalByteString = ...; // <-- This is my input data
ByteIterator originalIterator = originalByteString .iterator();
...
read some data from originalIterator
...
int length = 100; // < -- Size of the view
int from = originalIterator.currentPosition(); // <-- I need this
int until = from + length;
ByteString viewOfOriginalByteString = originalByteString.slice(from, until);
ByteIterator iteratorForView = viewOfOriginalByteString.iterator(); // <-- This is my goal
Update:
Tried to do this with duplicate():
ByteIterator iteratorForView = originalIterator.duplicate()._2.take(length);
ByteIterator's from field is private, and none of the methods seems to simply return it. All I can suggest is to use originalIterator.duplicate to get a safe copy, or else to "cheat" by using reflection to read the from field, assuming reflection is available in your deployment environment.
I want to read the <param> values of custom plugin
I could not find answer on the internet, what I found was:
https://github.com/firebreath/FireBreath/blob/master/src/NpapiCore/NpapiPlugin.cpp#L76
I see params are stored in pluginMain->setParams(paramList);
Can you point how can I access this paramList later? or pluginMain
Is there pluginMain->getParams()? I could not find reference
Nor I could locate the source for setParams().
The question is, how do I get that parameters from PluginWindowXXX or FB::NpapiPluginXXX ?
I exported m_npHost to PluginWindowXXX, set breakpoint in it with gdb but still no success.
All I can think of was:
(gdb) p ((FB::Npapi::NpapiBrowserHost)this->m_npHost)->GetValue
$17 = {NPError (const FB::Npapi::NpapiBrowserHost * const, NPNVariable, void *)} 0x7fe435adeff8 <FB::Npapi::NpapiBrowserHost::GetValue(NPNVariable, void*) const>
Obviously what I do is wrong but I am stuck,
I am passing this host from NpapiPluginX11.cpp
pluginWin->setHost(m_npHost);
taxilian's answer is the most correct one as always but I'll give a try. I'm reading params in my MyPluginAPI constructor.
MyPluginAPI::MyPluginAPI(const MyPluginPtr& plugin, const FB::BrowserHostPtr& host) : m_plugin(plugin), m_host(host)
{
string settings; //<param name="settings" value="{'foo':'bar'}">
settings = plugin->getParam("settings");
}
Inside your PluginCore-derived class, you can use either the getParam method or the getParamVariant method.
From the FireBreath Source:
boost::optional<std::string> PluginCore::getParam(const std::string& key) {
boost::optional<std::string> rval;
FB::VariantMap::const_iterator fnd = m_params.find(key.c_str());
if (fnd != m_params.end())
rval.reset(fnd->second.convert_cast<std::string>());
return rval;
}
FB::variant FB::PluginCore::getParamVariant( const std::string& key )
{
FB::VariantMap::const_iterator fnd = m_params.find(key.c_str());
if (fnd != m_params.end())
return fnd->second;
return FB::variant();
}
So if it's for sure a string (which it pretty much is, unless it starts with on, in which case it might have been converted to a referenced function), you can use:
boost::optional<std::string> mystr = getParam("mystr");
if (mystr) {
call_fn_with_string(*mystr);
}
Alternately, you can get it as a variant and convert it:
FB::variant mystrVal = getParamVariant("mystr");
try {
call_fn_with_string(mystrVal.convert_cast<std::string>());
} catch (FB::bad_variant_cast &err) {
// What to do if the cast to string fails
}
I've got this odd problem.
If I make a call on that function through amfphp service browser and give it a valid ID and leave the $num_images field blank amfphp will actually pass a blank string as the argument.
// if i call this function width just an ID
function getWorkers($id, $num_images = 100) {
...
// num_images will be set as ''
}
I can easily override using a check:
function getWorkers($id, $num_images = 100) {
if($num_images=='') $num_images = 100;
...
// num_images will now be really set as 100
}
Anyone experiencing the same with amfphp?
That's odd, I never got that from AMFPHP. If you don't have the latest version try updating your installation of AMFPHP. Also make sure Flash doesn't somehow pass an empty variable as the second variable.
(Copied from the comment.)