$OpenBSD: patch-c_Objects_pobject_c,v 1.1 2005/06/08 22:24:01 fgsch Exp $
--- c/Objects/pobject.c.orig	Tue Sep  7 06:07:05 2004
+++ c/Objects/pobject.c	Wed Jun  8 19:15:52 2005
@@ -586,6 +586,80 @@ vinfo_t* PsycoObject_RichCompareBool(Psy
 	return diff;
 }
 
+static vinfo_t* collect_undeletable_vars(vinfo_t* vi, vinfo_t* link)
+{
+	int i;
+	PyTypeObject* tp;
+	switch (gettime(vi->source)) {
+
+	case RunTime:
+		if (vi->tmp != NULL || (vi->source & RunTime_NoRef) != 0)
+			break;  /* already seen or not holding a ref */
+		tp = Psyco_KnownType(vi);
+		if (tp && (tp == &PyInt_Type || tp == &PyString_Type ||
+#if BOOLEAN_TYPE
+			   tp == &PyBool_Type ||
+#endif
+			   tp == &PyFloat_Type || tp == &PyLong_Type ||
+			   tp == &PyRange_Type))
+			break;  /* known safe type */
+		/* make a linked list of results */
+		vi->tmp = link;
+		link = vi;
+		break;
+
+	case VirtualTime:
+		for (i=vi->array->count; i--; )
+			if (vi->array->items[i] != NULL)
+				link = collect_undeletable_vars(
+					vi->array->items[i], link);
+		break;
+
+	default:
+		break;
+	}
+	return link;
+}
+
+DEFINEFN
+vinfo_t* Psyco_SafelyDeleteVar(PsycoObject* po, vinfo_t* vi)
+{
+	vinfo_t* result;
+	vinfo_t* head;
+	vinfo_t* queue = (vinfo_t*) 1;
+	vinfo_t* p;
+	int count;
+	vi->tmp = NULL;
+	clear_tmp_marks(vi->array);
+
+	head = collect_undeletable_vars(vi, queue);
+	count = 0;
+	for (p = head; p != queue; p = p->tmp) {
+		vinfo_array_t* a = p->array;
+		p->array = NullArray;
+		array_delete(a, po);
+		count++;
+	}
+	if (count == 0) {
+		result = psyco_vi_Zero();
+	}
+	else if (count == 1) {
+		result = head;
+		vinfo_incref(result);
+	}
+	else {
+		result = vinfo_new(
+			VirtualTime_New(&psyco_vsource_not_important));
+		count += iOB_TYPE + 1;
+		result->array = array_new(count);
+		for (p = head; p != queue; p = p->tmp) {
+			vinfo_incref(p);
+			result->array->items[--count] = p;
+		}
+	}
+	return result;
+}
+
 
 INITIALIZATIONFN
 void psy_object_init(void)
