zrax / pycdc

C++ python bytecode disassembler and decompiler
GNU General Public License v3.0
3.38k stars 645 forks source link

Code flags issue #504

Closed greenozon closed 3 months ago

greenozon commented 3 months ago

@zrax I wanted to extend code flags with more flags, but it turned out some kind of mystery....

currently we have this set of bits embedded in the code:

class PycCode : public PycObject {
public:
    enum CodeFlags {
        CO_OPTIMIZED = 0x1,
        CO_NEWLOCALS = 0x2,
        CO_VARARGS = 0x4,
        CO_VARKEYWORDS = 0x8,
        CO_NESTED = 0x10,
        CO_GENERATOR = 0x20,
        CO_NOFREE = 0x40,
        CO_COROUTINE = 0x80,
        CO_ITERABLE_COROUTINE = 0x100,
        CO_ASYNC_GENERATOR = 0x200,
        CO_GENERATOR_ALLOWED = 0x1000,
        CO_FUTURE_DIVISION = 0x2000,
        CO_FUTURE_ABSOLUTE_IMPORT = 0x4000,
        CO_FUTURE_WITH_STATEMENT = 0x8000,
        CO_FUTURE_PRINT_FUNCTION = 0x10000,
        CO_FUTURE_UNICODE_LITERALS = 0x20000,
        CO_FUTURE_BARRY_AS_BDFL = 0x40000,
        CO_FUTURE_GENERATOR_STOP = 0x80000,
        CO_FUTURE_ANNOTATIONS = 0x100000,
    };

I"ve found that Pythons version 3.6, 3.7 have the on par values in the CPython:

#define CO_FUTURE_DIVISION      0x2000
#define CO_FUTURE_ABSOLUTE_IMPORT 0x4000 /* do absolute imports by default */
#define CO_FUTURE_WITH_STATEMENT  0x8000
#define CO_FUTURE_PRINT_FUNCTION  0x10000
#define CO_FUTURE_UNICODE_LITERALS 0x20000

#define CO_FUTURE_BARRY_AS_BDFL  0x40000
#define CO_FUTURE_GENERATOR_STOP  0x80000

but starting from Python 3.8 (though the comment says from 3.9) the values had been changed as follows:

/* bpo-39562: These constant values are changed in Python 3.9
   to prevent collision with compiler flags. CO_FUTURE_ and PyCF_
   constants must be kept unique. PyCF_ constants can use bits from
   0x0100 to 0x10000. CO_FUTURE_ constants use bits starting at 0x20000. */
#define CO_FUTURE_DIVISION      0x20000
#define CO_FUTURE_ABSOLUTE_IMPORT 0x40000 /* do absolute imports by default */
#define CO_FUTURE_WITH_STATEMENT  0x80000
#define CO_FUTURE_PRINT_FUNCTION  0x100000
#define CO_FUTURE_UNICODE_LITERALS 0x200000

#define CO_FUTURE_BARRY_AS_BDFL  0x400000
#define CO_FUTURE_GENERATOR_STOP  0x800000
#define CO_FUTURE_ANNOTATIONS    0x1000000

so the question is - should be somehow keep 2 differnt sets of enums? and do you know what it was changed historically...