diff --git a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm index 1d7614637e..4cb71099ff 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm @@ -143,14 +143,12 @@ public: virtual NSDictionary* getFullState() { - objc_super s = { getAudioUnit(), [AUAudioUnit class] }; - return ObjCMsgSendSuper*> (&s, @selector (fullState)); + return ObjCMsgSendSuper*> (getAudioUnit(), @selector (fullState)); } virtual void setFullState (NSDictionary* state) { - objc_super s = { getAudioUnit(), [AUAudioUnit class] }; - ObjCMsgSendSuper*> (&s, @selector (setFullState:), state); + ObjCMsgSendSuper (getAudioUnit(), @selector (setFullState:), state); } virtual AUParameterTree* getParameterTree() = 0; @@ -179,14 +177,12 @@ public: virtual bool getShouldBypassEffect() { - objc_super s = { getAudioUnit(), [AUAudioUnit class] }; - return (ObjCMsgSendSuper (&s, @selector (shouldBypassEffect)) == YES); + return (ObjCMsgSendSuper (getAudioUnit(), @selector (shouldBypassEffect)) == YES); } virtual void setShouldBypassEffect (bool shouldBypass) { - objc_super s = { getAudioUnit(), [AUAudioUnit class] }; - ObjCMsgSendSuper (&s, @selector (setShouldBypassEffect:), shouldBypass ? YES : NO); + ObjCMsgSendSuper (getAudioUnit(), @selector (setShouldBypassEffect:), shouldBypass ? YES : NO); } //============================================================================== @@ -195,14 +191,12 @@ public: virtual bool allocateRenderResourcesAndReturnError (NSError **outError) { - objc_super s = { getAudioUnit(), [AUAudioUnit class] }; - return (ObjCMsgSendSuper (&s, @selector (allocateRenderResourcesAndReturnError:), outError) == YES); + return (ObjCMsgSendSuper (getAudioUnit(), @selector (allocateRenderResourcesAndReturnError:), outError) == YES); } virtual void deallocateRenderResources() { - objc_super s = { getAudioUnit(), [AUAudioUnit class] }; - ObjCMsgSendSuper (&s, @selector (deallocateRenderResources)); + ObjCMsgSendSuper (getAudioUnit(), @selector (deallocateRenderResources)); } //============================================================================== @@ -294,9 +288,8 @@ private: { AUAudioUnit* self = _self; - objc_super s = { self, [AUAudioUnit class] }; - self = ObjCMsgSendSuper (&s, @selector(initWithComponentDescription:options:error:), descr, options, error); + self = ObjCMsgSendSuper (self, @selector (initWithComponentDescription:options:error:), descr, options, error); JuceAudioUnitv3Base* juceAU = JuceAudioUnitv3Base::create (self, descr, options, error); @@ -308,9 +301,8 @@ private: { AUAudioUnit* self = _self; - objc_super s = { self, [AUAudioUnit class] }; - self = ObjCMsgSendSuper (&s, @selector(initWithComponentDescription:options:error:), descr, options, error); + self = ObjCMsgSendSuper (self, @selector(initWithComponentDescription:options:error:), descr, options, error); setThis (self, juceAU); diff --git a/modules/juce_audio_utils/native/juce_mac_BluetoothMidiDevicePairingDialogue.mm b/modules/juce_audio_utils/native/juce_mac_BluetoothMidiDevicePairingDialogue.mm index 11679a4f78..39f442ac82 100644 --- a/modules/juce_audio_utils/native/juce_mac_BluetoothMidiDevicePairingDialogue.mm +++ b/modules/juce_audio_utils/native/juce_mac_BluetoothMidiDevicePairingDialogue.mm @@ -80,7 +80,6 @@ private: static void dealloc (id self, SEL) { [getController (self) release]; - sendSuperclassMessage (self, @selector (dealloc)); } diff --git a/modules/juce_core/native/juce_osx_ObjCHelpers.h b/modules/juce_core/native/juce_osx_ObjCHelpers.h index beffbe1236..86256ae772 100644 --- a/modules/juce_core/native/juce_osx_ObjCHelpers.h +++ b/modules/juce_core/native/juce_osx_ObjCHelpers.h @@ -192,21 +192,33 @@ NSRect makeNSRect (const RectangleType& r) noexcept static_cast (r.getHeight())); } #endif -#if JUCE_MAC || JUCE_IOS -// This is necessary as on iOS/ARM builds, some arguments may be passed on registers -// depending on the argument type. The re-cast objc_msgSendSuper to a function -// take the same arguments as the target method. -template -ReturnValue ObjCMsgSendSuper (struct objc_super* s, SEL sel, Params... params) -{ - using SuperFn = ReturnValue (*)(struct objc_super*, SEL, Params...); - SuperFn fn = reinterpret_cast (objc_msgSendSuper); - return fn (s, sel, params...); -} +#if JUCE_INTEL + template + struct NeedsStret { static constexpr auto value = sizeof (T) > 16; }; + template<> + struct NeedsStret { static constexpr auto value = false; }; + template ::value> + struct MetaSuperFn { static constexpr auto value = objc_msgSendSuper_stret; }; + + template + struct MetaSuperFn { static constexpr auto value = objc_msgSendSuper; }; +#else + template + struct MetaSuperFn { static constexpr auto value = objc_msgSendSuper; }; #endif +template +static ReturnType ObjCMsgSendSuper (id self, SEL sel, Params... params) +{ + using SuperFn = ReturnType (*) (struct objc_super*, SEL, Params...); + const auto fn = reinterpret_cast (MetaSuperFn::value); + + objc_super s = { self, [SuperType class] }; + return fn (&s, sel, params...); +} + //============================================================================== struct NSObjectDeleter { @@ -278,14 +290,11 @@ struct ObjCClass jassert (b); ignoreUnused (b); } - #if JUCE_MAC || JUCE_IOS - template - static Result sendSuperclassMessage (id self, SEL selector) + template + static ReturnType sendSuperclassMessage (id self, SEL sel, Params... params) { - objc_super s = { self, [SuperclassType class] }; - return ObjCMsgSendSuper (&s, selector); + return ObjCMsgSendSuper (self, sel, params...); } - #endif template static Type getIvar (id self, const char* name) @@ -322,18 +331,14 @@ struct ObjCLifetimeManagedClass : public ObjCClass addMethod (@selector (dealloc), dealloc, "v@:"); - registerClass(); } static id initWithJuceObject (id _self, SEL, JuceClass* obj) { - NSObject* self = _self; - - objc_super s = { self, [NSObject class] }; - self = ObjCMsgSendSuper (&s, @selector(init)); - + NSObject* self = sendSuperclassMessage (_self, @selector (init)); object_setInstanceVariable (self, "cppObject", obj); + return self; } @@ -345,11 +350,9 @@ struct ObjCLifetimeManagedClass : public ObjCClass object_setInstanceVariable (_self, "cppObject", nullptr); } - objc_super s = { _self, [NSObject class] }; - ObjCMsgSendSuper (&s, @selector(dealloc)); + sendSuperclassMessage (_self, @selector (dealloc)); } - static ObjCLifetimeManagedClass objCLifetimeManagedClass; }; diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index 51ac39d7ec..b90b78944e 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -1771,10 +1771,7 @@ private: owner->stringBeingComposed.clear(); if (! (owner->textWasInserted || owner->redirectKeyDown (ev))) - { - objc_super s = { self, [NSView class] }; - ObjCMsgSendSuper (&s, @selector (keyDown:), ev); - } + sendSuperclassMessage (self, @selector (keyDown:), ev); } } @@ -1782,11 +1779,8 @@ private: { auto* owner = getOwner (self); - if (owner == nullptr || ! owner->redirectKeyUp (ev)) - { - objc_super s = { self, [NSView class] }; - ObjCMsgSendSuper (&s, @selector (keyUp:), ev); - } + if (! owner->redirectKeyUp (ev)) + sendSuperclassMessage (self, @selector (keyUp:), ev); } //============================================================================== @@ -2058,7 +2052,7 @@ private: return owner == nullptr || owner->windowShouldClose(); } - static NSRect constrainFrameRect (id self, SEL, NSRect frameRect, NSScreen*) + static NSRect constrainFrameRect (id self, SEL, NSRect frameRect, NSScreen* screen) { if (auto* owner = getOwner (self)) frameRect = owner->constrainRect (frameRect); @@ -2105,10 +2099,10 @@ private: { if (auto* owner = getOwner (self)) { - owner->isZooming = true; - objc_super s = { self, [NSWindow class] }; - ObjCMsgSendSuper (&s, @selector (zoom:), sender); - owner->isZooming = false; + { + const ScopedValueSetter svs (owner->isZooming, true); + sendSuperclassMessage (self, @selector (zoom:), sender); + } owner->redirectMovedOrResized(); } diff --git a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm index 2640fc72cb..0cc702d3f4 100644 --- a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm +++ b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm @@ -276,11 +276,17 @@ struct WebViewKeyEquivalentResponder : public ObjCClass { WebViewKeyEquivalentResponder() : ObjCClass ("WebViewKeyEquivalentResponder_") { + addIvar ("owner"); addMethod (@selector (performKeyEquivalent:), performKeyEquivalent, @encode (BOOL), "@:@"); registerClass(); } private: + static WebViewKeyEquivalentResponder* getOwner (id self) + { + return getIvar (self, "owner"); + } + static BOOL performKeyEquivalent (id self, SEL selector, NSEvent* event) { NSResponder* first = [[self window] firstResponder]; @@ -293,8 +299,7 @@ private: if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) return [NSApp sendAction:@selector(selectAll:) to:first from:self]; } - objc_super s = { self, [WebView class] }; - return ObjCMsgSendSuper (&s, selector, event); + return sendSuperclassMessage (self, selector, event); } };