[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Is the GNUstep Objective-C runtime to picky about method signatures?
From: |
Wolfgang Lux |
Subject: |
Is the GNUstep Objective-C runtime to picky about method signatures? |
Date: |
Mon, 13 Apr 2020 16:23:39 +0200 |
Hi,
I've just recently come across a strange issue where the MySQL interface in the
SQLClient library had stopped working with a weird error when using the
libobjc2 runtime. In particular, the code was complaining that the
backendQuery:recordType:listType: method was called without a loaded bundle. A
debugging session later it was clear that the MySQL backend bundle was actually
loaded into the program and that the backendQuery:recordType:listType: was
available inside the bundle, but that the runtime simply refused to call the
override and just called the implementation in the SQLClient base class
instead, which emits the error message.
A more careful look at the code revealed a subtle difference between the
definition of the backendQuery:recordType:listType: method in the SQLClient
class and its MySQL bundle subclass: While the former (and all other backend
bundles) uses id parameters for the record and list type arguments, the MySQL
bundle was using Class parameters instead. This resulted in slightly different
method signatures (@40@0:8@16@32 vs. @40@0:8#16#32 on a 64-bit architecture)
and the libobjc2 method dispatch apparently is rather picky about those
signatures. As I've already changed the SQLClient library to use consistent
types, I've condensed the issue into a little test program (Test1.m) below. The
output for this on macOS with Apple's Foundation looks like this (and for
GNUstep with gcc and the gcc runtime it looks similar):
2020-04-13 16:08:47.544 Test[48495:1640682] Calling [a run] for <A:
0x7ffd99d01ae0>
2020-04-13 16:08:47.545 Test[48495:1640682] method: <null> with:
0x7ffedfc11798
2020-04-13 16:08:47.545 Test[48495:1640682] Calling [b run] for <B:
0x7ffd99d03a90>
2020-04-13 16:08:47.545 Test[48495:1640682] method: NSNull with:
0x7ffedfc11798
2020-04-13 16:08:47.545 Test[48495:1640682] Calling [c run] for <C:
0x7ffd99d03c20>
2020-04-13 16:08:47.545 Test[48495:1640682] method: <null> with:
0x7fffada0af60
but with clang and libobjc2 I get this:
2020-04-13 16:11:17.464 Test1[17213:17213] Calling [a run] for <A: 0x1ab1be8>
2020-04-13 16:11:17.465 Test1[17213:17213] method: <null> with: 0x7fff7219f738
2020-04-13 16:11:17.465 Test1[17213:17213] Calling [b run] for <B: 0x1ab3578>
2020-04-13 16:11:17.466 Test1[17213:17213] In base implementation of
-method:with:
2020-04-13 16:11:17.466 Test1[17213:17213] Calling [c run] for <C: 0x1ab4f08>
2020-04-13 16:11:17.466 Test1[17213:17213] In base implementation of
-method:with:
And while I was writing that test program, I accidentally uncovered another bug
in the libobjc2 runtime (see Test2.m): When calling super with a method that
isn't implemented by the super class (or its own ancestors) libobjc2 simply
does nothing, as if the method was called against nil. I would have expected an
unrecognized selector exception to be raised instead, as happens with Apple's
Foundation:
2020-04-13 16:13:34.742 Test[48512:1642397] -[D initWithObject:ptr:]:
unrecognized selector sent to instance 0x7fecbb704a00
2020-04-13 16:13:34.743 Test[48512:1642397] Caught exception -[D
initWithObject:ptr:]: unrecognized selector sent to instance 0x7fecbb704a00
2020-04-13 16:13:34.743 Test[48512:1642397] Calling [e run] for <E:
0x7fecbb407890>
2020-04-13 16:13:34.743 Test[48512:1642397] -[E method:pointer:]:
unrecognized selector sent to instance 0x7fecbb407890
2020-04-13 16:13:34.743 Test[48512:1642397] Caught exception -[E
method:pointer:]: unrecognized selector sent to instance 0x7fecbb407890
Just for reference here's the output with libobjc2 and GNUstep-base
2020-04-13 16:18:10.644 Test2[17264:17264] Calling [d run] for (null)
2020-04-13 16:18:10.645 Test2[17264:17264] Calling [e run] for <E: 0x1cc65c8>
Wolfgang
GNUmakefile
Description: Binary data
Test1.m
Description: Binary data
Test2.m
Description: Binary data
- Is the GNUstep Objective-C runtime to picky about method signatures?,
Wolfgang Lux <=