[Stackless-checkins] CVS: slpdev/src/2.2/src/Objects abstract.c, 1.5, 1.6 classobject.c, 1.8, 1.9 descrobject.c, 1.4, 1.5 frameobject.c, 1.18, 1.19 funcobject.c, 1.2, 1.3 methodobject.c, 1.4, 1.5 object.c, 1.4, 1.5 rangeobject.c, 1.1.1.3, 1.2 typeobject.c, 1.6, 1.7

Christian Tismer tismer at centera.de
Sat May 1 03:21:17 CEST 2004


Update of /home/cvs/slpdev/src/2.2/src/Objects
In directory centera.de:/tmp/cvs-serv18709/src/Objects

Modified Files:
	abstract.c classobject.c descrobject.c frameobject.c 
	funcobject.c methodobject.c object.c rangeobject.c 
	typeobject.c 
Log Message:
initial patches from diffs (merge) plus a little Visual Studio

Index: abstract.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.2/src/Objects/abstract.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** abstract.c	30 Apr 2004 22:11:26 -0000	1.5
--- abstract.c	1 May 2004 01:21:10 -0000	1.6
***************
*** 6,9 ****
--- 6,10 ----
  #include "structmember.h" /* we need the offsetof() macro from there */
  #include "longintrepr.h"
+ #include "core/stackless_impl.h"
  
  #define NEW_STYLE_NUMBER(o) PyType_HasFeature((o)->ob_type, \
***************
*** 1683,1690 ****
  PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
  {
!         ternaryfunc call;
  
  	if ((call = func->ob_type->tp_call) != NULL) {
! 		PyObject *result = (*call)(func, arg, kw);
  		if (result == NULL && !PyErr_Occurred())
  			PyErr_SetString(
--- 1684,1693 ----
  PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
  {
! 	STACKLESS_GETARG();
! 	ternaryfunc call;
  
  	if ((call = func->ob_type->tp_call) != NULL) {
! 		PyObject *result = (STACKLESS_PROMOTE(func), (*call)(func, arg, kw));
! 		STACKLESS_ASSERT();
  		if (result == NULL && !PyErr_Occurred())
  			PyErr_SetString(
***************
*** 1701,1704 ****
--- 1704,1708 ----
  PyObject_CallFunction(PyObject *callable, char *format, ...)
  {
+ 	STACKLESS_GETARG();
  	va_list va;
  	PyObject *args, *retval;
***************
*** 1728,1733 ****
--- 1732,1743 ----
  		args = a;
  	}
+ <<<<<<< ../../2.2/src/./Objects/abstract.c
  	retval = PyObject_CallObject(callable, args);
  
+ =======
+ 	STACKLESS_PROMOTE_ALL();
+ 	retval = PyObject_Call(callable, args, NULL);
+ 	STACKLESS_ASSERT();
+ >>>>>>> ././Objects/abstract.c
  	Py_DECREF(args);
  
***************
*** 1738,1741 ****
--- 1748,1752 ----
  PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
  {
+ 	STACKLESS_GETARG();
  	va_list va;
  	PyObject *args, *func = 0, *retval;
***************
*** 1774,1780 ****
--- 1785,1793 ----
  		args = a;
  	}
+ 	STACKLESS_PROMOTE_ALL();
  
  	retval = PyObject_CallObject(func, args);
  
+ 	STACKLESS_ASSERT();
  	Py_DECREF(args);
  	Py_DECREF(func);
***************
*** 1817,1820 ****
--- 1830,1834 ----
  PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
  {
+ 	STACKLESS_GETARG();
  	PyObject *args, *tmp;
  	va_list vargs;
***************
*** 1835,1839 ****
--- 1849,1855 ----
  		return NULL;
  	}
+ 	STACKLESS_PROMOTE_ALL();
  	tmp = PyObject_Call(callable, args, NULL);
+ 	STACKLESS_ASSERT();
  	Py_DECREF(args);
  	Py_DECREF(callable);
***************
*** 1845,1848 ****
--- 1861,1865 ----
  PyObject_CallFunctionObjArgs(PyObject *callable, ...)
  {
+ 	STACKLESS_GETARG();
  	PyObject *args, *tmp;
  	va_list vargs;
***************
*** 1857,1861 ****
--- 1874,1880 ----
  	if (args == NULL)
  		return NULL;
+ 	STACKLESS_PROMOTE_ALL();
  	tmp = PyObject_Call(callable, args, NULL);
+ 	STACKLESS_ASSERT();
  	Py_DECREF(args);
  
***************
*** 2083,2087 ****
--- 2102,2108 ----
  PyIter_Next(PyObject *iter)
  {
+ 	STACKLESS_GETARG();
  	PyObject *result;
+ <<<<<<< ../../2.2/src/./Objects/abstract.c
  	if (!PyIter_Check(iter)) {
  		PyErr_Format(PyExc_TypeError,
***************
*** 2090,2094 ****
--- 2111,2123 ----
  		return NULL;
  	}
+ =======
+ 	assert(PyIter_Check(iter));
+ #ifdef STACKLESS
+ 	/* we use the same flag here, since iterators are not callable */
+ #endif
+ 	STACKLESS_PROMOTE(iter);
+ >>>>>>> ././Objects/abstract.c
  	result = (*iter->ob_type->tp_iternext)(iter);
+ 	STACKLESS_ASSERT();
  	if (result == NULL &&
  	    PyErr_Occurred() &&

Index: classobject.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.2/src/Objects/classobject.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** classobject.c	30 Apr 2004 22:11:26 -0000	1.8
--- classobject.c	1 May 2004 01:21:10 -0000	1.9
***************
*** 4,7 ****
--- 4,8 ----
  #include "Python.h"
  #include "structmember.h"
+ #include "core/stackless_impl.h"
  
  #define TP_DESCR_GET(t) \
***************
*** 2266,2269 ****
--- 2267,2271 ----
  instancemethod_call(PyObject *func, PyObject *arg, PyObject *kw)
  {
+ 	STACKLESS_GETARG();
  	PyObject *self = PyMethod_GET_SELF(func);
  	PyObject *class = PyMethod_GET_CLASS(func);
***************
*** 2313,2317 ****
--- 2315,2321 ----
  		arg = newarg;
  	}
+ 	STACKLESS_PROMOTE_ALL();
  	result = PyObject_Call((PyObject *)func, arg, kw);
+ 	STACKLESS_ASSERT();
  	Py_DECREF(arg);
  	return result;
***************
*** 2355,2360 ****
--- 2359,2374 ----
  	PyObject_GenericSetAttr,		/* tp_setattro */
  	0,					/* tp_as_buffer */
+ <<<<<<< ../../2.2/src/./Objects/classobject.c
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
  	0,					/* tp_doc */
+ =======
+ #ifdef STACKLESS
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ 		Py_TPFLAGS_HAVE_STACKLESS_CALL,	/* tp_flags */
+ #else
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ #endif
+ 	instancemethod_doc,			/* tp_doc */
+ >>>>>>> ././Objects/classobject.c
  	(traverseproc)instancemethod_traverse,	/* tp_traverse */
  	0,					/* tp_clear */

Index: descrobject.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.2/src/Objects/descrobject.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** descrobject.c	30 Apr 2004 22:11:26 -0000	1.4
--- descrobject.c	1 May 2004 01:21:10 -0000	1.5
***************
*** 3,6 ****
--- 3,7 ----
  #include "Python.h"
  #include "structmember.h" /* Why is this not included in Python.h? */
+ #include "core/stackless_impl.h"
  
  static void
***************
*** 173,176 ****
--- 174,178 ----
  methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds)
  {
+ 	STACKLESS_GETARG();
  	int argc;
  	PyObject *self, *func, *result;
***************
*** 207,211 ****
--- 209,215 ----
  		return NULL;
  	}
+ 	STACKLESS_PROMOTE_ALL();
  	result = PyEval_CallObjectWithKeywords(func, args, kwds);
+ 	STACKLESS_ASSERT();
  	Py_DECREF(args);
  	Py_DECREF(func);
***************
*** 214,219 ****
--- 218,245 ----
  
  static PyObject *
+ <<<<<<< ../../2.2/src/./Objects/descrobject.c
+ =======
+ classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
+ 		      PyObject *kwds)
+ {
+ 	STACKLESS_GETARG();
+ 	PyObject *func, *result;
+ 
+ 	func = PyCFunction_New(descr->d_method, (PyObject *)descr->d_type);
+ 	if (func == NULL)
+ 		return NULL;
+ 
+ 	STACKLESS_PROMOTE_ALL();
+ 	result = PyEval_CallObjectWithKeywords(func, args, kwds);
+ 	STACKLESS_ASSERT();
+ 	Py_DECREF(func);
+ 	return result;
+ }
+ 
+ static PyObject *
+ >>>>>>> ././Objects/descrobject.c
  wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
  {
+ 	STACKLESS_GETARG();
  	int argc;
  	PyObject *self, *func, *result;
***************
*** 250,254 ****
--- 276,282 ----
  		return NULL;
  	}
+ 	STACKLESS_PROMOTE_ALL();
  	result = PyEval_CallObjectWithKeywords(func, args, kwds);
+ 	STACKLESS_ASSERT();
  	Py_DECREF(args);
  	Py_DECREF(func);
***************
*** 336,340 ****
--- 364,372 ----
  }
  
+ #ifdef STACKLESS
+ PyTypeObject PyMethodDescr_Type = {
+ #else
  static PyTypeObject PyMethodDescr_Type = {
+ #endif
  	PyObject_HEAD_INIT(&PyType_Type)
  	0,
***************
*** 357,361 ****
--- 389,398 ----
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
+ #ifdef STACKLESS
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ 		Py_TPFLAGS_HAVE_STACKLESS_CALL, /* tp_flags */
+ #else
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ #endif
  	0,					/* tp_doc */
  	descr_traverse,				/* tp_traverse */
***************
*** 374,377 ****
--- 411,461 ----
  };
  
+ <<<<<<< ../../2.2/src/./Objects/descrobject.c
+ =======
+ /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
+ static PyTypeObject PyClassMethodDescr_Type = {
+ 	PyObject_HEAD_INIT(&PyType_Type)
+ 	0,
+ 	"classmethod_descriptor",
+ 	sizeof(PyMethodDescrObject),
+ 	0,
+ 	(destructor)descr_dealloc,		/* tp_dealloc */
+ 	0,					/* tp_print */
+ 	0,					/* tp_getattr */
+ 	0,					/* tp_setattr */
+ 	0,					/* tp_compare */
+ 	(reprfunc)method_repr,			/* tp_repr */
+ 	0,					/* tp_as_number */
+ 	0,					/* tp_as_sequence */
+ 	0,					/* tp_as_mapping */
+ 	0,					/* tp_hash */
+ 	(ternaryfunc)classmethoddescr_call,	/* tp_call */
+ 	0,					/* tp_str */
+ 	PyObject_GenericGetAttr,		/* tp_getattro */
+ 	0,					/* tp_setattro */
+ 	0,					/* tp_as_buffer */
+ #ifdef STACKLESS
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ 		Py_TPFLAGS_HAVE_STACKLESS_CALL, /* tp_flags */
+ #else
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ #endif
+ 	0,					/* tp_doc */
+ 	descr_traverse,				/* tp_traverse */
+ 	0,					/* tp_clear */
+ 	0,					/* tp_richcompare */
+ 	0,					/* tp_weaklistoffset */
+ 	0,					/* tp_iter */
+ 	0,					/* tp_iternext */
+ 	0,					/* tp_methods */
+ 	descr_members,				/* tp_members */
+ 	method_getset,				/* tp_getset */
+ 	0,					/* tp_base */
+ 	0,					/* tp_dict */
+ 	(descrgetfunc)classmethod_get,		/* tp_descr_get */
+ 	0,					/* tp_descr_set */
+ };
+ 
+ >>>>>>> ././Objects/descrobject.c
  static PyTypeObject PyMemberDescr_Type = {
  	PyObject_HEAD_INIT(&PyType_Type)
***************
*** 471,475 ****
--- 555,564 ----
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
+ #ifdef STACKLESS
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ 		Py_TPFLAGS_HAVE_STACKLESS_CALL, /* tp_flags */
+ #else
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ #endif
  	0,					/* tp_doc */
  	descr_traverse,				/* tp_traverse */
***************
*** 800,806 ****
--- 889,912 ----
  };
  
+ #ifdef STACKLESS
+ #define WRAP_RETURN(call) { \
+ 	PyObject * retval; \
+ 	STACKLESS_PROMOTE_FLAG( \
+ 		wp->descr->d_base->flags & PyWrapperFlag_STACKLESS && \
+ 		wp->descr->d_type->tp_flags & Py_TPFLAGS_HAVE_STACKLESS_CALL); \
+ 	retval = (call); \
+ 	STACKLESS_ASSERT(); \
+ 	return retval; \
+ }
+ #else
+ #define WRAP_RETURN(call) return (call)
+ #endif
+ 
  static PyObject *
  wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds)
  {
+ #ifdef STACKLESS
+ 	STACKLESS_GETARG();
+ #endif
  	wrapperfunc wrapper = wp->descr->d_base->wrapper;
  	PyObject *self = wp->self;
***************
*** 808,812 ****
  	if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
  		wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
! 		return (*wk)(self, args, wp->descr->d_wrapped, kwds);
  	}
  
--- 914,918 ----
  	if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
  		wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
! 		WRAP_RETURN( (*wk)(self, args, wp->descr->d_wrapped, kwds) );
  	}
  
***************
*** 817,821 ****
  		return NULL;
  	}
! 	return (*wrapper)(self, args, wp->descr->d_wrapped);
  }
  
--- 923,927 ----
  		return NULL;
  	}
! 	WRAP_RETURN( (*wrapper)(self, args, wp->descr->d_wrapped) );
  }
  
***************
*** 839,843 ****
--- 945,954 ----
  }
  
+ #ifdef STACKLESS
+ #define wrappertype PyMethodWrapper_Type
+ PyTypeObject PyMethodWrapper_Type = {
+ #else
  static PyTypeObject wrappertype = {
+ #endif
  	PyObject_HEAD_INIT(&PyType_Type)
  	0,					/* ob_size */
***************
*** 861,865 ****
--- 972,981 ----
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
+ #ifdef STACKLESS
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ 		Py_TPFLAGS_HAVE_STACKLESS_CALL, /* tp_flags */
+ #else
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ #endif
   	0,					/* tp_doc */
  	wrapper_traverse,			/* tp_traverse */

Index: frameobject.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.2/src/Objects/frameobject.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** frameobject.c	1 May 2004 00:44:35 -0000	1.18
--- frameobject.c	1 May 2004 01:21:10 -0000	1.19
***************
*** 12,16 ****
--- 12,18 ----
  
  static PyMemberDef frame_memberlist[] = {
+ #ifndef STACKLESS
  	{"f_back",	T_OBJECT,	OFF(f_back),	RO},
+ #endif
  	{"f_code",	T_OBJECT,	OFF(f_code),	RO},
  	{"f_builtins",	T_OBJECT,	OFF(f_builtins),RO},
***************
*** 23,26 ****
--- 25,33 ----
  	{"f_exc_value",	T_OBJECT,	OFF(f_exc_value)},
  	{"f_exc_traceback", T_OBJECT,	OFF(f_exc_traceback)},
+ #ifdef STACKLESS
+ 	{"_exec_adr",	T_INT,		OFF(f_execute), RO,
+ 	 "The address of the execute C function of this frame.\n"
+ 	 "use f._exec_map[adr] to find its pickling name."},
+ #endif
  	{NULL}	/* Sentinel */
  };
***************
*** 34,38 ****
--- 41,376 ----
  }
  
+ <<<<<<< ../../2.2/src/./Objects/frameobject.c
+ =======
+ static PyObject *
+ frame_getlineno(PyFrameObject *f, void *closure)
+ {
+ 	int lineno;
+ 
+ 	if (f->f_trace)
+ 		lineno = f->f_lineno;
+ 	else
+ 		lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
+ 
+ 	return PyInt_FromLong(lineno);
+ }
+ 
+ /* Setter for f_lineno - you can set f_lineno from within a trace function in
+  * order to jump to a given line of code, subject to some restrictions.  Most
+  * lines are OK to jump to because they don't make any assumptions about the
+  * state of the stack (obvious because you could remove the line and the code
+  * would still work without any stack errors), but there are some constructs
+  * that limit jumping:
+  *
+  *  o Lines with an 'except' statement on them can't be jumped to, because
+  *    they expect an exception to be on the top of the stack.
+  *  o Lines that live in a 'finally' block can't be jumped from or to, since
+  *    the END_FINALLY expects to clean up the stack after the 'try' block.
+  *  o 'try'/'for'/'while' blocks can't be jumped into because the blockstack
+  *    needs to be set up before their code runs, and for 'for' loops the
+  *    iterator needs to be on the stack.
+  */
+ static int
+ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
+ {
+ 	int new_lineno = 0;		/* The new value of f_lineno */
+ 	int new_lasti = 0;		/* The new value of f_lasti */
+ 	int new_iblock = 0;		/* The new value of f_iblock */
+ 	char *code = NULL;		/* The bytecode for the frame... */
+ 	int code_len = 0;		/* ...and its length */
+ 	char *lnotab = NULL;		/* Iterating over co_lnotab */
+ 	int lnotab_len = 0;		/* (ditto) */
+ 	int offset = 0;			/* (ditto) */
+ 	int line = 0;			/* (ditto) */
+ 	int addr = 0;			/* (ditto) */
+ 	int min_addr = 0;		/* Scanning the SETUPs and POPs */
+ 	int max_addr = 0;		/* (ditto) */
+ 	int delta_iblock = 0;		/* (ditto) */
+ 	int min_delta_iblock = 0;	/* (ditto) */
+ 	int min_iblock = 0;		/* (ditto) */
+ 	int f_lasti_setup_addr = 0;	/* Policing no-jump-into-finally */
+ 	int new_lasti_setup_addr = 0;	/* (ditto) */
+ 	int blockstack[CO_MAXBLOCKS];	/* Walking the 'finally' blocks */
+ 	int in_finally[CO_MAXBLOCKS];	/* (ditto) */
+ 	int blockstack_top = 0;		/* (ditto) */
+ 	int setup_op = 0;               /* (ditto) */
+ 
+ 	/* f_lineno must be an integer. */
+ 	if (!PyInt_Check(p_new_lineno)) {
+ 		PyErr_SetString(PyExc_ValueError,
+ 				"lineno must be an integer");
+ 		return -1;
+ 	}
+ 
+ 	/* You can only do this from within a trace function, not via
+ 	 * _getframe or similar hackery. */
+ 	if (!f->f_trace)
+ 	{
+ 		PyErr_Format(PyExc_ValueError,
+ 			     "f_lineno can only be set by a trace function");
+ 		return -1;
+ 	}
+ 
+ 	/* Fail if the line comes before the start of the code block. */
+ 	new_lineno = (int) PyInt_AsLong(p_new_lineno);
+ 	if (new_lineno < f->f_code->co_firstlineno) {
+ 		PyErr_Format(PyExc_ValueError,
+ 			     "line %d comes before the current code block",
+ 			     new_lineno);
+ 		return -1;
+ 	}
+ 
+ 	/* Find the bytecode offset for the start of the given line, or the
+ 	 * first code-owning line after it. */
+ 	PyString_AsStringAndSize(f->f_code->co_lnotab, &lnotab, &lnotab_len);
+ 	addr = 0;
+ 	line = f->f_code->co_firstlineno;
+ 	new_lasti = -1;
+ 	for (offset = 0; offset < lnotab_len; offset += 2) {
+ 		addr += lnotab[offset];
+ 		line += lnotab[offset+1];
+ 		if (line >= new_lineno) {
+ 			new_lasti = addr;
+ 			new_lineno = line;
+ 			break;
+ 		}
+ 	}
+ 
+ 	/* If we didn't reach the requested line, return an error. */
+ 	if (new_lasti == -1) {
+ 		PyErr_Format(PyExc_ValueError,
+ 			     "line %d comes after the current code block",
+ 			     new_lineno);
+ 		return -1;
+ 	}
+ 
+ 	/* We're now ready to look at the bytecode. */
+ 	PyString_AsStringAndSize(f->f_code->co_code, &code, &code_len);
+ 	min_addr = MIN(new_lasti, f->f_lasti);
+ 	max_addr = MAX(new_lasti, f->f_lasti);
+ 
+ 	/* You can't jump onto a line with an 'except' statement on it -
+ 	 * they expect to have an exception on the top of the stack, which
+ 	 * won't be true if you jump to them.  They always start with code
+ 	 * that either pops the exception using POP_TOP (plain 'except:'
+ 	 * lines do this) or duplicates the exception on the stack using
+ 	 * DUP_TOP (if there's an exception type specified).  See compile.c,
+ 	 * 'com_try_except' for the full details.  There aren't any other
+ 	 * cases (AFAIK) where a line's code can start with DUP_TOP or
+ 	 * POP_TOP, but if any ever appear, they'll be subject to the same
+ 	 * restriction (but with a different error message). */
+ 	if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) {
+ 		PyErr_SetString(PyExc_ValueError,
+ 		    "can't jump to 'except' line as there's no exception");
+ 		return -1;
+ 	}
+ 
+ 	/* You can't jump into or out of a 'finally' block because the 'try'
+ 	 * block leaves something on the stack for the END_FINALLY to clean
+ 	 * up.  So we walk the bytecode, maintaining a simulated blockstack.
+ 	 * When we reach the old or new address and it's in a 'finally' block
+ 	 * we note the address of the corresponding SETUP_FINALLY.  The jump
+ 	 * is only legal if neither address is in a 'finally' block or
+ 	 * they're both in the same one.  'blockstack' is a stack of the
+ 	 * bytecode addresses of the SETUP_X opcodes, and 'in_finally' tracks
+ 	 * whether we're in a 'finally' block at each blockstack level. */
+ 	f_lasti_setup_addr = -1;
+ 	new_lasti_setup_addr = -1;
+ 	memset(blockstack, '\0', sizeof(blockstack));
+ 	memset(in_finally, '\0', sizeof(in_finally));
+ 	blockstack_top = 0;
+ 	for (addr = 0; addr < code_len; addr++) {
+ 		unsigned char op = code[addr];
+ 		switch (op) {
+ 		case SETUP_LOOP:
+ 		case SETUP_EXCEPT:
+ 		case SETUP_FINALLY:
+ 			blockstack[blockstack_top++] = addr;
+ 			in_finally[blockstack_top-1] = 0;
+ 			break;
+ 
+ 		case POP_BLOCK:
+ 			assert(blockstack_top > 0);
+ 			setup_op = code[blockstack[blockstack_top-1]];
+ 			if (setup_op == SETUP_FINALLY) {
+ 				in_finally[blockstack_top-1] = 1;
+ 			}
+ 			else {
+ 				blockstack_top--;
+ 			}
+ 			break;
+ 
+ 		case END_FINALLY:
+ 			/* Ignore END_FINALLYs for SETUP_EXCEPTs - they exist
+ 			 * in the bytecode but don't correspond to an actual
+ 			 * 'finally' block.  (If blockstack_top is 0, we must
+ 			 * be seeing such an END_FINALLY.) */
+ 			if (blockstack_top > 0) {
+ 				setup_op = code[blockstack[blockstack_top-1]];
+ 				if (setup_op == SETUP_FINALLY) {
+ 					blockstack_top--;
+ 				}
+ 			}
+ 			break;
+ 		}
+ 
+ 		/* For the addresses we're interested in, see whether they're
+ 		 * within a 'finally' block and if so, remember the address
+ 		 * of the SETUP_FINALLY. */
+ 		if (addr == new_lasti || addr == f->f_lasti) {
+ 			int i = 0;
+ 			int setup_addr = -1;
+ 			for (i = blockstack_top-1; i >= 0; i--) {
+ 				if (in_finally[i]) {
+ 					setup_addr = blockstack[i];
+ 					break;
+ 				}
+ 			}
+ 
+ 			if (setup_addr != -1) {
+ 				if (addr == new_lasti) {
+ 					new_lasti_setup_addr = setup_addr;
+ 				}
+ 
+ 				if (addr == f->f_lasti) {
+ 					f_lasti_setup_addr = setup_addr;
+ 				}
+ 			}
+ 		}
+ 
+ 		if (op >= HAVE_ARGUMENT) {
+ 			addr += 2;
+ 		}
+ 	}
+ 
+ 	/* Verify that the blockstack tracking code didn't get lost. */
+ 	assert(blockstack_top == 0);
+ 
+ 	/* After all that, are we jumping into / out of a 'finally' block? */
+ 	if (new_lasti_setup_addr != f_lasti_setup_addr) {
+ 		PyErr_SetString(PyExc_ValueError,
+ 			    "can't jump into or out of a 'finally' block");
+ 		return -1;
+ 	}
+ 
+ 
+ 	/* Police block-jumping (you can't jump into the middle of a block)
+ 	 * and ensure that the blockstack finishes up in a sensible state (by
+ 	 * popping any blocks we're jumping out of).  We look at all the
+ 	 * blockstack operations between the current position and the new
+ 	 * one, and keep track of how many blocks we drop out of on the way.
+ 	 * By also keeping track of the lowest blockstack position we see, we
+ 	 * can tell whether the jump goes into any blocks without coming out
+ 	 * again - in that case we raise an exception below. */
+ 	delta_iblock = 0;
+ 	for (addr = min_addr; addr < max_addr; addr++) {
+ 		unsigned char op = code[addr];
+ 		switch (op) {
+ 		case SETUP_LOOP:
+ 		case SETUP_EXCEPT:
+ 		case SETUP_FINALLY:
+ 			delta_iblock++;
+ 			break;
+ 
+ 		case POP_BLOCK:
+ 			delta_iblock--;
+ 			break;
+ 		}
+ 
+ 		min_delta_iblock = MIN(min_delta_iblock, delta_iblock);
+ 
+ 		if (op >= HAVE_ARGUMENT) {
+ 			addr += 2;
+ 		}
+ 	}
+ 
+ 	/* Derive the absolute iblock values from the deltas. */
+ 	min_iblock = f->f_iblock + min_delta_iblock;
+ 	if (new_lasti > f->f_lasti) {
+ 		/* Forwards jump. */
+ 		new_iblock = f->f_iblock + delta_iblock;
+ 	}
+ 	else {
+ 		/* Backwards jump. */
+ 		new_iblock = f->f_iblock - delta_iblock;
+ 	}
+ 
+ 	/* Are we jumping into a block? */
+ 	if (new_iblock > min_iblock) {
+ 		PyErr_SetString(PyExc_ValueError,
+ 				"can't jump into the middle of a block");
+ 		return -1;
+ 	}
+ 
+ 	/* Pop any blocks that we're jumping out of. */
+ 	while (f->f_iblock > new_iblock) {
+ 		PyTryBlock *b = &f->f_blockstack[--f->f_iblock];
+ 		while ((f->f_stacktop - f->f_valuestack) > b->b_level) {
+ 			PyObject *v = (*--f->f_stacktop);
+ 			Py_DECREF(v);
+ 		}
+ 	}
+ 
+ 	/* Finally set the new f_lineno and f_lasti and return OK. */
+ 	f->f_lineno = new_lineno;
+ 	f->f_lasti = new_lasti;
+ 	return 0;
+ }
+ 
+ static PyObject *
+ frame_gettrace(PyFrameObject *f, void *closure)
+ {
+ 	PyObject* trace = f->f_trace;
+ 
+ 	if (trace == NULL)
+ 		trace = Py_None;
+ 
+ 	Py_INCREF(trace);
+ 
+ 	return trace;
+ }
+ 
+ static int
+ frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
+ {
+ 	/* We rely on f_lineno being accurate when f_trace is set. */
+ 
+ 	PyObject* old_value = f->f_trace;
+ 
+ 	Py_XINCREF(v);
+ 	f->f_trace = v;
+ 	
+ 	if (v != NULL)
+ 		f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
+ 
+ 	Py_XDECREF(old_value);
+ 
+ 	return 0;
+ }
+ 
+ #ifdef STACKLESS
+ 
+ static PyObject *
+ frame_getback(PyFrameObject *f, void *nope)
+ {
+ 	PyFrameObject *fb = f->f_back;
+ 	PyObject *ret;
+ 	while (fb != NULL && ! PyFrame_Check(fb))
+ 		fb = fb->f_back;
+ 	ret = (PyObject *) fb;
+ 	if (ret == NULL)
+ 		ret = Py_None;
+     Py_INCREF(ret);
+     return ret;
+ }
+ 
+ #endif
+ 
+ 
+ >>>>>>> ././Objects/frameobject.c
  static PyGetSetDef frame_getsetlist[] = {
+ #ifdef STACKLESS
+ 	{"f_back",	(getter)frame_getback, NULL, NULL},
+ #endif
  	{"f_locals",	(getter)frame_getlocals, NULL, NULL},
  	{0}
***************
*** 305,309 ****
--- 643,649 ----
  	f->f_trace = NULL;
  	f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL;
+ #ifndef STACKLESS
  	f->f_tstate = tstate;
+ #endif
  
  	f->f_lasti = 0;
***************
*** 321,324 ****
--- 661,667 ----
  	f->f_valuestack = f->f_localsplus + extras;
  	f->f_stacktop = f->f_valuestack;
+ #ifdef STACKLESS
+ 	f->f_execute = NULL;
+ #endif
  	_PyObject_GC_TRACK(f);
  	return f;

Index: funcobject.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.2/src/Objects/funcobject.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** funcobject.c	21 Aug 2003 16:59:16 -0000	1.2
--- funcobject.c	1 May 2004 01:21:10 -0000	1.3
***************
*** 6,9 ****
--- 6,10 ----
  #include "eval.h"
  #include "structmember.h"
+ #include "core/stackless_impl.h"
  
  PyObject *
***************
*** 440,443 ****
--- 441,445 ----
  function_call(PyObject *func, PyObject *arg, PyObject *kw)
  {
+ 	STACKLESS_GETARG();
  	PyObject *result;
  	PyObject *argdefs;
***************
*** 474,477 ****
--- 476,480 ----
  	}
  
+ 	STACKLESS_PROMOTE_ALL();
  	result = PyEval_EvalCodeEx(
  		(PyCodeObject *)PyFunction_GET_CODE(func),
***************
*** 480,483 ****
--- 483,487 ----
  		k, nk, d, nd,
  		PyFunction_GET_CLOSURE(func));
+ 	STACKLESS_ASSERT();
  
  	if (k != NULL)
***************
*** 517,521 ****
--- 521,530 ----
  	PyObject_GenericSetAttr,		/* tp_setattro */
  	0,					/* tp_as_buffer */
+ #ifdef STACKLESS
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ 		Py_TPFLAGS_HAVE_STACKLESS_CALL,/* tp_flags */
+ #else
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ #endif
  	func_doc,				/* tp_doc */
  	(traverseproc)func_traverse,		/* tp_traverse */

Index: methodobject.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.2/src/Objects/methodobject.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** methodobject.c	1 May 2004 00:44:35 -0000	1.4
--- methodobject.c	1 May 2004 01:21:10 -0000	1.5
***************
*** 3,6 ****
--- 3,11 ----
  
  #include "Python.h"
+ <<<<<<< ../../2.2/src/./Objects/methodobject.c
+ =======
+ #include "structmember.h"
+ #include "core/stackless_impl.h"
+ >>>>>>> ././Objects/methodobject.c
  
  static PyCFunctionObject *free_list = NULL;
***************
*** 56,62 ****
--- 61,82 ----
  }
  
+ #ifdef STACKLESS
+ #define WRAP_RETURN(call) { \
+ 	PyObject * retval; \
+ 	STACKLESS_PROMOTE_FLAG(PyCFunction_GET_FLAGS(func) & METH_STACKLESS); \
+ 	retval = (call); \
+ 	STACKLESS_ASSERT(); \
+ 	return retval; \
+ }
+ #else
+ #define WRAP_RETURN(call) return (call)
+ #endif
+ 
  PyObject *
  PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
  {
+ #ifdef STACKLESS
+ 	STACKLESS_GETARG();
+ #endif
  	PyCFunctionObject* f = (PyCFunctionObject*)func;
  	PyCFunction meth = PyCFunction_GET_FUNCTION(func);
***************
*** 65,68 ****
--- 85,89 ----
  	int size = PyTuple_GET_SIZE(arg);
  
+ <<<<<<< ../../2.2/src/./Objects/methodobject.c
  	if (flags & METH_KEYWORDS) {
  		return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
***************
*** 76,82 ****
--- 97,120 ----
  
  	switch (flags) {
+ =======
+ #ifdef STACKLESS
+ 	switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_STACKLESS)) {
+ #else
+ 	switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC)) {
+ #endif
+ >>>>>>> ././Objects/methodobject.c
  	case METH_VARARGS:
+ <<<<<<< ../../2.2/src/./Objects/methodobject.c
  		return (*meth)(self, arg);
+ =======
+ 		if (kw == NULL || PyDict_Size(kw) == 0)
+ 			WRAP_RETURN( (*meth)(self, arg) );
+ 		break;
+ 	case METH_VARARGS | METH_KEYWORDS:
+ 	case METH_OLDARGS | METH_KEYWORDS:
+ 		WRAP_RETURN( (*(PyCFunctionWithKeywords)meth)(self, arg, kw) );
+ >>>>>>> ././Objects/methodobject.c
  	case METH_NOARGS:
+ <<<<<<< ../../2.2/src/./Objects/methodobject.c
  		if (size == 0)
  			return (*meth)(self, NULL);
***************
*** 85,89 ****
--- 123,140 ----
  			     f->m_ml->ml_name, size);
  		return NULL;
+ =======
+ 		if (kw == NULL || PyDict_Size(kw) == 0) {
+ 			size = PyTuple_GET_SIZE(arg);
+ 			if (size == 0)
+ 				WRAP_RETURN( (*meth)(self, NULL) );
+ 			PyErr_Format(PyExc_TypeError,
+ 			    "%.200s() takes no arguments (%d given)",
+ 			    f->m_ml->ml_name, size);
+ 			return NULL;
+ 		}
+ 		break;
+ >>>>>>> ././Objects/methodobject.c
  	case METH_O:
+ <<<<<<< ../../2.2/src/./Objects/methodobject.c
  		if (size == 1)
  			return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
***************
*** 92,97 ****
--- 143,161 ----
  			     f->m_ml->ml_name, size);
  		return NULL;
+ =======
+ 		if (kw == NULL || PyDict_Size(kw) == 0) {
+ 			size = PyTuple_GET_SIZE(arg);
+ 			if (size == 1)
+ 				WRAP_RETURN( (*meth)(self, PyTuple_GET_ITEM(arg, 0)) );
+ 			PyErr_Format(PyExc_TypeError,
+ 			    "%.200s() takes exactly one argument (%d given)",
+ 			    f->m_ml->ml_name, size);
+ 			return NULL;
+ 		}
+ 		break;
+ >>>>>>> ././Objects/methodobject.c
  	case METH_OLDARGS:
  		/* the really old style */
+ <<<<<<< ../../2.2/src/./Objects/methodobject.c
  		if (size == 1)
  			arg = PyTuple_GET_ITEM(arg, 0);
***************
*** 99,102 ****
--- 163,177 ----
  			arg = NULL;
  		return (*meth)(self, arg);
+ =======
+ 		if (kw == NULL || PyDict_Size(kw) == 0) {
+ 			size = PyTuple_GET_SIZE(arg);
+ 			if (size == 1)
+ 				arg = PyTuple_GET_ITEM(arg, 0);
+ 			else if (size == 0)
+ 				arg = NULL;
+ 			WRAP_RETURN( (*meth)(self, arg) );
+ 		}
+ 		break;
+ >>>>>>> ././Objects/methodobject.c
  	default:
  		/* should never get here ??? */
***************
*** 232,236 ****
--- 307,320 ----
  	0,					/* tp_setattro */
  	0,					/* tp_as_buffer */
+ <<<<<<< ../../2.2/src/./Objects/methodobject.c
  	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+ =======
+ #ifdef STACKLESS
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ 		Py_TPFLAGS_HAVE_STACKLESS_CALL, /* tp_flags */
+ #else
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
+ #endif
+ >>>>>>> ././Objects/methodobject.c
   	0,					/* tp_doc */
   	(traverseproc)meth_traverse,		/* tp_traverse */

Index: object.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.2/src/Objects/object.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** object.c	1 May 2004 00:44:35 -0000	1.4
--- object.c	1 May 2004 01:21:10 -0000	1.5
***************
*** 23,26 ****
--- 23,72 ----
     Do not call them otherwise, they do not initialize the object! */
  
+ <<<<<<< ../../2.2/src/./Objects/object.c
+ =======
+ #ifdef Py_TRACE_REFS
+ /* Head of circular doubly-linked list of all objects.  These are linked
+  * together via the _ob_prev and _ob_next members of a PyObject, which
+  * exist only in a Py_TRACE_REFS build.
+  */
+ static PyObject refchain = {&refchain, &refchain};
+ 
+ #ifdef STACKLESS
+ /* track refcount problems down */
+ PyObject *_Py_RefChain = &refchain;
+ #endif
+ 
+ /* Insert op at the front of the list of all objects.  If force is true,
+  * op is added even if _ob_prev and _ob_next are non-NULL already.  If
+  * force is false amd _ob_prev or _ob_next are non-NULL, do nothing.
+  * force should be true if and only if op points to freshly allocated,
+  * uninitialized memory, or you've unlinked op from the list and are
+  * relinking it into the front.
+  * Note that objects are normally added to the list via _Py_NewReference,
+  * which is called by PyObject_Init.  Not all objects are initialized that
+  * way, though; exceptions include statically allocated type objects, and
+  * statically allocated singletons (like Py_True and Py_None).
+  */
+ void
+ _Py_AddToAllObjects(PyObject *op, int force)
+ {
+ #ifdef  Py_DEBUG
+ 	if (!force) {
+ 		/* If it's initialized memory, op must be in or out of
+ 		 * the list unambiguously.
+ 		 */
+ 		assert((op->_ob_prev == NULL) == (op->_ob_next == NULL));
+ 	}
+ #endif
+ 	if (force || op->_ob_prev == NULL) {
+ 		op->_ob_next = refchain._ob_next;
+ 		op->_ob_prev = &refchain;
+ 		refchain._ob_next->_ob_prev = op;
+ 		refchain._ob_next = op;
+ 	}
+ }
+ #endif	/* Py_TRACE_REFS */
+ 
+ >>>>>>> ././Objects/object.c
  #ifdef COUNT_ALLOCS
  static PyTypeObject *type_list;

Index: rangeobject.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.2/src/Objects/rangeobject.c,v
retrieving revision 1.1.1.3
retrieving revision 1.2
diff -C2 -d -r1.1.1.3 -r1.2
*** rangeobject.c	15 Oct 2002 22:26:33 -0000	1.1.1.3
--- rangeobject.c	1 May 2004 01:21:10 -0000	1.2
***************
*** 204,210 ****
--- 204,219 ----
  		return r1->len - r2->len;
  
+ <<<<<<< ../../2.2/src/./Objects/rangeobject.c
  	else
  		return r1->reps - r2->reps;
  }
+ =======
+ #ifdef STACKLESS
+ PyTypeObject PyRangeIter_Type;
+ #define Pyrangeiter_Type PyRangeIter_Type
+ #else
+ static PyTypeObject Pyrangeiter_Type;
+ #endif
+ >>>>>>> ././Objects/rangeobject.c
  
  static PyObject *
***************
*** 304,307 ****
--- 313,317 ----
  }
  
+ <<<<<<< ../../2.2/src/./Objects/rangeobject.c
  static PySequenceMethods range_as_sequence = {
  	(inquiry)range_length,	/*sq_length*/
***************
*** 316,319 ****
--- 326,336 ----
  
  PyTypeObject PyRange_Type = {
+ =======
+ #ifdef STACKLESS
+ PyTypeObject PyRangeIter_Type = {
+ #else
+ static PyTypeObject Pyrangeiter_Type = {
+ #endif
+ >>>>>>> ././Objects/rangeobject.c
  	PyObject_HEAD_INIT(&PyType_Type)
  	0,			/* Number of items for varobject */

Index: typeobject.c
===================================================================
RCS file: /home/cvs/slpdev/src/2.2/src/Objects/typeobject.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** typeobject.c	1 May 2004 00:44:35 -0000	1.6
--- typeobject.c	1 May 2004 01:21:10 -0000	1.7
***************
*** 4,7 ****
--- 4,8 ----
  #include "Python.h"
  #include "structmember.h"
+ #include "core/stackless_impl.h"
  
  #include <ctype.h>
***************
*** 502,506 ****
  	}
  	else {
! 		/* a is not completely initilized yet; follow tp_base */
  		do {
  			if (a == b)
--- 503,507 ----
  	}
  	else {
! 		/* a is not completely initialized yet; follow tp_base */
  		do {
  			if (a == b)
***************
*** 564,567 ****
--- 565,569 ----
  call_method(PyObject *o, char *name, PyObject **nameobj, char *format, ...)
  {
+ 	STACKLESS_GETARG();
  	va_list va;
  	PyObject *args, *func = 0, *retval;
***************
*** 587,591 ****
--- 589,595 ----
  
  	assert(PyTuple_Check(args));
+ 	STACKLESS_PROMOTE_ALL();
  	retval = PyObject_Call(func, args, NULL);
+ 	STACKLESS_ASSERT();
  
  	Py_DECREF(args);
***************
*** 600,603 ****
--- 604,608 ----
  call_maybe(PyObject *o, char *name, PyObject **nameobj, char *format, ...)
  {
+ 	STACKLESS_GETARG();
  	va_list va;
  	PyObject *args, *func = 0, *retval;
***************
*** 625,629 ****
--- 630,636 ----
  
  	assert(PyTuple_Check(args));
+ 	STACKLESS_PROMOTE_ALL();
  	retval = PyObject_Call(func, args, NULL);
+ 	STACKLESS_ASSERT();
  
  	Py_DECREF(args);
***************
*** 1073,1077 ****
--- 1080,1089 ----
  			return NULL;
  		nslots = PyTuple_GET_SIZE(slots);
+ #ifdef STACKLESS
+ 		if (nslots > 0 && base->tp_itemsize != 0 && !PyType_Check(base)) {
+ 			/* for the special case of meta types, allow slots */
+ #else
  		if (nslots > 0 && base->tp_itemsize != 0) {
+ #endif
  			PyErr_Format(PyExc_TypeError,
  				     "nonempty __slots__ "
***************
*** 3902,3907 ****
--- 3914,3925 ----
  	TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc,
  	       "x.__iter__() <==> iter(x)"),
+ #ifdef STACKLESS
+ 	FLSLOT("next", tp_iternext, slot_tp_iternext, wrap_next,
+ 	       "x.next() -> the next value, or raise StopIteration",
+ 		   PyWrapperFlag_STACKLESS),
+ #else
  	TPSLOT("next", tp_iternext, slot_tp_iternext, wrap_next,
  	       "x.next() -> the next value, or raise StopIteration"),
+ #endif
  	TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get,
  	       "descr.__get__(obj[, type]) -> value"),


_______________________________________________
Stackless-checkins mailing list
Stackless-checkins at stackless.com
http://www.stackless.com/mailman/listinfo/stackless-checkins



More information about the Stackless-checkins mailing list