diff options
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/classobject.c | 37 | ||||
-rw-r--r-- | Objects/fileobject.c | 102 | ||||
-rw-r--r-- | Objects/floatobject.c | 12 | ||||
-rw-r--r-- | Objects/frameobject.c | 132 | ||||
-rw-r--r-- | Objects/funcobject.c | 29 | ||||
-rw-r--r-- | Objects/intobject.c | 114 | ||||
-rw-r--r-- | Objects/listobject.c | 18 | ||||
-rw-r--r-- | Objects/methodobject.c | 41 | ||||
-rw-r--r-- | Objects/moduleobject.c | 69 | ||||
-rw-r--r-- | Objects/object.c | 121 | ||||
-rw-r--r-- | Objects/stringobject.c | 9 | ||||
-rw-r--r-- | Objects/tupleobject.c | 15 | ||||
-rw-r--r-- | Objects/typeobject.c | 28 |
13 files changed, 449 insertions, 278 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c index edc6070..4ee32d4 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -1,28 +1,17 @@ /* Class object implementation */ -#include <stdio.h> +#include "allobjects.h" -#include "PROTO.h" -#include "node.h" -#include "object.h" -#include "stringobject.h" -#include "tupleobject.h" -#include "dictobject.h" -#include "funcobject.h" -#include "classobject.h" -#include "objimpl.h" -#include "errors.h" +#include "structmember.h" typedef struct { OB_HEAD - node *cl_tree; /* The entire classdef parse tree */ object *cl_bases; /* A tuple */ object *cl_methods; /* A dictionary */ } classobject; object * -newclassobject(tree, bases, methods) - node *tree; +newclassobject(bases, methods) object *bases; /* NULL or tuple of classobjects! */ object *methods; { @@ -30,7 +19,6 @@ newclassobject(tree, bases, methods) op = NEWOBJ(classobject, &Classtype); if (op == NULL) return NULL; - op->cl_tree = tree; if (bases != NULL) INCREF(bases); op->cl_bases = bases; @@ -70,6 +58,7 @@ class_getattr(op, name) v = class_getattr(gettupleitem(op->cl_bases, i), name); if (v != NULL) return v; + err_clear(); } } err_setstr(NameError, name); @@ -242,6 +231,22 @@ classmethodgetself(cm) /* Class method methods */ +#define OFF(x) offsetof(classmethodobject, x) + +static struct memberlist classmethod_memberlist[] = { + {"cm_func", T_OBJECT, OFF(cm_func)}, + {"cm_self", T_OBJECT, OFF(cm_self)}, + {NULL} /* Sentinel */ +}; + +static object * +classmethod_getattr(cm, name) + register classmethodobject *cm; + char *name; +{ + return getmember((char *)cm, classmethod_memberlist, name); +} + static void classmethod_dealloc(cm) register classmethodobject *cm; @@ -259,7 +264,7 @@ typeobject Classmethodtype = { 0, classmethod_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - 0, /*tp_getattr*/ + classmethod_getattr, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 7eb6f5c..09690c6 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -2,19 +2,16 @@ /* XXX This should become a built-in module 'io'. It should support more functionality, better exception handling for invalid calls, etc. + (Especially reading on a write-only file or vice versa!) It should also cooperate with posix to support popen(), which should share most code but have a special close function. */ -#include <stdio.h> +#include "allobjects.h" -#include "PROTO.h" -#include "object.h" -#include "stringobject.h" -#include "intobject.h" -#include "fileobject.h" -#include "methodobject.h" -#include "objimpl.h" -#include "errors.h" +#include "errno.h" +#ifndef errno +extern int errno; +#endif typedef struct { OB_HEAD @@ -29,7 +26,7 @@ getfilefile(f) object *f; { if (!is_fileobject(f)) { - errno = EBADF; + err_badcall(); return NULL; } return ((fileobject *)f)->f_fp; @@ -49,7 +46,6 @@ newopenfileobject(fp, name, mode) f->f_mode = newstringobject(mode); if (f->f_name == NULL || f->f_mode == NULL) { DECREF(f); - errno = ENOMEM; return NULL; } f->f_fp = fp; @@ -67,6 +63,7 @@ newfileobject(name, mode) return NULL; if ((f->f_fp = fopen(name, mode)) == NULL) { DECREF(f); + err_errno(RuntimeError); /* XXX Should use another error */ return NULL; } return (object *)f; @@ -75,7 +72,7 @@ newfileobject(name, mode) /* Methods */ static void -filedealloc(f) +file_dealloc(f) fileobject *f; { if (f->f_fp != NULL) @@ -88,7 +85,7 @@ filedealloc(f) } static void -fileprint(f, fp, flags) +file_print(f, fp, flags) fileobject *f; FILE *fp; int flags; @@ -101,11 +98,11 @@ fileprint(f, fp, flags) } static object * -filerepr(f) +file_repr(f) fileobject *f; { char buf[300]; - /* XXX This differs from fileprint if the filename contains + /* XXX This differs from file_print if the filename contains quotes or other funny characters. */ sprintf(buf, "<%s file '%.256s', mode '%.10s'>", f->f_fp == NULL ? "closed" : "open", @@ -115,12 +112,12 @@ filerepr(f) } static object * -fileclose(f, args) +file_close(f, args) fileobject *f; object *args; { if (args != NULL) { - errno = EINVAL; + err_badarg(); return NULL; } if (f->f_fp != NULL) { @@ -132,30 +129,28 @@ fileclose(f, args) } static object * -fileread(f, args) +file_read(f, args) fileobject *f; object *args; { int n; object *v; if (f->f_fp == NULL) { - errno = EBADF; + err_badarg(); return NULL; } if (args == NULL || !is_intobject(args)) { - errno = EINVAL; + err_badarg(); return NULL; } n = getintvalue(args); if (n < 0) { - errno = EDOM; + err_badarg(); return NULL; } v = newsizedstringobject((char *)NULL, n); - if (v == NULL) { - errno = ENOMEM; + if (v == NULL) return NULL; - } n = fread(getstringvalue(v), 1, n, f->f_fp); /* EOF is reported as an empty string */ /* XXX should detect real I/O errors? */ @@ -166,14 +161,14 @@ fileread(f, args) /* XXX Should this be unified with raw_input()? */ static object * -filereadline(f, args) +file_readline(f, args) fileobject *f; object *args; { int n; object *v; if (f->f_fp == NULL) { - errno = EBADF; + err_badarg(); return NULL; } if (args == NULL) { @@ -181,21 +176,23 @@ filereadline(f, args) } else if (is_intobject(args)) { n = getintvalue(args); - if (n < 0 || n > 0x7fff /*XXX*/ ) { - errno = EDOM; + if (n < 0) { + err_badarg(); return NULL; } } else { - errno = EINVAL; + err_badarg(); return NULL; } v = newsizedstringobject((char *)NULL, n); - if (v == NULL) { - errno = ENOMEM; + if (v == NULL) return NULL; - } - if (fgets(getstringvalue(v), n+1, f->f_fp) == NULL) { +#ifndef THINK_C + /* XXX Think C reads n characters, others read n-1 characters... */ + n = n+1; +#endif + if (fgets(getstringvalue(v), n, f->f_fp) == NULL) { /* EOF is reported as an empty string */ /* XXX should detect real I/O errors? */ n = 0; @@ -208,17 +205,17 @@ filereadline(f, args) } static object * -filewrite(f, args) +file_write(f, args) fileobject *f; object *args; { int n, n2; if (f->f_fp == NULL) { - errno = EBADF; + err_badarg(); return NULL; } if (args == NULL || !is_stringobject(args)) { - errno = EINVAL; + err_badarg(); return NULL; } errno = 0; @@ -226,36 +223,27 @@ filewrite(f, args) if (n2 != n) { if (errno == 0) errno = EIO; + err_errno(RuntimeError); return NULL; } INCREF(None); return None; } -static struct methodlist { - char *ml_name; - method ml_meth; -} filemethods[] = { - {"write", filewrite}, - {"read", fileread}, - {"readline", filereadline}, - {"close", fileclose}, +static struct methodlist file_methods[] = { + {"write", file_write}, + {"read", file_read}, + {"readline", file_readline}, + {"close", file_close}, {NULL, NULL} /* sentinel */ }; static object * -filegetattr(f, name) +file_getattr(f, name) fileobject *f; char *name; { - struct methodlist *ml = filemethods; - for (; ml->ml_name != NULL; ml++) { - if (strcmp(name, ml->ml_name) == 0) - return newmethodobject(ml->ml_name, ml->ml_meth, - (object *)f); - } - err_setstr(NameError, name); - return NULL; + return findmethod(file_methods, (object *)f, name); } typeobject Filetype = { @@ -264,10 +252,10 @@ typeobject Filetype = { "file", sizeof(fileobject), 0, - filedealloc, /*tp_dealloc*/ - fileprint, /*tp_print*/ - filegetattr, /*tp_getattr*/ + file_dealloc, /*tp_dealloc*/ + file_print, /*tp_print*/ + file_getattr, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ - filerepr, /*tp_repr*/ + file_repr, /*tp_repr*/ }; diff --git a/Objects/floatobject.c b/Objects/floatobject.c index c2b132e..82d4643 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -3,16 +3,10 @@ /* XXX There should be overflow checks here, but it's hard to check for any kind of float exception without losing portability. */ -#include <stdio.h> -#include <math.h> -#include <ctype.h> +#include "allobjects.h" -#include "PROTO.h" -#include "object.h" -#include "floatobject.h" -#include "stringobject.h" -#include "objimpl.h" -#include "errors.h" +#include <ctype.h> +#include <math.h> #ifndef THINK_C extern double fmod PROTO((double, double)); diff --git a/Objects/frameobject.c b/Objects/frameobject.c new file mode 100644 index 0000000..6da3929 --- /dev/null +++ b/Objects/frameobject.c @@ -0,0 +1,132 @@ +/* Frame object implementation */ + +#include "allobjects.h" + +#include "compile.h" +#include "frameobject.h" +#include "opcode.h" +#include "structmember.h" + +#define OFF(x) offsetof(frameobject, x) + +static struct memberlist frame_memberlist[] = { + {"f_back", T_OBJECT, OFF(f_back)}, + {"f_code", T_OBJECT, OFF(f_code)}, + {"f_globals", T_OBJECT, OFF(f_globals)}, + {"f_locals", T_OBJECT, OFF(f_locals)}, + {NULL} /* Sentinel */ +}; + +static object * +frame_getattr(f, name) + frameobject *f; + char *name; +{ + return getmember((char *)f, frame_memberlist, name); +} + +static void +frame_dealloc(f) + frameobject *f; +{ + XDECREF(f->f_back); + XDECREF(f->f_code); + XDECREF(f->f_globals); + XDECREF(f->f_locals); + XDEL(f->f_valuestack); + XDEL(f->f_blockstack); + DEL(f); +} + +typeobject Frametype = { + OB_HEAD_INIT(&Typetype) + 0, + "frame", + sizeof(frameobject), + 0, + frame_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + frame_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ +}; + +frameobject * +newframeobject(back, code, globals, locals, nvalues, nblocks) + frameobject *back; + codeobject *code; + object *globals; + object *locals; + int nvalues; + int nblocks; +{ + frameobject *f; + if ((back != NULL && !is_frameobject(back)) || + code == NULL || !is_codeobject(code) || + globals == NULL || !is_dictobject(globals) || + locals == NULL || !is_dictobject(locals) || + nvalues < 0 || nblocks < 0) { + err_badcall(); + return NULL; + } + f = NEWOBJ(frameobject, &Frametype); + if (f != NULL) { + if (back) + INCREF(back); + f->f_back = back; + INCREF(code); + f->f_code = code; + INCREF(globals); + f->f_globals = globals; + INCREF(locals); + f->f_locals = locals; + f->f_valuestack = NEW(object *, nvalues+1); + f->f_blockstack = NEW(block, nblocks+1); + f->f_nvalues = nvalues; + f->f_nblocks = nblocks; + f->f_iblock = 0; + if (f->f_valuestack == NULL || f->f_blockstack == NULL) { + err_nomem(); + DECREF(f); + f = NULL; + } + } + return f; +} + +/* Block management */ + +void +setup_block(f, type, handler, level) + frameobject *f; + int type; + int handler; + int level; +{ + block *b; + if (f->f_iblock >= f->f_nblocks) { + fprintf(stderr, "XXX block stack overflow\n"); + abort(); + } + b = &f->f_blockstack[f->f_iblock++]; + b->b_type = type; + b->b_level = level; + b->b_handler = handler; +} + +block * +pop_block(f) + frameobject *f; +{ + block *b; + if (f->f_iblock <= 0) { + fprintf(stderr, "XXX block stack underflow\n"); + abort(); + } + b = &f->f_blockstack[--f->f_iblock]; + return b; +} diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 8850872..23236da 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -1,11 +1,8 @@ /* Function object implementation */ -#include <stdio.h> +#include "allobjects.h" -#include "PROTO.h" -#include "object.h" -#include "funcobject.h" -#include "objimpl.h" +#include "structmember.h" typedef struct { OB_HEAD @@ -52,8 +49,24 @@ getfuncglobals(op) /* Methods */ +#define OFF(x) offsetof(funcobject, x) + +static struct memberlist func_memberlist[] = { + {"func_code", T_OBJECT, OFF(func_code)}, + {"func_globals",T_OBJECT, OFF(func_globals)}, + {NULL} /* Sentinel */ +}; + +static object * +func_getattr(op, name) + funcobject *op; + char *name; +{ + return getmember((char *)op, func_memberlist, name); +} + static void -funcdealloc(op) +func_dealloc(op) funcobject *op; { DECREF(op->func_code); @@ -67,9 +80,9 @@ typeobject Functype = { "function", sizeof(funcobject), 0, - funcdealloc, /*tp_dealloc*/ + func_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - 0, /*tp_getattr*/ + func_getattr, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ diff --git a/Objects/intobject.c b/Objects/intobject.c index b0dd036..d70fcef 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -1,19 +1,14 @@ /* Integer object implementation */ -#include <stdio.h> - -#include "PROTO.h" -#include "object.h" -#include "intobject.h" -#include "stringobject.h" -#include "objimpl.h" -#include "errors.h" +#include "allobjects.h" /* Standard Booleans */ + intobject FalseObject = { OB_HEAD_INIT(&Inttype) 0 }; + intobject TrueObject = { OB_HEAD_INIT(&Inttype) 1 @@ -33,21 +28,58 @@ err_zdiv() return NULL; } +/* Integers are quite normal objects, to make object handling uniform. + (Using odd pointers to represent integers would save much space + but require extra checks for this special case throughout the code.) + Since, a typical Python program spends much of its time allocating + and deallocating integers, these operations should be very fast. + Therefore we use a dedicated allocation scheme with a much lower + overhead (in space and time) than straight malloc(): a simple + dedicated free list, filled when necessary with memory from malloc(). +*/ + +#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */ +#define N_INTOBJECTS (BLOCK_SIZE / sizeof(intobject)) + +static intobject * +fill_free_list() +{ + intobject *p, *q; + p = NEW(intobject, N_INTOBJECTS); + if (p == NULL) + return (intobject *)err_nomem(); + q = p + N_INTOBJECTS; + while (--q > p) + *(intobject **)q = q-1; + *(intobject **)q = NULL; + return p + N_INTOBJECTS - 1; +} + +static intobject *free_list = NULL; + object * newintobject(ival) long ival; { - /* For efficiency, this code is copied from newobject() */ - register intobject *op = (intobject *) malloc(sizeof(intobject)); - if (op == NULL) { - err_nomem(); - } - else { - NEWREF(op); - op->ob_type = &Inttype; - op->ob_ival = ival; + register intobject *v; + if (free_list == NULL) { + if ((free_list = fill_free_list()) == NULL) + return NULL; } - return (object *) op; + v = free_list; + free_list = *(intobject **)free_list; + NEWREF(v); + v->ob_type = &Inttype; + v->ob_ival = ival; + return (object *) v; +} + +static void +int_dealloc(v) + intobject *v; +{ + *(intobject **)v = free_list; + free_list = v; } long @@ -65,7 +97,7 @@ getintvalue(op) /* Methods */ static void -intprint(v, fp, flags) +int_print(v, fp, flags) intobject *v; FILE *fp; int flags; @@ -74,7 +106,7 @@ intprint(v, fp, flags) } static object * -intrepr(v) +int_repr(v) intobject *v; { char buf[20]; @@ -83,7 +115,7 @@ intrepr(v) } static int -intcompare(v, w) +int_compare(v, w) intobject *v, *w; { register long i = v->ob_ival; @@ -92,7 +124,7 @@ intcompare(v, w) } static object * -intadd(v, w) +int_add(v, w) intobject *v; register object *w; { @@ -110,7 +142,7 @@ intadd(v, w) } static object * -intsub(v, w) +int_sub(v, w) intobject *v; register object *w; { @@ -128,7 +160,7 @@ intsub(v, w) } static object * -intmul(v, w) +int_mul(v, w) intobject *v; register object *w; { @@ -147,7 +179,7 @@ intmul(v, w) } static object * -intdiv(v, w) +int_div(v, w) intobject *v; register object *w; { @@ -161,7 +193,7 @@ intdiv(v, w) } static object * -intrem(v, w) +int_rem(v, w) intobject *v; register object *w; { @@ -175,7 +207,7 @@ intrem(v, w) } static object * -intpow(v, w) +int_pow(v, w) intobject *v; register object *w; { @@ -203,7 +235,7 @@ intpow(v, w) } static object * -intneg(v) +int_neg(v) intobject *v; { register long a, x; @@ -215,7 +247,7 @@ intneg(v) } static object * -intpos(v) +int_pos(v) intobject *v; { INCREF(v); @@ -223,14 +255,14 @@ intpos(v) } static number_methods int_as_number = { - intadd, /*tp_add*/ - intsub, /*tp_subtract*/ - intmul, /*tp_multiply*/ - intdiv, /*tp_divide*/ - intrem, /*tp_remainder*/ - intpow, /*tp_power*/ - intneg, /*tp_negate*/ - intpos, /*tp_plus*/ + int_add, /*tp_add*/ + int_sub, /*tp_subtract*/ + int_mul, /*tp_multiply*/ + int_div, /*tp_divide*/ + int_rem, /*tp_remainder*/ + int_pow, /*tp_power*/ + int_neg, /*tp_negate*/ + int_pos, /*tp_plus*/ }; typeobject Inttype = { @@ -239,12 +271,12 @@ typeobject Inttype = { "int", sizeof(intobject), 0, - free, /*tp_dealloc*/ - intprint, /*tp_print*/ + int_dealloc, /*tp_dealloc*/ + int_print, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - intcompare, /*tp_compare*/ - intrepr, /*tp_repr*/ + int_compare, /*tp_compare*/ + int_repr, /*tp_repr*/ &int_as_number, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ diff --git a/Objects/listobject.c b/Objects/listobject.c index 97088c5..c59604d 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1,22 +1,6 @@ /* List object implementation */ -#include <stdio.h> - -#include "PROTO.h" -#include "object.h" -#include "intobject.h" -#include "stringobject.h" -#include "tupleobject.h" -#include "methodobject.h" -#include "listobject.h" -#include "objimpl.h" -#include "modsupport.h" -#include "errors.h" - -typedef struct { - OB_VARHEAD - object **ob_item; -} listobject; +#include "allobjects.h" object * newlistobject(size) diff --git a/Objects/methodobject.c b/Objects/methodobject.c index c8b5ee0..5cc4b88 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -1,15 +1,8 @@ /* Method object implementation */ -#include <stdio.h> +#include "allobjects.h" -#include "PROTO.h" -#include "object.h" -#include "node.h" -#include "stringobject.h" -#include "methodobject.h" -#include "objimpl.h" #include "token.h" -#include "errors.h" typedef struct { OB_HEAD @@ -75,11 +68,10 @@ meth_print(m, fp, flags) int flags; { if (m->m_self == NULL) - fprintf(fp, "<%s method>", m->m_name); + fprintf(fp, "<built-in function '%s'>", m->m_name); else - fprintf(fp, "<%s method of %s object at %lx>", - m->m_name, m->m_self->ob_type->tp_name, - (long)m->m_self); + fprintf(fp, "<built-in method '%s' of some %s object>", + m->m_name, m->m_self->ob_type->tp_name); } static object * @@ -88,11 +80,11 @@ meth_repr(m) { char buf[200]; if (m->m_self == NULL) - sprintf(buf, "<%.80s method>", m->m_name); + sprintf(buf, "<built-in function '%.80s'>", m->m_name); else - sprintf(buf, "<%.80s method of %.80s object at %lx>", - m->m_name, m->m_self->ob_type->tp_name, - (long)m->m_self); + sprintf(buf, + "<built-in method '%.80s' of some %.80s object>", + m->m_name, m->m_self->ob_type->tp_name); return newstringobject(buf); } @@ -112,3 +104,20 @@ typeobject Methodtype = { 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ }; + +/* Find a method in a module's method table. + Usually called from an object's getattr method. */ + +object * +findmethod(ml, op, name) + struct methodlist *ml; + object *op; + char *name; +{ + for (; ml->ml_name != NULL; ml++) { + if (strcmp(name, ml->ml_name) == 0) + return newmethodobject(ml->ml_name, ml->ml_meth, op); + } + err_setstr(NameError, name); + return NULL; +} diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 22a793f..cf96a70 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -1,14 +1,6 @@ /* Module object implementation */ -#include <stdio.h> - -#include "PROTO.h" -#include "object.h" -#include "stringobject.h" -#include "dictobject.h" -#include "moduleobject.h" -#include "objimpl.h" -#include "errors.h" +#include "allobjects.h" typedef struct { OB_HEAD @@ -37,31 +29,12 @@ getmoduledict(m) object *m; { if (!is_moduleobject(m)) { - err_badarg(); + err_badcall(); return NULL; } return ((moduleobject *)m) -> md_dict; } -int -setmoduledict(m, v) - object *m; - object *v; -{ - if (!is_moduleobject(m)) { - err_badarg(); - return -1; - } - if (!is_dictobject(v)) { - err_badarg(); - return -1; - } - DECREF(((moduleobject *)m) -> md_dict); - INCREF(v); - ((moduleobject *)m) -> md_dict = v; - return 0; -} - char * getmodulename(m) object *m; @@ -76,7 +49,7 @@ getmodulename(m) /* Methods */ static void -moduledealloc(m) +module_dealloc(m) moduleobject *m; { if (m->md_name != NULL) @@ -87,33 +60,37 @@ moduledealloc(m) } static void -moduleprint(m, fp, flags) +module_print(m, fp, flags) moduleobject *m; FILE *fp; int flags; { - fprintf(fp, "<module %s>", getstringvalue(m->md_name)); + fprintf(fp, "<module '%s'>", getstringvalue(m->md_name)); } static object * -modulerepr(m) +module_repr(m) moduleobject *m; { char buf[100]; - sprintf(buf, "<module %.80s>", getstringvalue(m->md_name)); + sprintf(buf, "<module '%.80s'>", getstringvalue(m->md_name)); return newstringobject(buf); } static object * -modulegetattr(m, name) +module_getattr(m, name) moduleobject *m; char *name; { object *res; - if (strcmp(name, "__dict") == 0) { + if (strcmp(name, "__dict__") == 0) { INCREF(m->md_dict); return m->md_dict; } + if (strcmp(name, "__name__") == 0) { + INCREF(m->md_name); + return m->md_name; + } res = dictlookup(m->md_dict, name); if (res == NULL) err_setstr(NameError, name); @@ -123,15 +100,13 @@ modulegetattr(m, name) } static int -modulesetattr(m, name, v) +module_setattr(m, name, v) moduleobject *m; char *name; object *v; { - if (strcmp(name, "__dict") == 0) { - /* Can't allow assignment to __dict, it would screw up - module's functions which still use the old dictionary. */ - err_setstr(NameError, "__dict is a reserved member name"); + if (strcmp(name, "__dict__") == 0 || strcmp(name, "__name__") == 0) { + err_setstr(NameError, "can't assign to reserved member name"); return NULL; } if (v == NULL) @@ -146,10 +121,10 @@ typeobject Moduletype = { "module", /*tp_name*/ sizeof(moduleobject), /*tp_size*/ 0, /*tp_itemsize*/ - moduledealloc, /*tp_dealloc*/ - moduleprint, /*tp_print*/ - modulegetattr, /*tp_getattr*/ - modulesetattr, /*tp_setattr*/ - 0, /*tp_compare*/ - modulerepr, /*tp_repr*/ + module_dealloc, /*tp_dealloc*/ + module_print, /*tp_print*/ + module_getattr, /*tp_getattr*/ + module_setattr, /*tp_setattr*/ + 0, /*tp_compare*/ + module_repr, /*tp_repr*/ }; diff --git a/Objects/object.c b/Objects/object.c index ebeb0f8..f2b4d1f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1,16 +1,14 @@ -/* Object implementation; and 'noobject' implementation */ +/* Generic object operations; and implementation of None (NoObject) */ -#include <stdio.h> +#include "allobjects.h" -#include "PROTO.h" -#include "object.h" -#include "stringobject.h" -#include "objimpl.h" -#include "errors.h" - -int StopPrint; /* Flag to indicate printing must be stopped */ +#ifdef REF_DEBUG +long ref_total; +#endif -/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros */ +/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros. + These are used by the individual routines for object creation. + Do not call them otherwise, they do not initialize the object! */ object * newobject(tp) @@ -43,6 +41,8 @@ newvarobject(tp, size) #endif +int StopPrint; /* Flag to indicate printing must be stopped */ + static int prlevel; void @@ -52,6 +52,7 @@ printobject(op, fp, flags) int flags; { /* Hacks to make printing a long or recursive object interruptible */ + /* XXX Interrupts should leave a more permanent error */ prlevel++; if (!StopPrint && intrcheck()) { fprintf(fp, "\n[print interrupted]\n"); @@ -61,12 +62,16 @@ printobject(op, fp, flags) if (op == NULL) { fprintf(fp, "<nil>"); } - else if (op->ob_type->tp_print == NULL) { - fprintf(fp, "<%s object at %lx>", - op->ob_type->tp_name, (long)op); - } else { - (*op->ob_type->tp_print)(op, fp, flags); + if (op->ob_refcnt <= 0) + fprintf(fp, "(refcnt %d):", op->ob_refcnt); + if (op->ob_type->tp_print == NULL) { + fprintf(fp, "<%s object at %lx>", + op->ob_type->tp_name, (long)op); + } + else { + (*op->ob_type->tp_print)(op, fp, flags); + } } } prlevel--; @@ -78,17 +83,16 @@ object * reprobject(v) object *v; { - object *w; + object *w = NULL; /* Hacks to make converting a long or recursive object interruptible */ prlevel++; if (!StopPrint && intrcheck()) { StopPrint = 1; - w = NULL; err_set(KeyboardInterrupt); } if (!StopPrint) { if (v == NULL) { - w = newstringobject("<nil>"); + w = newstringobject("<NULL>"); } else if (v->ob_type->tp_repr == NULL) { char buf[100]; @@ -99,6 +103,10 @@ reprobject(v) else { w = (*v->ob_type->tp_repr)(v); } + if (StopPrint) { + XDECREF(w); + w = NULL; + } } prlevel--; if (prlevel == 0) @@ -124,30 +132,76 @@ cmpobject(v, w) return ((*tp->tp_compare)(v, w)); } +object * +getattr(v, name) + object *v; + char *name; +{ + if (v->ob_type->tp_getattr == NULL) { + err_setstr(TypeError, "attribute-less object"); + return NULL; + } + else { + return (*v->ob_type->tp_getattr)(v, name); + } +} + +int +setattr(v, name, w) + object *v; + char *name; + object *w; +{ + if (v->ob_type->tp_setattr == NULL) { + if (v->ob_type->tp_getattr == NULL) + err_setstr(TypeError, "attribute-less object"); + else + err_setstr(TypeError, "object has read-only attributes"); + return NULL; + } + else { + return (*v->ob_type->tp_setattr)(v, name, w); + } +} + /* NoObject is usable as a non-NULL undefined value, used by the macro None. There is (and should be!) no way to create other objects of this type, -so there is exactly one. +so there is exactly one (which is indestructible, by the way). */ static void -noprint(op, fp, flags) +none_print(op, fp, flags) object *op; FILE *fp; int flags; { - fprintf(fp, "<no value>"); + fprintf(fp, "None"); +} + +static object * +none_repr(op) + object *op; +{ + return newstringobject("None"); } static typeobject Notype = { OB_HEAD_INIT(&Typetype) 0, - "novalue", + "None", 0, 0, 0, /*tp_dealloc*/ /*never called*/ - noprint, /*tp_print*/ + none_print, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + none_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ }; object NoObject = { @@ -170,15 +224,30 @@ NEWREF(op) refchain._ob_next = op; } -DELREF(op) - object *op; +UNREF(op) + register object *op; { + register object *p; if (op->ob_refcnt < 0) { - fprintf(stderr, "negative refcnt\n"); + fprintf(stderr, "UNREF negative refcnt\n"); + abort(); + } + for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) { + if (p == op) + break; + } + if (p == &refchain) { /* Not found */ + fprintf(stderr, "UNREF unknown object\n"); abort(); } op->_ob_next->_ob_prev = op->_ob_prev; op->_ob_prev->_ob_next = op->_ob_next; +} + +DELREF(op) + object *op; +{ + UNREF(op); (*(op)->ob_type->tp_dealloc)(op); } diff --git a/Objects/stringobject.c b/Objects/stringobject.c index 40cd15a..1881bdf 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -1,13 +1,6 @@ /* String object implementation */ -#include <stdio.h> - -#include "PROTO.h" -#include "object.h" -#include "stringobject.h" -#include "intobject.h" -#include "objimpl.h" -#include "errors.h" +#include "allobjects.h" object * newsizedstringobject(str, size) diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 960d78a..89ba4e9 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -1,19 +1,6 @@ /* Tuple object implementation */ -#include <stdio.h> - -#include "PROTO.h" -#include "object.h" -#include "stringobject.h" -#include "tupleobject.h" -#include "intobject.h" -#include "objimpl.h" -#include "errors.h" - -typedef struct { - OB_VARHEAD - object *ob_item[1]; -} tupleobject; +#include "allobjects.h" object * newtupleobject(size) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index f7acaad..f80c518 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1,16 +1,11 @@ /* Type object implementation */ -#include <stdio.h> - -#include "PROTO.h" -#include "object.h" -#include "stringobject.h" -#include "objimpl.h" +#include "allobjects.h" /* Type object implementation */ static void -typeprint(v, fp, flags) +type_print(v, fp, flags) typeobject *v; FILE *fp; int flags; @@ -19,7 +14,7 @@ typeprint(v, fp, flags) } static object * -typerepr(v) +type_repr(v) typeobject *v; { char buf[100]; @@ -27,21 +22,16 @@ typerepr(v) return newstringobject(buf); } -typedef struct { - OB_HEAD - long ob_ival; -} intobject; - typeobject Typetype = { OB_HEAD_INIT(&Typetype) 0, /* Number of items for varobject */ "type", /* Name of this type */ sizeof(typeobject), /* Basic object size */ 0, /* Item size for varobject */ - 0, /*tp_dealloc*/ - typeprint, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - typerepr, /*tp_repr*/ + 0, /*tp_dealloc*/ + type_print, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + type_repr, /*tp_repr*/ }; |