annotate Modules/_pickle.c @ 79691:05c8928362ee

Merge __next__ method link fixes with 3.3.
author Ezio Melotti <ezio.melotti@gmail.com>
date Fri, 12 Oct 2012 13:46:37 +0300
parents 9e5fb0b274d8
children c9d205e2dd02
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1 #include "Python.h"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2 #include "structmember.h"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4 PyDoc_STRVAR(pickle_module_doc,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5 "Optimized C implementation for the Python pickle module.");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
7 /* Bump this when new opcodes are added to the pickle protocol. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
8 enum {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
9 HIGHEST_PROTOCOL = 3,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
10 DEFAULT_PROTOCOL = 3
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
11 };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
12
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
13 /* Pickle opcodes. These must be kept updated with pickle.py.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
14 Extensive docs are in pickletools.py. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
15 enum opcode {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
16 MARK = '(',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
17 STOP = '.',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
18 POP = '0',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
19 POP_MARK = '1',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
20 DUP = '2',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
21 FLOAT = 'F',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
22 INT = 'I',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
23 BININT = 'J',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
24 BININT1 = 'K',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
25 LONG = 'L',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
26 BININT2 = 'M',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
27 NONE = 'N',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
28 PERSID = 'P',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
29 BINPERSID = 'Q',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
30 REDUCE = 'R',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
31 STRING = 'S',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
32 BINSTRING = 'T',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
33 SHORT_BINSTRING = 'U',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
34 UNICODE = 'V',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
35 BINUNICODE = 'X',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
36 APPEND = 'a',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
37 BUILD = 'b',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
38 GLOBAL = 'c',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
39 DICT = 'd',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
40 EMPTY_DICT = '}',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
41 APPENDS = 'e',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
42 GET = 'g',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
43 BINGET = 'h',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
44 INST = 'i',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
45 LONG_BINGET = 'j',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
46 LIST = 'l',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
47 EMPTY_LIST = ']',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
48 OBJ = 'o',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
49 PUT = 'p',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
50 BINPUT = 'q',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
51 LONG_BINPUT = 'r',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
52 SETITEM = 's',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
53 TUPLE = 't',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
54 EMPTY_TUPLE = ')',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
55 SETITEMS = 'u',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
56 BINFLOAT = 'G',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
57
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
58 /* Protocol 2. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
59 PROTO = '\x80',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
60 NEWOBJ = '\x81',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
61 EXT1 = '\x82',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
62 EXT2 = '\x83',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
63 EXT4 = '\x84',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
64 TUPLE1 = '\x85',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
65 TUPLE2 = '\x86',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
66 TUPLE3 = '\x87',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
67 NEWTRUE = '\x88',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
68 NEWFALSE = '\x89',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
69 LONG1 = '\x8a',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
70 LONG4 = '\x8b',
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
71
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
72 /* Protocol 3 (Python 3.x) */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
73 BINBYTES = 'B',
66106
194f30dc4703 Issue #10359: Remove useless comma, invalid in ISO C
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65599
diff changeset
74 SHORT_BINBYTES = 'C'
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
75 };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
76
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
77 /* These aren't opcodes -- they're ways to pickle bools before protocol 2
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
78 * so that unpicklers written before bools were introduced unpickle them
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
79 * as ints, but unpicklers after can recognize that bools were intended.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
80 * Note that protocol 2 added direct ways to pickle bools.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
81 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
82 #undef TRUE
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
83 #define TRUE "I01\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
84 #undef FALSE
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
85 #define FALSE "I00\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
86
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
87 enum {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
88 /* Keep in synch with pickle.Pickler._BATCHSIZE. This is how many elements
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
89 batch_list/dict() pumps out before doing APPENDS/SETITEMS. Nothing will
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
90 break if this gets out of synch with pickle.py, but it's unclear that would
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
91 help anything either. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
92 BATCHSIZE = 1000,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
93
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
94 /* Nesting limit until Pickler, when running in "fast mode", starts
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
95 checking for self-referential data-structures. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
96 FAST_NESTING_LIMIT = 50,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
97
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
98 /* Initial size of the write buffer of Pickler. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
99 WRITE_BUF_SIZE = 4096,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
100
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
101 /* Maximum size of the write buffer of Pickler when pickling to a
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
102 stream. This is ignored for in-memory pickling. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
103 MAX_WRITE_BUF_SIZE = 64 * 1024,
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
104
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
105 /* Prefetch size when unpickling (disabled on unpeekable streams) */
66106
194f30dc4703 Issue #10359: Remove useless comma, invalid in ISO C
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65599
diff changeset
106 PREFETCH = 8192 * 16
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
107 };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
108
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
109 /* Exception classes for pickle. These should override the ones defined in
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
110 pickle.py, when the C-optimized Pickler and Unpickler are used. */
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
111 static PyObject *PickleError = NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
112 static PyObject *PicklingError = NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
113 static PyObject *UnpicklingError = NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
114
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
115 /* copyreg.dispatch_table, {type_object: pickling_function} */
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
116 static PyObject *dispatch_table = NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
117 /* For EXT[124] opcodes. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
118 /* copyreg._extension_registry, {(module_name, function_name): code} */
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
119 static PyObject *extension_registry = NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
120 /* copyreg._inverted_registry, {code: (module_name, function_name)} */
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
121 static PyObject *inverted_registry = NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
122 /* copyreg._extension_cache, {code: object} */
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
123 static PyObject *extension_cache = NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
124
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
125 /* _compat_pickle.NAME_MAPPING, {(oldmodule, oldname): (newmodule, newname)} */
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
126 static PyObject *name_mapping_2to3 = NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
127 /* _compat_pickle.IMPORT_MAPPING, {oldmodule: newmodule} */
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
128 static PyObject *import_mapping_2to3 = NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
129 /* Same, but with REVERSE_NAME_MAPPING / REVERSE_IMPORT_MAPPING */
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
130 static PyObject *name_mapping_3to2 = NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
131 static PyObject *import_mapping_3to2 = NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
132
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
133 /* XXX: Are these really nescessary? */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
134 /* As the name says, an empty tuple. */
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
135 static PyObject *empty_tuple = NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
136 /* For looking up name pairs in copyreg._extension_registry. */
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
137 static PyObject *two_tuple = NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
138
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
139 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
140 stack_underflow(void)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
141 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
142 PyErr_SetString(UnpicklingError, "unpickling stack underflow");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
143 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
144 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
145
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
146 /* Internal data type used as the unpickling stack. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
147 typedef struct {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
148 PyObject_VAR_HEAD
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
149 PyObject **data;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
150 Py_ssize_t allocated; /* number of slots in data allocated */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
151 } Pdata;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
152
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
153 static void
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
154 Pdata_dealloc(Pdata *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
155 {
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
156 Py_ssize_t i = Py_SIZE(self);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
157 while (--i >= 0) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
158 Py_DECREF(self->data[i]);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
159 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
160 PyMem_FREE(self->data);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
161 PyObject_Del(self);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
162 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
163
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
164 static PyTypeObject Pdata_Type = {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
165 PyVarObject_HEAD_INIT(NULL, 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
166 "_pickle.Pdata", /*tp_name*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
167 sizeof(Pdata), /*tp_basicsize*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
168 0, /*tp_itemsize*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
169 (destructor)Pdata_dealloc, /*tp_dealloc*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
170 };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
171
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
172 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
173 Pdata_New(void)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
174 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
175 Pdata *self;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
176
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
177 if (!(self = PyObject_New(Pdata, &Pdata_Type)))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
178 return NULL;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
179 Py_SIZE(self) = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
180 self->allocated = 8;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
181 self->data = PyMem_MALLOC(self->allocated * sizeof(PyObject *));
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
182 if (self->data)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
183 return (PyObject *)self;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
184 Py_DECREF(self);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
185 return PyErr_NoMemory();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
186 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
187
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
188
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
189 /* Retain only the initial clearto items. If clearto >= the current
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
190 * number of items, this is a (non-erroneous) NOP.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
191 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
192 static int
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
193 Pdata_clear(Pdata *self, Py_ssize_t clearto)
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
194 {
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
195 Py_ssize_t i = Py_SIZE(self);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
196
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
197 if (clearto < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
198 return stack_underflow();
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
199 if (clearto >= i)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
200 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
201
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
202 while (--i >= clearto) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
203 Py_CLEAR(self->data[i]);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
204 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
205 Py_SIZE(self) = clearto;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
206 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
207 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
208
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
209 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
210 Pdata_grow(Pdata *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
211 {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
212 PyObject **data = self->data;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
213 Py_ssize_t allocated = self->allocated;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
214 Py_ssize_t new_allocated;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
215
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
216 new_allocated = (allocated >> 3) + 6;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
217 /* check for integer overflow */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
218 if (new_allocated > PY_SSIZE_T_MAX - allocated)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
219 goto nomemory;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
220 new_allocated += allocated;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
221 if (new_allocated > (PY_SSIZE_T_MAX / sizeof(PyObject *)))
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
222 goto nomemory;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
223 data = PyMem_REALLOC(data, new_allocated * sizeof(PyObject *));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
224 if (data == NULL)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
225 goto nomemory;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
226
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
227 self->data = data;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
228 self->allocated = new_allocated;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
229 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
230
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
231 nomemory:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
232 PyErr_NoMemory();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
233 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
234 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
235
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
236 /* D is a Pdata*. Pop the topmost element and store it into V, which
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
237 * must be an lvalue holding PyObject*. On stack underflow, UnpicklingError
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
238 * is raised and V is set to NULL.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
239 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
240 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
241 Pdata_pop(Pdata *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
242 {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
243 if (Py_SIZE(self) == 0) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
244 PyErr_SetString(UnpicklingError, "bad pickle data");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
245 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
246 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
247 return self->data[--Py_SIZE(self)];
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
248 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
249 #define PDATA_POP(D, V) do { (V) = Pdata_pop((D)); } while (0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
250
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
251 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
252 Pdata_push(Pdata *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
253 {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
254 if (Py_SIZE(self) == self->allocated && Pdata_grow(self) < 0) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
255 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
256 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
257 self->data[Py_SIZE(self)++] = obj;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
258 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
259 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
260
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
261 /* Push an object on stack, transferring its ownership to the stack. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
262 #define PDATA_PUSH(D, O, ER) do { \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
263 if (Pdata_push((D), (O)) < 0) return (ER); } while(0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
264
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
265 /* Push an object on stack, adding a new reference to the object. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
266 #define PDATA_APPEND(D, O, ER) do { \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
267 Py_INCREF((O)); \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
268 if (Pdata_push((D), (O)) < 0) return (ER); } while(0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
269
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
270 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
271 Pdata_poptuple(Pdata *self, Py_ssize_t start)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
272 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
273 PyObject *tuple;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
274 Py_ssize_t len, i, j;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
275
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
276 len = Py_SIZE(self) - start;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
277 tuple = PyTuple_New(len);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
278 if (tuple == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
279 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
280 for (i = start, j = 0; j < len; i++, j++)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
281 PyTuple_SET_ITEM(tuple, j, self->data[i]);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
282
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
283 Py_SIZE(self) = start;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
284 return tuple;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
285 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
286
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
287 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
288 Pdata_poplist(Pdata *self, Py_ssize_t start)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
289 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
290 PyObject *list;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
291 Py_ssize_t len, i, j;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
292
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
293 len = Py_SIZE(self) - start;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
294 list = PyList_New(len);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
295 if (list == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
296 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
297 for (i = start, j = 0; j < len; i++, j++)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
298 PyList_SET_ITEM(list, j, self->data[i]);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
299
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
300 Py_SIZE(self) = start;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
301 return list;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
302 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
303
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
304 typedef struct {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
305 PyObject *me_key;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
306 Py_ssize_t me_value;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
307 } PyMemoEntry;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
308
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
309 typedef struct {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
310 Py_ssize_t mt_mask;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
311 Py_ssize_t mt_used;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
312 Py_ssize_t mt_allocated;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
313 PyMemoEntry *mt_table;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
314 } PyMemoTable;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
315
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
316 typedef struct PicklerObject {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
317 PyObject_HEAD
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
318 PyMemoTable *memo; /* Memo table, keep track of the seen
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
319 objects to support self-referential objects
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
320 pickling. */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
321 PyObject *pers_func; /* persistent_id() method, can be NULL */
75391
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
322 PyObject *dispatch_table; /* private dispatch_table, can be NULL */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
323 PyObject *arg;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
324
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
325 PyObject *write; /* write() method of the output stream. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
326 PyObject *output_buffer; /* Write into a local bytearray buffer before
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
327 flushing to the stream. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
328 Py_ssize_t output_len; /* Length of output_buffer. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
329 Py_ssize_t max_output_len; /* Allocation size of output_buffer. */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
330 int proto; /* Pickle protocol number, >= 0 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
331 int bin; /* Boolean, true if proto > 0 */
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
332 Py_ssize_t buf_size; /* Size of the current buffered pickle data */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
333 int fast; /* Enable fast mode if set to a true value.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
334 The fast mode disable the usage of memo,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
335 therefore speeding the pickling process by
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
336 not generating superfluous PUT opcodes. It
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
337 should not be used if with self-referential
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
338 objects. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
339 int fast_nesting;
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
340 int fix_imports; /* Indicate whether Pickler should fix
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
341 the name of globals for Python 2.x. */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
342 PyObject *fast_memo;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
343 } PicklerObject;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
344
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
345 typedef struct UnpicklerObject {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
346 PyObject_HEAD
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
347 Pdata *stack; /* Pickle data stack, store unpickled objects. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
348
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
349 /* The unpickler memo is just an array of PyObject *s. Using a dict
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
350 is unnecessary, since the keys are contiguous ints. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
351 PyObject **memo;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
352 Py_ssize_t memo_size;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
353
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
354 PyObject *arg;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
355 PyObject *pers_func; /* persistent_load() method, can be NULL. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
356
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
357 Py_buffer buffer;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
358 char *input_buffer;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
359 char *input_line;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
360 Py_ssize_t input_len;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
361 Py_ssize_t next_read_idx;
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
362 Py_ssize_t prefetched_idx; /* index of first prefetched byte */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
363 PyObject *read; /* read() method of the input stream. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
364 PyObject *readline; /* readline() method of the input stream. */
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
365 PyObject *peek; /* peek() method of the input stream, or NULL */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
366
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
367 char *encoding; /* Name of the encoding to be used for
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
368 decoding strings pickled using Python
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
369 2.x. The default value is "ASCII" */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
370 char *errors; /* Name of errors handling scheme to used when
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
371 decoding strings. The default value is
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
372 "strict". */
73957
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
373 Py_ssize_t *marks; /* Mark stack, used for unpickling container
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
374 objects. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
375 Py_ssize_t num_marks; /* Number of marks in the mark stack. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
376 Py_ssize_t marks_size; /* Current allocated size of the mark stack. */
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
377 int proto; /* Protocol of the pickle loaded. */
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
378 int fix_imports; /* Indicate whether Unpickler should fix
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
379 the name of globals pickled by Python 2.x. */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
380 } UnpicklerObject;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
381
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
382 /* Forward declarations */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
383 static int save(PicklerObject *, PyObject *, int);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
384 static int save_reduce(PicklerObject *, PyObject *, PyObject *);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
385 static PyTypeObject Pickler_Type;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
386 static PyTypeObject Unpickler_Type;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
387
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
388
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
389 /*************************************************************************
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
390 A custom hashtable mapping void* to longs. This is used by the pickler for
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
391 memoization. Using a custom hashtable rather than PyDict allows us to skip
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
392 a bunch of unnecessary object creation. This makes a huge performance
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
393 difference. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
394
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
395 #define MT_MINSIZE 8
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
396 #define PERTURB_SHIFT 5
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
397
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
398
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
399 static PyMemoTable *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
400 PyMemoTable_New(void)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
401 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
402 PyMemoTable *memo = PyMem_MALLOC(sizeof(PyMemoTable));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
403 if (memo == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
404 PyErr_NoMemory();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
405 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
406 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
407
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
408 memo->mt_used = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
409 memo->mt_allocated = MT_MINSIZE;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
410 memo->mt_mask = MT_MINSIZE - 1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
411 memo->mt_table = PyMem_MALLOC(MT_MINSIZE * sizeof(PyMemoEntry));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
412 if (memo->mt_table == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
413 PyMem_FREE(memo);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
414 PyErr_NoMemory();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
415 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
416 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
417 memset(memo->mt_table, 0, MT_MINSIZE * sizeof(PyMemoEntry));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
418
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
419 return memo;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
420 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
421
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
422 static PyMemoTable *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
423 PyMemoTable_Copy(PyMemoTable *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
424 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
425 Py_ssize_t i;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
426 PyMemoTable *new = PyMemoTable_New();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
427 if (new == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
428 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
429
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
430 new->mt_used = self->mt_used;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
431 new->mt_allocated = self->mt_allocated;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
432 new->mt_mask = self->mt_mask;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
433 /* The table we get from _New() is probably smaller than we wanted.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
434 Free it and allocate one that's the right size. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
435 PyMem_FREE(new->mt_table);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
436 new->mt_table = PyMem_MALLOC(self->mt_allocated * sizeof(PyMemoEntry));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
437 if (new->mt_table == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
438 PyMem_FREE(new);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
439 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
440 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
441 for (i = 0; i < self->mt_allocated; i++) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
442 Py_XINCREF(self->mt_table[i].me_key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
443 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
444 memcpy(new->mt_table, self->mt_table,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
445 sizeof(PyMemoEntry) * self->mt_allocated);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
446
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
447 return new;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
448 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
449
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
450 static Py_ssize_t
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
451 PyMemoTable_Size(PyMemoTable *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
452 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
453 return self->mt_used;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
454 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
455
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
456 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
457 PyMemoTable_Clear(PyMemoTable *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
458 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
459 Py_ssize_t i = self->mt_allocated;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
460
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
461 while (--i >= 0) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
462 Py_XDECREF(self->mt_table[i].me_key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
463 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
464 self->mt_used = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
465 memset(self->mt_table, 0, self->mt_allocated * sizeof(PyMemoEntry));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
466 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
467 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
468
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
469 static void
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
470 PyMemoTable_Del(PyMemoTable *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
471 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
472 if (self == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
473 return;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
474 PyMemoTable_Clear(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
475
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
476 PyMem_FREE(self->mt_table);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
477 PyMem_FREE(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
478 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
479
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
480 /* Since entries cannot be deleted from this hashtable, _PyMemoTable_Lookup()
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
481 can be considerably simpler than dictobject.c's lookdict(). */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
482 static PyMemoEntry *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
483 _PyMemoTable_Lookup(PyMemoTable *self, PyObject *key)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
484 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
485 size_t i;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
486 size_t perturb;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
487 size_t mask = (size_t)self->mt_mask;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
488 PyMemoEntry *table = self->mt_table;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
489 PyMemoEntry *entry;
65494
e8969fb822fc make hashes always the size of pointers; introduce Py_hash_t #9778
Benjamin Peterson <benjamin@python.org>
parents: 65224
diff changeset
490 Py_hash_t hash = (Py_hash_t)key >> 3;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
491
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
492 i = hash & mask;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
493 entry = &table[i];
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
494 if (entry->me_key == NULL || entry->me_key == key)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
495 return entry;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
496
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
497 for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
498 i = (i << 2) + i + perturb + 1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
499 entry = &table[i & mask];
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
500 if (entry->me_key == NULL || entry->me_key == key)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
501 return entry;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
502 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
503 assert(0); /* Never reached */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
504 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
505 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
506
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
507 /* Returns -1 on failure, 0 on success. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
508 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
509 _PyMemoTable_ResizeTable(PyMemoTable *self, Py_ssize_t min_size)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
510 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
511 PyMemoEntry *oldtable = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
512 PyMemoEntry *oldentry, *newentry;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
513 Py_ssize_t new_size = MT_MINSIZE;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
514 Py_ssize_t to_process;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
515
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
516 assert(min_size > 0);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
517
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
518 /* Find the smallest valid table size >= min_size. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
519 while (new_size < min_size && new_size > 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
520 new_size <<= 1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
521 if (new_size <= 0) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
522 PyErr_NoMemory();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
523 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
524 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
525 /* new_size needs to be a power of two. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
526 assert((new_size & (new_size - 1)) == 0);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
527
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
528 /* Allocate new table. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
529 oldtable = self->mt_table;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
530 self->mt_table = PyMem_MALLOC(new_size * sizeof(PyMemoEntry));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
531 if (self->mt_table == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
532 PyMem_FREE(oldtable);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
533 PyErr_NoMemory();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
534 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
535 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
536 self->mt_allocated = new_size;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
537 self->mt_mask = new_size - 1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
538 memset(self->mt_table, 0, sizeof(PyMemoEntry) * new_size);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
539
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
540 /* Copy entries from the old table. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
541 to_process = self->mt_used;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
542 for (oldentry = oldtable; to_process > 0; oldentry++) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
543 if (oldentry->me_key != NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
544 to_process--;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
545 /* newentry is a pointer to a chunk of the new
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
546 mt_table, so we're setting the key:value pair
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
547 in-place. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
548 newentry = _PyMemoTable_Lookup(self, oldentry->me_key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
549 newentry->me_key = oldentry->me_key;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
550 newentry->me_value = oldentry->me_value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
551 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
552 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
553
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
554 /* Deallocate the old table. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
555 PyMem_FREE(oldtable);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
556 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
557 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
558
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
559 /* Returns NULL on failure, a pointer to the value otherwise. */
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
560 static Py_ssize_t *
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
561 PyMemoTable_Get(PyMemoTable *self, PyObject *key)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
562 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
563 PyMemoEntry *entry = _PyMemoTable_Lookup(self, key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
564 if (entry->me_key == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
565 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
566 return &entry->me_value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
567 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
568
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
569 /* Returns -1 on failure, 0 on success. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
570 static int
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
571 PyMemoTable_Set(PyMemoTable *self, PyObject *key, Py_ssize_t value)
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
572 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
573 PyMemoEntry *entry;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
574
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
575 assert(key != NULL);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
576
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
577 entry = _PyMemoTable_Lookup(self, key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
578 if (entry->me_key != NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
579 entry->me_value = value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
580 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
581 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
582 Py_INCREF(key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
583 entry->me_key = key;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
584 entry->me_value = value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
585 self->mt_used++;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
586
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
587 /* If we added a key, we can safely resize. Otherwise just return!
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
588 * If used >= 2/3 size, adjust size. Normally, this quaduples the size.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
589 *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
590 * Quadrupling the size improves average table sparseness
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
591 * (reducing collisions) at the cost of some memory. It also halves
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
592 * the number of expensive resize operations in a growing memo table.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
593 *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
594 * Very large memo tables (over 50K items) use doubling instead.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
595 * This may help applications with severe memory constraints.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
596 */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
597 if (!(self->mt_used * 3 >= (self->mt_mask + 1) * 2))
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
598 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
599 return _PyMemoTable_ResizeTable(self,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
600 (self->mt_used > 50000 ? 2 : 4) * self->mt_used);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
601 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
602
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
603 #undef MT_MINSIZE
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
604 #undef PERTURB_SHIFT
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
605
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
606 /*************************************************************************/
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
607
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
608 /* Helpers for creating the argument tuple passed to functions. This has the
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
609 performance advantage of calling PyTuple_New() only once.
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
610
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
611 XXX(avassalotti): Inline directly in _Pickler_FastCall() and
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
612 _Unpickler_FastCall(). */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
613 #define ARG_TUP(self, obj) do { \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
614 if ((self)->arg || ((self)->arg=PyTuple_New(1))) { \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
615 Py_XDECREF(PyTuple_GET_ITEM((self)->arg, 0)); \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
616 PyTuple_SET_ITEM((self)->arg, 0, (obj)); \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
617 } \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
618 else { \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
619 Py_DECREF((obj)); \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
620 } \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
621 } while (0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
622
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
623 #define FREE_ARG_TUP(self) do { \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
624 if ((self)->arg->ob_refcnt > 1) \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
625 Py_CLEAR((self)->arg); \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
626 } while (0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
627
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
628 /* A temporary cleaner API for fast single argument function call.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
629
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
630 XXX: Does caching the argument tuple provides any real performance benefits?
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
631
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
632 A quick benchmark, on a 2.0GHz Athlon64 3200+ running Linux 2.6.24 with
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
633 glibc 2.7, tells me that it takes roughly 20,000,000 PyTuple_New(1) calls
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
634 when the tuple is retrieved from the freelist (i.e, call PyTuple_New() then
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
635 immediately DECREF it) and 1,200,000 calls when allocating brand new tuples
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
636 (i.e, call PyTuple_New() and store the returned value in an array), to save
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
637 one second (wall clock time). Either ways, the loading time a pickle stream
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
638 large enough to generate this number of calls would be massively
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
639 overwhelmed by other factors, like I/O throughput, the GC traversal and
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
640 object allocation overhead. So, I really doubt these functions provide any
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
641 real benefits.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
642
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
643 On the other hand, oprofile reports that pickle spends a lot of time in
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
644 these functions. But, that is probably more related to the function call
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
645 overhead, than the argument tuple allocation.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
646
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
647 XXX: And, what is the reference behavior of these? Steal, borrow? At first
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
648 glance, it seems to steal the reference of 'arg' and borrow the reference
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
649 of 'func'. */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
650 static PyObject *
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
651 _Pickler_FastCall(PicklerObject *self, PyObject *func, PyObject *arg)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
652 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
653 PyObject *result = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
654
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
655 ARG_TUP(self, arg);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
656 if (self->arg) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
657 result = PyObject_Call(func, self->arg, NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
658 FREE_ARG_TUP(self);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
659 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
660 return result;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
661 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
662
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
663 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
664 _Pickler_ClearBuffer(PicklerObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
665 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
666 Py_CLEAR(self->output_buffer);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
667 self->output_buffer =
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
668 PyBytes_FromStringAndSize(NULL, self->max_output_len);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
669 if (self->output_buffer == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
670 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
671 self->output_len = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
672 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
673 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
674
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
675 static PyObject *
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
676 _Pickler_GetString(PicklerObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
677 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
678 PyObject *output_buffer = self->output_buffer;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
679
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
680 assert(self->output_buffer != NULL);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
681 self->output_buffer = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
682 /* Resize down to exact size */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
683 if (_PyBytes_Resize(&output_buffer, self->output_len) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
684 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
685 return output_buffer;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
686 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
687
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
688 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
689 _Pickler_FlushToFile(PicklerObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
690 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
691 PyObject *output, *result;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
692
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
693 assert(self->write != NULL);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
694
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
695 output = _Pickler_GetString(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
696 if (output == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
697 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
698
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
699 result = _Pickler_FastCall(self, self->write, output);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
700 Py_XDECREF(result);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
701 return (result == NULL) ? -1 : 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
702 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
703
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
704 static Py_ssize_t
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
705 _Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t n)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
706 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
707 Py_ssize_t i, required;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
708 char *buffer;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
709
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
710 assert(s != NULL);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
711
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
712 required = self->output_len + n;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
713 if (required > self->max_output_len) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
714 if (self->write != NULL && required > MAX_WRITE_BUF_SIZE) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
715 /* XXX This reallocates a new buffer every time, which is a bit
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
716 wasteful. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
717 if (_Pickler_FlushToFile(self) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
718 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
719 if (_Pickler_ClearBuffer(self) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
720 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
721 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
722 if (self->write != NULL && n > MAX_WRITE_BUF_SIZE) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
723 /* we already flushed above, so the buffer is empty */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
724 PyObject *result;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
725 /* XXX we could spare an intermediate copy and pass
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
726 a memoryview instead */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
727 PyObject *output = PyBytes_FromStringAndSize(s, n);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
728 if (s == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
729 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
730 result = _Pickler_FastCall(self, self->write, output);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
731 Py_XDECREF(result);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
732 return (result == NULL) ? -1 : 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
733 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
734 else {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
735 if (self->output_len >= PY_SSIZE_T_MAX / 2 - n) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
736 PyErr_NoMemory();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
737 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
738 }
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
739 self->max_output_len = (self->output_len + n) / 2 * 3;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
740 if (_PyBytes_Resize(&self->output_buffer, self->max_output_len) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
741 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
742 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
743 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
744 buffer = PyBytes_AS_STRING(self->output_buffer);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
745 if (n < 8) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
746 /* This is faster than memcpy when the string is short. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
747 for (i = 0; i < n; i++) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
748 buffer[self->output_len + i] = s[i];
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
749 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
750 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
751 else {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
752 memcpy(buffer + self->output_len, s, n);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
753 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
754 self->output_len += n;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
755 return n;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
756 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
757
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
758 static PicklerObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
759 _Pickler_New(void)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
760 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
761 PicklerObject *self;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
762
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
763 self = PyObject_GC_New(PicklerObject, &Pickler_Type);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
764 if (self == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
765 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
766
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
767 self->pers_func = NULL;
75391
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
768 self->dispatch_table = NULL;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
769 self->arg = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
770 self->write = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
771 self->proto = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
772 self->bin = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
773 self->fast = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
774 self->fast_nesting = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
775 self->fix_imports = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
776 self->fast_memo = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
777
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
778 self->memo = PyMemoTable_New();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
779 if (self->memo == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
780 Py_DECREF(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
781 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
782 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
783 self->max_output_len = WRITE_BUF_SIZE;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
784 self->output_len = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
785 self->output_buffer = PyBytes_FromStringAndSize(NULL,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
786 self->max_output_len);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
787 if (self->output_buffer == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
788 Py_DECREF(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
789 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
790 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
791 return self;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
792 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
793
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
794 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
795 _Pickler_SetProtocol(PicklerObject *self, PyObject *proto_obj,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
796 PyObject *fix_imports_obj)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
797 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
798 long proto = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
799 int fix_imports;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
800
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
801 if (proto_obj == NULL || proto_obj == Py_None)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
802 proto = DEFAULT_PROTOCOL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
803 else {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
804 proto = PyLong_AsLong(proto_obj);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
805 if (proto == -1 && PyErr_Occurred())
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
806 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
807 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
808 if (proto < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
809 proto = HIGHEST_PROTOCOL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
810 if (proto > HIGHEST_PROTOCOL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
811 PyErr_Format(PyExc_ValueError, "pickle protocol must be <= %d",
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
812 HIGHEST_PROTOCOL);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
813 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
814 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
815 fix_imports = PyObject_IsTrue(fix_imports_obj);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
816 if (fix_imports == -1)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
817 return -1;
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
818
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
819 self->proto = proto;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
820 self->bin = proto > 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
821 self->fix_imports = fix_imports && proto < 3;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
822
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
823 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
824 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
825
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
826 /* Returns -1 (with an exception set) on failure, 0 on success. This may
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
827 be called once on a freshly created Pickler. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
828 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
829 _Pickler_SetOutputStream(PicklerObject *self, PyObject *file)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
830 {
72925
7109f31300fb Rename _Py_identifier to _Py_IDENTIFIER.
Martin v. Löwis <martin@v.loewis.de>
parents: 72918
diff changeset
831 _Py_IDENTIFIER(write);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
832 assert(file != NULL);
72848
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
833 self->write = _PyObject_GetAttrId(file, &PyId_write);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
834 if (self->write == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
835 if (PyErr_ExceptionMatches(PyExc_AttributeError))
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
836 PyErr_SetString(PyExc_TypeError,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
837 "file must have a 'write' attribute");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
838 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
839 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
840
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
841 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
842 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
843
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
844 /* See documentation for _Pickler_FastCall(). */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
845 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
846 _Unpickler_FastCall(UnpicklerObject *self, PyObject *func, PyObject *arg)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
847 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
848 PyObject *result = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
849
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
850 ARG_TUP(self, arg);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
851 if (self->arg) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
852 result = PyObject_Call(func, self->arg, NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
853 FREE_ARG_TUP(self);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
854 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
855 return result;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
856 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
857
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
858 /* Returns the size of the input on success, -1 on failure. This takes its
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
859 own reference to `input`. */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
860 static Py_ssize_t
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
861 _Unpickler_SetStringInput(UnpicklerObject *self, PyObject *input)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
862 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
863 if (self->buffer.buf != NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
864 PyBuffer_Release(&self->buffer);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
865 if (PyObject_GetBuffer(input, &self->buffer, PyBUF_CONTIG_RO) < 0)
49546
bc1f43252c92 #3664: The pickle module could segfault if a Pickler instance is not correctly initialized:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49149
diff changeset
866 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
867 self->input_buffer = self->buffer.buf;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
868 self->input_len = self->buffer.len;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
869 self->next_read_idx = 0;
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
870 self->prefetched_idx = self->input_len;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
871 return self->input_len;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
872 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
873
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
874 static int
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
875 _Unpickler_SkipConsumed(UnpicklerObject *self)
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
876 {
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
877 Py_ssize_t consumed = self->next_read_idx - self->prefetched_idx;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
878
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
879 if (consumed > 0) {
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
880 PyObject *r;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
881 assert(self->peek); /* otherwise we did something wrong */
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
882 /* This makes an useless copy... */
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
883 r = PyObject_CallFunction(self->read, "n", consumed);
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
884 if (r == NULL)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
885 return -1;
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
886 Py_DECREF(r);
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
887 self->prefetched_idx = self->next_read_idx;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
888 }
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
889 return 0;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
890 }
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
891
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
892 static const Py_ssize_t READ_WHOLE_LINE = -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
893
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
894 /* If reading from a file, we need to only pull the bytes we need, since there
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
895 may be multiple pickle objects arranged contiguously in the same input
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
896 buffer.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
897
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
898 If `n` is READ_WHOLE_LINE, read a whole line. Otherwise, read up to `n`
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
899 bytes from the input stream/buffer.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
900
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
901 Update the unpickler's input buffer with the newly-read data. Returns -1 on
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
902 failure; on success, returns the number of bytes read from the file.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
903
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
904 On success, self->input_len will be 0; this is intentional so that when
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
905 unpickling from a file, the "we've run out of data" code paths will trigger,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
906 causing the Unpickler to go back to the file for more data. Use the returned
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
907 size to tell you how much data you can process. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
908 static Py_ssize_t
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
909 _Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
910 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
911 PyObject *data;
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
912 Py_ssize_t read_size, prefetched_size = 0;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
913
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
914 assert(self->read != NULL);
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
915
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
916 if (_Unpickler_SkipConsumed(self) < 0)
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
917 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
918
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
919 if (n == READ_WHOLE_LINE)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
920 data = PyObject_Call(self->readline, empty_tuple, NULL);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
921 else {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
922 PyObject *len = PyLong_FromSsize_t(n);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
923 if (len == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
924 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
925 data = _Unpickler_FastCall(self, self->read, len);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
926 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
927 if (data == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
928 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
929
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
930 /* Prefetch some data without advancing the file pointer, if possible */
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
931 if (self->peek) {
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
932 PyObject *len, *prefetched;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
933 len = PyLong_FromSsize_t(PREFETCH);
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
934 if (len == NULL) {
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
935 Py_DECREF(data);
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
936 return -1;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
937 }
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
938 prefetched = _Unpickler_FastCall(self, self->peek, len);
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
939 if (prefetched == NULL) {
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
940 if (PyErr_ExceptionMatches(PyExc_NotImplementedError)) {
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
941 /* peek() is probably not supported by the given file object */
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
942 PyErr_Clear();
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
943 Py_CLEAR(self->peek);
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
944 }
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
945 else {
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
946 Py_DECREF(data);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
947 return -1;
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
948 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
949 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
950 else {
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
951 assert(PyBytes_Check(prefetched));
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
952 prefetched_size = PyBytes_GET_SIZE(prefetched);
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
953 PyBytes_ConcatAndDel(&data, prefetched);
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
954 if (data == NULL)
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
955 return -1;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
956 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
957 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
958
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
959 read_size = _Unpickler_SetStringInput(self, data) - prefetched_size;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
960 Py_DECREF(data);
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
961 self->prefetched_idx = read_size;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
962 return read_size;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
963 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
964
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
965 /* Read `n` bytes from the unpickler's data source, storing the result in `*s`.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
966
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
967 This should be used for all data reads, rather than accessing the unpickler's
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
968 input buffer directly. This method deals correctly with reading from input
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
969 streams, which the input buffer doesn't deal with.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
970
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
971 Note that when reading from a file-like object, self->next_read_idx won't
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
972 be updated (it should remain at 0 for the entire unpickling process). You
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
973 should use this function's return value to know how many bytes you can
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
974 consume.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
975
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
976 Returns -1 (with an exception set) on failure. On success, return the
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
977 number of chars read. */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
978 static Py_ssize_t
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
979 _Unpickler_Read(UnpicklerObject *self, char **s, Py_ssize_t n)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
980 {
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
981 Py_ssize_t num_read;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
982
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
983 if (self->next_read_idx + n <= self->input_len) {
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
984 *s = self->input_buffer + self->next_read_idx;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
985 self->next_read_idx += n;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
986 return n;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
987 }
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
988 if (!self->read) {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
989 PyErr_Format(PyExc_EOFError, "Ran out of input");
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
990 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
991 }
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
992 num_read = _Unpickler_ReadFromFile(self, n);
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
993 if (num_read < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
994 return -1;
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
995 if (num_read < n) {
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
996 PyErr_Format(PyExc_EOFError, "Ran out of input");
49705
218a98981183 #4298: pickle.load() can segfault on invalid or truncated input.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49638
diff changeset
997 return -1;
218a98981183 #4298: pickle.load() can segfault on invalid or truncated input.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49638
diff changeset
998 }
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
999 *s = self->input_buffer;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
1000 self->next_read_idx = n;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1001 return n;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1002 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1003
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1004 static Py_ssize_t
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1005 _Unpickler_CopyLine(UnpicklerObject *self, char *line, Py_ssize_t len,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1006 char **result)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1007 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1008 char *input_line = PyMem_Realloc(self->input_line, len + 1);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1009 if (input_line == NULL)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1010 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1011
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1012 memcpy(input_line, line, len);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1013 input_line[len] = '\0';
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1014 self->input_line = input_line;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1015 *result = self->input_line;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1016 return len;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1017 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1018
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1019 /* Read a line from the input stream/buffer. If we run off the end of the input
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1020 before hitting \n, return the data we found.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1021
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1022 Returns the number of chars read, or -1 on failure. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1023 static Py_ssize_t
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1024 _Unpickler_Readline(UnpicklerObject *self, char **result)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1025 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1026 Py_ssize_t i, num_read;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1027
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1028 for (i = self->next_read_idx; i < self->input_len; i++) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1029 if (self->input_buffer[i] == '\n') {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1030 char *line_start = self->input_buffer + self->next_read_idx;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1031 num_read = i - self->next_read_idx + 1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1032 self->next_read_idx = i + 1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1033 return _Unpickler_CopyLine(self, line_start, num_read, result);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1034 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1035 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1036 if (self->read) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1037 num_read = _Unpickler_ReadFromFile(self, READ_WHOLE_LINE);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1038 if (num_read < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1039 return -1;
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
1040 self->next_read_idx = num_read;
71817
c47bc1349e61 Issue #12687: Fix a possible buffering bug when unpickling text mode (protocol 0, mostly) pickles.
Antoine Pitrou <solipsis@pitrou.net>
parents: 71347
diff changeset
1041 return _Unpickler_CopyLine(self, self->input_buffer, num_read, result);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1042 }
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
1043
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1044 /* If we get here, we've run off the end of the input string. Return the
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1045 remaining string and let the caller figure it out. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1046 *result = self->input_buffer + self->next_read_idx;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1047 num_read = i - self->next_read_idx;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1048 self->next_read_idx = i;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1049 return num_read;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1050 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1051
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1052 /* Returns -1 (with an exception set) on failure, 0 on success. The memo array
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1053 will be modified in place. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1054 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1055 _Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1056 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1057 Py_ssize_t i;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1058 PyObject **memo;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1059
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1060 assert(new_size > self->memo_size);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1061
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1062 memo = PyMem_REALLOC(self->memo, new_size * sizeof(PyObject *));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1063 if (memo == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1064 PyErr_NoMemory();
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1065 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1066 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1067 self->memo = memo;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1068 for (i = self->memo_size; i < new_size; i++)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1069 self->memo[i] = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1070 self->memo_size = new_size;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1071 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1072 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1073
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1074 /* Returns NULL if idx is out of bounds. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1075 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1076 _Unpickler_MemoGet(UnpicklerObject *self, Py_ssize_t idx)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1077 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1078 if (idx < 0 || idx >= self->memo_size)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1079 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1080
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1081 return self->memo[idx];
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1082 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1083
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1084 /* Returns -1 (with an exception set) on failure, 0 on success.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1085 This takes its own reference to `value`. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1086 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1087 _Unpickler_MemoPut(UnpicklerObject *self, Py_ssize_t idx, PyObject *value)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1088 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1089 PyObject *old_item;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1090
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1091 if (idx >= self->memo_size) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1092 if (_Unpickler_ResizeMemoList(self, idx * 2) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1093 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1094 assert(idx < self->memo_size);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1095 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1096 Py_INCREF(value);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1097 old_item = self->memo[idx];
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1098 self->memo[idx] = value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1099 Py_XDECREF(old_item);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1100 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1101 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1102
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1103 static PyObject **
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1104 _Unpickler_NewMemo(Py_ssize_t new_size)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1105 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1106 PyObject **memo = PyMem_MALLOC(new_size * sizeof(PyObject *));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1107 if (memo == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1108 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1109 memset(memo, 0, new_size * sizeof(PyObject *));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1110 return memo;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1111 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1112
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1113 /* Free the unpickler's memo, taking care to decref any items left in it. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1114 static void
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1115 _Unpickler_MemoCleanup(UnpicklerObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1116 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1117 Py_ssize_t i;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1118 PyObject **memo = self->memo;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1119
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1120 if (self->memo == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1121 return;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1122 self->memo = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1123 i = self->memo_size;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1124 while (--i >= 0) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1125 Py_XDECREF(memo[i]);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1126 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1127 PyMem_FREE(memo);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1128 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1129
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1130 static UnpicklerObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1131 _Unpickler_New(void)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1132 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1133 UnpicklerObject *self;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1134
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1135 self = PyObject_GC_New(UnpicklerObject, &Unpickler_Type);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1136 if (self == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1137 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1138
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1139 self->stack = (Pdata *)Pdata_New();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1140 if (self->stack == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1141 Py_DECREF(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1142 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1143 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1144 memset(&self->buffer, 0, sizeof(Py_buffer));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1145
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1146 self->memo_size = 32;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1147 self->memo = _Unpickler_NewMemo(self->memo_size);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1148 if (self->memo == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1149 Py_DECREF(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1150 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1151 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1152
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1153 self->arg = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1154 self->pers_func = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1155 self->input_buffer = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1156 self->input_line = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1157 self->input_len = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1158 self->next_read_idx = 0;
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
1159 self->prefetched_idx = 0;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1160 self->read = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1161 self->readline = NULL;
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
1162 self->peek = NULL;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1163 self->encoding = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1164 self->errors = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1165 self->marks = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1166 self->num_marks = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1167 self->marks_size = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1168 self->proto = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1169 self->fix_imports = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1170
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1171 return self;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1172 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1173
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1174 /* Returns -1 (with an exception set) on failure, 0 on success. This may
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1175 be called once on a freshly created Pickler. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1176 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1177 _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1178 {
72925
7109f31300fb Rename _Py_identifier to _Py_IDENTIFIER.
Martin v. Löwis <martin@v.loewis.de>
parents: 72918
diff changeset
1179 _Py_IDENTIFIER(peek);
7109f31300fb Rename _Py_identifier to _Py_IDENTIFIER.
Martin v. Löwis <martin@v.loewis.de>
parents: 72918
diff changeset
1180 _Py_IDENTIFIER(read);
7109f31300fb Rename _Py_identifier to _Py_IDENTIFIER.
Martin v. Löwis <martin@v.loewis.de>
parents: 72918
diff changeset
1181 _Py_IDENTIFIER(readline);
72848
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
1182
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
1183 self->peek = _PyObject_GetAttrId(file, &PyId_peek);
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
1184 if (self->peek == NULL) {
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
1185 if (PyErr_ExceptionMatches(PyExc_AttributeError))
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
1186 PyErr_Clear();
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
1187 else
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
1188 return -1;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
1189 }
72848
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
1190 self->read = _PyObject_GetAttrId(file, &PyId_read);
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
1191 self->readline = _PyObject_GetAttrId(file, &PyId_readline);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1192 if (self->readline == NULL || self->read == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1193 if (PyErr_ExceptionMatches(PyExc_AttributeError))
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1194 PyErr_SetString(PyExc_TypeError,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1195 "file must have 'read' and 'readline' attributes");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1196 Py_CLEAR(self->read);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1197 Py_CLEAR(self->readline);
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
1198 Py_CLEAR(self->peek);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1199 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1200 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1201 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1202 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1203
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1204 /* Returns -1 (with an exception set) on failure, 0 on success. This may
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1205 be called once on a freshly created Pickler. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1206 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1207 _Unpickler_SetInputEncoding(UnpicklerObject *self,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1208 const char *encoding,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1209 const char *errors)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1210 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1211 if (encoding == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1212 encoding = "ASCII";
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1213 if (errors == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1214 errors = "strict";
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1215
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1216 self->encoding = strdup(encoding);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1217 self->errors = strdup(errors);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1218 if (self->encoding == NULL || self->errors == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1219 PyErr_NoMemory();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1220 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1221 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1222 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1223 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1224
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1225 /* Generate a GET opcode for an object stored in the memo. */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1226 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1227 memo_get(PicklerObject *self, PyObject *key)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1228 {
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1229 Py_ssize_t *value;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1230 char pdata[30];
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1231 Py_ssize_t len;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1232
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1233 value = PyMemoTable_Get(self->memo, key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1234 if (value == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1235 PyErr_SetObject(PyExc_KeyError, key);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1236 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1237 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1238
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1239 if (!self->bin) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1240 pdata[0] = GET;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1241 PyOS_snprintf(pdata + 1, sizeof(pdata) - 1,
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1242 "%" PY_FORMAT_SIZE_T "d\n", *value);
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1243 len = strlen(pdata);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1244 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1245 else {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1246 if (*value < 256) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1247 pdata[0] = BINGET;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1248 pdata[1] = (unsigned char)(*value & 0xff);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1249 len = 2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1250 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1251 else if (*value <= 0xffffffffL) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1252 pdata[0] = LONG_BINGET;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1253 pdata[1] = (unsigned char)(*value & 0xff);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1254 pdata[2] = (unsigned char)((*value >> 8) & 0xff);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1255 pdata[3] = (unsigned char)((*value >> 16) & 0xff);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1256 pdata[4] = (unsigned char)((*value >> 24) & 0xff);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1257 len = 5;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1258 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1259 else { /* unlikely */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1260 PyErr_SetString(PicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1261 "memo id too large for LONG_BINGET");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1262 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1263 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1264 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1265
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1266 if (_Pickler_Write(self, pdata, len) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1267 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1268
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1269 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1270 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1271
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1272 /* Store an object in the memo, assign it a new unique ID based on the number
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1273 of objects currently stored in the memo and generate a PUT opcode. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1274 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1275 memo_put(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1276 {
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1277 Py_ssize_t x;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1278 char pdata[30];
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1279 Py_ssize_t len;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1280 int status = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1281
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1282 if (self->fast)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1283 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1284
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1285 x = PyMemoTable_Size(self->memo);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1286 if (PyMemoTable_Set(self->memo, obj, x) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1287 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1288
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1289 if (!self->bin) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1290 pdata[0] = PUT;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1291 PyOS_snprintf(pdata + 1, sizeof(pdata) - 1,
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1292 "%" PY_FORMAT_SIZE_T "d\n", x);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1293 len = strlen(pdata);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1294 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1295 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1296 if (x < 256) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1297 pdata[0] = BINPUT;
47670
13071add8f48 Fixed compiler warnings on MSVC9.0
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 47645
diff changeset
1298 pdata[1] = (unsigned char)x;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1299 len = 2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1300 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1301 else if (x <= 0xffffffffL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1302 pdata[0] = LONG_BINPUT;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1303 pdata[1] = (unsigned char)(x & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1304 pdata[2] = (unsigned char)((x >> 8) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1305 pdata[3] = (unsigned char)((x >> 16) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1306 pdata[4] = (unsigned char)((x >> 24) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1307 len = 5;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1308 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1309 else { /* unlikely */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1310 PyErr_SetString(PicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1311 "memo id too large for LONG_BINPUT");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1312 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1313 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1314 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1315
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1316 if (_Pickler_Write(self, pdata, len) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1317 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1318
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1319 if (0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1320 error:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1321 status = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1322 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1323
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1324 return status;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1325 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1326
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1327 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1328 whichmodule(PyObject *global, PyObject *global_name)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1329 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1330 Py_ssize_t i, j;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1331 static PyObject *module_str = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1332 static PyObject *main_str = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1333 PyObject *module_name;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1334 PyObject *modules_dict;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1335 PyObject *module;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1336 PyObject *obj;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1337
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1338 if (module_str == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1339 module_str = PyUnicode_InternFromString("__module__");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1340 if (module_str == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1341 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1342 main_str = PyUnicode_InternFromString("__main__");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1343 if (main_str == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1344 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1345 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1346
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1347 module_name = PyObject_GetAttr(global, module_str);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1348
52761
cbfbff233ef5 Update a comment about why the __module__ can sometime be NULL.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 51270
diff changeset
1349 /* In some rare cases (e.g., bound methods of extension types),
cbfbff233ef5 Update a comment about why the __module__ can sometime be NULL.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 51270
diff changeset
1350 __module__ can be None. If it is so, then search sys.modules
cbfbff233ef5 Update a comment about why the __module__ can sometime be NULL.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 51270
diff changeset
1351 for the module of global. */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1352 if (module_name == Py_None) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1353 Py_DECREF(module_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1354 goto search;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1355 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1356
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1357 if (module_name) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1358 return module_name;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1359 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1360 if (PyErr_ExceptionMatches(PyExc_AttributeError))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1361 PyErr_Clear();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1362 else
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1363 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1364
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1365 search:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1366 modules_dict = PySys_GetObject("modules");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1367 if (modules_dict == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1368 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1369
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1370 i = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1371 module_name = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1372 while ((j = PyDict_Next(modules_dict, &i, &module_name, &module))) {
51243
7c91f479bd0d Issue #1717, stage 2: remove uses of tp_compare in Modules and most
Mark Dickinson <dickinsm@gmail.com>
parents: 51021
diff changeset
1373 if (PyObject_RichCompareBool(module_name, main_str, Py_EQ) == 1)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1374 continue;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1375
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1376 obj = PyObject_GetAttr(module, global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1377 if (obj == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1378 if (PyErr_ExceptionMatches(PyExc_AttributeError))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1379 PyErr_Clear();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1380 else
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1381 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1382 continue;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1383 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1384
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1385 if (obj != global) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1386 Py_DECREF(obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1387 continue;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1388 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1389
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1390 Py_DECREF(obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1391 break;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1392 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1393
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1394 /* If no module is found, use __main__. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1395 if (!j) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1396 module_name = main_str;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1397 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1398
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1399 Py_INCREF(module_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1400 return module_name;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1401 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1402
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1403 /* fast_save_enter() and fast_save_leave() are guards against recursive
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1404 objects when Pickler is used with the "fast mode" (i.e., with object
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1405 memoization disabled). If the nesting of a list or dict object exceed
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1406 FAST_NESTING_LIMIT, these guards will start keeping an internal
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1407 reference to the seen list or dict objects and check whether these objects
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1408 are recursive. These are not strictly necessary, since save() has a
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1409 hard-coded recursion limit, but they give a nicer error message than the
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1410 typical RuntimeError. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1411 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1412 fast_save_enter(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1413 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1414 /* if fast_nesting < 0, we're doing an error exit. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1415 if (++self->fast_nesting >= FAST_NESTING_LIMIT) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1416 PyObject *key = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1417 if (self->fast_memo == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1418 self->fast_memo = PyDict_New();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1419 if (self->fast_memo == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1420 self->fast_nesting = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1421 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1422 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1423 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1424 key = PyLong_FromVoidPtr(obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1425 if (key == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1426 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1427 if (PyDict_GetItem(self->fast_memo, key)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1428 Py_DECREF(key);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1429 PyErr_Format(PyExc_ValueError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1430 "fast mode: can't pickle cyclic objects "
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1431 "including object type %.200s at %p",
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1432 obj->ob_type->tp_name, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1433 self->fast_nesting = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1434 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1435 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1436 if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1437 Py_DECREF(key);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1438 self->fast_nesting = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1439 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1440 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1441 Py_DECREF(key);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1442 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1443 return 1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1444 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1445
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1446 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1447 fast_save_leave(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1448 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1449 if (self->fast_nesting-- >= FAST_NESTING_LIMIT) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1450 PyObject *key = PyLong_FromVoidPtr(obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1451 if (key == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1452 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1453 if (PyDict_DelItem(self->fast_memo, key) < 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1454 Py_DECREF(key);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1455 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1456 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1457 Py_DECREF(key);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1458 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1459 return 1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1460 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1461
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1462 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1463 save_none(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1464 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1465 const char none_op = NONE;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1466 if (_Pickler_Write(self, &none_op, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1467 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1468
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1469 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1470 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1471
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1472 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1473 save_bool(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1474 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1475 static const char *buf[2] = { FALSE, TRUE };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1476 const char len[2] = {sizeof(FALSE) - 1, sizeof(TRUE) - 1};
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1477 int p = (obj == Py_True);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1478
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1479 if (self->proto >= 2) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1480 const char bool_op = p ? NEWTRUE : NEWFALSE;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1481 if (_Pickler_Write(self, &bool_op, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1482 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1483 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1484 else if (_Pickler_Write(self, buf[p], len[p]) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1485 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1486
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1487 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1488 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1489
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1490 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1491 save_int(PicklerObject *self, long x)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1492 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1493 char pdata[32];
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1494 Py_ssize_t len = 0;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1495
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1496 if (!self->bin
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1497 #if SIZEOF_LONG > 4
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1498 || x > 0x7fffffffL || x < -0x80000000L
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1499 #endif
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1500 ) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1501 /* Text-mode pickle, or long too big to fit in the 4-byte
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1502 * signed BININT format: store as a string.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1503 */
50946
a57d10d6bc89 Merged revisions 68814-68815 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50544
diff changeset
1504 pdata[0] = LONG; /* use LONG for consistency with pickle.py */
a57d10d6bc89 Merged revisions 68814-68815 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50544
diff changeset
1505 PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ldL\n", x);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1506 if (_Pickler_Write(self, pdata, strlen(pdata)) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1507 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1508 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1509 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1510 /* Binary pickle and x fits in a signed 4-byte int. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1511 pdata[1] = (unsigned char)(x & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1512 pdata[2] = (unsigned char)((x >> 8) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1513 pdata[3] = (unsigned char)((x >> 16) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1514 pdata[4] = (unsigned char)((x >> 24) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1515
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1516 if ((pdata[4] == 0) && (pdata[3] == 0)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1517 if (pdata[2] == 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1518 pdata[0] = BININT1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1519 len = 2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1520 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1521 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1522 pdata[0] = BININT2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1523 len = 3;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1524 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1525 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1526 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1527 pdata[0] = BININT;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1528 len = 5;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1529 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1530
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1531 if (_Pickler_Write(self, pdata, len) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1532 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1533 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1534
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1535 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1536 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1537
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1538 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1539 save_long(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1540 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1541 PyObject *repr = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1542 Py_ssize_t size;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1543 long val = PyLong_AsLong(obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1544 int status = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1545
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1546 const char long_op = LONG;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1547
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1548 if (val == -1 && PyErr_Occurred()) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1549 /* out of range for int pickling */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1550 PyErr_Clear();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1551 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1552 else
71861
72aaaff280d1 Followup to 8e824e09924a: fix regression on 32-bit builds
Antoine Pitrou <solipsis@pitrou.net>
parents: 71860
diff changeset
1553 #if SIZEOF_LONG > 4
72aaaff280d1 Followup to 8e824e09924a: fix regression on 32-bit builds
Antoine Pitrou <solipsis@pitrou.net>
parents: 71860
diff changeset
1554 if (val <= 0x7fffffffL && val >= -0x80000000L)
72aaaff280d1 Followup to 8e824e09924a: fix regression on 32-bit builds
Antoine Pitrou <solipsis@pitrou.net>
parents: 71860
diff changeset
1555 #endif
72aaaff280d1 Followup to 8e824e09924a: fix regression on 32-bit builds
Antoine Pitrou <solipsis@pitrou.net>
parents: 71860
diff changeset
1556 return save_int(self, val);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1557
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1558 if (self->proto >= 2) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1559 /* Linear-time pickling. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1560 size_t nbits;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1561 size_t nbytes;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1562 unsigned char *pdata;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1563 char header[5];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1564 int i;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1565 int sign = _PyLong_Sign(obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1566
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1567 if (sign == 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1568 header[0] = LONG1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1569 header[1] = 0; /* It's 0 -- an empty bytestring. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1570 if (_Pickler_Write(self, header, 2) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1571 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1572 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1573 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1574 nbits = _PyLong_NumBits(obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1575 if (nbits == (size_t)-1 && PyErr_Occurred())
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1576 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1577 /* How many bytes do we need? There are nbits >> 3 full
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1578 * bytes of data, and nbits & 7 leftover bits. If there
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1579 * are any leftover bits, then we clearly need another
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1580 * byte. Wnat's not so obvious is that we *probably*
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1581 * need another byte even if there aren't any leftovers:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1582 * the most-significant bit of the most-significant byte
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1583 * acts like a sign bit, and it's usually got a sense
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1584 * opposite of the one we need. The exception is longs
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1585 * of the form -(2**(8*j-1)) for j > 0. Such a long is
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1586 * its own 256's-complement, so has the right sign bit
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1587 * even without the extra byte. That's a pain to check
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1588 * for in advance, though, so we always grab an extra
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1589 * byte at the start, and cut it back later if possible.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1590 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1591 nbytes = (nbits >> 3) + 1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1592 if (nbytes > INT_MAX) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1593 PyErr_SetString(PyExc_OverflowError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1594 "long too large to pickle");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1595 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1596 }
48862
678a0f0e61bc Issue #3657: Fix uninitialized memory read when pickling longs.
Neal Norwitz <nnorwitz@gmail.com>
parents: 48696
diff changeset
1597 repr = PyBytes_FromStringAndSize(NULL, (Py_ssize_t)nbytes);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1598 if (repr == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1599 goto error;
48862
678a0f0e61bc Issue #3657: Fix uninitialized memory read when pickling longs.
Neal Norwitz <nnorwitz@gmail.com>
parents: 48696
diff changeset
1600 pdata = (unsigned char *)PyBytes_AS_STRING(repr);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1601 i = _PyLong_AsByteArray((PyLongObject *)obj,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1602 pdata, nbytes,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1603 1 /* little endian */ , 1 /* signed */ );
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1604 if (i < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1605 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1606 /* If the long is negative, this may be a byte more than
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1607 * needed. This is so iff the MSB is all redundant sign
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1608 * bits.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1609 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1610 if (sign < 0 &&
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
1611 nbytes > 1 &&
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1612 pdata[nbytes - 1] == 0xff &&
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1613 (pdata[nbytes - 2] & 0x80) != 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1614 nbytes--;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1615 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1616
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1617 if (nbytes < 256) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1618 header[0] = LONG1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1619 header[1] = (unsigned char)nbytes;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1620 size = 2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1621 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1622 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1623 header[0] = LONG4;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1624 size = (Py_ssize_t) nbytes;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1625 for (i = 1; i < 5; i++) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1626 header[i] = (unsigned char)(size & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1627 size >>= 8;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1628 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1629 size = 5;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1630 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1631 if (_Pickler_Write(self, header, size) < 0 ||
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1632 _Pickler_Write(self, (char *)pdata, (int)nbytes) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1633 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1634 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1635 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1636 char *string;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1637
50946
a57d10d6bc89 Merged revisions 68814-68815 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50544
diff changeset
1638 /* proto < 2: write the repr and newline. This is quadratic-time (in
a57d10d6bc89 Merged revisions 68814-68815 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50544
diff changeset
1639 the number of digits), in both directions. We add a trailing 'L'
a57d10d6bc89 Merged revisions 68814-68815 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50544
diff changeset
1640 to the repr, for compatibility with Python 2.x. */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1641
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1642 repr = PyObject_Repr(obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1643 if (repr == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1644 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1645
48660
85b67fb5672b Rename PyUnicode_AsString -> _PyUnicode_AsString and
Marc-André Lemburg <mal@egenix.com>
parents: 48462
diff changeset
1646 string = _PyUnicode_AsStringAndSize(repr, &size);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1647 if (string == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1648 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1649
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1650 if (_Pickler_Write(self, &long_op, 1) < 0 ||
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1651 _Pickler_Write(self, string, size) < 0 ||
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1652 _Pickler_Write(self, "L\n", 2) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1653 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1654 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1655
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1656 if (0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1657 error:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1658 status = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1659 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1660 Py_XDECREF(repr);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1661
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1662 return status;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1663 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1664
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1665 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1666 save_float(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1667 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1668 double x = PyFloat_AS_DOUBLE((PyFloatObject *)obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1669
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1670 if (self->bin) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1671 char pdata[9];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1672 pdata[0] = BINFLOAT;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1673 if (_PyFloat_Pack8(x, (unsigned char *)&pdata[1], 0) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1674 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1675 if (_Pickler_Write(self, pdata, 9) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1676 return -1;
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
1677 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1678 else {
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1679 int result = -1;
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1680 char *buf = NULL;
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1681 char op = FLOAT;
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1682
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1683 if (_Pickler_Write(self, &op, 1) < 0)
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1684 goto done;
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1685
53192
973f4d7aa87c Make sure that marshal and pickle continue to output 17
Mark Dickinson <dickinsm@gmail.com>
parents: 53187
diff changeset
1686 buf = PyOS_double_to_string(x, 'g', 17, 0, NULL);
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1687 if (!buf) {
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1688 PyErr_NoMemory();
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1689 goto done;
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1690 }
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1691
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1692 if (_Pickler_Write(self, buf, strlen(buf)) < 0)
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1693 goto done;
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1694
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1695 if (_Pickler_Write(self, "\n", 1) < 0)
53187
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1696 goto done;
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1697
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1698 result = 0;
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1699 done:
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1700 PyMem_Free(buf);
b653eab13b73 The other half of Issue #1580: use short float repr where possible.
Eric Smith <eric@trueblade.com>
parents: 52761
diff changeset
1701 return result;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1702 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1703
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1704 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1705 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1706
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1707 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1708 save_bytes(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1709 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1710 if (self->proto < 3) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1711 /* Older pickle protocols do not have an opcode for pickling bytes
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1712 objects. Therefore, we need to fake the copy protocol (i.e.,
73957
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1713 the __reduce__ method) to permit bytes object unpickling.
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1714
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1715 Here we use a hack to be compatible with Python 2. Since in Python
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1716 2 'bytes' is just an alias for 'str' (which has different
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1717 parameters than the actual bytes object), we use codecs.encode
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1718 to create the appropriate 'str' object when unpickled using
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1719 Python 2 *and* the appropriate 'bytes' object when unpickled
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1720 using Python 3. Again this is a hack and we don't need to do this
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1721 with newer protocols. */
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1722 static PyObject *codecs_encode = NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1723 PyObject *reduce_value = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1724 int status;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1725
73957
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1726 if (codecs_encode == NULL) {
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1727 PyObject *codecs_module = PyImport_ImportModule("codecs");
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1728 if (codecs_module == NULL) {
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1729 return -1;
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1730 }
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1731 codecs_encode = PyObject_GetAttrString(codecs_module, "encode");
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1732 Py_DECREF(codecs_module);
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1733 if (codecs_encode == NULL) {
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1734 return -1;
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1735 }
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1736 }
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1737
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1738 if (PyBytes_GET_SIZE(obj) == 0) {
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1739 reduce_value = Py_BuildValue("(O())", (PyObject*)&PyBytes_Type);
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1740 }
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1741 else {
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1742 static PyObject *latin1 = NULL;
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1743 PyObject *unicode_str =
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1744 PyUnicode_DecodeLatin1(PyBytes_AS_STRING(obj),
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1745 PyBytes_GET_SIZE(obj),
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1746 "strict");
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1747 if (unicode_str == NULL)
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1748 return -1;
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1749 if (latin1 == NULL) {
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1750 latin1 = PyUnicode_InternFromString("latin1");
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1751 if (latin1 == NULL)
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1752 return -1;
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1753 }
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1754 reduce_value = Py_BuildValue("(O(OO))",
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1755 codecs_encode, unicode_str, latin1);
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1756 Py_DECREF(unicode_str);
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1757 }
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1758
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1759 if (reduce_value == NULL)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1760 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1761
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1762 /* save_reduce() will memoize the object automatically. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1763 status = save_reduce(self, reduce_value, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1764 Py_DECREF(reduce_value);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1765 return status;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1766 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1767 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1768 Py_ssize_t size;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1769 char header[5];
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1770 Py_ssize_t len;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1771
73957
14695b4825dc Issue #13505: Make pickling of bytes object compatible with Python 2.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 72639
diff changeset
1772 size = PyBytes_GET_SIZE(obj);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1773 if (size < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1774 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1775
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1776 if (size < 256) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1777 header[0] = SHORT_BINBYTES;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1778 header[1] = (unsigned char)size;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1779 len = 2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1780 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1781 else if (size <= 0xffffffffL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1782 header[0] = BINBYTES;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1783 header[1] = (unsigned char)(size & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1784 header[2] = (unsigned char)((size >> 8) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1785 header[3] = (unsigned char)((size >> 16) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1786 header[4] = (unsigned char)((size >> 24) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1787 len = 5;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1788 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1789 else {
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1790 PyErr_SetString(PyExc_OverflowError,
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1791 "cannot serialize a bytes object larger than 4GB");
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1792 return -1; /* string too large */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1793 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1794
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1795 if (_Pickler_Write(self, header, len) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1796 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1797
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1798 if (_Pickler_Write(self, PyBytes_AS_STRING(obj), size) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1799 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1800
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1801 if (memo_put(self, obj) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1802 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1803
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1804 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1805 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1806 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1807
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1808 /* A copy of PyUnicode_EncodeRawUnicodeEscape() that also translates
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1809 backslash and newline characters to \uXXXX escapes. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1810 static PyObject *
72539
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1811 raw_unicode_escape(PyObject *obj)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1812 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1813 PyObject *repr, *result;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1814 char *p;
72539
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1815 Py_ssize_t i, size, expandsize;
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1816 void *data;
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1817 unsigned int kind;
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1818
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1819 if (PyUnicode_READY(obj))
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1820 return NULL;
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1821
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1822 size = PyUnicode_GET_LENGTH(obj);
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1823 data = PyUnicode_DATA(obj);
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1824 kind = PyUnicode_KIND(obj);
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1825 if (kind == PyUnicode_4BYTE_KIND)
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1826 expandsize = 10;
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1827 else
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1828 expandsize = 6;
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
1829
50544
c9e5c1fa285e Merged revisions 67937-67938 via svnmerge from
Georg Brandl <georg@python.org>
parents: 49849
diff changeset
1830 if (size > PY_SSIZE_T_MAX / expandsize)
c9e5c1fa285e Merged revisions 67937-67938 via svnmerge from
Georg Brandl <georg@python.org>
parents: 49849
diff changeset
1831 return PyErr_NoMemory();
c9e5c1fa285e Merged revisions 67937-67938 via svnmerge from
Georg Brandl <georg@python.org>
parents: 49849
diff changeset
1832 repr = PyByteArray_FromStringAndSize(NULL, expandsize * size);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1833 if (repr == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1834 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1835 if (size == 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1836 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1837
72539
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1838 p = PyByteArray_AS_STRING(repr);
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1839 for (i=0; i < size; i++) {
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1840 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1841 /* Map 32-bit characters to '\Uxxxxxxxx' */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1842 if (ch >= 0x10000) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1843 *p++ = '\\';
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1844 *p++ = 'U';
72918
d76338eacf7c Issue #13088: Add shared Py_hexdigits constant to format a number into base 16
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72848
diff changeset
1845 *p++ = Py_hexdigits[(ch >> 28) & 0xf];
d76338eacf7c Issue #13088: Add shared Py_hexdigits constant to format a number into base 16
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72848
diff changeset
1846 *p++ = Py_hexdigits[(ch >> 24) & 0xf];
d76338eacf7c Issue #13088: Add shared Py_hexdigits constant to format a number into base 16
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72848
diff changeset
1847 *p++ = Py_hexdigits[(ch >> 20) & 0xf];
d76338eacf7c Issue #13088: Add shared Py_hexdigits constant to format a number into base 16
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72848
diff changeset
1848 *p++ = Py_hexdigits[(ch >> 16) & 0xf];
d76338eacf7c Issue #13088: Add shared Py_hexdigits constant to format a number into base 16
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72848
diff changeset
1849 *p++ = Py_hexdigits[(ch >> 12) & 0xf];
d76338eacf7c Issue #13088: Add shared Py_hexdigits constant to format a number into base 16
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72848
diff changeset
1850 *p++ = Py_hexdigits[(ch >> 8) & 0xf];
d76338eacf7c Issue #13088: Add shared Py_hexdigits constant to format a number into base 16
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72848
diff changeset
1851 *p++ = Py_hexdigits[(ch >> 4) & 0xf];
d76338eacf7c Issue #13088: Add shared Py_hexdigits constant to format a number into base 16
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72848
diff changeset
1852 *p++ = Py_hexdigits[ch & 15];
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1853 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1854 /* Map 16-bit characters to '\uxxxx' */
72539
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1855 else if (ch >= 256 || ch == '\\' || ch == '\n') {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1856 *p++ = '\\';
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1857 *p++ = 'u';
72918
d76338eacf7c Issue #13088: Add shared Py_hexdigits constant to format a number into base 16
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72848
diff changeset
1858 *p++ = Py_hexdigits[(ch >> 12) & 0xf];
d76338eacf7c Issue #13088: Add shared Py_hexdigits constant to format a number into base 16
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72848
diff changeset
1859 *p++ = Py_hexdigits[(ch >> 8) & 0xf];
d76338eacf7c Issue #13088: Add shared Py_hexdigits constant to format a number into base 16
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72848
diff changeset
1860 *p++ = Py_hexdigits[(ch >> 4) & 0xf];
d76338eacf7c Issue #13088: Add shared Py_hexdigits constant to format a number into base 16
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72848
diff changeset
1861 *p++ = Py_hexdigits[ch & 15];
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1862 }
50544
c9e5c1fa285e Merged revisions 67937-67938 via svnmerge from
Georg Brandl <georg@python.org>
parents: 49849
diff changeset
1863 /* Copy everything else as-is */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1864 else
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1865 *p++ = (char) ch;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1866 }
72539
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1867 size = p - PyByteArray_AS_STRING(repr);
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1868
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1869 done:
50544
c9e5c1fa285e Merged revisions 67937-67938 via svnmerge from
Georg Brandl <georg@python.org>
parents: 49849
diff changeset
1870 result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(repr), size);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1871 Py_DECREF(repr);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1872 return result;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1873 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1874
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1875 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1876 save_unicode(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1877 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1878 Py_ssize_t size;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1879 PyObject *encoded = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1880
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1881 if (self->bin) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1882 char pdata[5];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1883
72475
8beaa9a37387 Implement PEP 393.
Martin v. Löwis <martin@v.loewis.de>
parents: 72458
diff changeset
1884 encoded = PyUnicode_AsEncodedString(obj, "utf-8", "surrogatepass");
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1885 if (encoded == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1886 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1887
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1888 size = PyBytes_GET_SIZE(encoded);
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1889 if (size > 0xffffffffL) {
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1890 PyErr_SetString(PyExc_OverflowError,
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1891 "cannot serialize a string larger than 4GB");
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1892 goto error; /* string too large */
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1893 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1894
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1895 pdata[0] = BINUNICODE;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1896 pdata[1] = (unsigned char)(size & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1897 pdata[2] = (unsigned char)((size >> 8) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1898 pdata[3] = (unsigned char)((size >> 16) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1899 pdata[4] = (unsigned char)((size >> 24) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1900
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1901 if (_Pickler_Write(self, pdata, 5) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1902 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1903
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1904 if (_Pickler_Write(self, PyBytes_AS_STRING(encoded), size) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1905 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1906 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1907 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1908 const char unicode_op = UNICODE;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1909
72539
b9558df8cc58 raw_unicode_escape() uses the new Unicode API
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72538
diff changeset
1910 encoded = raw_unicode_escape(obj);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1911 if (encoded == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1912 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1913
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1914 if (_Pickler_Write(self, &unicode_op, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1915 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1916
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1917 size = PyBytes_GET_SIZE(encoded);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1918 if (_Pickler_Write(self, PyBytes_AS_STRING(encoded), size) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1919 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1920
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1921 if (_Pickler_Write(self, "\n", 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1922 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1923 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1924 if (memo_put(self, obj) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1925 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1926
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1927 Py_DECREF(encoded);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1928 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1929
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1930 error:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1931 Py_XDECREF(encoded);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1932 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1933 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1934
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1935 /* A helper for save_tuple. Push the len elements in tuple t on the stack. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1936 static int
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1937 store_tuple_elements(PicklerObject *self, PyObject *t, Py_ssize_t len)
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1938 {
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1939 Py_ssize_t i;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1940
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1941 assert(PyTuple_Size(t) == len);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1942
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1943 for (i = 0; i < len; i++) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1944 PyObject *element = PyTuple_GET_ITEM(t, i);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1945
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1946 if (element == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1947 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1948 if (save(self, element, 0) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1949 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1950 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1951
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1952 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1953 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1954
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1955 /* Tuples are ubiquitous in the pickle protocols, so many techniques are
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1956 * used across protocols to minimize the space needed to pickle them.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1957 * Tuples are also the only builtin immutable type that can be recursive
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1958 * (a tuple can be reached from itself), and that requires some subtle
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1959 * magic so that it works in all cases. IOW, this is a long routine.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1960 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1961 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1962 save_tuple(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1963 {
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
1964 Py_ssize_t len, i;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1965
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1966 const char mark_op = MARK;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1967 const char tuple_op = TUPLE;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1968 const char pop_op = POP;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1969 const char pop_mark_op = POP_MARK;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1970 const char len2opcode[] = {EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3};
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1971
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1972 if ((len = PyTuple_Size(obj)) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1973 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1974
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1975 if (len == 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1976 char pdata[2];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1977
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1978 if (self->proto) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1979 pdata[0] = EMPTY_TUPLE;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1980 len = 1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1981 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1982 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1983 pdata[0] = MARK;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1984 pdata[1] = TUPLE;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1985 len = 2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1986 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1987 if (_Pickler_Write(self, pdata, len) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1988 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1989 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1990 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1991
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
1992 /* The tuple isn't in the memo now. If it shows up there after
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1993 * saving the tuple elements, the tuple must be recursive, in
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1994 * which case we'll pop everything we put on the stack, and fetch
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1995 * its value from the memo.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1996 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1997 if (len <= 3 && self->proto >= 2) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1998 /* Use TUPLE{1,2,3} opcodes. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
1999 if (store_tuple_elements(self, obj, len) < 0)
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2000 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2001
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2002 if (PyMemoTable_Get(self->memo, obj)) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2003 /* pop the len elements */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2004 for (i = 0; i < len; i++)
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2005 if (_Pickler_Write(self, &pop_op, 1) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2006 return -1;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2007 /* fetch from memo */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2008 if (memo_get(self, obj) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2009 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2010
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2011 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2012 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2013 else { /* Not recursive. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2014 if (_Pickler_Write(self, len2opcode + len, 1) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2015 return -1;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2016 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2017 goto memoize;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2018 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2019
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2020 /* proto < 2 and len > 0, or proto >= 2 and len > 3.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2021 * Generate MARK e1 e2 ... TUPLE
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2022 */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2023 if (_Pickler_Write(self, &mark_op, 1) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2024 return -1;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2025
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2026 if (store_tuple_elements(self, obj, len) < 0)
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2027 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2028
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2029 if (PyMemoTable_Get(self->memo, obj)) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2030 /* pop the stack stuff we pushed */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2031 if (self->bin) {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2032 if (_Pickler_Write(self, &pop_mark_op, 1) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2033 return -1;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2034 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2035 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2036 /* Note that we pop one more than len, to remove
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2037 * the MARK too.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2038 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2039 for (i = 0; i <= len; i++)
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2040 if (_Pickler_Write(self, &pop_op, 1) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2041 return -1;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2042 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2043 /* fetch from memo */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2044 if (memo_get(self, obj) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2045 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2046
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2047 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2048 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2049 else { /* Not recursive. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2050 if (_Pickler_Write(self, &tuple_op, 1) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2051 return -1;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2052 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2053
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2054 memoize:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2055 if (memo_put(self, obj) < 0)
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2056 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2057
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2058 return 0;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2059 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2060
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2061 /* iter is an iterator giving items, and we batch up chunks of
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2062 * MARK item item ... item APPENDS
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2063 * opcode sequences. Calling code should have arranged to first create an
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2064 * empty list, or list-like object, for the APPENDS to operate on.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2065 * Returns 0 on success, <0 on error.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2066 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2067 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2068 batch_list(PicklerObject *self, PyObject *iter)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2069 {
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2070 PyObject *obj = NULL;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2071 PyObject *firstitem = NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2072 int i, n;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2073
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2074 const char mark_op = MARK;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2075 const char append_op = APPEND;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2076 const char appends_op = APPENDS;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2077
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2078 assert(iter != NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2079
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2080 /* XXX: I think this function could be made faster by avoiding the
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2081 iterator interface and fetching objects directly from list using
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2082 PyList_GET_ITEM.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2083 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2084
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2085 if (self->proto == 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2086 /* APPENDS isn't available; do one at a time. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2087 for (;;) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2088 obj = PyIter_Next(iter);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2089 if (obj == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2090 if (PyErr_Occurred())
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2091 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2092 break;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2093 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2094 i = save(self, obj, 0);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2095 Py_DECREF(obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2096 if (i < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2097 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2098 if (_Pickler_Write(self, &append_op, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2099 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2100 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2101 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2102 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2103
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2104 /* proto > 0: write in batches of BATCHSIZE. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2105 do {
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2106 /* Get first item */
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2107 firstitem = PyIter_Next(iter);
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2108 if (firstitem == NULL) {
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2109 if (PyErr_Occurred())
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2110 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2111
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2112 /* nothing more to add */
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2113 break;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2114 }
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2115
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2116 /* Try to get a second item */
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2117 obj = PyIter_Next(iter);
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2118 if (obj == NULL) {
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2119 if (PyErr_Occurred())
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2120 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2121
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2122 /* Only one item to write */
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2123 if (save(self, firstitem, 0) < 0)
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2124 goto error;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2125 if (_Pickler_Write(self, &append_op, 1) < 0)
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2126 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2127 Py_CLEAR(firstitem);
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2128 break;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2129 }
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2130
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2131 /* More than one item to write */
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2132
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2133 /* Pump out MARK, items, APPENDS. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2134 if (_Pickler_Write(self, &mark_op, 1) < 0)
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2135 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2136
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2137 if (save(self, firstitem, 0) < 0)
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2138 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2139 Py_CLEAR(firstitem);
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2140 n = 1;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2141
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2142 /* Fetch and save up to BATCHSIZE items */
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2143 while (obj) {
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2144 if (save(self, obj, 0) < 0)
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2145 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2146 Py_CLEAR(obj);
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2147 n += 1;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2148
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2149 if (n == BATCHSIZE)
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2150 break;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2151
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2152 obj = PyIter_Next(iter);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2153 if (obj == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2154 if (PyErr_Occurred())
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2155 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2156 break;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2157 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2158 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2159
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2160 if (_Pickler_Write(self, &appends_op, 1) < 0)
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2161 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2162
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2163 } while (n == BATCHSIZE);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2164 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2165
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2166 error:
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2167 Py_XDECREF(firstitem);
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2168 Py_XDECREF(obj);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2169 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2170 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2171
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2172 /* This is a variant of batch_list() above, specialized for lists (with no
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2173 * support for list subclasses). Like batch_list(), we batch up chunks of
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2174 * MARK item item ... item APPENDS
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2175 * opcode sequences. Calling code should have arranged to first create an
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2176 * empty list, or list-like object, for the APPENDS to operate on.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2177 * Returns 0 on success, -1 on error.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2178 *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2179 * This version is considerably faster than batch_list(), if less general.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2180 *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2181 * Note that this only works for protocols > 0.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2182 */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2183 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2184 batch_list_exact(PicklerObject *self, PyObject *obj)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2185 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2186 PyObject *item = NULL;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
2187 Py_ssize_t this_batch, total;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2188
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2189 const char append_op = APPEND;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2190 const char appends_op = APPENDS;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2191 const char mark_op = MARK;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2192
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2193 assert(obj != NULL);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2194 assert(self->proto > 0);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2195 assert(PyList_CheckExact(obj));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2196
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2197 if (PyList_GET_SIZE(obj) == 1) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2198 item = PyList_GET_ITEM(obj, 0);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2199 if (save(self, item, 0) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2200 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2201 if (_Pickler_Write(self, &append_op, 1) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2202 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2203 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2204 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2205
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2206 /* Write in batches of BATCHSIZE. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2207 total = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2208 do {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2209 this_batch = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2210 if (_Pickler_Write(self, &mark_op, 1) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2211 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2212 while (total < PyList_GET_SIZE(obj)) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2213 item = PyList_GET_ITEM(obj, total);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2214 if (save(self, item, 0) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2215 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2216 total++;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2217 if (++this_batch == BATCHSIZE)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2218 break;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2219 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2220 if (_Pickler_Write(self, &appends_op, 1) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2221 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2222
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2223 } while (total < PyList_GET_SIZE(obj));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2224
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2225 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2226 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2227
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2228 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2229 save_list(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2230 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2231 char header[3];
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
2232 Py_ssize_t len;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2233 int status = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2234
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2235 if (self->fast && !fast_save_enter(self, obj))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2236 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2237
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2238 /* Create an empty list. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2239 if (self->bin) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2240 header[0] = EMPTY_LIST;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2241 len = 1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2242 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2243 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2244 header[0] = MARK;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2245 header[1] = LIST;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2246 len = 2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2247 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2248
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2249 if (_Pickler_Write(self, header, len) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2250 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2251
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2252 /* Get list length, and bow out early if empty. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2253 if ((len = PyList_Size(obj)) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2254 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2255
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2256 if (memo_put(self, obj) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2257 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2258
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2259 if (len != 0) {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2260 /* Materialize the list elements. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2261 if (PyList_CheckExact(obj) && self->proto > 0) {
67724
4c4abfb884fb Issue #10987: Fix the recursion limit handling in the _pickle module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 66106
diff changeset
2262 if (Py_EnterRecursiveCall(" while pickling an object"))
4c4abfb884fb Issue #10987: Fix the recursion limit handling in the _pickle module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 66106
diff changeset
2263 goto error;
4c4abfb884fb Issue #10987: Fix the recursion limit handling in the _pickle module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 66106
diff changeset
2264 status = batch_list_exact(self, obj);
4c4abfb884fb Issue #10987: Fix the recursion limit handling in the _pickle module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 66106
diff changeset
2265 Py_LeaveRecursiveCall();
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2266 } else {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2267 PyObject *iter = PyObject_GetIter(obj);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2268 if (iter == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2269 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2270
67724
4c4abfb884fb Issue #10987: Fix the recursion limit handling in the _pickle module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 66106
diff changeset
2271 if (Py_EnterRecursiveCall(" while pickling an object")) {
4c4abfb884fb Issue #10987: Fix the recursion limit handling in the _pickle module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 66106
diff changeset
2272 Py_DECREF(iter);
4c4abfb884fb Issue #10987: Fix the recursion limit handling in the _pickle module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 66106
diff changeset
2273 goto error;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2274 }
67724
4c4abfb884fb Issue #10987: Fix the recursion limit handling in the _pickle module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 66106
diff changeset
2275 status = batch_list(self, iter);
4c4abfb884fb Issue #10987: Fix the recursion limit handling in the _pickle module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 66106
diff changeset
2276 Py_LeaveRecursiveCall();
67725
bcf030f73eee Merged revisions 88147 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2277 Py_DECREF(iter);
bcf030f73eee Merged revisions 88147 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2278 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2279 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2280 if (0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2281 error:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2282 status = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2283 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2284
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2285 if (self->fast && !fast_save_leave(self, obj))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2286 status = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2287
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2288 return status;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2289 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2290
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2291 /* iter is an iterator giving (key, value) pairs, and we batch up chunks of
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2292 * MARK key value ... key value SETITEMS
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2293 * opcode sequences. Calling code should have arranged to first create an
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2294 * empty dict, or dict-like object, for the SETITEMS to operate on.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2295 * Returns 0 on success, <0 on error.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2296 *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2297 * This is very much like batch_list(). The difference between saving
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2298 * elements directly, and picking apart two-tuples, is so long-winded at
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2299 * the C level, though, that attempts to combine these routines were too
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2300 * ugly to bear.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2301 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2302 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2303 batch_dict(PicklerObject *self, PyObject *iter)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2304 {
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2305 PyObject *obj = NULL;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2306 PyObject *firstitem = NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2307 int i, n;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2308
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2309 const char mark_op = MARK;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2310 const char setitem_op = SETITEM;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2311 const char setitems_op = SETITEMS;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2312
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2313 assert(iter != NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2314
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2315 if (self->proto == 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2316 /* SETITEMS isn't available; do one at a time. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2317 for (;;) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2318 obj = PyIter_Next(iter);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2319 if (obj == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2320 if (PyErr_Occurred())
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2321 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2322 break;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2323 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2324 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2325 PyErr_SetString(PyExc_TypeError, "dict items "
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2326 "iterator must return 2-tuples");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2327 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2328 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2329 i = save(self, PyTuple_GET_ITEM(obj, 0), 0);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2330 if (i >= 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2331 i = save(self, PyTuple_GET_ITEM(obj, 1), 0);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2332 Py_DECREF(obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2333 if (i < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2334 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2335 if (_Pickler_Write(self, &setitem_op, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2336 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2337 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2338 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2339 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2340
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2341 /* proto > 0: write in batches of BATCHSIZE. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2342 do {
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2343 /* Get first item */
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2344 firstitem = PyIter_Next(iter);
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2345 if (firstitem == NULL) {
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2346 if (PyErr_Occurred())
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2347 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2348
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2349 /* nothing more to add */
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2350 break;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2351 }
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2352 if (!PyTuple_Check(firstitem) || PyTuple_Size(firstitem) != 2) {
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2353 PyErr_SetString(PyExc_TypeError, "dict items "
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2354 "iterator must return 2-tuples");
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2355 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2356 }
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2357
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2358 /* Try to get a second item */
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2359 obj = PyIter_Next(iter);
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2360 if (obj == NULL) {
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2361 if (PyErr_Occurred())
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2362 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2363
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2364 /* Only one item to write */
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2365 if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0)
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2366 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2367 if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0)
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2368 goto error;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2369 if (_Pickler_Write(self, &setitem_op, 1) < 0)
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2370 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2371 Py_CLEAR(firstitem);
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2372 break;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2373 }
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2374
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2375 /* More than one item to write */
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2376
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2377 /* Pump out MARK, items, SETITEMS. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2378 if (_Pickler_Write(self, &mark_op, 1) < 0)
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2379 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2380
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2381 if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0)
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2382 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2383 if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0)
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2384 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2385 Py_CLEAR(firstitem);
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2386 n = 1;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2387
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2388 /* Fetch and save up to BATCHSIZE items */
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2389 while (obj) {
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2390 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) {
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2391 PyErr_SetString(PyExc_TypeError, "dict items "
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2392 "iterator must return 2-tuples");
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2393 goto error;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2394 }
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2395 if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 ||
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2396 save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0)
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2397 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2398 Py_CLEAR(obj);
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2399 n += 1;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2400
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2401 if (n == BATCHSIZE)
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2402 break;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2403
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2404 obj = PyIter_Next(iter);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2405 if (obj == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2406 if (PyErr_Occurred())
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2407 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2408 break;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2409 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2410 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2411
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2412 if (_Pickler_Write(self, &setitems_op, 1) < 0)
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2413 goto error;
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2414
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2415 } while (n == BATCHSIZE);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2416 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2417
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2418 error:
49149
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2419 Py_XDECREF(firstitem);
4cd97f8de69e #3640: Correct a crash in cPickle on 64bit platforms, in the case of deeply nested lists or dicts.
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49023
diff changeset
2420 Py_XDECREF(obj);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2421 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2422 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2423
54328
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2424 /* This is a variant of batch_dict() above that specializes for dicts, with no
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2425 * support for dict subclasses. Like batch_dict(), we batch up chunks of
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2426 * MARK key value ... key value SETITEMS
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2427 * opcode sequences. Calling code should have arranged to first create an
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2428 * empty dict, or dict-like object, for the SETITEMS to operate on.
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2429 * Returns 0 on success, -1 on error.
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2430 *
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2431 * Note that this currently doesn't work for protocol 0.
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2432 */
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2433 static int
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2434 batch_dict_exact(PicklerObject *self, PyObject *obj)
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2435 {
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2436 PyObject *key = NULL, *value = NULL;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2437 int i;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2438 Py_ssize_t dict_size, ppos = 0;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2439
54331
39d3a75fa821 Make variable declarations for opcodes in batch_dict_exact consistent
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 54328
diff changeset
2440 const char mark_op = MARK;
39d3a75fa821 Make variable declarations for opcodes in batch_dict_exact consistent
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 54328
diff changeset
2441 const char setitem_op = SETITEM;
39d3a75fa821 Make variable declarations for opcodes in batch_dict_exact consistent
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 54328
diff changeset
2442 const char setitems_op = SETITEMS;
54328
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2443
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2444 assert(obj != NULL);
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2445 assert(self->proto > 0);
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2446
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2447 dict_size = PyDict_Size(obj);
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2448
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2449 /* Special-case len(d) == 1 to save space. */
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2450 if (dict_size == 1) {
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2451 PyDict_Next(obj, &ppos, &key, &value);
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2452 if (save(self, key, 0) < 0)
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2453 return -1;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2454 if (save(self, value, 0) < 0)
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2455 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2456 if (_Pickler_Write(self, &setitem_op, 1) < 0)
54328
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2457 return -1;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2458 return 0;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2459 }
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2460
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2461 /* Write in batches of BATCHSIZE. */
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2462 do {
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2463 i = 0;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2464 if (_Pickler_Write(self, &mark_op, 1) < 0)
54328
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2465 return -1;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2466 while (PyDict_Next(obj, &ppos, &key, &value)) {
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2467 if (save(self, key, 0) < 0)
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2468 return -1;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2469 if (save(self, value, 0) < 0)
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2470 return -1;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2471 if (++i == BATCHSIZE)
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2472 break;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2473 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2474 if (_Pickler_Write(self, &setitems_op, 1) < 0)
54328
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2475 return -1;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2476 if (PyDict_Size(obj) != dict_size) {
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2477 PyErr_Format(
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2478 PyExc_RuntimeError,
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2479 "dictionary changed size during iteration");
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2480 return -1;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2481 }
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2482
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2483 } while (i == BATCHSIZE);
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2484 return 0;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2485 }
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2486
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2487 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2488 save_dict(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2489 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2490 PyObject *items, *iter;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2491 char header[3];
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
2492 Py_ssize_t len;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2493 int status = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2494
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2495 if (self->fast && !fast_save_enter(self, obj))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2496 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2497
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2498 /* Create an empty dict. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2499 if (self->bin) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2500 header[0] = EMPTY_DICT;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2501 len = 1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2502 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2503 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2504 header[0] = MARK;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2505 header[1] = DICT;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2506 len = 2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2507 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2508
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2509 if (_Pickler_Write(self, header, len) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2510 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2511
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2512 /* Get dict size, and bow out early if empty. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2513 if ((len = PyDict_Size(obj)) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2514 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2515
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2516 if (memo_put(self, obj) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2517 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2518
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2519 if (len != 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2520 /* Save the dict items. */
54328
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2521 if (PyDict_CheckExact(obj) && self->proto > 0) {
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2522 /* We can take certain shortcuts if we know this is a dict and
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2523 not a dict subclass. */
67725
bcf030f73eee Merged revisions 88147 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2524 if (Py_EnterRecursiveCall(" while pickling an object"))
bcf030f73eee Merged revisions 88147 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2525 goto error;
bcf030f73eee Merged revisions 88147 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2526 status = batch_dict_exact(self, obj);
bcf030f73eee Merged revisions 88147 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2527 Py_LeaveRecursiveCall();
54328
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2528 } else {
72925
7109f31300fb Rename _Py_identifier to _Py_IDENTIFIER.
Martin v. Löwis <martin@v.loewis.de>
parents: 72918
diff changeset
2529 _Py_IDENTIFIER(items);
72835
5e33219492bc Add API for static strings, primarily good for identifiers.
Martin v. Löwis <martin@v.loewis.de>
parents: 72640
diff changeset
2530
5e33219492bc Add API for static strings, primarily good for identifiers.
Martin v. Löwis <martin@v.loewis.de>
parents: 72640
diff changeset
2531 items = _PyObject_CallMethodId(obj, &PyId_items, "()");
54328
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2532 if (items == NULL)
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2533 goto error;
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2534 iter = PyObject_GetIter(items);
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2535 Py_DECREF(items);
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2536 if (iter == NULL)
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2537 goto error;
67725
bcf030f73eee Merged revisions 88147 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2538 if (Py_EnterRecursiveCall(" while pickling an object")) {
bcf030f73eee Merged revisions 88147 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2539 Py_DECREF(iter);
bcf030f73eee Merged revisions 88147 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2540 goto error;
bcf030f73eee Merged revisions 88147 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2541 }
54328
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2542 status = batch_dict(self, iter);
67725
bcf030f73eee Merged revisions 88147 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2543 Py_LeaveRecursiveCall();
54328
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2544 Py_DECREF(iter);
5ab2f6ca65aa Merged revisions 72909 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 53707
diff changeset
2545 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2546 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2547
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2548 if (0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2549 error:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2550 status = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2551 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2552
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2553 if (self->fast && !fast_save_leave(self, obj))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2554 status = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2555
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2556 return status;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2557 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2558
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2559 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2560 save_global(PicklerObject *self, PyObject *obj, PyObject *name)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2561 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2562 static PyObject *name_str = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2563 PyObject *global_name = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2564 PyObject *module_name = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2565 PyObject *module = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2566 PyObject *cls;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2567 int status = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2568
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2569 const char global_op = GLOBAL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2570
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2571 if (name_str == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2572 name_str = PyUnicode_InternFromString("__name__");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2573 if (name_str == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2574 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2575 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2576
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2577 if (name) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2578 global_name = name;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2579 Py_INCREF(global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2580 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2581 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2582 global_name = PyObject_GetAttr(obj, name_str);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2583 if (global_name == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2584 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2585 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2586
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2587 module_name = whichmodule(obj, global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2588 if (module_name == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2589 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2590
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2591 /* XXX: Change to use the import C API directly with level=0 to disallow
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2592 relative imports.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2593
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2594 XXX: PyImport_ImportModuleLevel could be used. However, this bypasses
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2595 builtins.__import__. Therefore, _pickle, unlike pickle.py, will ignore
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2596 custom import functions (IMHO, this would be a nice security
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2597 feature). The import C API would need to be extended to support the
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2598 extra parameters of __import__ to fix that. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2599 module = PyImport_Import(module_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2600 if (module == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2601 PyErr_Format(PicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2602 "Can't pickle %R: import of module %R failed",
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2603 obj, module_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2604 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2605 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2606 cls = PyObject_GetAttr(module, global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2607 if (cls == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2608 PyErr_Format(PicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2609 "Can't pickle %R: attribute lookup %S.%S failed",
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2610 obj, module_name, global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2611 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2612 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2613 if (cls != obj) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2614 Py_DECREF(cls);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2615 PyErr_Format(PicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2616 "Can't pickle %R: it's not the same object as %S.%S",
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2617 obj, module_name, global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2618 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2619 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2620 Py_DECREF(cls);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2621
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2622 if (self->proto >= 2) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2623 /* See whether this is in the extension registry, and if
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2624 * so generate an EXT opcode.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2625 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2626 PyObject *code_obj; /* extension code as Python object */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2627 long code; /* extension code as C value */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2628 char pdata[5];
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
2629 Py_ssize_t n;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2630
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2631 PyTuple_SET_ITEM(two_tuple, 0, module_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2632 PyTuple_SET_ITEM(two_tuple, 1, global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2633 code_obj = PyDict_GetItem(extension_registry, two_tuple);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2634 /* The object is not registered in the extension registry.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2635 This is the most likely code path. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2636 if (code_obj == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2637 goto gen_global;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2638
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2639 /* XXX: pickle.py doesn't check neither the type, nor the range
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2640 of the value returned by the extension_registry. It should for
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2641 consistency. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2642
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2643 /* Verify code_obj has the right type and value. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2644 if (!PyLong_Check(code_obj)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2645 PyErr_Format(PicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2646 "Can't pickle %R: extension code %R isn't an integer",
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2647 obj, code_obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2648 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2649 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2650 code = PyLong_AS_LONG(code_obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2651 if (code <= 0 || code > 0x7fffffffL) {
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
2652 if (!PyErr_Occurred())
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
2653 PyErr_Format(PicklingError,
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
2654 "Can't pickle %R: extension code %ld is out of range",
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
2655 obj, code);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2656 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2657 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2658
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2659 /* Generate an EXT opcode. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2660 if (code <= 0xff) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2661 pdata[0] = EXT1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2662 pdata[1] = (unsigned char)code;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2663 n = 2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2664 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2665 else if (code <= 0xffff) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2666 pdata[0] = EXT2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2667 pdata[1] = (unsigned char)(code & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2668 pdata[2] = (unsigned char)((code >> 8) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2669 n = 3;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2670 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2671 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2672 pdata[0] = EXT4;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2673 pdata[1] = (unsigned char)(code & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2674 pdata[2] = (unsigned char)((code >> 8) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2675 pdata[3] = (unsigned char)((code >> 16) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2676 pdata[4] = (unsigned char)((code >> 24) & 0xff);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2677 n = 5;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2678 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2679
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2680 if (_Pickler_Write(self, pdata, n) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2681 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2682 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2683 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2684 /* Generate a normal global opcode if we are using a pickle
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2685 protocol <= 2, or if the object is not registered in the
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2686 extension registry. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2687 PyObject *encoded;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2688 PyObject *(*unicode_encoder)(PyObject *);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2689
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2690 gen_global:
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2691 if (_Pickler_Write(self, &global_op, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2692 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2693
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2694 /* Since Python 3.0 now supports non-ASCII identifiers, we encode both
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2695 the module name and the global name using UTF-8. We do so only when
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2696 we are using the pickle protocol newer than version 3. This is to
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2697 ensure compatibility with older Unpickler running on Python 2.x. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2698 if (self->proto >= 3) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2699 unicode_encoder = PyUnicode_AsUTF8String;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2700 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2701 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2702 unicode_encoder = PyUnicode_AsASCIIString;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2703 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2704
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2705 /* For protocol < 3 and if the user didn't request against doing so,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2706 we convert module names to the old 2.x module names. */
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2707 if (self->fix_imports) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2708 PyObject *key;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2709 PyObject *item;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2710
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2711 key = PyTuple_Pack(2, module_name, global_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2712 if (key == NULL)
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2713 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2714 item = PyDict_GetItemWithError(name_mapping_3to2, key);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2715 Py_DECREF(key);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2716 if (item) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2717 if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2718 PyErr_Format(PyExc_RuntimeError,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2719 "_compat_pickle.REVERSE_NAME_MAPPING values "
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2720 "should be 2-tuples, not %.200s",
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2721 Py_TYPE(item)->tp_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2722 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2723 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2724 Py_CLEAR(module_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2725 Py_CLEAR(global_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2726 module_name = PyTuple_GET_ITEM(item, 0);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2727 global_name = PyTuple_GET_ITEM(item, 1);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2728 if (!PyUnicode_Check(module_name) ||
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2729 !PyUnicode_Check(global_name)) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2730 PyErr_Format(PyExc_RuntimeError,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2731 "_compat_pickle.REVERSE_NAME_MAPPING values "
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2732 "should be pairs of str, not (%.200s, %.200s)",
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2733 Py_TYPE(module_name)->tp_name,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2734 Py_TYPE(global_name)->tp_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2735 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2736 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2737 Py_INCREF(module_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2738 Py_INCREF(global_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2739 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2740 else if (PyErr_Occurred()) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2741 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2742 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2743
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2744 item = PyDict_GetItemWithError(import_mapping_3to2, module_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2745 if (item) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2746 if (!PyUnicode_Check(item)) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2747 PyErr_Format(PyExc_RuntimeError,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2748 "_compat_pickle.REVERSE_IMPORT_MAPPING values "
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2749 "should be strings, not %.200s",
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2750 Py_TYPE(item)->tp_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2751 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2752 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2753 Py_CLEAR(module_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2754 module_name = item;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2755 Py_INCREF(module_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2756 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2757 else if (PyErr_Occurred()) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2758 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2759 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2760 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
2761
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2762 /* Save the name of the module. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2763 encoded = unicode_encoder(module_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2764 if (encoded == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2765 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2766 PyErr_Format(PicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2767 "can't pickle module identifier '%S' using "
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2768 "pickle protocol %i", module_name, self->proto);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2769 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2770 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2771 if (_Pickler_Write(self, PyBytes_AS_STRING(encoded),
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2772 PyBytes_GET_SIZE(encoded)) < 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2773 Py_DECREF(encoded);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2774 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2775 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2776 Py_DECREF(encoded);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2777 if(_Pickler_Write(self, "\n", 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2778 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2779
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2780 /* Save the name of the module. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2781 encoded = unicode_encoder(global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2782 if (encoded == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2783 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2784 PyErr_Format(PicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2785 "can't pickle global identifier '%S' using "
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2786 "pickle protocol %i", global_name, self->proto);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2787 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2788 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2789 if (_Pickler_Write(self, PyBytes_AS_STRING(encoded),
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2790 PyBytes_GET_SIZE(encoded)) < 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2791 Py_DECREF(encoded);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2792 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2793 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2794 Py_DECREF(encoded);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2795 if(_Pickler_Write(self, "\n", 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2796 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2797
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2798 /* Memoize the object. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2799 if (memo_put(self, obj) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2800 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2801 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2802
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2803 if (0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2804 error:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2805 status = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2806 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2807 Py_XDECREF(module_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2808 Py_XDECREF(global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2809 Py_XDECREF(module);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2810
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2811 return status;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2812 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2813
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2814 static int
75548
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
2815 save_ellipsis(PicklerObject *self, PyObject *obj)
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
2816 {
75554
5353357382e2 #13842: check whether PyUnicode_FromString succeeded
Łukasz Langa <lukasz@langa.pl>
parents: 75548
diff changeset
2817 PyObject *str = PyUnicode_FromString("Ellipsis");
75756
9e5fb0b274d8 cleanup Ellipsis and NotImplemented strings after we're done
Benjamin Peterson <benjamin@python.org>
parents: 75562
diff changeset
2818 int res;
75554
5353357382e2 #13842: check whether PyUnicode_FromString succeeded
Łukasz Langa <lukasz@langa.pl>
parents: 75548
diff changeset
2819 if (str == NULL)
75562
fa0d86b4a656 minor PEP7-related fix
Łukasz Langa <lukasz@langa.pl>
parents: 75554
diff changeset
2820 return -1;
75756
9e5fb0b274d8 cleanup Ellipsis and NotImplemented strings after we're done
Benjamin Peterson <benjamin@python.org>
parents: 75562
diff changeset
2821 res = save_global(self, Py_Ellipsis, str);
9e5fb0b274d8 cleanup Ellipsis and NotImplemented strings after we're done
Benjamin Peterson <benjamin@python.org>
parents: 75562
diff changeset
2822 Py_DECREF(str);
9e5fb0b274d8 cleanup Ellipsis and NotImplemented strings after we're done
Benjamin Peterson <benjamin@python.org>
parents: 75562
diff changeset
2823 return res;
75548
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
2824 }
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
2825
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
2826 static int
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
2827 save_notimplemented(PicklerObject *self, PyObject *obj)
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
2828 {
75554
5353357382e2 #13842: check whether PyUnicode_FromString succeeded
Łukasz Langa <lukasz@langa.pl>
parents: 75548
diff changeset
2829 PyObject *str = PyUnicode_FromString("NotImplemented");
75756
9e5fb0b274d8 cleanup Ellipsis and NotImplemented strings after we're done
Benjamin Peterson <benjamin@python.org>
parents: 75562
diff changeset
2830 int res;
75554
5353357382e2 #13842: check whether PyUnicode_FromString succeeded
Łukasz Langa <lukasz@langa.pl>
parents: 75548
diff changeset
2831 if (str == NULL)
75562
fa0d86b4a656 minor PEP7-related fix
Łukasz Langa <lukasz@langa.pl>
parents: 75554
diff changeset
2832 return -1;
75756
9e5fb0b274d8 cleanup Ellipsis and NotImplemented strings after we're done
Benjamin Peterson <benjamin@python.org>
parents: 75562
diff changeset
2833 res = save_global(self, Py_NotImplemented, str);
9e5fb0b274d8 cleanup Ellipsis and NotImplemented strings after we're done
Benjamin Peterson <benjamin@python.org>
parents: 75562
diff changeset
2834 Py_DECREF(str);
9e5fb0b274d8 cleanup Ellipsis and NotImplemented strings after we're done
Benjamin Peterson <benjamin@python.org>
parents: 75562
diff changeset
2835 return res;
75548
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
2836 }
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
2837
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
2838 static int
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2839 save_pers(PicklerObject *self, PyObject *obj, PyObject *func)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2840 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2841 PyObject *pid = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2842 int status = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2843
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2844 const char persid_op = PERSID;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2845 const char binpersid_op = BINPERSID;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2846
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2847 Py_INCREF(obj);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2848 pid = _Pickler_FastCall(self, func, obj);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2849 if (pid == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2850 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2851
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2852 if (pid != Py_None) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2853 if (self->bin) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2854 if (save(self, pid, 1) < 0 ||
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2855 _Pickler_Write(self, &binpersid_op, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2856 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2857 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2858 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2859 PyObject *pid_str = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2860 char *pid_ascii_bytes;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2861 Py_ssize_t size;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2862
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2863 pid_str = PyObject_Str(pid);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2864 if (pid_str == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2865 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2866
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2867 /* XXX: Should it check whether the persistent id only contains
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2868 ASCII characters? And what if the pid contains embedded
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2869 newlines? */
48660
85b67fb5672b Rename PyUnicode_AsString -> _PyUnicode_AsString and
Marc-André Lemburg <mal@egenix.com>
parents: 48462
diff changeset
2870 pid_ascii_bytes = _PyUnicode_AsStringAndSize(pid_str, &size);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2871 Py_DECREF(pid_str);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2872 if (pid_ascii_bytes == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2873 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2874
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2875 if (_Pickler_Write(self, &persid_op, 1) < 0 ||
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2876 _Pickler_Write(self, pid_ascii_bytes, size) < 0 ||
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2877 _Pickler_Write(self, "\n", 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2878 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2879 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2880 status = 1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2881 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2882
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2883 if (0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2884 error:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2885 status = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2886 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2887 Py_XDECREF(pid);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2888
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2889 return status;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2890 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2891
68383
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2892 static PyObject *
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2893 get_class(PyObject *obj)
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2894 {
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2895 PyObject *cls;
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2896 static PyObject *str_class;
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2897
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2898 if (str_class == NULL) {
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2899 str_class = PyUnicode_InternFromString("__class__");
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2900 if (str_class == NULL)
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2901 return NULL;
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2902 }
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2903 cls = PyObject_GetAttr(obj, str_class);
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2904 if (cls == NULL) {
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2905 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2906 PyErr_Clear();
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2907 cls = (PyObject *) Py_TYPE(obj);
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2908 Py_INCREF(cls);
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2909 }
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2910 }
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2911 return cls;
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2912 }
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2913
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2914 /* We're saving obj, and args is the 2-thru-5 tuple returned by the
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2915 * appropriate __reduce__ method for obj.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2916 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2917 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2918 save_reduce(PicklerObject *self, PyObject *args, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2919 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2920 PyObject *callable;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2921 PyObject *argtup;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2922 PyObject *state = NULL;
49615
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2923 PyObject *listitems = Py_None;
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2924 PyObject *dictitems = Py_None;
49638
f2bb133ef517 Sorry, r67092 is commit miss....
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 49637
diff changeset
2925 Py_ssize_t size;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2926
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2927 int use_newobj = self->proto >= 2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2928
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2929 const char reduce_op = REDUCE;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2930 const char build_op = BUILD;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2931 const char newobj_op = NEWOBJ;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2932
49638
f2bb133ef517 Sorry, r67092 is commit miss....
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 49637
diff changeset
2933 size = PyTuple_Size(args);
f2bb133ef517 Sorry, r67092 is commit miss....
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 49637
diff changeset
2934 if (size < 2 || size > 5) {
f2bb133ef517 Sorry, r67092 is commit miss....
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 49637
diff changeset
2935 PyErr_SetString(PicklingError, "tuple returned by "
f2bb133ef517 Sorry, r67092 is commit miss....
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 49637
diff changeset
2936 "__reduce__ must contain 2 through 5 elements");
f2bb133ef517 Sorry, r67092 is commit miss....
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 49637
diff changeset
2937 return -1;
f2bb133ef517 Sorry, r67092 is commit miss....
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 49637
diff changeset
2938 }
f2bb133ef517 Sorry, r67092 is commit miss....
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 49637
diff changeset
2939
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2940 if (!PyArg_UnpackTuple(args, "save_reduce", 2, 5,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2941 &callable, &argtup, &state, &listitems, &dictitems))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2942 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2943
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2944 if (!PyCallable_Check(callable)) {
49615
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2945 PyErr_SetString(PicklingError, "first item of the tuple "
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2946 "returned by __reduce__ must be callable");
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2947 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2948 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2949 if (!PyTuple_Check(argtup)) {
49615
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2950 PyErr_SetString(PicklingError, "second item of the tuple "
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2951 "returned by __reduce__ must be a tuple");
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2952 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2953 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2954
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2955 if (state == Py_None)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2956 state = NULL;
49615
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2957
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2958 if (listitems == Py_None)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2959 listitems = NULL;
49615
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2960 else if (!PyIter_Check(listitems)) {
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2961 PyErr_Format(PicklingError, "Fourth element of tuple"
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2962 "returned by __reduce__ must be an iterator, not %s",
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2963 Py_TYPE(listitems)->tp_name);
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2964 return -1;
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2965 }
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2966
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2967 if (dictitems == Py_None)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2968 dictitems = NULL;
49615
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2969 else if (!PyIter_Check(dictitems)) {
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2970 PyErr_Format(PicklingError, "Fifth element of tuple"
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2971 "returned by __reduce__ must be an iterator, not %s",
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2972 Py_TYPE(dictitems)->tp_name);
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2973 return -1;
a5ca8951bef1 Merged revisions 67049 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49546
diff changeset
2974 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2975
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2976 /* Protocol 2 special case: if callable's name is __newobj__, use
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2977 NEWOBJ. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2978 if (use_newobj) {
68383
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2979 static PyObject *newobj_str = NULL, *name_str = NULL;
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2980 PyObject *name;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2981
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2982 if (newobj_str == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2983 newobj_str = PyUnicode_InternFromString("__newobj__");
68383
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2984 name_str = PyUnicode_InternFromString("__name__");
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2985 if (newobj_str == NULL || name_str == NULL)
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
2986 return -1;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2987 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2988
68383
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2989 name = PyObject_GetAttr(callable, name_str);
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2990 if (name == NULL) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2991 if (PyErr_ExceptionMatches(PyExc_AttributeError))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2992 PyErr_Clear();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2993 else
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2994 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2995 use_newobj = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2996 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
2997 else {
68383
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2998 use_newobj = PyUnicode_Check(name) &&
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
2999 PyUnicode_Compare(name, newobj_str) == 0;
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
3000 Py_DECREF(name);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3001 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3002 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3003 if (use_newobj) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3004 PyObject *cls;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3005 PyObject *newargtup;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3006 PyObject *obj_class;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3007 int p;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3008
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3009 /* Sanity checks. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3010 if (Py_SIZE(argtup) < 1) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3011 PyErr_SetString(PicklingError, "__newobj__ arglist is empty");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3012 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3013 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3014
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3015 cls = PyTuple_GET_ITEM(argtup, 0);
68383
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
3016 if (!PyType_Check(cls)) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3017 PyErr_SetString(PicklingError, "args[0] from "
68383
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
3018 "__newobj__ args is not a type");
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3019 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3020 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3021
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3022 if (obj != NULL) {
68383
ff0220c9d213 Issue #9935: Speed up pickling of instances of user-defined classes.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68257
diff changeset
3023 obj_class = get_class(obj);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3024 p = obj_class != cls; /* true iff a problem */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3025 Py_DECREF(obj_class);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3026 if (p) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3027 PyErr_SetString(PicklingError, "args[0] from "
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3028 "__newobj__ args has the wrong class");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3029 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3030 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3031 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3032 /* XXX: These calls save() are prone to infinite recursion. Imagine
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3033 what happen if the value returned by the __reduce__() method of
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3034 some extension type contains another object of the same type. Ouch!
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3035
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3036 Here is a quick example, that I ran into, to illustrate what I
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3037 mean:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3038
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3039 >>> import pickle, copyreg
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3040 >>> copyreg.dispatch_table.pop(complex)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3041 >>> pickle.dumps(1+2j)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3042 Traceback (most recent call last):
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3043 ...
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3044 RuntimeError: maximum recursion depth exceeded
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3045
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3046 Removing the complex class from copyreg.dispatch_table made the
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3047 __reduce_ex__() method emit another complex object:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3048
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3049 >>> (1+1j).__reduce_ex__(2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3050 (<function __newobj__ at 0xb7b71c3c>,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3051 (<class 'complex'>, (1+1j)), None, None, None)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3052
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3053 Thus when save() was called on newargstup (the 2nd item) recursion
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3054 ensued. Of course, the bug was in the complex class which had a
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3055 broken __getnewargs__() that emitted another complex object. But,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3056 the point, here, is it is quite easy to end up with a broken reduce
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3057 function. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3058
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3059 /* Save the class and its __new__ arguments. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3060 if (save(self, cls, 0) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3061 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3062
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3063 newargtup = PyTuple_GetSlice(argtup, 1, Py_SIZE(argtup));
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3064 if (newargtup == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3065 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3066
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3067 p = save(self, newargtup, 0);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3068 Py_DECREF(newargtup);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3069 if (p < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3070 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3071
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3072 /* Add NEWOBJ opcode. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3073 if (_Pickler_Write(self, &newobj_op, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3074 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3075 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3076 else { /* Not using NEWOBJ. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3077 if (save(self, callable, 0) < 0 ||
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3078 save(self, argtup, 0) < 0 ||
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3079 _Pickler_Write(self, &reduce_op, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3080 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3081 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3082
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3083 /* obj can be NULL when save_reduce() is used directly. A NULL obj means
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3084 the caller do not want to memoize the object. Not particularly useful,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3085 but that is to mimic the behavior save_reduce() in pickle.py when
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3086 obj is None. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3087 if (obj && memo_put(self, obj) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3088 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3089
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3090 if (listitems && batch_list(self, listitems) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3091 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3092
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3093 if (dictitems && batch_dict(self, dictitems) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3094 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3095
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3096 if (state) {
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
3097 if (save(self, state, 0) < 0 ||
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3098 _Pickler_Write(self, &build_op, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3099 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3100 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3101
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3102 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3103 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3104
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3105 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3106 save(PicklerObject *self, PyObject *obj, int pers_save)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3107 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3108 PyTypeObject *type;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3109 PyObject *reduce_func = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3110 PyObject *reduce_value = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3111 int status = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3112
67725
bcf030f73eee Merged revisions 88147 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3113 if (Py_EnterRecursiveCall(" while pickling an object"))
48462
c5710f0debae Fixed _pickle to use Py_EnterRecursiveCall().
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 47670
diff changeset
3114 return -1;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3115
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3116 /* The extra pers_save argument is necessary to avoid calling save_pers()
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3117 on its returned object. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3118 if (!pers_save && self->pers_func) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3119 /* save_pers() returns:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3120 -1 to signal an error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3121 0 if it did nothing successfully;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3122 1 if a persistent id was saved.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3123 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3124 if ((status = save_pers(self, obj, self->pers_func)) != 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3125 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3126 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3127
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3128 type = Py_TYPE(obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3129
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3130 /* The old cPickle had an optimization that used switch-case statement
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3131 dispatching on the first letter of the type name. This has was removed
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3132 since benchmarks shown that this optimization was actually slowing
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3133 things down. */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3134
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3135 /* Atom types; these aren't memoized, so don't check the memo. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3136
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3137 if (obj == Py_None) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3138 status = save_none(self, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3139 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3140 }
75548
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
3141 else if (obj == Py_Ellipsis) {
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
3142 status = save_ellipsis(self, obj);
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
3143 goto done;
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
3144 }
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
3145 else if (obj == Py_NotImplemented) {
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
3146 status = save_notimplemented(self, obj);
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
3147 goto done;
5832d3622473 Fixes #13842: cannot pickle Ellipsis or NotImplemented.
Łukasz Langa <lukasz@langa.pl>
parents: 75391
diff changeset
3148 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3149 else if (obj == Py_False || obj == Py_True) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3150 status = save_bool(self, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3151 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3152 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3153 else if (type == &PyLong_Type) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3154 status = save_long(self, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3155 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3156 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3157 else if (type == &PyFloat_Type) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3158 status = save_float(self, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3159 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3160 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3161
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3162 /* Check the memo to see if it has the object. If so, generate
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3163 a GET (or BINGET) opcode, instead of pickling the object
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3164 once again. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3165 if (PyMemoTable_Get(self->memo, obj)) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3166 if (memo_get(self, obj) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3167 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3168 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3169 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3170
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3171 if (type == &PyBytes_Type) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3172 status = save_bytes(self, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3173 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3174 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3175 else if (type == &PyUnicode_Type) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3176 status = save_unicode(self, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3177 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3178 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3179 else if (type == &PyDict_Type) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3180 status = save_dict(self, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3181 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3182 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3183 else if (type == &PyList_Type) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3184 status = save_list(self, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3185 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3186 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3187 else if (type == &PyTuple_Type) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3188 status = save_tuple(self, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3189 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3190 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3191 else if (type == &PyType_Type) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3192 status = save_global(self, obj, NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3193 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3194 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3195 else if (type == &PyFunction_Type) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3196 status = save_global(self, obj, NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3197 if (status < 0 && PyErr_ExceptionMatches(PickleError)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3198 /* fall back to reduce */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3199 PyErr_Clear();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3200 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3201 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3202 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3203 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3204 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3205 else if (type == &PyCFunction_Type) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3206 status = save_global(self, obj, NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3207 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3208 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3209
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3210 /* XXX: This part needs some unit tests. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3211
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3212 /* Get a reduction callable, and call it. This may come from
75391
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3213 * self.dispatch_table, copyreg.dispatch_table, the object's
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3214 * __reduce_ex__ method, or the object's __reduce__ method.
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3215 */
75391
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3216 if (self->dispatch_table == NULL) {
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3217 reduce_func = PyDict_GetItem(dispatch_table, (PyObject *)type);
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3218 /* PyDict_GetItem() unlike PyObject_GetItem() and
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3219 PyObject_GetAttr() returns a borrowed ref */
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3220 Py_XINCREF(reduce_func);
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3221 } else {
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3222 reduce_func = PyObject_GetItem(self->dispatch_table, (PyObject *)type);
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3223 if (reduce_func == NULL) {
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3224 if (PyErr_ExceptionMatches(PyExc_KeyError))
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3225 PyErr_Clear();
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3226 else
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3227 goto error;
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3228 }
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3229 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3230 if (reduce_func != NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3231 Py_INCREF(obj);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3232 reduce_value = _Pickler_FastCall(self, reduce_func, obj);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3233 }
72639
760ac320fa3d Issue #7689: Allow pickling of dynamically created classes when their
Antoine Pitrou <solipsis@pitrou.net>
parents: 72457
diff changeset
3234 else if (PyType_IsSubtype(type, &PyType_Type)) {
760ac320fa3d Issue #7689: Allow pickling of dynamically created classes when their
Antoine Pitrou <solipsis@pitrou.net>
parents: 72457
diff changeset
3235 status = save_global(self, obj, NULL);
760ac320fa3d Issue #7689: Allow pickling of dynamically created classes when their
Antoine Pitrou <solipsis@pitrou.net>
parents: 72457
diff changeset
3236 goto done;
760ac320fa3d Issue #7689: Allow pickling of dynamically created classes when their
Antoine Pitrou <solipsis@pitrou.net>
parents: 72457
diff changeset
3237 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3238 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3239 static PyObject *reduce_str = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3240 static PyObject *reduce_ex_str = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3241
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3242 /* Cache the name of the reduce methods. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3243 if (reduce_str == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3244 reduce_str = PyUnicode_InternFromString("__reduce__");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3245 if (reduce_str == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3246 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3247 reduce_ex_str = PyUnicode_InternFromString("__reduce_ex__");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3248 if (reduce_ex_str == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3249 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3250 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3251
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3252 /* XXX: If the __reduce__ method is defined, __reduce_ex__ is
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3253 automatically defined as __reduce__. While this is convenient, this
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3254 make it impossible to know which method was actually called. Of
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3255 course, this is not a big deal. But still, it would be nice to let
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3256 the user know which method was called when something go
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3257 wrong. Incidentally, this means if __reduce_ex__ is not defined, we
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3258 don't actually have to check for a __reduce__ method. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3259
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3260 /* Check for a __reduce_ex__ method. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3261 reduce_func = PyObject_GetAttr(obj, reduce_ex_str);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3262 if (reduce_func != NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3263 PyObject *proto;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3264 proto = PyLong_FromLong(self->proto);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3265 if (proto != NULL) {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3266 reduce_value = _Pickler_FastCall(self, reduce_func, proto);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3267 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3268 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3269 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3270 if (PyErr_ExceptionMatches(PyExc_AttributeError))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3271 PyErr_Clear();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3272 else
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3273 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3274 /* Check for a __reduce__ method. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3275 reduce_func = PyObject_GetAttr(obj, reduce_str);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3276 if (reduce_func != NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3277 reduce_value = PyObject_Call(reduce_func, empty_tuple, NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3278 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3279 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3280 PyErr_Format(PicklingError, "can't pickle '%.200s' object: %R",
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3281 type->tp_name, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3282 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3283 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3284 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3285 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3286
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3287 if (reduce_value == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3288 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3289
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3290 if (PyUnicode_Check(reduce_value)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3291 status = save_global(self, obj, reduce_value);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3292 goto done;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3293 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3294
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3295 if (!PyTuple_Check(reduce_value)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3296 PyErr_SetString(PicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3297 "__reduce__ must return a string or tuple");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3298 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3299 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3300
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3301 status = save_reduce(self, reduce_value, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3302
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3303 if (0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3304 error:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3305 status = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3306 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3307 done:
48462
c5710f0debae Fixed _pickle to use Py_EnterRecursiveCall().
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 47670
diff changeset
3308 Py_LeaveRecursiveCall();
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3309 Py_XDECREF(reduce_func);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3310 Py_XDECREF(reduce_value);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3311
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3312 return status;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3313 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3314
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3315 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3316 dump(PicklerObject *self, PyObject *obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3317 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3318 const char stop_op = STOP;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3319
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3320 if (self->proto >= 2) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3321 char header[2];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3322
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3323 header[0] = PROTO;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3324 assert(self->proto >= 0 && self->proto < 256);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3325 header[1] = (unsigned char)self->proto;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3326 if (_Pickler_Write(self, header, 2) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3327 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3328 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3329
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3330 if (save(self, obj, 0) < 0 ||
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3331 _Pickler_Write(self, &stop_op, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3332 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3333
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3334 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3335 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3336
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3337 PyDoc_STRVAR(Pickler_clear_memo_doc,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3338 "clear_memo() -> None. Clears the pickler's \"memo\"."
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3339 "\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3340 "The memo is the data structure that remembers which objects the\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3341 "pickler has already seen, so that shared or recursive objects are\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3342 "pickled by reference and not by value. This method is useful when\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3343 "re-using picklers.");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3344
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3345 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3346 Pickler_clear_memo(PicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3347 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3348 if (self->memo)
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3349 PyMemoTable_Clear(self->memo);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3350
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3351 Py_RETURN_NONE;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3352 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3353
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3354 PyDoc_STRVAR(Pickler_dump_doc,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3355 "dump(obj) -> None. Write a pickled representation of obj to the open file.");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3356
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3357 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3358 Pickler_dump(PicklerObject *self, PyObject *args)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3359 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3360 PyObject *obj;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3361
49546
bc1f43252c92 #3664: The pickle module could segfault if a Pickler instance is not correctly initialized:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49149
diff changeset
3362 /* Check whether the Pickler was initialized correctly (issue3664).
bc1f43252c92 #3664: The pickle module could segfault if a Pickler instance is not correctly initialized:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49149
diff changeset
3363 Developers often forget to call __init__() in their subclasses, which
bc1f43252c92 #3664: The pickle module could segfault if a Pickler instance is not correctly initialized:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49149
diff changeset
3364 would trigger a segfault without this check. */
bc1f43252c92 #3664: The pickle module could segfault if a Pickler instance is not correctly initialized:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49149
diff changeset
3365 if (self->write == NULL) {
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
3366 PyErr_Format(PicklingError,
49546
bc1f43252c92 #3664: The pickle module could segfault if a Pickler instance is not correctly initialized:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49149
diff changeset
3367 "Pickler.__init__() was not called by %s.__init__()",
bc1f43252c92 #3664: The pickle module could segfault if a Pickler instance is not correctly initialized:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49149
diff changeset
3368 Py_TYPE(self)->tp_name);
bc1f43252c92 #3664: The pickle module could segfault if a Pickler instance is not correctly initialized:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49149
diff changeset
3369 return NULL;
bc1f43252c92 #3664: The pickle module could segfault if a Pickler instance is not correctly initialized:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49149
diff changeset
3370 }
bc1f43252c92 #3664: The pickle module could segfault if a Pickler instance is not correctly initialized:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 49149
diff changeset
3371
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3372 if (!PyArg_ParseTuple(args, "O:dump", &obj))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3373 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3374
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3375 if (_Pickler_ClearBuffer(self) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3376 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3377
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3378 if (dump(self, obj) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3379 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3380
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3381 if (_Pickler_FlushToFile(self) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3382 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3383
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3384 Py_RETURN_NONE;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3385 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3386
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3387 static struct PyMethodDef Pickler_methods[] = {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3388 {"dump", (PyCFunction)Pickler_dump, METH_VARARGS,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3389 Pickler_dump_doc},
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3390 {"clear_memo", (PyCFunction)Pickler_clear_memo, METH_NOARGS,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3391 Pickler_clear_memo_doc},
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3392 {NULL, NULL} /* sentinel */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3393 };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3394
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3395 static void
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3396 Pickler_dealloc(PicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3397 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3398 PyObject_GC_UnTrack(self);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3399
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3400 Py_XDECREF(self->output_buffer);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3401 Py_XDECREF(self->write);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3402 Py_XDECREF(self->pers_func);
75391
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3403 Py_XDECREF(self->dispatch_table);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3404 Py_XDECREF(self->arg);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3405 Py_XDECREF(self->fast_memo);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3406
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3407 PyMemoTable_Del(self->memo);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3408
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3409 Py_TYPE(self)->tp_free((PyObject *)self);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3410 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3411
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3412 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3413 Pickler_traverse(PicklerObject *self, visitproc visit, void *arg)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3414 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3415 Py_VISIT(self->write);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3416 Py_VISIT(self->pers_func);
75391
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3417 Py_VISIT(self->dispatch_table);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3418 Py_VISIT(self->arg);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3419 Py_VISIT(self->fast_memo);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3420 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3421 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3422
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3423 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3424 Pickler_clear(PicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3425 {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3426 Py_CLEAR(self->output_buffer);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3427 Py_CLEAR(self->write);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3428 Py_CLEAR(self->pers_func);
75391
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3429 Py_CLEAR(self->dispatch_table);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3430 Py_CLEAR(self->arg);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3431 Py_CLEAR(self->fast_memo);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3432
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3433 if (self->memo != NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3434 PyMemoTable *memo = self->memo;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3435 self->memo = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3436 PyMemoTable_Del(memo);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3437 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3438 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3439 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3440
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3441
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3442 PyDoc_STRVAR(Pickler_doc,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3443 "Pickler(file, protocol=None)"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3444 "\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3445 "This takes a binary file for writing a pickle data stream.\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3446 "\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3447 "The optional protocol argument tells the pickler to use the\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3448 "given protocol; supported protocols are 0, 1, 2, 3. The default\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3449 "protocol is 3; a backward-incompatible protocol designed for\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3450 "Python 3.0.\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3451 "\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3452 "Specifying a negative protocol version selects the highest\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3453 "protocol version supported. The higher the protocol used, the\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3454 "more recent the version of Python needed to read the pickle\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3455 "produced.\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3456 "\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3457 "The file argument must have a write() method that accepts a single\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3458 "bytes argument. It can thus be a file object opened for binary\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3459 "writing, a io.BytesIO instance, or any other custom object that\n"
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3460 "meets this interface.\n"
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3461 "\n"
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3462 "If fix_imports is True and protocol is less than 3, pickle will try to\n"
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3463 "map the new Python 3.x names to the old module names used in Python\n"
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3464 "2.x, so that the pickle data stream is readable with Python 2.x.\n");
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3465
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3466 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3467 Pickler_init(PicklerObject *self, PyObject *args, PyObject *kwds)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3468 {
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3469 static char *kwlist[] = {"file", "protocol", "fix_imports", 0};
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3470 PyObject *file;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3471 PyObject *proto_obj = NULL;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3472 PyObject *fix_imports = Py_True;
72925
7109f31300fb Rename _Py_identifier to _Py_IDENTIFIER.
Martin v. Löwis <martin@v.loewis.de>
parents: 72918
diff changeset
3473 _Py_IDENTIFIER(persistent_id);
75391
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3474 _Py_IDENTIFIER(dispatch_table);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3475
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3476 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO:Pickler",
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3477 kwlist, &file, &proto_obj, &fix_imports))
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3478 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3479
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3480 /* In case of multiple __init__() calls, clear previous content. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3481 if (self->write != NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3482 (void)Pickler_clear(self);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3483
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3484 if (_Pickler_SetProtocol(self, proto_obj, fix_imports) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3485 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3486
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3487 if (_Pickler_SetOutputStream(self, file) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3488 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3489
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3490 /* memo and output_buffer may have already been created in _Pickler_New */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3491 if (self->memo == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3492 self->memo = PyMemoTable_New();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3493 if (self->memo == NULL)
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3494 return -1;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3495 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3496 self->output_len = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3497 if (self->output_buffer == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3498 self->max_output_len = WRITE_BUF_SIZE;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3499 self->output_buffer = PyBytes_FromStringAndSize(NULL,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3500 self->max_output_len);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3501 if (self->output_buffer == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3502 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3503 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3504
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3505 self->arg = NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3506 self->fast = 0;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3507 self->fast_nesting = 0;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
3508 self->fast_memo = NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3509 self->pers_func = NULL;
72848
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
3510 if (_PyObject_HasAttrId((PyObject *)self, &PyId_persistent_id)) {
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
3511 self->pers_func = _PyObject_GetAttrId((PyObject *)self,
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
3512 &PyId_persistent_id);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3513 if (self->pers_func == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3514 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3515 }
75391
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3516 self->dispatch_table = NULL;
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3517 if (_PyObject_HasAttrId((PyObject *)self, &PyId_dispatch_table)) {
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3518 self->dispatch_table = _PyObject_GetAttrId((PyObject *)self,
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3519 &PyId_dispatch_table);
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3520 if (self->dispatch_table == NULL)
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3521 return -1;
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3522 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3523 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3524 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3525
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3526 /* Define a proxy object for the Pickler's internal memo object. This is to
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3527 * avoid breaking code like:
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3528 * pickler.memo.clear()
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3529 * and
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3530 * pickler.memo = saved_memo
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3531 * Is this a good idea? Not really, but we don't want to break code that uses
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3532 * it. Note that we don't implement the entire mapping API here. This is
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3533 * intentional, as these should be treated as black-box implementation details.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3534 */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3535
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3536 typedef struct {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3537 PyObject_HEAD
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3538 PicklerObject *pickler; /* Pickler whose memo table we're proxying. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3539 } PicklerMemoProxyObject;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3540
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3541 PyDoc_STRVAR(pmp_clear_doc,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3542 "memo.clear() -> None. Remove all items from memo.");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3543
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3544 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3545 pmp_clear(PicklerMemoProxyObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3546 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3547 if (self->pickler->memo)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3548 PyMemoTable_Clear(self->pickler->memo);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3549 Py_RETURN_NONE;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3550 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3551
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3552 PyDoc_STRVAR(pmp_copy_doc,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3553 "memo.copy() -> new_memo. Copy the memo to a new object.");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3554
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3555 static PyObject *
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3556 pmp_copy(PicklerMemoProxyObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3557 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3558 Py_ssize_t i;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3559 PyMemoTable *memo;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3560 PyObject *new_memo = PyDict_New();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3561 if (new_memo == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3562 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3563
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3564 memo = self->pickler->memo;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3565 for (i = 0; i < memo->mt_allocated; ++i) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3566 PyMemoEntry entry = memo->mt_table[i];
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3567 if (entry.me_key != NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3568 int status;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3569 PyObject *key, *value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3570
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3571 key = PyLong_FromVoidPtr(entry.me_key);
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3572 value = Py_BuildValue("nO", entry.me_value, entry.me_key);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3573
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3574 if (key == NULL || value == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3575 Py_XDECREF(key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3576 Py_XDECREF(value);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3577 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3578 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3579 status = PyDict_SetItem(new_memo, key, value);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3580 Py_DECREF(key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3581 Py_DECREF(value);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3582 if (status < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3583 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3584 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3585 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3586 return new_memo;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3587
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3588 error:
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3589 Py_XDECREF(new_memo);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3590 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3591 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3592
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3593 PyDoc_STRVAR(pmp_reduce_doc,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3594 "memo.__reduce__(). Pickling support.");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3595
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3596 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3597 pmp_reduce(PicklerMemoProxyObject *self, PyObject *args)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3598 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3599 PyObject *reduce_value, *dict_args;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3600 PyObject *contents = pmp_copy(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3601 if (contents == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3602 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3603
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3604 reduce_value = PyTuple_New(2);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3605 if (reduce_value == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3606 Py_DECREF(contents);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3607 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3608 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3609 dict_args = PyTuple_New(1);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3610 if (dict_args == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3611 Py_DECREF(contents);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3612 Py_DECREF(reduce_value);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3613 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3614 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3615 PyTuple_SET_ITEM(dict_args, 0, contents);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3616 Py_INCREF((PyObject *)&PyDict_Type);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3617 PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3618 PyTuple_SET_ITEM(reduce_value, 1, dict_args);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3619 return reduce_value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3620 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3621
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3622 static PyMethodDef picklerproxy_methods[] = {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3623 {"clear", (PyCFunction)pmp_clear, METH_NOARGS, pmp_clear_doc},
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3624 {"copy", (PyCFunction)pmp_copy, METH_NOARGS, pmp_copy_doc},
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3625 {"__reduce__", (PyCFunction)pmp_reduce, METH_VARARGS, pmp_reduce_doc},
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3626 {NULL, NULL} /* sentinel */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3627 };
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3628
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3629 static void
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3630 PicklerMemoProxy_dealloc(PicklerMemoProxyObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3631 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3632 PyObject_GC_UnTrack(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3633 Py_XDECREF(self->pickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3634 PyObject_GC_Del((PyObject *)self);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3635 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3636
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3637 static int
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3638 PicklerMemoProxy_traverse(PicklerMemoProxyObject *self,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3639 visitproc visit, void *arg)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3640 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3641 Py_VISIT(self->pickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3642 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3643 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3644
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3645 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3646 PicklerMemoProxy_clear(PicklerMemoProxyObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3647 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3648 Py_CLEAR(self->pickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3649 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3650 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3651
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3652 static PyTypeObject PicklerMemoProxyType = {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3653 PyVarObject_HEAD_INIT(NULL, 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3654 "_pickle.PicklerMemoProxy", /*tp_name*/
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3655 sizeof(PicklerMemoProxyObject), /*tp_basicsize*/
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3656 0,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3657 (destructor)PicklerMemoProxy_dealloc, /* tp_dealloc */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3658 0, /* tp_print */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3659 0, /* tp_getattr */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3660 0, /* tp_setattr */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3661 0, /* tp_compare */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3662 0, /* tp_repr */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3663 0, /* tp_as_number */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3664 0, /* tp_as_sequence */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3665 0, /* tp_as_mapping */
65513
5b069892e413 Remove more unneeded casts to hashfunc.
Georg Brandl <georg@python.org>
parents: 65494
diff changeset
3666 PyObject_HashNotImplemented, /* tp_hash */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3667 0, /* tp_call */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3668 0, /* tp_str */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3669 PyObject_GenericGetAttr, /* tp_getattro */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3670 PyObject_GenericSetAttr, /* tp_setattro */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3671 0, /* tp_as_buffer */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3672 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3673 0, /* tp_doc */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3674 (traverseproc)PicklerMemoProxy_traverse, /* tp_traverse */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3675 (inquiry)PicklerMemoProxy_clear, /* tp_clear */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3676 0, /* tp_richcompare */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3677 0, /* tp_weaklistoffset */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3678 0, /* tp_iter */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3679 0, /* tp_iternext */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3680 picklerproxy_methods, /* tp_methods */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3681 };
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3682
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3683 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3684 PicklerMemoProxy_New(PicklerObject *pickler)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3685 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3686 PicklerMemoProxyObject *self;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3687
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3688 self = PyObject_GC_New(PicklerMemoProxyObject, &PicklerMemoProxyType);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3689 if (self == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3690 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3691 Py_INCREF(pickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3692 self->pickler = pickler;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3693 PyObject_GC_Track(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3694 return (PyObject *)self;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3695 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3696
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3697 /*****************************************************************************/
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3698
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3699 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3700 Pickler_get_memo(PicklerObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3701 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3702 return PicklerMemoProxy_New(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3703 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3704
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3705 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3706 Pickler_set_memo(PicklerObject *self, PyObject *obj)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3707 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3708 PyMemoTable *new_memo = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3709
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3710 if (obj == NULL) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3711 PyErr_SetString(PyExc_TypeError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3712 "attribute deletion is not supported");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3713 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3714 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3715
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3716 if (Py_TYPE(obj) == &PicklerMemoProxyType) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3717 PicklerObject *pickler =
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3718 ((PicklerMemoProxyObject *)obj)->pickler;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3719
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3720 new_memo = PyMemoTable_Copy(pickler->memo);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3721 if (new_memo == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3722 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3723 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3724 else if (PyDict_Check(obj)) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3725 Py_ssize_t i = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3726 PyObject *key, *value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3727
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3728 new_memo = PyMemoTable_New();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3729 if (new_memo == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3730 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3731
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3732 while (PyDict_Next(obj, &i, &key, &value)) {
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3733 Py_ssize_t memo_id;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3734 PyObject *memo_obj;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3735
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3736 if (!PyTuple_Check(value) || Py_SIZE(value) != 2) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3737 PyErr_SetString(PyExc_TypeError,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3738 "'memo' values must be 2-item tuples");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3739 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3740 }
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3741 memo_id = PyLong_AsSsize_t(PyTuple_GET_ITEM(value, 0));
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3742 if (memo_id == -1 && PyErr_Occurred())
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3743 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3744 memo_obj = PyTuple_GET_ITEM(value, 1);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3745 if (PyMemoTable_Set(new_memo, memo_obj, memo_id) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3746 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3747 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3748 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3749 else {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3750 PyErr_Format(PyExc_TypeError,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3751 "'memo' attribute must be an PicklerMemoProxy object"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3752 "or dict, not %.200s", Py_TYPE(obj)->tp_name);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3753 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3754 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3755
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3756 PyMemoTable_Del(self->memo);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3757 self->memo = new_memo;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3758
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3759 return 0;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3760
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3761 error:
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3762 if (new_memo)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3763 PyMemoTable_Del(new_memo);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3764 return -1;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3765 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3766
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3767 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3768 Pickler_get_persid(PicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3769 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3770 if (self->pers_func == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3771 PyErr_SetString(PyExc_AttributeError, "persistent_id");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3772 else
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3773 Py_INCREF(self->pers_func);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3774 return self->pers_func;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3775 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3776
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3777 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3778 Pickler_set_persid(PicklerObject *self, PyObject *value)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3779 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3780 PyObject *tmp;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3781
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3782 if (value == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3783 PyErr_SetString(PyExc_TypeError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3784 "attribute deletion is not supported");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3785 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3786 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3787 if (!PyCallable_Check(value)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3788 PyErr_SetString(PyExc_TypeError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3789 "persistent_id must be a callable taking one argument");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3790 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3791 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3792
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3793 tmp = self->pers_func;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3794 Py_INCREF(value);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3795 self->pers_func = value;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3796 Py_XDECREF(tmp); /* self->pers_func can be NULL, so be careful. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3797
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3798 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3799 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3800
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3801 static PyMemberDef Pickler_members[] = {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3802 {"bin", T_INT, offsetof(PicklerObject, bin)},
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3803 {"fast", T_INT, offsetof(PicklerObject, fast)},
75391
f7a9a10ae0c0 Issue #14166: Pickler objects now have an optional `dispatch_table` attribute which allows to set custom per-pickler reduction functions.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73958
diff changeset
3804 {"dispatch_table", T_OBJECT_EX, offsetof(PicklerObject, dispatch_table)},
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3805 {NULL}
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3806 };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3807
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3808 static PyGetSetDef Pickler_getsets[] = {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3809 {"memo", (getter)Pickler_get_memo,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3810 (setter)Pickler_set_memo},
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3811 {"persistent_id", (getter)Pickler_get_persid,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3812 (setter)Pickler_set_persid},
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3813 {NULL}
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3814 };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3815
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3816 static PyTypeObject Pickler_Type = {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3817 PyVarObject_HEAD_INIT(NULL, 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3818 "_pickle.Pickler" , /*tp_name*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3819 sizeof(PicklerObject), /*tp_basicsize*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3820 0, /*tp_itemsize*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3821 (destructor)Pickler_dealloc, /*tp_dealloc*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3822 0, /*tp_print*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3823 0, /*tp_getattr*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3824 0, /*tp_setattr*/
51270
debd14c489b9 Issue #1717: rename tp_compare to tp_reserved. I'll change the
Mark Dickinson <dickinsm@gmail.com>
parents: 51243
diff changeset
3825 0, /*tp_reserved*/
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3826 0, /*tp_repr*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3827 0, /*tp_as_number*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3828 0, /*tp_as_sequence*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3829 0, /*tp_as_mapping*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3830 0, /*tp_hash*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3831 0, /*tp_call*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3832 0, /*tp_str*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3833 0, /*tp_getattro*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3834 0, /*tp_setattro*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3835 0, /*tp_as_buffer*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3836 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3837 Pickler_doc, /*tp_doc*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3838 (traverseproc)Pickler_traverse, /*tp_traverse*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3839 (inquiry)Pickler_clear, /*tp_clear*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3840 0, /*tp_richcompare*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3841 0, /*tp_weaklistoffset*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3842 0, /*tp_iter*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3843 0, /*tp_iternext*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3844 Pickler_methods, /*tp_methods*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3845 Pickler_members, /*tp_members*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3846 Pickler_getsets, /*tp_getset*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3847 0, /*tp_base*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3848 0, /*tp_dict*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3849 0, /*tp_descr_get*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3850 0, /*tp_descr_set*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3851 0, /*tp_dictoffset*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3852 (initproc)Pickler_init, /*tp_init*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3853 PyType_GenericAlloc, /*tp_alloc*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3854 PyType_GenericNew, /*tp_new*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3855 PyObject_GC_Del, /*tp_free*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3856 0, /*tp_is_gc*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3857 };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3858
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
3859 /* Temporary helper for calling self.find_class().
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3860
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3861 XXX: It would be nice to able to avoid Python function call overhead, by
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3862 using directly the C version of find_class(), when find_class() is not
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3863 overridden by a subclass. Although, this could become rather hackish. A
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3864 simpler optimization would be to call the C function when self is not a
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3865 subclass instance. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3866 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3867 find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3868 {
72925
7109f31300fb Rename _Py_identifier to _Py_IDENTIFIER.
Martin v. Löwis <martin@v.loewis.de>
parents: 72918
diff changeset
3869 _Py_IDENTIFIER(find_class);
72835
5e33219492bc Add API for static strings, primarily good for identifiers.
Martin v. Löwis <martin@v.loewis.de>
parents: 72640
diff changeset
3870
5e33219492bc Add API for static strings, primarily good for identifiers.
Martin v. Löwis <martin@v.loewis.de>
parents: 72640
diff changeset
3871 return _PyObject_CallMethodId((PyObject *)self, &PyId_find_class, "OO",
5e33219492bc Add API for static strings, primarily good for identifiers.
Martin v. Löwis <martin@v.loewis.de>
parents: 72640
diff changeset
3872 module_name, global_name);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3873 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3874
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3875 static Py_ssize_t
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3876 marker(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3877 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3878 if (self->num_marks < 1) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3879 PyErr_SetString(UnpicklingError, "could not find MARK");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3880 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3881 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3882
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3883 return self->marks[--self->num_marks];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3884 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3885
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3886 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3887 load_none(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3888 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3889 PDATA_APPEND(self->stack, Py_None, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3890 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3891 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3892
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3893 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3894 bad_readline(void)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3895 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3896 PyErr_SetString(UnpicklingError, "pickle data was truncated");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3897 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3898 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3899
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3900 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3901 load_int(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3902 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3903 PyObject *value;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3904 char *endptr, *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3905 Py_ssize_t len;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3906 long x;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3907
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3908 if ((len = _Unpickler_Readline(self, &s)) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3909 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3910 if (len < 2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3911 return bad_readline();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3912
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3913 errno = 0;
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
3914 /* XXX: Should the base argument of strtol() be explicitly set to 10?
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3915 XXX(avassalotti): Should this uses PyOS_strtol()? */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3916 x = strtol(s, &endptr, 0);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3917
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3918 if (errno || (*endptr != '\n' && *endptr != '\0')) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3919 /* Hm, maybe we've got something long. Let's try reading
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3920 * it as a Python long object. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3921 errno = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3922 /* XXX: Same thing about the base here. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
3923 value = PyLong_FromString(s, NULL, 0);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3924 if (value == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3925 PyErr_SetString(PyExc_ValueError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3926 "could not convert string to int");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3927 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3928 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3929 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3930 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3931 if (len == 3 && (x == 0 || x == 1)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3932 if ((value = PyBool_FromLong(x)) == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3933 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3934 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3935 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3936 if ((value = PyLong_FromLong(x)) == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3937 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3938 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3939 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3940
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3941 PDATA_PUSH(self->stack, value, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3942 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3943 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3944
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3945 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3946 load_bool(UnpicklerObject *self, PyObject *boolean)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3947 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3948 assert(boolean == Py_True || boolean == Py_False);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3949 PDATA_APPEND(self->stack, boolean, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3950 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3951 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3952
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3953 /* s contains x bytes of an unsigned little-endian integer. Return its value
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3954 * as a C Py_ssize_t, or -1 if it's higher than PY_SSIZE_T_MAX.
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3955 */
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3956 static Py_ssize_t
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3957 calc_binsize(char *bytes, int size)
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3958 {
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3959 unsigned char *s = (unsigned char *)bytes;
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3960 size_t x = 0;
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3961
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3962 assert(size == 4);
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3963
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3964 x = (size_t) s[0];
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3965 x |= (size_t) s[1] << 8;
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3966 x |= (size_t) s[2] << 16;
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3967 x |= (size_t) s[3] << 24;
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3968
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3969 if (x > PY_SSIZE_T_MAX)
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3970 return -1;
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3971 else
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3972 return (Py_ssize_t) x;
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3973 }
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
3974
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3975 /* s contains x bytes of a little-endian integer. Return its value as a
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3976 * C int. Obscure: when x is 1 or 2, this is an unsigned little-endian
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3977 * int, but when x is 4 it's a signed one. This is an historical source
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3978 * of x-platform bugs.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3979 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3980 static long
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3981 calc_binint(char *bytes, int size)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3982 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3983 unsigned char *s = (unsigned char *)bytes;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3984 int i = size;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3985 long x = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3986
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3987 for (i = 0; i < size; i++) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3988 x |= (long)s[i] << (i * 8);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3989 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3990
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3991 /* Unlike BININT1 and BININT2, BININT (more accurately BININT4)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3992 * is signed, so on a box with longs bigger than 4 bytes we need
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3993 * to extend a BININT's sign bit to the full width.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3994 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3995 if (SIZEOF_LONG > 4 && size == 4) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3996 x |= -(x & (1L << 31));
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3997 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3998
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
3999 return x;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4000 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4001
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4002 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4003 load_binintx(UnpicklerObject *self, char *s, int size)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4004 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4005 PyObject *value;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4006 long x;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4007
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4008 x = calc_binint(s, size);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4009
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4010 if ((value = PyLong_FromLong(x)) == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4011 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4012
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4013 PDATA_PUSH(self->stack, value, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4014 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4015 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4016
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4017 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4018 load_binint(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4019 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4020 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4021
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4022 if (_Unpickler_Read(self, &s, 4) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4023 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4024
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4025 return load_binintx(self, s, 4);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4026 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4027
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4028 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4029 load_binint1(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4030 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4031 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4032
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4033 if (_Unpickler_Read(self, &s, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4034 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4035
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4036 return load_binintx(self, s, 1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4037 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4038
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4039 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4040 load_binint2(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4041 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4042 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4043
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4044 if (_Unpickler_Read(self, &s, 2) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4045 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4046
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4047 return load_binintx(self, s, 2);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4048 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4049
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4050 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4051 load_long(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4052 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4053 PyObject *value;
50987
04c95fc3765f Remove unnecessary copying in load_long().
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 50946
diff changeset
4054 char *s;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4055 Py_ssize_t len;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4056
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4057 if ((len = _Unpickler_Readline(self, &s)) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4058 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4059 if (len < 2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4060 return bad_readline();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4061
50946
a57d10d6bc89 Merged revisions 68814-68815 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50544
diff changeset
4062 /* s[len-2] will usually be 'L' (and s[len-1] is '\n'); we need to remove
a57d10d6bc89 Merged revisions 68814-68815 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50544
diff changeset
4063 the 'L' before calling PyLong_FromString. In order to maintain
a57d10d6bc89 Merged revisions 68814-68815 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50544
diff changeset
4064 compatibility with Python 3.0.0, we don't actually *require*
a57d10d6bc89 Merged revisions 68814-68815 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50544
diff changeset
4065 the 'L' to be present. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4066 if (s[len-2] == 'L')
50987
04c95fc3765f Remove unnecessary copying in load_long().
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 50946
diff changeset
4067 s[len-2] = '\0';
50994
52ff0579a41f Factor common branch in load_long().
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 50987
diff changeset
4068 /* XXX: Should the base argument explicitly set to 10? */
52ff0579a41f Factor common branch in load_long().
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 50987
diff changeset
4069 value = PyLong_FromString(s, NULL, 0);
50946
a57d10d6bc89 Merged revisions 68814-68815 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 50544
diff changeset
4070 if (value == NULL)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4071 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4072
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4073 PDATA_PUSH(self->stack, value, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4074 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4075 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4076
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4077 /* 'size' bytes contain the # of bytes of little-endian 256's-complement
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4078 * data following.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4079 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4080 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4081 load_counted_long(UnpicklerObject *self, int size)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4082 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4083 PyObject *value;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4084 char *nbytes;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4085 char *pdata;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4086
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4087 assert(size == 1 || size == 4);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4088 if (_Unpickler_Read(self, &nbytes, size) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4089 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4090
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4091 size = calc_binint(nbytes, size);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4092 if (size < 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4093 /* Corrupt or hostile pickle -- we never write one like this */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4094 PyErr_SetString(UnpicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4095 "LONG pickle has negative byte count");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4096 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4097 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4098
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4099 if (size == 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4100 value = PyLong_FromLong(0L);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4101 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4102 /* Read the raw little-endian bytes and convert. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4103 if (_Unpickler_Read(self, &pdata, size) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4104 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4105 value = _PyLong_FromByteArray((unsigned char *)pdata, (size_t)size,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4106 1 /* little endian */ , 1 /* signed */ );
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4107 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4108 if (value == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4109 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4110 PDATA_PUSH(self->stack, value, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4111 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4112 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4113
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4114 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4115 load_float(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4116 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4117 PyObject *value;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4118 char *endptr, *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4119 Py_ssize_t len;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4120 double d;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4121
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4122 if ((len = _Unpickler_Readline(self, &s)) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4123 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4124 if (len < 2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4125 return bad_readline();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4126
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4127 errno = 0;
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53694
diff changeset
4128 d = PyOS_string_to_double(s, &endptr, PyExc_OverflowError);
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53694
diff changeset
4129 if (d == -1.0 && PyErr_Occurred())
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53694
diff changeset
4130 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4131 if ((endptr[0] != '\n') && (endptr[0] != '\0')) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4132 PyErr_SetString(PyExc_ValueError, "could not convert string to float");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4133 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4134 }
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53694
diff changeset
4135 value = PyFloat_FromDouble(d);
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53694
diff changeset
4136 if (value == NULL)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4137 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4138
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4139 PDATA_PUSH(self->stack, value, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4140 return 0;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4141 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4142
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4143 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4144 load_binfloat(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4145 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4146 PyObject *value;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4147 double x;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4148 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4149
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4150 if (_Unpickler_Read(self, &s, 8) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4151 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4152
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4153 x = _PyFloat_Unpack8((unsigned char *)s, 0);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4154 if (x == -1.0 && PyErr_Occurred())
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4155 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4156
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4157 if ((value = PyFloat_FromDouble(x)) == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4158 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4159
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4160 PDATA_PUSH(self->stack, value, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4161 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4162 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4163
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4164 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4165 load_string(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4166 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4167 PyObject *bytes;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4168 PyObject *str = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4169 Py_ssize_t len;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4170 char *s, *p;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4171
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4172 if ((len = _Unpickler_Readline(self, &s)) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4173 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4174 if (len < 3)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4175 return bad_readline();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4176 if ((s = strdup(s)) == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4177 PyErr_NoMemory();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4178 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4179 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4180
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4181 /* Strip outermost quotes */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4182 while (s[len - 1] <= ' ')
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4183 len--;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4184 if (s[0] == '"' && s[len - 1] == '"') {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4185 s[len - 1] = '\0';
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4186 p = s + 1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4187 len -= 2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4188 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4189 else if (s[0] == '\'' && s[len - 1] == '\'') {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4190 s[len - 1] = '\0';
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4191 p = s + 1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4192 len -= 2;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4193 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4194 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4195 free(s);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4196 PyErr_SetString(PyExc_ValueError, "insecure string pickle");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4197 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4198 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4199
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4200 /* Use the PyBytes API to decode the string, since that is what is used
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4201 to encode, and then coerce the result to Unicode. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4202 bytes = PyBytes_DecodeEscape(p, len, NULL, 0, NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4203 free(s);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4204 if (bytes == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4205 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4206 str = PyUnicode_FromEncodedObject(bytes, self->encoding, self->errors);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4207 Py_DECREF(bytes);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4208 if (str == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4209 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4210
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4211 PDATA_PUSH(self->stack, str, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4212 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4213 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4214
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4215 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4216 load_binbytes(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4217 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4218 PyObject *bytes;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4219 Py_ssize_t x;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4220 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4221
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4222 if (_Unpickler_Read(self, &s, 4) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4223 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4224
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4225 x = calc_binsize(s, 4);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4226 if (x < 0) {
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4227 PyErr_Format(PyExc_OverflowError,
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4228 "BINBYTES exceeds system's maximum size of %zd bytes",
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4229 PY_SSIZE_T_MAX
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4230 );
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4231 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4232 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4233
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4234 if (_Unpickler_Read(self, &s, x) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4235 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4236 bytes = PyBytes_FromStringAndSize(s, x);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4237 if (bytes == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4238 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4239
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4240 PDATA_PUSH(self->stack, bytes, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4241 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4242 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4243
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4244 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4245 load_short_binbytes(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4246 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4247 PyObject *bytes;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4248 Py_ssize_t x;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4249 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4250
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4251 if (_Unpickler_Read(self, &s, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4252 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4253
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4254 x = (unsigned char)s[0];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4255
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4256 if (_Unpickler_Read(self, &s, x) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4257 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4258
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4259 bytes = PyBytes_FromStringAndSize(s, x);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4260 if (bytes == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4261 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4262
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4263 PDATA_PUSH(self->stack, bytes, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4264 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4265 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4266
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4267 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4268 load_binstring(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4269 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4270 PyObject *str;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4271 Py_ssize_t x;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4272 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4273
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4274 if (_Unpickler_Read(self, &s, 4) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4275 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4276
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4277 x = calc_binint(s, 4);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4278 if (x < 0) {
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
4279 PyErr_SetString(UnpicklingError,
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4280 "BINSTRING pickle has negative byte count");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4281 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4282 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4283
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4284 if (_Unpickler_Read(self, &s, x) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4285 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4286
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4287 /* Convert Python 2.x strings to unicode. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4288 str = PyUnicode_Decode(s, x, self->encoding, self->errors);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4289 if (str == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4290 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4291
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4292 PDATA_PUSH(self->stack, str, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4293 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4294 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4295
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4296 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4297 load_short_binstring(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4298 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4299 PyObject *str;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4300 Py_ssize_t x;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4301 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4302
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4303 if (_Unpickler_Read(self, &s, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4304 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4305
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4306 x = (unsigned char)s[0];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4307
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4308 if (_Unpickler_Read(self, &s, x) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4309 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4310
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4311 /* Convert Python 2.x strings to unicode. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4312 str = PyUnicode_Decode(s, x, self->encoding, self->errors);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4313 if (str == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4314 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4315
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4316 PDATA_PUSH(self->stack, str, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4317 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4318 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4319
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4320 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4321 load_unicode(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4322 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4323 PyObject *str;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4324 Py_ssize_t len;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4325 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4326
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4327 if ((len = _Unpickler_Readline(self, &s)) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4328 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4329 if (len < 1)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4330 return bad_readline();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4331
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4332 str = PyUnicode_DecodeRawUnicodeEscape(s, len - 1, NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4333 if (str == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4334 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4335
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4336 PDATA_PUSH(self->stack, str, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4337 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4338 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4339
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4340 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4341 load_binunicode(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4342 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4343 PyObject *str;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4344 Py_ssize_t size;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4345 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4346
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4347 if (_Unpickler_Read(self, &s, 4) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4348 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4349
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4350 size = calc_binsize(s, 4);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4351 if (size < 0) {
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4352 PyErr_Format(PyExc_OverflowError,
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4353 "BINUNICODE exceeds system's maximum size of %zd bytes",
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4354 PY_SSIZE_T_MAX
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4355 );
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4356 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4357 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4358
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4359
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4360 if (_Unpickler_Read(self, &s, size) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4361 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4362
60577
7994269ad3a1 Issue #8383: pickle and pickletools use surrogatepass error handler when
Victor Stinner <victor.stinner@haypocalc.com>
parents: 58186
diff changeset
4363 str = PyUnicode_DecodeUTF8(s, size, "surrogatepass");
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4364 if (str == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4365 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4366
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4367 PDATA_PUSH(self->stack, str, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4368 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4369 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4370
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4371 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4372 load_tuple(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4373 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4374 PyObject *tuple;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4375 Py_ssize_t i;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4376
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4377 if ((i = marker(self)) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4378 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4379
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4380 tuple = Pdata_poptuple(self->stack, i);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4381 if (tuple == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4382 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4383 PDATA_PUSH(self->stack, tuple, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4384 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4385 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4386
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4387 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4388 load_counted_tuple(UnpicklerObject *self, int len)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4389 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4390 PyObject *tuple;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4391
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4392 tuple = PyTuple_New(len);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4393 if (tuple == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4394 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4395
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4396 while (--len >= 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4397 PyObject *item;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4398
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4399 PDATA_POP(self->stack, item);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4400 if (item == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4401 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4402 PyTuple_SET_ITEM(tuple, len, item);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4403 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4404 PDATA_PUSH(self->stack, tuple, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4405 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4406 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4407
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4408 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4409 load_empty_list(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4410 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4411 PyObject *list;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4412
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4413 if ((list = PyList_New(0)) == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4414 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4415 PDATA_PUSH(self->stack, list, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4416 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4417 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4418
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4419 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4420 load_empty_dict(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4421 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4422 PyObject *dict;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4423
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4424 if ((dict = PyDict_New()) == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4425 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4426 PDATA_PUSH(self->stack, dict, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4427 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4428 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4429
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4430 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4431 load_list(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4432 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4433 PyObject *list;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4434 Py_ssize_t i;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4435
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4436 if ((i = marker(self)) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4437 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4438
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4439 list = Pdata_poplist(self->stack, i);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4440 if (list == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4441 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4442 PDATA_PUSH(self->stack, list, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4443 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4444 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4445
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4446 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4447 load_dict(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4448 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4449 PyObject *dict, *key, *value;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4450 Py_ssize_t i, j, k;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4451
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4452 if ((i = marker(self)) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4453 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4454 j = Py_SIZE(self->stack);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4455
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4456 if ((dict = PyDict_New()) == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4457 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4458
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4459 for (k = i + 1; k < j; k += 2) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4460 key = self->stack->data[k - 1];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4461 value = self->stack->data[k];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4462 if (PyDict_SetItem(dict, key, value) < 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4463 Py_DECREF(dict);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4464 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4465 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4466 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4467 Pdata_clear(self->stack, i);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4468 PDATA_PUSH(self->stack, dict, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4469 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4470 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4471
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4472 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4473 instantiate(PyObject *cls, PyObject *args)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4474 {
63061
3c78b3cfd462 Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents: 60577
diff changeset
4475 PyObject *result = NULL;
72926
db4aa878cea2 Port SetAttrString/HasAttrString to SetAttrId/GetAttrId.
Martin v. Löwis <martin@v.loewis.de>
parents: 72925
diff changeset
4476 _Py_IDENTIFIER(__getinitargs__);
63061
3c78b3cfd462 Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents: 60577
diff changeset
4477 /* Caller must assure args are a tuple. Normally, args come from
3c78b3cfd462 Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents: 60577
diff changeset
4478 Pdata_poptuple which packs objects from the top of the stack
3c78b3cfd462 Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents: 60577
diff changeset
4479 into a newly created tuple. */
3c78b3cfd462 Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents: 60577
diff changeset
4480 assert(PyTuple_Check(args));
3c78b3cfd462 Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents: 60577
diff changeset
4481 if (Py_SIZE(args) > 0 || !PyType_Check(cls) ||
72926
db4aa878cea2 Port SetAttrString/HasAttrString to SetAttrId/GetAttrId.
Martin v. Löwis <martin@v.loewis.de>
parents: 72925
diff changeset
4482 _PyObject_HasAttrId(cls, &PyId___getinitargs__)) {
63061
3c78b3cfd462 Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents: 60577
diff changeset
4483 result = PyObject_CallObject(cls, args);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4484 }
63061
3c78b3cfd462 Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents: 60577
diff changeset
4485 else {
72925
7109f31300fb Rename _Py_identifier to _Py_IDENTIFIER.
Martin v. Löwis <martin@v.loewis.de>
parents: 72918
diff changeset
4486 _Py_IDENTIFIER(__new__);
72835
5e33219492bc Add API for static strings, primarily good for identifiers.
Martin v. Löwis <martin@v.loewis.de>
parents: 72640
diff changeset
4487
5e33219492bc Add API for static strings, primarily good for identifiers.
Martin v. Löwis <martin@v.loewis.de>
parents: 72640
diff changeset
4488 result = _PyObject_CallMethodId(cls, &PyId___new__, "O", cls);
63061
3c78b3cfd462 Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents: 60577
diff changeset
4489 }
3c78b3cfd462 Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents: 60577
diff changeset
4490 return result;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4491 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4492
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4493 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4494 load_obj(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4495 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4496 PyObject *cls, *args, *obj = NULL;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4497 Py_ssize_t i;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4498
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4499 if ((i = marker(self)) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4500 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4501
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4502 args = Pdata_poptuple(self->stack, i + 1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4503 if (args == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4504 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4505
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4506 PDATA_POP(self->stack, cls);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4507 if (cls) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4508 obj = instantiate(cls, args);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4509 Py_DECREF(cls);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4510 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4511 Py_DECREF(args);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4512 if (obj == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4513 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4514
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4515 PDATA_PUSH(self->stack, obj, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4516 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4517 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4518
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4519 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4520 load_inst(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4521 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4522 PyObject *cls = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4523 PyObject *args = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4524 PyObject *obj = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4525 PyObject *module_name;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4526 PyObject *class_name;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4527 Py_ssize_t len;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4528 Py_ssize_t i;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4529 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4530
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4531 if ((i = marker(self)) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4532 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4533 if ((len = _Unpickler_Readline(self, &s)) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4534 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4535 if (len < 2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4536 return bad_readline();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4537
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4538 /* Here it is safe to use PyUnicode_DecodeASCII(), even though non-ASCII
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4539 identifiers are permitted in Python 3.0, since the INST opcode is only
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4540 supported by older protocols on Python 2.x. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4541 module_name = PyUnicode_DecodeASCII(s, len - 1, "strict");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4542 if (module_name == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4543 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4544
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4545 if ((len = _Unpickler_Readline(self, &s)) >= 0) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4546 if (len < 2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4547 return bad_readline();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4548 class_name = PyUnicode_DecodeASCII(s, len - 1, "strict");
63061
3c78b3cfd462 Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents: 60577
diff changeset
4549 if (class_name != NULL) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4550 cls = find_class(self, module_name, class_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4551 Py_DECREF(class_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4552 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4553 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4554 Py_DECREF(module_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4555
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4556 if (cls == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4557 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4558
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4559 if ((args = Pdata_poptuple(self->stack, i)) != NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4560 obj = instantiate(cls, args);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4561 Py_DECREF(args);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4562 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4563 Py_DECREF(cls);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4564
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4565 if (obj == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4566 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4567
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4568 PDATA_PUSH(self->stack, obj, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4569 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4570 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4571
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4572 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4573 load_newobj(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4574 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4575 PyObject *args = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4576 PyObject *clsraw = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4577 PyTypeObject *cls; /* clsraw cast to its true type */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4578 PyObject *obj;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4579
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4580 /* Stack is ... cls argtuple, and we want to call
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4581 * cls.__new__(cls, *argtuple).
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4582 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4583 PDATA_POP(self->stack, args);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4584 if (args == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4585 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4586 if (!PyTuple_Check(args)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4587 PyErr_SetString(UnpicklingError, "NEWOBJ expected an arg " "tuple.");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4588 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4589 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4590
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4591 PDATA_POP(self->stack, clsraw);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4592 cls = (PyTypeObject *)clsraw;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4593 if (cls == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4594 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4595 if (!PyType_Check(cls)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4596 PyErr_SetString(UnpicklingError, "NEWOBJ class argument "
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4597 "isn't a type object");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4598 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4599 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4600 if (cls->tp_new == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4601 PyErr_SetString(UnpicklingError, "NEWOBJ class argument "
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4602 "has NULL tp_new");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4603 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4604 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4605
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4606 /* Call __new__. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4607 obj = cls->tp_new(cls, args, NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4608 if (obj == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4609 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4610
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4611 Py_DECREF(args);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4612 Py_DECREF(clsraw);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4613 PDATA_PUSH(self->stack, obj, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4614 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4615
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4616 error:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4617 Py_XDECREF(args);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4618 Py_XDECREF(clsraw);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4619 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4620 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4621
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4622 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4623 load_global(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4624 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4625 PyObject *global = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4626 PyObject *module_name;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4627 PyObject *global_name;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4628 Py_ssize_t len;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4629 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4630
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4631 if ((len = _Unpickler_Readline(self, &s)) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4632 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4633 if (len < 2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4634 return bad_readline();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4635 module_name = PyUnicode_DecodeUTF8(s, len - 1, "strict");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4636 if (!module_name)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4637 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4638
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4639 if ((len = _Unpickler_Readline(self, &s)) >= 0) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4640 if (len < 2) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4641 Py_DECREF(module_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4642 return bad_readline();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4643 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4644 global_name = PyUnicode_DecodeUTF8(s, len - 1, "strict");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4645 if (global_name) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4646 global = find_class(self, module_name, global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4647 Py_DECREF(global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4648 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4649 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4650 Py_DECREF(module_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4651
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4652 if (global == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4653 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4654 PDATA_PUSH(self->stack, global, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4655 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4656 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4657
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4658 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4659 load_persid(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4660 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4661 PyObject *pid;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4662 Py_ssize_t len;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4663 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4664
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4665 if (self->pers_func) {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4666 if ((len = _Unpickler_Readline(self, &s)) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4667 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4668 if (len < 2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4669 return bad_readline();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4670
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4671 pid = PyBytes_FromStringAndSize(s, len - 1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4672 if (pid == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4673 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4674
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4675 /* Ugh... this does not leak since _Unpickler_FastCall() steals the
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4676 reference to pid first. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4677 pid = _Unpickler_FastCall(self, self->pers_func, pid);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4678 if (pid == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4679 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4680
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4681 PDATA_PUSH(self->stack, pid, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4682 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4683 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4684 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4685 PyErr_SetString(UnpicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4686 "A load persistent id instruction was encountered,\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4687 "but no persistent_load function was specified.");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4688 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4689 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4690 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4691
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4692 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4693 load_binpersid(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4694 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4695 PyObject *pid;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4696
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4697 if (self->pers_func) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4698 PDATA_POP(self->stack, pid);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4699 if (pid == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4700 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4701
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4702 /* Ugh... this does not leak since _Unpickler_FastCall() steals the
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4703 reference to pid first. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4704 pid = _Unpickler_FastCall(self, self->pers_func, pid);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4705 if (pid == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4706 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4707
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4708 PDATA_PUSH(self->stack, pid, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4709 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4710 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4711 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4712 PyErr_SetString(UnpicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4713 "A load persistent id instruction was encountered,\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4714 "but no persistent_load function was specified.");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4715 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4716 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4717 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4718
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4719 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4720 load_pop(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4721 {
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4722 Py_ssize_t len = Py_SIZE(self->stack);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4723
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4724 /* Note that we split the (pickle.py) stack into two stacks,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4725 * an object stack and a mark stack. We have to be clever and
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4726 * pop the right one. We do this by looking at the top of the
54355
9012ff7d75a2 Merged revisions 72930 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 54331
diff changeset
4727 * mark stack first, and only signalling a stack underflow if
9012ff7d75a2 Merged revisions 72930 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 54331
diff changeset
4728 * the object stack is empty and the mark stack doesn't match
9012ff7d75a2 Merged revisions 72930 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 54331
diff changeset
4729 * our expectations.
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4730 */
54355
9012ff7d75a2 Merged revisions 72930 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 54331
diff changeset
4731 if (self->num_marks > 0 && self->marks[self->num_marks - 1] == len) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4732 self->num_marks--;
58186
8903ea6a9e64 Merged revisions 77352-77354 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 54584
diff changeset
4733 } else if (len > 0) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4734 len--;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4735 Py_DECREF(self->stack->data[len]);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4736 Py_SIZE(self->stack) = len;
54355
9012ff7d75a2 Merged revisions 72930 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 54331
diff changeset
4737 } else {
9012ff7d75a2 Merged revisions 72930 via svnmerge from
Collin Winter <collinw@gmail.com>
parents: 54331
diff changeset
4738 return stack_underflow();
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4739 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4740 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4741 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4742
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4743 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4744 load_pop_mark(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4745 {
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4746 Py_ssize_t i;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4747
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4748 if ((i = marker(self)) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4749 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4750
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4751 Pdata_clear(self->stack, i);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4752
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4753 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4754 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4755
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4756 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4757 load_dup(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4758 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4759 PyObject *last;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4760 Py_ssize_t len;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4761
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4762 if ((len = Py_SIZE(self->stack)) <= 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4763 return stack_underflow();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4764 last = self->stack->data[len - 1];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4765 PDATA_APPEND(self->stack, last, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4766 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4767 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4768
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4769 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4770 load_get(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4771 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4772 PyObject *key, *value;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4773 Py_ssize_t idx;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4774 Py_ssize_t len;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4775 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4776
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4777 if ((len = _Unpickler_Readline(self, &s)) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4778 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4779 if (len < 2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4780 return bad_readline();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4781
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4782 key = PyLong_FromString(s, NULL, 10);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4783 if (key == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4784 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4785 idx = PyLong_AsSsize_t(key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4786 if (idx == -1 && PyErr_Occurred()) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4787 Py_DECREF(key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4788 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4789 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4790
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4791 value = _Unpickler_MemoGet(self, idx);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4792 if (value == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4793 if (!PyErr_Occurred())
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4794 PyErr_SetObject(PyExc_KeyError, key);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4795 Py_DECREF(key);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4796 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4797 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4798 Py_DECREF(key);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4799
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4800 PDATA_APPEND(self->stack, value, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4801 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4802 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4803
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4804 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4805 load_binget(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4806 {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4807 PyObject *value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4808 Py_ssize_t idx;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4809 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4810
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4811 if (_Unpickler_Read(self, &s, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4812 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4813
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4814 idx = Py_CHARMASK(s[0]);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4815
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4816 value = _Unpickler_MemoGet(self, idx);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4817 if (value == NULL) {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4818 PyObject *key = PyLong_FromSsize_t(idx);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4819 if (!PyErr_Occurred())
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4820 PyErr_SetObject(PyExc_KeyError, key);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4821 Py_DECREF(key);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4822 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4823 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4824
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4825 PDATA_APPEND(self->stack, value, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4826 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4827 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4828
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4829 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4830 load_long_binget(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4831 {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4832 PyObject *value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4833 Py_ssize_t idx;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4834 char *s;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4835
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4836 if (_Unpickler_Read(self, &s, 4) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4837 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4838
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4839 idx = calc_binsize(s, 4);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4840
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4841 value = _Unpickler_MemoGet(self, idx);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4842 if (value == NULL) {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4843 PyObject *key = PyLong_FromSsize_t(idx);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4844 if (!PyErr_Occurred())
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4845 PyErr_SetObject(PyExc_KeyError, key);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4846 Py_DECREF(key);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4847 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4848 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4849
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4850 PDATA_APPEND(self->stack, value, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4851 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4852 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4853
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4854 /* Push an object from the extension registry (EXT[124]). nbytes is
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4855 * the number of bytes following the opcode, holding the index (code) value.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4856 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4857 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4858 load_extension(UnpicklerObject *self, int nbytes)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4859 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4860 char *codebytes; /* the nbytes bytes after the opcode */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4861 long code; /* calc_binint returns long */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4862 PyObject *py_code; /* code as a Python int */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4863 PyObject *obj; /* the object to push */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4864 PyObject *pair; /* (module_name, class_name) */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4865 PyObject *module_name, *class_name;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4866
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4867 assert(nbytes == 1 || nbytes == 2 || nbytes == 4);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4868 if (_Unpickler_Read(self, &codebytes, nbytes) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4869 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4870 code = calc_binint(codebytes, nbytes);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4871 if (code <= 0) { /* note that 0 is forbidden */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4872 /* Corrupt or hostile pickle. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4873 PyErr_SetString(UnpicklingError, "EXT specifies code <= 0");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4874 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4875 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4876
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4877 /* Look for the code in the cache. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4878 py_code = PyLong_FromLong(code);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4879 if (py_code == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4880 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4881 obj = PyDict_GetItem(extension_cache, py_code);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4882 if (obj != NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4883 /* Bingo. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4884 Py_DECREF(py_code);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4885 PDATA_APPEND(self->stack, obj, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4886 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4887 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4888
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4889 /* Look up the (module_name, class_name) pair. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4890 pair = PyDict_GetItem(inverted_registry, py_code);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4891 if (pair == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4892 Py_DECREF(py_code);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4893 PyErr_Format(PyExc_ValueError, "unregistered extension "
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4894 "code %ld", code);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4895 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4896 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4897 /* Since the extension registry is manipulable via Python code,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4898 * confirm that pair is really a 2-tuple of strings.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4899 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4900 if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2 ||
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4901 !PyUnicode_Check(module_name = PyTuple_GET_ITEM(pair, 0)) ||
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4902 !PyUnicode_Check(class_name = PyTuple_GET_ITEM(pair, 1))) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4903 Py_DECREF(py_code);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4904 PyErr_Format(PyExc_ValueError, "_inverted_registry[%ld] "
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4905 "isn't a 2-tuple of strings", code);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4906 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4907 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4908 /* Load the object. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4909 obj = find_class(self, module_name, class_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4910 if (obj == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4911 Py_DECREF(py_code);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4912 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4913 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4914 /* Cache code -> obj. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4915 code = PyDict_SetItem(extension_cache, py_code, obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4916 Py_DECREF(py_code);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4917 if (code < 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4918 Py_DECREF(obj);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4919 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4920 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4921 PDATA_PUSH(self->stack, obj, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4922 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4923 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4924
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4925 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4926 load_put(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4927 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4928 PyObject *key, *value;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4929 Py_ssize_t idx;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4930 Py_ssize_t len;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4931 char *s;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4932
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4933 if ((len = _Unpickler_Readline(self, &s)) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4934 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4935 if (len < 2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4936 return bad_readline();
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4937 if (Py_SIZE(self->stack) <= 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4938 return stack_underflow();
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4939 value = self->stack->data[Py_SIZE(self->stack) - 1];
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4940
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4941 key = PyLong_FromString(s, NULL, 10);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4942 if (key == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4943 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4944 idx = PyLong_AsSsize_t(key);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4945 Py_DECREF(key);
72121
0d9e4ce1c010 Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
Antoine Pitrou <solipsis@pitrou.net>
parents: 72119
diff changeset
4946 if (idx < 0) {
0d9e4ce1c010 Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
Antoine Pitrou <solipsis@pitrou.net>
parents: 72119
diff changeset
4947 if (!PyErr_Occurred())
0d9e4ce1c010 Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
Antoine Pitrou <solipsis@pitrou.net>
parents: 72119
diff changeset
4948 PyErr_SetString(PyExc_ValueError,
0d9e4ce1c010 Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
Antoine Pitrou <solipsis@pitrou.net>
parents: 72119
diff changeset
4949 "negative PUT argument");
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4950 return -1;
72121
0d9e4ce1c010 Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
Antoine Pitrou <solipsis@pitrou.net>
parents: 72119
diff changeset
4951 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4952
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4953 return _Unpickler_MemoPut(self, idx, value);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4954 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4955
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4956 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4957 load_binput(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4958 {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4959 PyObject *value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4960 Py_ssize_t idx;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4961 char *s;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4962
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4963 if (_Unpickler_Read(self, &s, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4964 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4965
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4966 if (Py_SIZE(self->stack) <= 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4967 return stack_underflow();
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4968 value = self->stack->data[Py_SIZE(self->stack) - 1];
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4969
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4970 idx = Py_CHARMASK(s[0]);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4971
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4972 return _Unpickler_MemoPut(self, idx, value);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4973 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4974
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4975 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4976 load_long_binput(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4977 {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4978 PyObject *value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4979 Py_ssize_t idx;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4980 char *s;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4981
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4982 if (_Unpickler_Read(self, &s, 4) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4983 return -1;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4984
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4985 if (Py_SIZE(self->stack) <= 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4986 return stack_underflow();
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4987 value = self->stack->data[Py_SIZE(self->stack) - 1];
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4988
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
4989 idx = calc_binsize(s, 4);
72121
0d9e4ce1c010 Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
Antoine Pitrou <solipsis@pitrou.net>
parents: 72119
diff changeset
4990 if (idx < 0) {
0d9e4ce1c010 Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
Antoine Pitrou <solipsis@pitrou.net>
parents: 72119
diff changeset
4991 PyErr_SetString(PyExc_ValueError,
0d9e4ce1c010 Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
Antoine Pitrou <solipsis@pitrou.net>
parents: 72119
diff changeset
4992 "negative LONG_BINPUT argument");
0d9e4ce1c010 Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
Antoine Pitrou <solipsis@pitrou.net>
parents: 72119
diff changeset
4993 return -1;
0d9e4ce1c010 Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
Antoine Pitrou <solipsis@pitrou.net>
parents: 72119
diff changeset
4994 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4995
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
4996 return _Unpickler_MemoPut(self, idx, value);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4997 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4998
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
4999 static int
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
5000 do_append(UnpicklerObject *self, Py_ssize_t x)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5001 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5002 PyObject *value;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5003 PyObject *list;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
5004 Py_ssize_t len, i;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5005
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5006 len = Py_SIZE(self->stack);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5007 if (x > len || x <= 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5008 return stack_underflow();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5009 if (len == x) /* nothing to do */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5010 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5011
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5012 list = self->stack->data[x - 1];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5013
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5014 if (PyList_Check(list)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5015 PyObject *slice;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5016 Py_ssize_t list_len;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
5017 int ret;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5018
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5019 slice = Pdata_poplist(self->stack, x);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5020 if (!slice)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5021 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5022 list_len = PyList_GET_SIZE(list);
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
5023 ret = PyList_SetSlice(list, list_len, list_len, slice);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5024 Py_DECREF(slice);
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
5025 return ret;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5026 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5027 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5028 PyObject *append_func;
72925
7109f31300fb Rename _Py_identifier to _Py_IDENTIFIER.
Martin v. Löwis <martin@v.loewis.de>
parents: 72918
diff changeset
5029 _Py_IDENTIFIER(append);
72848
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
5030
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
5031 append_func = _PyObject_GetAttrId(list, &PyId_append);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5032 if (append_func == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5033 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5034 for (i = x; i < len; i++) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5035 PyObject *result;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5036
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5037 value = self->stack->data[i];
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5038 result = _Unpickler_FastCall(self, append_func, value);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5039 if (result == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5040 Pdata_clear(self->stack, i + 1);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5041 Py_SIZE(self->stack) = x;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5042 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5043 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5044 Py_DECREF(result);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5045 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5046 Py_SIZE(self->stack) = x;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5047 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5048
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5049 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5050 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5051
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5052 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5053 load_append(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5054 {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5055 return do_append(self, Py_SIZE(self->stack) - 1);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5056 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5057
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5058 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5059 load_appends(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5060 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5061 return do_append(self, marker(self));
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5062 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5063
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5064 static int
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
5065 do_setitems(UnpicklerObject *self, Py_ssize_t x)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5066 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5067 PyObject *value, *key;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5068 PyObject *dict;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
5069 Py_ssize_t len, i;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5070 int status = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5071
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5072 len = Py_SIZE(self->stack);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5073 if (x > len || x <= 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5074 return stack_underflow();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5075 if (len == x) /* nothing to do */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5076 return 0;
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
5077 if ((len - x) % 2 != 0) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5078 /* Currupt or hostile pickle -- we never write one like this. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5079 PyErr_SetString(UnpicklingError, "odd number of items for SETITEMS");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5080 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5081 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5082
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5083 /* Here, dict does not actually need to be a PyDict; it could be anything
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5084 that supports the __setitem__ attribute. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5085 dict = self->stack->data[x - 1];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5086
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5087 for (i = x + 1; i < len; i += 2) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5088 key = self->stack->data[i - 1];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5089 value = self->stack->data[i];
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5090 if (PyObject_SetItem(dict, key, value) < 0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5091 status = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5092 break;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5093 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5094 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5095
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5096 Pdata_clear(self->stack, x);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5097 return status;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5098 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5099
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5100 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5101 load_setitem(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5102 {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5103 return do_setitems(self, Py_SIZE(self->stack) - 2);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5104 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5105
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5106 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5107 load_setitems(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5108 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5109 return do_setitems(self, marker(self));
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5110 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5111
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5112 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5113 load_build(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5114 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5115 PyObject *state, *inst, *slotstate;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5116 PyObject *setstate;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5117 int status = 0;
72925
7109f31300fb Rename _Py_identifier to _Py_IDENTIFIER.
Martin v. Löwis <martin@v.loewis.de>
parents: 72918
diff changeset
5118 _Py_IDENTIFIER(__setstate__);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5119
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5120 /* Stack is ... instance, state. We want to leave instance at
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5121 * the stack top, possibly mutated via instance.__setstate__(state).
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5122 */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5123 if (Py_SIZE(self->stack) < 2)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5124 return stack_underflow();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5125
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5126 PDATA_POP(self->stack, state);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5127 if (state == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5128 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5129
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5130 inst = self->stack->data[Py_SIZE(self->stack) - 1];
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5131
72848
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
5132 setstate = _PyObject_GetAttrId(inst, &PyId___setstate__);
48696
e961cc014619 Issue 3514: Fixed segfault dues to infinite loop in __getattr__.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 48660
diff changeset
5133 if (setstate == NULL) {
e961cc014619 Issue 3514: Fixed segfault dues to infinite loop in __getattr__.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 48660
diff changeset
5134 if (PyErr_ExceptionMatches(PyExc_AttributeError))
e961cc014619 Issue 3514: Fixed segfault dues to infinite loop in __getattr__.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 48660
diff changeset
5135 PyErr_Clear();
49023
fdd93bfa6c1b Issue #3660 (part of): fix a memory leak in _pickle.
Antoine Pitrou <solipsis@pitrou.net>
parents: 48862
diff changeset
5136 else {
fdd93bfa6c1b Issue #3660 (part of): fix a memory leak in _pickle.
Antoine Pitrou <solipsis@pitrou.net>
parents: 48862
diff changeset
5137 Py_DECREF(state);
48696
e961cc014619 Issue 3514: Fixed segfault dues to infinite loop in __getattr__.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 48660
diff changeset
5138 return -1;
49023
fdd93bfa6c1b Issue #3660 (part of): fix a memory leak in _pickle.
Antoine Pitrou <solipsis@pitrou.net>
parents: 48862
diff changeset
5139 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5140 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5141 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5142 PyObject *result;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5143
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5144 /* The explicit __setstate__ is responsible for everything. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5145 /* Ugh... this does not leak since _Unpickler_FastCall() steals the
49023
fdd93bfa6c1b Issue #3660 (part of): fix a memory leak in _pickle.
Antoine Pitrou <solipsis@pitrou.net>
parents: 48862
diff changeset
5146 reference to state first. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5147 result = _Unpickler_FastCall(self, setstate, state);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5148 Py_DECREF(setstate);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5149 if (result == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5150 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5151 Py_DECREF(result);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5152 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5153 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5154
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5155 /* A default __setstate__. First see whether state embeds a
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5156 * slot state dict too (a proto 2 addition).
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5157 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5158 if (PyTuple_Check(state) && Py_SIZE(state) == 2) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5159 PyObject *tmp = state;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5160
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5161 state = PyTuple_GET_ITEM(tmp, 0);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5162 slotstate = PyTuple_GET_ITEM(tmp, 1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5163 Py_INCREF(state);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5164 Py_INCREF(slotstate);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5165 Py_DECREF(tmp);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5166 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5167 else
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5168 slotstate = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5169
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5170 /* Set inst.__dict__ from the state dict (if any). */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5171 if (state != Py_None) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5172 PyObject *dict;
53694
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5173 PyObject *d_key, *d_value;
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5174 Py_ssize_t i;
72925
7109f31300fb Rename _Py_identifier to _Py_IDENTIFIER.
Martin v. Löwis <martin@v.loewis.de>
parents: 72918
diff changeset
5175 _Py_IDENTIFIER(__dict__);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5176
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5177 if (!PyDict_Check(state)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5178 PyErr_SetString(UnpicklingError, "state is not a dictionary");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5179 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5180 }
72848
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
5181 dict = _PyObject_GetAttrId(inst, &PyId___dict__);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5182 if (dict == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5183 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5184
53694
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5185 i = 0;
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5186 while (PyDict_Next(state, &i, &d_key, &d_value)) {
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5187 /* normally the keys for instance attributes are
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5188 interned. we should try to do that here. */
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5189 Py_INCREF(d_key);
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5190 if (PyUnicode_CheckExact(d_key))
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5191 PyUnicode_InternInPlace(&d_key);
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5192 if (PyObject_SetItem(dict, d_key, d_value) < 0) {
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5193 Py_DECREF(d_key);
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5194 goto error;
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5195 }
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5196 Py_DECREF(d_key);
64d9a9e7f68e Merged revisions 72223 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 53192
diff changeset
5197 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5198 Py_DECREF(dict);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5199 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5200
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5201 /* Also set instance attributes from the slotstate dict (if any). */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5202 if (slotstate != NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5203 PyObject *d_key, *d_value;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5204 Py_ssize_t i;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5205
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5206 if (!PyDict_Check(slotstate)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5207 PyErr_SetString(UnpicklingError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5208 "slot state is not a dictionary");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5209 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5210 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5211 i = 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5212 while (PyDict_Next(slotstate, &i, &d_key, &d_value)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5213 if (PyObject_SetAttr(inst, d_key, d_value) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5214 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5215 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5216 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5217
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5218 if (0) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5219 error:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5220 status = -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5221 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5222
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5223 Py_DECREF(state);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5224 Py_XDECREF(slotstate);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5225 return status;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5226 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5227
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5228 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5229 load_mark(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5230 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5231
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5232 /* Note that we split the (pickle.py) stack into two stacks, an
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5233 * object stack and a mark stack. Here we push a mark onto the
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5234 * mark stack.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5235 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5236
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5237 if ((self->num_marks + 1) >= self->marks_size) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5238 size_t alloc;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
5239 Py_ssize_t *marks;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5240
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5241 /* Use the size_t type to check for overflow. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5242 alloc = ((size_t)self->num_marks << 1) + 20;
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
5243 if (alloc > (PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) ||
47670
13071add8f48 Fixed compiler warnings on MSVC9.0
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 47645
diff changeset
5244 alloc <= ((size_t)self->num_marks + 1)) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5245 PyErr_NoMemory();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5246 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5247 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5248
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5249 if (self->marks == NULL)
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
5250 marks = (Py_ssize_t *) PyMem_Malloc(alloc * sizeof(Py_ssize_t));
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5251 else
72119
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
5252 marks = (Py_ssize_t *) PyMem_Realloc(self->marks,
babc90f3cbf4 Issue #11564: Avoid crashes when trying to pickle huge objects or containers
Antoine Pitrou <solipsis@pitrou.net>
parents: 71817
diff changeset
5253 alloc * sizeof(Py_ssize_t));
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5254 if (marks == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5255 PyErr_NoMemory();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5256 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5257 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5258 self->marks = marks;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5259 self->marks_size = (Py_ssize_t)alloc;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5260 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5261
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5262 self->marks[self->num_marks++] = Py_SIZE(self->stack);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5263
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5264 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5265 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5266
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5267 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5268 load_reduce(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5269 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5270 PyObject *callable = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5271 PyObject *argtup = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5272 PyObject *obj = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5273
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5274 PDATA_POP(self->stack, argtup);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5275 if (argtup == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5276 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5277 PDATA_POP(self->stack, callable);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5278 if (callable) {
63061
3c78b3cfd462 Issue #5180: Fixed a bug that prevented loading 2.x pickles in 3.x
Alexander Belopolsky <alexander.belopolsky@gmail.com>
parents: 60577
diff changeset
5279 obj = PyObject_CallObject(callable, argtup);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5280 Py_DECREF(callable);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5281 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5282 Py_DECREF(argtup);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5283
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5284 if (obj == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5285 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5286
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5287 PDATA_PUSH(self->stack, obj, -1);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5288 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5289 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5290
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5291 /* Just raises an error if we don't know the protocol specified. PROTO
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5292 * is the first opcode for protocols >= 2.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5293 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5294 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5295 load_proto(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5296 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5297 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5298 int i;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5299
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5300 if (_Unpickler_Read(self, &s, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5301 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5302
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5303 i = (unsigned char)s[0];
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5304 if (i <= HIGHEST_PROTOCOL) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5305 self->proto = i;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5306 return 0;
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5307 }
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5308
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5309 PyErr_Format(PyExc_ValueError, "unsupported pickle protocol: %d", i);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5310 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5311 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5312
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5313 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5314 load(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5315 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5316 PyObject *err;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5317 PyObject *value = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5318 char *s;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5319
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5320 self->num_marks = 0;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5321 if (Py_SIZE(self->stack))
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5322 Pdata_clear(self->stack, 0);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5323
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5324 /* Convenient macros for the dispatch while-switch loop just below. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5325 #define OP(opcode, load_func) \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5326 case opcode: if (load_func(self) < 0) break; continue;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5327
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5328 #define OP_ARG(opcode, load_func, arg) \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5329 case opcode: if (load_func(self, (arg)) < 0) break; continue;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5330
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5331 while (1) {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5332 if (_Unpickler_Read(self, &s, 1) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5333 break;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5334
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5335 switch ((enum opcode)s[0]) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5336 OP(NONE, load_none)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5337 OP(BININT, load_binint)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5338 OP(BININT1, load_binint1)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5339 OP(BININT2, load_binint2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5340 OP(INT, load_int)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5341 OP(LONG, load_long)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5342 OP_ARG(LONG1, load_counted_long, 1)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5343 OP_ARG(LONG4, load_counted_long, 4)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5344 OP(FLOAT, load_float)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5345 OP(BINFLOAT, load_binfloat)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5346 OP(BINBYTES, load_binbytes)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5347 OP(SHORT_BINBYTES, load_short_binbytes)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5348 OP(BINSTRING, load_binstring)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5349 OP(SHORT_BINSTRING, load_short_binstring)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5350 OP(STRING, load_string)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5351 OP(UNICODE, load_unicode)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5352 OP(BINUNICODE, load_binunicode)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5353 OP_ARG(EMPTY_TUPLE, load_counted_tuple, 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5354 OP_ARG(TUPLE1, load_counted_tuple, 1)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5355 OP_ARG(TUPLE2, load_counted_tuple, 2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5356 OP_ARG(TUPLE3, load_counted_tuple, 3)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5357 OP(TUPLE, load_tuple)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5358 OP(EMPTY_LIST, load_empty_list)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5359 OP(LIST, load_list)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5360 OP(EMPTY_DICT, load_empty_dict)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5361 OP(DICT, load_dict)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5362 OP(OBJ, load_obj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5363 OP(INST, load_inst)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5364 OP(NEWOBJ, load_newobj)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5365 OP(GLOBAL, load_global)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5366 OP(APPEND, load_append)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5367 OP(APPENDS, load_appends)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5368 OP(BUILD, load_build)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5369 OP(DUP, load_dup)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5370 OP(BINGET, load_binget)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5371 OP(LONG_BINGET, load_long_binget)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5372 OP(GET, load_get)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5373 OP(MARK, load_mark)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5374 OP(BINPUT, load_binput)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5375 OP(LONG_BINPUT, load_long_binput)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5376 OP(PUT, load_put)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5377 OP(POP, load_pop)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5378 OP(POP_MARK, load_pop_mark)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5379 OP(SETITEM, load_setitem)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5380 OP(SETITEMS, load_setitems)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5381 OP(PERSID, load_persid)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5382 OP(BINPERSID, load_binpersid)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5383 OP(REDUCE, load_reduce)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5384 OP(PROTO, load_proto)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5385 OP_ARG(EXT1, load_extension, 1)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5386 OP_ARG(EXT2, load_extension, 2)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5387 OP_ARG(EXT4, load_extension, 4)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5388 OP_ARG(NEWTRUE, load_bool, Py_True)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5389 OP_ARG(NEWFALSE, load_bool, Py_False)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5390
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5391 case STOP:
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5392 break;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5393
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5394 default:
72457
db8027df8458 fix compiler compliant about \0 not being an opcode
Benjamin Peterson <benjamin@python.org>
parents: 72121
diff changeset
5395 if (s[0] == '\0')
db8027df8458 fix compiler compliant about \0 not being an opcode
Benjamin Peterson <benjamin@python.org>
parents: 72121
diff changeset
5396 PyErr_SetNone(PyExc_EOFError);
db8027df8458 fix compiler compliant about \0 not being an opcode
Benjamin Peterson <benjamin@python.org>
parents: 72121
diff changeset
5397 else
db8027df8458 fix compiler compliant about \0 not being an opcode
Benjamin Peterson <benjamin@python.org>
parents: 72121
diff changeset
5398 PyErr_Format(UnpicklingError,
db8027df8458 fix compiler compliant about \0 not being an opcode
Benjamin Peterson <benjamin@python.org>
parents: 72121
diff changeset
5399 "invalid load key, '%c'.", s[0]);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5400 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5401 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5402
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5403 break; /* and we are done! */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5404 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5405
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
5406 if (_Unpickler_SkipConsumed(self) < 0)
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
5407 return NULL;
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
5408
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5409 /* XXX: It is not clear what this is actually for. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5410 if ((err = PyErr_Occurred())) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5411 if (err == PyExc_EOFError) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5412 PyErr_SetNone(PyExc_EOFError);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5413 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5414 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5415 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5416
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5417 PDATA_POP(self->stack, value);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5418 return value;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5419 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5420
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5421 PyDoc_STRVAR(Unpickler_load_doc,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5422 "load() -> object. Load a pickle."
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5423 "\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5424 "Read a pickled object representation from the open file object given in\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5425 "the constructor, and return the reconstituted object hierarchy specified\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5426 "therein.\n");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5427
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5428 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5429 Unpickler_load(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5430 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5431 /* Check whether the Unpickler was initialized correctly. This prevents
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5432 segfaulting if a subclass overridden __init__ with a function that does
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5433 not call Unpickler.__init__(). Here, we simply ensure that self->read
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5434 is not NULL. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5435 if (self->read == NULL) {
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
5436 PyErr_Format(UnpicklingError,
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5437 "Unpickler.__init__() was not called by %s.__init__()",
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5438 Py_TYPE(self)->tp_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5439 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5440 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5441
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5442 return load(self);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5443 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5444
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5445 /* The name of find_class() is misleading. In newer pickle protocols, this
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5446 function is used for loading any global (i.e., functions), not just
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5447 classes. The name is kept only for backward compatibility. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5448
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5449 PyDoc_STRVAR(Unpickler_find_class_doc,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5450 "find_class(module_name, global_name) -> object.\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5451 "\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5452 "Return an object from a specified module, importing the module if\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5453 "necessary. Subclasses may override this method (e.g. to restrict\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5454 "unpickling of arbitrary classes and functions).\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5455 "\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5456 "This method is called whenever a class or a function object is\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5457 "needed. Both arguments passed are str objects.\n");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5458
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5459 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5460 Unpickler_find_class(UnpicklerObject *self, PyObject *args)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5461 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5462 PyObject *global;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5463 PyObject *modules_dict;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5464 PyObject *module;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5465 PyObject *module_name, *global_name;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5466
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5467 if (!PyArg_UnpackTuple(args, "find_class", 2, 2,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5468 &module_name, &global_name))
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5469 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5470
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5471 /* Try to map the old names used in Python 2.x to the new ones used in
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5472 Python 3.x. We do this only with old pickle protocols and when the
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5473 user has not disabled the feature. */
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5474 if (self->proto < 3 && self->fix_imports) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5475 PyObject *key;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5476 PyObject *item;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5477
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5478 /* Check if the global (i.e., a function or a class) was renamed
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5479 or moved to another module. */
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5480 key = PyTuple_Pack(2, module_name, global_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5481 if (key == NULL)
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5482 return NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5483 item = PyDict_GetItemWithError(name_mapping_2to3, key);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5484 Py_DECREF(key);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5485 if (item) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5486 if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5487 PyErr_Format(PyExc_RuntimeError,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5488 "_compat_pickle.NAME_MAPPING values should be "
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5489 "2-tuples, not %.200s", Py_TYPE(item)->tp_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5490 return NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5491 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5492 module_name = PyTuple_GET_ITEM(item, 0);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5493 global_name = PyTuple_GET_ITEM(item, 1);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5494 if (!PyUnicode_Check(module_name) ||
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5495 !PyUnicode_Check(global_name)) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5496 PyErr_Format(PyExc_RuntimeError,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5497 "_compat_pickle.NAME_MAPPING values should be "
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5498 "pairs of str, not (%.200s, %.200s)",
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5499 Py_TYPE(module_name)->tp_name,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5500 Py_TYPE(global_name)->tp_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5501 return NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5502 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5503 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5504 else if (PyErr_Occurred()) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5505 return NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5506 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5507
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5508 /* Check if the module was renamed. */
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5509 item = PyDict_GetItemWithError(import_mapping_2to3, module_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5510 if (item) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5511 if (!PyUnicode_Check(item)) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5512 PyErr_Format(PyExc_RuntimeError,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5513 "_compat_pickle.IMPORT_MAPPING values should be "
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5514 "strings, not %.200s", Py_TYPE(item)->tp_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5515 return NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5516 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5517 module_name = item;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5518 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5519 else if (PyErr_Occurred()) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5520 return NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5521 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5522 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5523
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5524 modules_dict = PySys_GetObject("modules");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5525 if (modules_dict == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5526 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5527
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5528 module = PyDict_GetItemWithError(modules_dict, module_name);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5529 if (module == NULL) {
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5530 if (PyErr_Occurred())
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5531 return NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5532 module = PyImport_Import(module_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5533 if (module == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5534 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5535 global = PyObject_GetAttr(module, global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5536 Py_DECREF(module);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5537 }
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
5538 else {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5539 global = PyObject_GetAttr(module, global_name);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5540 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5541 return global;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5542 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5543
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5544 static struct PyMethodDef Unpickler_methods[] = {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5545 {"load", (PyCFunction)Unpickler_load, METH_NOARGS,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5546 Unpickler_load_doc},
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5547 {"find_class", (PyCFunction)Unpickler_find_class, METH_VARARGS,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5548 Unpickler_find_class_doc},
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5549 {NULL, NULL} /* sentinel */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5550 };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5551
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5552 static void
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5553 Unpickler_dealloc(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5554 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5555 PyObject_GC_UnTrack((PyObject *)self);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5556 Py_XDECREF(self->readline);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5557 Py_XDECREF(self->read);
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
5558 Py_XDECREF(self->peek);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5559 Py_XDECREF(self->stack);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5560 Py_XDECREF(self->pers_func);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5561 Py_XDECREF(self->arg);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5562 if (self->buffer.buf != NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5563 PyBuffer_Release(&self->buffer);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5564 self->buffer.buf = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5565 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5566
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5567 _Unpickler_MemoCleanup(self);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5568 PyMem_Free(self->marks);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5569 PyMem_Free(self->input_line);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5570 free(self->encoding);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5571 free(self->errors);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5572
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5573 Py_TYPE(self)->tp_free((PyObject *)self);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5574 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5575
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5576 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5577 Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5578 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5579 Py_VISIT(self->readline);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5580 Py_VISIT(self->read);
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
5581 Py_VISIT(self->peek);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5582 Py_VISIT(self->stack);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5583 Py_VISIT(self->pers_func);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5584 Py_VISIT(self->arg);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5585 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5586 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5587
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5588 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5589 Unpickler_clear(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5590 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5591 Py_CLEAR(self->readline);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5592 Py_CLEAR(self->read);
65224
4613e1449000 Issue #3873: Speed up unpickling from file objects which have a peek()
Antoine Pitrou <solipsis@pitrou.net>
parents: 64588
diff changeset
5593 Py_CLEAR(self->peek);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5594 Py_CLEAR(self->stack);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5595 Py_CLEAR(self->pers_func);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5596 Py_CLEAR(self->arg);
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5597 if (self->buffer.buf != NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5598 PyBuffer_Release(&self->buffer);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5599 self->buffer.buf = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5600 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5601
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5602 _Unpickler_MemoCleanup(self);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5603 PyMem_Free(self->marks);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5604 self->marks = NULL;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5605 PyMem_Free(self->input_line);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5606 self->input_line = NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5607 free(self->encoding);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5608 self->encoding = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5609 free(self->errors);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5610 self->errors = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5611
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5612 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5613 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5614
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5615 PyDoc_STRVAR(Unpickler_doc,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5616 "Unpickler(file, *, encoding='ASCII', errors='strict')"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5617 "\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5618 "This takes a binary file for reading a pickle data stream.\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5619 "\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5620 "The protocol version of the pickle is detected automatically, so no\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5621 "proto argument is needed.\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5622 "\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5623 "The file-like object must have two methods, a read() method\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5624 "that takes an integer argument, and a readline() method that\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5625 "requires no arguments. Both methods should return bytes.\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5626 "Thus file-like object can be a binary file object opened for\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5627 "reading, a BytesIO object, or any other custom object that\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5628 "meets this interface.\n"
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5629 "\n"
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5630 "Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n"
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5631 "which are used to control compatiblity support for pickle stream\n"
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5632 "generated by Python 2.x. If *fix_imports* is True, pickle will try to\n"
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5633 "map the old Python 2.x names to the new names used in Python 3.x. The\n"
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5634 "*encoding* and *errors* tell pickle how to decode 8-bit string\n"
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5635 "instances pickled by Python 2.x; these default to 'ASCII' and\n"
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5636 "'strict', respectively.\n");
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5637
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5638 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5639 Unpickler_init(UnpicklerObject *self, PyObject *args, PyObject *kwds)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5640 {
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5641 static char *kwlist[] = {"file", "fix_imports", "encoding", "errors", 0};
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5642 PyObject *file;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5643 PyObject *fix_imports = Py_True;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5644 char *encoding = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5645 char *errors = NULL;
72926
db4aa878cea2 Port SetAttrString/HasAttrString to SetAttrId/GetAttrId.
Martin v. Löwis <martin@v.loewis.de>
parents: 72925
diff changeset
5646 _Py_IDENTIFIER(persistent_load);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5647
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5648 /* XXX: That is an horrible error message. But, I don't know how to do
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5649 better... */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5650 if (Py_SIZE(args) != 1) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5651 PyErr_Format(PyExc_TypeError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5652 "%s takes exactly one positional argument (%zd given)",
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5653 Py_TYPE(self)->tp_name, Py_SIZE(args));
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5654 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5655 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5656
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5657 /* Arguments parsing needs to be done in the __init__() method to allow
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5658 subclasses to define their own __init__() method, which may (or may
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5659 not) support Unpickler arguments. However, this means we need to be
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5660 extra careful in the other Unpickler methods, since a subclass could
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5661 forget to call Unpickler.__init__() thus breaking our internal
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5662 invariants. */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5663 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oss:Unpickler", kwlist,
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5664 &file, &fix_imports, &encoding, &errors))
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5665 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5666
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5667 /* In case of multiple __init__() calls, clear previous content. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5668 if (self->read != NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5669 (void)Unpickler_clear(self);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5670
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5671 if (_Unpickler_SetInputStream(self, file) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5672 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5673
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5674 if (_Unpickler_SetInputEncoding(self, encoding, errors) < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5675 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5676
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5677 self->fix_imports = PyObject_IsTrue(fix_imports);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5678 if (self->fix_imports == -1)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5679 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5680
72926
db4aa878cea2 Port SetAttrString/HasAttrString to SetAttrId/GetAttrId.
Martin v. Löwis <martin@v.loewis.de>
parents: 72925
diff changeset
5681 if (_PyObject_HasAttrId((PyObject *)self, &PyId_persistent_load)) {
72848
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
5682 self->pers_func = _PyObject_GetAttrId((PyObject *)self,
81380082d216 Use identifier API for PyObject_GetAttrString.
Martin v. Löwis <martin@v.loewis.de>
parents: 72835
diff changeset
5683 &PyId_persistent_load);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5684 if (self->pers_func == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5685 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5686 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5687 else {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5688 self->pers_func = NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5689 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5690
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5691 self->stack = (Pdata *)Pdata_New();
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5692 if (self->stack == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5693 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5694
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5695 self->memo_size = 32;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5696 self->memo = _Unpickler_NewMemo(self->memo_size);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5697 if (self->memo == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5698 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5699
52761
cbfbff233ef5 Update a comment about why the __module__ can sometime be NULL.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 51270
diff changeset
5700 self->arg = NULL;
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
5701 self->proto = 0;
52761
cbfbff233ef5 Update a comment about why the __module__ can sometime be NULL.
Alexandre Vassalotti <alexandre@peadrop.com>
parents: 51270
diff changeset
5702
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5703 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5704 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5705
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5706 /* Define a proxy object for the Unpickler's internal memo object. This is to
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5707 * avoid breaking code like:
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5708 * unpickler.memo.clear()
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5709 * and
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5710 * unpickler.memo = saved_memo
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5711 * Is this a good idea? Not really, but we don't want to break code that uses
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5712 * it. Note that we don't implement the entire mapping API here. This is
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5713 * intentional, as these should be treated as black-box implementation details.
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5714 *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5715 * We do, however, have to implement pickling/unpickling support because of
72538
a4a9ba2c31ef Strip trailing spaces of _pickle.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 72475
diff changeset
5716 * real-world code like cvs2svn.
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5717 */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5718
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5719 typedef struct {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5720 PyObject_HEAD
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5721 UnpicklerObject *unpickler;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5722 } UnpicklerMemoProxyObject;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5723
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5724 PyDoc_STRVAR(ump_clear_doc,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5725 "memo.clear() -> None. Remove all items from memo.");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5726
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5727 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5728 ump_clear(UnpicklerMemoProxyObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5729 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5730 _Unpickler_MemoCleanup(self->unpickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5731 self->unpickler->memo = _Unpickler_NewMemo(self->unpickler->memo_size);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5732 if (self->unpickler->memo == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5733 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5734 Py_RETURN_NONE;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5735 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5736
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5737 PyDoc_STRVAR(ump_copy_doc,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5738 "memo.copy() -> new_memo. Copy the memo to a new object.");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5739
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5740 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5741 ump_copy(UnpicklerMemoProxyObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5742 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5743 Py_ssize_t i;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5744 PyObject *new_memo = PyDict_New();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5745 if (new_memo == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5746 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5747
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5748 for (i = 0; i < self->unpickler->memo_size; i++) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5749 int status;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5750 PyObject *key, *value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5751
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5752 value = self->unpickler->memo[i];
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5753 if (value == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5754 continue;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5755
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5756 key = PyLong_FromSsize_t(i);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5757 if (key == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5758 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5759 status = PyDict_SetItem(new_memo, key, value);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5760 Py_DECREF(key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5761 if (status < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5762 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5763 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5764 return new_memo;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5765
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5766 error:
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5767 Py_DECREF(new_memo);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5768 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5769 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5770
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5771 PyDoc_STRVAR(ump_reduce_doc,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5772 "memo.__reduce__(). Pickling support.");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5773
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5774 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5775 ump_reduce(UnpicklerMemoProxyObject *self, PyObject *args)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5776 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5777 PyObject *reduce_value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5778 PyObject *constructor_args;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5779 PyObject *contents = ump_copy(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5780 if (contents == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5781 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5782
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5783 reduce_value = PyTuple_New(2);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5784 if (reduce_value == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5785 Py_DECREF(contents);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5786 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5787 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5788 constructor_args = PyTuple_New(1);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5789 if (constructor_args == NULL) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5790 Py_DECREF(contents);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5791 Py_DECREF(reduce_value);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5792 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5793 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5794 PyTuple_SET_ITEM(constructor_args, 0, contents);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5795 Py_INCREF((PyObject *)&PyDict_Type);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5796 PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5797 PyTuple_SET_ITEM(reduce_value, 1, constructor_args);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5798 return reduce_value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5799 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5800
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5801 static PyMethodDef unpicklerproxy_methods[] = {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5802 {"clear", (PyCFunction)ump_clear, METH_NOARGS, ump_clear_doc},
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5803 {"copy", (PyCFunction)ump_copy, METH_NOARGS, ump_copy_doc},
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5804 {"__reduce__", (PyCFunction)ump_reduce, METH_VARARGS, ump_reduce_doc},
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5805 {NULL, NULL} /* sentinel */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5806 };
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5807
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5808 static void
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5809 UnpicklerMemoProxy_dealloc(UnpicklerMemoProxyObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5810 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5811 PyObject_GC_UnTrack(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5812 Py_XDECREF(self->unpickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5813 PyObject_GC_Del((PyObject *)self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5814 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5815
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5816 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5817 UnpicklerMemoProxy_traverse(UnpicklerMemoProxyObject *self,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5818 visitproc visit, void *arg)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5819 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5820 Py_VISIT(self->unpickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5821 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5822 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5823
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5824 static int
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5825 UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5826 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5827 Py_CLEAR(self->unpickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5828 return 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5829 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5830
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5831 static PyTypeObject UnpicklerMemoProxyType = {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5832 PyVarObject_HEAD_INIT(NULL, 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5833 "_pickle.UnpicklerMemoProxy", /*tp_name*/
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5834 sizeof(UnpicklerMemoProxyObject), /*tp_basicsize*/
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5835 0,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5836 (destructor)UnpicklerMemoProxy_dealloc, /* tp_dealloc */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5837 0, /* tp_print */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5838 0, /* tp_getattr */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5839 0, /* tp_setattr */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5840 0, /* tp_compare */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5841 0, /* tp_repr */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5842 0, /* tp_as_number */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5843 0, /* tp_as_sequence */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5844 0, /* tp_as_mapping */
65513
5b069892e413 Remove more unneeded casts to hashfunc.
Georg Brandl <georg@python.org>
parents: 65494
diff changeset
5845 PyObject_HashNotImplemented, /* tp_hash */
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5846 0, /* tp_call */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5847 0, /* tp_str */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5848 PyObject_GenericGetAttr, /* tp_getattro */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5849 PyObject_GenericSetAttr, /* tp_setattro */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5850 0, /* tp_as_buffer */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5851 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5852 0, /* tp_doc */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5853 (traverseproc)UnpicklerMemoProxy_traverse, /* tp_traverse */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5854 (inquiry)UnpicklerMemoProxy_clear, /* tp_clear */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5855 0, /* tp_richcompare */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5856 0, /* tp_weaklistoffset */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5857 0, /* tp_iter */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5858 0, /* tp_iternext */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5859 unpicklerproxy_methods, /* tp_methods */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5860 };
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5861
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5862 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5863 UnpicklerMemoProxy_New(UnpicklerObject *unpickler)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5864 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5865 UnpicklerMemoProxyObject *self;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5866
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5867 self = PyObject_GC_New(UnpicklerMemoProxyObject,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5868 &UnpicklerMemoProxyType);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5869 if (self == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5870 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5871 Py_INCREF(unpickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5872 self->unpickler = unpickler;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5873 PyObject_GC_Track(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5874 return (PyObject *)self;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5875 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5876
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5877 /*****************************************************************************/
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5878
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5879
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5880 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5881 Unpickler_get_memo(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5882 {
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5883 return UnpicklerMemoProxy_New(self);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5884 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5885
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5886 static int
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5887 Unpickler_set_memo(UnpicklerObject *self, PyObject *obj)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5888 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5889 PyObject **new_memo;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5890 Py_ssize_t new_memo_size = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5891 Py_ssize_t i;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5892
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5893 if (obj == NULL) {
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5894 PyErr_SetString(PyExc_TypeError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5895 "attribute deletion is not supported");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5896 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5897 }
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5898
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5899 if (Py_TYPE(obj) == &UnpicklerMemoProxyType) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5900 UnpicklerObject *unpickler =
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5901 ((UnpicklerMemoProxyObject *)obj)->unpickler;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5902
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5903 new_memo_size = unpickler->memo_size;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5904 new_memo = _Unpickler_NewMemo(new_memo_size);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5905 if (new_memo == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5906 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5907
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5908 for (i = 0; i < new_memo_size; i++) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5909 Py_XINCREF(unpickler->memo[i]);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5910 new_memo[i] = unpickler->memo[i];
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5911 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5912 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5913 else if (PyDict_Check(obj)) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5914 Py_ssize_t i = 0;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5915 PyObject *key, *value;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5916
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5917 new_memo_size = PyDict_Size(obj);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5918 new_memo = _Unpickler_NewMemo(new_memo_size);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5919 if (new_memo == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5920 return -1;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5921
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5922 while (PyDict_Next(obj, &i, &key, &value)) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5923 Py_ssize_t idx;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5924 if (!PyLong_Check(key)) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5925 PyErr_SetString(PyExc_TypeError,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5926 "memo key must be integers");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5927 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5928 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5929 idx = PyLong_AsSsize_t(key);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5930 if (idx == -1 && PyErr_Occurred())
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5931 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5932 if (_Unpickler_MemoPut(self, idx, value) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5933 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5934 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5935 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5936 else {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5937 PyErr_Format(PyExc_TypeError,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5938 "'memo' attribute must be an UnpicklerMemoProxy object"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5939 "or dict, not %.200s", Py_TYPE(obj)->tp_name);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5940 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5941 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5942
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5943 _Unpickler_MemoCleanup(self);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5944 self->memo_size = new_memo_size;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5945 self->memo = new_memo;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5946
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5947 return 0;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5948
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5949 error:
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5950 if (new_memo_size) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5951 i = new_memo_size;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5952 while (--i >= 0) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5953 Py_XDECREF(new_memo[i]);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5954 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5955 PyMem_FREE(new_memo);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5956 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
5957 return -1;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5958 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5959
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5960 static PyObject *
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5961 Unpickler_get_persload(UnpicklerObject *self)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5962 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5963 if (self->pers_func == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5964 PyErr_SetString(PyExc_AttributeError, "persistent_load");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5965 else
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5966 Py_INCREF(self->pers_func);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5967 return self->pers_func;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5968 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5969
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5970 static int
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5971 Unpickler_set_persload(UnpicklerObject *self, PyObject *value)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5972 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5973 PyObject *tmp;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5974
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5975 if (value == NULL) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5976 PyErr_SetString(PyExc_TypeError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5977 "attribute deletion is not supported");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5978 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5979 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5980 if (!PyCallable_Check(value)) {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5981 PyErr_SetString(PyExc_TypeError,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5982 "persistent_load must be a callable taking "
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5983 "one argument");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5984 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5985 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5986
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5987 tmp = self->pers_func;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5988 Py_INCREF(value);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5989 self->pers_func = value;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5990 Py_XDECREF(tmp); /* self->pers_func can be NULL, so be careful. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5991
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5992 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5993 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5994
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5995 static PyGetSetDef Unpickler_getsets[] = {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5996 {"memo", (getter)Unpickler_get_memo, (setter)Unpickler_set_memo},
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5997 {"persistent_load", (getter)Unpickler_get_persload,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5998 (setter)Unpickler_set_persload},
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
5999 {NULL}
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6000 };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6001
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6002 static PyTypeObject Unpickler_Type = {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6003 PyVarObject_HEAD_INIT(NULL, 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6004 "_pickle.Unpickler", /*tp_name*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6005 sizeof(UnpicklerObject), /*tp_basicsize*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6006 0, /*tp_itemsize*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6007 (destructor)Unpickler_dealloc, /*tp_dealloc*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6008 0, /*tp_print*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6009 0, /*tp_getattr*/
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6010 0, /*tp_setattr*/
51270
debd14c489b9 Issue #1717: rename tp_compare to tp_reserved. I'll change the
Mark Dickinson <dickinsm@gmail.com>
parents: 51243
diff changeset
6011 0, /*tp_reserved*/
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6012 0, /*tp_repr*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6013 0, /*tp_as_number*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6014 0, /*tp_as_sequence*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6015 0, /*tp_as_mapping*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6016 0, /*tp_hash*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6017 0, /*tp_call*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6018 0, /*tp_str*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6019 0, /*tp_getattro*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6020 0, /*tp_setattro*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6021 0, /*tp_as_buffer*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6022 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6023 Unpickler_doc, /*tp_doc*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6024 (traverseproc)Unpickler_traverse, /*tp_traverse*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6025 (inquiry)Unpickler_clear, /*tp_clear*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6026 0, /*tp_richcompare*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6027 0, /*tp_weaklistoffset*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6028 0, /*tp_iter*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6029 0, /*tp_iternext*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6030 Unpickler_methods, /*tp_methods*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6031 0, /*tp_members*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6032 Unpickler_getsets, /*tp_getset*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6033 0, /*tp_base*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6034 0, /*tp_dict*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6035 0, /*tp_descr_get*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6036 0, /*tp_descr_set*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6037 0, /*tp_dictoffset*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6038 (initproc)Unpickler_init, /*tp_init*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6039 PyType_GenericAlloc, /*tp_alloc*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6040 PyType_GenericNew, /*tp_new*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6041 PyObject_GC_Del, /*tp_free*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6042 0, /*tp_is_gc*/
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6043 };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6044
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6045 PyDoc_STRVAR(pickle_dump_doc,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6046 "dump(obj, file, protocol=None, *, fix_imports=True) -> None\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6047 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6048 "Write a pickled representation of obj to the open file object file. This\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6049 "is equivalent to ``Pickler(file, protocol).dump(obj)``, but may be more\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6050 "efficient.\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6051 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6052 "The optional protocol argument tells the pickler to use the given protocol;\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6053 "supported protocols are 0, 1, 2, 3. The default protocol is 3; a\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6054 "backward-incompatible protocol designed for Python 3.0.\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6055 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6056 "Specifying a negative protocol version selects the highest protocol version\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6057 "supported. The higher the protocol used, the more recent the version of\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6058 "Python needed to read the pickle produced.\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6059 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6060 "The file argument must have a write() method that accepts a single bytes\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6061 "argument. It can thus be a file object opened for binary writing, a\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6062 "io.BytesIO instance, or any other custom object that meets this interface.\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6063 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6064 "If fix_imports is True and protocol is less than 3, pickle will try to\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6065 "map the new Python 3.x names to the old module names used in Python 2.x,\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6066 "so that the pickle data stream is readable with Python 2.x.\n");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6067
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6068 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6069 pickle_dump(PyObject *self, PyObject *args, PyObject *kwds)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6070 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6071 static char *kwlist[] = {"obj", "file", "protocol", "fix_imports", 0};
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6072 PyObject *obj;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6073 PyObject *file;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6074 PyObject *proto = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6075 PyObject *fix_imports = Py_True;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6076 PicklerObject *pickler;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6077
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6078 /* fix_imports is a keyword-only argument. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6079 if (Py_SIZE(args) > 3) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6080 PyErr_Format(PyExc_TypeError,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6081 "pickle.dump() takes at most 3 positional "
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6082 "argument (%zd given)", Py_SIZE(args));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6083 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6084 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6085
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6086 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO:dump", kwlist,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6087 &obj, &file, &proto, &fix_imports))
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6088 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6089
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6090 pickler = _Pickler_New();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6091 if (pickler == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6092 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6093
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6094 if (_Pickler_SetProtocol(pickler, proto, fix_imports) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6095 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6096
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6097 if (_Pickler_SetOutputStream(pickler, file) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6098 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6099
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6100 if (dump(pickler, obj) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6101 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6102
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6103 if (_Pickler_FlushToFile(pickler) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6104 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6105
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6106 Py_DECREF(pickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6107 Py_RETURN_NONE;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6108
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6109 error:
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6110 Py_XDECREF(pickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6111 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6112 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6113
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6114 PyDoc_STRVAR(pickle_dumps_doc,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6115 "dumps(obj, protocol=None, *, fix_imports=True) -> bytes\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6116 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6117 "Return the pickled representation of the object as a bytes\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6118 "object, instead of writing it to a file.\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6119 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6120 "The optional protocol argument tells the pickler to use the given protocol;\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6121 "supported protocols are 0, 1, 2, 3. The default protocol is 3; a\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6122 "backward-incompatible protocol designed for Python 3.0.\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6123 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6124 "Specifying a negative protocol version selects the highest protocol version\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6125 "supported. The higher the protocol used, the more recent the version of\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6126 "Python needed to read the pickle produced.\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6127 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6128 "If fix_imports is True and *protocol* is less than 3, pickle will try to\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6129 "map the new Python 3.x names to the old module names used in Python 2.x,\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6130 "so that the pickle data stream is readable with Python 2.x.\n");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6131
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6132 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6133 pickle_dumps(PyObject *self, PyObject *args, PyObject *kwds)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6134 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6135 static char *kwlist[] = {"obj", "protocol", "fix_imports", 0};
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6136 PyObject *obj;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6137 PyObject *proto = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6138 PyObject *result;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6139 PyObject *fix_imports = Py_True;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6140 PicklerObject *pickler;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6141
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6142 /* fix_imports is a keyword-only argument. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6143 if (Py_SIZE(args) > 2) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6144 PyErr_Format(PyExc_TypeError,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6145 "pickle.dumps() takes at most 2 positional "
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6146 "argument (%zd given)", Py_SIZE(args));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6147 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6148 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6149
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6150 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO:dumps", kwlist,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6151 &obj, &proto, &fix_imports))
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6152 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6153
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6154 pickler = _Pickler_New();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6155 if (pickler == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6156 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6157
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6158 if (_Pickler_SetProtocol(pickler, proto, fix_imports) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6159 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6160
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6161 if (dump(pickler, obj) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6162 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6163
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6164 result = _Pickler_GetString(pickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6165 Py_DECREF(pickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6166 return result;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6167
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6168 error:
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6169 Py_XDECREF(pickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6170 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6171 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6172
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6173 PyDoc_STRVAR(pickle_load_doc,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6174 "load(file, *, fix_imports=True, encoding='ASCII', errors='strict') -> object\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6175 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6176 "Read a pickled object representation from the open file object file and\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6177 "return the reconstituted object hierarchy specified therein. This is\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6178 "equivalent to ``Unpickler(file).load()``, but may be more efficient.\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6179 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6180 "The protocol version of the pickle is detected automatically, so no protocol\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6181 "argument is needed. Bytes past the pickled object's representation are\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6182 "ignored.\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6183 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6184 "The argument file must have two methods, a read() method that takes an\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6185 "integer argument, and a readline() method that requires no arguments. Both\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6186 "methods should return bytes. Thus *file* can be a binary file object opened\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6187 "for reading, a BytesIO object, or any other custom object that meets this\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6188 "interface.\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6189 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6190 "Optional keyword arguments are fix_imports, encoding and errors,\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6191 "which are used to control compatiblity support for pickle stream generated\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6192 "by Python 2.x. If fix_imports is True, pickle will try to map the old\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6193 "Python 2.x names to the new names used in Python 3.x. The encoding and\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6194 "errors tell pickle how to decode 8-bit string instances pickled by Python\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6195 "2.x; these default to 'ASCII' and 'strict', respectively.\n");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6196
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6197 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6198 pickle_load(PyObject *self, PyObject *args, PyObject *kwds)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6199 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6200 static char *kwlist[] = {"file", "fix_imports", "encoding", "errors", 0};
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6201 PyObject *file;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6202 PyObject *fix_imports = Py_True;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6203 PyObject *result;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6204 char *encoding = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6205 char *errors = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6206 UnpicklerObject *unpickler;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6207
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6208 /* fix_imports, encoding and errors are a keyword-only argument. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6209 if (Py_SIZE(args) != 1) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6210 PyErr_Format(PyExc_TypeError,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6211 "pickle.load() takes exactly one positional "
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6212 "argument (%zd given)", Py_SIZE(args));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6213 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6214 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6215
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6216 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oss:load", kwlist,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6217 &file, &fix_imports, &encoding, &errors))
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6218 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6219
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6220 unpickler = _Unpickler_New();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6221 if (unpickler == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6222 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6223
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6224 if (_Unpickler_SetInputStream(unpickler, file) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6225 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6226
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6227 if (_Unpickler_SetInputEncoding(unpickler, encoding, errors) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6228 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6229
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6230 unpickler->fix_imports = PyObject_IsTrue(fix_imports);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6231 if (unpickler->fix_imports == -1)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6232 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6233
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6234 result = load(unpickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6235 Py_DECREF(unpickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6236 return result;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6237
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6238 error:
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6239 Py_XDECREF(unpickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6240 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6241 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6242
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6243 PyDoc_STRVAR(pickle_loads_doc,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6244 "loads(input, *, fix_imports=True, encoding='ASCII', errors='strict') -> object\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6245 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6246 "Read a pickled object hierarchy from a bytes object and return the\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6247 "reconstituted object hierarchy specified therein\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6248 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6249 "The protocol version of the pickle is detected automatically, so no protocol\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6250 "argument is needed. Bytes past the pickled object's representation are\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6251 "ignored.\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6252 "\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6253 "Optional keyword arguments are fix_imports, encoding and errors, which\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6254 "are used to control compatiblity support for pickle stream generated\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6255 "by Python 2.x. If fix_imports is True, pickle will try to map the old\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6256 "Python 2.x names to the new names used in Python 3.x. The encoding and\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6257 "errors tell pickle how to decode 8-bit string instances pickled by Python\n"
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6258 "2.x; these default to 'ASCII' and 'strict', respectively.\n");
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6259
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6260 static PyObject *
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6261 pickle_loads(PyObject *self, PyObject *args, PyObject *kwds)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6262 {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6263 static char *kwlist[] = {"input", "fix_imports", "encoding", "errors", 0};
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6264 PyObject *input;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6265 PyObject *fix_imports = Py_True;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6266 PyObject *result;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6267 char *encoding = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6268 char *errors = NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6269 UnpicklerObject *unpickler;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6270
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6271 /* fix_imports, encoding and errors are a keyword-only argument. */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6272 if (Py_SIZE(args) != 1) {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6273 PyErr_Format(PyExc_TypeError,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6274 "pickle.loads() takes exactly one positional "
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6275 "argument (%zd given)", Py_SIZE(args));
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6276 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6277 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6278
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6279 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oss:loads", kwlist,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6280 &input, &fix_imports, &encoding, &errors))
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6281 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6282
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6283 unpickler = _Unpickler_New();
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6284 if (unpickler == NULL)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6285 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6286
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6287 if (_Unpickler_SetStringInput(unpickler, input) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6288 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6289
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6290 if (_Unpickler_SetInputEncoding(unpickler, encoding, errors) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6291 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6292
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6293 unpickler->fix_imports = PyObject_IsTrue(fix_imports);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6294 if (unpickler->fix_imports == -1)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6295 goto error;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6296
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6297 result = load(unpickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6298 Py_DECREF(unpickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6299 return result;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6300
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6301 error:
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6302 Py_XDECREF(unpickler);
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6303 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6304 }
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6305
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6306
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6307 static struct PyMethodDef pickle_methods[] = {
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6308 {"dump", (PyCFunction)pickle_dump, METH_VARARGS|METH_KEYWORDS,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6309 pickle_dump_doc},
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6310 {"dumps", (PyCFunction)pickle_dumps, METH_VARARGS|METH_KEYWORDS,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6311 pickle_dumps_doc},
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6312 {"load", (PyCFunction)pickle_load, METH_VARARGS|METH_KEYWORDS,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6313 pickle_load_doc},
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6314 {"loads", (PyCFunction)pickle_loads, METH_VARARGS|METH_KEYWORDS,
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6315 pickle_loads_doc},
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6316 {NULL, NULL} /* sentinel */
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6317 };
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6318
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6319 static int
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6320 initmodule(void)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6321 {
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6322 PyObject *copyreg = NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6323 PyObject *compat_pickle = NULL;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6324
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6325 /* XXX: We should ensure that the types of the dictionaries imported are
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6326 exactly PyDict objects. Otherwise, it is possible to crash the pickle
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6327 since we use the PyDict API directly to access these dictionaries. */
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6328
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6329 copyreg = PyImport_ImportModule("copyreg");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6330 if (!copyreg)
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6331 goto error;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6332 dispatch_table = PyObject_GetAttrString(copyreg, "dispatch_table");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6333 if (!dispatch_table)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6334 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6335 extension_registry = \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6336 PyObject_GetAttrString(copyreg, "_extension_registry");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6337 if (!extension_registry)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6338 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6339 inverted_registry = PyObject_GetAttrString(copyreg, "_inverted_registry");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6340 if (!inverted_registry)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6341 goto error;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6342 extension_cache = PyObject_GetAttrString(copyreg, "_extension_cache");
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6343 if (!extension_cache)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6344 goto error;
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6345 Py_CLEAR(copyreg);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6346
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6347 /* Load the 2.x -> 3.x stdlib module mapping tables */
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6348 compat_pickle = PyImport_ImportModule("_compat_pickle");
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6349 if (!compat_pickle)
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6350 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6351 name_mapping_2to3 = PyObject_GetAttrString(compat_pickle, "NAME_MAPPING");
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6352 if (!name_mapping_2to3)
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6353 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6354 if (!PyDict_CheckExact(name_mapping_2to3)) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6355 PyErr_Format(PyExc_RuntimeError,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6356 "_compat_pickle.NAME_MAPPING should be a dict, not %.200s",
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6357 Py_TYPE(name_mapping_2to3)->tp_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6358 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6359 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6360 import_mapping_2to3 = PyObject_GetAttrString(compat_pickle,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6361 "IMPORT_MAPPING");
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6362 if (!import_mapping_2to3)
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6363 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6364 if (!PyDict_CheckExact(import_mapping_2to3)) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6365 PyErr_Format(PyExc_RuntimeError,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6366 "_compat_pickle.IMPORT_MAPPING should be a dict, "
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6367 "not %.200s", Py_TYPE(import_mapping_2to3)->tp_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6368 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6369 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6370 /* ... and the 3.x -> 2.x mapping tables */
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6371 name_mapping_3to2 = PyObject_GetAttrString(compat_pickle,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6372 "REVERSE_NAME_MAPPING");
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6373 if (!name_mapping_3to2)
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6374 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6375 if (!PyDict_CheckExact(name_mapping_3to2)) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6376 PyErr_Format(PyExc_RuntimeError,
68585
bf94b6a73fc8 #11565: Fix several typos. Patch by Piotr Kasprzyk.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 67725
diff changeset
6377 "_compat_pickle.REVERSE_NAME_MAPPING should be a dict, "
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6378 "not %.200s", Py_TYPE(name_mapping_3to2)->tp_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6379 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6380 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6381 import_mapping_3to2 = PyObject_GetAttrString(compat_pickle,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6382 "REVERSE_IMPORT_MAPPING");
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6383 if (!import_mapping_3to2)
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6384 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6385 if (!PyDict_CheckExact(import_mapping_3to2)) {
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6386 PyErr_Format(PyExc_RuntimeError,
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6387 "_compat_pickle.REVERSE_IMPORT_MAPPING should be a dict, "
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6388 "not %.200s", Py_TYPE(import_mapping_3to2)->tp_name);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6389 goto error;
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6390 }
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6391 Py_CLEAR(compat_pickle);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6392
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6393 empty_tuple = PyTuple_New(0);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6394 if (empty_tuple == NULL)
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6395 goto error;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6396 two_tuple = PyTuple_New(2);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6397 if (two_tuple == NULL)
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6398 goto error;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6399 /* We use this temp container with no regard to refcounts, or to
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6400 * keeping containees alive. Exempt from GC, because we don't
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6401 * want anything looking at two_tuple() by magic.
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6402 */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6403 PyObject_GC_UnTrack(two_tuple);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6404
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6405 return 0;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6406
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6407 error:
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6408 Py_CLEAR(copyreg);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6409 Py_CLEAR(dispatch_table);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6410 Py_CLEAR(extension_registry);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6411 Py_CLEAR(inverted_registry);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6412 Py_CLEAR(extension_cache);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6413 Py_CLEAR(compat_pickle);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6414 Py_CLEAR(name_mapping_2to3);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6415 Py_CLEAR(import_mapping_2to3);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6416 Py_CLEAR(name_mapping_3to2);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6417 Py_CLEAR(import_mapping_3to2);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6418 Py_CLEAR(empty_tuple);
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6419 Py_CLEAR(two_tuple);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6420 return -1;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6421 }
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6422
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6423 static struct PyModuleDef _picklemodule = {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6424 PyModuleDef_HEAD_INIT,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6425 "_pickle",
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6426 pickle_module_doc,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6427 -1,
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6428 pickle_methods,
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6429 NULL,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6430 NULL,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6431 NULL,
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6432 NULL
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6433 };
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6434
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6435 PyMODINIT_FUNC
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6436 PyInit__pickle(void)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6437 {
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6438 PyObject *m;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6439
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6440 if (PyType_Ready(&Unpickler_Type) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6441 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6442 if (PyType_Ready(&Pickler_Type) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6443 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6444 if (PyType_Ready(&Pdata_Type) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6445 return NULL;
64588
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6446 if (PyType_Ready(&PicklerMemoProxyType) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6447 return NULL;
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6448 if (PyType_Ready(&UnpicklerMemoProxyType) < 0)
027f81579b4a Issue #9410: Various optimizations to the pickle module, leading to
Antoine Pitrou <solipsis@pitrou.net>
parents: 64440
diff changeset
6449 return NULL;
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6450
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6451 /* Create the module and add the functions. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6452 m = PyModule_Create(&_picklemodule);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6453 if (m == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6454 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6455
71347
1ae0b7b8de0b Issue #11321: Fix a crash with multiple imports of the _pickle module when
Antoine Pitrou <solipsis@pitrou.net>
parents: 68586
diff changeset
6456 Py_INCREF(&Pickler_Type);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6457 if (PyModule_AddObject(m, "Pickler", (PyObject *)&Pickler_Type) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6458 return NULL;
71347
1ae0b7b8de0b Issue #11321: Fix a crash with multiple imports of the _pickle module when
Antoine Pitrou <solipsis@pitrou.net>
parents: 68586
diff changeset
6459 Py_INCREF(&Unpickler_Type);
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6460 if (PyModule_AddObject(m, "Unpickler", (PyObject *)&Unpickler_Type) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6461 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6462
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6463 /* Initialize the exceptions. */
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6464 PickleError = PyErr_NewException("_pickle.PickleError", NULL, NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6465 if (PickleError == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6466 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6467 PicklingError = \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6468 PyErr_NewException("_pickle.PicklingError", PickleError, NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6469 if (PicklingError == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6470 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6471 UnpicklingError = \
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6472 PyErr_NewException("_pickle.UnpicklingError", PickleError, NULL);
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6473 if (UnpicklingError == NULL)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6474 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6475
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6476 if (PyModule_AddObject(m, "PickleError", PickleError) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6477 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6478 if (PyModule_AddObject(m, "PicklingError", PicklingError) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6479 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6480 if (PyModule_AddObject(m, "UnpicklingError", UnpicklingError) < 0)
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6481 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6482
54584
0805ea211122 Issue #6137: The pickle module now translates module names when loading
Antoine Pitrou <solipsis@pitrou.net>
parents: 54355
diff changeset
6483 if (initmodule() < 0)
47645
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6484 return NULL;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6485
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6486 return m;
0ae50aa7d97c Restore _pickle module accelerator module.
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
diff changeset
6487 }