Change log and history

990513
Sam Rushing brings "stackless Python" up in python-dev.

990516
Sam comes up with some call/cc stuff in C.
A first brute force attempt with stack juggling.

CT 990518
After some testing with the C stuff, I boldly claimed
"""I have to remove the hardware stack copying now.
Will try to create a non-recursive version of the interpreter."""
but I didn't know how hard this would be.

CT 990522
Figured out how to make stackless extensions. Stackless
map will use its own frame. In other words, extensions
are either tail recursive or they need a callback.

CT 990606
Posted a first preview to python-dev. Already called v.0.2
since I did a redesign of crucial sematics.

CT 990612
Released version 0.2 and some documentation to the newsgroup.


CT 990620
Version 0.3 is in progress.
It *will* have to change, since now it will have to stand
true continuations, but without building them in.

Slight modification and correction of map_nr, replaces map now.
Old map is available as map_old.

Minor changes due to Sam Rushing, for gcc compatibility.

Changed the frame refcount policy.
The frame chain contained the inherent promise that every
frame would be freed by the interpreter which owned it.
For that reason, every frame in the back chain had a refcount
of two.
With stackless Python, we need to change this. Due to its
flexibility, there is no longer the promise that a frame
chain will be unwound by eval_code.
New policy:
Frames do no longer increase the refcount for their f_back pointer.
All execute functions now have to incref the f_back frame,
before they release the current frame.

CT 990621
Realized that the field f_stackpointer must always be
correct, also on normal return. Reason: Frames can be
revived by continuations, which means the stackpointer
is used to free objects before begin reset.

Corrected map to add a reference to its args.

CT 990623
Changed frame deallocation to be iterative. Frames are
deallocated one after the other.

CT 990624
Exposed almost all of the frame fields as read-only
integer attributes for debugging purposes.

A hairy bug showed up finally when trying to build
continuations. In eval_code2_loop, different strategies
are used to pass parameters. In one case, I had to
adjust the f_stackpointer field, after parameters were
popped into a tuple.

CT 990625
Not abusing f_signature as a temporary register any longer.
Changed it from void* to char** to create incompatibility
to existing extensions which must change.
The new field f_temp_result holds temporary results now.
This is a PyObject, but is *not* refcounted.

CT990627
Added a f_callguard function pointer to frames. This
is executed by eval_code whenever a new frame is
about to be called. Reason: In order to make continuations
always use the recent stack state, we need to be able
to monitor calls. This is an optional field which
costs nearly no runtime penalty for normal programs.

CT990628
Added a stackless apply. Totally simple.

CT990630
Added PyFrame_HoldReference. Simplifies to put more
than one object to f_hold_ref.
Added code to free stack entries in frame_dealloc.
On an unusual return, frames might still hold values
in the stack.

CT990708
Turned the for-loop index into a PyLoopIndex_Object
which is a mutable int. Makes useful loop behavior
when the stack is shared by more than one continuation
*and* it is a little faster, in fact.
Tailored after Marc Lemburg's counterobject, but much
more lightweight.
Added a hook to frameobject, to hook additional Fini
methods. Needed for the loopindex cache, not spoiling
python run with this.

CT990709
Thinking hard about frame compatibility issues, since
I'm about to publish this release, with the 
continuations extension. What does frame compatibility
mean, exactly? Think of __init__ which does an extra
check if the result is None. This creates a recursive
call, which I think is fine so. But it should be
allowed to split a frame off which is meant to run later.
Other scenario: Two recursive calls in sequence can give
two frames with the same signature, but they aren't 
compatible since we don't know which condition was
on the C stack and why. Somehow I need to keep track
of which dispatcher created which frame, and wether
the dispatcher is still alive or not. So the old
f_signature field is gone, and will be replaced
by a f_dispatcher as a true PyObject. I guess, a dead
dispatcher will inherit its frames to his caller,
but this can be figured out later. Hope this is no
serious slowdown.

CT990710
It works, it's fine, will perhaps ship it today.

CT990711
Realized that the callguard field is crucial to
do the right thing in cases where we see nested
dispatchers and want to do frame push back for
continuations. It does not work when an eval_code
is sitting on a frame, calling a function which
isn't aware of the unwind token. It will continue
to run the frame which is already a continuation
frame.
The way out (and this makes things finally very
much cleaner and easier): The f_callgate function
does all necessary pushback when it is necessary,
not before. It will only happen for frames with a
refcount of more than one.
For that reason, delivery is again delayed, and
we allow the callguard to return a -42 which causes
another unwind action. Phew, that's it I think.

CT990713
Minor bug in apply, found by Michael Hudson.
	if (retval == Py_UnwindToken) {
was missing a "=" :-(
Had also to remove a "static" for a function again.

CT990714
Added proper exception output to PyRun_SimpleFile,
which had to have its own PyErr_Print handling in the
unwind case. Problem found by Markus Lauer.

CT990722
Moved the check for callguard requests inside the
main interpreter loop. This appeared to be expensive
at first sight. But the proper place was to extend the
already things_to_do query. The extra query if f->callguard
is non-zero took no measurable extra time. Everything
else disturbed VC++' optimization reasonably (one or
two percent pystone loss :-)

This should have been the last crucial change to the
Python kernel. Continuations should be safe by this!

CT991026
Found a bug in the dispatcher chain when tracing was
enabled. In the context of a trace, the frame chain
has a frame which has not seen any dispatcher yet.
Changed the dispatcher initialization to always
find a valid dispatcher chain.

CT991030
Another small bug: dispatcher_sentinel must have
a NULL d_back link or it will not stand PythonWin browsing.

CT991120
Had to take care of exception propagation through
continuations. WANTS_RETURN_VALUE is now propagated
through the f_back chain if an exception is due,
and it works great with continuations.
Removed a minor bug in builtin_map_nr which complained
about missing builtins. Now uses PyEval_GetGlobals().
PyFrame_New leaves a KeyError after failing a lookup.
Probably a Python bug.

CT991205
A couple of changes done to the frame structure: New fields,
a callback fromframe disposal.

CT991206
Minor bug in apply_nr.

CT991207 f_temp_val should not be decref'd on disposal
since it is meant to be transient. For continuations that
means to use this field as necessary and never having
to think about cleanup.

CT991215 extracted SPC from standard Python dist and made
a stand-alone tree which overrides certain standard modules.

CT2k0102 Merged my speedup patches for Win32 into SLP.
They originated in some work of spring '99. With this patch,
SLP outperforms standard Python for pystone.

CT2k0120 Squeezed the hell out of ceval. SLP is now 3
to 4.5 percent faster, depending on the machine layout.

Release as Stackless Python 1.0 !

CT2k0123 Small changes and cleanup of ceval.c for
non-Windows platforms. Problems were reported by
Jeff Collins. Split the distribution into source and
build, made a webpage, built an installer.

CT2k0129 Bug fix in stackless map: reset statusflags
when map catches an indexerrors. SLP now makes the
standard tests.

CT2k0131 new trashcan.c avoids crashes when large
structures are deallocated. At the moment this eats
about 5% of PyStone, probably loss of locality.
Regaining this would need to change 5 modules, so
maybe later.
Bug fix in END_FINALLY.

CT2k0220 Bug fix in the inner loop protection:
Unwinding must be done without an expected value.

CT2k0218 Trashcan is optimized as a macro.
SLP is now faster than ever before, about 10% above standard.
Dispatcher objects are now gone

CT2k0305 Microthread support is there!

Trashcan has got two functions, to make the
macro shorter and debuggable. Also, this makes
it go into the dist. (whow:)
About to release version 1.1

CT2k0326 What a delay. I had to compress the huge
new unicode database, or it had made me unhappy.
As a final change, uthreads are now stopped in
the context of an exception.

CT2k0329 tiny bugfix. The PyFrame_LocalsToFast
problem with eval crept in again.
Version 1.1.1