Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updated some of the pylibs packages.

  • Loading branch information...
commit 8a48383f5260e243f7d8e0cbd56d0a316a798e40 1 parent dd543dc
@tav authored
Showing with 149 additions and 29,619 deletions.
  1. +0 −2  .gitignore
  2. +19 −16 BeautifulSoup.py
  3. +0 −148 daemon.py
  4. +0 −309 exception.py
  5. +0 −20 greenlet/LICENSE.txt
  6. +0 −1,279 greenlet/greenlet.c
  7. +0 −131 greenlet/greenlet.h
  8. +0 −66 greenlet/platform/switch_amd64_unix.h
  9. +0 −50 greenlet/platform/switch_arm32_gcc.h
  10. +0 −56 greenlet/platform/switch_mips_unix.h
  11. +0 −80 greenlet/platform/switch_ppc_macosx.h
  12. +0 −80 greenlet/platform/switch_ppc_unix.h
  13. +0 −54 greenlet/platform/switch_s390_unix.h
  14. +0 −85 greenlet/platform/switch_sparc_sun_gcc.h
  15. +0 −83 greenlet/platform/switch_x86_msvc.h
  16. +0 −81 greenlet/platform/switch_x86_unix.h
  17. +0 −25 greenlet/slp_platformselect.h
  18. +130 −41 ipaddr.py
  19. +0 −202 openid/LICENSE.txt
  20. +0 −55 openid/__init__.py
  21. +0 −555 openid/association.py
  22. +0 −6 openid/consumer/__init__.py
  23. +0 −1,901 openid/consumer/consumer.py
  24. +0 −470 openid/consumer/discover.py
  25. +0 −249 openid/consumer/html_parse.py
  26. +0 −220 openid/cryptutil.py
  27. +0 −42 openid/dh.py
  28. +0 −46 openid/extension.py
  29. +0 −5 openid/extensions/__init__.py
  30. +0 −774 openid/extensions/ax.py
  31. 0  openid/extensions/draft/__init__.py
  32. +0 −277 openid/extensions/draft/pape2.py
  33. +0 −473 openid/extensions/draft/pape5.py
  34. +0 −518 openid/extensions/sreg.py
  35. +0 −423 openid/fetchers.py
  36. +0 −123 openid/kvform.py
  37. +0 −631 openid/message.py
  38. +0 −190 openid/oidutil.py
  39. +0 −6 openid/server/__init__.py
  40. +0 −1,849 openid/server/server.py
  41. +0 −454 openid/server/trustroot.py
  42. +0 −7 openid/sreg.py
  43. +0 −8 openid/store/__init__.py
  44. +0 −426 openid/store/filestore.py
  45. +0 −197 openid/store/interface.py
  46. +0 −125 openid/store/memstore.py
  47. +0 −98 openid/store/nonce.py
  48. +0 −516 openid/store/sqlstore.py
  49. +0 −202 openid/urinorm.py
  50. +0 −29 openid/yadis/__init__.py
  51. +0 −133 openid/yadis/accept.py
  52. +0 −13 openid/yadis/constants.py
  53. +0 −135 openid/yadis/discover.py
  54. +0 −300 openid/yadis/etxrd.py
  55. +0 −200 openid/yadis/filters.py
  56. +0 −194 openid/yadis/manager.py
  57. +0 −197 openid/yadis/parsehtml.py
  58. +0 −54 openid/yadis/services.py
  59. +0 −168 openid/yadis/xri.py
  60. +0 −123 openid/yadis/xrires.py
  61. +0 −476 optcomplete.py
  62. +0 −312 optimise.py
  63. +0 −19 py/LICENSE.txt
  64. +0 −178 py/__init__.py
  65. +0 −2  py/__metainfo.py
  66. +0 −203 py/_builtin.py
  67. +0 −1  py/_cmdline/__init__.py
  68. +0 −47 py/_cmdline/pycleanup.py
  69. +0 −249 py/_cmdline/pyconvert_unittest.py
  70. +0 −94 py/_cmdline/pycountloc.py
  71. +0 −83 py/_cmdline/pylookup.py
  72. +0 −55 py/_cmdline/pysvnwcrevert.py
  73. +0 −5 py/_cmdline/pytest.py
  74. +0 −23 py/_cmdline/pywhich.py
  75. +0 −1  py/_code/__init__.py
  76. +0 −337 py/_code/_assertionnew.py
  77. +0 −558 py/_code/_assertionold.py
  78. +0 −75 py/_code/assertion.py
  79. +0 −768 py/_code/code.py
  80. +0 −62 py/_code/oldmagic.py
  81. +0 −6 py/_code/oldmagic2.py
  82. +0 −347 py/_code/source.py
  83. +0 −2  py/_compat/__init__.py
  84. +0 −5 py/_compat/dep_doctest.py
  85. +0 −4 py/_compat/dep_optparse.py
  86. +0 −5 py/_compat/dep_subprocess.py
  87. +0 −5 py/_compat/dep_textwrap.py
  88. +0 −83 py/_error.py
  89. +0 −1  py/_io/__init__.py
  90. +0 −344 py/_io/capture.py
  91. +0 −264 py/_io/terminalwriter.py
  92. +0 −2  py/_log/__init__.py
  93. +0 −186 py/_log/log.py
  94. +0 −76 py/_log/warning.py
  95. +0 −1  py/_path/__init__.py
  96. +0 −114 py/_path/cacheutil.py
  97. +0 −333 py/_path/common.py
  98. +0 −799 py/_path/local.py
  99. +0 −376 py/_path/svnurl.py
  100. +0 −1,231 py/_path/svnwc.py
  101. +0 −1  py/_plugin/__init__.py
  102. +0 −179 py/_plugin/hookspec.py
  103. +0 −97 py/_plugin/pytest__pytest.py
  104. +0 −31 py/_plugin/pytest_assertion.py
  105. +0 −281 py/_plugin/pytest_capture.py
  106. +0 −107 py/_plugin/pytest_default.py
  107. +0 −100 py/_plugin/pytest_doctest.py
  108. +0 −69 py/_plugin/pytest_genscript.py
  109. +0 −159 py/_plugin/pytest_helpconfig.py
  110. +0 −33 py/_plugin/pytest_hooklog.py
  111. +0 −156 py/_plugin/pytest_junitxml.py
  112. +0 −152 py/_plugin/pytest_mark.py
  113. +0 −142 py/_plugin/pytest_monkeypatch.py
  114. +0 −98 py/_plugin/pytest_nose.py
  115. +0 −83 py/_plugin/pytest_pastebin.py
  116. +0 −104 py/_plugin/pytest_pdb.py
  117. +0 −36 py/_plugin/pytest_pylint.py
  118. +0 −490 py/_plugin/pytest_pytester.py
  119. +0 −121 py/_plugin/pytest_recwarn.py
  120. +0 −429 py/_plugin/pytest_restdoc.py
  121. +0 −98 py/_plugin/pytest_resultlog.py
  122. +0 −253 py/_plugin/pytest_runner.py
  123. +0 −231 py/_plugin/pytest_skipping.py
  124. +0 −441 py/_plugin/pytest_terminal.py
  125. +0 −22 py/_plugin/pytest_tmpdir.py
  126. +0 −79 py/_plugin/pytest_unittest.py
  127. +0 −63 py/_plugin/standalonetemplate.py
  128. +0 −1  py/_process/__init__.py
  129. +0 −46 py/_process/cmdexec.py
  130. +0 −108 py/_process/forkedfunc.py
  131. +0 −23 py/_process/killproc.py
  132. +0 −18 py/_std.py
  133. +0 −1  py/_test/__init__.py
  134. +0 −24 py/_test/cmdline.py
  135. +0 −432 py/_test/collect.py
  136. +0 −291 py/_test/config.py
  137. +0 −109 py/_test/conftesthandle.py
  138. +0 −176 py/_test/funcargs.py
  139. +0 −136 py/_test/outcome.py
  140. +0 −112 py/_test/parseopt.py
  141. +0 −333 py/_test/pluginmanager.py
  142. +0 −370 py/_test/pycollect.py
  143. +0 −118 py/_test/session.py
  144. +0 −243 py/_xmlgen.py
  145. +0 −91 py/apipkg.py
Sorry, we could not display the entire diff because it was too big.
View
2  .gitignore
@@ -1,8 +1,6 @@
# specific files/directories
build
-keyspace.py
-keyspace_client.py
# hidden files/directories
View
35 BeautifulSoup.py
@@ -42,7 +42,7 @@
Here, have some legalese:
-Copyright (c) 2004-2009, Leonard Richardson
+Copyright (c) 2004-2010, Leonard Richardson
All rights reserved.
@@ -79,8 +79,8 @@
from __future__ import generators
__author__ = "Leonard Richardson (leonardr@segfault.org)"
-__version__ = "3.0.8"
-__copyright__ = "Copyright (c) 2004-2009 Leonard Richardson"
+__version__ = "3.2.0"
+__copyright__ = "Copyright (c) 2004-2010 Leonard Richardson"
__license__ = "New-style BSD"
from sgmllib import SGMLParser, SGMLParseError
@@ -335,18 +335,19 @@ def _findAll(self, name, attrs, text, limit, generator, **kwargs):
if isinstance(name, SoupStrainer):
strainer = name
- # Special case some findAll* searches
- # findAll*(True)
- elif not limit and name is True and not attrs and not kwargs:
- return [element for element in generator()
- if isinstance(element, Tag)]
-
- # findAll*('tag-name')
- elif not limit and isinstance(name, basestring) and not attrs \
- and not kwargs:
- return [element for element in generator()
- if isinstance(element, Tag) and element.name == name]
-
+ # (Possibly) special case some findAll*(...) searches
+ elif text is None and not limit and not attrs and not kwargs:
+ # findAll*(True)
+ if name is True:
+ return [element for element in generator()
+ if isinstance(element, Tag)]
+ # findAll*('tag-name')
+ elif isinstance(name, basestring):
+ return [element for element in generator()
+ if isinstance(element, Tag) and
+ element.name == name]
+ else:
+ strainer = SoupStrainer(name, attrs, text, **kwargs)
# Build a SoupStrainer
else:
strainer = SoupStrainer(name, attrs, text, **kwargs)
@@ -530,6 +531,8 @@ def __init__(self, parser, name, attrs=None, parent=None,
self.name = name
if attrs is None:
attrs = []
+ elif isinstance(attrs, dict):
+ attrs = attrs.items()
self.attrs = attrs
self.contents = []
self.setup(parent, previous)
@@ -1647,7 +1650,7 @@ class ICantBelieveItsBeautifulSoup(BeautifulSoup):
'cite', 'code', 'dfn', 'kbd', 'samp', 'strong', 'var', 'b',
'big')
- I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS = ('noscript')
+ I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS = ('noscript',)
NESTABLE_TAGS = buildTagMap([], BeautifulSoup.NESTABLE_TAGS,
I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS,
View
148 daemon.py
@@ -1,148 +0,0 @@
-# Changes to this file by The Ampify Authors are in the Public Domain.
-# See the Ampify UNLICENSE file for details.
-
-# Released into the Public Domain by Sander Marechal
-# http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
-
-import atexit
-import os
-import sys
-import time
-
-from os.path import isabs
-from signal import SIGTERM
-
-class Daemon(object):
- """
- A generic daemon class.
-
- Usage: subclass the Daemon class and override the run() method
- """
-
- def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
- self.stdin = stdin
- self.stdout = stdout
- self.stderr = stderr
- if not isabs(pidfile):
- raise RuntimeError("The pidfile path is not absolute: %s" % pidfile)
- self.pidfile = pidfile
-
- def daemonize(self):
- """
- do the UNIX double-fork magic, see Stevens' "Advanced
- Programming in the UNIX Environment" for details (ISBN 0201563177)
- http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
- """
- try:
- pid = os.fork()
- if pid > 0:
- # exit first parent
- sys.exit(0)
- except OSError, e:
- sys.stderr.write("ERROR: fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
- sys.exit(1)
-
- # decouple from parent environment
- os.chdir("/")
- os.setsid()
- os.umask(0)
-
- # do second fork
- try:
- pid = os.fork()
- if pid > 0:
- # exit from second parent
- sys.exit(0)
- except OSError, e:
- sys.stderr.write("ERROR: fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
- sys.exit(1)
-
- # redirect standard file descriptors
- sys.stdout.flush()
- sys.stderr.flush()
- si = file(self.stdin, 'r')
- so = file(self.stdout, 'a+')
- se = file(self.stderr, 'a+', 0)
- os.dup2(si.fileno(), sys.stdin.fileno())
- os.dup2(so.fileno(), sys.stdout.fileno())
- os.dup2(se.fileno(), sys.stderr.fileno())
-
- # write pidfile
- atexit.register(self.exithook)
- pid = str(os.getpid())
- file(self.pidfile,'w+').write("%s\n" % pid)
-
- def delpid(self):
- os.remove(self.pidfile)
-
- def start(self):
- """
- Start the daemon
- """
- # Check for a pidfile to see if the daemon already runs
- try:
- pf = file(self.pidfile,'r')
- pid = int(pf.read().strip())
- pf.close()
- except IOError:
- pid = None
-
- if pid:
- message = (
- "ERROR: PID file %s already exists.\n"
- "ERROR: The daemon might be already running.\n"
- )
- sys.stderr.write(message % self.pidfile)
- sys.exit(1)
-
- # Start the daemon
- self.daemonize()
- self.run()
-
- def stop(self):
- """
- Stop the daemon
- """
- # Get the pid from the pidfile
- try:
- pf = file(self.pidfile,'r')
- pid = int(pf.read().strip())
- pf.close()
- except IOError:
- pid = None
-
- if not pid:
- return
-
- # Try killing the daemon process
- try:
- while 1:
- os.kill(pid, SIGTERM)
- time.sleep(0.1)
- except OSError, err:
- err = str(err)
- if err.find("No such process") > 0:
- if os.path.exists(self.pidfile):
- os.remove(self.pidfile)
- else:
- print str(err)
- sys.exit(1)
-
- def restart(self):
- """
- Restart the daemon
- """
- self.stop()
- self.start()
-
- def run(self):
- """
- You should override this method when you subclass Daemon. It will be
- called after the process has been daemonized by start() or restart().
- """
-
- def exithook(self):
- """
- Override this method to add additional exit hooks in your subclass.
- """
- self.delpid()
View
309 exception.py
@@ -1,309 +0,0 @@
-# Changes to this file by The Ampify Authors are in the Public Domain.
-# See the Ampify UNLICENSE file for details.
-
-# This file was adapted from zope/exceptions/exceptionformatter.py in the Zope
-# repository and has the following License:
-
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-
-"""
-An exception formatter that shows traceback supplements and traceback info.
-
- >>> try:
- ... 1/0
- ... except:
- ... print print_exception()
- Traceback (most recent call last):
- Module pyutil.exception, line 2, in <module>
- 1/0
- ZeroDivisionError: integer division or modulo by zero
- <BLANKLINE>
-
- >>> try:
- ... 1/0
- ... except:
- ... print print_exception(stream=sys.stdout)
- Traceback (most recent call last):
- Module pyutil.exception, line 2, in <module>
- 1/0
- ZeroDivisionError: integer division or modulo by zero
- <BLANKLINE>
-
-Output could be optionally rendered in HTML too:
-
- >>> try: # doctest: +NORMALIZE_WHITESPACE
- ... 1/0
- ... except:
- ... print print_exception(as_html=True)
- <p>Traceback (most recent call last):
- <ul>
- <li> Module pyutil.exception, line 2, in &lt;module&gt;<br />
- 1/0</li>
- </ul>ZeroDivisionError: integer division or modulo by zero<br />
- </p>
-
-"""
-
-import sys
-import cgi
-import linecache
-import traceback
-
-# ------------------------------------------------------------------------------
-# some konstants
-# ------------------------------------------------------------------------------
-
-__metaclass__ = type
-
-DEBUG_EXCEPTION_FORMATTER = 1
-
-LIMIT = 200
-
-if hasattr(sys, 'tracebacklimit'):
- LIMIT = min(LIMIT, sys.tracebacklimit)
-
-# ------------------------------------------------------------------------------
-# the klasses that do the actual formatting
-# ------------------------------------------------------------------------------
-
-class TextExceptionFormatter:
-
- line_sep = '\n'
- show_revisions = 0
-
- def __init__(self, limit=None, with_filenames=False):
- self.limit = limit
- self.with_filenames = with_filenames
-
- def escape(self, s):
- return s
-
- def getPrefix(self):
- return 'Traceback (most recent call last):'
-
- def getLimit(self):
- limit = self.limit
- if limit is None:
- limit = getattr(sys, 'tracebacklimit', 200)
- return limit
-
- def formatSupplementLine(self, line):
- return ' - %s' % line
-
- def formatSourceURL(self, url):
- return [self.formatSupplementLine(url)]
-
- def formatSupplement(self, supplement, tb):
- result = []
- fmtLine = self.formatSupplementLine
-
- url = getattr(supplement, 'source_url', None)
- if url is not None:
- result.extend(self.formatSourceURL(url))
-
- line = getattr(supplement, 'line', 0)
- if line == -1:
- line = tb.tb_lineno
- col = getattr(supplement, 'column', -1)
- if line:
- if col is not None and col >= 0:
- result.append(fmtLine('Line %s, Column %s' % (
- line, col)))
- else:
- result.append(fmtLine('Line %s' % line))
- elif col is not None and col >= 0:
- result.append(fmtLine('Column %s' % col))
-
- expr = getattr(supplement, 'expression', None)
- if expr:
- result.append(fmtLine('Expression: %s' % expr))
-
- warnings = getattr(supplement, 'warnings', None)
- if warnings:
- for warning in warnings:
- result.append(fmtLine('Warning: %s' % warning))
-
- getInfo = getattr(supplement, 'getInfo', None)
- if getInfo is not None:
- try:
- extra = getInfo()
- if extra:
- extra = self.escape(extra)
- if self.line_sep != "\n":
- extra = extra.replace(" ", "&nbsp;")
- extra = extra.replace("\n", self.line_sep)
- result.append(extra)
- except:
- if DEBUG_EXCEPTION_FORMATTER:
- traceback.print_exc()
- # else just swallow the exception.
- return result
-
- def formatTracebackInfo(self, tbi):
- return self.formatSupplementLine('__traceback_info__: %s' % (tbi, ))
-
- def formatLine(self, tb):
- f = tb.tb_frame
- lineno = tb.tb_lineno
- co = f.f_code
- filename = co.co_filename
- name = co.co_name
- locals = f.f_locals
- globals = f.f_globals
-
- if self.with_filenames:
- s = ' File "%s", line %d' % (filename, lineno)
- else:
- modname = globals.get('__name__', filename)
- s = ' Module %s, line %d' % (modname, lineno)
-
- s = s + ', in %s' % name
-
- result = []
- result.append(self.escape(s))
-
- # Append the source line, if available
- line = linecache.getline(filename, lineno)
- if line:
- result.append(" " + self.escape(line.strip()))
-
- # Output a traceback supplement, if any.
- if '__traceback_supplement__' in locals:
- # Use the supplement defined in the function.
- tbs = locals['__traceback_supplement__']
- elif '__traceback_supplement__' in globals:
- # Use the supplement defined in the module.
- # This is used by Scripts (Python).
- tbs = globals['__traceback_supplement__']
- else:
- tbs = None
- if tbs is not None:
- factory = tbs[0]
- args = tbs[1:]
- try:
- supp = factory(*args)
- result.extend(self.formatSupplement(supp, tb))
- except:
- if DEBUG_EXCEPTION_FORMATTER:
- traceback.print_exc()
- # else just swallow the exception.
-
- try:
- tbi = locals.get('__traceback_info__', None)
- if tbi is not None:
- result.append(self.formatTracebackInfo(tbi))
- except:
- if DEBUG_EXCEPTION_FORMATTER:
- traceback.print_exc()
- # else just swallow the exception.
-
- return self.line_sep.join(result)
-
- def formatExceptionOnly(self, etype, value):
- result = ''.join(traceback.format_exception_only(etype, value))
- return result.replace('\n', self.line_sep)
-
- def formatLastLine(self, exc_line):
- return self.escape(exc_line)
-
- def formatException(self, etype, value, tb):
- # The next line provides a way to detect recursion.
- __exception_formatter__ = 1
- result = [self.getPrefix() + '\n']
- limit = self.getLimit()
- n = 0
- while tb is not None and (limit is None or n < limit):
- if tb.tb_frame.f_locals.get('__exception_formatter__'):
- # Stop recursion.
- result.append('(Recursive formatException() stopped)\n')
- break
- line = self.formatLine(tb)
- result.append(line + '\n')
- tb = tb.tb_next
- n = n + 1
- exc_line = self.formatExceptionOnly(etype, value)
- result.append(self.formatLastLine(exc_line))
- return result
-
-class HTMLExceptionFormatter(TextExceptionFormatter):
-
- line_sep = '<br />\r\n'
-
- def escape(self, s):
- return cgi.escape(s, 1)
-
- def getPrefix(self):
- return '<p>Traceback (most recent call last):\r\n<ul>'
-
- def formatSupplementLine(self, line):
- return '<b>%s</b>' % self.escape(str(line))
-
- def formatTracebackInfo(self, tbi):
- s = self.escape(str(tbi))
- s = s.replace('\n', self.line_sep)
- return '__traceback_info__: %s' % (s, )
-
- def formatLine(self, tb):
- line = TextExceptionFormatter.formatLine(self, tb)
- return '<li>%s</li>' % line
-
- def formatLastLine(self, exc_line):
- return '</ul>%s</p>' % self.escape(exc_line).replace(
- '&lt;br /&gt;',
- '<br />'
- )
-
-# ------------------------------------------------------------------------------
-# our kore function
-#-------------------------------------------------------------------------------
-
-def format_exception(
- type=None, value=None, traceback=None, limit=LIMIT, as_html=False,
- with_filenames=False
- ):
- """Format a stack trace and the exception information."""
-
- if not type:
- type, value, traceback = sys.exc_info()
-
- if as_html:
- formatter = HTMLExceptionFormatter(limit, with_filenames)
- else:
- formatter = TextExceptionFormatter(limit, with_filenames)
-
- return formatter.formatException(type, value, traceback)
-
-def html_format_exception(type=None, value=None, traceback=None, limit=LIMIT):
- """Format a stack trace and the exception information as HTML."""
-
- if not type:
- type, value, traceback = sys.exc_info()
-
- return HTMLExceptionFormatter(limit).formatException(
- type, value, traceback
- )
-
-def print_exception(
- type=None, value=None, traceback=None, limit=LIMIT, as_html=False,
- with_filenames=False, stream=None
- ):
- """Print the exception to the given `stream`."""
-
- info = format_exception(
- type, value, traceback, limit, as_html, with_filenames
- )
-
- if stream is None:
- return ''.join(info)
- else:
- for line in info:
- stream.write(line)
- return ''
View
20 greenlet/LICENSE.txt
@@ -1,20 +0,0 @@
-The code has been placed under the MIT License by the Authors.
-
-
-Original Authors
-----------------
-* Armin Rigo
-* Christian Tismer
-
-
-Contributors
-------------
-* Bob Ippolito
-* Donovan Preston
-* Gerd Woetzel
-* Gustavo Niemeyer
-* Hye-Shik Chang
-* Jared Kuolt
-* Kyle Ambroff
-* Marcin Bachry
-* Samual M. Rushing
View
1,279 greenlet/greenlet.c
@@ -1,1279 +0,0 @@
-/* vim:set noet ts=8 sw=8 : */
-
-#define GREENLET_MODULE
-
-#include "greenlet.h"
-#include "structmember.h"
-
-
-/* XXX major open bugs:
- XXX - no GC. Unfinished greenlets won't be deallocated if they
- XXX contain a cycle to themselves from anywhere in their frame stack.
-*/
-
-/***********************************************************
-
-A PyGreenlet is a range of C stack addresses that must be
-saved and restored in such a way that the full range of the
-stack contains valid data when we switch to it.
-
-Stack layout for a greenlet:
-
- | ^^^ |
- | older data |
- | |
- stack_stop . |_______________|
- . | |
- . | greenlet data |
- . | in stack |
- . * |_______________| . . _____________ stack_copy + stack_saved
- . | | | |
- . | data | |greenlet data|
- . | unrelated | | saved |
- . | to | | in heap |
- stack_start . | this | . . |_____________| stack_copy
- | greenlet |
- | |
- | newer data |
- | vvv |
-
-
-Note that a greenlet's stack data is typically partly at its correct
-place in the stack, and partly saved away in the heap, but always in
-the above configuration: two blocks, the more recent one in the heap
-and the older one still in the stack (either block may be empty).
-
-Greenlets are chained: each points to the previous greenlet, which is
-the one that owns the data currently in the C stack above my
-stack_stop. The currently running greenlet is the first element of
-this chain. The main (initial) greenlet is the last one. Greenlets
-whose stack is entirely in the heap can be skipped from the chain.
-
-The chain is not related to execution order, but only to the order
-in which bits of C stack happen to belong to greenlets at a particular
-point in time.
-
-The main greenlet doesn't have a stack_stop: it is responsible for the
-complete rest of the C stack, and we don't know where it begins. We
-use (char*) -1, the largest possible address.
-
-States:
- stack_stop == NULL && stack_start == NULL: did not start yet
- stack_stop != NULL && stack_start == NULL: already finished
- stack_stop != NULL && stack_start != NULL: active
-
-The running greenlet's stack_start is undefined but not NULL.
-
- ***********************************************************/
-
-/*** global state ***/
-
-/* In the presence of multithreading, this is a bit tricky:
-
- - ts_current always store a reference to a greenlet, but it is
- not really the current greenlet after a thread switch occurred.
-
- - each *running* greenlet uses its run_info field to know which
- thread it is attached to. A greenlet can only run in the thread
- where it was created. This run_info is a ref to tstate->dict.
-
- - the thread state dict is used to save and restore ts_current,
- using the dictionary key 'ts_curkey'.
-*/
-
-/* Python 2.3 support */
-#ifndef Py_VISIT
-#define Py_VISIT(o) \
- if (o) { \
- if ((err = visit((PyObject *)(o), arg))) { \
- return err; \
- } \
- }
-#endif /* !Py_VISIT */
-
-#ifndef Py_CLEAR
-#define Py_CLEAR(op) \
- do { \
- if (op) { \
- PyObject *tmp = (PyObject *)(op); \
- (op) = NULL; \
- Py_DECREF(tmp); \
- } \
- } while (0)
-#endif /* !Py_CLEAR */
-
-/* Python <= 2.5 support */
-#if PY_MAJOR_VERSION < 3
-#ifndef Py_REFCNT
-# define Py_REFCNT(ob) (((PyObject *) (ob))->ob_refcnt)
-#endif
-#ifndef Py_TYPE
-# define Py_TYPE(ob) (((PyObject *) (ob))->ob_type)
-#endif
-#endif
-
-extern PyTypeObject PyGreenlet_Type;
-
-/* The current greenlet in this thread state (holds a reference) */
-static PyGreenlet* ts_current = NULL;
-/* Holds a reference to the switching-from stack during the slp switch */
-static PyGreenlet* ts_origin = NULL;
-/* Holds a reference to the switching-to stack during the slp switch */
-static PyGreenlet* ts_target = NULL;
-/* NULL if error, otherwise args tuple to pass around during slp switch */
-static PyObject* ts_passaround_args = NULL;
-static PyObject* ts_passaround_kwargs = NULL;
-
-/***********************************************************/
-/* Thread-aware routines, switching global variables when needed */
-
-#define STATE_OK (ts_current->run_info == PyThreadState_GET()->dict \
- || !green_updatecurrent())
-
-static PyObject* ts_curkey;
-static PyObject* ts_delkey;
-static PyObject* PyExc_GreenletError;
-static PyObject* PyExc_GreenletExit;
-
-#undef GREENLET_USE_GC
-
-#ifdef GREENLET_USE_GC
-#define GREENLET_GC_FLAGS Py_TPFLAGS_HAVE_GC
-#define GREENLET_tp_alloc PyType_GenericAlloc
-#define GREENLET_tp_free PyObject_GC_Del
-#define GREENLET_tp_traverse green_traverse
-#define GREENLET_tp_clear green_clear
-#define GREENLET_tp_is_gc green_is_gc
-#else /* GREENLET_USE_GC */
-#define GREENLET_GC_FLAGS 0
-#define GREENLET_tp_alloc 0
-#define GREENLET_tp_free 0
-#define GREENLET_tp_traverse 0
-#define GREENLET_tp_clear 0
-#define GREENLET_tp_is_gc 0
-#endif /* !GREENLET_USE_GC */
-
-static PyGreenlet* green_create_main(void)
-{
- PyGreenlet* gmain;
- PyObject* dict = PyThreadState_GetDict();
- if (dict == NULL) {
- if (!PyErr_Occurred())
- PyErr_NoMemory();
- return NULL;
- }
-
- /* create the main greenlet for this thread */
- gmain = (PyGreenlet*) PyType_GenericAlloc(&PyGreenlet_Type, 0);
- if (gmain == NULL)
- return NULL;
- gmain->stack_start = (char*) 1;
- gmain->stack_stop = (char*) -1;
- gmain->run_info = dict;
- Py_INCREF(dict);
-#ifdef GREENLET_USE_GC
- printf("green_create_main %p\n", gmain);
-#endif
- return gmain;
-}
-
-static int green_updatecurrent(void)
-{
- PyThreadState* tstate;
- PyGreenlet* next;
- PyGreenlet* previous;
- PyObject* deleteme;
-
- /* save ts_current as the current greenlet of its own thread */
- previous = ts_current;
- if (PyDict_SetItem(previous->run_info, ts_curkey, (PyObject*) previous))
- return -1;
-
- /* get ts_current from the active tstate */
- tstate = PyThreadState_GET();
- if (tstate->dict && (next =
- (PyGreenlet*) PyDict_GetItem(tstate->dict, ts_curkey))) {
- /* found -- remove it, to avoid keeping a ref */
- Py_INCREF(next);
- if (PyDict_SetItem(tstate->dict, ts_curkey, Py_None))
- PyErr_Clear();
- }
- else {
- /* first time we see this tstate */
- next = green_create_main();
- if (next == NULL)
- return -1;
- }
- ts_current = next;
- Py_DECREF(previous);
- /* green_dealloc() cannot delete greenlets from other threads, so
- it stores them in the thread dict; delete them now. */
- deleteme = PyDict_GetItem(tstate->dict, ts_delkey);
- if (deleteme != NULL) {
- PyList_SetSlice(deleteme, 0, INT_MAX, NULL);
- }
- return 0;
-}
-
-static PyObject* green_statedict(PyGreenlet* g)
-{
- while (!PyGreenlet_STARTED(g))
- g = g->parent;
- return g->run_info;
-}
-
-/***********************************************************/
-
-static int g_save(PyGreenlet* g, char* stop)
-{
- /* Save more of g's stack into the heap -- at least up to 'stop'
-
- g->stack_stop |________|
- | |
- | __ stop . . . . .
- | | ==> . .
- |________| _______
- | | | |
- | | | |
- g->stack_start | | |_______| g->stack_copy
-
- */
- long sz1 = g->stack_saved;
- long sz2 = stop - g->stack_start;
- assert(g->stack_start != NULL);
- if (sz2 > sz1) {
- char* c = PyMem_Realloc(g->stack_copy, sz2);
- if (!c) {
- PyErr_NoMemory();
- return -1;
- }
- memcpy(c+sz1, g->stack_start+sz1, sz2-sz1);
- g->stack_copy = c;
- g->stack_saved = sz2;
- }
- return 0;
-}
-
-static void slp_restore_state(void)
-{
- PyGreenlet* g = ts_target;
-
- /* Restore the heap copy back into the C stack */
- if (g->stack_saved != 0) {
- memcpy(g->stack_start, g->stack_copy, g->stack_saved);
- PyMem_Free(g->stack_copy);
- g->stack_copy = NULL;
- g->stack_saved = 0;
- }
- if (ts_current->stack_stop == g->stack_stop)
- g->stack_prev = ts_current->stack_prev;
- else
- g->stack_prev = ts_current;
-}
-
-static int slp_save_state(char* stackref)
-{
- /* must free all the C stack up to target_stop */
- char* target_stop = ts_target->stack_stop;
- assert(ts_current->stack_saved == 0);
- if (ts_current->stack_start == NULL)
- ts_current = ts_current->stack_prev; /* not saved if dying */
- else
- ts_current->stack_start = stackref;
-
- while (ts_current->stack_stop < target_stop) {
- /* ts_current is entierely within the area to free */
- if (g_save(ts_current, ts_current->stack_stop))
- return -1; /* XXX */
- ts_current = ts_current->stack_prev;
- }
- if (ts_current != ts_target) {
- if (g_save(ts_current, target_stop))
- return -1; /* XXX */
- }
- return 0;
-}
-
-
-/*
- * the following macros are spliced into the OS/compiler
- * specific code, in order to simplify maintenance.
- */
-
-#define SLP_SAVE_STATE(stackref, stsizediff) \
- stackref += STACK_MAGIC; \
- if (slp_save_state((char*)stackref)) return -1; \
- if (!PyGreenlet_ACTIVE(ts_target)) return 1; \
- stsizediff = ts_target->stack_start - (char*)stackref
-
-#define SLP_RESTORE_STATE() \
- slp_restore_state()
-
-
-#define SLP_EVAL
-#include "slp_platformselect.h"
-
-#ifndef STACK_MAGIC
-#error "greenlet needs to be ported to this platform,\
- or teached how to detect your compiler properly."
-#endif /* !STACK_MAGIC */
-
-
-/* This is a trick to prevent the compiler from inlining or
- removing the frames */
-int (*_PyGreenlet_slp_switch) (void);
-int (*_PyGreenlet_switchstack) (void);
-void (*_PyGreenlet_initialstub) (void*);
-
-static int g_switchstack(void)
-{
- /* perform a stack switch according to some global variables
- that must be set before:
- - ts_current: current greenlet (holds a reference)
- - ts_target: greenlet to switch to
- - ts_passaround_args: NULL if PyErr_Occurred(),
- else a tuple of args sent to ts_target (holds a reference)
- - ts_passaround_kwargs: same as ts_passaround_args
- */
- int err;
- { /* save state */
- PyThreadState* tstate = PyThreadState_GET();
- ts_current->recursion_depth = tstate->recursion_depth;
- ts_current->top_frame = tstate->frame;
- }
- ts_origin = ts_current;
- err = _PyGreenlet_slp_switch();
- if (err < 0) { /* error */
- Py_XDECREF(ts_passaround_args);
- ts_passaround_args = NULL;
-
- Py_XDECREF(ts_passaround_kwargs);
- ts_passaround_kwargs = NULL;
- }
- else {
- PyThreadState* tstate = PyThreadState_GET();
- tstate->recursion_depth = ts_target->recursion_depth;
- tstate->frame = ts_target->top_frame;
- ts_target->top_frame = NULL;
- ts_current = ts_target;
- Py_INCREF(ts_target);
- Py_DECREF(ts_origin);
- }
- return err;
-}
-
-static PyObject *
-g_switch(PyGreenlet* target, PyObject* args, PyObject* kwargs)
-{
- /* _consumes_ a reference to the args tuple and kwargs dict,
- and return a new tuple reference */
-
- /* check ts_current */
- if (!STATE_OK) {
- Py_DECREF(args);
- Py_XDECREF(kwargs);
- return NULL;
- }
- if (green_statedict(target) != ts_current->run_info) {
- PyErr_SetString(PyExc_GreenletError,
- "cannot switch to a different thread");
- Py_DECREF(args);
- Py_XDECREF(kwargs);
- return NULL;
- }
-
- ts_passaround_args = args;
- ts_passaround_kwargs = kwargs;
-
- /* find the real target by ignoring dead greenlets,
- and if necessary starting a greenlet. */
- while (1) {
- if (PyGreenlet_ACTIVE(target)) {
- ts_target = target;
- _PyGreenlet_switchstack();
- break;
- }
- if (!PyGreenlet_STARTED(target)) {
- void* dummymarker;
- ts_target = target;
- _PyGreenlet_initialstub(&dummymarker);
- break;
- }
- target = target->parent;
- }
-
- /* We need to figure out what values to pass to the target greenlet
- based on the arguments that have been passed to greenlet.switch(). If
- switch() was just passed an arg tuple, then we'll just return that.
- If only keyword arguments were passed, then we'll pass the keyword
- argument dict. Otherwise, we'll create a tuple of (args, kwargs) and
- return both. */
- if (ts_passaround_kwargs == NULL)
- {
- return ts_passaround_args;
- }
- else if (PyDict_Size(ts_passaround_kwargs) == 0)
- {
- Py_DECREF(ts_passaround_kwargs);
- return ts_passaround_args;
- }
- else if (PySequence_Length(ts_passaround_args) == 0)
- {
- return ts_passaround_kwargs;
- }
- else
- {
- PyObject *tuple = PyTuple_New(2);
- PyTuple_SetItem(tuple, 0, ts_passaround_args);
- PyTuple_SetItem(tuple, 1, ts_passaround_kwargs);
- return tuple;
- }
-}
-
-static PyObject *
-g_handle_exit(PyObject *result)
-{
- if (result == NULL && PyErr_ExceptionMatches(PyExc_GreenletExit))
- {
- /* catch and ignore GreenletExit */
- PyObject *exc, *val, *tb;
- PyErr_Fetch(&exc, &val, &tb);
- if (val == NULL)
- {
- Py_INCREF(Py_None);
- val = Py_None;
- }
- result = val;
- Py_DECREF(exc);
- Py_XDECREF(tb);
- }
- if (result != NULL)
- {
- /* package the result into a 1-tuple */
- PyObject *r = result;
- result = PyTuple_New(1);
- if (result)
- {
- PyTuple_SET_ITEM(result, 0, r);
- }
- else
- {
- Py_DECREF(r);
- }
- }
- return result;
-}
-
-static void g_initialstub(void* mark)
-{
- int err;
- PyObject* o;
-
- /* ts_target.run is the object to call in the new greenlet */
- PyObject* run = PyObject_GetAttrString((PyObject*) ts_target, "run");
- if (run == NULL) {
- Py_XDECREF(ts_passaround_args);
- ts_passaround_args = NULL;
-
- Py_XDECREF(ts_passaround_kwargs);
- ts_passaround_kwargs = NULL;
- return;
- }
- /* now use run_info to store the statedict */
- o = ts_target->run_info;
- ts_target->run_info = green_statedict(ts_target->parent);
- Py_INCREF(ts_target->run_info);
- Py_XDECREF(o);
-
- /* start the greenlet */
- ts_target->stack_start = NULL;
- ts_target->stack_stop = (char*) mark;
- if (ts_current->stack_start == NULL) {
- /* ts_current is dying */
- ts_target->stack_prev = ts_current->stack_prev;
- }
- else {
- ts_target->stack_prev = ts_current;
- }
- ts_target->top_frame = NULL;
- ts_target->recursion_depth = PyThreadState_GET()->recursion_depth;
- err = _PyGreenlet_switchstack();
- /* returns twice!
- The 1st time with err=1: we are in the new greenlet
- The 2nd time with err=0: back in the caller's greenlet
- */
- if (err == 1) {
- /* in the new greenlet */
- PyObject* args;
- PyObject* kwargs;
- PyObject* result;
- PyGreenlet* ts_self = ts_current;
- ts_self->stack_start = (char*) 1; /* running */
-
- args = ts_passaround_args;
- kwargs = ts_passaround_kwargs;
- if (args == NULL) /* pending exception */
- result = NULL;
- else {
- /* call g.run(*args, **kwargs) */
- result = PyEval_CallObjectWithKeywords(
- run, args, kwargs);
- Py_DECREF(args);
- Py_XDECREF(kwargs);
- }
- Py_DECREF(run);
- result = g_handle_exit(result);
-
- /* jump back to parent */
- ts_self->stack_start = NULL; /* dead */
- g_switch(ts_self->parent, result, NULL);
- /* must not return from here! */
- PyErr_WriteUnraisable((PyObject *) ts_self);
- Py_FatalError("greenlets cannot continue");
- }
- /* back in the parent */
-}
-
-
-/***********************************************************/
-
-
-static PyObject* green_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyObject* o;
- if (!STATE_OK)
- return NULL;
-
- o = type->tp_alloc(type, 0);
- if (o != NULL) {
- Py_INCREF(ts_current);
- ((PyGreenlet*) o)->parent = ts_current;
- }
-#ifdef GREENLET_USE_GC
- printf("green_new %p\n", o);
-#endif
- return o;
-}
-
-static int green_setrun(PyGreenlet* self, PyObject* nparent, void* c);
-static int green_setparent(PyGreenlet* self, PyObject* nparent, void* c);
-
-static int green_init(PyGreenlet *self, PyObject *args, PyObject *kwargs)
-{
- PyObject *run = NULL;
- PyObject* nparent = NULL;
- static char *kwlist[] = {"run", "parent", 0};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO:green", kwlist,
- &run, &nparent))
- return -1;
-
- if (run != NULL) {
- if (green_setrun(self, run, NULL))
- return -1;
- }
- if (nparent != NULL)
- return green_setparent(self, nparent, NULL);
- return 0;
-}
-
-static int kill_greenlet(PyGreenlet* self)
-{
- /* Cannot raise an exception to kill the greenlet if
- it is not running in the same thread! */
-#ifdef GREENLET_USE_GC
- printf("kill_greenlet %p\n", self);
-#endif
- if (self->run_info == PyThreadState_GET()->dict) {
- /* The dying greenlet cannot be a parent of ts_current
- because the 'parent' field chain would hold a
- reference */
- PyObject* result;
- if (!STATE_OK) {
- return -1;
- }
- Py_INCREF(ts_current);
- self->parent = ts_current;
- /* Send the greenlet a GreenletExit exception. */
- PyErr_SetNone(PyExc_GreenletExit);
- result = g_switch(self, NULL, NULL);
- if (result == NULL)
- return -1;
- Py_DECREF(result);
- return 0;
- }
- else {
- /* Not the same thread! Temporarily save the greenlet
- into its thread's ts_delkey list. */
- PyObject* lst;
- lst = PyDict_GetItem(self->run_info, ts_delkey);
- if (lst == NULL) {
- lst = PyList_New(0);
- if (lst == NULL || PyDict_SetItem(self->run_info,
- ts_delkey, lst) < 0)
- return -1;
- }
- if (PyList_Append(lst, (PyObject*) self) < 0)
- return -1;
- if (!STATE_OK) /* to force ts_delkey to be reconsidered */
- return -1;
- return 0;
- }
-}
-
-#ifdef GREENLET_USE_GC
-static int
-green_traverse(PyGreenlet *so, visitproc visit, void *arg)
-{
- printf("green_traverse %p\n", so);
- Py_VISIT((PyObject*)so->run_info);
- Py_VISIT((PyObject*)so->parent);
- Py_VISIT((PyObject*)so->top_frame);
- Py_VISIT((PyObject*)so->stack_prev);
- Py_VISIT((PyObject*)so->parent);
- return 0;
-}
-
-static int green_is_gc(PyGreenlet* self)
-{
- int rval;
- rval = (self->stack_stop == ((char *)-1)) ? 0 : 1;
- printf("green_is_gc %p = %d\n", self, rval);
- return rval;
-}
-
-static int green_clear(PyGreenlet* self)
-{
- printf("green_clear %p run_info %p\n", self, self->run_info);
- if (PyGreenlet_ACTIVE(self))
- return kill_greenlet(self);
- return 0;
-}
-#endif
-
-static void green_dealloc(PyGreenlet* self)
-{
- PyObject *error_type, *error_value, *error_traceback;
-
-#ifdef GREENLET_USE_GC
- printf("green_dealloc %p\n", self);
- PyObject_GC_UnTrack((PyObject *)self);
- Py_TRASHCAN_SAFE_BEGIN(self);
-#endif /* GREENLET_USE_GC */
- Py_CLEAR(self->parent);
- if (PyGreenlet_ACTIVE(self)) {
- /* Hacks hacks hacks copied from instance_dealloc() */
- /* Temporarily resurrect the greenlet. */
- assert(Py_REFCNT(self) == 0);
- Py_REFCNT(self) = 1;
- /* Save the current exception, if any. */
- PyErr_Fetch(&error_type, &error_value, &error_traceback);
- if (kill_greenlet(self) < 0) {
- PyErr_WriteUnraisable((PyObject*) self);
- /* XXX what else should we do? */
- }
- /* Restore the saved exception. */
- PyErr_Restore(error_type, error_value, error_traceback);
- /* Undo the temporary resurrection; can't use DECREF here,
- * it would cause a recursive call.
- */
- assert(Py_REFCNT(self) > 0);
- --Py_REFCNT(self);
- if (Py_REFCNT(self) == 0 && PyGreenlet_ACTIVE(self)) {
- /* Not resurrected, but still not dead!
- XXX what else should we do? we complain. */
- PyObject* f = PySys_GetObject("stderr");
- if (f != NULL) {
- PyFile_WriteString("GreenletExit did not kill ",
- f);
- PyFile_WriteObject((PyObject*) self, f, 0);
- PyFile_WriteString("\n", f);
- }
- Py_INCREF(self); /* leak! */
- }
- if (Py_REFCNT(self) != 0) {
- /* Resurrected! */
- int refcnt = Py_REFCNT(self);
- _Py_NewReference((PyObject*) self);
-#ifdef GREENLET_USE_GC
- PyObject_GC_Track((PyObject *)self);
-#endif
- Py_REFCNT(self) = refcnt;
-#ifdef COUNT_ALLOCS
- --Py_TYPE(self)->tp_frees;
- --Py_TYPE(self)->tp_allocs;
-#endif /* COUNT_ALLOCS */
- goto green_dealloc_end;
- }
- }
- if (self->weakreflist != NULL)
- PyObject_ClearWeakRefs((PyObject *) self);
- Py_CLEAR(self->run_info);
- Py_TYPE(self)->tp_free((PyObject*) self);
-green_dealloc_end:
-#ifdef GREENLET_USE_GC
- Py_TRASHCAN_SAFE_END(self);
-#endif /* GREENLET_USE_GC */
- return;
-}
-
-static PyObject* single_result(PyObject* results)
-{
- if (results != NULL && PyTuple_Check(results) &&
- PyTuple_GET_SIZE(results) == 1) {
- PyObject *result = PyTuple_GET_ITEM(results, 0);
- Py_INCREF(result);
- Py_DECREF(results);
- return result;
- }
- else
- return results;
-}
-
-static PyObject *
-throw_greenlet(PyGreenlet *self, PyObject *typ, PyObject *val, PyObject *tb)
-{
- /* Note: _consumes_ a reference to typ, val, tb */
- PyObject *result = NULL;
- PyErr_Restore(typ, val, tb);
- if (PyGreenlet_STARTED(self) && !PyGreenlet_ACTIVE(self))
- {
- /* dead greenlet: turn GreenletExit into a regular return */
- result = g_handle_exit(result);
- }
- return single_result(g_switch(self, result, NULL));
-}
-
-PyDoc_STRVAR(green_switch_doc,
-"switch(*args, **kwargs)\n\
-\n\
-Switch execution to this greenlet.\n\
-\n\
-If this greenlet has never been run, then this greenlet\n\
-will be switched to using the body of self.run(*args, **kwargs).\n\
-\n\
-If the greenlet is active (has been run, but was switch()'ed\n\
-out before leaving its run function), then this greenlet will\n\
-be resumed and the return value to its switch call will be\n\
-None if no arguments are given, the given argument if one\n\
-argument is given, or the args tuple and keyword args dict if\n\
-multiple arguments are given.\n\
-\n\
-If the greenlet is dead, or is the current greenlet then this\n\
-function will simply return the arguments using the same rules as\n\
-above.");
-
-static PyObject* green_switch(
- PyGreenlet* self,
- PyObject* args,
- PyObject* kwargs)
-{
- Py_INCREF(args);
- Py_XINCREF(kwargs);
- return single_result(g_switch(self, args, kwargs));
-}
-
-/* Macros required to support Python < 2.6 for green_throw() */
-#ifndef PyExceptionClass_Check
-# define PyExceptionClass_Check PyClass_Check
-#endif
-#ifndef PyExceptionInstance_Check
-# define PyExceptionInstance_Check PyInstance_Check
-#endif
-#ifndef PyExceptionInstance_Class
-# define PyExceptionInstance_Class(x) \
- ((PyObject *) ((PyInstanceObject *)(x))->in_class)
-#endif
-
-PyDoc_STRVAR(green_throw_doc,
-"Switches execution to the greenlet ``g``, but immediately raises the\n"
-"given exception in ``g``. If no argument is provided, the exception\n"
-"defaults to ``greenlet.GreenletExit``. The normal exception\n"
-"propagation rules apply, as described above. Note that calling this\n"
-"method is almost equivalent to the following::\n"
-"\n"
-" def raiser():\n"
-" raise typ, val, tb\n"
-" g_raiser = greenlet(raiser, parent=g)\n"
-" g_raiser.switch()\n"
-"\n"
-"except that this trick does not work for the\n"
-"``greenlet.GreenletExit`` exception, which would not propagate\n"
-"from ``g_raiser`` to ``g``.\n");
-
-static PyObject *
-green_throw(PyGreenlet *self, PyObject *args)
-{
- PyObject *typ = PyExc_GreenletExit;
- PyObject *val = NULL;
- PyObject *tb = NULL;
-
- if (!PyArg_ParseTuple(args, "|OOO:throw", &typ, &val, &tb))
- {
- return NULL;
- }
-
- /* First, check the traceback argument, replacing None, with NULL */
- if (tb == Py_None)
- {
- tb = NULL;
- }
- else if (tb != NULL && !PyTraceBack_Check(tb))
- {
- PyErr_SetString(
- PyExc_TypeError,
- "throw() third argument must be a traceback object");
- return NULL;
- }
-
- Py_INCREF(typ);
- Py_XINCREF(val);
- Py_XINCREF(tb);
-
- if (PyExceptionClass_Check(typ))
- {
- PyErr_NormalizeException(&typ, &val, &tb);
- }
- else if (PyExceptionInstance_Check(typ))
- {
- /* Raising an instance. The value should be a dummy. */
- if (val && val != Py_None)
- {
- PyErr_SetString(
- PyExc_TypeError,
- "instance exception may not have a separate value");
- goto failed_throw;
- }
- else
- {
- /* Normalize to raise <class>, <instance> */
- Py_XDECREF(val);
- val = typ;
- typ = PyExceptionInstance_Class(typ);
- Py_INCREF(typ);
- }
- }
- else
- {
- /* Not something you can raise. throw() fails. */
- PyErr_Format(
- PyExc_TypeError,
- "exceptions must be classes, or instances, not %s",
- Py_TYPE(typ)->tp_name);
- goto failed_throw;
- }
-
- return throw_greenlet(self, typ, val, tb);
-
- failed_throw:
- /* Didn't use our arguments, so restore their original refcounts */
- Py_DECREF(typ);
- Py_XDECREF(val);
- Py_XDECREF(tb);
- return NULL;
-}
-
-static int green_bool(PyGreenlet* self)
-{
- return PyGreenlet_ACTIVE(self);
-}
-
-static PyObject* green_getdead(PyGreenlet* self, void* c)
-{
- PyObject* res;
- if (PyGreenlet_ACTIVE(self) || !PyGreenlet_STARTED(self))
- res = Py_False;
- else
- res = Py_True;
- Py_INCREF(res);
- return res;
-}
-
-static PyObject* green_getrun(PyGreenlet* self, void* c)
-{
- if (PyGreenlet_STARTED(self) || self->run_info == NULL) {
- PyErr_SetString(PyExc_AttributeError, "run");
- return NULL;
- }
- Py_INCREF(self->run_info);
- return self->run_info;
-}
-
-static int green_setrun(PyGreenlet* self, PyObject* nrun, void* c)
-{
- PyObject* o;
- if (PyGreenlet_STARTED(self)) {
- PyErr_SetString(PyExc_AttributeError,
- "run cannot be set "
- "after the start of the greenlet");
- return -1;
- }
- o = self->run_info;
- self->run_info = nrun;
- Py_XINCREF(nrun);
- Py_XDECREF(o);
- return 0;
-}
-
-static PyObject* green_getparent(PyGreenlet* self, void* c)
-{
- PyObject* result = self->parent ? (PyObject*) self->parent : Py_None;
- Py_INCREF(result);
- return result;
-}
-
-static int green_setparent(PyGreenlet* self, PyObject* nparent, void* c)
-{
- PyGreenlet* p;
- if (nparent == NULL) {
- PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
- return -1;
- }
- if (!PyGreenlet_Check(nparent)) {
- PyErr_SetString(PyExc_TypeError, "parent must be a greenlet");
- return -1;
- }
- for (p=(PyGreenlet*) nparent; p; p=p->parent) {
- if (p == self) {
- PyErr_SetString(PyExc_ValueError, "cyclic parent chain");
- return -1;
- }
- }
- p = self->parent;
- self->parent = (PyGreenlet*) nparent;
- Py_INCREF(nparent);
- Py_XDECREF(p);
- return 0;
-}
-
-static PyObject* green_getframe(PyGreenlet* self, void* c)
-{
- PyObject* result = self->top_frame ? (PyObject*) self->top_frame : Py_None;
- Py_INCREF(result);
- return result;
-}
-
-
-/*****************************************************************************
- * C interface
- *
- * These are exported using the CObject API
- */
-
-static PyGreenlet *
-PyGreenlet_GetCurrent(void)
-{
- if (!STATE_OK) {
- return NULL;
- }
- Py_INCREF(ts_current);
- return ts_current;
-}
-
-static int
-PyGreenlet_SetParent(PyGreenlet *g, PyGreenlet *nparent)
-{
- if (!STATE_OK) {
- return -1;
- }
-
- if (!PyGreenlet_Check(g)) {
- PyErr_SetString(PyExc_TypeError, "parent must be a greenlet");
- return -1;
- }
-
- return green_setparent((PyGreenlet*) g, (PyObject *) nparent, NULL);
-}
-
-static PyGreenlet *
-PyGreenlet_New(PyObject *run, PyGreenlet *parent)
-{
- PyGreenlet* g = NULL;
-
- g = (PyGreenlet *) PyType_GenericAlloc(&PyGreenlet_Type, 0);
- if (g == NULL) {
- return NULL;
- }
-
- if (run != NULL) {
- Py_INCREF(run);
- g->run_info = run;
- }
- if (parent == NULL) {
- parent = PyGreenlet_GetCurrent();
- }
- PyGreenlet_SetParent(g, parent);
- return g;
-}
-
-static PyObject *
-PyGreenlet_Switch(PyGreenlet *g, PyObject *args, PyObject *kwargs)
-{
- PyGreenlet *self = (PyGreenlet *) g;
-
- if (!PyGreenlet_Check(self)) {
- PyErr_BadArgument();
- return NULL;
- }
-
- if (args == NULL) {
- args = Py_BuildValue("()");
- }
- else {
- Py_INCREF(args);
- }
-
- if (kwargs != NULL && PyDict_Check(kwargs)) {
- Py_INCREF(kwargs);
- }
- else {
- kwargs = NULL;
- }
-
- return single_result(g_switch(self, args, kwargs));
-}
-
-static PyObject *
-PyGreenlet_Throw(PyGreenlet *self, PyObject *typ, PyObject *val, PyObject *tb)
-{
- if (!PyGreenlet_Check(self)) {
- PyErr_BadArgument();
- return NULL;
- }
- return throw_greenlet(self, typ, val, tb);
-}
-
-/** End C API ****************************************************************/
-
-static PyMethodDef green_methods[] = {
- {"switch", (PyCFunction)green_switch,
- METH_VARARGS | METH_KEYWORDS, green_switch_doc},
- {"throw", (PyCFunction)green_throw, METH_VARARGS, green_throw_doc},
- {NULL, NULL} /* sentinel */
-};
-
-static PyGetSetDef green_getsets[] = {
- {"run", (getter)green_getrun,
- (setter)green_setrun, /*XXX*/ NULL},
- {"parent", (getter)green_getparent,
- (setter)green_setparent, /*XXX*/ NULL},
- {"gr_frame", (getter)green_getframe,
- NULL, /*XXX*/ NULL},
- {"dead", (getter)green_getdead,
- NULL, /*XXX*/ NULL},
- {NULL}
-};
-
-static PyNumberMethods green_as_number = {
- NULL, /* nb_add */
- NULL, /* nb_subtract */
- NULL, /* nb_multiply */
-#if PY_MAJOR_VERSION < 3
- NULL, /* nb_divide */
-#endif
- NULL, /* nb_remainder */
- NULL, /* nb_divmod */
- NULL, /* nb_power */
- NULL, /* nb_negative */
- NULL, /* nb_positive */
- NULL, /* nb_absolute */
- (inquiry)green_bool, /* nb_bool */
-};
-
-
-PyTypeObject PyGreenlet_Type = {
-#if PY_MAJOR_VERSION >= 3
- PyVarObject_HEAD_INIT(NULL, 0)
-#else
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
-#endif
- "greenlet.greenlet", /* tp_name */
- sizeof(PyGreenlet), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)green_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- &green_as_number, /* tp_as _number*/
- 0, /* tp_as _sequence*/
- 0, /* tp_as _mapping*/
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | GREENLET_GC_FLAGS, /* tp_flags */
- "greenlet(run=None, parent=None) -> greenlet\n\n"
- "Creates a new greenlet object (without running it).\n\n"
- " - *run* -- The callable to invoke.\n"
- " - *parent* -- The parent greenlet. The default is the current "
- "greenlet.", /* tp_doc */
- (traverseproc)GREENLET_tp_traverse, /* tp_traverse */
- (inquiry)GREENLET_tp_clear, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(PyGreenlet, weakreflist), /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- green_methods, /* tp_methods */
- 0, /* tp_members */
- green_getsets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)green_init, /* tp_init */
- GREENLET_tp_alloc, /* tp_alloc */
- green_new, /* tp_new */
- GREENLET_tp_free, /* tp_free */
- (inquiry)GREENLET_tp_is_gc, /* tp_is_gc */
-};
-/* XXX need GC support */
-
-static PyObject* mod_getcurrent(PyObject* self)
-{
- if (!STATE_OK)
- return NULL;
- Py_INCREF(ts_current);
- return (PyObject*) ts_current;
-}
-
-static PyMethodDef GreenMethods[] = {
- {"getcurrent", (PyCFunction)mod_getcurrent, METH_NOARGS, /*XXX*/ NULL},
- {NULL, NULL} /* Sentinel */
-};
-
-static char* copy_on_greentype[] = {
- "getcurrent", "error", "GreenletExit", NULL
-};
-
-#if PY_MAJOR_VERSION >= 3
-#define INITERROR return NULL
-
-static struct PyModuleDef greenlet_module_def = {
- PyModuleDef_HEAD_INIT,
- "greenlet",
- NULL,
- -1,
- GreenMethods,
-};
-
-PyObject *
-PyInit_greenlet(void)
-#else
-#define INITERROR return
-
-void initgreenlet(void)
-#endif
-{
- PyObject* m = NULL;
- char** p = NULL;
- PyObject *c_api_object;
- static void *_PyGreenlet_API[PyGreenlet_API_pointers];
-
- _PyGreenlet_switchstack = g_switchstack;
- _PyGreenlet_slp_switch = slp_switch;
- _PyGreenlet_initialstub = g_initialstub;
-
-#if PY_MAJOR_VERSION >= 3
- m = PyModule_Create(&greenlet_module_def);
-#else
- m = Py_InitModule("greenlet", GreenMethods);
-#endif
- if (m == NULL)
- {
- INITERROR;
- }
-
- if (PyModule_AddStringConstant(m, "__version__", GREENLET_VERSION) < 0)
- {
- INITERROR;
- }
-
-#if PY_MAJOR_VERSION >= 3
- ts_curkey = PyUnicode_InternFromString("__greenlet_ts_curkey");
- ts_delkey = PyUnicode_InternFromString("__greenlet_ts_delkey");
-#else
- ts_curkey = PyString_InternFromString("__greenlet_ts_curkey");
- ts_delkey = PyString_InternFromString("__greenlet_ts_delkey");
-#endif
- if (ts_curkey == NULL || ts_delkey == NULL)
- {
- INITERROR;
- }
- if (PyType_Ready(&PyGreenlet_Type) < 0)
- {
- INITERROR;
- }
- PyExc_GreenletError = PyErr_NewException("greenlet.error", NULL, NULL);
- if (PyExc_GreenletError == NULL)
- {
- INITERROR;
- }
- PyExc_GreenletExit = PyErr_NewException("greenlet.GreenletExit",
- NULL, NULL);
- if (PyExc_GreenletExit == NULL)
- {
- INITERROR;
- }
-
- ts_current = green_create_main();
- if (ts_current == NULL)
- {
- INITERROR;
- }
-
- Py_INCREF(&PyGreenlet_Type);
- PyModule_AddObject(m, "greenlet", (PyObject*) &PyGreenlet_Type);
- Py_INCREF(PyExc_GreenletError);
- PyModule_AddObject(m, "error", PyExc_GreenletError);
- Py_INCREF(PyExc_GreenletExit);
- PyModule_AddObject(m, "GreenletExit", PyExc_GreenletExit);
-#ifdef GREENLET_USE_GC
- PyModule_AddObject(m, "GREENLET_USE_GC", PyBool_FromLong(1));
-#else
- PyModule_AddObject(m, "GREENLET_USE_GC", PyBool_FromLong(0));
-#endif
-
- /* also publish module-level data as attributes of the greentype. */
- for (p=copy_on_greentype; *p; p++) {
- PyObject* o = PyObject_GetAttrString(m, *p);
- if (!o) continue;
- PyDict_SetItemString(PyGreenlet_Type.tp_dict, *p, o);
- Py_DECREF(o);
- }
-
- /*
- * Expose C API
- */
-
- /* types */
- _PyGreenlet_API[PyGreenlet_Type_NUM] = (void *) &PyGreenlet_Type;
-
- /* exceptions */
- _PyGreenlet_API[PyExc_GreenletError_NUM] = (void *) PyExc_GreenletError;
- _PyGreenlet_API[PyExc_GreenletExit_NUM] = (void *) PyExc_GreenletExit;
-
- /* methods */
- _PyGreenlet_API[PyGreenlet_New_NUM] = (void *) PyGreenlet_New;
- _PyGreenlet_API[PyGreenlet_GetCurrent_NUM] =
- (void *) PyGreenlet_GetCurrent;
- _PyGreenlet_API[PyGreenlet_Throw_NUM] = (void *) PyGreenlet_Throw;
- _PyGreenlet_API[PyGreenlet_Switch_NUM] = (void *) PyGreenlet_Switch;
- _PyGreenlet_API[PyGreenlet_SetParent_NUM] =
- (void *) PyGreenlet_SetParent;
-
- c_api_object = PyCObject_FromVoidPtr((void *) _PyGreenlet_API, NULL);
- if (c_api_object != NULL)
- {
- PyModule_AddObject(m, "_C_API", c_api_object);
- }
-
-#if PY_MAJOR_VERSION >= 3
- return m;
-#endif
-}
View
131 greenlet/greenlet.h
@@ -1,131 +0,0 @@
-/* vim:set noet ts=8 sw=8 : */
-
-/* Greenlet object interface */
-
-#ifndef Py_GREENLETOBJECT_H
-#define Py_GREENLETOBJECT_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <Python.h>
-
-#define GREENLET_VERSION "0.3.1"
-
-typedef struct _greenlet {
- PyObject_HEAD
- char* stack_start;
- char* stack_stop;
- char* stack_copy;
- long stack_saved;
- struct _greenlet* stack_prev;
- struct _greenlet* parent;
- PyObject* run_info;
- struct _frame* top_frame;
- int recursion_depth;
- PyObject* weakreflist;
-} PyGreenlet;
-
-#define PyGreenlet_Check(op) PyObject_TypeCheck(op, &PyGreenlet_Type)
-#define PyGreenlet_STARTED(op) (((PyGreenlet*)(op))->stack_stop != NULL)
-#define PyGreenlet_ACTIVE(op) (((PyGreenlet*)(op))->stack_start != NULL)
-#define PyGreenlet_GET_PARENT(op) (((PyGreenlet*)(op))->parent)
-
-/* C API functions */
-
-/* Total number of symbols that are exported */
-#define PyGreenlet_API_pointers 8
-
-#define PyGreenlet_Type_NUM 0
-#define PyExc_GreenletError_NUM 1
-#define PyExc_GreenletExit_NUM 2
-
-#define PyGreenlet_New_NUM 3
-#define PyGreenlet_GetCurrent_NUM 4
-#define PyGreenlet_Throw_NUM 5
-#define PyGreenlet_Switch_NUM 6
-#define PyGreenlet_SetParent_NUM 7
-
-#ifndef GREENLET_MODULE
-/* This section is used by modules that uses the greenlet C API */
-static void **_PyGreenlet_API = NULL;
-
-#define PyGreenlet_Type (*(PyTypeObject *) _PyGreenlet_API[PyGreenlet_Type_NUM])
-
-#define PyExc_GreenletError \
- ((PyObject *) _PyGreenlet_API[PyExc_GreenletError_NUM])
-
-#define PyExc_GreenletExit \
- ((PyObject *) _PyGreenlet_API[PyExc_GreenletExit_NUM])
-
-/*
- * PyGreenlet_New(PyObject *args)
- *
- * greenlet.greenlet(run, parent=None)
- */
-#define PyGreenlet_New \
- (* (PyGreenlet * (*)(PyObject *run, PyGreenlet *parent)) \
- _PyGreenlet_API[PyGreenlet_New_NUM])
-
-/*
- * PyGreenlet_GetCurrent(void)
- *
- * greenlet.getcurrent()
- */
-#define PyGreenlet_GetCurrent \
- (* (PyGreenlet * (*)(void)) _PyGreenlet_API[PyGreenlet_GetCurrent_NUM])
-
-/*
- * PyGreenlet_Throw(
- * PyGreenlet *greenlet,
- * PyObject *typ,
- * PyObject *val,
- * PyObject *tb)
- *
- * g.throw(...)
- */
-#define PyGreenlet_Throw \
- (* (PyObject * (*) \
- (PyGreenlet *self, PyObject *typ, PyObject *val, PyObject *tb)) \
- _PyGreenlet_API[PyGreenlet_Throw_NUM])
-
-/*
- * PyGreenlet_Switch(PyGreenlet *greenlet, PyObject *args)
- *
- * g.switch(*args, **kwargs)
- */
-#define PyGreenlet_Switch \
- (* (PyObject * (*)(PyGreenlet *greenlet, PyObject *args, PyObject *kwargs)) \
- _PyGreenlet_API[PyGreenlet_Switch_NUM])
-
-/*
- * PyGreenlet_SetParent(PyObject *greenlet, PyObject *new_parent)
- *
- * g.parent = new_parent
- */
-#define PyGreenlet_SetParent \
- (* (PyObject * (*)(PyGreenlet *greenlet, PyGreenlet *nparent)) \
- _PyGreenlet_API[PyGreenlet_SetParent_NUM])
-
-/* Macro that imports greenlet and initializes C API */
-#define PyGreenlet_Import() \
-{ \
- PyObject *module = PyImport_ImportModule("greenlet"); \
- if (module != NULL) { \
- PyObject *c_api_object = PyObject_GetAttrString( \
- module, "_C_API"); \
- if (c_api_object != NULL && PyCObject_Check(c_api_object)) { \
- _PyGreenlet_API = \
- (void **) PyCObject_AsVoidPtr(c_api_object); \
- Py_DECREF(c_api_object); \
- } \
- Py_DECREF(module); \
- } \
-}
-
-#endif /* GREENLET_MODULE */
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* !Py_GREENLETOBJECT_H */
View
66 greenlet/platform/switch_amd64_unix.h
@@ -1,66 +0,0 @@
-/*
- * this is the internal transfer function.
- *
- * HISTORY
- * 01-Apr-04 Hye-Shik Chang <perky@FreeBSD.org>
- * Ported from i386 to amd64.
- * 24-Nov-02 Christian Tismer <tismer@tismer.com>
- * needed to add another magic constant to insure
- * that f in slp_eval_frame(PyFrameObject *f)
- * STACK_REFPLUS will probably be 1 in most cases.
- * gets included into the saved stack area.
- * 17-Sep-02 Christian Tismer <tismer@tismer.com>
- * after virtualizing stack save/restore, the
- * stack size shrunk a bit. Needed to introduce
- * an adjustment STACK_MAGIC per platform.
- * 15-Sep-02 Gerd Woetzel <gerd.woetzel@GMD.DE>
- * slightly changed framework for spark
- * 31-Avr-02 Armin Rigo <arigo@ulb.ac.be>
- * Added ebx, esi and edi register-saves.
- * 01-Mar-02 Samual M. Rushing <rushing@ironport.com>
- * Ported from i386.
- */
-
-#define STACK_REFPLUS 1
-
-#ifdef SLP_EVAL
-
-/* #define STACK_MAGIC 3 */
-/* the above works fine with gcc 2.96, but 2.95.3 wants this */
-#define STACK_MAGIC 0
-
-#define REGS_TO_SAVE "rdx", "rbx", "r12", "r13", "r14", "r15"
-
-
-static int
-slp_switch(void)
-{
- register long *stackref, stsizediff;
- __asm__ volatile ("" : : : REGS_TO_SAVE);
- __asm__ ("movq %%rsp, %0" : "=g" (stackref));
- {
- SLP_SAVE_STATE(stackref, stsizediff);
- __asm__ volatile (
- "addq %0, %%rsp\n"
- "addq %0, %%rbp\n"
- :
- : "r" (stsizediff)
- );
- SLP_RESTORE_STATE();
- }
- __asm__ volatile ("" : : : REGS_TO_SAVE);
- return 0;
-}
-
-#endif
-
-/*
- * further self-processing support
- */
-
-/*
- * if you want to add self-inspection tools, place them
- * here. See the x86_msvc for the necessary defines.
- * These features are highly experimental und not
- * essential yet.
- */
View
50 greenlet/platform/switch_arm32_gcc.h
@@ -1,50 +0,0 @@
-/*
- * this is the internal transfer function.
- *
- * HISTORY
- * 14-Aug-06 File creation. Ported from Arm Thumb. Sylvain Baro
- * 3-Sep-06 Commented out saving of r1-r3 (r4 already commented out) as I
- * read that these do not need to be saved. Also added notes and
- * errors related to the frame pointer. Richard Tew.
- *
- * NOTES
- *
- * It is not possible to detect if fp is used or not, so the supplied
- * switch function needs to support it, so that you can remove it if
- * it does not apply to you.
- *
- * POSSIBLE ERRORS
- *
- * "fp cannot be used in asm here"
- *
- * - Try commenting out "fp" in REGS_TO_SAVE.
- *
- */
-
-#define STACK_REFPLUS 1
-
-#ifdef SLP_EVAL
-#define STACK_MAGIC 0
-#define REGS_TO_SAVE /*"r1", "r2", "r3", "r4",*/ "r5", "r6", "fp", "ip", "lr"
-
-static int
-slp_switch(void)
-{
- register int *stackref, stsizediff;
- __asm__ volatile ("" : : : REGS_TO_SAVE);
- __asm__ ("mov %0,sp" : "=g" (stackref));
- {
- SLP_SAVE_STATE(stackref, stsizediff);
- __asm__ volatile (
- "add sp,sp,%0\n"
- "add fp,fp,%0\n"
- :
- : "r" (stsizediff)
- );
- SLP_RESTORE_STATE();
- return 0;
- }
- __asm__ volatile ("" : : : REGS_TO_SAVE);
-}
-
-#endif
View
56 greenlet/platform/switch_mips_unix.h
@@ -1,56 +0,0 @@
-/*
- * this is the internal transfer function.
- *
- * HISTORY
- * 05-Jan-08 Thiemo Seufer <ths@debian.org>
- * Ported from ppc.
- */
-
-#define STACK_REFPLUS 1
-
-#ifdef SLP_EVAL
-
-#define STACK_MAGIC 0
-
-#ifdef __mips64
-#define REGS_TO_SAVE "$16", "$17", "$18", "$19", "$20", "$21", "$22", \
- "$23", "$28", "$30"
-#else
-#define REGS_TO_SAVE "$16", "$17", "$18", "$19", "$20", "$21", "$22", \
- "$23", "$30"
-#endif
-static int
-slp_switch(void)
-{
- register int *stackref, stsizediff;
- __asm__ __volatile__ ("" : : : REGS_TO_SAVE);
- __asm__ ("move %0, $29" : "=r" (stackref) : );
- {
- SLP_SAVE_STATE(stackref, stsizediff);
- __asm__ __volatile__ (
-#ifdef __mips64
- "daddu $29, %0\n"
-#else
- "addu $29, %0\n"
-#endif
- : /* no outputs */
- : "r" (stsizediff)
- );
- SLP_RESTORE_STATE();
- }
- __asm__ __volatile__ ("" : : : REGS_TO_SAVE);
- return 0;
-}
-
-#endif
-
-/*
- * further self-processing support
- */
-
-/*
- * if you want to add self-inspection tools, place them
- * here. See the x86_msvc for the necessary defines.
- * These features are highly experimental und not
- * essential yet.
- */
View
80 greenlet/platform/switch_ppc_macosx.h
@@ -1,80 +0,0 @@
-/*
- * this is the internal transfer function.
- *
- * HISTORY
- * 07-Sep-05 (py-dev mailing list discussion)
- * removed 'r31' from the register-saved. !!!! WARNING !!!!
- * It means that this file can no longer be compiled statically!
- * It is now only suitable as part of a dynamic library!
- * 14-Jan-04 Bob Ippolito <bob@redivi.com>
- * added cr2-cr4 to the registers to be saved.
- * Open questions: Should we save FP registers?
- * What about vector registers?
- * Differences between darwin and unix?
- * 24-Nov-02 Christian Tismer <tismer@tismer.com>
- * needed to add another magic constant to insure
- * that f in slp_eval_frame(PyFrameObject *f)
- * STACK_REFPLUS will probably be 1 in most cases.
- * gets included into the saved stack area.
- * 17-Sep-02 Christian Tismer <tismer@tismer.com>
- * after virtualizing stack save/restore, the
- * stack size shrunk a bit. Needed to introduce
- * an adjustment STACK_MAGIC per platform.
- * 15-Sep-02 Gerd Woetzel <gerd.woetzel@GMD.DE>
- * slightly changed framework for sparc
- * 29-Jun-02 Christian Tismer <tismer@tismer.com>
- * Added register 13-29, 31 saves. The same way as
- * Armin Rigo did for the x86_unix version.
- * This seems to be now fully functional!
- * 04-Mar-02 Hye-Shik Chang <perky@fallin.lv>
- * Ported from i386.
- */
-
-#define STACK_REFPLUS 1
-
-#ifdef SLP_EVAL
-
-#define STACK_MAGIC 3
-
-/* !!!!WARNING!!!! need to add "r31" in the next line if this header file
- * is meant to be compiled non-dynamically!
- */
-#define REGS_TO_SAVE "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", \
- "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", \
- "cr2", "cr3", "cr4"
-
-static int
-slp_switch(void)
-{
- register int *stackref, stsizediff;
- __asm__ volatile ("" : : : REGS_TO_SAVE);
- __asm__ ("; asm block 2\n\tmr %0, r1" : "=g" (stackref) : );
- {
- SLP_SAVE_STATE(stackref, stsizediff);
- __asm__ volatile (
- "; asm block 3\n"
- "\tmr r11, %0\n"
- "\tadd r1, r1, r11\n"
- "\tadd r30, r30, r11\n"
- : /* no outputs */
- : "g" (stsizediff)
- : "r11"
- );
- SLP_RESTORE_STATE();
- }
- __asm__ volatile ("" : : : REGS_TO_SAVE);
- return 0;
-}
-
-#endif
-
-/*
- * further self-processing support
- */
-
-/*
- * if you want to add self-inspection tools, place them
- * here. See the x86_msvc for the necessary defines.
- * These features are highly experimental und not
- * essential yet.
- */
View
80 greenlet/platform/switch_ppc_unix.h
@@ -1,80 +0,0 @@
-/*
- * this is the internal transfer function.
- *
- * HISTORY
- * 07-Sep-05 (py-dev mailing list discussion)
- * removed 'r31' from the register-saved. !!!! WARNING !!!!
- * It means that this file can no longer be compiled statically!
- * It is now only suitable as part of a dynamic library!
- * 14-Jan-04 Bob Ippolito <bob@redivi.com>
- * added cr2-cr4 to the registers to be saved.
- * Open questions: Should we save FP registers?
- * What about vector registers?
- * Differences between darwin and unix?
- * 24-Nov-02 Christian Tismer <tismer@tismer.com>
- * needed to add another magic constant to insure
- * that f in slp_eval_frame(PyFrameObject *f)
- * STACK_REFPLUS will probably be 1 in most cases.
- * gets included into the saved stack area.
- * 04-Oct-02 Gustavo Niemeyer <niemeyer@conectiva.com>
- * Ported from MacOS version.
- * 17-Sep-02 Christian Tismer <tismer@tismer.com>
- * after virtualizing stack save/restore, the
- * stack size shrunk a bit. Needed to introduce
- * an adjustment STACK_MAGIC per platform.
- * 15-Sep-02 Gerd Woetzel <gerd.woetzel@GMD.DE>
- * slightly changed framework for sparc
- * 29-Jun-02 Christian Tismer <tismer@tismer.com>