[pypy-commit] pypy py3k: hg merge default
mjacob
pypy.commits at gmail.com
Fri Feb 19 13:05:11 EST 2016
Author: Manuel Jacob <me at manueljacob.de>
Branch: py3k
Changeset: r82329:4634d8e8bf6e
Date: 2016-02-19 19:04 +0100
http://bitbucket.org/pypy/pypy/changeset/4634d8e8bf6e/
Log: hg merge default
diff --git a/lib-python/2.7/distutils/command/build_ext.py b/lib-python/2.7/distutils/command/build_ext.py
--- a/lib-python/2.7/distutils/command/build_ext.py
+++ b/lib-python/2.7/distutils/command/build_ext.py
@@ -188,7 +188,7 @@
# the 'libs' directory is for binary installs - we assume that
# must be the *native* platform. But we don't really support
# cross-compiling via a binary install anyway, so we let it go.
- self.library_dirs.append(os.path.join(sys.exec_prefix, 'include'))
+ self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs'))
if self.debug:
self.build_temp = os.path.join(self.build_temp, "Debug")
else:
diff --git a/lib_pypy/_pypy_testcapi.py b/lib_pypy/_pypy_testcapi.py
--- a/lib_pypy/_pypy_testcapi.py
+++ b/lib_pypy/_pypy_testcapi.py
@@ -62,7 +62,7 @@
if sys.platform == 'win32':
# XXX pyconfig.h uses a pragma to link to the import library,
# which is currently python3.lib
- library = os.path.join(thisdir, '..', 'include', 'python32')
+ library = os.path.join(thisdir, '..', 'libs', 'python32')
if not os.path.exists(library + '.lib'):
# For a local translation or nightly build
library = os.path.join(thisdir, '..', 'pypy', 'goal', 'python32')
diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO
--- a/lib_pypy/cffi.egg-info/PKG-INFO
+++ b/lib_pypy/cffi.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: cffi
-Version: 1.5.1
+Version: 1.5.2
Summary: Foreign Function Interface for Python calling C code.
Home-page: http://cffi.readthedocs.org
Author: Armin Rigo, Maciej Fijalkowski
diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -4,8 +4,8 @@
from .api import FFI, CDefError, FFIError
from .ffiplatform import VerificationError, VerificationMissing
-__version__ = "1.5.1"
-__version_info__ = (1, 5, 1)
+__version__ = "1.5.2"
+__version_info__ = (1, 5, 2)
# The verifier module file names are based on the CRC32 of a string that
# contains the following version number. It may be older than __version__
diff --git a/lib_pypy/cffi/_embedding.h b/lib_pypy/cffi/_embedding.h
--- a/lib_pypy/cffi/_embedding.h
+++ b/lib_pypy/cffi/_embedding.h
@@ -233,7 +233,7 @@
f = PySys_GetObject((char *)"stderr");
if (f != NULL && f != Py_None) {
PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME
- "\ncompiled with cffi version: 1.5.1"
+ "\ncompiled with cffi version: 1.5.2"
"\n_cffi_backend module: ", f);
modules = PyImport_GetModuleDict();
mod = PyDict_GetItemString(modules, "_cffi_backend");
diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py
--- a/lib_pypy/cffi/api.py
+++ b/lib_pypy/cffi/api.py
@@ -1,4 +1,4 @@
-import sys, sysconfig, types
+import sys, types
from .lock import allocate_lock
try:
@@ -550,16 +550,34 @@
lst.append(value)
#
if '__pypy__' in sys.builtin_module_names:
+ import os
+ if sys.platform == "win32":
+ # we need 'libpypy-c.lib'. Current distributions of
+ # pypy (>= 4.1) contain it as 'libs/python27.lib'.
+ pythonlib = "python27"
+ if hasattr(sys, 'prefix'):
+ ensure('library_dirs', os.path.join(sys.prefix, 'libs'))
+ else:
+ # we need 'libpypy-c.{so,dylib}', which should be by
+ # default located in 'sys.prefix/bin' for installed
+ # systems.
+ pythonlib = "pypy-c"
+ if hasattr(sys, 'prefix'):
+ ensure('library_dirs', os.path.join(sys.prefix, 'bin'))
+ # On uninstalled pypy's, the libpypy-c is typically found in
+ # .../pypy/goal/.
if hasattr(sys, 'prefix'):
- import os
- ensure('library_dirs', os.path.join(sys.prefix, 'bin'))
- pythonlib = "pypy-c"
+ ensure('library_dirs', os.path.join(sys.prefix, 'pypy', 'goal'))
else:
if sys.platform == "win32":
template = "python%d%d"
if hasattr(sys, 'gettotalrefcount'):
template += '_d'
else:
+ try:
+ import sysconfig
+ except ImportError: # 2.6
+ from distutils import sysconfig
template = "python%d.%d"
if sysconfig.get_config_var('DEBUG_EXT'):
template += sysconfig.get_config_var('DEBUG_EXT')
diff --git a/lib_pypy/cffi/vengine_cpy.py b/lib_pypy/cffi/vengine_cpy.py
--- a/lib_pypy/cffi/vengine_cpy.py
+++ b/lib_pypy/cffi/vengine_cpy.py
@@ -1,3 +1,6 @@
+#
+# DEPRECATED: implementation for ffi.verify()
+#
import sys, imp
from . import model, ffiplatform
diff --git a/lib_pypy/cffi/vengine_gen.py b/lib_pypy/cffi/vengine_gen.py
--- a/lib_pypy/cffi/vengine_gen.py
+++ b/lib_pypy/cffi/vengine_gen.py
@@ -1,3 +1,6 @@
+#
+# DEPRECATED: implementation for ffi.verify()
+#
import sys, os
import types
diff --git a/lib_pypy/cffi/verifier.py b/lib_pypy/cffi/verifier.py
--- a/lib_pypy/cffi/verifier.py
+++ b/lib_pypy/cffi/verifier.py
@@ -1,3 +1,6 @@
+#
+# DEPRECATED: implementation for ffi.verify()
+#
import sys, os, binascii, shutil, io
from . import __version_verifier_modules__
from . import ffiplatform
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -37,13 +37,16 @@
"thread", "itertools", "pyexpat", "_ssl", "cpyext", "array",
"binascii", "_multiprocessing", '_warnings', "_collections",
"_multibytecodec", "_continuation", "_cffi_backend",
- "_csv", "_pypyjson", "_vmprof", "_posixsubprocess", # "cppyy", "micronumpy"
+ "_csv", "_pypyjson", "_posixsubprocess", # "cppyy", "micronumpy"
])
-#if ((sys.platform.startswith('linux') or sys.platform == 'darwin')
-# and os.uname()[4] == 'x86_64' and sys.maxint > 2**32):
- # it's not enough that we get x86_64
-# working_modules.add('_vmprof')
+from rpython.jit.backend import detect_cpu
+try:
+ if detect_cpu.autodetect().startswith('x86'):
+ working_modules.add('_vmprof')
+except detect_cpu.ProcessorAutodetectError:
+ pass
+
translation_modules = default_modules.copy()
translation_modules.update([
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -7,6 +7,9 @@
Fixed ``_PyLong_FromByteArray()``, which was buggy.
+Fixed a crash with stacklets (or greenlets) on non-Linux machines
+which showed up if you forget stacklets without resuming them.
+
.. branch: numpy-1.10
Fix tests to run cleanly with -A and start to fix micronumpy for upstream numpy
@@ -38,7 +41,8 @@
.. branch: compress-numbering
-Improve the memory signature of numbering instances in the JIT.
+Improve the memory signature of numbering instances in the JIT. This should massively
+decrease the amount of memory consumed by the JIT, which is significant for most programs.
.. branch: fix-trace-too-long-heuristic
@@ -148,3 +152,14 @@
Seperate structmember.h from Python.h Also enhance creating api functions
to specify which header file they appear in (previously only pypy_decl.h)
+
+.. branch: llimpl
+
+Refactor register_external(), remove running_on_llinterp mechanism and
+apply sandbox transform on externals at the end of annotation.
+
+.. branch: cffi-embedding-win32
+
+.. branch: windows-vmprof-support
+
+vmprof should work on Windows.
diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -246,6 +246,9 @@
raise Exception("Cannot use the --output option with PyPy "
"when --shared is on (it is by default). "
"See issue #1971.")
+ if sys.platform == 'win32':
+ config.translation.libname = '..\\..\\libs\\python27.lib'
+ thisdir.join('..', '..', 'libs').ensure(dir=1)
if config.translation.thread:
config.objspace.usemodules.thread = True
diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py
--- a/pypy/module/_cffi_backend/__init__.py
+++ b/pypy/module/_cffi_backend/__init__.py
@@ -3,7 +3,7 @@
from rpython.rlib import rdynload, clibffi, entrypoint
from rpython.rtyper.lltypesystem import rffi
-VERSION = "1.5.1"
+VERSION = "1.5.2"
FFI_DEFAULT_ABI = clibffi.FFI_DEFAULT_ABI
try:
diff --git a/pypy/module/_cffi_backend/embedding.py b/pypy/module/_cffi_backend/embedding.py
--- a/pypy/module/_cffi_backend/embedding.py
+++ b/pypy/module/_cffi_backend/embedding.py
@@ -57,7 +57,7 @@
# pypy_init_embedded_cffi_module().
if not glob.patched_sys:
space.appexec([], """():
- import os
+ import os, sys
sys.stdin = sys.__stdin__ = os.fdopen(0, 'rb', 0)
sys.stdout = sys.__stdout__ = os.fdopen(1, 'wb', 0)
sys.stderr = sys.__stderr__ = os.fdopen(2, 'wb', 0)
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -1,7 +1,7 @@
# ____________________________________________________________
import sys
-assert __version__ == "1.5.1", ("This test_c.py file is for testing a version"
+assert __version__ == "1.5.2", ("This test_c.py file is for testing a version"
" of cffi that differs from the one that we"
" get from 'import _cffi_backend'")
if sys.version_info < (3,):
diff --git a/pypy/module/sys/interp_encoding.py b/pypy/module/sys/interp_encoding.py
--- a/pypy/module/sys/interp_encoding.py
+++ b/pypy/module/sys/interp_encoding.py
@@ -33,7 +33,7 @@
def _getfilesystemencoding(space):
encoding = base_encoding
- if rlocale.HAVE_LANGINFO and rlocale.CODESET:
+ if rlocale.HAVE_LANGINFO:
try:
oldlocale = rlocale.setlocale(rlocale.LC_CTYPE, None)
rlocale.setlocale(rlocale.LC_CTYPE, "")
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_zintegration.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_zintegration.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_zintegration.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_zintegration.py
@@ -5,6 +5,9 @@
if sys.platform == 'win32':
py.test.skip('snippets do not run on win32')
+if sys.version_info < (2, 7):
+ py.test.skip('fails e.g. on a Debian/Ubuntu which patches virtualenv'
+ ' in a non-2.6-friendly way')
def create_venv(name):
tmpdir = udir.join(name)
diff --git a/pypy/module/test_lib_pypy/cffi_tests/embedding/test_basic.py b/pypy/module/test_lib_pypy/cffi_tests/embedding/test_basic.py
--- a/pypy/module/test_lib_pypy/cffi_tests/embedding/test_basic.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/embedding/test_basic.py
@@ -28,11 +28,14 @@
def prefix_pythonpath():
cffi_base = os.path.dirname(os.path.dirname(local_dir))
- pythonpath = os.environ.get('PYTHONPATH', '').split(os.pathsep)
+ pythonpath = org_env.get('PYTHONPATH', '').split(os.pathsep)
if cffi_base not in pythonpath:
pythonpath.insert(0, cffi_base)
return os.pathsep.join(pythonpath)
+def setup_module(mod):
+ mod.org_env = os.environ.copy()
+
class EmbeddingTests:
_compiled_modules = {}
@@ -46,14 +49,12 @@
def get_path(self):
return str(self._path.ensure(dir=1))
- def _run_base(self, args, env_extra={}, **kwds):
- print('RUNNING:', args, env_extra, kwds)
- env = os.environ.copy()
- env.update(env_extra)
- return subprocess.Popen(args, env=env, **kwds)
+ def _run_base(self, args, **kwds):
+ print('RUNNING:', args, kwds)
+ return subprocess.Popen(args, **kwds)
- def _run(self, args, env_extra={}):
- popen = self._run_base(args, env_extra, cwd=self.get_path(),
+ def _run(self, args):
+ popen = self._run_base(args, cwd=self.get_path(),
stdout=subprocess.PIPE,
universal_newlines=True)
output = popen.stdout.read()
@@ -65,6 +66,7 @@
return output
def prepare_module(self, name):
+ self.patch_environment()
if name not in self._compiled_modules:
path = self.get_path()
filename = '%s.py' % name
@@ -74,9 +76,8 @@
# find a solution to that: we could hack sys.path inside the
# script run here, but we can't hack it in the same way in
# execute().
- env_extra = {'PYTHONPATH': prefix_pythonpath()}
- output = self._run([sys.executable, os.path.join(local_dir, filename)],
- env_extra=env_extra)
+ output = self._run([sys.executable,
+ os.path.join(local_dir, filename)])
match = re.compile(r"\bFILENAME: (.+)").search(output)
assert match
dynamic_lib_name = match.group(1)
@@ -101,6 +102,7 @@
c = distutils.ccompiler.new_compiler()
print('compiling %s with %r' % (name, modules))
extra_preargs = []
+ debug = True
if sys.platform == 'win32':
libfiles = []
for m in modules:
@@ -109,29 +111,45 @@
libfiles.append('Release\\%s.lib' % m[:-4])
modules = libfiles
extra_preargs.append('/MANIFEST')
+ debug = False # you need to install extra stuff
+ # for this to work
elif threads:
extra_preargs.append('-pthread')
- objects = c.compile([filename], macros=sorted(defines.items()), debug=True)
+ objects = c.compile([filename], macros=sorted(defines.items()),
+ debug=debug)
c.link_executable(objects + modules, name, extra_preargs=extra_preargs)
finally:
os.chdir(curdir)
+ def patch_environment(self):
+ path = self.get_path()
+ # for libpypy-c.dll or Python27.dll
+ path = os.path.split(sys.executable)[0] + os.path.pathsep + path
+ env_extra = {'PYTHONPATH': prefix_pythonpath()}
+ if sys.platform == 'win32':
+ envname = 'PATH'
+ else:
+ envname = 'LD_LIBRARY_PATH'
+ libpath = org_env.get(envname)
+ if libpath:
+ libpath = path + os.path.pathsep + libpath
+ else:
+ libpath = path
+ env_extra[envname] = libpath
+ for key, value in sorted(env_extra.items()):
+ if os.environ.get(key) != value:
+ print '* setting env var %r to %r' % (key, value)
+ os.environ[key] = value
+
def execute(self, name):
path = self.get_path()
- env_extra = {'PYTHONPATH': prefix_pythonpath()}
- libpath = os.environ.get('LD_LIBRARY_PATH')
- if libpath:
- libpath = path + ':' + libpath
- else:
- libpath = path
- env_extra['LD_LIBRARY_PATH'] = libpath
print('running %r in %r' % (name, path))
executable_name = name
if sys.platform == 'win32':
executable_name = os.path.join(path, executable_name + '.exe')
else:
executable_name = os.path.join('.', executable_name)
- popen = self._run_base([executable_name], env_extra, cwd=path,
+ popen = self._run_base([executable_name], cwd=path,
stdout=subprocess.PIPE,
universal_newlines=True)
result = popen.stdout.read()
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -111,13 +111,8 @@
#
builddir = py.path.local(options.builddir)
pypydir = builddir.ensure(name, dir=True)
+
includedir = basedir.join('include')
- # Recursively copy all headers, shutil has only ignore
- # so we do a double-negative to include what we want
- def copyonly(dirpath, contents):
- return set(contents) - set( # XXX function not used?
- shutil.ignore_patterns('*.h', '*.incl')(dirpath, contents),
- )
shutil.copytree(str(includedir), str(pypydir.join('include')))
pypydir.ensure('include', dir=True)
@@ -132,9 +127,6 @@
win_extras = ['libpypy-c.dll', 'sqlite3.dll']
if not options.no_tk:
win_extras += ['tcl85.dll', 'tk85.dll']
- # add the .lib too, which is convenient to compile other programs
- # that use the .dll (and for cffi's embedding mode)
- win_extras.append('libpypy-c.lib')
for extra in win_extras:
p = pypy_c.dirpath().join(extra)
@@ -145,32 +137,27 @@
continue
print "Picking %s" % p
binaries.append((p, p.basename))
- importlib_name = 'libpypy-c.lib'
- if pypy_c.dirpath().join(importlib_name).check():
- try:
- ver = subprocess.check_output([r'pypy\goal\pypy-c','-c',
- "import sys;print(sys.version)"])
- importlib_target = 'python%s%s.lib' % (ver[0], ver[2])
- shutil.copyfile(str(pypy_c.dirpath().join(importlib_name)),
- str(pypydir.join(importlib_target)))
- # XXX fix this, either an additional build step or rename
- # both DLL and LIB to versioned names, like cpython
- shutil.copyfile(str(pypy_c.dirpath().join(importlib_name)),
- str(pypy_c.dirpath().join(importlib_target)))
- print "Picking %s as %s" % (pypy_c.dirpath().join(importlib_name),
- pypydir.join('include', importlib_target))
- except:
- pass
+ libsdir = basedir.join('libs')
+ if libsdir.exists():
+ print 'Picking %s (and contents)' % libsdir
+ shutil.copytree(str(libsdir), str(pypydir.join('libs')))
else:
- pass
- # XXX users will complain that they cannot compile cpyext
- # modules for windows, has the lib moved or are there no
- # exported functions in the dll so no import library is created?
+ print '"libs" dir with import library not found.'
+ print 'You have to create %r' % (str(libsdir),)
+ print 'and copy libpypy-c.lib in there, renamed to python32.lib'
+ # XXX users will complain that they cannot compile capi (cpyext)
+ # modules for windows, also embedding pypy (i.e. in cffi)
+ # will fail.
+ # Has the lib moved, was translation not 'shared', or are
+ # there no exported functions in the dll so no import
+ # library was created?
if not options.no_tk:
try:
p = pypy_c.dirpath().join('tcl85.dll')
if not p.check():
p = py.path.local.sysfind('tcl85.dll')
+ if p is None:
+ raise WindowsError("tcl85.dll not found")
tktcldir = p.dirpath().join('..').join('lib')
shutil.copytree(str(tktcldir), str(pypydir.join('tcl')))
except WindowsError:
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -551,20 +551,6 @@
emulated = callback
return self.pbc_call(pbc, args, emulated=emulated)
- def _find_current_op(self, opname=None, arity=None, pos=None, s_type=None):
- """ Find operation that is currently being annotated. Do some
- sanity checks to see whether the correct op was found."""
- # XXX XXX HACK HACK HACK
- fn, block, i = self.position_key
- op = block.operations[i]
- if opname is not None:
- assert op.opname == opname
- if arity is not None:
- assert len(op.args) == arity
- if pos is not None:
- assert self.annotator.binding(op.args[pos]) == s_type
- return op
-
def whereami(self):
return self.annotator.whereami(self.position_key)
diff --git a/rpython/annotator/policy.py b/rpython/annotator/policy.py
--- a/rpython/annotator/policy.py
+++ b/rpython/annotator/policy.py
@@ -3,6 +3,9 @@
from rpython.annotator.specialize import (
specialize_argvalue, specialize_argtype, specialize_arglistitemtype,
specialize_arg_or_var, memo, specialize_call_location)
+from rpython.flowspace.operation import op
+from rpython.flowspace.model import Constant
+from rpython.annotator.model import SomeTuple
class AnnotatorPolicy(object):
@@ -64,7 +67,34 @@
return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args)
def no_more_blocks_to_annotate(pol, annotator):
+ bk = annotator.bookkeeper
# hint to all pending specializers that we are done
- for callback in annotator.bookkeeper.pending_specializations:
+ for callback in bk.pending_specializations:
callback()
- del annotator.bookkeeper.pending_specializations[:]
+ del bk.pending_specializations[:]
+ if annotator.added_blocks is not None:
+ all_blocks = annotator.added_blocks
+ else:
+ all_blocks = annotator.annotated
+ for block in list(all_blocks):
+ for i, instr in enumerate(block.operations):
+ if not isinstance(instr, (op.simple_call, op.call_args)):
+ continue
+ v_func = instr.args[0]
+ s_func = annotator.annotation(v_func)
+ if not hasattr(s_func, 'needs_sandboxing'):
+ continue
+ key = ('sandboxing', s_func.const)
+ if key not in bk.emulated_pbc_calls:
+ params_s = s_func.args_s
+ s_result = s_func.s_result
+ from rpython.translator.sandbox.rsandbox import make_sandbox_trampoline
+ sandbox_trampoline = make_sandbox_trampoline(
+ s_func.name, params_s, s_result)
+ sandbox_trampoline._signature_ = [SomeTuple(items=params_s)], s_result
+ bk.emulate_pbc_call(key, bk.immutablevalue(sandbox_trampoline), params_s)
+ else:
+ s_trampoline = bk.emulated_pbc_calls[key][0]
+ sandbox_trampoline = s_trampoline.const
+ new = instr.replace({instr.args[0]: Constant(sandbox_trampoline)})
+ block.operations[i] = new
diff --git a/rpython/annotator/specialize.py b/rpython/annotator/specialize.py
--- a/rpython/annotator/specialize.py
+++ b/rpython/annotator/specialize.py
@@ -317,18 +317,6 @@
yield (value,) + tuple_tail
-def make_constgraphbuilder(n, v=None, factory=None, srcmodule=None):
- def constgraphbuilder(translator, ignore):
- args = ','.join(["arg%d" % i for i in range(n)])
- if factory is not None:
- computed_v = factory()
- else:
- computed_v = v
- miniglobals = {'v': computed_v, '__name__': srcmodule}
- exec py.code.Source("constf = lambda %s: v" % args).compile() in miniglobals
- return translator.buildflowgraph(miniglobals['constf'])
- return constgraphbuilder
-
def maybe_star_args(funcdesc, key, args_s):
args_s, key1, builder = flatten_star_args(funcdesc, args_s)
if key1 is not None:
diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py
--- a/rpython/annotator/unaryop.py
+++ b/rpython/annotator/unaryop.py
@@ -113,8 +113,9 @@
@op.simple_call.register(SomeObject)
def simple_call_SomeObject(annotator, func, *args):
- return annotator.annotation(func).call(
- simple_args([annotator.annotation(arg) for arg in args]))
+ s_func = annotator.annotation(func)
+ argspec = simple_args([annotator.annotation(arg) for arg in args])
+ return s_func.call(argspec)
@op.call_args.register_transform(SomeObject)
def transform_varargs(annotator, v_func, v_shape, *data_v):
diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py
--- a/rpython/config/translationoption.py
+++ b/rpython/config/translationoption.py
@@ -192,6 +192,8 @@
"If true, makes an lldebug0 build", default=False,
cmdline="--lldebug0"),
StrOption("icon", "Path to the (Windows) icon to use for the executable"),
+ StrOption("libname",
+ "Windows: name and possibly location of the lib file to create"),
OptionDescription("backendopt", "Backend Optimization Options", [
# control inlining
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -380,7 +380,7 @@
raise InvalidLoop("promote of a virtual")
old_guard_op = info.get_last_guard(self.optimizer)
if old_guard_op is not None:
- op = self.replace_guard_class_with_guard_value(op, info,
+ op = self.replace_old_guard_with_guard_value(op, info,
old_guard_op)
elif arg0.type == 'f':
arg0 = self.get_box_replacement(arg0)
@@ -390,11 +390,26 @@
assert isinstance(constbox, Const)
self.optimize_guard(op, constbox)
- def replace_guard_class_with_guard_value(self, op, info, old_guard_op):
- if old_guard_op.opnum != rop.GUARD_NONNULL:
- previous_classbox = info.get_known_class(self.optimizer.cpu)
- expected_classbox = self.optimizer.cpu.ts.cls_of_box(op.getarg(1))
- assert previous_classbox is not None
+ def replace_old_guard_with_guard_value(self, op, info, old_guard_op):
+ # there already has been a guard_nonnull or guard_class or
+ # guard_nonnull_class on this value, which is rather silly.
+ # This function replaces the original guard with a
+ # guard_value. Must be careful: doing so is unsafe if the
+ # original guard checks for something inconsistent,
+ # i.e. different than what it would give if the guard_value
+ # passed (this is a rare case, but possible). If we get
+ # inconsistent results in this way, then we must not do the
+ # replacement, otherwise we'd put guard_value up there but all
+ # intermediate ops might be executed by assuming something
+ # different, from the old guard that is now removed...
+
+ c_value = op.getarg(1)
+ if not c_value.nonnull():
+ raise InvalidLoop('A GUARD_VALUE(..., NULL) follows some other '
+ 'guard that it is not NULL')
+ previous_classbox = info.get_known_class(self.optimizer.cpu)
+ if previous_classbox is not None:
+ expected_classbox = self.optimizer.cpu.ts.cls_of_box(c_value)
assert expected_classbox is not None
if not previous_classbox.same_constant(
expected_classbox):
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -3063,6 +3063,16 @@
self.optimize_loop(ops, expected, preamble)
#self.check_expanded_fail_descr("i0", rop.GUARD_VALUE)
+ def test_invalid_guard_value_after_guard_class(self):
+ ops = """
+ [p1, i0, i1, i2, p2]
+ guard_class(p1, ConstClass(node_vtable)) [i0]
+ i3 = int_add(i1, i2)
+ guard_value(p1, NULL) [i1]
+ jump(p2, i0, i1, i3, p2)
+ """
+ self.raises(InvalidLoop, self.optimize_loop, ops, ops)
+
def test_guard_class_oois(self):
ops = """
[p1]
diff --git a/rpython/memory/gctransform/test/test_transform.py b/rpython/memory/gctransform/test/test_transform.py
--- a/rpython/memory/gctransform/test/test_transform.py
+++ b/rpython/memory/gctransform/test/test_transform.py
@@ -5,6 +5,7 @@
from rpython.translator.exceptiontransform import ExceptionTransformer
from rpython.rtyper.lltypesystem import lltype
from rpython.conftest import option
+from rpython.rtyper.rtyper import llinterp_backend
class LLInterpedTranformerTests:
@@ -131,8 +132,10 @@
def rtype(func, inputtypes, specialize=True):
t = TranslationContext()
t.buildannotator().build_types(func, inputtypes)
+ rtyper = t.buildrtyper()
+ rtyper.backend = llinterp_backend
if specialize:
- t.buildrtyper().specialize()
+ rtyper.specialize()
if option.view:
t.view()
return t
diff --git a/rpython/memory/test/test_transformed_gc.py b/rpython/memory/test/test_transformed_gc.py
--- a/rpython/memory/test/test_transformed_gc.py
+++ b/rpython/memory/test/test_transformed_gc.py
@@ -14,6 +14,7 @@
from rpython.conftest import option
from rpython.rlib.rstring import StringBuilder
from rpython.rlib.rarithmetic import LONG_BIT
+from rpython.rtyper.rtyper import llinterp_backend
WORD = LONG_BIT // 8
@@ -29,9 +30,11 @@
t.config.set(**extraconfigopts)
ann = t.buildannotator()
ann.build_types(func, inputtypes)
+ rtyper = t.buildrtyper()
+ rtyper.backend = llinterp_backend
if specialize:
- t.buildrtyper().specialize()
+ rtyper.specialize()
if backendopt:
from rpython.translator.backendopt.all import backend_optimizations
backend_optimizations(t)
diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py
--- a/rpython/rlib/objectmodel.py
+++ b/rpython/rlib/objectmodel.py
@@ -275,8 +275,6 @@
return lltype.Signed
malloc_zero_filled = CDefinedIntSymbolic('MALLOC_ZERO_FILLED', default=0)
-running_on_llinterp = CDefinedIntSymbolic('RUNNING_ON_LLINTERP', default=1)
-# running_on_llinterp is meant to have the value 0 in all backends
# ____________________________________________________________
diff --git a/rpython/rlib/rvmprof/cintf.py b/rpython/rlib/rvmprof/cintf.py
--- a/rpython/rlib/rvmprof/cintf.py
+++ b/rpython/rlib/rvmprof/cintf.py
@@ -7,8 +7,6 @@
from rpython.rtyper.tool import rffi_platform as platform
from rpython.rlib import rthread
-from rpython.jit.backend import detect_cpu
-
class VMProfPlatformUnsupported(Exception):
pass
diff --git a/rpython/rlib/rvmprof/test/test_rvmprof.py b/rpython/rlib/rvmprof/test/test_rvmprof.py
--- a/rpython/rlib/rvmprof/test/test_rvmprof.py
+++ b/rpython/rlib/rvmprof/test/test_rvmprof.py
@@ -101,7 +101,7 @@
s = 0
for i in range(num):
s += (i << 1)
- if s % 32423423423 == 0:
+ if s % 2123423423 == 0:
print s
return s
diff --git a/rpython/rtyper/extfunc.py b/rpython/rtyper/extfunc.py
--- a/rpython/rtyper/extfunc.py
+++ b/rpython/rtyper/extfunc.py
@@ -1,99 +1,105 @@
-from rpython.rtyper.extregistry import ExtRegistryEntry
-from rpython.rtyper.lltypesystem.lltype import typeOf, FuncType, functionptr
-from rpython.annotator.model import unionof
+from rpython.annotator.model import unionof, SomeObject
from rpython.annotator.signature import annotation, SignatureError
+from rpython.rtyper.extregistry import ExtRegistryEntry, lookup
+from rpython.rtyper.lltypesystem.lltype import (
+ typeOf, FuncType, functionptr, _ptr, Void)
+from rpython.rtyper.error import TyperError
+from rpython.rtyper.rmodel import Repr
-import py
+class SomeExternalFunction(SomeObject):
+ def __init__(self, name, args_s, s_result):
+ self.name = name
+ self.args_s = args_s
+ self.s_result = s_result
+
+ def check_args(self, callspec):
+ params_s = self.args_s
+ args_s, kwargs = callspec.unpack()
+ if kwargs:
+ raise SignatureError(
+ "External functions cannot be called with keyword arguments")
+ if len(args_s) != len(params_s):
+ raise SignatureError("Argument number mismatch")
+ for i, s_param in enumerate(params_s):
+ arg = unionof(args_s[i], s_param)
+ if not s_param.contains(arg):
+ raise SignatureError(
+ "In call to external function %r:\n"
+ "arg %d must be %s,\n"
+ " got %s" % (
+ self.name, i + 1, s_param, args_s[i]))
+
+ def call(self, callspec):
+ self.check_args(callspec)
+ return self.s_result
+
+ def rtyper_makerepr(self, rtyper):
+ if not self.is_constant():
+ raise TyperError("Non-constant external function!")
+ entry = lookup(self.const)
+ impl = getattr(entry, 'lltypeimpl', None)
+ fakeimpl = getattr(entry, 'lltypefakeimpl', None)
+ return ExternalFunctionRepr(self, impl, fakeimpl)
+
+ def rtyper_makekey(self):
+ return self.__class__, self
+
+class ExternalFunctionRepr(Repr):
+ lowleveltype = Void
+
+ def __init__(self, s_func, impl, fakeimpl):
+ self.s_func = s_func
+ self.impl = impl
+ self.fakeimpl = fakeimpl
+
+ def rtype_simple_call(self, hop):
+ rtyper = hop.rtyper
+ args_r = [rtyper.getrepr(s_arg) for s_arg in self.s_func.args_s]
+ r_result = rtyper.getrepr(self.s_func.s_result)
+ obj = self.get_funcptr(rtyper, args_r, r_result)
+ hop2 = hop.copy()
+ hop2.r_s_popfirstarg()
+ vlist = [hop2.inputconst(typeOf(obj), obj)] + hop2.inputargs(*args_r)
+ hop2.exception_is_here()
+ return hop2.genop('direct_call', vlist, r_result)
+
+ def get_funcptr(self, rtyper, args_r, r_result):
+ from rpython.rtyper.rtyper import llinterp_backend
+ args_ll = [r_arg.lowleveltype for r_arg in args_r]
+ ll_result = r_result.lowleveltype
+ name = self.s_func.name
+ if self.fakeimpl and rtyper.backend is llinterp_backend:
+ FT = FuncType(args_ll, ll_result)
+ return functionptr(
+ FT, name, _external_name=name, _callable=self.fakeimpl)
+ elif self.impl:
+ if isinstance(self.impl, _ptr):
+ return self.impl
+ else:
+ # store some attributes to the 'impl' function, where
+ # the eventual call to rtyper.getcallable() will find them
+ # and transfer them to the final lltype.functionptr().
+ self.impl._llfnobjattrs_ = {'_name': name}
+ return rtyper.getannmixlevel().delayedfunction(
+ self.impl, self.s_func.args_s, self.s_func.s_result)
+ else:
+ fakeimpl = self.fakeimpl or self.s_func.const
+ FT = FuncType(args_ll, ll_result)
+ return functionptr(
+ FT, name, _external_name=name, _callable=fakeimpl)
+
class ExtFuncEntry(ExtRegistryEntry):
safe_not_sandboxed = False
- # common case: args is a list of annotation or types
- def normalize_args(self, *args_s):
- args = self.signature_args
- signature_args = [annotation(arg, None) for arg in args]
- assert len(args_s) == len(signature_args),\
- "Argument number mismatch"
+ def compute_annotation(self):
+ s_result = SomeExternalFunction(
+ self.name, self.signature_args, self.signature_result)
+ if (self.bookkeeper.annotator.translator.config.translation.sandbox
+ and not self.safe_not_sandboxed):
+ s_result.needs_sandboxing = True
+ return s_result
- for i, expected in enumerate(signature_args):
- arg = unionof(args_s[i], expected)
- if not expected.contains(arg):
- name = getattr(self, 'name', None)
- if not name:
- try:
- name = self.instance.__name__
- except AttributeError:
- name = '?'
- raise SignatureError("In call to external function %r:\n"
- "arg %d must be %s,\n"
- " got %s" % (
- name, i+1, expected, args_s[i]))
- return signature_args
-
- def compute_result_annotation(self, *args_s):
- self.normalize_args(*args_s) # check arguments
- return self.signature_result
-
- def specialize_call(self, hop):
- rtyper = hop.rtyper
- signature_args = self.normalize_args(*hop.args_s)
- args_r = [rtyper.getrepr(s_arg) for s_arg in signature_args]
- args_ll = [r_arg.lowleveltype for r_arg in args_r]
- s_result = hop.s_result
- r_result = rtyper.getrepr(s_result)
- ll_result = r_result.lowleveltype
- name = getattr(self, 'name', None) or self.instance.__name__
- impl = getattr(self, 'lltypeimpl', None)
- fakeimpl = getattr(self, 'lltypefakeimpl', self.instance)
- if impl:
- if (rtyper.annotator.translator.config.translation.sandbox
- and not self.safe_not_sandboxed):
- from rpython.translator.sandbox.rsandbox import (
- make_sandbox_trampoline)
- impl = make_sandbox_trampoline(
- self.name, signature_args, s_result)
- if hasattr(self, 'lltypefakeimpl'):
- # If we have both an llimpl and an llfakeimpl,
- # we need a wrapper that selects the proper one and calls it
- from rpython.tool.sourcetools import func_with_new_name
- # Using '*args' is delicate because this wrapper is also
- # created for init-time functions like llarena.arena_malloc
- # which are called before the GC is fully initialized
- args = ', '.join(['arg%d' % i for i in range(len(args_ll))])
- d = {'original_impl': impl,
- 's_result': s_result,
- 'fakeimpl': fakeimpl,
- '__name__': __name__,
- }
- exec py.code.compile("""
- from rpython.rlib.objectmodel import running_on_llinterp
- from rpython.rlib.debug import llinterpcall
- from rpython.rlib.jit import dont_look_inside
- # note: we say 'dont_look_inside' mostly because the
- # JIT does not support 'running_on_llinterp', but in
- # theory it is probably right to stop jitting anyway.
- @dont_look_inside
- def ll_wrapper(%s):
- if running_on_llinterp:
- return llinterpcall(s_result, fakeimpl, %s)
- else:
- return original_impl(%s)
- """ % (args, args, args)) in d
- impl = func_with_new_name(d['ll_wrapper'], name + '_wrapper')
- # store some attributes to the 'impl' function, where
- # the eventual call to rtyper.getcallable() will find them
- # and transfer them to the final lltype.functionptr().
- impl._llfnobjattrs_ = {'_name': self.name}
- obj = rtyper.getannmixlevel().delayedfunction(
- impl, signature_args, hop.s_result)
- else:
- FT = FuncType(args_ll, ll_result)
- obj = functionptr(FT, name, _external_name=self.name,
- _callable=fakeimpl,
- _safe_not_sandboxed=self.safe_not_sandboxed)
- vlist = [hop.inputconst(typeOf(obj), obj)] + hop.inputargs(*args_r)
- hop.exception_is_here()
- return hop.genop('direct_call', vlist, r_result)
def register_external(function, args, result=None, export_name=None,
llimpl=None, llfakeimpl=None, sandboxsafe=False):
@@ -109,32 +115,20 @@
if export_name is None:
export_name = function.__name__
+ params_s = [annotation(arg) for arg in args]
+ s_result = annotation(result)
class FunEntry(ExtFuncEntry):
_about_ = function
safe_not_sandboxed = sandboxsafe
-
- if args is None:
- def normalize_args(self, *args_s):
- return args_s # accept any argument unmodified
- elif callable(args):
- # custom annotation normalizer (see e.g. os.utime())
- normalize_args = staticmethod(args)
- else: # use common case behavior
- signature_args = args
-
- signature_result = annotation(result, None)
+ signature_args = params_s
+ signature_result = s_result
name = export_name
if llimpl:
lltypeimpl = staticmethod(llimpl)
if llfakeimpl:
lltypefakeimpl = staticmethod(llfakeimpl)
- if export_name:
- FunEntry.__name__ = export_name
- else:
- FunEntry.__name__ = function.func_name
-
def is_external(func):
if hasattr(func, 'value'):
func = func.value
diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py
--- a/rpython/rtyper/rtyper.py
+++ b/rpython/rtyper/rtyper.py
@@ -32,11 +32,24 @@
from rpython.translator.sandbox.rsandbox import make_sandbox_trampoline
+class RTyperBackend(object):
+ pass
+
+class GenCBackend(RTyperBackend):
+ pass
+genc_backend = GenCBackend()
+
+class LLInterpBackend(RTyperBackend):
+ pass
+llinterp_backend = LLInterpBackend()
+
+
class RPythonTyper(object):
from rpython.rtyper.rmodel import log
- def __init__(self, annotator):
+ def __init__(self, annotator, backend=genc_backend):
self.annotator = annotator
+ self.backend = backend
self.lowlevel_ann_policy = LowLevelAnnotatorPolicy(self)
self.reprs = {}
self._reprs_must_call_setup = []
diff --git a/rpython/rtyper/test/test_extfunc.py b/rpython/rtyper/test/test_extfunc.py
--- a/rpython/rtyper/test/test_extfunc.py
+++ b/rpython/rtyper/test/test_extfunc.py
@@ -1,7 +1,6 @@
import py
-from rpython.rtyper.extfunc import ExtFuncEntry, register_external,\
- is_external
+from rpython.rtyper.extfunc import register_external
from rpython.annotator.model import SomeInteger, SomeString, AnnotatorError
from rpython.annotator.annrpython import RPythonAnnotator
from rpython.annotator.policy import AnnotatorPolicy
@@ -19,11 +18,7 @@
"NOT_RPYTHON"
return eval("x+40")
- class BTestFuncEntry(ExtFuncEntry):
- _about_ = b
- name = 'b'
- signature_args = [SomeInteger()]
- signature_result = SomeInteger()
+ register_external(b, [int], result=int)
def f():
return b(2)
@@ -43,15 +38,11 @@
def c(y, x):
yyy
- class CTestFuncEntry(ExtFuncEntry):
- _about_ = c
- name = 'ccc'
- signature_args = [SomeInteger()] * 2
- signature_result = SomeInteger()
+ def llimpl(y, x):
+ return y + x
- def lltypeimpl(y, x):
- return y + x
- lltypeimpl = staticmethod(lltypeimpl)
+ register_external(c, [int, int], result=int, llimpl=llimpl,
+ export_name='ccc')
def f():
return c(3, 4)
@@ -59,22 +50,6 @@
res = interpret(f, [])
assert res == 7
- def test_register_external_signature(self):
- """
- Test the standard interface for external functions.
- """
- def dd():
- pass
- register_external(dd, [int], int)
-
- def f():
- return dd(3)
-
- policy = AnnotatorPolicy()
- a = RPythonAnnotator(policy=policy)
- s = a.build_types(f, [])
- assert isinstance(s, SomeInteger)
-
def test_register_external_tuple_args(self):
"""
Verify the annotation of a registered external function which takes a
@@ -121,23 +96,6 @@
s = a.build_types(f, [])
assert isinstance(s, SomeInteger)
- def test_register_external_specialcase(self):
- """
- When args=None, the external function accepts any arguments unmodified.
- """
- def function_withspecialcase(arg):
- return repr(arg)
- register_external(function_withspecialcase, args=None, result=str)
-
- def f():
- x = function_withspecialcase
- return x(33) + x("aaa") + x([]) + "\n"
-
- policy = AnnotatorPolicy()
- a = RPythonAnnotator(policy=policy)
- s = a.build_types(f, [])
- assert isinstance(s, SomeString)
-
def test_str0(self):
str0 = SomeString(no_nul=True)
def os_open(s):
@@ -182,3 +140,22 @@
# fails with TooLateForChange
a.build_types(g, [[str]])
a.build_types(g, [[str0]]) # Does not raise
+
+ def test_register_external_llfakeimpl(self):
+ def a(i):
+ return i
+ def a_llimpl(i):
+ return i * 2
+ def a_llfakeimpl(i):
+ return i * 3
+ register_external(a, [int], int, llimpl=a_llimpl,
+ llfakeimpl=a_llfakeimpl)
+ def f(i):
+ return a(i)
+
+ res = interpret(f, [7])
+ assert res == 21
+
+ from rpython.translator.c.test.test_genc import compile
+ fc = compile(f, [int])
+ assert fc(7) == 14
diff --git a/rpython/rtyper/test/test_llinterp.py b/rpython/rtyper/test/test_llinterp.py
--- a/rpython/rtyper/test/test_llinterp.py
+++ b/rpython/rtyper/test/test_llinterp.py
@@ -13,7 +13,7 @@
from rpython.rlib.rarithmetic import r_uint, ovfcheck
from rpython.tool import leakfinder
from rpython.conftest import option
-
+from rpython.rtyper.rtyper import llinterp_backend
# switch on logging of interp to show more info on failing tests
@@ -39,6 +39,7 @@
t.view()
global typer # we need it for find_exception
typer = t.buildrtyper()
+ typer.backend = llinterp_backend
typer.specialize()
#t.view()
t.checkgraphs()
diff --git a/rpython/rtyper/test/test_rbuiltin.py b/rpython/rtyper/test/test_rbuiltin.py
--- a/rpython/rtyper/test/test_rbuiltin.py
+++ b/rpython/rtyper/test/test_rbuiltin.py
@@ -3,8 +3,7 @@
import py
-from rpython.rlib.debug import llinterpcall
-from rpython.rlib.objectmodel import instantiate, running_on_llinterp, compute_unique_id, current_object_addr_as_int
+from rpython.rlib.objectmodel import instantiate, compute_unique_id, current_object_addr_as_int
from rpython.rlib.rarithmetic import (intmask, longlongmask, r_int64, is_valid_int,
r_int, r_uint, r_longlong, r_ulonglong)
from rpython.rlib.rstring import StringBuilder, UnicodeBuilder
@@ -456,26 +455,6 @@
res = self.interpret(fn, [3.25])
assert res == 7.25
- def test_debug_llinterpcall(self):
- S = lltype.Struct('S', ('m', lltype.Signed))
- SPTR = lltype.Ptr(S)
- def foo(n):
- "NOT_RPYTHON"
- s = lltype.malloc(S, immortal=True)
- s.m = eval("n*6", locals())
- return s
- def fn(n):
- if running_on_llinterp:
- return llinterpcall(SPTR, foo, n).m
- else:
- return 321
- res = self.interpret(fn, [7])
- assert res == 42
- from rpython.translator.c.test.test_genc import compile
- f = compile(fn, [int])
- res = f(7)
- assert res == 321
-
def test_id(self):
class A:
pass
diff --git a/rpython/rtyper/test/test_rpbc.py b/rpython/rtyper/test/test_rpbc.py
--- a/rpython/rtyper/test/test_rpbc.py
+++ b/rpython/rtyper/test/test_rpbc.py
@@ -1,7 +1,7 @@
import py
from rpython.annotator import model as annmodel
-from rpython.annotator import policy, specialize
+from rpython.annotator import specialize
from rpython.rtyper.lltypesystem.lltype import typeOf
from rpython.rtyper.test.tool import BaseRtypingTest
from rpython.rtyper.llannotation import SomePtr, lltype_to_annotation
@@ -1690,59 +1690,6 @@
# ____________________________________________________________
-class TestRPBCExtra(BaseRtypingTest):
-
- def test_folding_specialize_support(self):
-
- class S(object):
-
- def w(s, x):
- if isinstance(x, int):
- return x
- if isinstance(x, str):
- return len(x)
- return -1
- w._annspecialcase_ = "specialize:w"
-
- def _freeze_(self):
- return True
-
- s = S()
-
- def f(i, n):
- w = s.w
- if i == 0:
- return w(0)
- elif i == 1:
- return w("abc")
- elif i == 2:
- return w(3*n)
- elif i == 3:
- return w(str(n))
- return -1
-
- class P(policy.AnnotatorPolicy):
- def specialize__w(pol, funcdesc, args_s):
- typ = args_s[1].knowntype
- if args_s[0].is_constant() and args_s[1].is_constant():
- x = args_s[1].const
- v = s.w(x)
- builder = specialize.make_constgraphbuilder(2, v)
- return funcdesc.cachedgraph(x, builder=builder)
- return funcdesc.cachedgraph(typ)
-
- p = P()
-
- res = self.interpret(f, [0, 66], policy=p)
- assert res == 0
- res = self.interpret(f, [1, 66], policy=p)
- assert res == 3
- res = self.interpret(f, [2, 4], policy=p)
- assert res == 12
- res = self.interpret(f, [3, 5555], policy=p)
- assert res == 4
-
-
def test_hlinvoke_simple():
def f(a,b):
return a + b
diff --git a/rpython/translator/c/node.py b/rpython/translator/c/node.py
--- a/rpython/translator/c/node.py
+++ b/rpython/translator/c/node.py
@@ -913,6 +913,7 @@
return []
def new_funcnode(db, T, obj, forcename=None):
+ from rpython.rtyper.rtyper import llinterp_backend
if db.sandbox:
if (getattr(obj, 'external', None) is not None and
not obj._safe_not_sandboxed):
@@ -934,6 +935,9 @@
return ExternalFuncNode(db, T, obj, name)
elif hasattr(obj._callable, "c_name"):
return ExternalFuncNode(db, T, obj, name) # this case should only be used for entrypoints
+ elif db.translator.rtyper.backend is llinterp_backend:
+ # on llinterp, anything goes
+ return ExternalFuncNode(db, T, obj, name)
else:
raise ValueError("don't know how to generate code for %r" % (obj,))
diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py
--- a/rpython/translator/driver.py
+++ b/rpython/translator/driver.py
@@ -487,7 +487,15 @@
exe = py.path.local(exename)
exename = exe.new(purebasename=exe.purebasename + 'w')
shutil_copy(str(exename), str(newexename))
- ext_to_copy = ['lib', 'pdb']
+ # for pypy, the import library is renamed and moved to
+ # libs/python32.lib, according to the pragma in pyconfig.h
+ libname = self.config.translation.libname
+ libname = libname or soname.new(ext='lib').basename
+ libname = str(newsoname.dirpath().join(libname))
+ shutil.copyfile(str(soname.new(ext='lib')), libname)
+ self.log.info("copied: %s" % (libname,))
+ # the pdb file goes in the same place as pypy(w).exe
+ ext_to_copy = ['pdb',]
for ext in ext_to_copy:
name = soname.new(ext=ext)
newname = newexename.new(basename=soname.basename)
diff --git a/rpython/translator/sandbox/test/test_sandbox.py b/rpython/translator/sandbox/test/test_sandbox.py
--- a/rpython/translator/sandbox/test/test_sandbox.py
+++ b/rpython/translator/sandbox/test/test_sandbox.py
@@ -292,6 +292,21 @@
rescode = pipe.wait()
assert rescode == 0
+def test_environ_items():
+ def entry_point(argv):
+ print os.environ.items()
+ return 0
+
+ exe = compile(entry_point)
+ g, f = run_in_subprocess(exe)
+ expect(f, g, "ll_os.ll_os_envitems", (), [])
+ expect(f, g, "ll_os.ll_os_write", (1, "[]\n"), 3)
+ g.close()
+ tail = f.read()
+ f.close()
+ assert tail == ""
+
+
class TestPrintedResults:
def run(self, entry_point, args, expected):
More information about the pypy-commit
mailing list