"Compiling" version

This commit is contained in:
Guido van Rossum 1990-12-20 15:06:42 +00:00
parent 226d79eb4a
commit 3f5da24ea3
72 changed files with 3363 additions and 2061 deletions

View file

@ -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*/

View file

@ -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*/
};

View file

@ -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));

132
Objects/frameobject.c Normal file
View file

@ -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;
}

View file

@ -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*/

View file

@ -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();
register intobject *v;
if (free_list == NULL) {
if ((free_list = fill_free_list()) == NULL)
return NULL;
}
else {
NEWREF(op);
op->ob_type = &Inttype;
op->ob_ival = ival;
}
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*/

View file

@ -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)

View file

@ -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;
}

View file

@ -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*/
};

View file

@ -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"
#ifdef REF_DEBUG
long ref_total;
#endif
int StopPrint; /* Flag to indicate printing must be stopped */
/* 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);
}

View file

@ -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)

View file

@ -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)

View file

@ -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*/
};