Call c/objc functions with the API

Does the api expose any way to execute an objc selector a given value (SBValue)? (for example I have an NSException instance in an SBValue, and want to call "name" on it).

What about global (c) functions?

If not the api, how can I do the equivalent with the underlying api?

Thanks,

Currently, no.
You would have to craft your own expression and run it.

The C++ data formatters have their own helper functions to do so. You can refer to lldb_private::formatters::ExtractValueFromObjCExpression for an example.

I am not sure if this kind of API belongs in the SB layer. Ideas?

Enrico Granata
:email: egranata@.com
✆ 27683

I also don’t think it should be in the SB layer. There’s lots of stuff to deal with (arguments and their types, variable arguments selectors/functions, etc). I think creating an expression is better (maybe we can use clang so one doesn’t have to generate an expression string?).

Regards,

filipe

I'm not arguing for this, but you could do a fairly straightforward API like:

SBValue
SBValue::CallMethod(const char *methodName, SBValueList arguments);

This would only work if the SBValue was a C++ or ObjC object. In the ObjC case "methodName" would be the selector, and the value list would have to be in parameter order.

I can see this being useful, though probably under the covers it would take some work to get it right...

Jim

CallMethod is right for C++, but for ObjC it would be CallSelector. I don’t think ObjC even has the notion of method in its lexicon.

Also, dealing with the arguments is going to be tricky.Problems I can see at a glance:

  • how do you deal with each SBValue while making the string? expression path? numeric value + a cast? neither way looks perfect at a glance
  • for ObjC you need to also extract the “names of the arguments” (i.e. foo:arg1 bar:arg2 baz:arg3), while in C++ (arg1,arg2,arg3) is enough

Of course, there are ways around these issues, but I am not sure this is useful enough to warrant the work required to get it right.

The data formatters need a much more constrained subset of this functionality, so they implement their own wrapper.
Any special subset should be trivial to implement, the general case looks tricky.

Enrico Granata
:email: egranata@.com
✆ 27683

CallMethod is right for C++, but for ObjC it would be CallSelector. I don’t think ObjC even has the notion of method in its lexicon.

Yeah, the ObjC guys are pretty sloppy about their nomenclature (is it a method, is it a message...) And the selector defines the method, so I don't think you'd really need two calls.

Also, dealing with the arguments is going to be tricky.
Problems I can see at a glance:
- how do you deal with each SBValue while making the string? expression path? numeric value + a cast? neither way looks perfect at a glance

I don't think you would make up a string. You would implement this lower down than that, where we are directly populating the "arguments structure" that we are going to call, a la the Clang Functions. And by the time we get there, we would have the method signature, so we'd know how to interpret the SBValues from the input arguments.

- for ObjC you need to also extract the “names of the arguments” (i.e. foo:arg1 bar:arg2 baz:arg3), while in C++ (arg1,arg2,arg3) is enough

Again, you would be consing up a call to objc_msgSend with the arguments passed directly, so that would not be an issue.

Jim

Hi,

Hi,

>
> Also, dealing with the arguments is going to be tricky.
> Problems I can see at a glance:
> - how do you deal with each SBValue while making the string? expression path? numeric value + a cast? neither way looks perfect at a glance

I don't think you would make up a string. You would implement this lower down than that, where we are directly populating the "arguments structure" that we are going to call, a la the Clang Functions. And by the time we get there, we would have the method signature, so we'd know how to interpret the SBValues from the input arguments.

Yes, bypassing the string building and just going for the clang AST or something.

> - for ObjC you need to also extract the “names of the arguments” (i.e. foo:arg1 bar:arg2 baz:arg3), while in C++ (arg1,arg2,arg3) is enough

Again, you would be consing up a call to objc_msgSend with the arguments passed directly, so that would not be an issue.

Jim

I think you could even bypass objc_msgSend (though I don't know what it does internally). You would get a reference to either a function, an ObjC method that implements a selector (is my nomenclature right? :-P), or a C++ method, and then just creating something close to an llvm call instruction (but going through clang first, to validate the call, perform any needed conversions, and lower the arguments).

You could look up the implementation for the class & selector pair (using class_getMethodImplementation), and directly call that implementation function. But that's probably not worth the trouble, because objc_msgSend does a bunch of work to support lazy class loading, delegate objects, and the like, and you don't want to have to try to figure all that out. If you were going to do this it would be better just to call objc_msgSend.

Jim

If you go that route, you will have to take care of all the special cases introduced by the ABI (i.e calling the right objc_msgSend variant depending the arguments type and the return type).

-- Jean-Daniel

CallMethod is right for C++, but for ObjC it would be CallSelector. I don’t think ObjC even has the notion of method in its lexicon.

Yeah, the ObjC guys are pretty sloppy about their nomenclature (is it a method, is it a message...) And the selector defines the method, so I don't think you'd really need two calls.

Also, dealing with the arguments is going to be tricky.
Problems I can see at a glance:
- how do you deal with each SBValue while making the string? expression path? numeric value + a cast? neither way looks perfect at a glance

I don't think you would make up a string. You would implement this lower down than that, where we are directly populating the "arguments structure" that we are going to call, a la the Clang Functions. And by the time we get there, we would have the method signature, so we'd know how to interpret the SBValues from the input arguments.

- for ObjC you need to also extract the “names of the arguments” (i.e. foo:arg1 bar:arg2 baz:arg3), while in C++ (arg1,arg2,arg3) is enough

Again, you would be consing up a call to objc_msgSend with the arguments passed directly, so that would not be an issue.

If you go that route, you will have to take care of all the special cases introduced by the ABI (i.e calling the right objc_msgSend variant depending the arguments type and the return type).

Yes but that's actually not terribly difficult, there aren't all that many variants of objc_msgSend, and the decisions among them are not that complex.

Jim