Sorry IOhannes, my previous mail was sent right before your explanation saying where I got it wrong. So please ignore it.
Katja
On Wed, Feb 4, 2015 at 11:51 AM, IOhannes m zmoelnig zmoelnig@iem.at wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
On 2015-02-04 10:57, katja wrote:
To be sure if I understand the idea correctly: the setup method of each class is renamed (by the build system, essentially), and precision-aware Pd looks for that new name so it loads the code for the proper precision. This way you can bundle two versions of a class (or lib) in a single executable, one for each precision. The setup method of the wrong precision will not be called by Pd. Am I right?
no. we might misunderstand each other.
the basic idea (without phat binaries)
- Pd only looks for the good olde <name>_setup() function (or it's
hexmunged equivalent).
- the external registers a new object-class with a precision-aware
callback function (*class_new* for single-precision; *class_new64* for double precision); class_new64() is used automatically due to a define in m-pd.h triggered by a double-precision build.
loading scenarios:
- when an external is loaded, the Pd-runtime calls the external
*setup* function (via *dlopen()*).
- the external then registers it's objectclasses with the pd-runtime
** nothing really changes for a single-precision Pd-runtime (including a legacy Pd-runtime) loading a single-precision external.
** when a double-precision external is loaded by a double-precision runtime, the objectclasses will be registered via the new callback "class_new64()".
** when a single-precision external is loaded by a double-precision runtime, it will register the objectclasses via class_new() which is a noop (probably giving the user a warning about mismatched precisions)
** when a double-precision external is loaded by a (new) single-precision runtime, it will register the objectclasses via class_new64() which is a noop (probably giving the user a warning about mismatched precisions)
** when a double-precision external is loaded by a legacy (single-precision) runtime, it would register the objectclasses via class_new64() which does not exist (and thus the dlopen()ing ofthe external won't work in the first place)
multi-precision libraries (what i call "phat binaries" for lack of a better work; it's contains both "fat" and "precision") ===
- the external's setup()-function calls both class_new() and
class_new64() to register two different specializations of the same object (i just borrowed the term "specialization" from C++-templates)
- a (new) single-precision Pd will discard the class_new64() call, and
thus only *see* the single-precision objectclass.
- a (new) double-precision Pd will discard the class_new() call, and
thus only *see* the double-precision objectclass.
- a legacy (single-precision) Pd will not be able to load the phat
binary, since the "class_new64" symbol is missing.
the last item is obviously a little problem, but that problem always exists if an external uses a newly introduced function (e.g. using "logpost()" will make the external unusable on Pd<=0.42)
Does it also mean the rest of the wrong-precision code will not be loaded? What will happen with unintentionally exported symbols, like private functions accidentally not declared static, or functions defined in shared files? Compiler-dependent methods exist to hide symbols by default. Then, the same approach for renaming class setup methods according to precision, might be used to explicitly define them as exported symbol.
good points. my approach assumed, that the code was written "correctly" ("proper"). that is: t_float/t_sample is used throughout; *all* functions that need not be exported are not exported. probably others.
hiding (aka: not-exporting) symbols by default won't help us much, as this only works at the dylib boundaries: within the entire phat-binary the symbols are still visible (so it's different from "static" functions).
anyhow: my point was mainly, that it should be fairly simple to create phat binaries of many (simplistic) externals (and i think most externals fall into this category). for more complex externals, a lot of manual work might still be involved,
What would a legacy Pd build do with fat-precision binaries? Could we consider single precision the default and not rename the setup function compiled for single precision so it will still work with legacy Pd? If the extensions are not modified, a user can't see whether an external is fat-precision or not.
see my other (short) mail (and the above explanations): single-precision externals should continue to use the olde names. if we want to support phat binaries in legacy runtimes, we probably should think again (adding an extension will not help us here either). at least on linux (and most likely on OSX; but more unlikely on W32) it should be possible to provide a "stub-external", that only exports the new "class_new64" symbol (as a noop). having this stub-external loaded, should allow to dlopen() a phat binary (or a double-precision binary) with the double-precision parts not doing any harm.
fgmasdr IOhannes
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1
iQIcBAEBCAAGBQJU0fnBAAoJELZQGcR/ejb4ZvsQAIq1zomPlsirrBGFE7oVIc1p qPecDk9zReG1E/wSyU6ntLNasXUAojd44eTo4acijH86RR7n+MRQB5RgAAhmf1mm ZVesL8R7AoJ1qYkCg8AfkgSkYD+GZWydebfiEHTiWks4fq7amzYWeHk8BENMHCAU 4f7j2N1bp66E1GQTdhS/dI/Rm39Q/8Ja8M7lrI2nYbQx0WzGBYFV9hMkuYGO96zq aCNb3+UCMwTUDfWRFnyeGxTystOOB2kuaxPDKivYmpduX7Anfryb/IaypkVBxRoQ goU2b/FhglKyiNtlQRLqDwbxSgMD84rfwxFnQbGyRA79ZQHEi+riYB0l9ayrO3pM PwDKcfMIBA09awtWlv+a7uYXrQgK44nZcSoHkvZgGuZmQobEAZIwWKw8VgO+H5Di D/XoUDmXGPsHnElSc1kSMFwk0jIXZb2QaVQAK3fy4xvAZ+wWbzcPdS5GdF4rw0QR rXyjXMRY84G+3j+a5X4pByVaR6LFFDGaacnKE8hltdYhFhDhbrH6PQ/jn/UJGAMG JY+44knoIJQPlnXrWzsn56VnVXet8uE4SG1XSIueSKZpvwVJ42aYmStXZHJygk/r eQ0EMZ2YzIRbssCux5OYM7Oos/XOT2nSqE6aAFJACMJ2j++pEJUspOZwkC2DJc2I 31iJOloztJrgoa3z++RI =ZJt5 -----END PGP SIGNATURE-----
Pd-dev mailing list Pd-dev@lists.iem.at http://lists.puredata.info/listinfo/pd-dev