]> granicus.if.org Git - python/commitdiff
Changes to support other object types besides strings
authorGuido van Rossum <guido@python.org>
Wed, 7 Oct 1998 19:42:25 +0000 (19:42 +0000)
committerGuido van Rossum <guido@python.org>
Wed, 7 Oct 1998 19:42:25 +0000 (19:42 +0000)
as the code string of code objects, as long as they support
the (readonly) buffer interface.  By Greg Stein.

Include/compile.h
Modules/newmodule.c
Python/ceval.c
Python/compile.c
Python/marshal.c

index 6c8a62d1707f5433305f675655ed6c3bdc5623cd..b73561735739bcb30011acee27fcdc98c26d38a8 100644 (file)
@@ -44,7 +44,7 @@ typedef struct {
        int co_nlocals;         /* #local variables */
        int co_stacksize;       /* #entries needed for evaluation stack */
        int co_flags;           /* CO_..., see below */
-       PyStringObject *co_code; /* instruction opcodes */
+       PyObject *co_code;      /* instruction opcodes */
        PyObject *co_consts;    /* list (constants used) */
        PyObject *co_names;     /* list of strings (names used) */
        PyObject *co_varnames;  /* tuple of strings (local variable names) */
@@ -75,6 +75,11 @@ PyCodeObject *PyCode_New Py_PROTO((
        PyObject *, PyObject *, int, PyObject *)); /* same as struct above */
 int PyCode_Addr2Line Py_PROTO((PyCodeObject *, int));
 
+/* for internal use only */
+#define _PyCode_GETCODEPTR(co, pp) \
+       ((*(co)->co_code->ob_type->tp_as_buffer->bf_getreadbuffer) \
+        ((co)->co_code, 0, (void **)(pp)))
+
 #ifdef __cplusplus
 }
 #endif
index 52328a967d0c12b51476e4451c7ddf530e2fc032..5c92e0eda4fdc02bb535c524a776ee0db4f9b612 100644 (file)
@@ -150,8 +150,9 @@ new_code(unused, args)
        PyObject* name;
        int firstlineno;
        PyObject* lnotab;
-  
-       if (!PyArg_ParseTuple(args, "iiiiSO!O!O!SSiS",
+       PyBufferProcs *pb;
+
+       if (!PyArg_ParseTuple(args, "iiiiOO!O!O!SSiS",
                              &argcount, &nlocals, &stacksize, &flags,
                              &code,
                              &PyTuple_Type, &consts,
@@ -160,6 +161,18 @@ new_code(unused, args)
                              &filename, &name,
                              &firstlineno, &lnotab))
                return NULL;
+
+       pb = code->ob_type->tp_as_buffer;
+       if (pb == NULL ||
+           pb->bf_getreadbuffer == NULL ||
+           pb->bf_getsegcount == NULL ||
+           (*pb->bf_getsegcount)(code, NULL) != 1)
+       {
+               PyErr_SetString(PyExc_TypeError,
+                 "bytecode object must be a single-segment read-only buffer");
+               return NULL;
+       }
+
        return (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags,
                                      code, consts, names, varnames,
                                      filename, name, firstlineno, lnotab);
index b004c79640f61a8288d3f926f746d804e020174b..413b316dfd6c330f7e03918fb7d84c1e04b99b1c 100644 (file)
@@ -366,6 +366,7 @@ eval_code2(co, globals, locals,
        register PyObject **fastlocals = NULL;
        PyObject *retval = NULL;        /* Return value */
        PyThreadState *tstate = PyThreadState_Get();
+       unsigned char *first_instr;
 #ifdef LLTRACE
        int lltrace;
 #endif
@@ -379,11 +380,10 @@ eval_code2(co, globals, locals,
 #define GETCONST(i)    Getconst(f, i)
 #define GETNAME(i)     Getname(f, i)
 #define GETNAMEV(i)    Getnamev(f, i)
-#define FIRST_INSTR()  (GETUSTRINGVALUE(co->co_code))
-#define INSTR_OFFSET() (next_instr - FIRST_INSTR())
+#define INSTR_OFFSET() (next_instr - first_instr)
 #define NEXTOP()       (*next_instr++)
 #define NEXTARG()      (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
-#define JUMPTO(x)      (next_instr = FIRST_INSTR() + (x))
+#define JUMPTO(x)      (next_instr = first_instr + (x))
 #define JUMPBY(x)      (next_instr += (x))
 
 /* Stack manipulation macros */
@@ -580,7 +580,8 @@ eval_code2(co, globals, locals,
                return NULL;
        }
 
-       next_instr = GETUSTRINGVALUE(co->co_code);
+       _PyCode_GETCODEPTR(co, &first_instr);
+       next_instr = first_instr;
        stack_pointer = f->f_valuestack;
        
        why = WHY_NOT;
@@ -2801,7 +2802,9 @@ find_from_args(f, nexti)
        PyObject *list, *name;
        unsigned char *next_instr;
        
-       next_instr = GETUSTRINGVALUE(f->f_code->co_code) + nexti;
+       _PyCode_GETCODEPTR(f->f_code, &next_instr);
+       next_instr += nexti;
+
        opcode = (*next_instr++);
        if (opcode != IMPORT_FROM) {
                Py_INCREF(Py_None);
index 9871b0ff03deaca30a0563e0efe1d5d2f2c93bee..19f18e692dba41352e3744054c70c8e9d0a7c842 100644 (file)
@@ -121,9 +121,11 @@ code_repr(co)
 {
        char buf[500];
        int lineno = -1;
-       char *p = PyString_AS_STRING(co->co_code);
+       unsigned char *p;
        char *filename = "???";
        char *name = "???";
+
+       _PyCode_GETCODEPTR(co, &p);
        if (*p == SET_LINENO)
                lineno = (p[1] & 0xff) | ((p[2] & 0xff) << 8);
        if (co->co_filename && PyString_Check(co->co_filename))
@@ -146,8 +148,7 @@ code_compare(co, cp)
        if (cmp) return cmp;
        cmp = co->co_flags - cp->co_flags;
        if (cmp) return cmp;
-       cmp = PyObject_Compare((PyObject *)co->co_code,
-                              (PyObject *)cp->co_code);
+       cmp = PyObject_Compare(co->co_code, cp->co_code);
        if (cmp) return cmp;
        cmp = PyObject_Compare(co->co_consts, cp->co_consts);
        if (cmp) return cmp;
@@ -162,7 +163,7 @@ code_hash(co)
        PyCodeObject *co;
 {
        long h, h1, h2, h3, h4;
-       h1 = PyObject_Hash((PyObject *)co->co_code);
+       h1 = PyObject_Hash(co->co_code);
        if (h1 == -1) return -1;
        h2 = PyObject_Hash(co->co_consts);
        if (h2 == -1) return -1;
@@ -216,9 +217,10 @@ PyCode_New(argcount, nlocals, stacksize, flags,
 {
        PyCodeObject *co;
        int i;
+       PyBufferProcs *pb;
        /* Check argument types */
        if (argcount < 0 || nlocals < 0 ||
-           code == NULL || !PyString_Check(code) ||
+           code == NULL ||
            consts == NULL || !PyTuple_Check(consts) ||
            names == NULL || !PyTuple_Check(names) ||
            varnames == NULL || !PyTuple_Check(varnames) ||
@@ -228,6 +230,15 @@ PyCode_New(argcount, nlocals, stacksize, flags,
                PyErr_BadInternalCall();
                return NULL;
        }
+       pb = code->ob_type->tp_as_buffer;
+       if (pb == NULL ||
+           pb->bf_getreadbuffer == NULL ||
+           pb->bf_getsegcount == NULL ||
+           (*pb->bf_getsegcount)(code, NULL) != 1)
+       {
+               PyErr_BadInternalCall();
+               return NULL;
+       }
        /* Make sure names and varnames are all strings, & intern them */
        for (i = PyTuple_Size(names); --i >= 0; ) {
                PyObject *v = PyTuple_GetItem(names, i);
@@ -264,7 +275,7 @@ PyCode_New(argcount, nlocals, stacksize, flags,
                co->co_stacksize = stacksize;
                co->co_flags = flags;
                Py_INCREF(code);
-               co->co_code = (PyStringObject *)code;
+               co->co_code = code;
                Py_INCREF(consts);
                co->co_consts = consts;
                Py_INCREF(names);
index 3d5f2e5315514b2f59bff92e043a6eb6e9205b97..df7f51c867578f17e65b65ce9e64d801a25b9616 100644 (file)
@@ -142,6 +142,7 @@ w_object(v, p)
        WFILE *p;
 {
        int i, n;
+       PyBufferProcs *pb;
        
        if (v == NULL) {
                w_byte(TYPE_NULL, p);
@@ -251,7 +252,7 @@ w_object(v, p)
                w_short(co->co_nlocals, p);
                w_short(co->co_stacksize, p);
                w_short(co->co_flags, p);
-               w_object((PyObject *)co->co_code, 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);
@@ -260,6 +261,18 @@ w_object(v, 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;
@@ -730,7 +743,7 @@ marshal_loads(self, args)
        PyObject *v;
        char *s;
        int n;
-       if (!PyArg_Parse(args, "s#", &s, &n))
+       if (!PyArg_Parse(args, "r#", &s, &n))
                return NULL;
        rf.fp = NULL;
        rf.str = args;