summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Objects/classobject.c9
-rw-r--r--Objects/dictobject.c72
-rw-r--r--Objects/fileobject.c50
-rw-r--r--Objects/floatobject.c1
-rw-r--r--Objects/frameobject.c28
-rw-r--r--Objects/intobject.c1
-rw-r--r--Objects/listobject.c8
-rw-r--r--Objects/longobject.c1
-rw-r--r--Objects/mappingobject.c72
-rw-r--r--Objects/methodobject.c2
-rw-r--r--Objects/object.c20
-rw-r--r--Objects/stringobject.c2
12 files changed, 170 insertions, 96 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 7d8a8e9..376f031 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -247,7 +247,6 @@ addaccess(class, inst)
pos = 0;
while (mappinggetnext(class->cl_dict, &pos, &key, &value)) {
- object *v;
if (!is_accessobject(value))
continue;
if (hasaccessvalue(value))
@@ -274,7 +273,6 @@ newinstanceobject(class, arg)
object *arg;
{
register instanceobject *inst;
- object *v;
object *init;
if (!is_classobject(class)) {
err_badcall();
@@ -328,12 +326,12 @@ static void
instance_dealloc(inst)
register instanceobject *inst;
{
- object *error_type, *error_value;
+ object *error_type, *error_value, *error_traceback;
object *del;
/* Call the __del__ method if it exists. First temporarily
revive the object and save the current exception, if any. */
INCREF(inst);
- err_get(&error_type, &error_value);
+ err_fetch(&error_type, &error_value, &error_traceback);
if ((del = instance_getattr1(inst, "__del__")) != NULL) {
object *args = newtupleobject(0);
object *res = args;
@@ -345,7 +343,7 @@ instance_dealloc(inst)
/* XXX If __del__ raised an exception, it is ignored! */
}
/* Restore the saved exception and undo the temporary revival */
- err_setval(error_type, error_value);
+ err_restore(error_type, error_value, error_traceback);
/* Can't use DECREF here, it would cause a recursive call */
if (--inst->ob_refcnt > 0)
return; /* __del__ added a reference; don't delete now */
@@ -427,6 +425,7 @@ instance_getattr(inst, name)
}
}
#endif
+ err_clear();
args = mkvalue("(Os)", inst, name);
if (args == NULL)
return NULL;
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index e40ac8d..89fd314 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -46,9 +46,9 @@ static long primes[] = {
3, 7, 13, 31, 61, 127, 251, 509, 1021, 2017, 4093,
5987,
9551, 15683, 19609, 31397,
- 65521L, 131071L, 262139L, 524287L, 1048573L, 2097143L,
- 4194301L, 8388593L, 16777213L, 33554393L, 67108859L,
- 134217689L, 268435399L, 536870909L, 1073741789L,
+ 65521L, 131071L, 262139L, 524287L, 1048573L, 2097143L,
+ 4194301L, 8388593L, 16777213L, 33554393L, 67108859L,
+ 134217689L, 268435399L, 536870909L, 1073741789L,
0
};
@@ -95,12 +95,8 @@ newmappingobject()
mp = NEWOBJ(mappingobject, &Mappingtype);
if (mp == NULL)
return NULL;
- mp->ma_size = primes[0];
- mp->ma_table = (mappingentry *) calloc(sizeof(mappingentry), mp->ma_size);
- if (mp->ma_table == NULL) {
- DEL(mp);
- return err_nomem();
- }
+ mp->ma_size = 0;
+ mp->ma_table = NULL;
mp->ma_fill = 0;
mp->ma_used = 0;
return (object *)mp;
@@ -173,10 +169,13 @@ insertmapping(mp, key, hash, value)
long hash;
object *value;
{
+ object *old_value;
register mappingentry *ep;
ep = lookmapping(mp, key, hash);
if (ep->me_value != NULL) {
- DECREF(ep->me_value);
+ old_value = ep->me_value;
+ ep->me_value = value;
+ DECREF(old_value); /* which **CAN** re-enter */
DECREF(key);
}
else {
@@ -186,9 +185,9 @@ insertmapping(mp, key, hash, value)
DECREF(ep->me_key);
ep->me_key = key;
ep->me_hash = hash;
+ ep->me_value = value;
mp->ma_used++;
}
- ep->me_value = value;
}
/*
@@ -233,14 +232,19 @@ mappingresize(mp)
mp->ma_table = newtable;
mp->ma_fill = 0;
mp->ma_used = 0;
+
+ /* Make two passes, so we can avoid decrefs
+ (and possible side effects) till the table is copied */
for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
if (ep->me_value != NULL)
insertmapping(mp,ep->me_key,ep->me_hash,ep->me_value);
- else {
+ }
+ for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
+ if (ep->me_value == NULL)
XDECREF(ep->me_key);
- }
}
- DEL(oldtable);
+
+ XDEL(oldtable);
return 0;
}
@@ -254,6 +258,8 @@ mappinglookup(op, key)
err_badcall();
return NULL;
}
+ if (((mappingobject *)op)->ma_table == NULL)
+ return NULL;
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
@@ -303,6 +309,8 @@ mappingremove(op, key)
register mappingobject *mp;
register long hash;
register mappingentry *ep;
+ object *old_value, *old_key;
+
if (!is_mappingobject(op)) {
err_badcall();
return -1;
@@ -319,12 +327,14 @@ mappingremove(op, key)
err_setval(KeyError, key);
return -1;
}
- DECREF(ep->me_key);
+ old_key = ep->me_key;
INCREF(dummy);
ep->me_key = dummy;
- DECREF(ep->me_value);
+ old_value = ep->me_value;
ep->me_value = NULL;
mp->ma_used--;
+ DECREF(old_value);
+ DECREF(old_key);
return 0;
}
@@ -332,18 +342,23 @@ void
mappingclear(op)
object *op;
{
- int i;
- register mappingobject *mp;
+ int i, n;
+ register mappingentry *table;
+ mappingobject *mp;
if (!is_mappingobject(op))
return;
mp = (mappingobject *)op;
- for (i = 0; i < mp->ma_size; i++) {
- XDECREF(mp->ma_table[i].me_key);
- XDECREF(mp->ma_table[i].me_value);
- mp->ma_table[i].me_key = NULL;
- mp->ma_table[i].me_value = NULL;
+ table = mp->ma_table;
+ if (table == NULL)
+ return;
+ n = mp->ma_size;
+ mp->ma_size = mp->ma_used = mp->ma_fill = 0;
+ mp->ma_table = NULL;
+ for (i = 0; i < n; i++) {
+ XDECREF(table[i].me_key);
+ XDECREF(table[i].me_value);
}
- mp->ma_used = 0;
+ DEL(table);
}
int
@@ -387,8 +402,7 @@ mapping_dealloc(mp)
if (ep->me_value != NULL)
DECREF(ep->me_value);
}
- if (mp->ma_table != NULL)
- DEL(mp->ma_table);
+ XDEL(mp->ma_table);
DEL(mp);
}
@@ -460,6 +474,10 @@ mapping_subscript(mp, key)
{
object *v;
long hash;
+ if (mp->ma_table == NULL) {
+ err_setval(KeyError, key);
+ return NULL;
+ }
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
@@ -700,7 +718,7 @@ mapping_has_key(mp, args)
hash = hashobject(key);
if (hash == -1)
return NULL;
- ok = lookmapping(mp, key, hash)->me_value != NULL;
+ ok = mp->ma_size != 0 && lookmapping(mp, key, hash)->me_value != NULL;
return newintobject(ok);
}
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index eb8f4aa..44bc51b 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -94,7 +94,7 @@ newfileobject(name, mode)
f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode, fclose);
if (f == NULL)
return NULL;
-#ifdef USE_FOPENRF
+#ifdef HAVE_FOPENRF
if (*mode == '*') {
FILE *fopenRF();
f->f_fp = fopenRF(name, mode+1);
@@ -231,6 +231,51 @@ file_seek(f, args)
return None;
}
+#ifdef HAVE_FTRUNCATE
+static object *
+file_truncate(f, args)
+ fileobject *f;
+ object *args;
+{
+ long newsize;
+ int ret;
+
+ if (f->f_fp == NULL)
+ return err_closed();
+ if (!getargs(args, "l", &newsize)) {
+ err_clear();
+ if (!getnoarg(args))
+ return NULL;
+ BGN_SAVE
+ errno = 0;
+ newsize = ftell(f->f_fp); /* default to current position*/
+ END_SAVE
+ if (newsize == -1L) {
+ err_errno(IOError);
+ clearerr(f->f_fp);
+ return NULL;
+ }
+ }
+ BGN_SAVE
+ errno = 0;
+ ret = fflush(f->f_fp);
+ END_SAVE
+ if (ret == 0) {
+ BGN_SAVE
+ errno = 0;
+ ret = ftruncate(fileno(f->f_fp), newsize);
+ END_SAVE
+ }
+ if (ret != 0) {
+ err_errno(IOError);
+ clearerr(f->f_fp);
+ return NULL;
+ }
+ INCREF(None);
+ return None;
+}
+#endif /* HAVE_FTRUNCATE */
+
static object *
file_tell(f, args)
fileobject *f;
@@ -615,6 +660,9 @@ static struct methodlist file_methods[] = {
{"readline", (method)file_readline},
{"readlines", (method)file_readlines},
{"seek", (method)file_seek},
+#ifdef HAVE_FTRUNCATE
+ {"truncate", (method)file_truncate},
+#endif
{"tell", (method)file_tell},
{"write", (method)file_write},
{"writelines", (method)file_writelines},
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index b37dd15..3f8e6aa 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -285,7 +285,6 @@ float_divmod(v, w)
{
double vx, wx;
double div, mod;
- object *t;
wx = w->ob_fval;
if (wx == 0.0) {
err_setstr(ZeroDivisionError, "float divmod()");
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index a22193f..4d943694 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -39,7 +39,9 @@ static struct memberlist frame_memberlist[] = {
{"f_globals", T_OBJECT, OFF(f_globals), RO},
{"f_locals", T_OBJECT, OFF(f_locals), RO},
{"f_owner", T_OBJECT, OFF(f_owner), RO},
-/* {"f_fastlocals",T_OBJECT, OFF(f_fastlocals),RO}, /* XXX Unsafe */
+#if 0
+ {"f_fastlocals",T_OBJECT, OFF(f_fastlocals),RO}, /* XXX Unsafe */
+#endif
{"f_localmap", T_OBJECT, OFF(f_localmap),RO},
{"f_lasti", T_INT, OFF(f_lasti), RO},
{"f_lineno", T_INT, OFF(f_lineno), RO},
@@ -217,10 +219,8 @@ setup_block(f, type, handler, level)
int level;
{
block *b;
- if (f->f_iblock >= f->f_nblocks) {
- fprintf(stderr, "XXX block stack overflow\n");
- abort();
- }
+ if (f->f_iblock >= f->f_nblocks)
+ fatal("XXX block stack overflow");
b = &f->f_blockstack[f->f_iblock++];
b->b_type = type;
b->b_level = level;
@@ -232,10 +232,8 @@ pop_block(f)
frameobject *f;
{
block *b;
- if (f->f_iblock <= 0) {
- fprintf(stderr, "XXX block stack underflow\n");
- abort();
- }
+ if (f->f_iblock <= 0)
+ fatal("XXX block stack underflow");
b = &f->f_blockstack[--f->f_iblock];
return b;
}
@@ -248,7 +246,7 @@ fast_2_locals(f)
{
/* Merge f->f_fastlocals into f->f_locals */
object *locals, *fast, *map;
- object *error_type, *error_value;
+ object *error_type, *error_value, *error_traceback;
int j;
if (f == NULL)
return;
@@ -260,7 +258,7 @@ fast_2_locals(f)
if (!is_dictobject(locals) || !is_listobject(fast) ||
!is_tupleobject(map))
return;
- err_get(&error_type, &error_value);
+ err_fetch(&error_type, &error_value, &error_traceback);
for (j = gettuplesize(map); --j >= 0; ) {
object *key = gettupleitem(map, j);
object *value = getlistitem(fast, j);
@@ -274,7 +272,7 @@ fast_2_locals(f)
err_clear();
}
}
- err_setval(error_type, error_value);
+ err_restore(error_type, error_value, error_traceback);
}
void
@@ -284,7 +282,7 @@ locals_2_fast(f, clear)
{
/* Merge f->f_locals into f->f_fastlocals */
object *locals, *fast, *map;
- object *error_type, *error_value;
+ object *error_type, *error_value, *error_traceback;
int j;
if (f == NULL)
return;
@@ -296,7 +294,7 @@ locals_2_fast(f, clear)
if (!is_dictobject(locals) || !is_listobject(fast) ||
!is_tupleobject(map))
return;
- err_get(&error_type, &error_value);
+ err_fetch(&error_type, &error_value, &error_traceback);
for (j = gettuplesize(map); --j >= 0; ) {
object *key = gettupleitem(map, j);
object *value = dict2lookup(locals, key);
@@ -308,5 +306,5 @@ locals_2_fast(f, clear)
if (setlistitem(fast, j, value) != 0)
err_clear();
}
- err_setval(error_type, error_value);
+ err_restore(error_type, error_value, error_traceback);
}
diff --git a/Objects/intobject.c b/Objects/intobject.c
index 7a4708e..6b41ae1 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -456,7 +456,6 @@ int_divmod(x, y)
intobject *x;
intobject *y;
{
- object *v, *v0, *v1;
long d, m;
if (i_divmod(x, y, &d, &m) < 0)
return NULL;
diff --git a/Objects/listobject.c b/Objects/listobject.c
index a3e4cb9..521d1a8 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -404,7 +404,7 @@ list_ass_slice(a, ilow, ihigh, v)
d = n - (ihigh-ilow);
if (d <= 0) { /* Delete -d items; XDECREF ihigh-ilow items */
for (k = ilow; k < ihigh; k++)
- XDECREF(item[k]);
+ XDECREF(item[k]); /* bug: reentrant side effects */
if (d < 0) {
for (/*k = ihigh*/; k < a->ob_size; k++)
item[k+d] = item[k];
@@ -422,7 +422,7 @@ list_ass_slice(a, ilow, ihigh, v)
for (k = a->ob_size; --k >= ihigh; )
item[k+d] = item[k];
for (/*k = ihigh-1*/; k >= ilow; --k)
- XDECREF(item[k]);
+ XDECREF(item[k]); /* bug: side effects :-( */
a->ob_item = item;
a->ob_size += d;
}
@@ -454,6 +454,7 @@ list_ass_item(a, i, v)
int i;
object *v;
{
+ object *old_value;
if (i < 0 || i >= a->ob_size) {
err_setstr(IndexError, "list assignment index out of range");
return -1;
@@ -461,8 +462,9 @@ list_ass_item(a, i, v)
if (v == NULL)
return list_ass_slice(a, i, i+1, v);
INCREF(v);
- DECREF(a->ob_item[i]);
+ old_value = a->ob_item[i];
a->ob_item[i] = v;
+ DECREF(old_value);
return 0;
}
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 82a74c0..6561edc 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -570,7 +570,6 @@ x_divrem(v1, w1, prem)
/* Forward */
static void long_dealloc PROTO((object *));
-static int long_print PROTO((object *, FILE *, int));
static object *long_repr PROTO((object *));
static int long_compare PROTO((longobject *, longobject *));
static long long_hash PROTO((longobject *));
diff --git a/Objects/mappingobject.c b/Objects/mappingobject.c
index e40ac8d..89fd314 100644
--- a/Objects/mappingobject.c
+++ b/Objects/mappingobject.c
@@ -46,9 +46,9 @@ static long primes[] = {
3, 7, 13, 31, 61, 127, 251, 509, 1021, 2017, 4093,
5987,
9551, 15683, 19609, 31397,
- 65521L, 131071L, 262139L, 524287L, 1048573L, 2097143L,
- 4194301L, 8388593L, 16777213L, 33554393L, 67108859L,
- 134217689L, 268435399L, 536870909L, 1073741789L,
+ 65521L, 131071L, 262139L, 524287L, 1048573L, 2097143L,
+ 4194301L, 8388593L, 16777213L, 33554393L, 67108859L,
+ 134217689L, 268435399L, 536870909L, 1073741789L,
0
};
@@ -95,12 +95,8 @@ newmappingobject()
mp = NEWOBJ(mappingobject, &Mappingtype);
if (mp == NULL)
return NULL;
- mp->ma_size = primes[0];
- mp->ma_table = (mappingentry *) calloc(sizeof(mappingentry), mp->ma_size);
- if (mp->ma_table == NULL) {
- DEL(mp);
- return err_nomem();
- }
+ mp->ma_size = 0;
+ mp->ma_table = NULL;
mp->ma_fill = 0;
mp->ma_used = 0;
return (object *)mp;
@@ -173,10 +169,13 @@ insertmapping(mp, key, hash, value)
long hash;
object *value;
{
+ object *old_value;
register mappingentry *ep;
ep = lookmapping(mp, key, hash);
if (ep->me_value != NULL) {
- DECREF(ep->me_value);
+ old_value = ep->me_value;
+ ep->me_value = value;
+ DECREF(old_value); /* which **CAN** re-enter */
DECREF(key);
}
else {
@@ -186,9 +185,9 @@ insertmapping(mp, key, hash, value)
DECREF(ep->me_key);
ep->me_key = key;
ep->me_hash = hash;
+ ep->me_value = value;
mp->ma_used++;
}
- ep->me_value = value;
}
/*
@@ -233,14 +232,19 @@ mappingresize(mp)
mp->ma_table = newtable;
mp->ma_fill = 0;
mp->ma_used = 0;
+
+ /* Make two passes, so we can avoid decrefs
+ (and possible side effects) till the table is copied */
for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
if (ep->me_value != NULL)
insertmapping(mp,ep->me_key,ep->me_hash,ep->me_value);
- else {
+ }
+ for (i = 0, ep = oldtable; i < oldsize; i++, ep++) {
+ if (ep->me_value == NULL)
XDECREF(ep->me_key);
- }
}
- DEL(oldtable);
+
+ XDEL(oldtable);
return 0;
}
@@ -254,6 +258,8 @@ mappinglookup(op, key)
err_badcall();
return NULL;
}
+ if (((mappingobject *)op)->ma_table == NULL)
+ return NULL;
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
@@ -303,6 +309,8 @@ mappingremove(op, key)
register mappingobject *mp;
register long hash;
register mappingentry *ep;
+ object *old_value, *old_key;
+
if (!is_mappingobject(op)) {
err_badcall();
return -1;
@@ -319,12 +327,14 @@ mappingremove(op, key)
err_setval(KeyError, key);
return -1;
}
- DECREF(ep->me_key);
+ old_key = ep->me_key;
INCREF(dummy);
ep->me_key = dummy;
- DECREF(ep->me_value);
+ old_value = ep->me_value;
ep->me_value = NULL;
mp->ma_used--;
+ DECREF(old_value);
+ DECREF(old_key);
return 0;
}
@@ -332,18 +342,23 @@ void
mappingclear(op)
object *op;
{
- int i;
- register mappingobject *mp;
+ int i, n;
+ register mappingentry *table;
+ mappingobject *mp;
if (!is_mappingobject(op))
return;
mp = (mappingobject *)op;
- for (i = 0; i < mp->ma_size; i++) {
- XDECREF(mp->ma_table[i].me_key);
- XDECREF(mp->ma_table[i].me_value);
- mp->ma_table[i].me_key = NULL;
- mp->ma_table[i].me_value = NULL;
+ table = mp->ma_table;
+ if (table == NULL)
+ return;
+ n = mp->ma_size;
+ mp->ma_size = mp->ma_used = mp->ma_fill = 0;
+ mp->ma_table = NULL;
+ for (i = 0; i < n; i++) {
+ XDECREF(table[i].me_key);
+ XDECREF(table[i].me_value);
}
- mp->ma_used = 0;
+ DEL(table);
}
int
@@ -387,8 +402,7 @@ mapping_dealloc(mp)
if (ep->me_value != NULL)
DECREF(ep->me_value);
}
- if (mp->ma_table != NULL)
- DEL(mp->ma_table);
+ XDEL(mp->ma_table);
DEL(mp);
}
@@ -460,6 +474,10 @@ mapping_subscript(mp, key)
{
object *v;
long hash;
+ if (mp->ma_table == NULL) {
+ err_setval(KeyError, key);
+ return NULL;
+ }
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
@@ -700,7 +718,7 @@ mapping_has_key(mp, args)
hash = hashobject(key);
if (hash == -1)
return NULL;
- ok = lookmapping(mp, key, hash)->me_value != NULL;
+ ok = mp->ma_size != 0 && lookmapping(mp, key, hash)->me_value != NULL;
return newintobject(ok);
}
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index f7363bd..a9bc508 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -132,7 +132,7 @@ static long
meth_hash(a)
methodobject *a;
{
- long x, y;
+ long x;
if (a->m_self == NULL)
x = 0;
else {
diff --git a/Objects/object.c b/Objects/object.c
index 04e1ede..f5c22d1 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -63,7 +63,7 @@ inc_count(tp)
if (tp->tp_alloc == 0) {
/* first time; hang in linked list */
if (tp->tp_next != NULL) /* sanity check */
- abort();
+ fatal("XXX inc_count sanity check");
tp->tp_next = type_list;
type_list = tp;
}
@@ -379,24 +379,18 @@ UNREF(op)
register object *op;
{
register object *p;
- if (op->ob_refcnt < 0) {
- fprintf(stderr, "UNREF negative refcnt\n");
- abort();
- }
+ if (op->ob_refcnt < 0)
+ fatal("UNREF negative refcnt");
if (op == &refchain ||
- op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) {
- fprintf(stderr, "UNREF invalid object\n");
- abort();
- }
+ op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op)
+ fatal("UNREF invalid object");
#ifdef SLOW_UNREF_CHECK
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();
- }
+ if (p == &refchain) /* Not found */
+ fatal("UNREF unknown object");
#endif
op->_ob_next->_ob_prev = op->_ob_prev;
op->_ob_prev->_ob_next = op->_ob_next;
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 359e4e9..ae96cea 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -159,7 +159,7 @@ string_dealloc(op)
DEL(op);
}
-unsigned int
+int
getstringsize(op)
register object *op;
{