ObjFW  Artifact [57fb5578cc]

Artifact 57fb5578ccbf50db7566a37efd04b4026f9a9055afdb2080be0cd3c2ace6434b:

Manifest of check-in [57fb5578cc] - Remove forwarding methods. See long commit message for details.

There are two resons for removing it:

First, OFPlugin does not need forwarding anymore. Second is that
forwarding is broken in both, the GNU and the Apple runtime.

In GNU libobjc, objc_msg_sendv is implemented using __builtin_apply,
which is broken on many platforms, including x86_64. If forwarding is
used, the application will just crash. To work around that, I'd need to
parse the type encoding and use libffi to call the method instead of
using objc_msg_sendv.

Now the Apple runtime has a similar problem: There is no objc_msgSendv
for PPC64 and x86_64 as it's only in ObjC1 and on ARM (iPhone), it's
broken (most likely because the iPhone uses only ObjC2 - I was confused
that objc_msgSendv was even in the libobjc there). So I'd need to write
an ASM implementation for these 3.

Writing those 3 ASM implementations (or 5, so we don't depend on ObjC1
stuff on PPC32 and x86 as well) wouldn't be a problem, but there is a
problem the GNU libobjc and the Apple runtime got in common, which
originates from the early ObjC implementations:

forward:: and performv:: were only designed to return scalar types. But
today, it's possible to return floats, structs and unions as well. What
Apple and GNU use here is a very hacky workaround and it's just luck
that it works. forward:: and performv:: both return an id (Apple) or
void* (GNU). forward:: is called by the runtime if you called a method
that is not implemented. The compiler does not know at compile time
that it is not implemented, therefore expects a float as a return. On
x86, floats are returned in sp0. The runtime now notices that the
called method is not implemented and calls forward::. Forward then
calls performv:: to call the right method. The method returns a float
and stores it in sp0. Remember that both, forward:: and performv::
return an id / void*. performv:: returns now and after that, forward::
returns. The return of those was always put into eax, as that's how
scalar values are returned on x86. The original caller of the method
does not expect any return value in eax, but in sp0. This works, as
no code touched sp0. However, you can not rely on sp0 not being
touched. It's just luck that the compiler generates code that does not
touch sp0.

While this works for forwarding due to the ABI on x86 (and the ABIs on
many other platforms allow this hack as well), this fails if you call
performv:: directly on a method returning a float. In this case, the
compiler does not expect a return value in sp0, but in eax, as
performv:: is expected to return id / void*. Therefore the bogus value
in eax will be casted to float and the result will be useless.

This is why I decided to remove forwarding and performv:: from libobjfw
for now. If I encounter a situation where I need forwarding, I'm going
to implement it in a sane way and NOT the objc way. The forwarding
methods this commit removes did it the objc way, which is IMO just
wrong. (That way was ok back then when you only had scalar return
types, but today you're not limited to scalar return types anymore.) by js on 2009-04-19 17:37:52.


C Remove\sforwarding\smethods.\sSee\slong\scommit\smessage\sfor\sdetails.\n\nThere\sare\stwo\sresons\sfor\sremoving\sit:\n\nFirst,\sOFPlugin\sdoes\snot\sneed\sforwarding\sanymore.\sSecond\sis\sthat\nforwarding\sis\sbroken\sin\sboth,\sthe\sGNU\sand\sthe\sApple\sruntime.\n\nIn\sGNU\slibobjc,\sobjc_msg_sendv\sis\simplemented\susing\s__builtin_apply,\nwhich\sis\sbroken\son\smany\splatforms,\sincluding\sx86_64.\sIf\sforwarding\sis\nused,\sthe\sapplication\swill\sjust\scrash.\sTo\swork\saround\sthat,\sI'd\sneed\sto\nparse\sthe\stype\sencoding\sand\suse\slibffi\sto\scall\sthe\smethod\sinstead\sof\nusing\sobjc_msg_sendv.\n\nNow\sthe\sApple\sruntime\shas\sa\ssimilar\sproblem:\sThere\sis\sno\sobjc_msgSendv\nfor\sPPC64\sand\sx86_64\sas\sit's\sonly\sin\sObjC1\sand\son\sARM\s(iPhone),\sit's\nbroken\s(most\slikely\sbecause\sthe\siPhone\suses\sonly\sObjC2\s-\sI\swas\sconfused\nthat\sobjc_msgSendv\swas\seven\sin\sthe\slibobjc\sthere).\sSo\sI'd\sneed\sto\swrite\nan\sASM\simplementation\sfor\sthese\s3.\n\nWriting\sthose\s3\sASM\simplementations\s(or\s5,\sso\swe\sdon't\sdepend\son\sObjC1\nstuff\son\sPPC32\sand\sx86\sas\swell)\swouldn't\sbe\sa\sproblem,\sbut\sthere\sis\sa\nproblem\sthe\sGNU\slibobjc\sand\sthe\sApple\sruntime\sgot\sin\scommon,\swhich\noriginates\sfrom\sthe\searly\sObjC\simplementations:\n\nforward::\sand\sperformv::\swere\sonly\sdesigned\sto\sreturn\sscalar\stypes.\sBut\ntoday,\sit's\spossible\sto\sreturn\sfloats,\sstructs\sand\sunions\sas\swell.\sWhat\nApple\sand\sGNU\suse\shere\sis\sa\svery\shacky\sworkaround\sand\sit's\sjust\sluck\nthat\sit\sworks.\sforward::\sand\sperformv::\sboth\sreturn\san\sid\s(Apple)\sor\nvoid*\s(GNU).\sforward::\sis\scalled\sby\sthe\sruntime\sif\syou\scalled\sa\smethod\nthat\sis\snot\simplemented.\sThe\scompiler\sdoes\snot\sknow\sat\scompile\stime\nthat\sit\sis\snot\simplemented,\stherefore\sexpects\sa\sfloat\sas\sa\sreturn.\sOn\nx86,\sfloats\sare\sreturned\sin\ssp0.\sThe\sruntime\snow\snotices\sthat\sthe\ncalled\smethod\sis\snot\simplemented\sand\scalls\sforward::.\sForward\sthen\ncalls\sperformv::\sto\scall\sthe\sright\smethod.\sThe\smethod\sreturns\sa\sfloat\nand\sstores\sit\sin\ssp0.\sRemember\sthat\sboth,\sforward::\sand\sperformv::\nreturn\san\sid\s/\svoid*.\sperformv::\sreturns\snow\sand\safter\sthat,\sforward::\nreturns.\sThe\sreturn\sof\sthose\swas\salways\sput\sinto\seax,\sas\sthat's\show\nscalar\svalues\sare\sreturned\son\sx86.\sThe\soriginal\scaller\sof\sthe\smethod\ndoes\snot\sexpect\sany\sreturn\svalue\sin\seax,\sbut\sin\ssp0.\sThis\sworks,\sas\nno\scode\stouched\ssp0.\sHowever,\syou\scan\snot\srely\son\ssp0\snot\sbeing\ntouched.\sIt's\sjust\sluck\sthat\sthe\scompiler\sgenerates\scode\sthat\sdoes\snot\ntouch\ssp0.\n\nWhile\sthis\sworks\sfor\sforwarding\sdue\sto\sthe\sABI\son\sx86\s(and\sthe\sABIs\son\nmany\sother\splatforms\sallow\sthis\shack\sas\swell),\sthis\sfails\sif\syou\scall\nperformv::\sdirectly\son\sa\smethod\sreturning\sa\sfloat.\sIn\sthis\scase,\sthe\ncompiler\sdoes\snot\sexpect\sa\sreturn\svalue\sin\ssp0,\sbut\sin\seax,\sas\nperformv::\sis\sexpected\sto\sreturn\sid\s/\svoid*.\sTherefore\sthe\sbogus\svalue\nin\seax\swill\sbe\scasted\sto\sfloat\sand\sthe\sresult\swill\sbe\suseless.\n\nThis\sis\swhy\sI\sdecided\sto\sremove\sforwarding\sand\sperformv::\sfrom\slibobjfw\nfor\snow.\sIf\sI\sencounter\sa\ssituation\swhere\sI\sneed\sforwarding,\sI'm\sgoing\nto\simplement\sit\sin\sa\ssane\sway\sand\sNOT\sthe\sobjc\sway.\sThe\sforwarding\nmethods\sthis\scommit\sremoves\sdid\sit\sthe\sobjc\sway,\swhich\sis\sIMO\sjust\nwrong.\s(That\sway\swas\sok\sback\sthen\swhen\syou\sonly\shad\sscalar\sreturn\ntypes,\sbut\stoday\syou're\snot\slimited\sto\sscalar\sreturn\stypes\sanymore.)
D 2009-04-19T17:37:52
F LICENSE ae3c272ee81b620b28e044e8d89406b70103a4addb00ace5364837083e26efda
F Makefile 427824f052a1abcfa19d43620af94906530705a5dd0c470e7e8ee0d8c15d987b
F TODO 9efbe0a9f9ae0486846e8dfdd2f28cc7a054d73f1ea895d374b8bd92d4694ca6
F autogen.sh acec2711ea716bd75c913ed942b0a26d091e5afc818095540fa164ccf8160bbc x
F buildsys.mk.in 7300e92515109fd2ade6030dbeba1a991a7a357c7ffcdd993a095db1b85f0f31
F config.guess 9719765c11df4feacb4f2eb20098490dd3eadf076df56d33dadd45a5ac288a4a
F config.sub ae375c6af06c1abdaafcfd3df7672263ba434070fd84f81916b4fc208daf8012
F configure.ac e131a02e5c4246c57ee8863a5d53017679fda9bc07349e28e4496027b4ee3f00
F doxygen.cfg d551f60535bc44a4b03bddf2537948050b1587bfcf94fc94de7ed5cfc403fe0c
F extra.mk.in cf1b4ce92e418f628b4a5bbd2147ed4968451f168b89adb9acca0c588b511576
F install-sh d2b9a1735ea9cc00de20990f69eeaa84f800cea83aa3ab81b71187b4ec4bf247
F m4/acx_pthread.m4 79f26df4aaedda733368764d371f7b35642a17dbf58f5f1daea71cf510aca175
F m4/ax_check_compiler_flags.m4 eb1353b82e355b5d0bc59d3913e3398fedd37a5fea27e44acbc25584576e42d6
F m4/buildsys.m4 f07db37ba5e7dbc2e1f6b680b6d0af3c5193f9ce77eb2c8e7120c97058e72c32
F src/Makefile 549491be054e4b11c4672d40bead940dbefac7ee3ae0382e23ce2a74532cb77b
F src/OFArray.h 9a5683be2ad6cc018b6b7bfc2f232ddc9aef10fd6b7481ac190d13769de46c40
F src/OFArray.m b65574e4bc1af1db4c9dd64e70f42e6dc47249b487dab5346c100a7cc2b00bb7
F src/OFAutoreleasePool.h d4653e60d0dc937cf15a0645b66986ac583bbceaa263e926ddde21189875f8eb
F src/OFAutoreleasePool.m c444fdcf5158aa8b9a585782886c658edc0a35d69f505e3d131222fd8381439d
F src/OFConstString.h b313df502284a1de276f466344c7148c72c3785903b695860bcc30ae0c8408c5
F src/OFConstString.m 979d9dc5893bef09d44e032e583b77bafea791dfe50fe775d6c84f51388f3509
F src/OFDictionary.h 0e40b77f27942afed3a257b9644fc685836b6ef1511ecec61eb57bb5c18cd7ef
F src/OFDictionary.m 065f154d58eb11c9b1a091ce4d5ea1f864b6b489236576f031c9b43c4ce27574
F src/OFExceptions.h edbf4d480b73a70f638c21c36c86c33704364be2aee1ae054bfd82a55b75ca11
F src/OFExceptions.m 6c6b7a9a768e3e3b7114e0b9a8671c317b851d7758643fcbd535768e8acc2ac0
F src/OFFile.h 938ce6b8f3256e3b870b96b8e7cc7c4572738dff94bae3c72dbe6c2f07fb2486
F src/OFFile.m 08cbbc44cdff3a022c98d13d300e7358f05fdecc4e91dda46f360b04822650fd
F src/OFHashes.h 1c2aa1b47116ff3debc60deae8d06bc4e36eee32ad59488596ba33ad6ffffd9d
F src/OFHashes.m b4e6d3001509ae3e6ca586dcd63b4b71935709a31ea106edfc916c060a62cf63
F src/OFList.h 08eab0576a02749a0ba7223974754f427c1912beaba976c6ea4d66060c03ca39
F src/OFList.m 554cc90ca987fb3ad0af346718a1aea713c985b75412bcb6c99a6b3e666016ca
F src/OFMacros.h ec8a81722fb3a82397887b2f603e2b20437a51cc3cc054da3ec69ce75668f73b
F src/OFNumber.h 6453b5d17a4a49b5c3c0b6e8047c3e3d20b6c5d7e805b2637eda04347b7fa224
F src/OFNumber.m b19ce3cb166f219b6323c7a1187c88985a1923569c9cc15d9c722139305864a2
F src/OFObject.h 9fc0378e5da40f7bf72764490510afc1b898f9d8f7d13ba49fdf47e921085591
F src/OFObject.m a0cbb15bb48009e4e5bd3f386d7e9efb37e3826414dee3f4d84fa5aceb06679e
F src/OFPlugin.h 3326b854c77ed06ff98992112ecdfa1a19e51e062f3bd62af4d49d0e3e1a44e1
F src/OFPlugin.m ee4d5662a997995aac6354a05f9de63170e32df659c39538702cf3cecf5ae7e5
F src/OFStream.h 7f1379bb1f8ddbb6e7364a9ba59b7aedb7b9a51b19af7882bee5f52bae6cdac8
F src/OFString.h 2275e1b0332c7043275de110cf771dc81565f4364cd821f037ee1eb881e676f6
F src/OFString.m 0784bdbb565d925f57b22a1c5b86ba2b04ba8221c8c65aeb384fe3a9b32623db
F src/OFTCPSocket.h bd7229eefe6ba3f3f36125fa26021ca2586185bf8f8431b31158cbf4e3318daa
F src/OFTCPSocket.m b0a40b2d84b1d7ab4bd78446c2ba0f926524589f1147ff1929826b4a66fe9e3e
F src/OFXMLFactory.h 5c64021065c787c511d9b3975174cb3499235607f6fbcf0b736cc9d8a65e6430
F src/OFXMLFactory.m 88fdb05c43662c0bae22ae98aaabab9d9eb2ab345a988cff519870e2c5b0fe26
F src/asprintf.c 163772d3d60a3c570564b05cfb30e70a6a2aa8dd6ffe78802438922c20e8d20f
F src/asprintf.h e7761a686f8dab5e43abfd4145ad00a07462246d2c4e7564fb2e9278eac7b738
F tests/Makefile da80e99a87376291ce3af44bca4dbaf6195db16a53ae8d669f8bcd83c2918c53
F tests/OFArray/Makefile 43bcfb25a99581b6e28786f4f97dd6761f5483b8bd189604d55c6b0d46dd6705
F tests/OFArray/OFArray.m c4671d9ef0519090e796a15739416d458d0baf043a6bb2f510f2fba2999d6abf
F tests/OFAutoreleasePool/Makefile b0249dd3e5beaf78409e04c50267dd049bc65c836554c76155f6977175f2f839
F tests/OFAutoreleasePool/OFAutoreleasePool.m 5d50ad06033ec7f284f8a0953e1e3bb67b898960327142d00c539c7ed7865d44
F tests/OFDictionary/Makefile 59b0e45da4037a573f6806ea86e27c4c467c888d9e34cb51a2b8253b78034d7f
F tests/OFDictionary/OFDictionary.m 18eeb7ebbc53d8030d7a1eff58fca21d4b3451ea72af11ccb76e584ee348b481
F tests/OFHashes/Makefile fd6a97811c14aa694eac698171e68bd5588b28e15ff8ff146d52b9ae4527f789
F tests/OFHashes/OFHashes.m 4b23857f2bdaf1d90bf784ca07c4efed5c35bc186ed8ead45115db5a554c81e1
F tests/OFHashes/testfile ac78121630aaad87f7852695f00cc9175b9bf80bc63bbc0e65784f427cd51217
F tests/OFList/Makefile d6b98f18652a25c945e03d834c8ec2eb7bfd63860acc0861fb8c08aec3ef751d
F tests/OFList/OFList.m 61b6eedfea3a5e7bcb2695fdf52738483702fa6e021d790cb59a97b4e4540321
F tests/OFObject/Makefile 124082b2569e84fcf0e17949c24f5be8b17418c32e9dc09f9f2c02b6419f4098
F tests/OFObject/OFObject.m 875bad3799c3991703319a8b9a2e96ee42fc45fc2b598315a9d36d4176a041be
F tests/OFPlugin/Makefile dab086716a045f5f3bc1e9b2a028d3677a4ca5581e526d5b01955d63e92e6acd
F tests/OFPlugin/OFPlugin.m 0f4331146ff9ccedd7f0596506ed22a58263187138240fb226eafccc739e5bea
F tests/OFPlugin/TestPlugin/Makefile b512e9a9849107846525f7735554523b4451c34bf2f085ee80235e3a6aeae615
F tests/OFPlugin/TestPlugin/TestPlugin.h f72593c636161222bf942a8a1ff0625062540d24cb70dab3aee7becb38a02716
F tests/OFPlugin/TestPlugin/TestPlugin.m 6f671f6355477657b2874c468334cd8b143c56d4333260370c6e790b4a51118f
F tests/OFString/Makefile 64a4f01f91059e1919dbde92c5b41724acfa433a3e38c6f9251f83393a01517d
F tests/OFString/OFString.m 06121ecfbfbebac357ff207ee4b1830ff2e359b08ee052c382132dd207853df1
F tests/OFTCPSocket/Makefile 5caa62ad5c93885377925c190299614e1d02c7aa500b02b031479807a376404b
F tests/OFTCPSocket/OFTCPSocket.m 7883bf415d6c6d2bff23181db19538b575b701502a4101598041e957f7e28387
F tests/OFXMLFactory/Makefile 78f40e5cbf8a9d79a953da8c90b4774a8e38b739d9b196e91cc3343b1eb749da
F tests/OFXMLFactory/OFXMLFactory.m fed8fd03aec904e377aca1e998fe2577b57884ef23fb3f2e2dd6566ec04eac4e
P 179174571e60bbee1be7b2366a3ed425f9c2aa9d4935bc326c56f9f4af2940c3
U js
Z 06475076a21fa0338ccd0c191802df67