Commits

gstarnberger  committed c80f419

replaced marshal c module with python-based pypy version

  • Participants
  • Parent commits 67e4cc5

Comments (0)

Files changed (12)

        url = "http://github.com/sysfrog/uncompyle",
        packages=['uncompyle'],
        scripts=['scripts/uncompyle'],
-       ext_modules = [Extension('uncompyle/marshal_20',
-                                ['uncompyle/marshal_20.c'],
-                                define_macros=[]),
-                      Extension('uncompyle/marshal_21',
-                                ['uncompyle/marshal_21.c'],
-                                define_macros=[]),
-                      Extension('uncompyle/marshal_22',
-                                ['uncompyle/marshal_22.c'],
-                                define_macros=[]),
-                      Extension('uncompyle/marshal_23',
-                                ['uncompyle/marshal_23.c'],
-                                define_macros=[]),
-                      Extension('uncompyle/marshal_24',
-                                ['uncompyle/marshal_24.c'],
-                                define_macros=[]),
-                      Extension('uncompyle/marshal_25',
-                                ['uncompyle/marshal_25.c'],
-                                define_macros=[]),
-                      Extension('uncompyle/marshal_26',
-                                ['uncompyle/marshal_26.c'],
-                                define_macros=[]),
-                      Extension('uncompyle/marshal_27',
-                                ['uncompyle/marshal_27.c'],
-                                define_macros=[])
-                      ]
       )

File uncompyle/__init__.py

     		(normally a .pyc)
     code_object: code_object from this file
     """
-    import magics, marshal_files
+    import magics, marshal
     fp = open(filename, 'rb')
     magic = fp.read(4)
     try:
         version = magics.versions[magic]
-        marshal = marshal_files.import_(magic=magic)
+        # marshal = marshal_files.import_(magic=magic)
     except KeyError:
         raise ImportError, "Unknown magic number in %s" % filename
     #print version

File uncompyle/marshal.py

+"""Internal Python object serialization
+
+This module contains functions that can read and write Python values in a binary format. The format is specific to Python, but independent of machine architecture issues (e.g., you can write a Python value to a file on a PC, transport the file to a Sun, and read it back there). Details of the format may change between Python versions.
+"""
+
+import types
+from _codecs import utf_8_decode, utf_8_encode
+
+TYPE_NULL     = '0'
+TYPE_NONE     = 'N'
+TYPE_FALSE    = 'F'
+TYPE_TRUE     = 'T'
+TYPE_STOPITER = 'S'
+TYPE_ELLIPSIS = '.'
+TYPE_INT      = 'i'
+TYPE_INT64    = 'I'
+TYPE_FLOAT    = 'f'
+TYPE_COMPLEX  = 'x'
+TYPE_LONG     = 'l'
+TYPE_STRING   = 's'
+TYPE_INTERNED = 't'
+TYPE_STRINGREF= 'R'
+TYPE_TUPLE    = '('
+TYPE_LIST     = '['
+TYPE_DICT     = '{'
+TYPE_CODE     = 'c'
+TYPE_UNICODE  = 'u'
+TYPE_UNKNOWN  = '?'
+TYPE_SET      = '<'
+TYPE_FROZENSET= '>'
+
+class _Marshaller:
+
+    dispatch = {}
+
+    def __init__(self, writefunc):
+        self._write = writefunc
+
+    def dump(self, x):
+        try:
+            self.dispatch[type(x)](self, x)
+        except KeyError:
+            for tp in type(x).mro():
+                func = self.dispatch.get(tp)
+                if func:
+                    break
+            else:
+                raise ValueError, "unmarshallable object"
+            func(self, x)
+
+    def w_long64(self, x):
+        self.w_long(x)
+        self.w_long(x>>32)
+
+    def w_long(self, x):
+        a = chr(x & 0xff)
+        x >>= 8
+        b = chr(x & 0xff)
+        x >>= 8
+        c = chr(x & 0xff)
+        x >>= 8
+        d = chr(x & 0xff)
+        self._write(a + b + c + d)
+
+    def w_short(self, x):
+        self._write(chr((x)     & 0xff))
+        self._write(chr((x>> 8) & 0xff))
+
+    def dump_none(self, x):
+        self._write(TYPE_NONE)
+    dispatch[types.NoneType] = dump_none
+
+    def dump_bool(self, x):
+        if x:
+            self._write(TYPE_TRUE)
+        else:
+            self._write(TYPE_FALSE)
+    dispatch[bool] = dump_bool
+
+    def dump_stopiter(self, x):
+        if x is not StopIteration:
+            raise ValueError, "unmarshallable object"
+        self._write(TYPE_STOPITER)
+    dispatch[type(StopIteration)] = dump_stopiter
+
+    def dump_ellipsis(self, x):
+        self._write(TYPE_ELLIPSIS)
+    
+    try:
+        dispatch[types.EllipsisType] = dump_ellipsis
+    except NameError:
+        pass
+
+    def dump_int(self, x):
+        y = x>>31
+        if y and y != -1:
+            self._write(TYPE_INT64)
+            self.w_long64(x)
+        else:
+            self._write(TYPE_INT)
+            self.w_long(x)
+    dispatch[types.IntType] = dump_int
+
+    def dump_long(self, x):
+        self._write(TYPE_LONG)
+        sign = 1
+        if x < 0:
+            sign = -1
+            x = -x
+        digits = []
+        while x:
+            digits.append(x & 0x7FFF)
+            x = x>>15
+        self.w_long(len(digits) * sign)
+        for d in digits:
+            self.w_short(d)
+    dispatch[types.LongType] = dump_long
+
+    def dump_float(self, x):
+        write = self._write
+        write(TYPE_FLOAT)
+        s = `x`
+        write(chr(len(s)))
+        write(s)
+    dispatch[types.FloatType] = dump_float
+
+    def dump_complex(self, x):
+        write = self._write
+        write(TYPE_COMPLEX)
+        s = `x.real`
+        write(chr(len(s)))
+        write(s)
+        s = `x.imag`
+        write(chr(len(s)))
+        write(s)
+    try:
+        dispatch[types.ComplexType] = dump_complex
+    except NameError:
+        pass
+
+    def dump_string(self, x):
+        # XXX we can't check for interned strings, yet,
+        # so we (for now) never create TYPE_INTERNED or TYPE_STRINGREF
+        self._write(TYPE_STRING)
+        self.w_long(len(x))
+        self._write(x)
+    dispatch[types.StringType] = dump_string
+
+    def dump_unicode(self, x):
+        self._write(TYPE_UNICODE)
+        #s = x.encode('utf8')
+        s, len_s = utf_8_encode(x)
+        self.w_long(len_s)
+        self._write(s)
+    dispatch[types.UnicodeType] = dump_unicode
+
+    def dump_tuple(self, x):
+        self._write(TYPE_TUPLE)
+        self.w_long(len(x))
+        for item in x:
+            self.dump(item)
+    dispatch[types.TupleType] = dump_tuple
+
+    def dump_list(self, x):
+        self._write(TYPE_LIST)
+        self.w_long(len(x))
+        for item in x:
+            self.dump(item)
+    dispatch[types.ListType] = dump_list
+
+    def dump_dict(self, x):
+        self._write(TYPE_DICT)
+        for key, value in x.items():
+            self.dump(key)
+            self.dump(value)
+        self._write(TYPE_NULL)
+    dispatch[types.DictionaryType] = dump_dict
+
+    def dump_code(self, x):
+        self._write(TYPE_CODE)
+        self.w_long(x.co_argcount)
+        self.w_long(x.co_nlocals)
+        self.w_long(x.co_stacksize)
+        self.w_long(x.co_flags)
+        self.dump(x.co_code)
+        self.dump(x.co_consts)
+        self.dump(x.co_names)
+        self.dump(x.co_varnames)
+        self.dump(x.co_freevars)
+        self.dump(x.co_cellvars)
+        self.dump(x.co_filename)
+        self.dump(x.co_name)
+        self.w_long(x.co_firstlineno)
+        self.dump(x.co_lnotab)
+    try:
+        dispatch[types.CodeType] = dump_code
+    except NameError:
+        pass
+
+    def dump_set(self, x):
+        self._write(TYPE_SET)
+        self.w_long(len(x))
+        for each in x:
+            self.dump(each)
+    try:
+        dispatch[set] = dump_set
+    except NameError:
+        pass
+
+    def dump_frozenset(self, x):
+        self._write(TYPE_FROZENSET)
+        self.w_long(len(x))
+        for each in x:
+            self.dump(each)
+    try:
+        dispatch[frozenset] = dump_frozenset
+    except NameError:
+        pass
+
+class _NULL:
+    pass
+
+class _StringBuffer:
+    def __init__(self, value):
+        self.bufstr = value
+        self.bufpos = 0
+
+    def read(self, n):
+        pos = self.bufpos
+        newpos = pos + n
+        ret = self.bufstr[pos : newpos]
+        self.bufpos = newpos
+        return ret
+
+
+class _Unmarshaller:
+
+    dispatch = {}
+
+    def __init__(self, readfunc):
+        self._read = readfunc
+        self._stringtable = []
+
+    def load(self):
+        c = self._read(1)
+        if not c:
+            raise EOFError
+        try:
+            return self.dispatch[c](self)
+        except KeyError:
+            raise ValueError, "bad marshal code: %c (%d)" % (c, ord(c))
+
+    def r_short(self):
+        lo = ord(self._read(1))
+        hi = ord(self._read(1))
+        x = lo | (hi<<8)
+        if x & 0x8000:
+            x = x - 0x10000
+        return x
+
+    def r_long(self):
+        s = self._read(4)
+        a = ord(s[0])
+        b = ord(s[1])
+        c = ord(s[2])
+        d = ord(s[3])
+        x = a | (b<<8) | (c<<16) | (d<<24)
+        if d & 0x80 and x > 0:
+            x = -((1L<<32) - x)
+            return int(x)
+        else:
+            return x
+
+    def r_long64(self):
+        a = ord(self._read(1))
+        b = ord(self._read(1))
+        c = ord(self._read(1))
+        d = ord(self._read(1))
+        e = long(ord(self._read(1)))
+        f = long(ord(self._read(1)))
+        g = long(ord(self._read(1)))
+        h = long(ord(self._read(1)))
+        x = a | (b<<8) | (c<<16) | (d<<24)
+        x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56)
+        if h & 0x80 and x > 0:
+            x = -((1L<<64) - x)
+        return x
+
+    def load_null(self):
+        return _NULL
+    dispatch[TYPE_NULL] = load_null
+
+    def load_none(self):
+        return None
+    dispatch[TYPE_NONE] = load_none
+
+    def load_true(self):
+        return True
+    dispatch[TYPE_TRUE] = load_true
+
+    def load_false(self):
+        return False
+    dispatch[TYPE_FALSE] = load_false
+
+    def load_stopiter(self):
+        return StopIteration
+    dispatch[TYPE_STOPITER] = load_stopiter
+
+    def load_ellipsis(self):
+        return Ellipsis
+    dispatch[TYPE_ELLIPSIS] = load_ellipsis
+
+    dispatch[TYPE_INT] = r_long
+
+    dispatch[TYPE_INT64] = r_long64
+
+    def load_long(self):
+        size = self.r_long()
+        sign = 1
+        if size < 0:
+            sign = -1
+            size = -size
+        x = 0L
+        for i in range(size):
+            d = self.r_short()
+            x = x | (d<<(i*15L))
+        return x * sign
+    dispatch[TYPE_LONG] = load_long
+
+    def load_float(self):
+        n = ord(self._read(1))
+        s = self._read(n)
+        return float(s)
+    dispatch[TYPE_FLOAT] = load_float
+
+    def load_complex(self):
+        n = ord(self._read(1))
+        s = self._read(n)
+        real = float(s)
+        n = ord(self._read(1))
+        s = self._read(n)
+        imag = float(s)
+        return complex(real, imag)
+    dispatch[TYPE_COMPLEX] = load_complex
+
+    def load_string(self):
+        n = self.r_long()
+        return self._read(n)
+    dispatch[TYPE_STRING] = load_string
+
+    def load_interned(self):
+        n = self.r_long()
+        ret = intern(self._read(n))
+        self._stringtable.append(ret)
+        return ret
+    dispatch[TYPE_INTERNED] = load_interned
+
+    def load_stringref(self):
+        n = self.r_long()
+        return self._stringtable[n]
+    dispatch[TYPE_STRINGREF] = load_stringref
+
+    def load_unicode(self):
+        n = self.r_long()
+        s = self._read(n)
+        #ret = s.decode('utf8')
+        ret, len_ret = utf_8_decode(s)
+        return ret
+    dispatch[TYPE_UNICODE] = load_unicode
+
+    def load_tuple(self):
+        return tuple(self.load_list())
+    dispatch[TYPE_TUPLE] = load_tuple
+
+    def load_list(self):
+        n = self.r_long()
+        list = [self.load() for i in range(n)]
+        return list
+    dispatch[TYPE_LIST] = load_list
+
+    def load_dict(self):
+        d = {}
+        while 1:
+            key = self.load()
+            if key is _NULL:
+                break
+            value = self.load()
+            d[key] = value
+        return d
+    dispatch[TYPE_DICT] = load_dict
+
+    def load_code(self):
+        argcount = self.r_long()
+        nlocals = self.r_long()
+        stacksize = self.r_long()
+        flags = self.r_long()
+        code = self.load()
+        consts = self.load()
+        names = self.load()
+        varnames = self.load()
+        freevars = self.load()
+        cellvars = self.load()
+        filename = self.load()
+        name = self.load()
+        firstlineno = self.r_long()
+        lnotab = self.load()
+        return types.CodeType(argcount, nlocals, stacksize, flags, code, consts,
+                              names, varnames, filename, name, firstlineno,
+                              lnotab, freevars, cellvars)
+    dispatch[TYPE_CODE] = load_code
+
+    def load_set(self):
+        n = self.r_long()
+        args = [self.load() for i in range(n)]
+        return set(args)
+    dispatch[TYPE_SET] = load_set
+
+    def load_frozenset(self):
+        n = self.r_long()
+        args = [self.load() for i in range(n)]
+        return frozenset(args)
+    dispatch[TYPE_FROZENSET] = load_frozenset
+
+# ________________________________________________________________
+
+def _read(self, n):
+    pos = self.bufpos
+    newpos = pos + n
+    ret = self.bufstr[pos : newpos]
+    self.bufpos = newpos
+    return ret
+
+def _read1(self):
+    ret = self.bufstr[self.bufpos]
+    self.bufpos += 1
+    return ret
+
+def _r_short(self):
+    lo = ord(_read1(self))
+    hi = ord(_read1(self))
+    x = lo | (hi<<8)
+    if x & 0x8000:
+        x = x - 0x10000
+    return x
+
+def _r_long(self):
+    # inlined this most common case
+    p = self.bufpos
+    s = self.bufstr
+    a = ord(s[p])
+    b = ord(s[p+1])
+    c = ord(s[p+2])
+    d = ord(s[p+3])
+    self.bufpos += 4
+    x = a | (b<<8) | (c<<16) | (d<<24)
+    if d & 0x80 and x > 0:
+        x = -((1L<<32) - x)
+        return int(x)
+    else:
+        return x
+
+def _r_long64(self):
+    a = ord(_read1(self))
+    b = ord(_read1(self))
+    c = ord(_read1(self))
+    d = ord(_read1(self))
+    e = long(ord(_read1(self)))
+    f = long(ord(_read1(self)))
+    g = long(ord(_read1(self)))
+    h = long(ord(_read1(self)))
+    x = a | (b<<8) | (c<<16) | (d<<24)
+    x = x | (e<<32) | (f<<40) | (g<<48) | (h<<56)
+    if h & 0x80 and x > 0:
+        x = -((1L<<64) - x)
+    return x
+
+_load_dispatch = {}
+
+class _FastUnmarshaller:
+
+    dispatch = {}
+
+    def __init__(self, buffer):
+        self.bufstr = buffer
+        self.bufpos = 0
+        self._stringtable = []
+
+    def load(self):
+        # make flow space happy
+        c = '?'
+        try:
+            c = self.bufstr[self.bufpos]
+            self.bufpos += 1
+            return _load_dispatch[c](self)
+        except KeyError:
+            raise ValueError, "bad marshal code: %c (%d)" % (c, ord(c))
+        except IndexError:
+            raise EOFError
+
+    def load_null(self):
+        return _NULL
+    dispatch[TYPE_NULL] = load_null
+
+    def load_none(self):
+        return None
+    dispatch[TYPE_NONE] = load_none
+
+    def load_true(self):
+        return True
+    dispatch[TYPE_TRUE] = load_true
+
+    def load_false(self):
+        return False
+    dispatch[TYPE_FALSE] = load_false
+
+    def load_stopiter(self):
+        return StopIteration
+    dispatch[TYPE_STOPITER] = load_stopiter
+
+    def load_ellipsis(self):
+        return Ellipsis
+    dispatch[TYPE_ELLIPSIS] = load_ellipsis
+
+    def load_int(self):
+        return _r_long(self)
+    dispatch[TYPE_INT] = load_int
+
+    def load_int64(self):
+        return _r_long64(self)
+    dispatch[TYPE_INT64] = load_int64
+
+    def load_long(self):
+        size = _r_long(self)
+        sign = 1
+        if size < 0:
+            sign = -1
+            size = -size
+        x = 0L
+        for i in range(size):
+            d = _r_short(self)
+            x = x | (d<<(i*15L))
+        return x * sign
+    dispatch[TYPE_LONG] = load_long
+
+    def load_float(self):
+        n = ord(_read1(self))
+        s = _read(self, n)
+        return float(s)
+    dispatch[TYPE_FLOAT] = load_float
+
+    def load_complex(self):
+        n = ord(_read1(self))
+        s = _read(self, n)
+        real = float(s)
+        n = ord(_read1(self))
+        s = _read(self, n)
+        imag = float(s)
+        return complex(real, imag)
+    dispatch[TYPE_COMPLEX] = load_complex
+
+    def load_string(self):
+        n = _r_long(self)
+        return _read(self, n)
+    dispatch[TYPE_STRING] = load_string
+
+    def load_interned(self):
+        n = _r_long(self)
+        ret = intern(_read(self, n))
+        self._stringtable.append(ret)
+        return ret
+    dispatch[TYPE_INTERNED] = load_interned
+
+    def load_stringref(self):
+        n = _r_long(self)
+        return self._stringtable[n]
+    dispatch[TYPE_STRINGREF] = load_stringref
+
+    def load_unicode(self):
+        n = _r_long(self)
+        s = _read(self, n)
+        ret = s.decode('utf8')
+        return ret
+    dispatch[TYPE_UNICODE] = load_unicode
+
+    def load_tuple(self):
+        return tuple(self.load_list())
+    dispatch[TYPE_TUPLE] = load_tuple
+
+    def load_list(self):
+        n = _r_long(self)
+        list = []
+        for i in range(n):
+            list.append(self.load())
+        return list
+    dispatch[TYPE_LIST] = load_list
+
+    def load_dict(self):
+        d = {}
+        while 1:
+            key = self.load()
+            if key is _NULL:
+                break
+            value = self.load()
+            d[key] = value
+        return d
+    dispatch[TYPE_DICT] = load_dict
+
+    def load_code(self):
+        argcount = _r_long(self)
+        nlocals = _r_long(self)
+        stacksize = _r_long(self)
+        flags = _r_long(self)
+        code = self.load()
+        consts = self.load()
+        names = self.load()
+        varnames = self.load()
+        freevars = self.load()
+        cellvars = self.load()
+        filename = self.load()
+        name = self.load()
+        firstlineno = _r_long(self)
+        lnotab = self.load()
+        return types.CodeType(argcount, nlocals, stacksize, flags, code, consts,
+                              names, varnames, filename, name, firstlineno,
+                              lnotab, freevars, cellvars)
+    dispatch[TYPE_CODE] = load_code
+
+    def load_set(self):
+        n = _r_long(self)
+        args = [self.load() for i in range(n)]
+        return set(args)
+    dispatch[TYPE_SET] = load_set
+
+    def load_frozenset(self):
+        n = _r_long(self)
+        args = [self.load() for i in range(n)]
+        return frozenset(args)
+    dispatch[TYPE_FROZENSET] = load_frozenset
+
+_load_dispatch = _FastUnmarshaller.dispatch
+
+# _________________________________________________________________
+#
+# user interface
+
+version = 1
+
+def dump(x, f, version=version):
+    # XXX 'version' is ignored, we always dump in a version-0-compatible format
+    m = _Marshaller(f.write)
+    m.dump(x)
+
+def load(f):
+    um = _Unmarshaller(f.read)
+    return um.load()
+
+def dumps(x, version=version):
+    # XXX 'version' is ignored, we always dump in a version-0-compatible format
+    buffer = []
+    m = _Marshaller(buffer.append)
+    m.dump(x)
+    return ''.join(buffer)
+
+def loads(s):
+    um = _FastUnmarshaller(s)
+    return um.load()

File uncompyle/marshal_20.c

-
-
-/* Write Python objects to files and read them back.
-   This is intended for writing and reading compiled Python code only;
-   a true persistent storage facility would be much harder, since
-   it would have to take circular links and sharing into account. */
-
-#include "Python.h"
-#include "longintrepr.h"
-#include "compile.h"
-#include "marshal.h"
-
-/* High water mark to determine when the marshalled object is dangerously deep
- * and risks coring the interpreter.  When the object stack gets this deep,
- * raise an exception instead of continuing.
- */
-#define MAX_MARSHAL_STACK_DEPTH 5000
-
-#define TYPE_NULL	'0'
-#define TYPE_NONE	'N'
-#define TYPE_STOPITER	'S'
-#define TYPE_ELLIPSIS   '.'
-#define TYPE_INT	'i'
-#define TYPE_INT64	'I'
-#define TYPE_FLOAT	'f'
-#define TYPE_COMPLEX	'x'
-#define TYPE_LONG	'l'
-#define TYPE_STRING	's'
-#define TYPE_TUPLE	'('
-#define TYPE_LIST	'['
-#define TYPE_DICT	'{'
-#define TYPE_CODE	'c'
-#define TYPE_UNICODE	'u'
-#define TYPE_UNKNOWN	'?'
-
-typedef struct {
-	FILE *fp;
-	int error;
-	int depth;
-	/* If fp == NULL, the following are valid: */
-	PyObject *str;
-	char *ptr;
-	char *end;
-} WFILE;
-
-#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
-		      else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
-			   else w_more(c, p)
-
-static void
-w_more(int c, WFILE *p)
-{
-	int size, newsize;
-	if (p->str == NULL)
-		return; /* An error already occurred */
-	size = PyString_Size(p->str);
-	newsize = size + 1024;
-	if (_PyString_Resize(&p->str, newsize) != 0) {
-		p->ptr = p->end = NULL;
-	}
-	else {
-		p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
-		p->end =
-			PyString_AS_STRING((PyStringObject *)p->str) + newsize;
-		*p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);
-	}
-}
-
-static void
-w_string(char *s, int n, WFILE *p)
-{
-	if (p->fp != NULL) {
-		fwrite(s, 1, n, p->fp);
-	}
-	else {
-		while (--n >= 0) {
-			w_byte(*s, p);
-			s++;
-		}
-	}
-}
-
-static void
-w_short(int x, WFILE *p)
-{
-	w_byte( x      & 0xff, p);
-	w_byte((x>> 8) & 0xff, p);
-}
-
-static void
-w_long(long x, WFILE *p)
-{
-	w_byte((int)( x      & 0xff), p);
-	w_byte((int)((x>> 8) & 0xff), p);
-	w_byte((int)((x>>16) & 0xff), p);
-	w_byte((int)((x>>24) & 0xff), p);
-}
-
-#if SIZEOF_LONG > 4
-static void
-w_long64(long x, WFILE *p)
-{
-	w_long(x, p);
-	w_long(x>>32, p);
-}
-#endif
-
-static void
-w_object(PyObject *v, WFILE *p)
-{
-	int i, n;
-
-	p->depth++;
-
-	if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
-		p->error = 2;
-	}
-	else if (v == NULL) {
-		w_byte(TYPE_NULL, p);
-	}
-	else if (v == Py_None) {
-		w_byte(TYPE_NONE, p);
-	}
-	else if (v == PyExc_StopIteration) {
-		w_byte(TYPE_STOPITER, p);
-	}
-	else if (v == Py_Ellipsis) {
-	        w_byte(TYPE_ELLIPSIS, p);
-	}
-	else if (PyInt_Check(v)) {
-		long x = PyInt_AS_LONG((PyIntObject *)v);
-#if SIZEOF_LONG > 4
-		long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
-		if (y && y != -1) {
-			w_byte(TYPE_INT64, p);
-			w_long64(x, p);
-		}
-		else
-#endif
-			{
-			w_byte(TYPE_INT, p);
-			w_long(x, p);
-		}
-	}
-	else if (PyLong_Check(v)) {
-		PyLongObject *ob = (PyLongObject *)v;
-		w_byte(TYPE_LONG, p);
-		n = ob->ob_size;
-		w_long((long)n, p);
-		if (n < 0)
-			n = -n;
-		for (i = 0; i < n; i++)
-			w_short(ob->ob_digit[i], p);
-	}
-	else if (PyFloat_Check(v)) {
-		char buf[256]; /* Plenty to format any double */
-		PyFloat_AsReprString(buf, (PyFloatObject *)v);
-		n = strlen(buf);
-		w_byte(TYPE_FLOAT, p);
-		w_byte(n, p);
-		w_string(buf, n, p);
-	}
-#ifndef WITHOUT_COMPLEX
-	else if (PyComplex_Check(v)) {
-		char buf[256]; /* Plenty to format any double */
-		PyFloatObject *temp;
-		w_byte(TYPE_COMPLEX, p);
-		temp = (PyFloatObject*)PyFloat_FromDouble(
-			PyComplex_RealAsDouble(v));
-		PyFloat_AsReprString(buf, temp);
-		Py_DECREF(temp);
-		n = strlen(buf);
-		w_byte(n, p);
-		w_string(buf, n, p);
-		temp = (PyFloatObject*)PyFloat_FromDouble(
-			PyComplex_ImagAsDouble(v));
-		PyFloat_AsReprString(buf, temp);
-		Py_DECREF(temp);
-		n = strlen(buf);
-		w_byte(n, p);
-		w_string(buf, n, p);
-	}
-#endif
-	else if (PyString_Check(v)) {
-		w_byte(TYPE_STRING, p);
-		n = PyString_GET_SIZE(v);
-		w_long((long)n, p);
-		w_string(PyString_AS_STRING(v), n, p);
-	}
-#ifdef Py_USING_UNICODE
-	else if (PyUnicode_Check(v)) {
-	        PyObject *utf8;
-		utf8 = PyUnicode_AsUTF8String(v);
-		if (utf8 == NULL) {
-			p->depth--;
-			p->error = 1;
-			return;
-		}
-		w_byte(TYPE_UNICODE, p);
-		n = PyString_GET_SIZE(utf8);
-		w_long((long)n, p);
-		w_string(PyString_AS_STRING(utf8), n, p);
-		Py_DECREF(utf8);
-	}
-#endif
-	else if (PyTuple_Check(v)) {
-		w_byte(TYPE_TUPLE, p);
-		n = PyTuple_Size(v);
-		w_long((long)n, p);
-		for (i = 0; i < n; i++) {
-			w_object(PyTuple_GET_ITEM(v, i), p);
-		}
-	}
-	else if (PyList_Check(v)) {
-		w_byte(TYPE_LIST, p);
-		n = PyList_GET_SIZE(v);
-		w_long((long)n, p);
-		for (i = 0; i < n; i++) {
-			w_object(PyList_GET_ITEM(v, i), p);
-		}
-	}
-	else if (PyDict_Check(v)) {
-		int pos;
-		PyObject *key, *value;
-		w_byte(TYPE_DICT, p);
-		/* This one is NULL object terminated! */
-		pos = 0;
-		while (PyDict_Next(v, &pos, &key, &value)) {
-			w_object(key, p);
-			w_object(value, p);
-		}
-		w_object((PyObject *)NULL, p);
-	}
-	else if (PyCode_Check(v)) {
-		PyCodeObject *co = (PyCodeObject *)v;
-		w_byte(TYPE_CODE, p);
-		w_short(co->co_argcount, p);
-		w_short(co->co_nlocals, p);
-		w_short(co->co_stacksize, p);
-		w_short(co->co_flags, p);
-		w_object(co->co_code, p);
-		w_object(co->co_consts, p);
-		w_object(co->co_names, p);
-		w_object(co->co_varnames, p);
-		w_object(co->co_freevars, p);
-		w_object(co->co_cellvars, p);
-		w_object(co->co_filename, p);
-		w_object(co->co_name, p);
-		w_short(co->co_firstlineno, p);
-		w_object(co->co_lnotab, p);
-	}
-	else if (PyObject_CheckReadBuffer(v)) {
-		/* Write unknown buffer-style objects as a string */
-		char *s;
-		PyBufferProcs *pb = v->ob_type->tp_as_buffer;
-		w_byte(TYPE_STRING, p);
-		n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
-		w_long((long)n, p);
-		w_string(s, n, p);
-	}
-	else {
-		w_byte(TYPE_UNKNOWN, p);
-		p->error = 1;
-	}
-
-	p->depth--;
-}
-
-void
-PyMarshal_WriteLongToFile(long x, FILE *fp, int wat)
-{
-	WFILE wf;
-	wf.fp = fp;
-	wf.error = 0;
-	wf.depth = 0;
-	w_long(x, &wf);
-}
-
-void
-PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int wat)
-{
-	WFILE wf;
-	wf.fp = fp;
-	wf.error = 0;
-	wf.depth = 0;
-	w_object(x, &wf);
-}
-
-typedef WFILE RFILE; /* Same struct with different invariants */
-
-#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
-
-#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
-
-static int
-r_string(char *s, int n, RFILE *p)
-{
-	if (p->fp != NULL)
-		return fread(s, 1, n, p->fp);
-	if (p->end - p->ptr < n)
-		n = p->end - p->ptr;
-	memcpy(s, p->ptr, n);
-	p->ptr += n;
-	return n;
-}
-
-static int
-r_short(RFILE *p)
-{
-	register short x;
-	x = r_byte(p);
-	x |= r_byte(p) << 8;
-	/* Sign-extension, in case short greater than 16 bits */
-	x |= -(x & 0x8000);
-	return x;
-}
-
-static long
-r_long(RFILE *p)
-{
-	register long x;
-	register FILE *fp = p->fp;
-	if (fp) {
-		x = getc(fp);
-		x |= (long)getc(fp) << 8;
-		x |= (long)getc(fp) << 16;
-		x |= (long)getc(fp) << 24;
-	}
-	else {
-		x = rs_byte(p);
-		x |= (long)rs_byte(p) << 8;
-		x |= (long)rs_byte(p) << 16;
-		x |= (long)rs_byte(p) << 24;
-	}
-#if SIZEOF_LONG > 4
-	/* Sign extension for 64-bit machines */
-	x |= -(x & 0x80000000L);
-#endif
-	return x;
-}
-
-/* r_long64 deals with the TYPE_INT64 code.  On a machine with
-   sizeof(long) > 4, it returns a Python int object, else a Python long
-   object.  Note that w_long64 writes out TYPE_INT if 32 bits is enough,
-   so there's no inefficiency here in returning a PyLong on 32-bit boxes
-   for everything written via TYPE_INT64 (i.e., if an int is written via
-   TYPE_INT64, it *needs* more than 32 bits).
-*/
-static PyObject *
-r_long64(RFILE *p)
-{
-	long lo4 = r_long(p);
-	long hi4 = r_long(p);
-#if SIZEOF_LONG > 4
-	long x = (hi4 << 32) | (lo4 & 0xFFFFFFFFL);
-	return PyInt_FromLong(x);
-#else
-	unsigned char buf[8];
-	int one = 1;
-	int is_little_endian = (int)*(char*)&one;
-	if (is_little_endian) {
-		memcpy(buf, &lo4, 4);
-		memcpy(buf+4, &hi4, 4);
-	}
-	else {
-		memcpy(buf, &hi4, 4);
-		memcpy(buf+4, &lo4, 4);
-	}
-	return _PyLong_FromByteArray(buf, 8, is_little_endian, 1);
-#endif
-}
-
-static PyObject *
-r_object(RFILE *p)
-{
-	PyObject *v, *v2;
-	long i, n;
-	int type = r_byte(p);
-
-	switch (type) {
-
-	case EOF:
-		PyErr_SetString(PyExc_EOFError,
-				"EOF read where object expected");
-		return NULL;
-
-	case TYPE_NULL:
-		return NULL;
-
-	case TYPE_NONE:
-		Py_INCREF(Py_None);
-		return Py_None;
-
-	case TYPE_STOPITER:
-		Py_INCREF(PyExc_StopIteration);
-		return PyExc_StopIteration;
-
-	case TYPE_ELLIPSIS:
-		Py_INCREF(Py_Ellipsis);
-		return Py_Ellipsis;
-
-	case TYPE_INT:
-		return PyInt_FromLong(r_long(p));
-
-	case TYPE_INT64:
-		return r_long64(p);
-
-	case TYPE_LONG:
-		{
-			int size;
-			PyLongObject *ob;
-			n = r_long(p);
-			size = n<0 ? -n : n;
-			ob = _PyLong_New(size);
-			if (ob == NULL)
-				return NULL;
-			ob->ob_size = n;
-			for (i = 0; i < size; i++)
-				ob->ob_digit[i] = r_short(p);
-			return (PyObject *)ob;
-		}
-
-	case TYPE_FLOAT:
-		{
-			char buf[256];
-			double dx;
-			n = r_byte(p);
-			if (r_string(buf, (int)n, p) != n) {
-				PyErr_SetString(PyExc_EOFError,
-					"EOF read where object expected");
-				return NULL;
-			}
-			buf[n] = '\0';
-			PyFPE_START_PROTECT("atof", return 0)
-			dx = atof(buf);
-			PyFPE_END_PROTECT(dx)
-			return PyFloat_FromDouble(dx);
-		}
-
-#ifndef WITHOUT_COMPLEX
-	case TYPE_COMPLEX:
-		{
-			char buf[256];
-			Py_complex c;
-			n = r_byte(p);
-			if (r_string(buf, (int)n, p) != n) {
-				PyErr_SetString(PyExc_EOFError,
-					"EOF read where object expected");
-				return NULL;
-			}
-			buf[n] = '\0';
-			PyFPE_START_PROTECT("atof", return 0)
-			c.real = atof(buf);
-			PyFPE_END_PROTECT(c)
-			n = r_byte(p);
-			if (r_string(buf, (int)n, p) != n) {
-				PyErr_SetString(PyExc_EOFError,
-					"EOF read where object expected");
-				return NULL;
-			}
-			buf[n] = '\0';
-			PyFPE_START_PROTECT("atof", return 0)
-			c.imag = atof(buf);
-			PyFPE_END_PROTECT(c)
-			return PyComplex_FromCComplex(c);
-		}
-#endif
-
-	case TYPE_STRING:
-		n = r_long(p);
-		if (n < 0) {
-			PyErr_SetString(PyExc_ValueError, "bad marshal data");
-			return NULL;
-		}
-		v = PyString_FromStringAndSize((char *)NULL, n);
-		if (v != NULL) {
-			if (r_string(PyString_AS_STRING(v), (int)n, p) != n) {
-				Py_DECREF(v);
-				v = NULL;
-				PyErr_SetString(PyExc_EOFError,
-					"EOF read where object expected");
-			}
-		}
-		return v;
-
-#ifdef Py_USING_UNICODE
-	case TYPE_UNICODE:
-	    {
-		char *buffer;
-
-		n = r_long(p);
-		if (n < 0) {
-			PyErr_SetString(PyExc_ValueError, "bad marshal data");
-			return NULL;
-		}
-		buffer = PyMem_NEW(char, n);
-		if (buffer == NULL)
-			return PyErr_NoMemory();
-		if (r_string(buffer, (int)n, p) != n) {
-			PyMem_DEL(buffer);
-			PyErr_SetString(PyExc_EOFError,
-				"EOF read where object expected");
-			return NULL;
-		}
-		v = PyUnicode_DecodeUTF8(buffer, n, NULL);
-		PyMem_DEL(buffer);
-		return v;
-	    }
-#endif
-
-	case TYPE_TUPLE:
-		n = r_long(p);
-		if (n < 0) {
-			PyErr_SetString(PyExc_ValueError, "bad marshal data");
-			return NULL;
-		}
-		v = PyTuple_New((int)n);
-		if (v == NULL)
-			return v;
-		for (i = 0; i < n; i++) {
-			v2 = r_object(p);
-			if ( v2 == NULL ) {
-				Py_DECREF(v);
-				v = NULL;
-				break;
-			}
-			PyTuple_SET_ITEM(v, (int)i, v2);
-		}
-		return v;
-
-	case TYPE_LIST:
-		n = r_long(p);
-		if (n < 0) {
-			PyErr_SetString(PyExc_ValueError, "bad marshal data");
-			return NULL;
-		}
-		v = PyList_New((int)n);
-		if (v == NULL)
-			return v;
-		for (i = 0; i < n; i++) {
-			v2 = r_object(p);
-			if ( v2 == NULL ) {
-				Py_DECREF(v);
-				v = NULL;
-				break;
-			}
-			PyList_SetItem(v, (int)i, v2);
-		}
-		return v;
-
-	case TYPE_DICT:
-		v = PyDict_New();
-		if (v == NULL)
-			return NULL;
-		for (;;) {
-			PyObject *key, *val;
-			key = r_object(p);
-			if (key == NULL)
-				break; /* XXX Assume TYPE_NULL, not an error */
-			val = r_object(p);
-			if (val != NULL)
-				PyDict_SetItem(v, key, val);
-			Py_DECREF(key);
-			Py_XDECREF(val);
-		}
-		return v;
-
-	case TYPE_CODE:
-		if (PyEval_GetRestricted()) {
-			PyErr_SetString(PyExc_RuntimeError,
-				"cannot unmarshal code objects in "
-				"restricted execution mode");
-			return NULL;
-		}
-		else {
-			int argcount = r_short(p);
-			int nlocals = r_short(p);
-			int stacksize = r_short(p);
-			int flags = r_short(p);
-			PyObject *code = NULL;
-			PyObject *consts = NULL;
-			PyObject *names = NULL;
-			PyObject *varnames = NULL;
-			PyObject *freevars = NULL;
-			PyObject *cellvars = NULL;
-			PyObject *filename = NULL;
-			PyObject *name = NULL;
-			int firstlineno = 0;
-			PyObject *lnotab = NULL;
-
-			code = r_object(p);
-			if (code) consts = r_object(p);
-			if (consts) names = r_object(p);
-			if (names) varnames = r_object(p);
-			if (varnames) freevars = PyTuple_New(0);
-			if (freevars) cellvars = PyTuple_New(0);
-			if (cellvars) filename = r_object(p);
-			if (filename) name = r_object(p);
-			if (name) {
-				firstlineno = r_short(p);
-				lnotab = r_object(p);
-			}
-
-			if (!PyErr_Occurred()) {
-				v = (PyObject *) PyCode_New(
-					argcount, nlocals, stacksize, flags,
-					code, consts, names, varnames,
-					freevars, cellvars, filename, name,
-					firstlineno, lnotab);
-			}
-			else
-				v = NULL;
-			Py_XDECREF(code);
-			Py_XDECREF(consts);
-			Py_XDECREF(names);
-			Py_XDECREF(varnames);
-			Py_XDECREF(freevars);
-			Py_XDECREF(cellvars);
-			Py_XDECREF(filename);
-			Py_XDECREF(name);
-			Py_XDECREF(lnotab);
-
-		}
-		return v;
-
-	default:
-		/* Bogus data got written, which isn't ideal.
-		   This will let you keep working and recover. */
-		PyErr_SetString(PyExc_ValueError, "bad marshal data");
-		return NULL;
-
-	}
-}
-
-int
-PyMarshal_ReadShortFromFile(FILE *fp)
-{
-	RFILE rf;
-	rf.fp = fp;
-	return r_short(&rf);
-}
-
-long
-PyMarshal_ReadLongFromFile(FILE *fp)
-{
-	RFILE rf;
-	rf.fp = fp;
-	return r_long(&rf);
-}
-
-#ifdef HAVE_FSTAT
-/* Return size of file in bytes; < 0 if unknown. */
-static off_t
-getfilesize(FILE *fp)
-{
-	struct stat st;
-	if (fstat(fileno(fp), &st) != 0)
-		return -1;
-	else
-		return st.st_size;
-}
-#endif
-
-/* If we can get the size of the file up-front, and it's reasonably small,
- * read it in one gulp and delegate to ...FromString() instead.  Much quicker
- * than reading a byte at a time from file; speeds .pyc imports.
- * CAUTION:  since this may read the entire remainder of the file, don't
- * call it unless you know you're done with the file.
- */
-PyObject *
-PyMarshal_ReadLastObjectFromFile(FILE *fp)
-{
-/* 75% of 2.1's .pyc files can exploit SMALL_FILE_LIMIT.
- * REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc.
- */
-#define SMALL_FILE_LIMIT (1L << 14)
-#define REASONABLE_FILE_LIMIT (1L << 18)
-#ifdef HAVE_FSTAT
-	off_t filesize;
-#endif
-	if (PyErr_Occurred()) {
-		fprintf(stderr, "XXX rd_object called with exception set\n");
-		return NULL;
-	}
-#ifdef HAVE_FSTAT
-	filesize = getfilesize(fp);
-	if (filesize > 0) {
-		char buf[SMALL_FILE_LIMIT];
-		char* pBuf = NULL;
-		if (filesize <= SMALL_FILE_LIMIT)
-			pBuf = buf;
-		else if (filesize <= REASONABLE_FILE_LIMIT)
-			pBuf = (char *)PyMem_MALLOC(filesize);
-		if (pBuf != NULL) {
-			PyObject* v;
-			size_t n = fread(pBuf, 1, filesize, fp);
-			v = PyMarshal_ReadObjectFromString(pBuf, n);
-			if (pBuf != buf)
-				PyMem_FREE(pBuf);
-			return v;
-		}
-
-	}
-#endif
-	/* We don't have fstat, or we do but the file is larger than
-	 * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
-	 */
-	return PyMarshal_ReadObjectFromFile(fp);
-
-#undef SMALL_FILE_LIMIT
-#undef REASONABLE_FILE_LIMIT
-}
-
-PyObject *
-PyMarshal_ReadObjectFromFile(FILE *fp)
-{
-	RFILE rf;
-	if (PyErr_Occurred()) {
-		fprintf(stderr, "XXX rd_object called with exception set\n");
-		return NULL;
-	}
-	rf.fp = fp;
-	return r_object(&rf);
-}
-
-PyObject *
-PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
-{
-	RFILE rf;
-	if (PyErr_Occurred()) {
-		fprintf(stderr, "XXX rds_object called with exception set\n");
-		return NULL;
-	}
-	rf.fp = NULL;
-	rf.str = NULL;
-	rf.ptr = str;
-	rf.end = str + len;
-	return r_object(&rf);
-}
-
-PyObject *
-PyMarshal_WriteObjectToString(PyObject *x, int wat) /* wrs_object() */
-{
-	WFILE wf;
-	wf.fp = NULL;
-	wf.str = PyString_FromStringAndSize((char *)NULL, 50);
-	if (wf.str == NULL)
-		return NULL;
-	wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
-	wf.end = wf.ptr + PyString_Size(wf.str);
-	wf.error = 0;
-	wf.depth = 0;
-	w_object(x, &wf);
-	if (wf.str != NULL)
-		_PyString_Resize(&wf.str,
-		    (int) (wf.ptr -
-			   PyString_AS_STRING((PyStringObject *)wf.str)));
-	if (wf.error) {
-		Py_XDECREF(wf.str);
-		PyErr_SetString(PyExc_ValueError,
-				(wf.error==1)?"unmarshallable object"
-				:"object too deeply nested to marshal");
-		return NULL;
-	}
-	return wf.str;
-}
-
-/* And an interface for Python programs... */
-
-static PyObject *
-marshal_dump(PyObject *self, PyObject *args)
-{
-	WFILE wf;
-	PyObject *x;
-	PyObject *f;
-	if (!PyArg_ParseTuple(args, "OO:dump", &x, &f))
-		return NULL;
-	if (!PyFile_Check(f)) {
-		PyErr_SetString(PyExc_TypeError,
-				"marshal.dump() 2nd arg must be file");
-		return NULL;
-	}
-	wf.fp = PyFile_AsFile(f);
-	wf.str = NULL;
-	wf.ptr = wf.end = NULL;
-	wf.error = 0;
-	wf.depth = 0;
-	w_object(x, &wf);
-	if (wf.error) {
-		PyErr_SetString(PyExc_ValueError,
-				(wf.error==1)?"unmarshallable object"
-				:"object too deeply nested to marshal");
-		return NULL;
-	}
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
-static PyObject *
-marshal_load(PyObject *self, PyObject *args)
-{
-	RFILE rf;
-	PyObject *f;
-	PyObject *v;
-	if (!PyArg_ParseTuple(args, "O:load", &f))
-		return NULL;
-	if (!PyFile_Check(f)) {
-		PyErr_SetString(PyExc_TypeError,
-				"marshal.load() arg must be file");
-		return NULL;
-	}
-	rf.fp = PyFile_AsFile(f);
-	rf.str = NULL;
-	rf.ptr = rf.end = NULL;
-	PyErr_Clear();
-	v = r_object(&rf);
-	if (PyErr_Occurred()) {
-		Py_XDECREF(v);
-		v = NULL;
-	}
-	return v;
-}
-
-static PyObject *
-marshal_dumps(PyObject *self, PyObject *args)
-{
-	PyObject *x;
-	if (!PyArg_ParseTuple(args, "O:dumps", &x))
-		return NULL;
-	return PyMarshal_WriteObjectToString(x, 0);
-}
-
-static PyObject *
-marshal_loads(PyObject *self, PyObject *args)
-{
-	RFILE rf;
-	PyObject *v;
-	char *s;
-	int n;
-	if (!PyArg_ParseTuple(args, "s#:loads", &s, &n))
-		return NULL;
-	rf.fp = NULL;
-	rf.str = args;
-	rf.ptr = s;
-	rf.end = s + n;
-	PyErr_Clear();
-	v = r_object(&rf);
-	if (PyErr_Occurred()) {
-		Py_XDECREF(v);
-		v = NULL;
-	}
-	return v;
-}
-
-static PyMethodDef marshal_methods[] = {
-	{"dump",	marshal_dump,	1},
-	{"load",	marshal_load,	1},
-	{"dumps",	marshal_dumps,	1},
-	{"loads",	marshal_loads,	1},
-	{NULL,		NULL}		/* sentinel */
-};
-
-void
-initmarshal_20 (void)
-{
-  (void) Py_InitModule("marshal_20" , marshal_methods);
-}
-

File uncompyle/marshal_21.c

-
-/* Write Python objects to files and read them back.
-   This is intended for writing and reading compiled Python code only;
-   a true persistent storage facility would be much harder, since
-   it would have to take circular links and sharing into account. */
-
-#include "Python.h"
-#include "longintrepr.h"
-#include "compile.h"
-#include "marshal.h"
-
-/* High water mark to determine when the marshalled object is dangerously deep
- * and risks coring the interpreter.  When the object stack gets this deep,
- * raise an exception instead of continuing.
- */
-#define MAX_MARSHAL_STACK_DEPTH 5000
-
-#define TYPE_NULL	'0'
-#define TYPE_NONE	'N'
-#define TYPE_ELLIPSIS   '.'
-#define TYPE_INT	'i'
-#define TYPE_INT64	'I'
-#define TYPE_FLOAT	'f'
-#define TYPE_COMPLEX	'x'
-#define TYPE_LONG	'l'
-#define TYPE_STRING	's'
-#define TYPE_TUPLE	'('
-#define TYPE_LIST	'['
-#define TYPE_DICT	'{'
-#define TYPE_CODE	'c'
-#define TYPE_UNICODE	'u'
-#define TYPE_UNKNOWN	'?'
-
-typedef struct {
-	FILE *fp;
-	int error;
-	int depth;
-	/* If fp == NULL, the following are valid: */
-	PyObject *str;
-	char *ptr;
-	char *end;
-} WFILE;
-
-#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
-		      else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
-			   else w_more(c, p)
-
-static void
-w_more(int c, WFILE *p)
-{
-	int size, newsize;
-	if (p->str == NULL)
-		return; /* An error already occurred */
-	size = PyString_Size(p->str);
-	newsize = size + 1024;
-	if (_PyString_Resize(&p->str, newsize) != 0) {
-		p->ptr = p->end = NULL;
-	}
-	else {
-		p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
-		p->end =
-			PyString_AS_STRING((PyStringObject *)p->str) + newsize;
-		*p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);
-	}
-}
-
-static void
-w_string(char *s, int n, WFILE *p)
-{
-	if (p->fp != NULL) {
-		fwrite(s, 1, n, p->fp);
-	}
-	else {
-		while (--n >= 0) {
-			w_byte(*s, p);
-			s++;
-		}
-	}
-}
-
-static void
-w_short(int x, WFILE *p)
-{
-	w_byte( x      & 0xff, p);
-	w_byte((x>> 8) & 0xff, p);
-}
-
-static void
-w_long(long x, WFILE *p)
-{
-	w_byte((int)( x      & 0xff), p);
-	w_byte((int)((x>> 8) & 0xff), p);
-	w_byte((int)((x>>16) & 0xff), p);
-	w_byte((int)((x>>24) & 0xff), p);
-}
-
-#if SIZEOF_LONG > 4
-static void
-w_long64(long x, WFILE *p)
-{
-	w_long(x, p);
-	w_long(x>>32, p);
-}
-#endif
-
-static void
-w_object(PyObject *v, WFILE *p)
-{
-	int i, n;
-	PyBufferProcs *pb;
-
-	p->depth++;
-
-	if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
-		p->error = 2;
-	}
-	else if (v == NULL) {
-		w_byte(TYPE_NULL, p);
-	}
-	else if (v == Py_None) {
-		w_byte(TYPE_NONE, p);
-	}
-	else if (v == Py_Ellipsis) {
-	        w_byte(TYPE_ELLIPSIS, p);
-	}
-	else if (PyInt_Check(v)) {
-		long x = PyInt_AS_LONG((PyIntObject *)v);
-#if SIZEOF_LONG > 4
-		long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
-		if (y && y != -1) {
-			w_byte(TYPE_INT64, p);
-			w_long64(x, p);
-		}
-		else
-#endif
-			{
-			w_byte(TYPE_INT, p);
-			w_long(x, p);
-		}
-	}
-	else if (PyLong_Check(v)) {
-		PyLongObject *ob = (PyLongObject *)v;
-		w_byte(TYPE_LONG, p);
-		n = ob->ob_size;
-		w_long((long)n, p);
-		if (n < 0)
-			n = -n;
-		for (i = 0; i < n; i++)
-			w_short(ob->ob_digit[i], p);
-	}
-	else if (PyFloat_Check(v)) {
-		extern void PyFloat_AsString(char *, PyFloatObject *);
-		char buf[256]; /* Plenty to format any double */
-		PyFloat_AsString(buf, (PyFloatObject *)v);
-		n = strlen(buf);
-		w_byte(TYPE_FLOAT, p);
-		w_byte(n, p);
-		w_string(buf, n, p);
-	}
-#ifndef WITHOUT_COMPLEX
-	else if (PyComplex_Check(v)) {
-		extern void PyFloat_AsString(char *, PyFloatObject *);
-		char buf[256]; /* Plenty to format any double */
-		PyFloatObject *temp;
-		w_byte(TYPE_COMPLEX, p);
-		temp = (PyFloatObject*)PyFloat_FromDouble(
-			PyComplex_RealAsDouble(v));
-		PyFloat_AsString(buf, temp);
-		Py_DECREF(temp);
-		n = strlen(buf);
-		w_byte(n, p);
-		w_string(buf, n, p);
-		temp = (PyFloatObject*)PyFloat_FromDouble(
-			PyComplex_ImagAsDouble(v));
-		PyFloat_AsString(buf, temp);
-		Py_DECREF(temp);
-		n = strlen(buf);
-		w_byte(n, p);
-		w_string(buf, n, p);
-	}
-#endif
-	else if (PyString_Check(v)) {
-		w_byte(TYPE_STRING, p);
-		n = PyString_GET_SIZE(v);
-		w_long((long)n, p);
-		w_string(PyString_AS_STRING(v), n, p);
-	}
-	else if (PyUnicode_Check(v)) {
-	        PyObject *utf8;
-		utf8 = PyUnicode_AsUTF8String(v);
-		if (utf8 == NULL) {
-			p->depth--;
-			p->error = 1;
-			return;
-		}
-		w_byte(TYPE_UNICODE, p);
-		n = PyString_GET_SIZE(utf8);
-		w_long((long)n, p);
-		w_string(PyString_AS_STRING(utf8), n, p);
-		Py_DECREF(utf8);
-	}
-	else if (PyTuple_Check(v)) {
-		w_byte(TYPE_TUPLE, p);
-		n = PyTuple_Size(v);
-		w_long((long)n, p);
-		for (i = 0; i < n; i++) {
-			w_object(PyTuple_GET_ITEM(v, i), p);
-		}
-	}
-	else if (PyList_Check(v)) {
-		w_byte(TYPE_LIST, p);
-		n = PyList_GET_SIZE(v);
-		w_long((long)n, p);
-		for (i = 0; i < n; i++) {
-			w_object(PyList_GET_ITEM(v, i), p);
-		}
-	}
-	else if (PyDict_Check(v)) {
-		int pos;
-		PyObject *key, *value;
-		w_byte(TYPE_DICT, p);
-		/* This one is NULL object terminated! */
-		pos = 0;
-		while (PyDict_Next(v, &pos, &key, &value)) {
-			w_object(key, p);
-			w_object(value, p);
-		}
-		w_object((PyObject *)NULL, p);
-	}
-	else if (PyCode_Check(v)) {
-		PyCodeObject *co = (PyCodeObject *)v;
-		w_byte(TYPE_CODE, p);
-		w_short(co->co_argcount, p);
-		w_short(co->co_nlocals, p);
-		w_short(co->co_stacksize, p);
-		w_short(co->co_flags, p);
-		w_object(co->co_code, p);
-		w_object(co->co_consts, p);
-		w_object(co->co_names, p);
-		w_object(co->co_varnames, p);
-		w_object(co->co_freevars, p);
-		w_object(co->co_cellvars, p);
-		w_object(co->co_filename, p);
-		w_object(co->co_name, p);
-		w_short(co->co_firstlineno, p);
-		w_object(co->co_lnotab, p);
-	}
-	else if ((pb = v->ob_type->tp_as_buffer) != NULL &&
-		 pb->bf_getsegcount != NULL &&
-		 pb->bf_getreadbuffer != NULL &&
-		 (*pb->bf_getsegcount)(v, NULL) == 1)
-	{
-		/* Write unknown buffer-style objects as a string */
-		char *s;
-		w_byte(TYPE_STRING, p);
-		n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
-		w_long((long)n, p);
-		w_string(s, n, p);
-	}
-	else {
-		w_byte(TYPE_UNKNOWN, p);
-		p->error = 1;
-	}
-
-	p->depth--;
-}
-
-void
-PyMarshal_WriteLongToFile(long x, FILE *fp, int wat)
-{
-	WFILE wf;
-	wf.fp = fp;
-	wf.error = 0;
-	wf.depth = 0;
-	w_long(x, &wf);
-}
-
-void
-PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int wat)
-{
-	WFILE wf;
-	wf.fp = fp;
-	wf.error = 0;
-	wf.depth = 0;
-	w_object(x, &wf);
-}
-
-typedef WFILE RFILE; /* Same struct with different invariants */
-
-#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
-
-#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
-
-static int
-r_string(char *s, int n, RFILE *p)
-{
-	if (p->fp != NULL)
-		return fread(s, 1, n, p->fp);
-	if (p->end - p->ptr < n)
-		n = p->end - p->ptr;
-	memcpy(s, p->ptr, n);
-	p->ptr += n;
-	return n;
-}
-
-static int
-r_short(RFILE *p)
-{
-	register short x;
-	x = r_byte(p);
-	x |= r_byte(p) << 8;
-	/* Sign-extension, in case short greater than 16 bits */
-	x |= -(x & 0x8000);
-	return x;
-}
-
-static long
-r_long(RFILE *p)
-{
-	register long x;
-	register FILE *fp = p->fp;
-	if (fp) {
-		x = getc(fp);
-		x |= (long)getc(fp) << 8;
-		x |= (long)getc(fp) << 16;
-		x |= (long)getc(fp) << 24;
-	}
-	else {
-		x = rs_byte(p);
-		x |= (long)rs_byte(p) << 8;
-		x |= (long)rs_byte(p) << 16;
-		x |= (long)rs_byte(p) << 24;
-	}
-#if SIZEOF_LONG > 4
-	/* Sign extension for 64-bit machines */
-	x |= -(x & 0x80000000L);
-#endif
-	return x;
-}
-
-static long
-r_long64(RFILE *p)
-{
-	register long x;
-	x = r_long(p);
-#if SIZEOF_LONG > 4
-	x = (x & 0xFFFFFFFFL) | (r_long(p) << 32);
-#else
-	if (r_long(p) != 0) {
-		PyObject *f = PySys_GetObject("stderr");
-		if (f != NULL)
-			(void) PyFile_WriteString(
-			    "Warning: un-marshal 64-bit int in 32-bit mode\n",
-			    f);
-	}
-#endif
-	return x;
-}
-
-static PyObject *
-r_object(RFILE *p)
-{
-	PyObject *v, *v2;
-	long i, n;
-	int type = r_byte(p);
-
-	switch (type) {
-
-	case EOF:
-		PyErr_SetString(PyExc_EOFError,
-				"EOF read where object expected");
-		return NULL;
-
-	case TYPE_NULL:
-		return NULL;
-
-	case TYPE_NONE:
-		Py_INCREF(Py_None);
-		return Py_None;
-
-	case TYPE_ELLIPSIS:
-		Py_INCREF(Py_Ellipsis);
-		return Py_Ellipsis;
-
-	case TYPE_INT:
-		return PyInt_FromLong(r_long(p));
-
-	case TYPE_INT64:
-		return PyInt_FromLong(r_long64(p));
-
-	case TYPE_LONG:
-		{
-			int size;
-			PyLongObject *ob;
-			n = r_long(p);
-			size = n<0 ? -n : n;
-			ob = _PyLong_New(size);
-			if (ob == NULL)
-				return NULL;
-			ob->ob_size = n;
-			for (i = 0; i < size; i++)
-				ob->ob_digit[i] = r_short(p);
-			return (PyObject *)ob;
-		}
-
-	case TYPE_FLOAT:
-		{
-			char buf[256];
-			double dx;
-			n = r_byte(p);
-			if (r_string(buf, (int)n, p) != n) {
-				PyErr_SetString(PyExc_EOFError,
-					"EOF read where object expected");
-				return NULL;
-			}
-			buf[n] = '\0';
-			PyFPE_START_PROTECT("atof", return 0)
-			dx = atof(buf);
-			PyFPE_END_PROTECT(dx)
-			return PyFloat_FromDouble(dx);
-		}
-
-#ifndef WITHOUT_COMPLEX
-	case TYPE_COMPLEX:
-		{
-			char buf[256];
-			Py_complex c;
-			n = r_byte(p);
-			if (r_string(buf, (int)n, p) != n) {
-				PyErr_SetString(PyExc_EOFError,
-					"EOF read where object expected");
-				return NULL;
-			}
-			buf[n] = '\0';
-			PyFPE_START_PROTECT("atof", return 0)
-			c.real = atof(buf);
-			PyFPE_END_PROTECT(c)
-			n = r_byte(p);
-			if (r_string(buf, (int)n, p) != n) {
-				PyErr_SetString(PyExc_EOFError,
-					"EOF read where object expected");
-				return NULL;
-			}
-			buf[n] = '\0';
-			PyFPE_START_PROTECT("atof", return 0)
-			c.imag = atof(buf);
-			PyFPE_END_PROTECT(c)
-			return PyComplex_FromCComplex(c);
-		}
-#endif
-
-	case TYPE_STRING:
-		n = r_long(p);
-		if (n < 0) {
-			PyErr_SetString(PyExc_ValueError, "bad marshal data");
-			return NULL;
-		}
-		v = PyString_FromStringAndSize((char *)NULL, n);
-		if (v != NULL) {
-			if (r_string(PyString_AS_STRING(v), (int)n, p) != n) {
-				Py_DECREF(v);
-				v = NULL;
-				PyErr_SetString(PyExc_EOFError,
-					"EOF read where object expected");
-			}
-		}
-		return v;
-
-	case TYPE_UNICODE:
-	    {
-		char *buffer;
-
-		n = r_long(p);
-		if (n < 0) {
-			PyErr_SetString(PyExc_ValueError, "bad marshal data");
-			return NULL;
-		}
-		buffer = PyMem_NEW(char, n);
-		if (buffer == NULL)
-			return PyErr_NoMemory();
-		if (r_string(buffer, (int)n, p) != n) {
-			PyMem_DEL(buffer);
-			PyErr_SetString(PyExc_EOFError,
-				"EOF read where object expected");
-			return NULL;
-		}
-		v = PyUnicode_DecodeUTF8(buffer, n, NULL);
-		PyMem_DEL(buffer);
-		return v;
-	    }
-
-	case TYPE_TUPLE:
-		n = r_long(p);
-		if (n < 0) {
-			PyErr_SetString(PyExc_ValueError, "bad marshal data");
-			return NULL;
-		}
-		v = PyTuple_New((int)n);
-		if (v == NULL)
-			return v;
-		for (i = 0; i < n; i++) {
-			v2 = r_object(p);
-			if ( v2 == NULL ) {
-				Py_DECREF(v);
-				v = NULL;
-				break;
-			}
-			PyTuple_SET_ITEM(v, (int)i, v2);
-		}
-		return v;
-
-	case TYPE_LIST:
-		n = r_long(p);
-		if (n < 0) {
-			PyErr_SetString(PyExc_ValueError, "bad marshal data");
-			return NULL;
-		}
-		v = PyList_New((int)n);
-		if (v == NULL)
-			return v;
-		for (i = 0; i < n; i++) {
-			v2 = r_object(p);
-			if ( v2 == NULL ) {
-				Py_DECREF(v);
-				v = NULL;
-				break;
-			}
-			PyList_SetItem(v, (int)i, v2);
-		}
-		return v;
-
-	case TYPE_DICT:
-		v = PyDict_New();
-		if (v == NULL)
-			return NULL;
-		for (;;) {
-			PyObject *key, *val;
-			key = r_object(p);
-			if (key == NULL)
-				break; /* XXX Assume TYPE_NULL, not an error */
-			val = r_object(p);
-			if (val != NULL)
-				PyDict_SetItem(v, key, val);
-			Py_DECREF(key);
-			Py_XDECREF(val);
-		}
-		return v;
-
-	case TYPE_CODE:
-		{
-			int argcount = r_short(p);
-			int nlocals = r_short(p);
-			int stacksize = r_short(p);
-			int flags = r_short(p);
-			PyObject *code = NULL;
-			PyObject *consts = NULL;
-			PyObject *names = NULL;
-			PyObject *varnames = NULL;
-			PyObject *freevars = NULL;
-			PyObject *cellvars = NULL;
-			PyObject *filename = NULL;
-			PyObject *name = NULL;
-			int firstlineno = 0;
-			PyObject *lnotab = NULL;
-
-			code = r_object(p);
-			if (code) consts = r_object(p);
-			if (consts) names = r_object(p);
-			if (names) varnames = r_object(p);
-			if (varnames) freevars = r_object(p);
-			if (freevars) cellvars = r_object(p);
-			if (cellvars) filename = r_object(p);
-			if (filename) name = r_object(p);
-			if (name) {
-				firstlineno = r_short(p);
-				lnotab = r_object(p);
-			}
-
-			if (!PyErr_Occurred()) {
-				v = (PyObject *) PyCode_New(
-					argcount, nlocals, stacksize, flags,
-					code, consts, names, varnames,
-					freevars, cellvars, filename, name,
-					firstlineno, lnotab);
-			}
-			else
-				v = NULL;
-			Py_XDECREF(code);
-			Py_XDECREF(consts);
-			Py_XDECREF(names);
-			Py_XDECREF(varnames);
-			Py_XDECREF(freevars);
-			Py_XDECREF(cellvars);
-			Py_XDECREF(filename);
-			Py_XDECREF(name);
-			Py_XDECREF(lnotab);
-
-		}
-		return v;
-
-	default:
-		/* Bogus data got written, which isn't ideal.