summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1998-10-07 19:42:25 (GMT)
committerGuido van Rossum <guido@python.org>1998-10-07 19:42:25 (GMT)
commitd076c73cc81a974794c9aa7e812931b74d6e03c2 (patch)
tree55b5c7b6c145d5491c2dd63780c9654c51aa2306
parent437ff8600a2959e87194f1491ba99116d73ea543 (diff)
downloadcpython-d076c73cc81a974794c9aa7e812931b74d6e03c2.zip
cpython-d076c73cc81a974794c9aa7e812931b74d6e03c2.tar.gz
cpython-d076c73cc81a974794c9aa7e812931b74d6e03c2.tar.bz2
Changes to support other object types besides strings
as the code string of code objects, as long as they support the (readonly) buffer interface. By Greg Stein.
-rw-r--r--Include/compile.h7
-rw-r--r--Modules/newmodule.c17
-rw-r--r--Python/ceval.c13
-rw-r--r--Python/compile.c23
-rw-r--r--Python/marshal.c17
5 files changed, 61 insertions, 16 deletions
diff --git a/Include/compile.h b/Include/compile.h
index 6c8a62d..b735617 100644
--- a/Include/compile.h
+++ b/Include/compile.h
@@ -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
diff --git a/Modules/newmodule.c b/Modules/newmodule.c
index 52328a9..5c92e0e 100644
--- a/Modules/newmodule.c
+++ b/Modules/newmodule.c
@@ -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);
diff --git a/Python/ceval.c b/Python/ceval.c
index b004c79..413b316 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -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);
diff --git a/Python/compile.c b/Python/compile.c
index 9871b0f..19f18e6 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -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);
diff --git a/Python/marshal.c b/Python/marshal.c
index 3d5f2e5..df7f51c 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -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;