[pypy-svn] pypy commit a437dc2fde54: hg merge default
Bitbucket
commits-noreply at bitbucket.org
Wed Dec 15 21:43:35 CET 2010
# HG changeset patch -- Bitbucket.org
# Project pypy
# URL http://bitbucket.org/pypy/pypy/overview
# User Hakan Ardo <hakan at debian.org>
# Date 1292444071 -3600
# Node ID a437dc2fde54f8842c5e1f814e8722d874ced640
# Parent 31c498ed04be76444c28579a2bec330689953577
# Parent 446ebfcd4f8dfa3588cb3de6945d2ea506fac0ed
hg merge default
--- a/pypy/rpython/llinterp.py
+++ b/pypy/rpython/llinterp.py
@@ -948,6 +948,9 @@ class LLFrame(object):
def op_set_stack_depth_limit(self):
raise NotImplementedError("set_stack_depth_limit")
+ def op_stack_current(self):
+ return 0
+
# operations on pyobjects!
for opname in lloperation.opimpls.keys():
exec py.code.Source("""
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -103,9 +103,9 @@ class Arguments(object):
make_sure_not_resized(self.keywords_w)
make_sure_not_resized(self.arguments_w)
- if w_stararg is not None and space.is_true(w_stararg):
+ if w_stararg is not None:
self._combine_starargs_wrapped(w_stararg)
- if w_starstararg is not None and space.is_true(w_starstararg):
+ if w_starstararg is not None:
self._combine_starstarargs_wrapped(w_starstararg)
# if we have a call where **args are used at the callsite
# we shouldn't let the JIT see the argument matching
--- a/pypy/module/posix/__init__.py
+++ b/pypy/module/posix/__init__.py
@@ -71,6 +71,8 @@ corresponding Unix manual entries for mo
if hasattr(os, 'chown'):
interpleveldefs['chown'] = 'interp_posix.chown'
+ if hasattr(os, 'lchown'):
+ interpleveldefs['lchown'] = 'interp_posix.lchown'
if hasattr(os, 'ftruncate'):
interpleveldefs['ftruncate'] = 'interp_posix.ftruncate'
if hasattr(os, 'fsync'):
@@ -86,6 +88,8 @@ corresponding Unix manual entries for mo
if hasattr(os, 'kill') and sys.platform != 'win32':
interpleveldefs['kill'] = 'interp_posix.kill'
interpleveldefs['abort'] = 'interp_posix.abort'
+ if hasattr(os, 'killpg'):
+ interpleveldefs['killpg'] = 'interp_posix.killpg'
if hasattr(os, 'getpid'):
interpleveldefs['getpid'] = 'interp_posix.getpid'
if hasattr(os, 'link'):
@@ -115,6 +119,12 @@ corresponding Unix manual entries for mo
interpleveldefs['ttyname'] = 'interp_posix.ttyname'
if hasattr(os, 'getloadavg'):
interpleveldefs['getloadavg'] = 'interp_posix.getloadavg'
+ if hasattr(os, 'mkfifo'):
+ interpleveldefs['mkfifo'] = 'interp_posix.mkfifo'
+ if hasattr(os, 'mknod'):
+ interpleveldefs['mknod'] = 'interp_posix.mknod'
+ if hasattr(os, 'nice'):
+ interpleveldefs['nice'] = 'interp_posix.nice'
for name in ['setsid', 'getuid', 'geteuid', 'getgid', 'getegid', 'setuid',
'seteuid', 'setgid', 'setegid', 'getpgrp', 'setpgrp',
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -16,6 +16,7 @@ class TestW_DictObject:
space = self.space
d = self.space.newdict()
assert not self.space.is_true(d)
+ assert d.r_dict_content is None
def test_nonempty(self):
space = self.space
@@ -505,6 +506,7 @@ class AppTest_DictMultiObject(AppTest_Di
def test_emptydict_unhashable(self):
raises(TypeError, "{}[['x']]")
+ raises(TypeError, "del {}[['x']]")
def test_string_subclass_via_setattr(self):
class A(object):
--- a/pypy/translator/benchmark/bench-custom.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# benchmarks on a unix machine.
-
-import autopath
-from pypy.translator.benchmark.result import BenchmarkResultSet
-from pypy.translator.benchmark.benchmarks import BENCHMARKS
-import os, sys, time, pickle, re, py
-
-SPLIT_TABLE = True # useful when executable names are very long
-
-def get_executables(args): #sorted by revision number (highest first)
- exes = sorted(args, key=os.path.getmtime)
- r = []
- for exe in exes:
- if '/' not in exe:
- r.append('./' + exe)
- else:
- r.append(exe)
- return r
-
-def main(options, args):
- if os.path.exists(options.picklefile):
- benchmark_result = pickle.load(open(options.picklefile, 'rb'))
- else:
- benchmark_result = BenchmarkResultSet()
-
- benchmarks = []
- for b in BENCHMARKS:
- if b.name in options.benchmarks:
- if not b.check():
- print "can't run %s benchmark for some reason"%(b.name,)
- else:
- if int(options.sizefactor) > 1:
- b = b * int(options.sizefactor)
- benchmarks.append(b)
-
- exes = get_executables(args)
- pythons = 'python2.6 python2.5 python2.4'.split()
- full_pythons = []
- for python in pythons:
- full_python = py.path.local.sysfind(python)
- if full_python:
- full_pythons.append(str(full_python))
-
- sys.stdout.flush()
-
- refs = {}
- final_error_count = 0
-
- if not options.nocpython:
- exes = full_pythons + exes
-
- for i in range(int(options.runcount)) or [None]:
- if i is not None:
- for exe in exes:
- for b in benchmarks:
- br = benchmark_result.result(exe, allowcreate=True)
- result = br.run_benchmark(b, verbose=options.verbose)
- if not result:
- final_error_count += 1
-
- if options.relto:
- relto = options.relto
- else:
- relto = full_pythons[0]
- if relto not in benchmark_result.benchmarks:
- continue
-
- pickle.dump(benchmark_result, open(options.picklefile, 'wb'))
-
- exe_stats = ['stat:st_mtime', 'exe_name', 'pypy_rev']
- if not SPLIT_TABLE:
- stats = exe_stats[:]
- else:
- stats = ['exe']
- for b in benchmarks:
- stats.append('bench:'+b.name)
- kwds = {'relto': relto,
- 'filteron' :lambda r: r.exe_name in exes,
- }
- for row in benchmark_result.txt_summary(stats, **kwds):
- print row
- if SPLIT_TABLE:
- print
- print 'Reference:'
- for row in benchmark_result.txt_summary(['exe'] + exe_stats,
- **kwds):
- print row
- print
-
- if final_error_count:
- raise SystemExit("%d benchmark run(s) failed (see -FAILED- above)"
- % final_error_count)
-
-if __name__ == '__main__':
- from optparse import OptionParser
- parser = OptionParser()
- default_benches = ','.join([b.name for b in BENCHMARKS if b.check()])
- parser.add_option(
- '--benchmarks', dest='benchmarks',
- default=default_benches,
- )
- parser.add_option(
- '--pickle', dest='picklefile',
- default='bench-custom.benchmark_result'
- )
- parser.add_option(
- '--runcount', dest='runcount',
- default='1',
- )
- parser.add_option(
- '--relto', dest='relto',
- default=None,
- )
- parser.add_option(
- '-v', '--verbose', action='store_true', dest='verbose',
- default=None,
- )
- parser.add_option(
- '--no-cpython', action='store_true', dest='nocpython',
- default=None,
- )
- parser.add_option(
- '--size-factor', dest='sizefactor',
- default='1',
- )
- options, args = parser.parse_args(sys.argv[1:])
- main(options, args)
--- a/pypy/translator/goal/app_main.py
+++ b/pypy/translator/goal/app_main.py
@@ -22,6 +22,25 @@ DEBUG = False # dump exceptions be
originalexcepthook = sys.__excepthook__
+def handle_sys_exit(e):
+ # exit if we catch a w_SystemExit
+ exitcode = e.code
+ if exitcode is None:
+ exitcode = 0
+ else:
+ try:
+ exitcode = int(exitcode)
+ except:
+ # not an integer: print it to stderr
+ try:
+ stderr = sys.stderr
+ except AttributeError:
+ pass # too bad
+ else:
+ print >> stderr, exitcode
+ exitcode = 1
+ raise SystemExit(exitcode)
+
def run_toplevel(f, *fargs, **fkwds):
"""Calls f() and handles all OperationErrors.
Intended use is to run the main program or one interactive statement.
@@ -45,72 +64,58 @@ def run_toplevel(f, *fargs, **fkwds):
stdout.write('\n')
except SystemExit, e:
- # exit if we catch a w_SystemExit
- exitcode = e.code
- if exitcode is None:
- exitcode = 0
- else:
- try:
- exitcode = int(exitcode)
- except:
- # not an integer: print it to stderr
- try:
- stderr = sys.stderr
- except AttributeError:
- pass # too bad
- else:
- print >> stderr, exitcode
- exitcode = 1
- raise SystemExit(exitcode)
+ handle_sys_exit(e)
+ except:
+ display_exception()
+ return False
+ return True # success
+
+def display_exception():
+ etype, evalue, etraceback = sys.exc_info()
+ try:
+ # extra debugging info in case the code below goes very wrong
+ if DEBUG and hasattr(sys, 'stderr'):
+ s = getattr(etype, '__name__', repr(etype))
+ print >> sys.stderr, "debug: exception-type: ", s
+ print >> sys.stderr, "debug: exception-value:", str(evalue)
+ tbentry = etraceback
+ if tbentry:
+ while tbentry.tb_next:
+ tbentry = tbentry.tb_next
+ lineno = tbentry.tb_lineno
+ filename = tbentry.tb_frame.f_code.co_filename
+ print >> sys.stderr, "debug: exception-tb: %s:%d" % (
+ filename, lineno)
+
+ # set the sys.last_xxx attributes
+ sys.last_type = etype
+ sys.last_value = evalue
+ sys.last_traceback = etraceback
+
+ # call sys.excepthook
+ hook = getattr(sys, 'excepthook', originalexcepthook)
+ hook(etype, evalue, etraceback)
+ return # done
except:
- etype, evalue, etraceback = sys.exc_info()
try:
- # extra debugging info in case the code below goes very wrong
- if DEBUG and hasattr(sys, 'stderr'):
- s = getattr(etype, '__name__', repr(etype))
- print >> sys.stderr, "debug: exception-type: ", s
- print >> sys.stderr, "debug: exception-value:", str(evalue)
- tbentry = etraceback
- if tbentry:
- while tbentry.tb_next:
- tbentry = tbentry.tb_next
- lineno = tbentry.tb_lineno
- filename = tbentry.tb_frame.f_code.co_filename
- print >> sys.stderr, "debug: exception-tb: %s:%d" % (
- filename, lineno)
+ stderr = sys.stderr
+ except AttributeError:
+ pass # too bad
+ else:
+ print >> stderr, 'Error calling sys.excepthook:'
+ originalexcepthook(*sys.exc_info())
+ print >> stderr
+ print >> stderr, 'Original exception was:'
- # set the sys.last_xxx attributes
- sys.last_type = etype
- sys.last_value = evalue
- sys.last_traceback = etraceback
+ # we only get here if sys.excepthook didn't do its job
+ originalexcepthook(etype, evalue, etraceback)
- # call sys.excepthook
- hook = getattr(sys, 'excepthook', originalexcepthook)
- hook(etype, evalue, etraceback)
- return False # done
-
- except:
- try:
- stderr = sys.stderr
- except AttributeError:
- pass # too bad
- else:
- print >> stderr, 'Error calling sys.excepthook:'
- originalexcepthook(*sys.exc_info())
- print >> stderr
- print >> stderr, 'Original exception was:'
-
- # we only get here if sys.excepthook didn't do its job
- originalexcepthook(etype, evalue, etraceback)
- return False
-
- return True # success
# ____________________________________________________________
# Option parsing
-def print_info():
+def print_info(*args):
try:
options = sys.pypy_translation_info
except AttributeError:
@@ -120,15 +125,17 @@ def print_info():
optitems.sort()
for name, value in optitems:
print ' %51s: %s' % (name, value)
+ raise SystemExit
-def print_help():
+def print_help(*args):
print 'usage: %s [options]' % (sys.executable,)
print __doc__.rstrip()
if 'pypyjit' in sys.builtin_module_names:
- print_jit_help()
+ _print_jit_help()
print
+ raise SystemExit
-def print_jit_help():
+def _print_jit_help():
import pypyjit
items = pypyjit.defaults.items()
items.sort()
@@ -136,6 +143,18 @@ def print_jit_help():
print ' --jit %s=N %slow-level JIT parameter (default %s)' % (
key, ' '*(18-len(key)), value)
+def print_version(*args):
+ print "Python", sys.version
+ raise SystemExit
+
+def set_jit_option(options, jitparam, *args):
+ if 'pypyjit' not in sys.builtin_module_names:
+ print >> sys.stderr, ("Warning: No jit support in %s" %
+ (sys.executable,))
+ else:
+ import pypyjit
+ pypyjit.set_param(jitparam)
+
class CommandLineError(Exception):
pass
@@ -171,18 +190,6 @@ if 'nt' in sys.builtin_module_names:
else:
IS_WINDOWS = False
-def get_argument(option, argv, i):
- arg = argv[i]
- n = len(option)
- if len(arg) > n:
- return arg[n:], i
- else:
- i += 1
- if i >= len(argv):
- raise CommandLineError('Argument expected for the %s option' %
- option)
- return argv[i], i
-
def get_library_path(executable):
search = executable
while 1:
@@ -200,7 +207,7 @@ def get_library_path(executable):
break # found!
return newpath
-def setup_initial_paths(executable, nanos, readenv=True, **extra):
+def setup_sys_executable(executable, nanos):
# a substituted os if we are translated
global os
os = nanos
@@ -220,7 +227,9 @@ def setup_initial_paths(executable, nano
break
sys.executable = os.path.abspath(executable)
- newpath = get_library_path(executable)
+def setup_initial_paths(ignore_environment=False, **extra):
+ newpath = get_library_path(sys.executable)
+ readenv = not ignore_environment
path = readenv and os.getenv('PYTHONPATH')
if path:
newpath = path.split(os.pathsep) + newpath
@@ -232,84 +241,181 @@ def setup_initial_paths(executable, nano
sys.path.append(dir)
_seen[dir] = True
+# Order is significant!
+sys_flags = (
+ "debug",
+ "py3k_warning",
+ "division_warning",
+ "division_new",
+ "inspect",
+ "interactive",
+ "optimize",
+ "dont_write_bytecode",
+ "no_user_site",
+ "no_site",
+ "ignore_environment",
+ "tabcheck",
+ "verbose",
+ "unicode",
+ "bytes_warning",
+)
+
+
+default_options = dict.fromkeys(
+ sys_flags +
+ ("run_command",
+ "run_module",
+ "run_stdin",
+ "warnoptions",
+ "unbuffered"), 0)
+
+
+PYTHON26 = False
+
+def simple_option(options, name, iterargv):
+ options[name] += 1
+
+def div_option(options, div, iterargv):
+ if div == "warn":
+ options["division_warning"] = 1
+ elif div == "warnall":
+ options["division_warning"] = 2
+ elif div == "new":
+ options["division_new"] = 1
+ elif div != "old":
+ raise CommandLineError("invalid division option: %r" % (div,))
+
+def c_option(options, runcmd, iterargv):
+ options["run_command"] = runcmd
+ return ['-c'] + list(iterargv)
+
+def m_option(options, runmodule, iterargv):
+ options["run_module"] = True
+ return [runmodule] + list(iterargv)
+
+def W_option(options, warnoption, iterargv):
+ options["warnoptions"].append(warnoption)
+
+def end_options(options, _, iterargv):
+ return list(iterargv)
+
+cmdline_options = {
+ # simple options just increment the counter of the options listed above
+ 'd': (simple_option, 'debug'),
+ 'i': (simple_option, 'interactive'),
+ 'O': (simple_option, 'optimize'),
+ 'S': (simple_option, 'no_site'),
+ 'E': (simple_option, 'ignore_environment'),
+ 't': (simple_option, 'tabcheck'),
+ 'v': (simple_option, 'verbose'),
+ 'U': (simple_option, 'unicode'),
+ 'u': (simple_option, 'unbuffered'),
+ # more complex options
+ 'Q': (div_option, Ellipsis),
+ 'c': (c_option, Ellipsis),
+ 'm': (m_option, Ellipsis),
+ 'W': (W_option, Ellipsis),
+ 'V': (print_version, None),
+ '--version': (print_version, None),
+ '--info': (print_info, None),
+ 'h': (print_help, None),
+ '--help': (print_help, None),
+ '--jit': (set_jit_option, Ellipsis),
+ '--': (end_options, None),
+ }
+
+if PYTHON26:
+ cmdline_options.update({
+ '3': (simple_option, 'py3k_warning'),
+ 'B': (simple_option, 'dont_write_bytecode'),
+ 's': (simple_option, 'no_user_site'),
+ 'b': (simple_option, 'bytes_warning'),
+ })
+
+
+def handle_argument(c, options, iterargv, iterarg=iter(())):
+ function, funcarg = cmdline_options[c]
+ #
+ # If needed, fill in the real argument by taking it from the command line
+ if funcarg is Ellipsis:
+ remaining = list(iterarg)
+ if remaining:
+ funcarg = ''.join(remaining)
+ else:
+ try:
+ funcarg = iterargv.next()
+ except StopIteration:
+ if len(c) == 1:
+ c = '-' + c
+ raise CommandLineError('Argument expected for the %r option' % c)
+ #
+ return function(options, funcarg, iterargv)
+
def parse_command_line(argv):
- go_interactive = False
- run_command = False
- import_site = True
- i = 0
- run_module = False
- run_stdin = False
- warnoptions = []
- unbuffered = False
- readenv = True
- while i < len(argv):
- arg = argv[i]
- if not arg.startswith('-'):
- break
- if arg == '-i':
- go_interactive = True
- elif arg.startswith('-c'):
- cmd, i = get_argument('-c', argv, i)
- argv[i] = '-c'
- run_command = True
- break
- elif arg == '-E':
- readenv = False
- elif arg == '-u':
- unbuffered = True
- elif arg == '-O' or arg == '-OO':
- pass
- elif arg == '--version' or arg == '-V':
- print "Python", sys.version
- return
- elif arg == '--info':
- print_info()
- return
- elif arg == '-h' or arg == '--help':
- print_help()
- return
- elif arg == '-S':
- import_site = False
- elif arg == '-':
- run_stdin = True
- break # not an option but a file name representing stdin
- elif arg.startswith('-m'):
- module, i = get_argument('-m', argv, i)
- argv[i] = module
- run_module = True
- break
- elif arg.startswith('-W'):
- warnoptions, i = get_argument('-W', argv, i)
- elif arg.startswith('--jit'):
- jitparam, i = get_argument('--jit', argv, i)
- if 'pypyjit' not in sys.builtin_module_names:
- print >> sys.stderr, ("Warning: No jit support in %s" %
- (sys.executable,))
- else:
- import pypyjit
- pypyjit.set_param(jitparam)
- elif arg == '--':
- i += 1
- break # terminates option list
+ options = default_options.copy()
+ options['warnoptions'] = []
+ #
+ iterargv = iter(argv)
+ argv = None
+ for arg in iterargv:
+ #
+ # If the next argument isn't at least two characters long or
+ # doesn't start with '-', stop processing
+ if len(arg) < 2 or arg[0] != '-':
+ if IS_WINDOWS and arg == '/?': # special case
+ print_help()
+ argv = [arg] + list(iterargv) # finishes processing
+ #
+ # If the next argument is directly in cmdline_options, handle
+ # it as a single argument
+ elif arg in cmdline_options:
+ argv = handle_argument(arg, options, iterargv)
+ #
+ # Else interpret the rest of the argument character by character
else:
- raise CommandLineError('unrecognized option %r' % (arg,))
- i += 1
- sys.argv[:] = argv[i:] # don't change the list that sys.argv is bound to
- if not sys.argv: # (relevant in case of "reload(sys)")
- sys.argv.append('')
- run_stdin = True
- return locals()
+ iterarg = iter(arg)
+ iterarg.next() # skip the '-'
+ for c in iterarg:
+ if c not in cmdline_options:
+ raise CommandLineError('Unknown option: -%s' % (c,))
+ argv = handle_argument(c, options, iterargv, iterarg)
-def run_command_line(go_interactive,
+ if not argv:
+ argv = ['']
+ options["run_stdin"] = True
+ elif argv[0] == '-':
+ options["run_stdin"] = True
+
+ # don't change the list that sys.argv is bound to
+ # (relevant in case of "reload(sys)")
+ sys.argv[:] = argv
+
+ if (options["interactive"] or
+ (not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))):
+ options["inspect"] = True
+
+ if PYTHON26 and we_are_translated():
+ flags = [options[flag] for flag in sys_flags]
+ sys.flags = type(sys.flags)(flags)
+ sys.py3kwarning = sys.flags.py3k_warning
+
+## if not we_are_translated():
+## for key in sorted(options):
+## print '%40s: %s' % (key, options[key])
+## print '%40s: %s' % ("sys.argv", sys.argv)
+
+ return options
+
+def run_command_line(interactive,
+ inspect,
run_command,
- import_site,
+ no_site,
run_module,
run_stdin,
warnoptions,
unbuffered,
- readenv,
- cmd=None,
+ ignore_environment,
**ignored):
# with PyPy in top of CPython we can only have around 100
# but we need more in the translated PyPy for the compiler package
@@ -325,14 +431,18 @@ def run_command_line(go_interactive,
mainmodule = type(sys)('__main__')
sys.modules['__main__'] = mainmodule
- if import_site:
+ if not no_site:
try:
import site
except:
print >> sys.stderr, "'import site' failed"
+ readenv = not ignore_environment
+ pythonwarnings = readenv and os.getenv('PYTHONWARNINGS')
+ if pythonwarnings:
+ warnoptions.extend(pythonwarnings.split(','))
if warnoptions:
- sys.warnoptions.append(warnoptions)
+ sys.warnoptions[:] = warnoptions
from warnings import _processoptions
_processoptions(sys.warnoptions)
@@ -352,26 +462,28 @@ def run_command_line(go_interactive,
signal.signal(signal.SIGXFSZ, signal.SIG_IGN)
def inspect_requested():
- # We get an interactive prompt in one of the following two cases:
+ # We get an interactive prompt in one of the following three cases:
#
- # * go_interactive=True, either from the "-i" option or
- # from the fact that we printed the banner;
+ # * interactive=True, from the "-i" option
+ # or
+ # * inspect=True and stdin is a tty
# or
# * PYTHONINSPECT is set and stdin is a tty.
#
- return (go_interactive or
- (readenv and os.getenv('PYTHONINSPECT') and sys.stdin.isatty()))
+ return (interactive or
+ ((inspect or (readenv and os.getenv('PYTHONINSPECT')))
+ and sys.stdin.isatty()))
success = True
try:
- if run_command:
+ if run_command != 0:
# handle the "-c" command
# Put '' on sys.path
sys.path.insert(0, '')
def run_it():
- exec cmd in mainmodule.__dict__
+ exec run_command in mainmodule.__dict__
success = run_toplevel(run_it)
elif run_module:
# handle the "-m" command
@@ -389,7 +501,7 @@ def run_command_line(go_interactive,
# put it's directory on sys.path
sys.path.insert(0, '')
- if go_interactive or sys.stdin.isatty():
+ if interactive or sys.stdin.isatty():
# If stdin is a tty or if "-i" is specified, we print
# a banner and run $PYTHONSTARTUP.
print_banner()
@@ -410,7 +522,7 @@ def run_command_line(go_interactive,
exec co_python_startup in mainmodule.__dict__
run_toplevel(run_it)
# Then we need a prompt.
- go_interactive = True
+ inspect = True
else:
# If not interactive, just read and execute stdin normally.
def run_it():
@@ -426,14 +538,25 @@ def run_command_line(go_interactive,
sys.path.insert(0, scriptdir)
success = run_toplevel(execfile, sys.argv[0], mainmodule.__dict__)
- # start a prompt if requested
+ except SystemExit, e:
+ status = e.code
if inspect_requested():
+ display_exception()
+ else:
+ status = not success
+
+ # start a prompt if requested
+ if inspect_requested():
+ inteactive = False
+ try:
from _pypy_interact import interactive_console
success = run_toplevel(interactive_console, mainmodule)
- except SystemExit, e:
- return e.code
- else:
- return not success
+ except SystemExit, e:
+ status = e.code
+ else:
+ status = not success
+
+ return status
def resolvedirof(filename):
try:
@@ -456,14 +579,15 @@ def print_banner():
'"license" for more information.')
def entry_point(executable, argv, nanos):
+ setup_sys_executable(executable, nanos)
try:
cmdline = parse_command_line(argv)
except CommandLineError, e:
print_error(str(e))
return 2
- if cmdline is None:
- return 0
- setup_initial_paths(executable, nanos, **cmdline)
+ except SystemExit, e:
+ return e.code or 0
+ setup_initial_paths(**cmdline)
return run_command_line(**cmdline)
--- a/pypy/module/cpyext/test/conftest.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import py
-from pypy.conftest import option, gettestobjspace
-
-def pytest_collect_directory(parent):
- if parent.config.option.runappdirect:
- py.test.skip("cannot be run by py.test -A")
-
- # ensure additional functions are registered
- import pypy.module.cpyext.test.test_cpyext
-
-def pytest_funcarg__space(request):
- return gettestobjspace(usemodules=['cpyext', 'thread'])
-
-def pytest_funcarg__api(request):
- return request.cls.api
-
--- a/pypy/translator/benchmark/autopath.py
+++ /dev/null
@@ -1,134 +0,0 @@
-"""
-self cloning, automatic path configuration
-
-copy this into any subdirectory of pypy from which scripts need
-to be run, typically all of the test subdirs.
-The idea is that any such script simply issues
-
- import autopath
-
-and this will make sure that the parent directory containing "pypy"
-is in sys.path.
-
-If you modify the master "autopath.py" version (in pypy/tool/autopath.py)
-you can directly run it which will copy itself on all autopath.py files
-it finds under the pypy root directory.
-
-This module always provides these attributes:
-
- pypydir pypy root directory path
- this_dir directory where this autopath.py resides
-
-"""
-
-def __dirinfo(part):
- """ return (partdir, this_dir) and insert parent of partdir
- into sys.path. If the parent directories don't have the part
- an EnvironmentError is raised."""
-
- import sys, os
- try:
- head = this_dir = os.path.realpath(os.path.dirname(__file__))
- except NameError:
- head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
-
- error = None
- while head:
- partdir = head
- head, tail = os.path.split(head)
- if tail == part:
- checkfile = os.path.join(partdir, os.pardir, 'pypy', '__init__.py')
- if not os.path.exists(checkfile):
- error = "Cannot find %r" % (os.path.normpath(checkfile),)
- break
- else:
- error = "Cannot find the parent directory %r of the path %r" % (
- partdir, this_dir)
- if not error:
- # check for bogus end-of-line style (e.g. files checked out on
- # Windows and moved to Unix)
- f = open(__file__.replace('.pyc', '.py'), 'r')
- data = f.read()
- f.close()
- if data.endswith('\r\n') or data.endswith('\r'):
- error = ("Bad end-of-line style in the .py files. Typically "
- "caused by a zip file or a checkout done on Windows and "
- "moved to Unix or vice-versa.")
- if error:
- raise EnvironmentError("Invalid source tree - bogus checkout! " +
- error)
-
- pypy_root = os.path.join(head, '')
- try:
- sys.path.remove(head)
- except ValueError:
- pass
- sys.path.insert(0, head)
-
- munged = {}
- for name, mod in sys.modules.items():
- if '.' in name:
- continue
- fn = getattr(mod, '__file__', None)
- if not isinstance(fn, str):
- continue
- newname = os.path.splitext(os.path.basename(fn))[0]
- if not newname.startswith(part + '.'):
- continue
- path = os.path.join(os.path.dirname(os.path.realpath(fn)), '')
- if path.startswith(pypy_root) and newname != part:
- modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep)
- if newname != '__init__':
- modpaths.append(newname)
- modpath = '.'.join(modpaths)
- if modpath not in sys.modules:
- munged[modpath] = mod
-
- for name, mod in munged.iteritems():
- if name not in sys.modules:
- sys.modules[name] = mod
- if '.' in name:
- prename = name[:name.rfind('.')]
- postname = name[len(prename)+1:]
- if prename not in sys.modules:
- __import__(prename)
- if not hasattr(sys.modules[prename], postname):
- setattr(sys.modules[prename], postname, mod)
-
- return partdir, this_dir
-
-def __clone():
- """ clone master version of autopath.py into all subdirs """
- from os.path import join, walk
- if not this_dir.endswith(join('pypy','tool')):
- raise EnvironmentError("can only clone master version "
- "'%s'" % join(pypydir, 'tool',_myname))
-
-
- def sync_walker(arg, dirname, fnames):
- if _myname in fnames:
- fn = join(dirname, _myname)
- f = open(fn, 'rwb+')
- try:
- if f.read() == arg:
- print "checkok", fn
- else:
- print "syncing", fn
- f = open(fn, 'w')
- f.write(arg)
- finally:
- f.close()
- s = open(join(pypydir, 'tool', _myname), 'rb').read()
- walk(pypydir, sync_walker, s)
-
-_myname = 'autopath.py'
-
-# set guaranteed attributes
-
-pypydir, this_dir = __dirinfo('pypy')
-import py # note: py is imported only AFTER the path has been set
-libpythondir = str(py.path.local(pypydir).dirpath().join('lib-python', '2.5.2'))
-libpythonmodifieddir = str(py.path.local(libpythondir).dirpath().join('modified-2.5.2'))
-
-if __name__ == '__main__':
- __clone()
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -57,7 +57,6 @@ class W_DictMultiObject(W_Object):
w_type = space.w_dict
w_self = space.allocate_instance(W_DictMultiObject, w_type)
W_DictMultiObject.__init__(w_self, space)
- w_self.initialize_as_rdict()
return w_self
def __init__(self, space):
@@ -98,29 +97,39 @@ class W_DictMultiObject(W_Object):
# implementation methods
def impl_getitem(self, w_key):
#return w_value or None
- raise NotImplementedError("abstract base class")
+ # in case the key is unhashable, try to hash it
+ self.space.hash(w_key)
+ # return None anyway
+ return None
def impl_getitem_str(self, key):
#return w_value or None
- raise NotImplementedError("abstract base class")
+ return None
+
+ def impl_setitem(self, w_key, w_value):
+ self._as_rdict().impl_fallback_setitem(w_key, w_value)
def impl_setitem_str(self, key, w_value):
- raise NotImplementedError("abstract base class")
-
- def impl_setitem(self, w_key, w_value):
- raise NotImplementedError("abstract base class")
+ self._as_rdict().impl_fallback_setitem_str(key, w_value)
def impl_delitem(self, w_key):
- raise NotImplementedError("abstract base class")
+ # in case the key is unhashable, try to hash it
+ self.space.hash(w_key)
+ raise KeyError
def impl_length(self):
- raise NotImplementedError("abstract base class")
+ return 0
def impl_iter(self):
- raise NotImplementedError("abstract base class")
+ # XXX I guess it's not important to be fast in this case?
+ return self._as_rdict().impl_fallback_iter()
def impl_clear(self):
- raise NotImplementedError("abstract base class")
+ self.r_dict_content = None
+
+ def _as_rdict(self):
+ r_dict_content = self.initialize_as_rdict()
+ return self
def impl_keys(self):
iterator = self.impl_iter()
--- a/pypy/translator/benchmark/__init__.py
+++ /dev/null
@@ -1,1 +0,0 @@
-#
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -101,7 +101,6 @@ class X86FrameManager(FrameManager):
return StackLoc(i, get_ebp_ofs(i), 1, box_type)
class RegAlloc(object):
- exc = False
def __init__(self, assembler, translate_support_code=False):
assert isinstance(translate_support_code, bool)
@@ -428,7 +427,10 @@ class RegAlloc(object):
locs = [self.loc(op.getarg(i)) for i in range(op.numargs())]
locs_are_ref = [op.getarg(i).type == REF for i in range(op.numargs())]
fail_index = self.assembler.cpu.get_fail_descr_number(op.getdescr())
- self.assembler.generate_failure(fail_index, locs, self.exc,
+ # note: no exception should currently be set in llop.get_exception_addr
+ # even if this finish may be an exit_frame_with_exception (in this case
+ # the exception instance is in locs[0]).
+ self.assembler.generate_failure(fail_index, locs, False,
locs_are_ref)
self.possibly_free_vars_for_op(op)
--- a/pypy/translator/benchmark/conftest.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import py
-
-def pytest_ignore_collect(path):
- return path.basename == "test"
--- a/pypy/jit/backend/llsupport/asmmemmgr.py
+++ b/pypy/jit/backend/llsupport/asmmemmgr.py
@@ -2,6 +2,8 @@ import sys
from pypy.rlib.rarithmetic import intmask, r_uint, LONG_BIT
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib import rmmap
+from pypy.rlib.debug import debug_start, debug_print, debug_stop
+from pypy.rlib.debug import have_debug_prints
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
@@ -265,6 +267,31 @@ class BlockBuilderMixin(object):
targetindex -= self.SUBBLOCK_SIZE
assert not block
+ def _dump(self, addr, logname, backend=None):
+ debug_start(logname)
+ if have_debug_prints():
+ #
+ if backend is not None:
+ debug_print('BACKEND', backend)
+ #
+ from pypy.jit.backend.hlinfo import highleveljitinfo
+ if highleveljitinfo.sys_executable:
+ debug_print('SYS_EXECUTABLE', highleveljitinfo.sys_executable)
+ #
+ HEX = '0123456789ABCDEF'
+ dump = []
+ src = rffi.cast(rffi.CCHARP, addr)
+ for p in range(self.get_relative_pos()):
+ o = ord(src[p])
+ dump.append(HEX[o >> 4])
+ dump.append(HEX[o & 15])
+ debug_print('CODE_DUMP',
+ '@%x' % addr,
+ '+0 ', # backwards compatibility
+ ''.join(dump))
+ #
+ debug_stop(logname)
+
def materialize(self, asmmemmgr, allblocks, gcrootmap=None):
size = self.get_relative_pos()
malloced = asmmemmgr.malloc(size, size)
--- a/pypy/jit/backend/llsupport/test/test_asmmemmgr.py
+++ b/pypy/jit/backend/llsupport/test/test_asmmemmgr.py
@@ -3,6 +3,7 @@ from pypy.jit.backend.llsupport.asmmemmg
from pypy.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
from pypy.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.rlib import debug
def test_get_index():
@@ -184,9 +185,11 @@ class TestAsmMemoryManager:
def test_blockbuildermixin(translated=True):
mc = BlockBuilderMixin(translated)
+ writtencode = []
for i in range(mc.SUBBLOCK_SIZE * 2 + 3):
assert mc.get_relative_pos() == i
mc.writechar(chr(i % 255))
+ writtencode.append(chr(i % 255))
if translated:
assert mc._cursubindex == 3
assert mc._cursubblock
@@ -196,16 +199,26 @@ def test_blockbuildermixin(translated=Tr
#
for i in range(0, mc.SUBBLOCK_SIZE * 2 + 3, 2):
mc.overwrite(i, chr((i + 63) % 255))
+ writtencode[i] = chr((i + 63) % 255)
#
p = lltype.malloc(rffi.CCHARP.TO, mc.SUBBLOCK_SIZE * 2 + 3, flavor='raw')
addr = rffi.cast(lltype.Signed, p)
mc.copy_to_raw_memory(addr)
#
for i in range(mc.SUBBLOCK_SIZE * 2 + 3):
- if i & 1:
- assert p[i] == chr(i % 255)
- else:
- assert p[i] == chr((i + 63) % 255)
+ assert p[i] == writtencode[i]
+ #
+ debug._log = debug.DebugLog()
+ try:
+ mc._dump(addr, 'test-logname-section')
+ log = list(debug._log)
+ finally:
+ debug._log = None
+ encoded = ''.join(writtencode).encode('hex').upper()
+ ataddr = '@%x' % addr
+ assert log == [('test-logname-section',
+ [('debug_print', 'CODE_DUMP', ataddr, '+0 ', encoded)])]
+ #
lltype.free(p, flavor='raw')
def test_blockbuildermixin2():
--- a/pypy/rpython/module/ll_os.py
+++ b/pypy/rpython/module/ll_os.py
@@ -99,7 +99,7 @@ class UnicodeTraits:
return 'll_os.ll_os_w' + name
def registering_str_unicode(posixfunc, condition=True):
- if not condition:
+ if not condition or posixfunc is None:
return registering(None, condition=False)
func_name = posixfunc.__name__
@@ -1129,6 +1129,19 @@ class RegisterOs(BaseLazyRegistering):
return extdef([str, int, int], None, "ll_os.ll_os_chown",
llimpl=os_chown_llimpl)
+ @registering_if(os, 'lchown')
+ def register_os_lchown(self):
+ os_lchown = self.llexternal('lchown',[rffi.CCHARP, rffi.INT, rffi.INT],
+ rffi.INT)
+
+ def os_lchown_llimpl(path, uid, gid):
+ res = os_lchown(path, uid, gid)
+ if res == -1:
+ raise OSError(rposix.get_errno(), "os_lchown failed")
+
+ return extdef([str, int, int], None, "ll_os.ll_os_lchown",
+ llimpl=os_lchown_llimpl)
+
@registering_if(os, 'readlink')
def register_os_readlink(self):
os_readlink = self.llexternal('readlink',
@@ -1323,6 +1336,33 @@ class RegisterOs(BaseLazyRegistering):
return extdef([traits.str, traits.str], s_None, llimpl=rename_llimpl,
export_name=traits.ll_os_name('rename'))
+ @registering_str_unicode(getattr(os, 'mkfifo', None))
+ def register_os_mkfifo(self, traits):
+ os_mkfifo = self.llexternal(traits.posix_function_name('mkfifo'),
+ [traits.CCHARP, rffi.MODE_T], rffi.INT)
+
+ def mkfifo_llimpl(path, mode):
+ res = rffi.cast(lltype.Signed, os_mkfifo(path, mode))
+ if res < 0:
+ raise OSError(rposix.get_errno(), "os_mkfifo failed")
+
+ return extdef([traits.str, int], s_None, llimpl=mkfifo_llimpl,
+ export_name=traits.ll_os_name('mkfifo'))
+
+ @registering_str_unicode(getattr(os, 'mknod', None))
+ def register_os_mknod(self, traits):
+ os_mknod = self.llexternal(traits.posix_function_name('mknod'),
+ [traits.CCHARP, rffi.MODE_T, rffi.INT],
+ rffi.INT) # xxx: actually ^^^ dev_t
+
+ def mknod_llimpl(path, mode, dev):
+ res = rffi.cast(lltype.Signed, os_mknod(path, mode, dev))
+ if res < 0:
+ raise OSError(rposix.get_errno(), "os_mknod failed")
+
+ return extdef([traits.str, int, int], s_None, llimpl=mknod_llimpl,
+ export_name=traits.ll_os_name('mknod'))
+
@registering(os.umask)
def register_os_umask(self):
os_umask = self.llexternal(underscore_on_windows+'umask', [rffi.MODE_T], rffi.MODE_T)
@@ -1348,6 +1388,20 @@ class RegisterOs(BaseLazyRegistering):
return extdef([int, int], s_None, llimpl=kill_llimpl,
export_name="ll_os.ll_os_kill")
+ @registering_if(os, 'killpg')
+ def register_os_killpg(self):
+ os_killpg = self.llexternal('killpg', [rffi.INT, rffi.INT],
+ rffi.INT)
+
+ def killpg_llimpl(pid, sig):
+ res = rffi.cast(lltype.Signed, os_killpg(rffi.cast(rffi.INT, pid),
+ rffi.cast(rffi.INT, sig)))
+ if res < 0:
+ raise OSError(rposix.get_errno(), "os_killpg failed")
+
+ return extdef([int, int], s_None, llimpl=killpg_llimpl,
+ export_name="ll_os.ll_os_killpg")
+
@registering_if(os, 'link')
def register_os_link(self):
os_link = self.llexternal('link', [rffi.CCHARP, rffi.CCHARP],
@@ -1444,6 +1498,25 @@ class RegisterOs(BaseLazyRegistering):
return extdef([int], s_None, llimpl=_exit_llimpl,
export_name="ll_os.ll_os__exit")
+ @registering_if(os, 'nice')
+ def register_os_nice(self):
+ os_nice = self.llexternal('nice', [rffi.INT], rffi.INT)
+
+ def nice_llimpl(inc):
+ # Assume that the system provides a standard-compliant version
+ # of nice() that returns the new priority. Nowadays, FreeBSD
+ # might be the last major non-compliant system (xxx check me).
+ rposix.set_errno(0)
+ res = rffi.cast(lltype.Signed, os_nice(inc))
+ if res == -1:
+ err = rposix.get_errno()
+ if err != 0:
+ raise OSError(err, "os_nice failed")
+ return res
+
+ return extdef([int], int, llimpl=nice_llimpl,
+ export_name="ll_os.ll_os_nice")
+
# --------------------------- os.stat & variants ---------------------------
@registering(os.fstat)
--- a/pypy/translator/c/test/test_extfunc.py
+++ b/pypy/translator/c/test/test_extfunc.py
@@ -4,6 +4,7 @@ import os, time, sys
from pypy.tool.udir import udir
from pypy.rlib.rarithmetic import r_longlong
from pypy.translator.c.test.test_genc import compile
+from pypy.translator.c.test.test_standalone import StandaloneTests
posix = __import__(os.name)
# note: clock synchronizes itself!
@@ -404,6 +405,28 @@ def test_os_rename():
assert os.path.exists(tmpfile2)
assert not os.path.exists(tmpfile1)
+if hasattr(os, 'mkfifo'):
+ def test_os_mkfifo():
+ tmpfile = str(udir.join('test_os_mkfifo.txt'))
+ def does_stuff():
+ os.mkfifo(tmpfile, 0666)
+ f1 = compile(does_stuff, [])
+ f1()
+ import stat
+ st = os.lstat(tmpfile)
+ assert stat.S_ISFIFO(st.st_mode)
+
+if hasattr(os, 'mknod'):
+ def test_os_mknod():
+ import stat
+ tmpfile = str(udir.join('test_os_mknod.txt'))
+ def does_stuff():
+ os.mknod(tmpfile, 0600 | stat.S_IFIFO, 0)
+ f1 = compile(does_stuff, [])
+ f1()
+ st = os.lstat(tmpfile)
+ assert stat.S_ISFIFO(st.st_mode)
+
def test_os_umask():
def does_stuff():
mask1 = os.umask(0660)
@@ -516,6 +539,62 @@ elif hasattr(os, 'waitpid'):
# for what reason do they want us to shift by 8? See the doc
assert status1 >> 8 == 4
+if hasattr(os, 'kill'):
+ def test_kill_to_send_sigusr1():
+ import signal
+ from pypy.module.signal import interp_signal
+ def does_stuff():
+ interp_signal.pypysig_setflag(signal.SIGUSR1)
+ os.kill(os.getpid(), signal.SIGUSR1)
+ interp_signal.pypysig_ignore(signal.SIGUSR1)
+ while True:
+ n = interp_signal.pypysig_poll()
+ if n < 0 or n == signal.SIGUSR1:
+ break
+ return n
+ f1 = compile(does_stuff, [])
+ got_signal = f1()
+ assert got_signal == signal.SIGUSR1
+
+if hasattr(os, 'killpg'):
+ def test_killpg():
+ import signal
+ from pypy.module.signal import interp_signal
+ def does_stuff():
+ interp_signal.pypysig_setflag(signal.SIGUSR1)
+ os.killpg(os.getpgrp(), signal.SIGUSR1)
+ interp_signal.pypysig_ignore(signal.SIGUSR1)
+ while True:
+ n = interp_signal.pypysig_poll()
+ if n < 0 or n == signal.SIGUSR1:
+ break
+ return n
+ f1 = compile(does_stuff, [])
+ got_signal = f1()
+ assert got_signal == signal.SIGUSR1
+
+if hasattr(os, 'chown') and hasattr(os, 'lchown'):
+ def test_os_chown_lchown():
+ path1 = udir.join('test_os_chown_lchown-1.txt')
+ path2 = udir.join('test_os_chown_lchown-2.txt')
+ path1.write('foobar')
+ path2.mksymlinkto('some-broken-symlink')
+ tmpfile1 = str(path1)
+ tmpfile2 = str(path2)
+ def does_stuff():
+ # xxx not really a test, just checks that they are callable
+ os.chown(tmpfile1, os.getuid(), os.getgid())
+ os.lchown(tmpfile1, os.getuid(), os.getgid())
+ os.lchown(tmpfile2, os.getuid(), os.getgid())
+ try:
+ os.chown(tmpfile2, os.getuid(), os.getgid())
+ except OSError:
+ pass
+ else:
+ raise AssertionError("os.chown(broken symlink) should raise")
+ f1 = compile(does_stuff, [])
+ f1()
+
# ____________________________________________________________
def _real_getenv(var):
@@ -783,3 +862,19 @@ if hasattr(os, 'fchdir'):
finally:
os.chdir(localdir)
assert res == True
+
+# ____________________________________________________________
+
+
+class TestExtFuncStandalone(StandaloneTests):
+
+ if hasattr(os, 'nice'):
+ def test_os_nice(self):
+ def does_stuff(argv):
+ res = os.nice(3)
+ print 'os.nice returned', res
+ return 0
+ t, cbuilder = self.compile(does_stuff)
+ data = cbuilder.cmdexec('')
+ res = os.nice(0) + 3
+ assert data.startswith('os.nice returned %d\n' % res)
--- a/pypy/module/sys/test/test_version.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from pypy.module.sys.version import rev2int
-
-def test_rev2int():
- assert rev2int("71630") == 71630
- assert rev2int("") == 0
--- a/pypy/translator/benchmark/jitbench.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import sys, os
-from optparse import OptionParser
-
-parser = OptionParser()
-parser.add_option(
- '--size-factor-list', dest='sizefactorlist',
- default='1,2,5,20,1,2,5,20,1,2,5,20',
- )
-options, args = parser.parse_args(sys.argv[1:])
-args = args or [sys.executable]
-executables = [os.path.abspath(executable) for executable in args]
-sizefactors = [int(s) for s in options.sizefactorlist.split(',')]
-
-os.chdir(os.path.dirname(sys.argv[0]) or '.')
-
-errors = []
-
-for sizefactor in sizefactors:
- for executable in executables:
- sys.argv[1:] = [executable, '--pickle=jitbench.benchmark_result',
- '-v', '--no-cpython',
- '--size-factor=%d' % sizefactor]
- try:
- execfile('bench-custom.py')
- except SystemExit, e:
- errors.append('%s:*%s: %s' % (executable, sizefactor, e))
-
-if errors:
- print '\n'.join(errors)
- sys.exit(1)
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1295,6 +1295,10 @@ class MetaInterpStaticData(object):
num = self.cpu.get_fail_descr_number(tokens[0].finishdescr)
setattr(self.cpu, 'done_with_this_frame_%s_v' % name, num)
#
+ tokens = self.loop_tokens_exit_frame_with_exception_ref
+ num = self.cpu.get_fail_descr_number(tokens[0].finishdescr)
+ self.cpu.exit_frame_with_exception_v = num
+ #
self.globaldata = MetaInterpGlobalData(self)
def _setup_once(self):
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -659,6 +659,67 @@ class AppTestPosix:
f.close()
os.chown(self.path, os.getuid(), os.getgid())
+ if hasattr(os, 'lchown'):
+ def test_lchown(self):
+ os = self.posix
+ os.unlink(self.path)
+ raises(OSError, os.lchown, self.path, os.getuid(), os.getgid())
+ os.symlink('foobar', self.path)
+ os.lchown(self.path, os.getuid(), os.getgid())
+
+ if hasattr(os, 'mkfifo'):
+ def test_mkfifo(self):
+ os = self.posix
+ os.mkfifo(self.path2 + 'test_mkfifo', 0666)
+ st = os.lstat(self.path2 + 'test_mkfifo')
+ import stat
+ assert stat.S_ISFIFO(st.st_mode)
+
+ if hasattr(os, 'mknod'):
+ def test_mknod(self):
+ import stat
+ os = self.posix
+ # not very useful: os.mknod() without specifying 'mode'
+ os.mknod(self.path2 + 'test_mknod-1')
+ st = os.lstat(self.path2 + 'test_mknod-1')
+ assert stat.S_ISREG(st.st_mode)
+ # os.mknod() with S_IFIFO
+ os.mknod(self.path2 + 'test_mknod-2', 0600 | stat.S_IFIFO)
+ st = os.lstat(self.path2 + 'test_mknod-2')
+ assert stat.S_ISFIFO(st.st_mode)
+
+ def test_mknod_with_ifchr(self):
+ # os.mknod() with S_IFCHR
+ # -- usually requires root priviledges --
+ os = self.posix
+ if hasattr(os.lstat('.'), 'st_rdev'):
+ import stat
+ try:
+ os.mknod(self.path2 + 'test_mknod-3', 0600 | stat.S_IFCHR,
+ 0x105)
+ except OSError, e:
+ skip("os.mknod() with S_IFCHR: got %r" % (e,))
+ else:
+ st = os.lstat(self.path2 + 'test_mknod-3')
+ assert stat.S_ISCHR(st.st_mode)
+ assert st.st_rdev == 0x105
+
+ if hasattr(os, 'nice') and hasattr(os, 'fork') and hasattr(os, 'waitpid'):
+ def test_nice(self):
+ os = self.posix
+ myprio = os.nice(0)
+ #
+ pid = os.fork()
+ if pid == 0: # in the child
+ res = os.nice(3)
+ os._exit(res)
+ #
+ pid1, status1 = os.waitpid(pid, 0)
+ assert pid1 == pid
+ assert os.WIFEXITED(status1)
+ assert os.WEXITSTATUS(status1) == myprio + 3
+
+
class AppTestEnvironment(object):
def setup_class(cls):
cls.space = space
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -153,6 +153,7 @@ def ftruncate(space, fd, length):
ftruncate.unwrap_spec = [ObjSpace, "c_int", r_longlong]
def fsync(space, w_fd):
+ """Force write of file with filedescriptor to disk."""
fd = space.c_filedescriptor_w(w_fd)
try:
os.fsync(fd)
@@ -161,6 +162,8 @@ def fsync(space, w_fd):
fsync.unwrap_spec = [ObjSpace, W_Root]
def fdatasync(space, w_fd):
+ """Force write of file with filedescriptor to disk.
+Does not force update of metadata."""
fd = space.c_filedescriptor_w(w_fd)
try:
os.fdatasync(fd)
@@ -169,6 +172,8 @@ def fdatasync(space, w_fd):
fdatasync.unwrap_spec = [ObjSpace, W_Root]
def fchdir(space, w_fd):
+ """Change to the directory of the given file descriptor. fildes must be
+opened on a directory, not a file."""
fd = space.c_filedescriptor_w(w_fd)
try:
os.fchdir(fd)
@@ -549,6 +554,27 @@ def rename(space, w_old, w_new):
raise wrap_oserror(space, e)
rename.unwrap_spec = [ObjSpace, W_Root, W_Root]
+def mkfifo(space, w_filename, mode=0666):
+ """Create a FIFO (a POSIX named pipe)."""
+ try:
+ dispatch_filename(rposix.mkfifo)(space, w_filename, mode)
+ except OSError, e:
+ raise wrap_oserror2(space, e, w_filename)
+mkfifo.unwrap_spec = [ObjSpace, W_Root, "c_int"]
+
+def mknod(space, w_filename, mode=0600, device=0):
+ """Create a filesystem node (file, device special file or named pipe)
+named filename. mode specifies both the permissions to use and the
+type of node to be created, being combined (bitwise OR) with one of
+S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,
+device defines the newly created device special file (probably using
+os.makedev()), otherwise it is ignored."""
+ try:
+ dispatch_filename(rposix.mknod)(space, w_filename, mode, device)
+ except OSError, e:
+ raise wrap_oserror2(space, e, w_filename)
+mknod.unwrap_spec = [ObjSpace, W_Root, "c_int", "c_int"]
+
def umask(space, mask):
"Set the current numeric umask and return the previous umask."
prevmask = os.umask(mask)
@@ -572,6 +598,14 @@ def kill(space, pid, sig):
raise wrap_oserror(space, e)
kill.unwrap_spec = [ObjSpace, "c_int", "c_int"]
+def killpg(space, pgid, sig):
+ "Kill a process group with a signal."
+ try:
+ os.killpg(pgid, sig)
+ except OSError, e:
+ raise wrap_oserror(space, e)
+killpg.unwrap_spec = [ObjSpace, "c_int", "c_int"]
+
def abort(space):
"""Abort the interpreter immediately. This 'dumps core' or otherwise fails
in the hardest way possible on the hosting operating system."""
@@ -974,6 +1008,14 @@ def chown(space, path, uid, gid):
return space.w_None
chown.unwrap_spec = [ObjSpace, str, "c_nonnegint", "c_nonnegint"]
+def lchown(space, path, uid, gid):
+ try:
+ os.lchown(path, uid, gid)
+ except OSError, e:
+ raise wrap_oserror(space, e, path)
+ return space.w_None
+lchown.unwrap_spec = [ObjSpace, str, "c_nonnegint", "c_nonnegint"]
+
def getloadavg(space):
try:
load = os.getloadavg()
@@ -985,6 +1027,15 @@ def getloadavg(space):
space.wrap(load[2])])
getloadavg.unwrap_spec = [ObjSpace]
+def nice(space, inc):
+ "Decrease the priority of process by inc and return the new priority."
+ try:
+ res = os.nice(inc)
+ except OSError, e:
+ raise wrap_oserror(space, e)
+ return space.wrap(res)
+nice.unwrap_spec = [ObjSpace, "c_int"]
+
if _WIN:
from pypy.rlib import rwin32
--- a/pypy/rlib/rsdl/test/conftest.py
+++ b/pypy/rlib/rsdl/test/conftest.py
@@ -1,8 +1,10 @@
from pypy.rlib.rsdl.eci import check_sdl_installation, SDLNotInstalled
import py
-def pytest_collect_directory():
+def pytest_ignore_collect(path):
try:
check_sdl_installation()
except SDLNotInstalled, e:
- py.test.skip("SDL not installed(?): %s" % (e,))
+ return True
+ else:
+ return False
--- a/pypy/translator/goal/test2/test_app_main.py
+++ b/pypy/translator/goal/test2/test_app_main.py
@@ -43,6 +43,93 @@ crashing_demo_script = getscript("""
""")
+class TestParseCommandLine:
+
+ def check_options(self, options, sys_argv, **expected):
+ assert sys.argv == sys_argv
+ for key, value in expected.items():
+ assert options[key] == value
+ for key, value in options.items():
+ if key not in expected:
+ assert not value, (
+ "option %r has unexpectedly the value %r" % (key, value))
+
+ def check(self, argv, **expected):
+ import StringIO
+ from pypy.translator.goal import app_main
+ saved_sys_argv = sys.argv[:]
+ saved_sys_stdout = sys.stdout
+ saved_sys_stderr = sys.stdout
+ app_main.os = os
+ try:
+ sys.stdout = sys.stderr = StringIO.StringIO()
+ try:
+ options = app_main.parse_command_line(argv)
+ except SystemExit:
+ output = expected['output_contains']
+ assert output in sys.stdout.getvalue()
+ else:
+ self.check_options(options, **expected)
+ finally:
+ sys.argv[:] = saved_sys_argv
+ sys.stdout = saved_sys_stdout
+ sys.stderr = saved_sys_stderr
+
+ def test_all_combinations_I_can_think_of(self):
+ self.check([], sys_argv=[''], run_stdin=True)
+ self.check(['-'], sys_argv=['-'], run_stdin=True)
+ self.check(['-S'], sys_argv=[''], run_stdin=True, no_site=1)
+ self.check(['-OO'], sys_argv=[''], run_stdin=True, optimize=2)
+ self.check(['-O', '-O'], sys_argv=[''], run_stdin=True, optimize=2)
+ self.check(['-Qnew'], sys_argv=[''], run_stdin=True, division_new=1)
+ self.check(['-Qold'], sys_argv=[''], run_stdin=True, division_new=0)
+ self.check(['-Qwarn'], sys_argv=[''], run_stdin=True, division_warning=1)
+ self.check(['-Qwarnall'], sys_argv=[''], run_stdin=True,
+ division_warning=2)
+ self.check(['-Q', 'new'], sys_argv=[''], run_stdin=True, division_new=1)
+ self.check(['-SOQnew'], sys_argv=[''], run_stdin=True,
+ no_site=1, optimize=1, division_new=1)
+ self.check(['-SOQ', 'new'], sys_argv=[''], run_stdin=True,
+ no_site=1, optimize=1, division_new=1)
+ self.check(['-i'], sys_argv=[''], run_stdin=True,
+ interactive=1, inspect=1)
+ self.check(['-h'], output_contains='usage:')
+ self.check(['-S', '-tO', '-h'], output_contains='usage:')
+ self.check(['-S', '-thO'], output_contains='usage:')
+ self.check(['-S', '-tO', '--help'], output_contains='usage:')
+ self.check(['-S', '-tO', '--info'], output_contains='translation')
+ self.check(['-S', '-tO', '--version'], output_contains='Python')
+ self.check(['-S', '-tOV'], output_contains='Python')
+ self.check(['--jit', 'foobar', '-S'], sys_argv=[''],
+ run_stdin=True, no_site=1)
+ self.check(['-c', 'pass'], sys_argv=['-c'], run_command='pass')
+ self.check(['-cpass'], sys_argv=['-c'], run_command='pass')
+ self.check(['-cpass','x'], sys_argv=['-c','x'], run_command='pass')
+ self.check(['-Sc', 'pass'], sys_argv=['-c'], run_command='pass',
+ no_site=1)
+ self.check(['-Scpass'], sys_argv=['-c'], run_command='pass', no_site=1)
+ self.check(['-c', '', ''], sys_argv=['-c', ''], run_command='')
+ self.check(['-mfoo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'],
+ run_module=True)
+ self.check(['-m', 'foo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'],
+ run_module=True)
+ self.check(['-Smfoo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'],
+ run_module=True, no_site=1)
+ self.check(['-Sm', 'foo', 'bar', 'baz'], sys_argv=['foo', 'bar', 'baz'],
+ run_module=True, no_site=1)
+ self.check(['-', 'foo', 'bar'], sys_argv=['-', 'foo', 'bar'],
+ run_stdin=True)
+ self.check(['foo', 'bar'], sys_argv=['foo', 'bar'])
+ self.check(['foo', '-i'], sys_argv=['foo', '-i'])
+ self.check(['-i', 'foo'], sys_argv=['foo'], interactive=1, inspect=1)
+ self.check(['--', 'foo'], sys_argv=['foo'])
+ self.check(['--', '-i', 'foo'], sys_argv=['-i', 'foo'])
+ self.check(['--', '-', 'foo'], sys_argv=['-', 'foo'], run_stdin=True)
+ self.check(['-Wbog'], sys_argv=[''], warnoptions=['bog'], run_stdin=True)
+ self.check(['-W', 'ab', '-SWc'], sys_argv=[''], warnoptions=['ab', 'c'],
+ run_stdin=True, no_site=1)
+
+
class TestInteraction:
"""
These tests require pexpect (UNIX-only).
@@ -101,6 +188,12 @@ class TestInteraction:
child.sendline("'' in sys.path")
child.expect("True")
+ def test_help(self):
+ # test that -h prints the usage, including the name of the executable
+ # which should be /full/path/to/app_main.py in this case
+ child = self.spawn(['-h'])
+ child.expect(r'usage: .*app_main.py \[options\]')
+
def test_run_script(self):
child = self.spawn([demo_script])
idx = child.expect(['hello', 'Python ', '>>> '])
@@ -416,7 +509,7 @@ class TestNonInteractive:
def test_option_W_crashing(self):
data = self.run('-W')
- assert 'Argument expected for the -W option' in data
+ assert "Argument expected for the '-W' option" in data
def test_option_W_arg_ignored(self):
data = self.run('-Wc')
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -797,8 +797,8 @@ class ObjSpace(object):
def call_obj_args(self, w_callable, w_obj, args):
if not self.config.objspace.disable_call_speedhacks:
- # XXX start of hack for performance
- from pypy.interpreter.function import Function
+ # XXX start of hack for performance
+ from pypy.interpreter.function import Function
if isinstance(w_callable, Function):
return w_callable.call_obj_args(w_obj, args)
# XXX end of hack for performance
@@ -1184,24 +1184,27 @@ class ObjSpace(object):
return value
def c_filedescriptor_w(self, w_fd):
- try:
- fd = self.c_int_w(w_fd)
- except OperationError, e:
- if not e.match(self, self.w_TypeError):
- raise
+ if (not self.isinstance_w(w_fd, self.w_int) and
+ not self.isinstance_w(w_fd, self.w_long)):
try:
- w_fileno = self.getattr(w_fd, self.wrap('fileno'))
+ w_fileno = self.getattr(w_fd, self.wrap("fileno"))
except OperationError, e:
if e.match(self, self.w_AttributeError):
raise OperationError(self.w_TypeError,
- self.wrap("argument must be an int, "
- "or have a fileno() method."))
+ self.wrap("argument must be an int, or have a fileno() "
+ "method.")
+ )
raise
w_fd = self.call_function(w_fileno)
- fd = self.c_int_w(w_fd)
+ if not self.isinstance_w(w_fd, self.w_int):
+ raise OperationError(self.w_TypeError,
+ self.wrap("fileno() must return an integer")
+ )
+ fd = self.int_w(w_fd)
if fd < 0:
raise operationerrfmt(self.w_ValueError,
- "file descriptor cannot be a negative integer (%d)", fd)
+ "file descriptor cannot be a negative integer (%d)", fd
+ )
return fd
def warn(self, msg, w_warningcls):
@@ -1403,4 +1406,3 @@ ObjSpace.IrregularOpTable = [
'call_args',
'marshal_w',
]
-
--- a/pypy/rpython/memory/gc/env.py
+++ b/pypy/rpython/memory/gc/env.py
@@ -51,7 +51,7 @@ def read_float_from_env(varname):
# ____________________________________________________________
# Get the total amount of RAM installed in a system.
# On 32-bit systems, it will try to return at most the addressable size.
-# Note that if unknown it will just return the addressable size, which
+# If unknown, it will just return the addressable size, which
# will be huge on 64-bit systems.
if sys.maxint == 2147483647: # 32-bit
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -322,6 +322,14 @@ class StdObjSpace(ObjSpace, DescrOperati
w_subtype = w_type.check_user_subclass(w_subtype)
if cls.typedef.applevel_subclasses_base is not None:
cls = cls.typedef.applevel_subclasses_base
+ #
+ if not we_are_translated():
+ if issubclass(cls, model.W_Object):
+ # If cls is missing from model.typeorder, then you
+ # need to add it there (including the inheritance
+ # relationship, if any)
+ assert cls in self.model.typeorder, repr(cls)
+ #
if (self.config.objspace.std.withmapdict and cls is W_ObjectObject
and not w_subtype.needsdel):
from pypy.objspace.std.mapdict import get_subclass_of_correct_size
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -115,6 +115,7 @@ class AbstractLLCPU(AbstractCPU):
self.pos_exception = pos_exception
self.pos_exc_value = pos_exc_value
self.save_exception = save_exception
+ self.insert_stack_check = lambda: (0, 0, 0)
def _setup_exception_handling_translated(self):
@@ -138,9 +139,20 @@ class AbstractLLCPU(AbstractCPU):
# in the assignment to self.saved_exc_value, as needed.
self.saved_exc_value = exc_value
+ from pypy.rlib import rstack
+ STACK_CHECK_SLOWPATH = lltype.Ptr(lltype.FuncType([lltype.Signed],
+ lltype.Void))
+ def insert_stack_check():
+ startaddr = rstack._stack_get_start_adr()
+ length = rstack._stack_get_length()
+ f = llhelper(STACK_CHECK_SLOWPATH, rstack.stack_check_slowpath)
+ slowpathaddr = rffi.cast(lltype.Signed, f)
+ return startaddr, length, slowpathaddr
+
self.pos_exception = pos_exception
self.pos_exc_value = pos_exc_value
self.save_exception = save_exception
+ self.insert_stack_check = insert_stack_check
def _setup_on_leave_jitted_untranslated(self):
# assume we don't need a backend leave in this case
--- a/pypy/jit/backend/cli/test/conftest.py
+++ b/pypy/jit/backend/cli/test/conftest.py
@@ -1,4 +1,4 @@
import py
-def pytest_collect_directory(path):
- py.test.skip("CLI backend tests skipped for now")
+def pytest_ignore_collect(path):
+ return True
--- a/pypy/translator/benchmark/benchmarks.py
+++ /dev/null
@@ -1,197 +0,0 @@
-import os, sys, time, pickle, re, py
-import yaml
-
-class BenchmarkFailed(Exception):
- pass
-
-PYSTONE_CMD = 'from test import pystone;pystone.main(%s)'
-PYSTONE_PATTERN = 'This machine benchmarks at'
-
-RICHARDS_CMD = 'from richards import *;main(iterations=%d)'
-RICHARDS_PATTERN = 'Average time per iteration:'
-
-TIME_FMT = 'max mem used: %Mk\nelapsed time: %e\nsystem time: %S\nuser time: %U\nCPU use: %P'
-
-def get_result(txt, pattern):
- for line in txt.split('\n'):
- if line.startswith(pattern):
- break
- else:
- raise BenchmarkFailed
- return float(line.split()[len(pattern.split())])
-
-class Benchmark(object):
- def __init__(self, name, runner, asc_good, units,
- check=lambda:True, sizefactor=1):
- if sizefactor > 1:
- self.name = name + '*%d' % sizefactor
- else:
- self.name = name
- self._basename = name
- self._run = runner
- self.asc_good = asc_good
- self.units = units
- self.check = check
- self.sizefactor = sizefactor
- def __mul__(self, n):
- return Benchmark(self._basename, self._run, self.asc_good, self.units,
- self.check, self.sizefactor * n)
- def run(self, exe):
- self.latest_output = ''
- try:
- result, latest_output = self._run(exe, self.sizefactor)
- self.latest_output = latest_output
- except BenchmarkFailed, e:
- result = '-FAILED-'
- return result
-
-def external_dependency(dirname, svnurl, revision=None):
- directory = py.path.local(__file__).dirpath().join(dirname)
- wc = py.path.svnwc(directory)
- wc.checkout(svnurl, rev=revision)
- return True
-
-def run_cmd(cmd):
- pipe = os.popen(cmd + ' 2>&1')
- r = pipe.read()
- status = pipe.close()
- if status:
- raise BenchmarkFailed(status)
- return r
-
-def run_pystone(executable, sizefactor=1):
- from pypy.tool import autopath
- distdir = py.path.local(autopath.pypydir).dirpath()
- pystone = py.path.local(autopath.libpythondir).join('test', 'pystone.py')
- txt = run_cmd('"%s" "%s" %d' % (executable, pystone, 50000 * sizefactor))
- return get_result(txt, PYSTONE_PATTERN), txt
-
-def run_richards(executable, sizefactor=1):
- richards = py.path.local(__file__).dirpath().dirpath().join('goal').join('richards.py')
- txt = run_cmd('"%s" %s %d' % (executable, richards, 5 * sizefactor))
- return get_result(txt, RICHARDS_PATTERN), txt
-
-def run_translate(executable):
- translate = py.path.local(__file__).dirpath().dirpath().join('goal').join('translate.py')
- target = py.path.local(__file__).dirpath().dirpath().join('goal').join('targetrpystonedalone.py')
- argstr = '%s %s --batch --backendopt --no-compile %s > /dev/null 2> /dev/null'
- T = time.time()
- status = os.system(argstr%(executable, translate, target))
- r = time.time() - T
- if status:
- raise BenchmarkFailed(status)
- return r
-
-def run_templess(executable, sizefactor=1):
- """ run some script in the templess package
-
- templess is some simple templating language.
- We have a copy at
- 'http://codespeak.net/svn/user/arigo/hack/pypy-hack/templess'
- """
- here = py.path.local(__file__).dirpath()
- pypath = os.path.dirname(os.path.dirname(py.__file__))
- templessdir = here.join('templess')
- testscript = templessdir.join('test/oneshot.py')
- command = 'PYTHONPATH="%s:%s" "%s" "%s" %d' % (here, pypath,
- executable, testscript,
- 100 * sizefactor)
- txt = run_cmd(command)
- for line in txt.split('\n'):
- if '.' in line:
- try:
- return float(line) / sizefactor, txt
- except ValueError:
- pass
- else:
- raise BenchmarkFailed
-
-def check_templess():
- return external_dependency('templess',
- 'http://codespeak.net/svn/user/arigo/hack/pypy-hack/templess')
-
-def run_gadfly(executable, sizefactor=1):
- """ run some tests in the gadfly pure Python database """
- here = py.path.local(__file__).dirpath()
- gadfly = here.join('gadfly')
- testscript = gadfly.join('test', 'testsubset.py')
- command = 'PYTHONPATH="%s" "%s" "%s" %d' % (gadfly, executable, testscript,
- sizefactor)
- txt = run_cmd(command)
- return get_result(txt, 'Total running time:') / sizefactor, txt
-
-def check_gadfly():
- return external_dependency('gadfly',
- 'http://codespeak.net/svn/user/arigo/hack/pypy-hack/gadflyZip',
- 70117)
-
-def run_mako(executable, sizefactor=1):
- """ run some tests in the mako templating system """
- here = py.path.local(__file__).dirpath()
- mako = here.join('mako')
- testscript = mako.join('examples', 'bench', 'basic.py')
- command = 'PYTHONPATH="%s" "%s" "%s" -n%d mako' % (mako.join('lib'),
- executable, testscript,
- 2000 * sizefactor)
- txt = run_cmd(command)
- return get_result(txt, 'Mako:'), txt
-
-def check_mako():
- return external_dependency('mako',
- 'http://codespeak.net/svn/user/arigo/hack/pypy-hack/mako',
- 70118)
-
-def check_translate():
- return False # XXX what should we do about the dependency on ctypes?
-
-class LanguageShootoutBenchmark(Benchmark):
- def __init__(self, name, sizefactor=1, test=False):
- self.test = test
- self.basename = name
- Benchmark.__init__(self, name, self.runner, False, 'ms',
- self.check, sizefactor)
-
- def __mul__(self, i):
- return LanguageShootoutBenchmark(self.name, self.sizefactor * i,
- self.test)
-
- def runner(self, executable, sizefactor=1):
- shootout = py.path.local(__file__).dirpath().join(
- 'shootout_benchmarks')
- argsfile = shootout.join('tests.yml')
- if self.test:
- kind = 'test'
- else:
- kind = 'run'
- args = yaml.load(argsfile.read())[self.basename][kind]['args']
- progname = str(shootout.join(self.basename)) + '.py'
- cmd = 'time -f "%s" %s %s %s %d' % (TIME_FMT, executable, progname,
- " ".join(args), sizefactor)
- txt = run_cmd(cmd)
- return get_result(txt, 'elapsed time:'), txt
-
- def check(self):
- return external_dependency('shootout_benchmarks',
- 'http://codespeak.net/svn/pypy/benchmarks/shootout')
-
-BENCHMARKS = [Benchmark('richards', run_richards, False, 'ms'),
- Benchmark('pystone', run_pystone, True, ''),
- Benchmark('translate', run_translate, False, 'ms',
- check_translate),
- Benchmark('templess', run_templess, False,
- 's', check_templess),
- Benchmark('gadfly2', run_gadfly, False,
- 's', check_gadfly),
- Benchmark('mako', run_mako, False,
- 's', check_mako),
- ]
-
-SHOOTOUT_NAMES = ['binary-trees', 'fannkuch', 'fasta', 'float',
- 'meteor-contest', 'nbody', 'spectral-norm']
-
-#for name in SHOOTOUT_NAMES:
-# BENCHMARKS.append(LanguageShootoutBenchmark(name))
-
-BENCHMARKS_BY_NAME = {}
-for _b in BENCHMARKS:
- BENCHMARKS_BY_NAME[_b.name] = _b
--- a/pypy/jit/backend/x86/test/test_ztranslation.py
+++ b/pypy/jit/backend/x86/test/test_ztranslation.py
@@ -93,6 +93,9 @@ class TestTranslationX86(CCompiledMixin)
assert res == expected
def test_direct_assembler_call_translates(self):
+ """Test CALL_ASSEMBLER and the recursion limit"""
+ from pypy.rlib.rstackovf import StackOverflow
+
class Thing(object):
def __init__(self, val):
self.val = val
@@ -135,9 +138,35 @@ class TestTranslationX86(CCompiledMixin)
i += 1
return frame.thing.val
- res = self.meta_interp(main, [0], inline=True,
+ driver2 = JitDriver(greens = [], reds = ['n'])
+
+ def main2(bound):
+ try:
+ while portal2(bound) == -bound+1:
+ bound *= 2
+ except StackOverflow:
+ pass
+ return bound
+
+ def portal2(n):
+ while True:
+ driver2.jit_merge_point(n=n)
+ n -= 1
+ if n <= 0:
+ return n
+ n = portal2(n)
+ assert portal2(10) == -9
+
+ def mainall(codeno, bound):
+ return main(codeno) + main2(bound)
+
+ res = self.meta_interp(mainall, [0, 1], inline=True,
policy=StopAtXPolicy(change))
- assert res == main(0)
+ print hex(res)
+ assert res & 255 == main(0)
+ bound = res & ~255
+ assert 1024 <= bound <= 131072
+ assert bound & (bound-1) == 0 # a power of two
class TestTranslationRemoveTypePtrX86(CCompiledMixin):
--- a/pypy/jit/backend/x86/codebuf.py
+++ b/pypy/jit/backend/x86/codebuf.py
@@ -10,8 +10,10 @@ from pypy.jit.backend.x86 import valgrin
# like this
if IS_X86_32:
codebuilder_cls = X86_32_CodeBuilder
+ backend_name = 'x86'
elif IS_X86_64:
codebuilder_cls = X86_64_CodeBuilder
+ backend_name = 'x86_64'
class MachineCodeBlockWrapper(BlockBuilderMixin,
@@ -34,3 +36,4 @@ class MachineCodeBlockWrapper(BlockBuild
adr = rffi.cast(rffi.LONGP, p - WORD)
adr[0] = intmask(adr[0] - p)
valgrind.discard_translations(addr, self.get_relative_pos())
+ self._dump(addr, "jit-backend-dump", backend_name)
--- a/pypy/module/test_lib_pypy/ctypes_tests/conftest.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/conftest.py
@@ -1,9 +1,9 @@
import py
import sys
-def pytest_collect_directory():
+def pytest_ignore_collect(path):
if '__pypy__' not in sys.builtin_module_names:
- py.test.skip("these tests are meant to be run on top of pypy-c")
+ return True
def compile_so_file():
from pypy.translator.platform import platform
--- a/pypy/jit/backend/model.py
+++ b/pypy/jit/backend/model.py
@@ -8,6 +8,7 @@ class AbstractCPU(object):
done_with_this_frame_int_v = -1
done_with_this_frame_ref_v = -1
done_with_this_frame_float_v = -1
+ exit_frame_with_exception_v = -1
total_compiled_loops = 0
total_compiled_bridges = 0
total_freed_loops = 0
--- a/pypy/jit/backend/llvm/test/conftest.py
+++ b/pypy/jit/backend/llvm/test/conftest.py
@@ -1,4 +1,4 @@
import py
-def pytest_collect_directory():
- py.test.skip("llvm backend tests skipped for now")
+def pytest_ignore_collect(path):
+ return True
--- a/pypy/translator/benchmark/result.py
+++ /dev/null
@@ -1,188 +0,0 @@
-import os, pickle, sys, time, re
-
-STAT2TITLE = {
- 'stat:st_mtime': "date",
- 'exe_name': "executable",
-}
-
-def stat2title(s):
- if s.startswith('bench:'):
- return s[6:]
- else:
- return STAT2TITLE.get(s, s)
-
-
-class BenchmarkResultSet(object):
- def __init__(self, max_results=10):
- self.benchmarks = {}
- self.max_results = max_results
-
- def result(self, exe, allowcreate=False):
- if exe in self.benchmarks or not allowcreate:
- return self.benchmarks[exe]
- else:
- r = self.benchmarks[exe] = BenchmarkResult(exe, self.max_results)
- return r
-
- def txt_summary(self, stats, **kw):
- sortkey = kw.get('sortby', 'stat:st_mtime')
- lst = self.benchmarks.values()
- lst.sort(key=lambda x:x.getstat(sortkey, None), reverse=kw.get('reverse', False))
- if 'filteron' in kw:
- filteron = kw['filteron']
- lst = [r for r in lst if filteron(r)]
- relto = kw.get('relto', None)
- table = [[(stat2title(s),0) for s in stats]]
- for r in lst:
- row = []
- for stat in stats:
- if stat.startswith('bench:'):
- benchname = stat[6:]
- if r.getstat(stat, None) is None:
- row.append(('XXX',-1))
- elif relto:
- factor = self.result(relto).getstat(stat)/r.getstat(stat)
- if not r.asc_goods[benchname]:
- factor = 1/factor
- s, f = r.fmtstat(stat)
- row.append((s + ' (%6.2fx)'%factor, f))
- else:
- row.append(r.fmtstat(stat))
- else:
- row.append(r.fmtstat(stat))
- table.append(row)
- widths = [0 for thing in stats]
- for row in table:
- for i, cell in enumerate(row):
- widths[i] = max(len(cell[0]), widths[i])
- concretetable = []
- concreterow = []
- for w, cell in zip(widths, table[0]):
- concreterow.append(cell[0].center(w))
- concretetable.append(' '.join(concreterow))
- for row in table[1:]:
- concreterow = []
- for w, cell in zip(widths, row):
- concreterow.append("%*s"%(cell[1]*w, cell[0]))
- concretetable.append(' '.join(concreterow))
- return concretetable
-
-class BenchmarkResult(object):
- IDS = {}
-
- def __init__(self, exe, max_results=10):
- self.max_results = max_results
- self.exe_stat = os.stat(exe)
- self.exe_name = exe
- self.codesize = os.popen('size "%s" | tail -n1 | cut -f1'%(exe,)).read().strip()
- try:
- self.pypy_rev = int(os.popen(
- exe + ' -c "import sys; print sys.pypy_version_info[-1]" 2>/dev/null').read().strip())
- except ValueError:
- self.pypy_rev = -1
- self.best_benchmarks = {}
- self.benchmarks = {}
- self.asc_goods = {}
- self.run_counts = {}
-
- def run_benchmark(self, benchmark, verbose=False):
- self.asc_goods[benchmark.name] = benchmark.asc_good
- if self.run_counts.get(benchmark.name, 0) > self.max_results:
- return -1
- print 'running', benchmark.name, 'for', self.exe_name,
- if verbose and self.pypy_rev > 0:
- print '[rev %d]' % self.pypy_rev,
- sys.stdout.flush()
- new_result = benchmark.run(self.exe_name)
- print new_result
- if verbose:
- print '{'
- lines = benchmark.latest_output.splitlines(False)
- for line in lines[:80]:
- print '\t' + line
- if len(lines) > 80:
- print '\t....'
- print '}'
- self.run_counts[benchmark.name] = self.run_counts.get(benchmark.name, 0) + 1
- if new_result == '-FAILED-':
- return 0
- self.benchmarks.setdefault(benchmark.name, []).append(new_result)
- if benchmark.name in self.best_benchmarks:
- old_result = self.best_benchmarks[benchmark.name]
- if benchmark.asc_good:
- new_result = max(new_result, old_result)
- else:
- new_result = min(new_result, old_result)
- self.best_benchmarks[benchmark.name] = new_result
- return 1
-
- def getstat(self, *args):
- # oh for supplied-p!
- return_default = False
- if len(args) == 1:
- stat, = args
- else:
- stat, default = args
- return_default = True
- if hasattr(self, stat):
- return getattr(self, stat)
- if stat == 'exe':
- myid = len(BenchmarkResult.IDS)
- myid = BenchmarkResult.IDS.setdefault(self, myid)
- return '[%s]' % myid
- statkind, statdetail = stat.split(':')
- if statkind == 'stat':
- return getattr(self.exe_stat, statdetail)
- elif statkind == 'bench':
- if return_default:
- return self.best_benchmarks.get(statdetail, default)
- else:
- return self.best_benchmarks[statdetail]
- else:
- 1/0
-
- def fmtstat(self, *args):
- stat = args[0]
- statvalue = self.getstat(*args)
- if stat == 'stat:st_mtime':
- return time.ctime(statvalue), -1
- elif stat == 'exe_name':
- return os.path.basename(statvalue), -1
- elif stat.startswith('bench:'):
- from pypy.translator.benchmark import benchmarks
- statkind, statdetail = stat.split(':', 1)
- if '*' in statdetail:
- statdetail = statdetail.split('*')[0]
- b = benchmarks.BENCHMARKS_BY_NAME[statdetail]
- return "%8.2f%s"%(statvalue, b.units), 1
- elif stat == 'pypy_rev':
- return str(statvalue), 1
- else:
- return str(statvalue), -1
-
- def summary(self, stats):
- return [self.getstat(stat) for stat in stats]
-
- def is_stable(self, name):
- try:
- return self.n_results[name] >= self.max_results
- except:
- return False
-
-if __name__ == '__main__':
- import autopath
- from pypy.translator.benchmark import benchmarks, result
- import cPickle
- if os.path.exists('foo.pickle'):
- s = cPickle.load(open('foo.pickle', 'rb'))
- else:
- s = result.BenchmarkResultSet(4)
- for exe in sys.argv[1:]:
- r = s.result(exe)
- r.run_benchmark(benchmarks.BENCHMARKS_BY_NAME['richards'])
- r.run_benchmark(benchmarks.BENCHMARKS_BY_NAME['pystone'])
- cPickle.dump(s, open('foo.pickle', 'wb'))
- stats = ['stat:st_mtime', 'exe_name', 'bench:richards', 'bench:pystone']
-
- for row in s.txt_summary(stats, sortby="exe_name", reverse=True, relto="/usr/local/bin/python2.4"):
- print row
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -84,6 +84,7 @@ class Assembler386(object):
self.fail_boxes_count = 0
self._current_depths_cache = (0, 0)
self.datablockwrapper = None
+ self.stack_check_slowpath = 0
self.teardown()
def leave_jitted_hook(self):
@@ -122,6 +123,7 @@ class Assembler386(object):
self._build_float_constants()
if hasattr(gc_ll_descr, 'get_malloc_fixedsize_slowpath_addr'):
self._build_malloc_fixedsize_slowpath()
+ self._build_stack_check_slowpath()
debug_start('jit-backend-counts')
self.set_debug(have_debug_prints())
debug_stop('jit-backend-counts')
@@ -194,6 +196,81 @@ class Assembler386(object):
rawstart = mc.materialize(self.cpu.asmmemmgr, [])
self.malloc_fixedsize_slowpath2 = rawstart
+ def _build_stack_check_slowpath(self):
+ from pypy.rlib import rstack
+ _, _, slowpathaddr = self.cpu.insert_stack_check()
+ if slowpathaddr == 0 or self.cpu.exit_frame_with_exception_v < 0:
+ return # no stack check (for tests, or non-translated)
+ #
+ mc = codebuf.MachineCodeBlockWrapper()
+ mc.PUSH_r(ebp.value)
+ mc.MOV_rr(ebp.value, esp.value)
+ #
+ if IS_X86_64:
+ # on the x86_64, we have to save all the registers that may
+ # have been used to pass arguments
+ for reg in [edi, esi, edx, ecx, r8, r9]:
+ mc.PUSH_r(reg.value)
+ mc.SUB_ri(esp.value, 8*8)
+ for i in range(8):
+ mc.MOVSD_sx(8*i, i) # xmm0 to xmm7
+ #
+ if IS_X86_32:
+ mc.LEA_rb(eax.value, +8)
+ mc.PUSH_r(eax.value)
+ elif IS_X86_64:
+ mc.LEA_rb(edi.value, +16)
+ mc.AND_ri(esp.value, -16)
+ #
+ mc.CALL(imm(slowpathaddr))
+ #
+ mc.MOV(eax, heap(self.cpu.pos_exception()))
+ mc.TEST_rr(eax.value, eax.value)
+ mc.J_il8(rx86.Conditions['NZ'], 0)
+ jnz_location = mc.get_relative_pos()
+ #
+ if IS_X86_64:
+ # restore the registers
+ for i in range(7, -1, -1):
+ mc.MOVSD_xs(i, 8*i)
+ for i, reg in [(6, r9), (5, r8), (4, ecx),
+ (3, edx), (2, esi), (1, edi)]:
+ mc.MOV_rb(reg.value, -8*i)
+ #
+ mc.MOV_rr(esp.value, ebp.value)
+ mc.POP_r(ebp.value)
+ mc.RET()
+ #
+ # patch the JNZ above
+ offset = mc.get_relative_pos() - jnz_location
+ assert 0 < offset <= 127
+ mc.overwrite(jnz_location-1, chr(offset))
+ # clear the exception from the global position
+ mc.MOV(eax, heap(self.cpu.pos_exc_value()))
+ mc.MOV(heap(self.cpu.pos_exception()), imm0)
+ mc.MOV(heap(self.cpu.pos_exc_value()), imm0)
+ # save the current exception instance into fail_boxes_ptr[0]
+ adr = self.fail_boxes_ptr.get_addr_for_num(0)
+ mc.MOV(heap(adr), eax)
+ # call the helper function to set the GC flag on the fail_boxes_ptr
+ # array (note that there is no exception any more here)
+ addr = self.cpu.get_on_leave_jitted_int(save_exception=False)
+ mc.CALL(imm(addr))
+ #
+ mc.MOV_ri(eax.value, self.cpu.exit_frame_with_exception_v)
+ #
+ # footer -- note the ADD, which skips the return address of this
+ # function, and will instead return to the caller's caller. Note
+ # also that we completely ignore the saved arguments, because we
+ # are interrupting the function.
+ mc.MOV_rr(esp.value, ebp.value)
+ mc.POP_r(ebp.value)
+ mc.ADD_ri(esp.value, WORD)
+ mc.RET()
+ #
+ rawstart = mc.materialize(self.cpu.asmmemmgr, [])
+ self.stack_check_slowpath = rawstart
+
def assemble_loop(self, inputargs, operations, looptoken, log):
'''adds the following attributes to looptoken:
_x86_loop_code (an integer giving an address)
@@ -468,6 +545,24 @@ class Assembler386(object):
for regloc in self.cpu.CALLEE_SAVE_REGISTERS:
self.mc.PUSH_r(regloc.value)
+ def _call_header_with_stack_check(self):
+ if self.stack_check_slowpath == 0:
+ pass # no stack check (e.g. not translated)
+ else:
+ startaddr, length, _ = self.cpu.insert_stack_check()
+ self.mc.MOV(eax, esp) # MOV eax, current
+ self.mc.SUB(eax, heap(startaddr)) # SUB eax, [startaddr]
+ self.mc.CMP(eax, imm(length)) # CMP eax, length
+ self.mc.J_il8(rx86.Conditions['B'], 0) # JB .skip
+ jb_location = self.mc.get_relative_pos()
+ self.mc.CALL(imm(self.stack_check_slowpath))# CALL slowpath
+ # patch the JB above # .skip:
+ offset = self.mc.get_relative_pos() - jb_location
+ assert 0 < offset <= 127
+ self.mc.overwrite(jb_location-1, chr(offset))
+ #
+ self._call_header()
+
def _call_footer(self):
self.mc.LEA_rb(esp.value, -len(self.cpu.CALLEE_SAVE_REGISTERS) * WORD)
@@ -485,7 +580,7 @@ class Assembler386(object):
# XXX this can be improved greatly. Right now it'll behave like
# a normal call
nonfloatlocs, floatlocs = arglocs
- self._call_header()
+ self._call_header_with_stack_check()
self.mc.LEA_rb(esp.value, self._get_offset_of_ebp_from_esp(stackdepth))
for i in range(len(nonfloatlocs)):
loc = nonfloatlocs[i]
@@ -526,7 +621,7 @@ class Assembler386(object):
unused_xmm = [xmm7, xmm6, xmm5, xmm4, xmm3, xmm2, xmm1, xmm0]
nonfloatlocs, floatlocs = arglocs
- self._call_header()
+ self._call_header_with_stack_check()
self.mc.LEA_rb(esp.value, self._get_offset_of_ebp_from_esp(stackdepth))
# The lists are padded with Nones
More information about the Pypy-commit
mailing list