Skip to content

[ffigen] Objective-C interface static methods and ffiNative: #1229

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
dcharkes opened this issue Jun 25, 2024 · 1 comment
Open

[ffigen] Objective-C interface static methods and ffiNative: #1229

dcharkes opened this issue Jun 25, 2024 · 1 comment
Labels
lang-objective_c Related to Objective C support package:ffigen

Comments

@dcharkes
Copy link
Collaborator

When using

ffiNative:

With toplevel methods in Objective-C we directly invoke via an @Native

@Native<Void Function()>()
external void play();

But if I change it to a static method on an interface we get a reflective implementation, that does dynamic symbol lookup.

class MyMediaPlayer extends objc.NSObject {
  static void play() {
    _objc_msgSend_2(_class_MyMediaPlayer, _sel_play);
  }

@liamappelbe Is it needed that we do something reflective here? Or can we use a @Native here as well? If we'd want to do that, we'd have to deal with the name mangling?

$ nm test/native_objc_test/static_func_test.dylib
0000000000003d08 t +[StaticFuncTestObj newWithCounter:]  // <-- name mangled?
0000000000003de4 t -[StaticFuncTestObj dealloc]
0000000000003d44 t -[StaticFuncTestObj initWithCounter:]
0000000000003dac t -[StaticFuncTestObj setCounter:]
                 U _OBJC_CLASS_$_NSObject
00000000000080f8 S _OBJC_CLASS_$_StaticFuncTestObj
00000000000080f0 S _OBJC_IVAR_$_StaticFuncTestObj.counter
                 U _OBJC_METACLASS_$_NSObject
0000000000008120 S _OBJC_METACLASS_$_StaticFuncTestObj
0000000000003ec8 s __OBJC_$_CLASS_METHODS_StaticFuncTestObj
0000000000003ee0 s __OBJC_$_INSTANCE_METHODS_StaticFuncTestObj
0000000000008048 s __OBJC_$_INSTANCE_VARIABLES_StaticFuncTestObj
0000000000008070 s __OBJC_CLASS_RO_$_StaticFuncTestObj
0000000000008000 s __OBJC_METACLASS_RO_$_StaticFuncTestObj
                 U __objc_empty_cache
0000000000003b30 T _getBlockRetainCount
0000000000003b54 T _getObjectRetainCount
0000000000003ba4 T _isReadableMemory
                 U _mach_task_self_
                 U _mach_vm_region
                 U _objc_alloc
                 U _objc_msgSend
0000000000003e88 s _objc_msgSend$initWithCounter:
0000000000003ea8 s _objc_msgSend$newWithCounter:
                 U _objc_msgSendSuper2
                 U _objc_retain
0000000000003ca4 T _staticFuncOfBlock
0000000000003c90 T _staticFuncOfNullableObject
0000000000003c7c T _staticFuncOfObject
0000000000003cb8 T _staticFuncReturnsRetained
0000000000003ce4 T _staticFuncReturnsRetainedArg

Or are there other reasons why we can't do this?

This would be mostly for performance reasons. For tree-shaking, we would generate different annotations anyway (#1099).

@dcharkes dcharkes added package:ffigen lang-objective_c Related to Objective C support labels Jun 25, 2024
@liamappelbe
Copy link
Contributor

liamappelbe commented Jun 25, 2024

That might be possible, but it's not just a matter of name mangling. In C++, a static method in a class is really just a top-level function under the hood (with exactly the same signature). But in ObjC, a static method in a class is really an instance method in the class object.

So whether it's possible depends on details of the ObjC ABI that I haven't investigated yet. The question is, what's the signature of the C function backing + (instancetype)newWithCounter:(int32_t*) _counter;? I could plausibly see it being any of:

StaticFuncTestObj *newWithCounter(int32_t* _counter);
StaticFuncTestObj *newWithCounter(Class* receiver, int32_t* _counter);
StaticFuncTestObj *newWithCounter(Class* receiver, SEL selector, int32_t* _counter);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lang-objective_c Related to Objective C support package:ffigen
Projects
Status: Backlog
Development

No branches or pull requests

2 participants