[pypy-commit] pypy ppc-jit-backend: merge
hager
noreply at buildbot.pypy.org
Tue Jan 3 14:42:06 CET 2012
Author: hager <sven.hager at uni-duesseldorf.de>
Branch: ppc-jit-backend
Changeset: r50997:0529ccad7c00
Date: 2012-01-03 14:41 +0100
http://bitbucket.org/pypy/pypy/changeset/0529ccad7c00/
Log: merge
diff too long, truncating to 10000 out of 53476 lines
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -1,3 +1,4 @@
b590cf6de4190623aad9aa698694c22e614d67b9 release-1.5
b48df0bf4e75b81d98f19ce89d4a7dc3e1dab5e5 benchmarked
d8ac7d23d3ec5f9a0fa1264972f74a010dbfd07f release-1.6
+ff4af8f318821f7f5ca998613a60fca09aa137da release-1.7
diff --git a/lib-python/modified-2.7/ctypes/__init__.py b/lib-python/modified-2.7/ctypes/__init__.py
--- a/lib-python/modified-2.7/ctypes/__init__.py
+++ b/lib-python/modified-2.7/ctypes/__init__.py
@@ -351,7 +351,7 @@
self._FuncPtr = _FuncPtr
if handle is None:
- self._handle = _ffi.CDLL(name)
+ self._handle = _ffi.CDLL(name, mode)
else:
self._handle = handle
diff --git a/lib-python/modified-2.7/ctypes/test/test_callbacks.py b/lib-python/modified-2.7/ctypes/test/test_callbacks.py
--- a/lib-python/modified-2.7/ctypes/test/test_callbacks.py
+++ b/lib-python/modified-2.7/ctypes/test/test_callbacks.py
@@ -1,5 +1,6 @@
import unittest
from ctypes import *
+from ctypes.test import xfail
import _ctypes_test
class Callbacks(unittest.TestCase):
@@ -98,6 +99,7 @@
## self.check_type(c_char_p, "abc")
## self.check_type(c_char_p, "def")
+ @xfail
def test_pyobject(self):
o = ()
from sys import getrefcount as grc
diff --git a/lib-python/modified-2.7/ctypes/test/test_libc.py b/lib-python/modified-2.7/ctypes/test/test_libc.py
--- a/lib-python/modified-2.7/ctypes/test/test_libc.py
+++ b/lib-python/modified-2.7/ctypes/test/test_libc.py
@@ -25,7 +25,10 @@
lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort))
self.assertEqual(chars.raw, " ,,aaaadmmmnpppsss\x00")
- def test_no_more_xfail(self):
+ def SKIPPED_test_no_more_xfail(self):
+ # We decided to not explicitly support the whole ctypes-2.7
+ # and instead go for a case-by-case, demand-driven approach.
+ # So this test is skipped instead of failing.
import socket
import ctypes.test
self.assertTrue(not hasattr(ctypes.test, 'xfail'),
diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py
--- a/lib_pypy/_collections.py
+++ b/lib_pypy/_collections.py
@@ -379,12 +379,14 @@
class defaultdict(dict):
def __init__(self, *args, **kwds):
- self.default_factory = None
- if 'default_factory' in kwds:
- self.default_factory = kwds.pop('default_factory')
- elif len(args) > 0 and (callable(args[0]) or args[0] is None):
- self.default_factory = args[0]
+ if len(args) > 0:
+ default_factory = args[0]
args = args[1:]
+ if not callable(default_factory) and default_factory is not None:
+ raise TypeError("first argument must be callable")
+ else:
+ default_factory = None
+ self.default_factory = default_factory
super(defaultdict, self).__init__(*args, **kwds)
def __missing__(self, key):
@@ -404,7 +406,7 @@
recurse.remove(id(self))
def copy(self):
- return type(self)(self, default_factory=self.default_factory)
+ return type(self)(self.default_factory, self)
def __copy__(self):
return self.copy()
diff --git a/lib_pypy/_sha.py b/lib_pypy/_sha.py
--- a/lib_pypy/_sha.py
+++ b/lib_pypy/_sha.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-# -*- coding: iso-8859-1
+# -*- coding: iso-8859-1 -*-
# Note that PyPy contains also a built-in module 'sha' which will hide
# this one if compiled in.
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -231,6 +231,11 @@
sqlite.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p]
sqlite.sqlite3_result_text.restype = None
+HAS_LOAD_EXTENSION = hasattr(sqlite, "sqlite3_enable_load_extension")
+if HAS_LOAD_EXTENSION:
+ sqlite.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int]
+ sqlite.sqlite3_enable_load_extension.restype = c_int
+
##########################################
# END Wrapped SQLite C API and constants
##########################################
@@ -705,6 +710,15 @@
from sqlite3.dump import _iterdump
return _iterdump(self)
+ if HAS_LOAD_EXTENSION:
+ def enable_load_extension(self, enabled):
+ self._check_thread()
+ self._check_closed()
+
+ rc = sqlite.sqlite3_enable_load_extension(self.db, int(enabled))
+ if rc != SQLITE_OK:
+ raise OperationalError("Error enabling load extension")
+
DML, DQL, DDL = range(3)
class Cursor(object):
diff --git a/lib_pypy/distributed/socklayer.py b/lib_pypy/distributed/socklayer.py
--- a/lib_pypy/distributed/socklayer.py
+++ b/lib_pypy/distributed/socklayer.py
@@ -2,7 +2,7 @@
import py
from socket import socket
-XXX needs import adaptation as 'green' is removed from py lib for years
+raise ImportError("XXX needs import adaptation as 'green' is removed from py lib for years")
from py.impl.green.msgstruct import decodemessage, message
from socket import socket, AF_INET, SOCK_STREAM
import marshal
diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py
--- a/lib_pypy/itertools.py
+++ b/lib_pypy/itertools.py
@@ -25,7 +25,7 @@
__all__ = ['chain', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter',
'ifilterfalse', 'imap', 'islice', 'izip', 'repeat', 'starmap',
- 'takewhile', 'tee']
+ 'takewhile', 'tee', 'compress', 'product']
try: from __pypy__ import builtinify
except ImportError: builtinify = lambda f: f
diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py
--- a/lib_pypy/pyrepl/unix_console.py
+++ b/lib_pypy/pyrepl/unix_console.py
@@ -412,7 +412,12 @@
e.args[4] == 'unexpected end of data':
pass
else:
- raise
+ # was: "raise". But it crashes pyrepl, and by extension the
+ # pypy currently running, in which we are e.g. in the middle
+ # of some debugging session. Argh. Instead just print an
+ # error message to stderr and continue running, for now.
+ self.partial_char = ''
+ sys.stderr.write('\n%s: %s\n' % (e.__class__.__name__, e))
else:
self.partial_char = ''
self.event_queue.push(c)
diff --git a/lib_pypy/syslog.py b/lib_pypy/syslog.py
--- a/lib_pypy/syslog.py
+++ b/lib_pypy/syslog.py
@@ -38,9 +38,27 @@
_setlogmask.argtypes = (c_int,)
_setlogmask.restype = c_int
+_S_log_open = False
+_S_ident_o = None
+
+def _get_argv():
+ try:
+ import sys
+ script = sys.argv[0]
+ if isinstance(script, str):
+ return script[script.rfind('/')+1:] or None
+ except Exception:
+ pass
+ return None
+
@builtinify
-def openlog(ident, option, facility):
- _openlog(ident, option, facility)
+def openlog(ident=None, logoption=0, facility=LOG_USER):
+ global _S_ident_o, _S_log_open
+ if ident is None:
+ ident = _get_argv()
+ _S_ident_o = c_char_p(ident) # keepalive
+ _openlog(_S_ident_o, logoption, facility)
+ _S_log_open = True
@builtinify
def syslog(arg1, arg2=None):
@@ -48,11 +66,18 @@
priority, message = arg1, arg2
else:
priority, message = LOG_INFO, arg1
+ # if log is not opened, open it now
+ if not _S_log_open:
+ openlog()
_syslog(priority, "%s", message)
@builtinify
def closelog():
- _closelog()
+ global _S_log_open, S_ident_o
+ if _S_log_open:
+ _closelog()
+ _S_log_open = False
+ _S_ident_o = None
@builtinify
def setlogmask(mask):
diff --git a/py/_code/code.py b/py/_code/code.py
--- a/py/_code/code.py
+++ b/py/_code/code.py
@@ -164,6 +164,7 @@
# if something: # assume this causes a NameError
# # _this_ lines and the one
# below we don't want from entry.getsource()
+ end = min(end, len(source))
for i in range(self.lineno, end):
if source[i].rstrip().endswith(':'):
end = i + 1
@@ -307,7 +308,7 @@
self._striptext = 'AssertionError: '
self._excinfo = tup
self.type, self.value, tb = self._excinfo
- self.typename = self.type.__name__
+ self.typename = getattr(self.type, "__name__", "???")
self.traceback = py.code.Traceback(tb)
def __repr__(self):
diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py
--- a/pypy/annotation/binaryop.py
+++ b/pypy/annotation/binaryop.py
@@ -252,7 +252,26 @@
# unsignedness is considered a rare and contagious disease
def union((int1, int2)):
- knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype)
+ if int1.unsigned == int2.unsigned:
+ knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype)
+ else:
+ t1 = int1.knowntype
+ if t1 is bool:
+ t1 = int
+ t2 = int2.knowntype
+ if t2 is bool:
+ t2 = int
+
+ if t2 is int:
+ if int2.nonneg == False:
+ raise UnionError, "Merging %s and a possibly negative int is not allowed" % t1
+ knowntype = t1
+ elif t1 is int:
+ if int1.nonneg == False:
+ raise UnionError, "Merging %s and a possibly negative int is not allowed" % t2
+ knowntype = t2
+ else:
+ raise UnionError, "Merging these types (%s, %s) is not supported" % (t1, t2)
return SomeInteger(nonneg=int1.nonneg and int2.nonneg,
knowntype=knowntype)
diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py
--- a/pypy/annotation/description.py
+++ b/pypy/annotation/description.py
@@ -180,7 +180,12 @@
if name is None:
name = pyobj.func_name
if signature is None:
- signature = cpython_code_signature(pyobj.func_code)
+ if hasattr(pyobj, '_generator_next_method_of_'):
+ from pypy.interpreter.argument import Signature
+ signature = Signature(['entry']) # haaaaaack
+ defaults = ()
+ else:
+ signature = cpython_code_signature(pyobj.func_code)
if defaults is None:
defaults = pyobj.func_defaults
self.name = name
diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py
--- a/pypy/annotation/model.py
+++ b/pypy/annotation/model.py
@@ -591,13 +591,11 @@
immutable = True
def __init__(self, method):
self.method = method
-
-NUMBER = object()
+
annotation_to_ll_map = [
(SomeSingleFloat(), lltype.SingleFloat),
(s_None, lltype.Void), # also matches SomeImpossibleValue()
(s_Bool, lltype.Bool),
- (SomeInteger(knowntype=r_ulonglong), NUMBER),
(SomeFloat(), lltype.Float),
(SomeLongFloat(), lltype.LongFloat),
(SomeChar(), lltype.Char),
@@ -623,10 +621,11 @@
return lltype.Ptr(p.PARENTTYPE)
if isinstance(s_val, SomePtr):
return s_val.ll_ptrtype
+ if type(s_val) is SomeInteger:
+ return lltype.build_number(None, s_val.knowntype)
+
for witness, T in annotation_to_ll_map:
if witness.contains(s_val):
- if T is NUMBER:
- return lltype.build_number(None, s_val.knowntype)
return T
if info is None:
info = ''
@@ -635,7 +634,7 @@
raise ValueError("%sshould return a low-level type,\ngot instead %r" % (
info, s_val))
-ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map if ll is not NUMBER])
+ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map])
def lltype_to_annotation(T):
try:
diff --git a/pypy/annotation/specialize.py b/pypy/annotation/specialize.py
--- a/pypy/annotation/specialize.py
+++ b/pypy/annotation/specialize.py
@@ -36,9 +36,7 @@
newtup = SpaceOperation('newtuple', starargs, argscopy[-1])
newstartblock.operations.append(newtup)
newstartblock.closeblock(Link(argscopy, graph.startblock))
- graph.startblock.isstartblock = False
graph.startblock = newstartblock
- newstartblock.isstartblock = True
argnames = argnames + ['.star%d' % i for i in range(nb_extra_args)]
graph.signature = Signature(argnames)
# note that we can mostly ignore defaults: if nb_extra_args > 0,
diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -856,6 +856,46 @@
py.test.raises(Exception, a.build_types, f, [])
# if you want to get a r_uint, you have to be explicit about it
+ def test_add_different_ints(self):
+ def f(a, b):
+ return a + b
+ a = self.RPythonAnnotator()
+ py.test.raises(Exception, a.build_types, f, [r_uint, int])
+
+ def test_merge_different_ints(self):
+ def f(a, b):
+ if a:
+ c = a
+ else:
+ c = b
+ return c
+ a = self.RPythonAnnotator()
+ py.test.raises(Exception, a.build_types, f, [r_uint, int])
+
+ def test_merge_ruint_zero(self):
+ def f(a):
+ if a:
+ c = a
+ else:
+ c = 0
+ return c
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [r_uint])
+ assert s == annmodel.SomeInteger(nonneg = True, unsigned = True)
+
+ def test_merge_ruint_nonneg_signed(self):
+ def f(a, b):
+ if a:
+ c = a
+ else:
+ assert b >= 0
+ c = b
+ return c
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [r_uint, int])
+ assert s == annmodel.SomeInteger(nonneg = True, unsigned = True)
+
+
def test_prebuilt_long_that_is_not_too_long(self):
small_constant = 12L
def f():
@@ -3029,7 +3069,7 @@
if g(x, y):
g(x, r_uint(y))
a = self.RPythonAnnotator()
- a.build_types(f, [int, int])
+ py.test.raises(Exception, a.build_types, f, [int, int])
def test_compare_with_zero(self):
def g():
diff --git a/pypy/bin/checkmodule.py b/pypy/bin/checkmodule.py
--- a/pypy/bin/checkmodule.py
+++ b/pypy/bin/checkmodule.py
@@ -1,43 +1,45 @@
#! /usr/bin/env python
"""
-Usage: checkmodule.py [-b backend] <module-name>
+Usage: checkmodule.py <module-name>
-Compiles the PyPy extension module from pypy/module/<module-name>/
-into a fake program which does nothing. Useful for testing whether a
-modules compiles without doing a full translation. Default backend is cli.
-
-WARNING: this is still incomplete: there are chances that the
-compilation fails with strange errors not due to the module. If a
-module is known to compile during a translation but don't pass
-checkmodule.py, please report the bug (or, better, correct it :-).
+Check annotation and rtyping of the PyPy extension module from
+pypy/module/<module-name>/. Useful for testing whether a
+modules compiles without doing a full translation.
"""
import autopath
-import sys
+import sys, os
from pypy.objspace.fake.checkmodule import checkmodule
def main(argv):
- try:
- assert len(argv) in (2, 4)
- if len(argv) == 2:
- backend = 'cli'
- modname = argv[1]
- if modname in ('-h', '--help'):
- print >> sys.stderr, __doc__
- sys.exit(0)
- if modname.startswith('-'):
- print >> sys.stderr, "Bad command line"
- print >> sys.stderr, __doc__
- sys.exit(1)
- else:
- _, b, backend, modname = argv
- assert b == '-b'
- except AssertionError:
+ if len(argv) != 2:
print >> sys.stderr, __doc__
sys.exit(2)
+ modname = argv[1]
+ if modname in ('-h', '--help'):
+ print >> sys.stderr, __doc__
+ sys.exit(0)
+ if modname.startswith('-'):
+ print >> sys.stderr, "Bad command line"
+ print >> sys.stderr, __doc__
+ sys.exit(1)
+ if os.path.sep in modname:
+ if os.path.basename(modname) == '':
+ modname = os.path.dirname(modname)
+ if os.path.basename(os.path.dirname(modname)) != 'module':
+ print >> sys.stderr, "Must give '../module/xxx', or just 'xxx'."
+ sys.exit(1)
+ modname = os.path.basename(modname)
+ try:
+ checkmodule(modname)
+ except Exception, e:
+ import traceback, pdb
+ traceback.print_exc()
+ pdb.post_mortem(sys.exc_info()[2])
+ return 1
else:
- checkmodule(modname, backend, interactive=True)
- print 'Module compiled succesfully'
+ print 'Passed.'
+ return 0
if __name__ == '__main__':
- main(sys.argv)
+ sys.exit(main(sys.argv))
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -252,6 +252,10 @@
"use small tuples",
default=False),
+ BoolOption("withspecialisedtuple",
+ "use specialised tuples",
+ default=False),
+
BoolOption("withrope", "use ropes as the string implementation",
default=False,
requires=[("objspace.std.withstrslice", False),
@@ -281,6 +285,9 @@
"actually create the full list until the resulting "
"list is mutated",
default=False),
+ BoolOption("withliststrategies",
+ "enable optimized ways to store lists of primitives ",
+ default=True),
BoolOption("withtypeversion",
"version type objects when changing them",
@@ -362,6 +369,7 @@
config.objspace.std.suggest(optimized_list_getitem=True)
config.objspace.std.suggest(getattributeshortcut=True)
config.objspace.std.suggest(newshortcut=True)
+ config.objspace.std.suggest(withspecialisedtuple=True)
#if not IS_64_BITS:
# config.objspace.std.suggest(withsmalllong=True)
diff --git a/pypy/config/test/test_translationoption.py b/pypy/config/test/test_translationoption.py
new file mode 100644
--- /dev/null
+++ b/pypy/config/test/test_translationoption.py
@@ -0,0 +1,10 @@
+import py
+from pypy.config.translationoption import get_combined_translation_config
+from pypy.config.translationoption import set_opt_level
+from pypy.config.config import ConflictConfigError
+
+
+def test_no_gcrootfinder_with_boehm():
+ config = get_combined_translation_config()
+ config.translation.gcrootfinder = "shadowstack"
+ py.test.raises(ConflictConfigError, set_opt_level, config, '0')
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -70,8 +70,8 @@
"statistics": [("translation.gctransformer", "framework")],
"generation": [("translation.gctransformer", "framework")],
"hybrid": [("translation.gctransformer", "framework")],
- "boehm": [("translation.gctransformer", "boehm"),
- ("translation.continuation", False)], # breaks
+ "boehm": [("translation.continuation", False), # breaks
+ ("translation.gctransformer", "boehm")],
"markcompact": [("translation.gctransformer", "framework")],
"minimark": [("translation.gctransformer", "framework")],
},
@@ -399,6 +399,10 @@
# make_sure_not_resized often relies on it, so we always enable them
config.translation.suggest(list_comprehension_operations=True)
+ # finally, make the choice of the gc definitive. This will fail
+ # if we have specified strange inconsistent settings.
+ config.translation.gc = config.translation.gc
+
# ----------------------------------------------------------------
def set_platform(config):
diff --git a/pypy/conftest.py b/pypy/conftest.py
--- a/pypy/conftest.py
+++ b/pypy/conftest.py
@@ -496,6 +496,17 @@
def setup(self):
super(AppClassCollector, self).setup()
cls = self.obj
+ #
+ # <hack>
+ for name in dir(cls):
+ if name.startswith('test_'):
+ func = getattr(cls, name, None)
+ code = getattr(func, 'func_code', None)
+ if code and code.co_flags & 32:
+ raise AssertionError("unsupported: %r is a generator "
+ "app-level test method" % (name,))
+ # </hack>
+ #
space = cls.space
clsname = cls.__name__
if self.config.option.runappdirect:
diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst
--- a/pypy/doc/coding-guide.rst
+++ b/pypy/doc/coding-guide.rst
@@ -270,7 +270,12 @@
- *slicing*:
the slice start must be within bounds. The stop doesn't need to, but it must
not be smaller than the start. All negative indexes are disallowed, except for
- the [:-1] special case. No step.
+ the [:-1] special case. No step. Slice deletion follows the same rules.
+
+ - *slice assignment*:
+ only supports ``lst[x:y] = sublist``, if ``len(sublist) == y - x``.
+ In other words, slice assignment cannot change the total length of the list,
+ but just replace items.
- *other operators*:
``+``, ``+=``, ``in``, ``*``, ``*=``, ``==``, ``!=`` work as expected.
diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py
--- a/pypy/doc/conf.py
+++ b/pypy/doc/conf.py
@@ -45,9 +45,9 @@
# built documents.
#
# The short X.Y version.
-version = '1.6'
+version = '1.7'
# The full version, including alpha/beta/rc tags.
-release = '1.6'
+release = '1.7'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/pypy/doc/config/objspace.std.withliststrategies.txt b/pypy/doc/config/objspace.std.withliststrategies.txt
new file mode 100644
--- /dev/null
+++ b/pypy/doc/config/objspace.std.withliststrategies.txt
@@ -0,0 +1,2 @@
+Enable list strategies: Use specialized representations for lists of primitive
+objects, such as ints.
diff --git a/pypy/doc/config/objspace.std.withspecialisedtuple.txt b/pypy/doc/config/objspace.std.withspecialisedtuple.txt
new file mode 100644
--- /dev/null
+++ b/pypy/doc/config/objspace.std.withspecialisedtuple.txt
@@ -0,0 +1,3 @@
+Use "specialized tuples", a custom implementation for some common kinds
+of tuples. Currently limited to tuples of length 2, in three variants:
+(int, int), (float, float), and a generic (object, object).
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -262,6 +262,26 @@
documented as such (as e.g. for hasattr()), in most cases PyPy
lets the exception propagate instead.
+Object Identity of Primitive Values, ``is`` and ``id``
+-------------------------------------------------------
+
+Object identity of primitive values works by value equality, not by identity of
+the wrapper. This means that ``x + 1 is x + 1`` is always true, for arbitrary
+integers ``x``. The rule applies for the following types:
+
+ - ``int``
+
+ - ``float``
+
+ - ``long``
+
+ - ``complex``
+
+This change requires some changes to ``id`` as well. ``id`` fulfills the
+following condition: ``x is y <=> id(x) == id(y)``. Therefore ``id`` of the
+above types will return a value that is computed from the argument, and can
+thus be larger than ``sys.maxint`` (i.e. it can be an arbitrary long).
+
Miscellaneous
-------------
@@ -284,14 +304,14 @@
never a dictionary as it sometimes is in CPython. Assigning to
``__builtins__`` has no effect.
-* Do not compare immutable objects with ``is``. For example on CPython
- it is true that ``x is 0`` works, i.e. does the same as ``type(x) is
- int and x == 0``, but it is so by accident. If you do instead
- ``x is 1000``, then it stops working, because 1000 is too large and
- doesn't come from the internal cache. In PyPy it fails to work in
- both cases, because we have no need for a cache at all.
+* directly calling the internal magic methods of a few built-in types
+ with invalid arguments may have a slightly different result. For
+ example, ``[].__add__(None)`` and ``(2).__add__(None)`` both return
+ ``NotImplemented`` on PyPy; on CPython, only the later does, and the
+ former raises ``TypeError``. (Of course, ``[]+None`` and ``2+None``
+ both raise ``TypeError`` everywhere.) This difference is an
+ implementation detail that shows up because of internal C-level slots
+ that PyPy does not have.
-* Also, object identity of immutable keys in dictionaries is not necessarily
- preserved.
.. include:: _ref.txt
diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst
--- a/pypy/doc/faq.rst
+++ b/pypy/doc/faq.rst
@@ -112,10 +112,32 @@
You might be interested in our `benchmarking site`_ and our
`jit documentation`_.
+Note that the JIT has a very high warm-up cost, meaning that the
+programs are slow at the beginning. If you want to compare the timings
+with CPython, even relatively simple programs need to run *at least* one
+second, preferrably at least a few seconds. Large, complicated programs
+need even more time to warm-up the JIT.
+
.. _`benchmarking site`: http://speed.pypy.org
.. _`jit documentation`: jit/index.html
+---------------------------------------------------------------
+Couldn't the JIT dump and reload already-compiled machine code?
+---------------------------------------------------------------
+
+No, we found no way of doing that. The JIT generates machine code
+containing a large number of constant addresses --- constant at the time
+the machine code is written. The vast majority is probably not at all
+constants that you find in the executable, with a nice link name. E.g.
+the addresses of Python classes are used all the time, but Python
+classes don't come statically from the executable; they are created anew
+every time you restart your program. This makes saving and reloading
+machine code completely impossible without some very advanced way of
+mapping addresses in the old (now-dead) process to addresses in the new
+process, including checking that all the previous assumptions about the
+(now-dead) object are still true about the new object.
+
.. _`prolog and javascript`:
diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst
--- a/pypy/doc/how-to-release.rst
+++ b/pypy/doc/how-to-release.rst
@@ -1,6 +1,3 @@
-.. include:: needswork.txt
-
-.. needs work, it talks about svn. also, it is not really user documentation
Making a PyPy Release
=======================
@@ -12,11 +9,8 @@
forgetting things. A set of todo files may also work.
Check and prioritize all issues for the release, postpone some if necessary,
-create new issues also as necessary. A meeting (or meetings) should be
-organized to decide what things are priorities, should go in and work for
-the release.
-
-An important thing is to get the documentation into an up-to-date state!
+create new issues also as necessary. An important thing is to get
+the documentation into an up-to-date state!
Release Steps
----------------
diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst
--- a/pypy/doc/index.rst
+++ b/pypy/doc/index.rst
@@ -15,7 +15,7 @@
* `FAQ`_: some frequently asked questions.
-* `Release 1.6`_: the latest official release
+* `Release 1.7`_: the latest official release
* `PyPy Blog`_: news and status info about PyPy
@@ -75,7 +75,7 @@
.. _`Getting Started`: getting-started.html
.. _`Papers`: extradoc.html
.. _`Videos`: video-index.html
-.. _`Release 1.6`: http://pypy.org/download.html
+.. _`Release 1.7`: http://pypy.org/download.html
.. _`speed.pypy.org`: http://speed.pypy.org
.. _`RPython toolchain`: translation.html
.. _`potential project ideas`: project-ideas.html
@@ -120,9 +120,9 @@
Windows, on top of .NET, and on top of Java.
To dig into PyPy it is recommended to try out the current
Mercurial default branch, which is always working or mostly working,
-instead of the latest release, which is `1.6`__.
+instead of the latest release, which is `1.7`__.
-.. __: release-1.6.0.html
+.. __: release-1.7.0.html
PyPy is mainly developed on Linux and Mac OS X. Windows is supported,
but platform-specific bugs tend to take longer before we notice and fix
diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst
--- a/pypy/doc/project-ideas.rst
+++ b/pypy/doc/project-ideas.rst
@@ -23,17 +23,20 @@
PyPy's implementation of the Python ``long`` type is slower than CPython's.
Find out why and optimize them.
+Make bytearray type fast
+------------------------
+
+PyPy's bytearray type is very inefficient. It would be an interesting
+task to look into possible optimizations on this.
+
Numpy improvements
------------------
-This is more of a project-container than a single project. Possible ideas:
+The numpy is rapidly progressing in pypy, so feel free to come to IRC and
+ask for proposed topic. A not necesarilly up-to-date `list of topics`_
+is also available.
-* experiment with auto-vectorization using SSE or implement vectorization
- without automatically detecting it for array operations.
-
-* improve numpy, for example implement memory views.
-
-* interface with fortran/C libraries.
+.. _`list of topics`: https://bitbucket.org/pypy/extradoc/src/extradoc/planning/micronumpy.txt
Improving the jitviewer
------------------------
diff --git a/pypy/doc/release-1.7.0.rst b/pypy/doc/release-1.7.0.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-1.7.0.rst
@@ -0,0 +1,94 @@
+==================================
+PyPy 1.7 - widening the sweet spot
+==================================
+
+We're pleased to announce the 1.7 release of PyPy. As became a habit, this
+release brings a lot of bugfixes and performance improvements over the 1.6
+release. However, unlike the previous releases, the focus has been on widening
+the "sweet spot" of PyPy. That is, classes of Python code that PyPy can greatly
+speed up should be vastly improved with this release. You can download the 1.7
+release here:
+
+ http://pypy.org/download.html
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`pypy 1.7 and cpython 2.7.1`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+This release supports x86 machines running Linux 32/64, Mac OS X 32/64 or
+Windows 32. Windows 64 work is ongoing, but not yet natively supported.
+
+The main topic of this release is widening the range of code which PyPy
+can greatly speed up. On average on
+our benchmark suite, PyPy 1.7 is around **30%** faster than PyPy 1.6 and up
+to **20 times** faster on some benchmarks.
+
+.. _`pypy 1.7 and cpython 2.7.1`: http://speed.pypy.org
+
+
+Highlights
+==========
+
+* Numerous performance improvements. There are too many examples which python
+ constructs now should behave faster to list them.
+
+* Bugfixes and compatibility fixes with CPython.
+
+* Windows fixes.
+
+* PyPy now comes with stackless features enabled by default. However,
+ any loop using stackless features will interrupt the JIT for now, so no real
+ performance improvement for stackless-based programs. Contact pypy-dev for
+ info how to help on removing this restriction.
+
+* NumPy effort in PyPy was renamed numpypy. In order to try using it, simply
+ write::
+
+ import numpypy as numpy
+
+ at the beginning of your program. There is a huge progress on numpy in PyPy
+ since 1.6, the main feature being implementation of dtypes.
+
+* JSON encoder (but not decoder) has been replaced with a new one. This one
+ is written in pure Python, but is known to outperform CPython's C extension
+ up to **2 times** in some cases. It's about **20 times** faster than
+ the one that we had in 1.6.
+
+* The memory footprint of some of our RPython modules has been drastically
+ improved. This should impact any applications using for example cryptography,
+ like tornado.
+
+* There was some progress in exposing even more CPython C API via cpyext.
+
+Things that didn't make it, expect in 1.8 soon
+==============================================
+
+There is an ongoing work, which while didn't make it to the release, is
+probably worth mentioning here. This is what you should probably expect in
+1.8 some time soon:
+
+* Specialized list implementation. There is a branch that implements lists of
+ integers/floats/strings as compactly as array.array. This should drastically
+ improve performance/memory impact of some applications
+
+* NumPy effort is progressing forward, with multi-dimensional arrays coming
+ soon.
+
+* There are two brand new JIT assembler backends, notably for the PowerPC and
+ ARM processors.
+
+Fundraising
+===========
+
+It's maybe worth mentioning that we're running fundraising campaigns for
+NumPy effort in PyPy and for Python 3 in PyPy. In case you want to see any
+of those happen faster, we urge you to donate to `numpy proposal`_ or
+`py3k proposal`_. In case you want PyPy to progress, but you trust us with
+the general direction, you can always donate to the `general pot`_.
+
+.. _`numpy proposal`: http://pypy.org/numpydonate.html
+.. _`py3k proposal`: http://pypy.org/py3donate.html
+.. _`general pot`: http://pypy.org
diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py
--- a/pypy/interpreter/astcompiler/ast.py
+++ b/pypy/interpreter/astcompiler/ast.py
@@ -51,6 +51,24 @@
space.setattr(self, w_name,
space.getitem(w_state, w_name))
+ def missing_field(self, space, required, host):
+ "Find which required field is missing."
+ state = self.initialization_state
+ for i in range(len(required)):
+ if (state >> i) & 1:
+ continue # field is present
+ missing = required[i]
+ if missing is None:
+ continue # field is optional
+ w_obj = self.getdictvalue(space, missing)
+ if w_obj is None:
+ err = "required field \"%s\" missing from %s"
+ raise operationerrfmt(space.w_TypeError, err, missing, host)
+ else:
+ err = "incorrect type for field \"%s\" in %s"
+ raise operationerrfmt(space.w_TypeError, err, missing, host)
+ raise AssertionError("should not reach here")
+
class NodeVisitorNotImplemented(Exception):
pass
@@ -94,17 +112,6 @@
)
-def missing_field(space, state, required, host):
- "Find which required field is missing."
- for i in range(len(required)):
- if not (state >> i) & 1:
- missing = required[i]
- if missing is not None:
- err = "required field \"%s\" missing from %s"
- err = err % (missing, host)
- w_err = space.wrap(err)
- raise OperationError(space.w_TypeError, w_err)
- raise AssertionError("should not reach here")
class mod(AST):
@@ -112,7 +119,6 @@
class Module(mod):
-
def __init__(self, body):
self.body = body
self.w_body = None
@@ -128,7 +134,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 1:
- missing_field(space, self.initialization_state, ['body'], 'Module')
+ self.missing_field(space, ['body'], 'Module')
else:
pass
w_list = self.w_body
@@ -145,7 +151,6 @@
class Interactive(mod):
-
def __init__(self, body):
self.body = body
self.w_body = None
@@ -161,7 +166,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 1:
- missing_field(space, self.initialization_state, ['body'], 'Interactive')
+ self.missing_field(space, ['body'], 'Interactive')
else:
pass
w_list = self.w_body
@@ -178,7 +183,6 @@
class Expression(mod):
-
def __init__(self, body):
self.body = body
self.initialization_state = 1
@@ -192,7 +196,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 1:
- missing_field(space, self.initialization_state, ['body'], 'Expression')
+ self.missing_field(space, ['body'], 'Expression')
else:
pass
self.body.sync_app_attrs(space)
@@ -200,7 +204,6 @@
class Suite(mod):
-
def __init__(self, body):
self.body = body
self.w_body = None
@@ -216,7 +219,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 1:
- missing_field(space, self.initialization_state, ['body'], 'Suite')
+ self.missing_field(space, ['body'], 'Suite')
else:
pass
w_list = self.w_body
@@ -232,15 +235,13 @@
class stmt(AST):
+
def __init__(self, lineno, col_offset):
self.lineno = lineno
self.col_offset = col_offset
class FunctionDef(stmt):
- _lineno_mask = 16
- _col_offset_mask = 32
-
def __init__(self, name, args, body, decorator_list, lineno, col_offset):
self.name = name
self.args = args
@@ -264,7 +265,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 63:
- missing_field(space, self.initialization_state, ['name', 'args', 'body', 'decorator_list', 'lineno', 'col_offset'], 'FunctionDef')
+ self.missing_field(space, ['lineno', 'col_offset', 'name', 'args', 'body', 'decorator_list'], 'FunctionDef')
else:
pass
self.args.sync_app_attrs(space)
@@ -292,9 +293,6 @@
class ClassDef(stmt):
- _lineno_mask = 16
- _col_offset_mask = 32
-
def __init__(self, name, bases, body, decorator_list, lineno, col_offset):
self.name = name
self.bases = bases
@@ -320,7 +318,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 63:
- missing_field(space, self.initialization_state, ['name', 'bases', 'body', 'decorator_list', 'lineno', 'col_offset'], 'ClassDef')
+ self.missing_field(space, ['lineno', 'col_offset', 'name', 'bases', 'body', 'decorator_list'], 'ClassDef')
else:
pass
w_list = self.w_bases
@@ -357,9 +355,6 @@
class Return(stmt):
- _lineno_mask = 2
- _col_offset_mask = 4
-
def __init__(self, value, lineno, col_offset):
self.value = value
stmt.__init__(self, lineno, col_offset)
@@ -374,10 +369,10 @@
return visitor.visit_Return(self)
def sync_app_attrs(self, space):
- if (self.initialization_state & ~1) ^ 6:
- missing_field(space, self.initialization_state, [None, 'lineno', 'col_offset'], 'Return')
+ if (self.initialization_state & ~4) ^ 3:
+ self.missing_field(space, ['lineno', 'col_offset', None], 'Return')
else:
- if not self.initialization_state & 1:
+ if not self.initialization_state & 4:
self.value = None
if self.value:
self.value.sync_app_attrs(space)
@@ -385,9 +380,6 @@
class Delete(stmt):
- _lineno_mask = 2
- _col_offset_mask = 4
-
def __init__(self, targets, lineno, col_offset):
self.targets = targets
self.w_targets = None
@@ -404,7 +396,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 7:
- missing_field(space, self.initialization_state, ['targets', 'lineno', 'col_offset'], 'Delete')
+ self.missing_field(space, ['lineno', 'col_offset', 'targets'], 'Delete')
else:
pass
w_list = self.w_targets
@@ -421,9 +413,6 @@
class Assign(stmt):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, targets, value, lineno, col_offset):
self.targets = targets
self.w_targets = None
@@ -442,7 +431,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 15:
- missing_field(space, self.initialization_state, ['targets', 'value', 'lineno', 'col_offset'], 'Assign')
+ self.missing_field(space, ['lineno', 'col_offset', 'targets', 'value'], 'Assign')
else:
pass
w_list = self.w_targets
@@ -460,9 +449,6 @@
class AugAssign(stmt):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, target, op, value, lineno, col_offset):
self.target = target
self.op = op
@@ -480,7 +466,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 31:
- missing_field(space, self.initialization_state, ['target', 'op', 'value', 'lineno', 'col_offset'], 'AugAssign')
+ self.missing_field(space, ['lineno', 'col_offset', 'target', 'op', 'value'], 'AugAssign')
else:
pass
self.target.sync_app_attrs(space)
@@ -489,9 +475,6 @@
class Print(stmt):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, dest, values, nl, lineno, col_offset):
self.dest = dest
self.values = values
@@ -511,10 +494,10 @@
return visitor.visit_Print(self)
def sync_app_attrs(self, space):
- if (self.initialization_state & ~1) ^ 30:
- missing_field(space, self.initialization_state, [None, 'values', 'nl', 'lineno', 'col_offset'], 'Print')
+ if (self.initialization_state & ~4) ^ 27:
+ self.missing_field(space, ['lineno', 'col_offset', None, 'values', 'nl'], 'Print')
else:
- if not self.initialization_state & 1:
+ if not self.initialization_state & 4:
self.dest = None
if self.dest:
self.dest.sync_app_attrs(space)
@@ -532,9 +515,6 @@
class For(stmt):
- _lineno_mask = 16
- _col_offset_mask = 32
-
def __init__(self, target, iter, body, orelse, lineno, col_offset):
self.target = target
self.iter = iter
@@ -559,7 +539,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 63:
- missing_field(space, self.initialization_state, ['target', 'iter', 'body', 'orelse', 'lineno', 'col_offset'], 'For')
+ self.missing_field(space, ['lineno', 'col_offset', 'target', 'iter', 'body', 'orelse'], 'For')
else:
pass
self.target.sync_app_attrs(space)
@@ -588,9 +568,6 @@
class While(stmt):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, test, body, orelse, lineno, col_offset):
self.test = test
self.body = body
@@ -613,7 +590,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 31:
- missing_field(space, self.initialization_state, ['test', 'body', 'orelse', 'lineno', 'col_offset'], 'While')
+ self.missing_field(space, ['lineno', 'col_offset', 'test', 'body', 'orelse'], 'While')
else:
pass
self.test.sync_app_attrs(space)
@@ -641,9 +618,6 @@
class If(stmt):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, test, body, orelse, lineno, col_offset):
self.test = test
self.body = body
@@ -666,7 +640,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 31:
- missing_field(space, self.initialization_state, ['test', 'body', 'orelse', 'lineno', 'col_offset'], 'If')
+ self.missing_field(space, ['lineno', 'col_offset', 'test', 'body', 'orelse'], 'If')
else:
pass
self.test.sync_app_attrs(space)
@@ -694,9 +668,6 @@
class With(stmt):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, context_expr, optional_vars, body, lineno, col_offset):
self.context_expr = context_expr
self.optional_vars = optional_vars
@@ -717,10 +688,10 @@
return visitor.visit_With(self)
def sync_app_attrs(self, space):
- if (self.initialization_state & ~2) ^ 29:
- missing_field(space, self.initialization_state, ['context_expr', None, 'body', 'lineno', 'col_offset'], 'With')
+ if (self.initialization_state & ~8) ^ 23:
+ self.missing_field(space, ['lineno', 'col_offset', 'context_expr', None, 'body'], 'With')
else:
- if not self.initialization_state & 2:
+ if not self.initialization_state & 8:
self.optional_vars = None
self.context_expr.sync_app_attrs(space)
if self.optional_vars:
@@ -739,9 +710,6 @@
class Raise(stmt):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, type, inst, tback, lineno, col_offset):
self.type = type
self.inst = inst
@@ -762,14 +730,14 @@
return visitor.visit_Raise(self)
def sync_app_attrs(self, space):
- if (self.initialization_state & ~7) ^ 24:
- missing_field(space, self.initialization_state, [None, None, None, 'lineno', 'col_offset'], 'Raise')
+ if (self.initialization_state & ~28) ^ 3:
+ self.missing_field(space, ['lineno', 'col_offset', None, None, None], 'Raise')
else:
- if not self.initialization_state & 1:
+ if not self.initialization_state & 4:
self.type = None
- if not self.initialization_state & 2:
+ if not self.initialization_state & 8:
self.inst = None
- if not self.initialization_state & 4:
+ if not self.initialization_state & 16:
self.tback = None
if self.type:
self.type.sync_app_attrs(space)
@@ -781,9 +749,6 @@
class TryExcept(stmt):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, body, handlers, orelse, lineno, col_offset):
self.body = body
self.w_body = None
@@ -808,7 +773,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 31:
- missing_field(space, self.initialization_state, ['body', 'handlers', 'orelse', 'lineno', 'col_offset'], 'TryExcept')
+ self.missing_field(space, ['lineno', 'col_offset', 'body', 'handlers', 'orelse'], 'TryExcept')
else:
pass
w_list = self.w_body
@@ -845,9 +810,6 @@
class TryFinally(stmt):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, body, finalbody, lineno, col_offset):
self.body = body
self.w_body = None
@@ -868,7 +830,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 15:
- missing_field(space, self.initialization_state, ['body', 'finalbody', 'lineno', 'col_offset'], 'TryFinally')
+ self.missing_field(space, ['lineno', 'col_offset', 'body', 'finalbody'], 'TryFinally')
else:
pass
w_list = self.w_body
@@ -895,9 +857,6 @@
class Assert(stmt):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, test, msg, lineno, col_offset):
self.test = test
self.msg = msg
@@ -914,10 +873,10 @@
return visitor.visit_Assert(self)
def sync_app_attrs(self, space):
- if (self.initialization_state & ~2) ^ 13:
- missing_field(space, self.initialization_state, ['test', None, 'lineno', 'col_offset'], 'Assert')
+ if (self.initialization_state & ~8) ^ 7:
+ self.missing_field(space, ['lineno', 'col_offset', 'test', None], 'Assert')
else:
- if not self.initialization_state & 2:
+ if not self.initialization_state & 8:
self.msg = None
self.test.sync_app_attrs(space)
if self.msg:
@@ -926,9 +885,6 @@
class Import(stmt):
- _lineno_mask = 2
- _col_offset_mask = 4
-
def __init__(self, names, lineno, col_offset):
self.names = names
self.w_names = None
@@ -945,7 +901,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 7:
- missing_field(space, self.initialization_state, ['names', 'lineno', 'col_offset'], 'Import')
+ self.missing_field(space, ['lineno', 'col_offset', 'names'], 'Import')
else:
pass
w_list = self.w_names
@@ -962,9 +918,6 @@
class ImportFrom(stmt):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, module, names, level, lineno, col_offset):
self.module = module
self.names = names
@@ -982,12 +935,12 @@
return visitor.visit_ImportFrom(self)
def sync_app_attrs(self, space):
- if (self.initialization_state & ~5) ^ 26:
- missing_field(space, self.initialization_state, [None, 'names', None, 'lineno', 'col_offset'], 'ImportFrom')
+ if (self.initialization_state & ~20) ^ 11:
+ self.missing_field(space, ['lineno', 'col_offset', None, 'names', None], 'ImportFrom')
else:
- if not self.initialization_state & 1:
+ if not self.initialization_state & 4:
self.module = None
- if not self.initialization_state & 4:
+ if not self.initialization_state & 16:
self.level = 0
w_list = self.w_names
if w_list is not None:
@@ -1003,9 +956,6 @@
class Exec(stmt):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, body, globals, locals, lineno, col_offset):
self.body = body
self.globals = globals
@@ -1025,12 +975,12 @@
return visitor.visit_Exec(self)
def sync_app_attrs(self, space):
- if (self.initialization_state & ~6) ^ 25:
- missing_field(space, self.initialization_state, ['body', None, None, 'lineno', 'col_offset'], 'Exec')
+ if (self.initialization_state & ~24) ^ 7:
+ self.missing_field(space, ['lineno', 'col_offset', 'body', None, None], 'Exec')
else:
- if not self.initialization_state & 2:
+ if not self.initialization_state & 8:
self.globals = None
- if not self.initialization_state & 4:
+ if not self.initialization_state & 16:
self.locals = None
self.body.sync_app_attrs(space)
if self.globals:
@@ -1041,9 +991,6 @@
class Global(stmt):
- _lineno_mask = 2
- _col_offset_mask = 4
-
def __init__(self, names, lineno, col_offset):
self.names = names
self.w_names = None
@@ -1058,7 +1005,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 7:
- missing_field(space, self.initialization_state, ['names', 'lineno', 'col_offset'], 'Global')
+ self.missing_field(space, ['lineno', 'col_offset', 'names'], 'Global')
else:
pass
w_list = self.w_names
@@ -1072,9 +1019,6 @@
class Expr(stmt):
- _lineno_mask = 2
- _col_offset_mask = 4
-
def __init__(self, value, lineno, col_offset):
self.value = value
stmt.__init__(self, lineno, col_offset)
@@ -1089,7 +1033,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 7:
- missing_field(space, self.initialization_state, ['value', 'lineno', 'col_offset'], 'Expr')
+ self.missing_field(space, ['lineno', 'col_offset', 'value'], 'Expr')
else:
pass
self.value.sync_app_attrs(space)
@@ -1097,9 +1041,6 @@
class Pass(stmt):
- _lineno_mask = 1
- _col_offset_mask = 2
-
def __init__(self, lineno, col_offset):
stmt.__init__(self, lineno, col_offset)
self.initialization_state = 3
@@ -1112,16 +1053,13 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 3:
- missing_field(space, self.initialization_state, ['lineno', 'col_offset'], 'Pass')
+ self.missing_field(space, ['lineno', 'col_offset'], 'Pass')
else:
pass
class Break(stmt):
- _lineno_mask = 1
- _col_offset_mask = 2
-
def __init__(self, lineno, col_offset):
stmt.__init__(self, lineno, col_offset)
self.initialization_state = 3
@@ -1134,16 +1072,13 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 3:
- missing_field(space, self.initialization_state, ['lineno', 'col_offset'], 'Break')
+ self.missing_field(space, ['lineno', 'col_offset'], 'Break')
else:
pass
class Continue(stmt):
- _lineno_mask = 1
- _col_offset_mask = 2
-
def __init__(self, lineno, col_offset):
stmt.__init__(self, lineno, col_offset)
self.initialization_state = 3
@@ -1156,21 +1091,19 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 3:
- missing_field(space, self.initialization_state, ['lineno', 'col_offset'], 'Continue')
+ self.missing_field(space, ['lineno', 'col_offset'], 'Continue')
else:
pass
class expr(AST):
+
def __init__(self, lineno, col_offset):
self.lineno = lineno
self.col_offset = col_offset
class BoolOp(expr):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, op, values, lineno, col_offset):
self.op = op
self.values = values
@@ -1188,7 +1121,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 15:
- missing_field(space, self.initialization_state, ['op', 'values', 'lineno', 'col_offset'], 'BoolOp')
+ self.missing_field(space, ['lineno', 'col_offset', 'op', 'values'], 'BoolOp')
else:
pass
w_list = self.w_values
@@ -1205,9 +1138,6 @@
class BinOp(expr):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, left, op, right, lineno, col_offset):
self.left = left
self.op = op
@@ -1225,7 +1155,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 31:
- missing_field(space, self.initialization_state, ['left', 'op', 'right', 'lineno', 'col_offset'], 'BinOp')
+ self.missing_field(space, ['lineno', 'col_offset', 'left', 'op', 'right'], 'BinOp')
else:
pass
self.left.sync_app_attrs(space)
@@ -1234,9 +1164,6 @@
class UnaryOp(expr):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, op, operand, lineno, col_offset):
self.op = op
self.operand = operand
@@ -1252,7 +1179,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 15:
- missing_field(space, self.initialization_state, ['op', 'operand', 'lineno', 'col_offset'], 'UnaryOp')
+ self.missing_field(space, ['lineno', 'col_offset', 'op', 'operand'], 'UnaryOp')
else:
pass
self.operand.sync_app_attrs(space)
@@ -1260,9 +1187,6 @@
class Lambda(expr):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, args, body, lineno, col_offset):
self.args = args
self.body = body
@@ -1279,7 +1203,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 15:
- missing_field(space, self.initialization_state, ['args', 'body', 'lineno', 'col_offset'], 'Lambda')
+ self.missing_field(space, ['lineno', 'col_offset', 'args', 'body'], 'Lambda')
else:
pass
self.args.sync_app_attrs(space)
@@ -1288,9 +1212,6 @@
class IfExp(expr):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, test, body, orelse, lineno, col_offset):
self.test = test
self.body = body
@@ -1309,7 +1230,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 31:
- missing_field(space, self.initialization_state, ['test', 'body', 'orelse', 'lineno', 'col_offset'], 'IfExp')
+ self.missing_field(space, ['lineno', 'col_offset', 'test', 'body', 'orelse'], 'IfExp')
else:
pass
self.test.sync_app_attrs(space)
@@ -1319,9 +1240,6 @@
class Dict(expr):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, keys, values, lineno, col_offset):
self.keys = keys
self.w_keys = None
@@ -1342,7 +1260,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 15:
- missing_field(space, self.initialization_state, ['keys', 'values', 'lineno', 'col_offset'], 'Dict')
+ self.missing_field(space, ['lineno', 'col_offset', 'keys', 'values'], 'Dict')
else:
pass
w_list = self.w_keys
@@ -1369,9 +1287,6 @@
class Set(expr):
- _lineno_mask = 2
- _col_offset_mask = 4
-
def __init__(self, elts, lineno, col_offset):
self.elts = elts
self.w_elts = None
@@ -1388,7 +1303,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 7:
- missing_field(space, self.initialization_state, ['elts', 'lineno', 'col_offset'], 'Set')
+ self.missing_field(space, ['lineno', 'col_offset', 'elts'], 'Set')
else:
pass
w_list = self.w_elts
@@ -1405,9 +1320,6 @@
class ListComp(expr):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, elt, generators, lineno, col_offset):
self.elt = elt
self.generators = generators
@@ -1426,7 +1338,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 15:
- missing_field(space, self.initialization_state, ['elt', 'generators', 'lineno', 'col_offset'], 'ListComp')
+ self.missing_field(space, ['lineno', 'col_offset', 'elt', 'generators'], 'ListComp')
else:
pass
self.elt.sync_app_attrs(space)
@@ -1444,9 +1356,6 @@
class SetComp(expr):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, elt, generators, lineno, col_offset):
self.elt = elt
self.generators = generators
@@ -1465,7 +1374,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 15:
- missing_field(space, self.initialization_state, ['elt', 'generators', 'lineno', 'col_offset'], 'SetComp')
+ self.missing_field(space, ['lineno', 'col_offset', 'elt', 'generators'], 'SetComp')
else:
pass
self.elt.sync_app_attrs(space)
@@ -1483,9 +1392,6 @@
class DictComp(expr):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, key, value, generators, lineno, col_offset):
self.key = key
self.value = value
@@ -1506,7 +1412,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 31:
- missing_field(space, self.initialization_state, ['key', 'value', 'generators', 'lineno', 'col_offset'], 'DictComp')
+ self.missing_field(space, ['lineno', 'col_offset', 'key', 'value', 'generators'], 'DictComp')
else:
pass
self.key.sync_app_attrs(space)
@@ -1525,9 +1431,6 @@
class GeneratorExp(expr):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, elt, generators, lineno, col_offset):
self.elt = elt
self.generators = generators
@@ -1546,7 +1449,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 15:
- missing_field(space, self.initialization_state, ['elt', 'generators', 'lineno', 'col_offset'], 'GeneratorExp')
+ self.missing_field(space, ['lineno', 'col_offset', 'elt', 'generators'], 'GeneratorExp')
else:
pass
self.elt.sync_app_attrs(space)
@@ -1564,9 +1467,6 @@
class Yield(expr):
- _lineno_mask = 2
- _col_offset_mask = 4
-
def __init__(self, value, lineno, col_offset):
self.value = value
expr.__init__(self, lineno, col_offset)
@@ -1581,10 +1481,10 @@
return visitor.visit_Yield(self)
def sync_app_attrs(self, space):
- if (self.initialization_state & ~1) ^ 6:
- missing_field(space, self.initialization_state, [None, 'lineno', 'col_offset'], 'Yield')
+ if (self.initialization_state & ~4) ^ 3:
+ self.missing_field(space, ['lineno', 'col_offset', None], 'Yield')
else:
- if not self.initialization_state & 1:
+ if not self.initialization_state & 4:
self.value = None
if self.value:
self.value.sync_app_attrs(space)
@@ -1592,9 +1492,6 @@
class Compare(expr):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, left, ops, comparators, lineno, col_offset):
self.left = left
self.ops = ops
@@ -1615,7 +1512,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 31:
- missing_field(space, self.initialization_state, ['left', 'ops', 'comparators', 'lineno', 'col_offset'], 'Compare')
+ self.missing_field(space, ['lineno', 'col_offset', 'left', 'ops', 'comparators'], 'Compare')
else:
pass
self.left.sync_app_attrs(space)
@@ -1640,9 +1537,6 @@
class Call(expr):
- _lineno_mask = 32
- _col_offset_mask = 64
-
def __init__(self, func, args, keywords, starargs, kwargs, lineno, col_offset):
self.func = func
self.args = args
@@ -1670,12 +1564,12 @@
return visitor.visit_Call(self)
def sync_app_attrs(self, space):
- if (self.initialization_state & ~24) ^ 103:
- missing_field(space, self.initialization_state, ['func', 'args', 'keywords', None, None, 'lineno', 'col_offset'], 'Call')
+ if (self.initialization_state & ~96) ^ 31:
+ self.missing_field(space, ['lineno', 'col_offset', 'func', 'args', 'keywords', None, None], 'Call')
else:
- if not self.initialization_state & 8:
+ if not self.initialization_state & 32:
self.starargs = None
- if not self.initialization_state & 16:
+ if not self.initialization_state & 64:
self.kwargs = None
self.func.sync_app_attrs(space)
w_list = self.w_args
@@ -1706,9 +1600,6 @@
class Repr(expr):
- _lineno_mask = 2
- _col_offset_mask = 4
-
def __init__(self, value, lineno, col_offset):
self.value = value
expr.__init__(self, lineno, col_offset)
@@ -1723,7 +1614,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 7:
- missing_field(space, self.initialization_state, ['value', 'lineno', 'col_offset'], 'Repr')
+ self.missing_field(space, ['lineno', 'col_offset', 'value'], 'Repr')
else:
pass
self.value.sync_app_attrs(space)
@@ -1731,9 +1622,6 @@
class Num(expr):
- _lineno_mask = 2
- _col_offset_mask = 4
-
def __init__(self, n, lineno, col_offset):
self.n = n
expr.__init__(self, lineno, col_offset)
@@ -1747,16 +1635,13 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 7:
- missing_field(space, self.initialization_state, ['n', 'lineno', 'col_offset'], 'Num')
+ self.missing_field(space, ['lineno', 'col_offset', 'n'], 'Num')
else:
pass
class Str(expr):
- _lineno_mask = 2
- _col_offset_mask = 4
-
def __init__(self, s, lineno, col_offset):
self.s = s
expr.__init__(self, lineno, col_offset)
@@ -1770,16 +1655,13 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 7:
- missing_field(space, self.initialization_state, ['s', 'lineno', 'col_offset'], 'Str')
+ self.missing_field(space, ['lineno', 'col_offset', 's'], 'Str')
else:
pass
class Attribute(expr):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, value, attr, ctx, lineno, col_offset):
self.value = value
self.attr = attr
@@ -1796,7 +1678,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 31:
- missing_field(space, self.initialization_state, ['value', 'attr', 'ctx', 'lineno', 'col_offset'], 'Attribute')
+ self.missing_field(space, ['lineno', 'col_offset', 'value', 'attr', 'ctx'], 'Attribute')
else:
pass
self.value.sync_app_attrs(space)
@@ -1804,9 +1686,6 @@
class Subscript(expr):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, value, slice, ctx, lineno, col_offset):
self.value = value
self.slice = slice
@@ -1824,7 +1703,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 31:
- missing_field(space, self.initialization_state, ['value', 'slice', 'ctx', 'lineno', 'col_offset'], 'Subscript')
+ self.missing_field(space, ['lineno', 'col_offset', 'value', 'slice', 'ctx'], 'Subscript')
else:
pass
self.value.sync_app_attrs(space)
@@ -1833,9 +1712,6 @@
class Name(expr):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, id, ctx, lineno, col_offset):
self.id = id
self.ctx = ctx
@@ -1850,16 +1726,13 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 15:
- missing_field(space, self.initialization_state, ['id', 'ctx', 'lineno', 'col_offset'], 'Name')
+ self.missing_field(space, ['lineno', 'col_offset', 'id', 'ctx'], 'Name')
else:
pass
class List(expr):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, elts, ctx, lineno, col_offset):
self.elts = elts
self.w_elts = None
@@ -1877,7 +1750,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 15:
- missing_field(space, self.initialization_state, ['elts', 'ctx', 'lineno', 'col_offset'], 'List')
+ self.missing_field(space, ['lineno', 'col_offset', 'elts', 'ctx'], 'List')
else:
pass
w_list = self.w_elts
@@ -1894,9 +1767,6 @@
class Tuple(expr):
- _lineno_mask = 4
- _col_offset_mask = 8
-
def __init__(self, elts, ctx, lineno, col_offset):
self.elts = elts
self.w_elts = None
@@ -1914,7 +1784,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 15:
- missing_field(space, self.initialization_state, ['elts', 'ctx', 'lineno', 'col_offset'], 'Tuple')
+ self.missing_field(space, ['lineno', 'col_offset', 'elts', 'ctx'], 'Tuple')
else:
pass
w_list = self.w_elts
@@ -1931,9 +1801,6 @@
class Const(expr):
- _lineno_mask = 2
- _col_offset_mask = 4
-
def __init__(self, value, lineno, col_offset):
self.value = value
expr.__init__(self, lineno, col_offset)
@@ -1947,7 +1814,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 7:
- missing_field(space, self.initialization_state, ['value', 'lineno', 'col_offset'], 'Const')
+ self.missing_field(space, ['lineno', 'col_offset', 'value'], 'Const')
else:
pass
@@ -2009,7 +1876,6 @@
class Ellipsis(slice):
-
def __init__(self):
self.initialization_state = 0
@@ -2021,14 +1887,13 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 0:
- missing_field(space, self.initialization_state, [], 'Ellipsis')
+ self.missing_field(space, [], 'Ellipsis')
else:
pass
class Slice(slice):
-
def __init__(self, lower, upper, step):
self.lower = lower
self.upper = upper
@@ -2049,7 +1914,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~7) ^ 0:
- missing_field(space, self.initialization_state, [None, None, None], 'Slice')
+ self.missing_field(space, [None, None, None], 'Slice')
else:
if not self.initialization_state & 1:
self.lower = None
@@ -2067,7 +1932,6 @@
class ExtSlice(slice):
-
def __init__(self, dims):
self.dims = dims
self.w_dims = None
@@ -2083,7 +1947,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 1:
- missing_field(space, self.initialization_state, ['dims'], 'ExtSlice')
+ self.missing_field(space, ['dims'], 'ExtSlice')
else:
pass
w_list = self.w_dims
@@ -2100,7 +1964,6 @@
class Index(slice):
-
def __init__(self, value):
self.value = value
self.initialization_state = 1
@@ -2114,7 +1977,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 1:
- missing_field(space, self.initialization_state, ['value'], 'Index')
+ self.missing_field(space, ['value'], 'Index')
else:
pass
self.value.sync_app_attrs(space)
@@ -2377,7 +2240,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 7:
- missing_field(space, self.initialization_state, ['target', 'iter', 'ifs'], 'comprehension')
+ self.missing_field(space, ['target', 'iter', 'ifs'], 'comprehension')
else:
pass
self.target.sync_app_attrs(space)
@@ -2394,15 +2257,13 @@
node.sync_app_attrs(space)
class excepthandler(AST):
+
def __init__(self, lineno, col_offset):
self.lineno = lineno
self.col_offset = col_offset
class ExceptHandler(excepthandler):
- _lineno_mask = 8
- _col_offset_mask = 16
-
def __init__(self, type, name, body, lineno, col_offset):
self.type = type
self.name = name
@@ -2424,12 +2285,12 @@
return visitor.visit_ExceptHandler(self)
def sync_app_attrs(self, space):
- if (self.initialization_state & ~3) ^ 28:
- missing_field(space, self.initialization_state, [None, None, 'body', 'lineno', 'col_offset'], 'ExceptHandler')
+ if (self.initialization_state & ~12) ^ 19:
+ self.missing_field(space, ['lineno', 'col_offset', None, None, 'body'], 'ExceptHandler')
else:
- if not self.initialization_state & 1:
+ if not self.initialization_state & 4:
self.type = None
- if not self.initialization_state & 2:
+ if not self.initialization_state & 8:
self.name = None
if self.type:
self.type.sync_app_attrs(space)
@@ -2470,7 +2331,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~6) ^ 9:
- missing_field(space, self.initialization_state, ['args', None, None, 'defaults'], 'arguments')
+ self.missing_field(space, ['args', None, None, 'defaults'], 'arguments')
else:
if not self.initialization_state & 2:
self.vararg = None
@@ -2513,7 +2374,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~0) ^ 3:
- missing_field(space, self.initialization_state, ['arg', 'value'], 'keyword')
+ self.missing_field(space, ['arg', 'value'], 'keyword')
else:
pass
self.value.sync_app_attrs(space)
@@ -2533,7 +2394,7 @@
def sync_app_attrs(self, space):
if (self.initialization_state & ~2) ^ 1:
- missing_field(space, self.initialization_state, ['name', None], 'alias')
+ self.missing_field(space, ['name', None], 'alias')
else:
if not self.initialization_state & 2:
self.asname = None
@@ -3019,6 +2880,8 @@
def Expression_set_body(space, w_self, w_new_value):
try:
w_self.body = space.interp_w(expr, w_new_value, False)
+ if type(w_self.body) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -3098,7 +2961,7 @@
w_obj = w_self.getdictvalue(space, 'lineno')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & w_self._lineno_mask:
+ if not w_self.initialization_state & 1:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'lineno')
return space.wrap(w_self.lineno)
@@ -3112,14 +2975,14 @@
w_self.setdictvalue(space, 'lineno', w_new_value)
return
w_self.deldictvalue(space, 'lineno')
- w_self.initialization_state |= w_self._lineno_mask
+ w_self.initialization_state |= 1
def stmt_get_col_offset(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'col_offset')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & w_self._col_offset_mask:
+ if not w_self.initialization_state & 2:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'col_offset')
return space.wrap(w_self.col_offset)
@@ -3133,7 +2996,7 @@
w_self.setdictvalue(space, 'col_offset', w_new_value)
return
w_self.deldictvalue(space, 'col_offset')
- w_self.initialization_state |= w_self._col_offset_mask
+ w_self.initialization_state |= 2
stmt.typedef = typedef.TypeDef("stmt",
AST.typedef,
@@ -3149,7 +3012,7 @@
w_obj = w_self.getdictvalue(space, 'name')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'name')
return space.wrap(w_self.name)
@@ -3163,14 +3026,14 @@
w_self.setdictvalue(space, 'name', w_new_value)
return
w_self.deldictvalue(space, 'name')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def FunctionDef_get_args(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'args')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'args')
return space.wrap(w_self.args)
@@ -3184,10 +3047,10 @@
w_self.setdictvalue(space, 'args', w_new_value)
return
w_self.deldictvalue(space, 'args')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def FunctionDef_get_body(space, w_self):
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
if w_self.w_body is None:
@@ -3201,10 +3064,10 @@
def FunctionDef_set_body(space, w_self, w_new_value):
w_self.w_body = w_new_value
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
def FunctionDef_get_decorator_list(space, w_self):
- if not w_self.initialization_state & 8:
+ if not w_self.initialization_state & 32:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'decorator_list')
if w_self.w_decorator_list is None:
@@ -3218,7 +3081,7 @@
def FunctionDef_set_decorator_list(space, w_self, w_new_value):
w_self.w_decorator_list = w_new_value
- w_self.initialization_state |= 8
+ w_self.initialization_state |= 32
_FunctionDef_field_unroller = unrolling_iterable(['name', 'args', 'body', 'decorator_list'])
def FunctionDef_init(space, w_self, __args__):
@@ -3254,7 +3117,7 @@
w_obj = w_self.getdictvalue(space, 'name')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'name')
return space.wrap(w_self.name)
@@ -3268,10 +3131,10 @@
w_self.setdictvalue(space, 'name', w_new_value)
return
w_self.deldictvalue(space, 'name')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def ClassDef_get_bases(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'bases')
if w_self.w_bases is None:
@@ -3285,10 +3148,10 @@
def ClassDef_set_bases(space, w_self, w_new_value):
w_self.w_bases = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def ClassDef_get_body(space, w_self):
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
if w_self.w_body is None:
@@ -3302,10 +3165,10 @@
def ClassDef_set_body(space, w_self, w_new_value):
w_self.w_body = w_new_value
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
def ClassDef_get_decorator_list(space, w_self):
- if not w_self.initialization_state & 8:
+ if not w_self.initialization_state & 32:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'decorator_list')
if w_self.w_decorator_list is None:
@@ -3319,7 +3182,7 @@
def ClassDef_set_decorator_list(space, w_self, w_new_value):
w_self.w_decorator_list = w_new_value
- w_self.initialization_state |= 8
+ w_self.initialization_state |= 32
_ClassDef_field_unroller = unrolling_iterable(['name', 'bases', 'body', 'decorator_list'])
def ClassDef_init(space, w_self, __args__):
@@ -3356,7 +3219,7 @@
w_obj = w_self.getdictvalue(space, 'value')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
return space.wrap(w_self.value)
@@ -3364,13 +3227,15 @@
def Return_set_value(space, w_self, w_new_value):
try:
w_self.value = space.interp_w(expr, w_new_value, True)
+ if type(w_self.value) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'value', w_new_value)
return
w_self.deldictvalue(space, 'value')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
_Return_field_unroller = unrolling_iterable(['value'])
def Return_init(space, w_self, __args__):
@@ -3397,7 +3262,7 @@
)
def Delete_get_targets(space, w_self):
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'targets')
if w_self.w_targets is None:
@@ -3411,7 +3276,7 @@
def Delete_set_targets(space, w_self, w_new_value):
w_self.w_targets = w_new_value
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
_Delete_field_unroller = unrolling_iterable(['targets'])
def Delete_init(space, w_self, __args__):
@@ -3439,7 +3304,7 @@
)
def Assign_get_targets(space, w_self):
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'targets')
if w_self.w_targets is None:
@@ -3453,14 +3318,14 @@
def Assign_set_targets(space, w_self, w_new_value):
w_self.w_targets = w_new_value
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Assign_get_value(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'value')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
return space.wrap(w_self.value)
@@ -3468,13 +3333,15 @@
def Assign_set_value(space, w_self, w_new_value):
try:
w_self.value = space.interp_w(expr, w_new_value, False)
+ if type(w_self.value) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'value', w_new_value)
return
w_self.deldictvalue(space, 'value')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_Assign_field_unroller = unrolling_iterable(['targets', 'value'])
def Assign_init(space, w_self, __args__):
@@ -3507,7 +3374,7 @@
w_obj = w_self.getdictvalue(space, 'target')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'target')
return space.wrap(w_self.target)
@@ -3515,20 +3382,22 @@
def AugAssign_set_target(space, w_self, w_new_value):
try:
w_self.target = space.interp_w(expr, w_new_value, False)
+ if type(w_self.target) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'target', w_new_value)
return
w_self.deldictvalue(space, 'target')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def AugAssign_get_op(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'op')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'op')
return operator_to_class[w_self.op - 1]()
@@ -3544,14 +3413,14 @@
return
# need to save the original object too
w_self.setdictvalue(space, 'op', w_new_value)
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def AugAssign_get_value(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'value')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
return space.wrap(w_self.value)
@@ -3559,13 +3428,15 @@
def AugAssign_set_value(space, w_self, w_new_value):
try:
w_self.value = space.interp_w(expr, w_new_value, False)
+ if type(w_self.value) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'value', w_new_value)
return
w_self.deldictvalue(space, 'value')
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_AugAssign_field_unroller = unrolling_iterable(['target', 'op', 'value'])
def AugAssign_init(space, w_self, __args__):
@@ -3598,7 +3469,7 @@
w_obj = w_self.getdictvalue(space, 'dest')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'dest')
return space.wrap(w_self.dest)
@@ -3606,16 +3477,18 @@
def Print_set_dest(space, w_self, w_new_value):
try:
w_self.dest = space.interp_w(expr, w_new_value, True)
+ if type(w_self.dest) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'dest', w_new_value)
return
w_self.deldictvalue(space, 'dest')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Print_get_values(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'values')
if w_self.w_values is None:
@@ -3629,14 +3502,14 @@
def Print_set_values(space, w_self, w_new_value):
w_self.w_values = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def Print_get_nl(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'nl')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'nl')
return space.wrap(w_self.nl)
@@ -3650,7 +3523,7 @@
w_self.setdictvalue(space, 'nl', w_new_value)
return
w_self.deldictvalue(space, 'nl')
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_Print_field_unroller = unrolling_iterable(['dest', 'values', 'nl'])
def Print_init(space, w_self, __args__):
@@ -3684,7 +3557,7 @@
w_obj = w_self.getdictvalue(space, 'target')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'target')
return space.wrap(w_self.target)
@@ -3692,20 +3565,22 @@
def For_set_target(space, w_self, w_new_value):
try:
w_self.target = space.interp_w(expr, w_new_value, False)
+ if type(w_self.target) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'target', w_new_value)
return
w_self.deldictvalue(space, 'target')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def For_get_iter(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'iter')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'iter')
return space.wrap(w_self.iter)
@@ -3713,16 +3588,18 @@
def For_set_iter(space, w_self, w_new_value):
try:
w_self.iter = space.interp_w(expr, w_new_value, False)
+ if type(w_self.iter) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'iter', w_new_value)
return
w_self.deldictvalue(space, 'iter')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def For_get_body(space, w_self):
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
if w_self.w_body is None:
@@ -3736,10 +3613,10 @@
def For_set_body(space, w_self, w_new_value):
w_self.w_body = w_new_value
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
def For_get_orelse(space, w_self):
- if not w_self.initialization_state & 8:
+ if not w_self.initialization_state & 32:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'orelse')
if w_self.w_orelse is None:
@@ -3753,7 +3630,7 @@
def For_set_orelse(space, w_self, w_new_value):
w_self.w_orelse = w_new_value
- w_self.initialization_state |= 8
+ w_self.initialization_state |= 32
_For_field_unroller = unrolling_iterable(['target', 'iter', 'body', 'orelse'])
def For_init(space, w_self, __args__):
@@ -3789,7 +3666,7 @@
w_obj = w_self.getdictvalue(space, 'test')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'test')
return space.wrap(w_self.test)
@@ -3797,16 +3674,18 @@
def While_set_test(space, w_self, w_new_value):
try:
w_self.test = space.interp_w(expr, w_new_value, False)
+ if type(w_self.test) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'test', w_new_value)
return
w_self.deldictvalue(space, 'test')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def While_get_body(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
if w_self.w_body is None:
@@ -3820,10 +3699,10 @@
def While_set_body(space, w_self, w_new_value):
w_self.w_body = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def While_get_orelse(space, w_self):
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'orelse')
if w_self.w_orelse is None:
@@ -3837,7 +3716,7 @@
def While_set_orelse(space, w_self, w_new_value):
w_self.w_orelse = w_new_value
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_While_field_unroller = unrolling_iterable(['test', 'body', 'orelse'])
def While_init(space, w_self, __args__):
@@ -3872,7 +3751,7 @@
w_obj = w_self.getdictvalue(space, 'test')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'test')
return space.wrap(w_self.test)
@@ -3880,16 +3759,18 @@
def If_set_test(space, w_self, w_new_value):
try:
w_self.test = space.interp_w(expr, w_new_value, False)
+ if type(w_self.test) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'test', w_new_value)
return
w_self.deldictvalue(space, 'test')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def If_get_body(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
if w_self.w_body is None:
@@ -3903,10 +3784,10 @@
def If_set_body(space, w_self, w_new_value):
w_self.w_body = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def If_get_orelse(space, w_self):
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'orelse')
if w_self.w_orelse is None:
@@ -3920,7 +3801,7 @@
def If_set_orelse(space, w_self, w_new_value):
w_self.w_orelse = w_new_value
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_If_field_unroller = unrolling_iterable(['test', 'body', 'orelse'])
def If_init(space, w_self, __args__):
@@ -3955,7 +3836,7 @@
w_obj = w_self.getdictvalue(space, 'context_expr')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'context_expr')
return space.wrap(w_self.context_expr)
@@ -3963,20 +3844,22 @@
def With_set_context_expr(space, w_self, w_new_value):
try:
w_self.context_expr = space.interp_w(expr, w_new_value, False)
+ if type(w_self.context_expr) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'context_expr', w_new_value)
return
w_self.deldictvalue(space, 'context_expr')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def With_get_optional_vars(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'optional_vars')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'optional_vars')
return space.wrap(w_self.optional_vars)
@@ -3984,16 +3867,18 @@
def With_set_optional_vars(space, w_self, w_new_value):
try:
w_self.optional_vars = space.interp_w(expr, w_new_value, True)
+ if type(w_self.optional_vars) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'optional_vars', w_new_value)
return
w_self.deldictvalue(space, 'optional_vars')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def With_get_body(space, w_self):
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
if w_self.w_body is None:
@@ -4007,7 +3892,7 @@
def With_set_body(space, w_self, w_new_value):
w_self.w_body = w_new_value
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_With_field_unroller = unrolling_iterable(['context_expr', 'optional_vars', 'body'])
def With_init(space, w_self, __args__):
@@ -4041,7 +3926,7 @@
w_obj = w_self.getdictvalue(space, 'type')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'type')
return space.wrap(w_self.type)
@@ -4049,20 +3934,22 @@
def Raise_set_type(space, w_self, w_new_value):
try:
w_self.type = space.interp_w(expr, w_new_value, True)
+ if type(w_self.type) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'type', w_new_value)
return
w_self.deldictvalue(space, 'type')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Raise_get_inst(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'inst')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'inst')
return space.wrap(w_self.inst)
@@ -4070,20 +3957,22 @@
def Raise_set_inst(space, w_self, w_new_value):
try:
w_self.inst = space.interp_w(expr, w_new_value, True)
+ if type(w_self.inst) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'inst', w_new_value)
return
w_self.deldictvalue(space, 'inst')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def Raise_get_tback(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'tback')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'tback')
return space.wrap(w_self.tback)
@@ -4091,13 +3980,15 @@
def Raise_set_tback(space, w_self, w_new_value):
try:
w_self.tback = space.interp_w(expr, w_new_value, True)
+ if type(w_self.tback) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'tback', w_new_value)
return
w_self.deldictvalue(space, 'tback')
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_Raise_field_unroller = unrolling_iterable(['type', 'inst', 'tback'])
def Raise_init(space, w_self, __args__):
@@ -4126,7 +4017,7 @@
)
def TryExcept_get_body(space, w_self):
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
if w_self.w_body is None:
@@ -4140,10 +4031,10 @@
def TryExcept_set_body(space, w_self, w_new_value):
w_self.w_body = w_new_value
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def TryExcept_get_handlers(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'handlers')
if w_self.w_handlers is None:
@@ -4157,10 +4048,10 @@
def TryExcept_set_handlers(space, w_self, w_new_value):
w_self.w_handlers = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def TryExcept_get_orelse(space, w_self):
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'orelse')
if w_self.w_orelse is None:
@@ -4174,7 +4065,7 @@
def TryExcept_set_orelse(space, w_self, w_new_value):
w_self.w_orelse = w_new_value
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_TryExcept_field_unroller = unrolling_iterable(['body', 'handlers', 'orelse'])
def TryExcept_init(space, w_self, __args__):
@@ -4206,7 +4097,7 @@
)
def TryFinally_get_body(space, w_self):
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
if w_self.w_body is None:
@@ -4220,10 +4111,10 @@
def TryFinally_set_body(space, w_self, w_new_value):
w_self.w_body = w_new_value
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def TryFinally_get_finalbody(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'finalbody')
if w_self.w_finalbody is None:
@@ -4237,7 +4128,7 @@
def TryFinally_set_finalbody(space, w_self, w_new_value):
w_self.w_finalbody = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_TryFinally_field_unroller = unrolling_iterable(['body', 'finalbody'])
def TryFinally_init(space, w_self, __args__):
@@ -4271,7 +4162,7 @@
w_obj = w_self.getdictvalue(space, 'test')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'test')
return space.wrap(w_self.test)
@@ -4279,20 +4170,22 @@
def Assert_set_test(space, w_self, w_new_value):
try:
w_self.test = space.interp_w(expr, w_new_value, False)
+ if type(w_self.test) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'test', w_new_value)
return
w_self.deldictvalue(space, 'test')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Assert_get_msg(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'msg')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'msg')
return space.wrap(w_self.msg)
@@ -4300,13 +4193,15 @@
def Assert_set_msg(space, w_self, w_new_value):
try:
w_self.msg = space.interp_w(expr, w_new_value, True)
+ if type(w_self.msg) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'msg', w_new_value)
return
w_self.deldictvalue(space, 'msg')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_Assert_field_unroller = unrolling_iterable(['test', 'msg'])
def Assert_init(space, w_self, __args__):
@@ -4334,7 +4229,7 @@
)
def Import_get_names(space, w_self):
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'names')
if w_self.w_names is None:
@@ -4348,7 +4243,7 @@
def Import_set_names(space, w_self, w_new_value):
w_self.w_names = w_new_value
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
_Import_field_unroller = unrolling_iterable(['names'])
def Import_init(space, w_self, __args__):
@@ -4380,7 +4275,7 @@
w_obj = w_self.getdictvalue(space, 'module')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'module')
return space.wrap(w_self.module)
@@ -4397,10 +4292,10 @@
w_self.setdictvalue(space, 'module', w_new_value)
return
w_self.deldictvalue(space, 'module')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def ImportFrom_get_names(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'names')
if w_self.w_names is None:
@@ -4414,14 +4309,14 @@
def ImportFrom_set_names(space, w_self, w_new_value):
w_self.w_names = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def ImportFrom_get_level(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'level')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'level')
return space.wrap(w_self.level)
@@ -4435,7 +4330,7 @@
w_self.setdictvalue(space, 'level', w_new_value)
return
w_self.deldictvalue(space, 'level')
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_ImportFrom_field_unroller = unrolling_iterable(['module', 'names', 'level'])
def ImportFrom_init(space, w_self, __args__):
@@ -4469,7 +4364,7 @@
w_obj = w_self.getdictvalue(space, 'body')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
return space.wrap(w_self.body)
@@ -4477,20 +4372,22 @@
def Exec_set_body(space, w_self, w_new_value):
try:
w_self.body = space.interp_w(expr, w_new_value, False)
+ if type(w_self.body) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'body', w_new_value)
return
w_self.deldictvalue(space, 'body')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Exec_get_globals(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'globals')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'globals')
return space.wrap(w_self.globals)
@@ -4498,20 +4395,22 @@
def Exec_set_globals(space, w_self, w_new_value):
try:
w_self.globals = space.interp_w(expr, w_new_value, True)
+ if type(w_self.globals) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'globals', w_new_value)
return
w_self.deldictvalue(space, 'globals')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def Exec_get_locals(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'locals')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'locals')
return space.wrap(w_self.locals)
@@ -4519,13 +4418,15 @@
def Exec_set_locals(space, w_self, w_new_value):
try:
w_self.locals = space.interp_w(expr, w_new_value, True)
+ if type(w_self.locals) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'locals', w_new_value)
return
w_self.deldictvalue(space, 'locals')
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_Exec_field_unroller = unrolling_iterable(['body', 'globals', 'locals'])
def Exec_init(space, w_self, __args__):
@@ -4554,7 +4455,7 @@
)
def Global_get_names(space, w_self):
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'names')
if w_self.w_names is None:
@@ -4568,7 +4469,7 @@
def Global_set_names(space, w_self, w_new_value):
w_self.w_names = w_new_value
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
_Global_field_unroller = unrolling_iterable(['names'])
def Global_init(space, w_self, __args__):
@@ -4600,7 +4501,7 @@
w_obj = w_self.getdictvalue(space, 'value')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
return space.wrap(w_self.value)
@@ -4608,13 +4509,15 @@
def Expr_set_value(space, w_self, w_new_value):
try:
w_self.value = space.interp_w(expr, w_new_value, False)
+ if type(w_self.value) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'value', w_new_value)
return
w_self.deldictvalue(space, 'value')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
_Expr_field_unroller = unrolling_iterable(['value'])
def Expr_init(space, w_self, __args__):
@@ -4696,7 +4599,7 @@
w_obj = w_self.getdictvalue(space, 'lineno')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & w_self._lineno_mask:
+ if not w_self.initialization_state & 1:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'lineno')
return space.wrap(w_self.lineno)
@@ -4710,14 +4613,14 @@
w_self.setdictvalue(space, 'lineno', w_new_value)
return
w_self.deldictvalue(space, 'lineno')
- w_self.initialization_state |= w_self._lineno_mask
+ w_self.initialization_state |= 1
def expr_get_col_offset(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'col_offset')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & w_self._col_offset_mask:
+ if not w_self.initialization_state & 2:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'col_offset')
return space.wrap(w_self.col_offset)
@@ -4731,7 +4634,7 @@
w_self.setdictvalue(space, 'col_offset', w_new_value)
return
w_self.deldictvalue(space, 'col_offset')
- w_self.initialization_state |= w_self._col_offset_mask
+ w_self.initialization_state |= 2
expr.typedef = typedef.TypeDef("expr",
AST.typedef,
@@ -4747,7 +4650,7 @@
w_obj = w_self.getdictvalue(space, 'op')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'op')
return boolop_to_class[w_self.op - 1]()
@@ -4763,10 +4666,10 @@
return
# need to save the original object too
w_self.setdictvalue(space, 'op', w_new_value)
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def BoolOp_get_values(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'values')
if w_self.w_values is None:
@@ -4780,7 +4683,7 @@
def BoolOp_set_values(space, w_self, w_new_value):
w_self.w_values = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_BoolOp_field_unroller = unrolling_iterable(['op', 'values'])
def BoolOp_init(space, w_self, __args__):
@@ -4813,7 +4716,7 @@
w_obj = w_self.getdictvalue(space, 'left')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'left')
return space.wrap(w_self.left)
@@ -4821,20 +4724,22 @@
def BinOp_set_left(space, w_self, w_new_value):
try:
w_self.left = space.interp_w(expr, w_new_value, False)
+ if type(w_self.left) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'left', w_new_value)
return
w_self.deldictvalue(space, 'left')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def BinOp_get_op(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'op')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'op')
return operator_to_class[w_self.op - 1]()
@@ -4850,14 +4755,14 @@
return
# need to save the original object too
w_self.setdictvalue(space, 'op', w_new_value)
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def BinOp_get_right(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'right')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'right')
return space.wrap(w_self.right)
@@ -4865,13 +4770,15 @@
def BinOp_set_right(space, w_self, w_new_value):
try:
w_self.right = space.interp_w(expr, w_new_value, False)
+ if type(w_self.right) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'right', w_new_value)
return
w_self.deldictvalue(space, 'right')
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_BinOp_field_unroller = unrolling_iterable(['left', 'op', 'right'])
def BinOp_init(space, w_self, __args__):
@@ -4904,7 +4811,7 @@
w_obj = w_self.getdictvalue(space, 'op')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'op')
return unaryop_to_class[w_self.op - 1]()
@@ -4920,14 +4827,14 @@
return
# need to save the original object too
w_self.setdictvalue(space, 'op', w_new_value)
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def UnaryOp_get_operand(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'operand')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'operand')
return space.wrap(w_self.operand)
@@ -4935,13 +4842,15 @@
def UnaryOp_set_operand(space, w_self, w_new_value):
try:
w_self.operand = space.interp_w(expr, w_new_value, False)
+ if type(w_self.operand) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'operand', w_new_value)
return
w_self.deldictvalue(space, 'operand')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_UnaryOp_field_unroller = unrolling_iterable(['op', 'operand'])
def UnaryOp_init(space, w_self, __args__):
@@ -4973,7 +4882,7 @@
w_obj = w_self.getdictvalue(space, 'args')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'args')
return space.wrap(w_self.args)
@@ -4987,14 +4896,14 @@
w_self.setdictvalue(space, 'args', w_new_value)
return
w_self.deldictvalue(space, 'args')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Lambda_get_body(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'body')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
return space.wrap(w_self.body)
@@ -5002,13 +4911,15 @@
def Lambda_set_body(space, w_self, w_new_value):
try:
w_self.body = space.interp_w(expr, w_new_value, False)
+ if type(w_self.body) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'body', w_new_value)
return
w_self.deldictvalue(space, 'body')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_Lambda_field_unroller = unrolling_iterable(['args', 'body'])
def Lambda_init(space, w_self, __args__):
@@ -5040,7 +4951,7 @@
w_obj = w_self.getdictvalue(space, 'test')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'test')
return space.wrap(w_self.test)
@@ -5048,20 +4959,22 @@
def IfExp_set_test(space, w_self, w_new_value):
try:
w_self.test = space.interp_w(expr, w_new_value, False)
+ if type(w_self.test) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'test', w_new_value)
return
w_self.deldictvalue(space, 'test')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def IfExp_get_body(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'body')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
return space.wrap(w_self.body)
@@ -5069,20 +4982,22 @@
def IfExp_set_body(space, w_self, w_new_value):
try:
w_self.body = space.interp_w(expr, w_new_value, False)
+ if type(w_self.body) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'body', w_new_value)
return
w_self.deldictvalue(space, 'body')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def IfExp_get_orelse(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'orelse')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'orelse')
return space.wrap(w_self.orelse)
@@ -5090,13 +5005,15 @@
def IfExp_set_orelse(space, w_self, w_new_value):
try:
w_self.orelse = space.interp_w(expr, w_new_value, False)
+ if type(w_self.orelse) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'orelse', w_new_value)
return
w_self.deldictvalue(space, 'orelse')
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_IfExp_field_unroller = unrolling_iterable(['test', 'body', 'orelse'])
def IfExp_init(space, w_self, __args__):
@@ -5125,7 +5042,7 @@
)
def Dict_get_keys(space, w_self):
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'keys')
if w_self.w_keys is None:
@@ -5139,10 +5056,10 @@
def Dict_set_keys(space, w_self, w_new_value):
w_self.w_keys = w_new_value
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Dict_get_values(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'values')
if w_self.w_values is None:
@@ -5156,7 +5073,7 @@
def Dict_set_values(space, w_self, w_new_value):
w_self.w_values = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_Dict_field_unroller = unrolling_iterable(['keys', 'values'])
def Dict_init(space, w_self, __args__):
@@ -5186,7 +5103,7 @@
)
def Set_get_elts(space, w_self):
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'elts')
if w_self.w_elts is None:
@@ -5200,7 +5117,7 @@
def Set_set_elts(space, w_self, w_new_value):
w_self.w_elts = w_new_value
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
_Set_field_unroller = unrolling_iterable(['elts'])
def Set_init(space, w_self, __args__):
@@ -5232,7 +5149,7 @@
w_obj = w_self.getdictvalue(space, 'elt')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'elt')
return space.wrap(w_self.elt)
@@ -5240,16 +5157,18 @@
def ListComp_set_elt(space, w_self, w_new_value):
try:
w_self.elt = space.interp_w(expr, w_new_value, False)
+ if type(w_self.elt) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'elt', w_new_value)
return
w_self.deldictvalue(space, 'elt')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def ListComp_get_generators(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'generators')
if w_self.w_generators is None:
@@ -5263,7 +5182,7 @@
def ListComp_set_generators(space, w_self, w_new_value):
w_self.w_generators = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_ListComp_field_unroller = unrolling_iterable(['elt', 'generators'])
def ListComp_init(space, w_self, __args__):
@@ -5296,7 +5215,7 @@
w_obj = w_self.getdictvalue(space, 'elt')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'elt')
return space.wrap(w_self.elt)
@@ -5304,16 +5223,18 @@
def SetComp_set_elt(space, w_self, w_new_value):
try:
w_self.elt = space.interp_w(expr, w_new_value, False)
+ if type(w_self.elt) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'elt', w_new_value)
return
w_self.deldictvalue(space, 'elt')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def SetComp_get_generators(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'generators')
if w_self.w_generators is None:
@@ -5327,7 +5248,7 @@
def SetComp_set_generators(space, w_self, w_new_value):
w_self.w_generators = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_SetComp_field_unroller = unrolling_iterable(['elt', 'generators'])
def SetComp_init(space, w_self, __args__):
@@ -5360,7 +5281,7 @@
w_obj = w_self.getdictvalue(space, 'key')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'key')
return space.wrap(w_self.key)
@@ -5368,20 +5289,22 @@
def DictComp_set_key(space, w_self, w_new_value):
try:
w_self.key = space.interp_w(expr, w_new_value, False)
+ if type(w_self.key) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'key', w_new_value)
return
w_self.deldictvalue(space, 'key')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def DictComp_get_value(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'value')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
return space.wrap(w_self.value)
@@ -5389,16 +5312,18 @@
def DictComp_set_value(space, w_self, w_new_value):
try:
w_self.value = space.interp_w(expr, w_new_value, False)
+ if type(w_self.value) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'value', w_new_value)
return
w_self.deldictvalue(space, 'value')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def DictComp_get_generators(space, w_self):
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'generators')
if w_self.w_generators is None:
@@ -5412,7 +5337,7 @@
def DictComp_set_generators(space, w_self, w_new_value):
w_self.w_generators = w_new_value
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_DictComp_field_unroller = unrolling_iterable(['key', 'value', 'generators'])
def DictComp_init(space, w_self, __args__):
@@ -5446,7 +5371,7 @@
w_obj = w_self.getdictvalue(space, 'elt')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'elt')
return space.wrap(w_self.elt)
@@ -5454,16 +5379,18 @@
def GeneratorExp_set_elt(space, w_self, w_new_value):
try:
w_self.elt = space.interp_w(expr, w_new_value, False)
+ if type(w_self.elt) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'elt', w_new_value)
return
w_self.deldictvalue(space, 'elt')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def GeneratorExp_get_generators(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'generators')
if w_self.w_generators is None:
@@ -5477,7 +5404,7 @@
def GeneratorExp_set_generators(space, w_self, w_new_value):
w_self.w_generators = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_GeneratorExp_field_unroller = unrolling_iterable(['elt', 'generators'])
def GeneratorExp_init(space, w_self, __args__):
@@ -5510,7 +5437,7 @@
w_obj = w_self.getdictvalue(space, 'value')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
return space.wrap(w_self.value)
@@ -5518,13 +5445,15 @@
def Yield_set_value(space, w_self, w_new_value):
try:
w_self.value = space.interp_w(expr, w_new_value, True)
+ if type(w_self.value) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'value', w_new_value)
return
w_self.deldictvalue(space, 'value')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
_Yield_field_unroller = unrolling_iterable(['value'])
def Yield_init(space, w_self, __args__):
@@ -5555,7 +5484,7 @@
w_obj = w_self.getdictvalue(space, 'left')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'left')
return space.wrap(w_self.left)
@@ -5563,16 +5492,18 @@
def Compare_set_left(space, w_self, w_new_value):
try:
w_self.left = space.interp_w(expr, w_new_value, False)
+ if type(w_self.left) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'left', w_new_value)
return
w_self.deldictvalue(space, 'left')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Compare_get_ops(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'ops')
if w_self.w_ops is None:
@@ -5586,10 +5517,10 @@
def Compare_set_ops(space, w_self, w_new_value):
w_self.w_ops = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def Compare_get_comparators(space, w_self):
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'comparators')
if w_self.w_comparators is None:
@@ -5603,7 +5534,7 @@
def Compare_set_comparators(space, w_self, w_new_value):
w_self.w_comparators = w_new_value
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_Compare_field_unroller = unrolling_iterable(['left', 'ops', 'comparators'])
def Compare_init(space, w_self, __args__):
@@ -5638,7 +5569,7 @@
w_obj = w_self.getdictvalue(space, 'func')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'func')
return space.wrap(w_self.func)
@@ -5646,16 +5577,18 @@
def Call_set_func(space, w_self, w_new_value):
try:
w_self.func = space.interp_w(expr, w_new_value, False)
+ if type(w_self.func) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'func', w_new_value)
return
w_self.deldictvalue(space, 'func')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Call_get_args(space, w_self):
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'args')
if w_self.w_args is None:
@@ -5669,10 +5602,10 @@
def Call_set_args(space, w_self, w_new_value):
w_self.w_args = w_new_value
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def Call_get_keywords(space, w_self):
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'keywords')
if w_self.w_keywords is None:
@@ -5686,14 +5619,14 @@
def Call_set_keywords(space, w_self, w_new_value):
w_self.w_keywords = w_new_value
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
def Call_get_starargs(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'starargs')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 8:
+ if not w_self.initialization_state & 32:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'starargs')
return space.wrap(w_self.starargs)
@@ -5701,20 +5634,22 @@
def Call_set_starargs(space, w_self, w_new_value):
try:
w_self.starargs = space.interp_w(expr, w_new_value, True)
+ if type(w_self.starargs) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'starargs', w_new_value)
return
w_self.deldictvalue(space, 'starargs')
- w_self.initialization_state |= 8
+ w_self.initialization_state |= 32
def Call_get_kwargs(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'kwargs')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 16:
+ if not w_self.initialization_state & 64:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'kwargs')
return space.wrap(w_self.kwargs)
@@ -5722,13 +5657,15 @@
def Call_set_kwargs(space, w_self, w_new_value):
try:
w_self.kwargs = space.interp_w(expr, w_new_value, True)
+ if type(w_self.kwargs) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'kwargs', w_new_value)
return
w_self.deldictvalue(space, 'kwargs')
- w_self.initialization_state |= 16
+ w_self.initialization_state |= 64
_Call_field_unroller = unrolling_iterable(['func', 'args', 'keywords', 'starargs', 'kwargs'])
def Call_init(space, w_self, __args__):
@@ -5765,7 +5702,7 @@
w_obj = w_self.getdictvalue(space, 'value')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
return space.wrap(w_self.value)
@@ -5773,13 +5710,15 @@
def Repr_set_value(space, w_self, w_new_value):
try:
w_self.value = space.interp_w(expr, w_new_value, False)
+ if type(w_self.value) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'value', w_new_value)
return
w_self.deldictvalue(space, 'value')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
_Repr_field_unroller = unrolling_iterable(['value'])
def Repr_init(space, w_self, __args__):
@@ -5810,7 +5749,7 @@
w_obj = w_self.getdictvalue(space, 'n')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'n')
return w_self.n
@@ -5824,7 +5763,7 @@
w_self.setdictvalue(space, 'n', w_new_value)
return
w_self.deldictvalue(space, 'n')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
_Num_field_unroller = unrolling_iterable(['n'])
def Num_init(space, w_self, __args__):
@@ -5855,7 +5794,7 @@
w_obj = w_self.getdictvalue(space, 's')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 's')
return w_self.s
@@ -5869,7 +5808,7 @@
w_self.setdictvalue(space, 's', w_new_value)
return
w_self.deldictvalue(space, 's')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
_Str_field_unroller = unrolling_iterable(['s'])
def Str_init(space, w_self, __args__):
@@ -5900,7 +5839,7 @@
w_obj = w_self.getdictvalue(space, 'value')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
return space.wrap(w_self.value)
@@ -5908,20 +5847,22 @@
def Attribute_set_value(space, w_self, w_new_value):
try:
w_self.value = space.interp_w(expr, w_new_value, False)
+ if type(w_self.value) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'value', w_new_value)
return
w_self.deldictvalue(space, 'value')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Attribute_get_attr(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'attr')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'attr')
return space.wrap(w_self.attr)
@@ -5935,14 +5876,14 @@
w_self.setdictvalue(space, 'attr', w_new_value)
return
w_self.deldictvalue(space, 'attr')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def Attribute_get_ctx(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'ctx')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'ctx')
return expr_context_to_class[w_self.ctx - 1]()
@@ -5958,7 +5899,7 @@
return
# need to save the original object too
w_self.setdictvalue(space, 'ctx', w_new_value)
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_Attribute_field_unroller = unrolling_iterable(['value', 'attr', 'ctx'])
def Attribute_init(space, w_self, __args__):
@@ -5991,7 +5932,7 @@
w_obj = w_self.getdictvalue(space, 'value')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
return space.wrap(w_self.value)
@@ -5999,20 +5940,22 @@
def Subscript_set_value(space, w_self, w_new_value):
try:
w_self.value = space.interp_w(expr, w_new_value, False)
+ if type(w_self.value) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'value', w_new_value)
return
w_self.deldictvalue(space, 'value')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Subscript_get_slice(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'slice')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'slice')
return space.wrap(w_self.slice)
@@ -6020,20 +5963,22 @@
def Subscript_set_slice(space, w_self, w_new_value):
try:
w_self.slice = space.interp_w(slice, w_new_value, False)
+ if type(w_self.slice) is slice:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'slice', w_new_value)
return
w_self.deldictvalue(space, 'slice')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def Subscript_get_ctx(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'ctx')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'ctx')
return expr_context_to_class[w_self.ctx - 1]()
@@ -6049,7 +5994,7 @@
return
# need to save the original object too
w_self.setdictvalue(space, 'ctx', w_new_value)
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_Subscript_field_unroller = unrolling_iterable(['value', 'slice', 'ctx'])
def Subscript_init(space, w_self, __args__):
@@ -6082,7 +6027,7 @@
w_obj = w_self.getdictvalue(space, 'id')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'id')
return space.wrap(w_self.id)
@@ -6096,14 +6041,14 @@
w_self.setdictvalue(space, 'id', w_new_value)
return
w_self.deldictvalue(space, 'id')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Name_get_ctx(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'ctx')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'ctx')
return expr_context_to_class[w_self.ctx - 1]()
@@ -6119,7 +6064,7 @@
return
# need to save the original object too
w_self.setdictvalue(space, 'ctx', w_new_value)
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_Name_field_unroller = unrolling_iterable(['id', 'ctx'])
def Name_init(space, w_self, __args__):
@@ -6147,7 +6092,7 @@
)
def List_get_elts(space, w_self):
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'elts')
if w_self.w_elts is None:
@@ -6161,14 +6106,14 @@
def List_set_elts(space, w_self, w_new_value):
w_self.w_elts = w_new_value
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def List_get_ctx(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'ctx')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'ctx')
return expr_context_to_class[w_self.ctx - 1]()
@@ -6184,7 +6129,7 @@
return
# need to save the original object too
w_self.setdictvalue(space, 'ctx', w_new_value)
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_List_field_unroller = unrolling_iterable(['elts', 'ctx'])
def List_init(space, w_self, __args__):
@@ -6213,7 +6158,7 @@
)
def Tuple_get_elts(space, w_self):
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'elts')
if w_self.w_elts is None:
@@ -6227,14 +6172,14 @@
def Tuple_set_elts(space, w_self, w_new_value):
w_self.w_elts = w_new_value
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def Tuple_get_ctx(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'ctx')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'ctx')
return expr_context_to_class[w_self.ctx - 1]()
@@ -6250,7 +6195,7 @@
return
# need to save the original object too
w_self.setdictvalue(space, 'ctx', w_new_value)
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
_Tuple_field_unroller = unrolling_iterable(['elts', 'ctx'])
def Tuple_init(space, w_self, __args__):
@@ -6283,7 +6228,7 @@
w_obj = w_self.getdictvalue(space, 'value')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
return w_self.value
@@ -6297,7 +6242,7 @@
w_self.setdictvalue(space, 'value', w_new_value)
return
w_self.deldictvalue(space, 'value')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
_Const_field_unroller = unrolling_iterable(['value'])
def Const_init(space, w_self, __args__):
@@ -6409,6 +6354,8 @@
def Slice_set_lower(space, w_self, w_new_value):
try:
w_self.lower = space.interp_w(expr, w_new_value, True)
+ if type(w_self.lower) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -6430,6 +6377,8 @@
def Slice_set_upper(space, w_self, w_new_value):
try:
w_self.upper = space.interp_w(expr, w_new_value, True)
+ if type(w_self.upper) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -6451,6 +6400,8 @@
def Slice_set_step(space, w_self, w_new_value):
try:
w_self.step = space.interp_w(expr, w_new_value, True)
+ if type(w_self.step) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -6540,6 +6491,8 @@
def Index_set_value(space, w_self, w_new_value):
try:
w_self.value = space.interp_w(expr, w_new_value, False)
+ if type(w_self.value) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -6809,6 +6762,8 @@
def comprehension_set_target(space, w_self, w_new_value):
try:
w_self.target = space.interp_w(expr, w_new_value, False)
+ if type(w_self.target) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -6830,6 +6785,8 @@
def comprehension_set_iter(space, w_self, w_new_value):
try:
w_self.iter = space.interp_w(expr, w_new_value, False)
+ if type(w_self.iter) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -6887,7 +6844,7 @@
w_obj = w_self.getdictvalue(space, 'lineno')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & w_self._lineno_mask:
+ if not w_self.initialization_state & 1:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'lineno')
return space.wrap(w_self.lineno)
@@ -6901,14 +6858,14 @@
w_self.setdictvalue(space, 'lineno', w_new_value)
return
w_self.deldictvalue(space, 'lineno')
- w_self.initialization_state |= w_self._lineno_mask
+ w_self.initialization_state |= 1
def excepthandler_get_col_offset(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'col_offset')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & w_self._col_offset_mask:
+ if not w_self.initialization_state & 2:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'col_offset')
return space.wrap(w_self.col_offset)
@@ -6922,7 +6879,7 @@
w_self.setdictvalue(space, 'col_offset', w_new_value)
return
w_self.deldictvalue(space, 'col_offset')
- w_self.initialization_state |= w_self._col_offset_mask
+ w_self.initialization_state |= 2
excepthandler.typedef = typedef.TypeDef("excepthandler",
AST.typedef,
@@ -6938,7 +6895,7 @@
w_obj = w_self.getdictvalue(space, 'type')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 1:
+ if not w_self.initialization_state & 4:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'type')
return space.wrap(w_self.type)
@@ -6946,20 +6903,22 @@
def ExceptHandler_set_type(space, w_self, w_new_value):
try:
w_self.type = space.interp_w(expr, w_new_value, True)
+ if type(w_self.type) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'type', w_new_value)
return
w_self.deldictvalue(space, 'type')
- w_self.initialization_state |= 1
+ w_self.initialization_state |= 4
def ExceptHandler_get_name(space, w_self):
if w_self.w_dict is not None:
w_obj = w_self.getdictvalue(space, 'name')
if w_obj is not None:
return w_obj
- if not w_self.initialization_state & 2:
+ if not w_self.initialization_state & 8:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'name')
return space.wrap(w_self.name)
@@ -6967,16 +6926,18 @@
def ExceptHandler_set_name(space, w_self, w_new_value):
try:
w_self.name = space.interp_w(expr, w_new_value, True)
+ if type(w_self.name) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
w_self.setdictvalue(space, 'name', w_new_value)
return
w_self.deldictvalue(space, 'name')
- w_self.initialization_state |= 2
+ w_self.initialization_state |= 8
def ExceptHandler_get_body(space, w_self):
- if not w_self.initialization_state & 4:
+ if not w_self.initialization_state & 16:
typename = space.type(w_self).getname(space)
raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
if w_self.w_body is None:
@@ -6990,7 +6951,7 @@
def ExceptHandler_set_body(space, w_self, w_new_value):
w_self.w_body = w_new_value
- w_self.initialization_state |= 4
+ w_self.initialization_state |= 16
_ExceptHandler_field_unroller = unrolling_iterable(['type', 'name', 'body'])
def ExceptHandler_init(space, w_self, __args__):
@@ -7164,6 +7125,8 @@
def keyword_set_value(space, w_self, w_new_value):
try:
w_self.value = space.interp_w(expr, w_new_value, False)
+ if type(w_self.value) is expr:
+ raise OperationError(space.w_TypeError, space.w_None)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
diff --git a/pypy/interpreter/astcompiler/optimize.py b/pypy/interpreter/astcompiler/optimize.py
--- a/pypy/interpreter/astcompiler/optimize.py
+++ b/pypy/interpreter/astcompiler/optimize.py
@@ -1,6 +1,5 @@
"""codegen helpers and AST constant folding."""
import sys
-import itertools
from pypy.interpreter.astcompiler import ast, consts, misc
from pypy.tool import stdlib_opcode as ops
@@ -146,8 +145,7 @@
}
unrolling_unary_folders = unrolling_iterable(unary_folders.items())
-for folder in itertools.chain(binary_folders.itervalues(),
- unary_folders.itervalues()):
+for folder in binary_folders.values() + unary_folders.values():
folder._always_inline_ = True
del folder
diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py
--- a/pypy/interpreter/astcompiler/tools/asdl_py.py
+++ b/pypy/interpreter/astcompiler/tools/asdl_py.py
@@ -79,6 +79,7 @@
else:
self.emit("class %s(AST):" % (base,))
if sum.attributes:
+ self.emit("")
args = ", ".join(attr.name.value for attr in sum.attributes)
self.emit("def __init__(self, %s):" % (args,), 1)
for attr in sum.attributes:
@@ -114,7 +115,7 @@
else:
names.append(repr(field.name.value))
sub = (", ".join(names), name.value)
- self.emit("missing_field(space, self.initialization_state, [%s], %r)"
+ self.emit("self.missing_field(space, [%s], %r)"
% sub, 3)
self.emit("else:", 2)
# Fill in all the default fields.
@@ -195,17 +196,13 @@
def visitConstructor(self, cons, base, extra_attributes):
self.emit("class %s(%s):" % (cons.name, base))
self.emit("")
- for field in self.data.cons_attributes[cons]:
- subst = (field.name, self.data.field_masks[field])
- self.emit("_%s_mask = %i" % subst, 1)
- self.emit("")
self.make_constructor(cons.fields, cons, extra_attributes, base)
self.emit("")
self.emit("def walkabout(self, visitor):", 1)
self.emit("visitor.visit_%s(self)" % (cons.name,), 2)
self.emit("")
self.make_mutate_over(cons, cons.name)
- self.make_var_syncer(cons.fields + self.data.cons_attributes[cons],
+ self.make_var_syncer(self.data.cons_attributes[cons] + cons.fields,
cons, cons.name)
def visitField(self, field):
@@ -324,7 +321,7 @@
def visitSum(self, sum, name):
for field in sum.attributes:
- self.make_property(field, name, True)
+ self.make_property(field, name)
self.make_typedef(name, "AST", sum.attributes,
fields_name="_attributes")
if not is_simple_sum(sum):
@@ -400,13 +397,10 @@
def visitField(self, field, name):
self.make_property(field, name)
- def make_property(self, field, name, different_masks=False):
+ def make_property(self, field, name):
func = "def %s_get_%s(space, w_self):" % (name, field.name)
self.emit(func)
- if different_masks:
- flag = "w_self._%s_mask" % (field.name,)
- else:
- flag = self.data.field_masks[field]
+ flag = self.data.field_masks[field]
if not field.seq:
self.emit("if w_self.w_dict is not None:", 1)
self.emit(" w_obj = w_self.getdictvalue(space, '%s')" % (field.name,), 1)
@@ -458,6 +452,11 @@
config = (field.name, field.type, repr(field.opt))
self.emit("w_self.%s = space.interp_w(%s, w_new_value, %s)" %
config, 2)
+ if field.type.value not in self.data.prod_simple:
+ self.emit("if type(w_self.%s) is %s:" % (
+ field.name, field.type), 2)
+ self.emit("raise OperationError(space.w_TypeError, "
+ "space.w_None)", 3)
else:
level = 2
if field.opt and field.type.value != "int":
@@ -505,7 +504,10 @@
optional_mask = 0
for i, field in enumerate(fields):
flag = 1 << i
- field_masks[field] = flag
+ if field not in field_masks:
+ field_masks[field] = flag
+ else:
+ assert field_masks[field] == flag
if field.opt:
optional_mask |= flag
else:
@@ -518,9 +520,9 @@
if is_simple_sum(sum):
simple_types.add(tp.name.value)
else:
+ attrs = [field for field in sum.attributes]
for cons in sum.types:
- attrs = [copy_field(field) for field in sum.attributes]
- add_masks(cons.fields + attrs, cons)
+ add_masks(attrs + cons.fields, cons)
cons_attributes[cons] = attrs
else:
prod = tp.value
@@ -588,6 +590,24 @@
space.setattr(self, w_name,
space.getitem(w_state, w_name))
+ def missing_field(self, space, required, host):
+ "Find which required field is missing."
+ state = self.initialization_state
+ for i in range(len(required)):
+ if (state >> i) & 1:
+ continue # field is present
+ missing = required[i]
+ if missing is None:
+ continue # field is optional
+ w_obj = self.getdictvalue(space, missing)
+ if w_obj is None:
+ err = "required field \\"%s\\" missing from %s"
+ raise operationerrfmt(space.w_TypeError, err, missing, host)
+ else:
+ err = "incorrect type for field \\"%s\\" in %s"
+ raise operationerrfmt(space.w_TypeError, err, missing, host)
+ raise AssertionError("should not reach here")
+
class NodeVisitorNotImplemented(Exception):
pass
@@ -631,15 +651,6 @@
)
-def missing_field(space, state, required, host):
- "Find which required field is missing."
- for i in range(len(required)):
- if not (state >> i) & 1:
- missing = required[i]
- if missing is not None:
- err = "required field \\"%s\\" missing from %s"
- raise operationerrfmt(space.w_TypeError, err, missing, host)
- raise AssertionError("should not reach here")
"""
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1,4 +1,3 @@
-import itertools
import pypy
from pypy.interpreter.executioncontext import ExecutionContext, ActionFlag
from pypy.interpreter.executioncontext import UserDelAction, FrameTraceAction
@@ -188,6 +187,12 @@
# -------------------------------------------------------------------
+ def is_w(self, space, w_other):
+ return self is w_other
+
+ def immutable_unique_id(self, space):
+ return None
+
def str_w(self, space):
w_msg = typed_unwrap_error_msg(space, "string", self)
raise OperationError(space.w_TypeError, w_msg)
@@ -482,6 +487,16 @@
'parser', 'fcntl', '_codecs', 'binascii'
]
+ # These modules are treated like CPython treats built-in modules,
+ # i.e. they always shadow any xx.py. The other modules are treated
+ # like CPython treats extension modules, and are loaded in sys.path
+ # order by the fake entry '.../lib_pypy/__extensions__'.
+ MODULES_THAT_ALWAYS_SHADOW = dict.fromkeys([
+ '__builtin__', '__pypy__', '_ast', '_codecs', '_sre', '_warnings',
+ '_weakref', 'errno', 'exceptions', 'gc', 'imp', 'marshal',
+ 'posix', 'nt', 'pwd', 'signal', 'sys', 'thread', 'zipimport',
+ ], None)
+
def make_builtins(self):
"NOT_RPYTHON: only for initializing the space."
@@ -513,8 +528,8 @@
exception_types_w = self.export_builtin_exceptions()
# initialize with "bootstrap types" from objspace (e.g. w_None)
- types_w = itertools.chain(self.get_builtin_types().iteritems(),
- exception_types_w.iteritems())
+ types_w = (self.get_builtin_types().items() +
+ exception_types_w.items())
for name, w_type in types_w:
self.setitem(self.builtin.w_dict, self.wrap(name), w_type)
@@ -681,9 +696,20 @@
"""shortcut for space.is_true(space.eq(w_obj1, w_obj2))"""
return self.is_w(w_obj1, w_obj2) or self.is_true(self.eq(w_obj1, w_obj2))
- def is_w(self, w_obj1, w_obj2):
- """shortcut for space.is_true(space.is_(w_obj1, w_obj2))"""
- return self.is_true(self.is_(w_obj1, w_obj2))
+ def is_(self, w_one, w_two):
+ return self.newbool(self.is_w(w_one, w_two))
+
+ def is_w(self, w_one, w_two):
+ # done by a method call on w_two (and not on w_one, because of the
+ # expected programming style where we say "if x is None" or
+ # "if x is object").
+ return w_two.is_w(self, w_one)
+
+ def id(self, w_obj):
+ w_result = w_obj.immutable_unique_id(self)
+ if w_result is None:
+ w_result = self.wrap(compute_unique_id(w_obj))
+ return w_result
def hash_w(self, w_obj):
"""shortcut for space.int_w(space.hash(w_obj))"""
@@ -879,6 +905,16 @@
"""
return self.unpackiterable(w_iterable, expected_length)
+ def listview_str(self, w_list):
+ """ Return a list of unwrapped strings out of a list of strings. If the
+ argument is not a list or does not contain only strings, return None.
+ May return None anyway.
+ """
+ return None
+
+ def newlist_str(self, list_s):
+ return self.newlist([self.wrap(s) for s in list_s])
+
@jit.unroll_safe
def exception_match(self, w_exc_type, w_check_class):
"""Checks if the given exception type matches 'w_check_class'."""
@@ -1013,9 +1049,6 @@
def isinstance_w(self, w_obj, w_type):
return self.is_true(self.isinstance(w_obj, w_type))
- def id(self, w_obj):
- return self.wrap(compute_unique_id(w_obj))
-
# The code below only works
# for the simple case (new-style instance).
# These methods are patched with the full logic by the __builtin__
@@ -1587,6 +1620,8 @@
'UnicodeError',
'ValueError',
'ZeroDivisionError',
+ 'UnicodeEncodeError',
+ 'UnicodeDecodeError',
]
## Irregular part of the interface:
diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py
--- a/pypy/interpreter/eval.py
+++ b/pypy/interpreter/eval.py
@@ -98,7 +98,6 @@
"Abstract. Get the expected number of locals."
raise TypeError, "abstract"
- @jit.dont_look_inside
def fast2locals(self):
# Copy values from the fastlocals to self.w_locals
if self.w_locals is None:
@@ -112,7 +111,6 @@
w_name = self.space.wrap(name)
self.space.setitem(self.w_locals, w_name, w_value)
- @jit.dont_look_inside
def locals2fast(self):
# Copy values from self.w_locals to the fastlocals
assert self.w_locals is not None
diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -619,7 +619,8 @@
self.descr_reqcls,
args)
except Exception, e:
- raise self.handle_exception(space, e)
+ self.handle_exception(space, e)
+ w_result = None
if w_result is None:
w_result = space.w_None
return w_result
@@ -655,7 +656,8 @@
self.descr_reqcls,
args)
except Exception, e:
- raise self.handle_exception(space, e)
+ self.handle_exception(space, e)
+ w_result = None
if w_result is None:
w_result = space.w_None
return w_result
@@ -674,7 +676,8 @@
self.descr_reqcls,
args.prepend(w_obj))
except Exception, e:
- raise self.handle_exception(space, e)
+ self.handle_exception(space, e)
+ w_result = None
if w_result is None:
w_result = space.w_None
return w_result
@@ -690,7 +693,8 @@
raise OperationError(space.w_SystemError,
space.wrap("unexpected DescrMismatch error"))
except Exception, e:
- raise self.handle_exception(space, e)
+ self.handle_exception(space, e)
+ w_result = None
if w_result is None:
w_result = space.w_None
return w_result
@@ -708,7 +712,8 @@
self.descr_reqcls,
Arguments(space, [w1]))
except Exception, e:
- raise self.handle_exception(space, e)
+ self.handle_exception(space, e)
+ w_result = None
if w_result is None:
w_result = space.w_None
return w_result
@@ -726,7 +731,8 @@
self.descr_reqcls,
Arguments(space, [w1, w2]))
except Exception, e:
- raise self.handle_exception(space, e)
+ self.handle_exception(space, e)
+ w_result = None
if w_result is None:
w_result = space.w_None
return w_result
@@ -744,7 +750,8 @@
self.descr_reqcls,
Arguments(space, [w1, w2, w3]))
except Exception, e:
- raise self.handle_exception(space, e)
+ self.handle_exception(space, e)
+ w_result = None
if w_result is None:
w_result = space.w_None
return w_result
@@ -763,7 +770,8 @@
Arguments(space,
[w1, w2, w3, w4]))
except Exception, e:
- raise self.handle_exception(space, e)
+ self.handle_exception(space, e)
+ w_result = None
if w_result is None:
w_result = space.w_None
return w_result
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -1,8 +1,9 @@
+from pypy.interpreter.baseobjspace import Wrappable
from pypy.interpreter.error import OperationError
-from pypy.interpreter.baseobjspace import Wrappable
from pypy.interpreter.gateway import NoneNotWrapped
+from pypy.interpreter.pyopcode import LoopBlock
from pypy.rlib import jit
-from pypy.interpreter.pyopcode import LoopBlock
+from pypy.rlib.objectmodel import specialize
class GeneratorIterator(Wrappable):
@@ -156,38 +157,43 @@
break
block = block.previous
- def unpack_into(self, results_w):
- """This is a hack for performance: runs the generator and collects
- all produced items in a list."""
- # XXX copied and simplified version of send_ex()
- space = self.space
- if self.running:
- raise OperationError(space.w_ValueError,
- space.wrap('generator already executing'))
- frame = self.frame
- if frame is None: # already finished
- return
- self.running = True
- try:
- pycode = self.pycode
- while True:
- jitdriver.jit_merge_point(self=self, frame=frame,
- results_w=results_w,
- pycode=pycode)
- try:
- w_result = frame.execute_frame(space.w_None)
- except OperationError, e:
- if not e.match(space, space.w_StopIteration):
- raise
- break
- # if the frame is now marked as finished, it was RETURNed from
- if frame.frame_finished_execution:
- break
- results_w.append(w_result) # YIELDed
- finally:
- frame.f_backref = jit.vref_None
- self.running = False
- self.frame = None
-
-jitdriver = jit.JitDriver(greens=['pycode'],
- reds=['self', 'frame', 'results_w'])
+ # Results can be either an RPython list of W_Root, or it can be an
+ # app-level W_ListObject, which also has an append() method, that's why we
+ # generate 2 versions of the function and 2 jit drivers.
+ def _create_unpack_into():
+ jitdriver = jit.JitDriver(greens=['pycode'],
+ reds=['self', 'frame', 'results'])
+ def unpack_into(self, results):
+ """This is a hack for performance: runs the generator and collects
+ all produced items in a list."""
+ # XXX copied and simplified version of send_ex()
+ space = self.space
+ if self.running:
+ raise OperationError(space.w_ValueError,
+ space.wrap('generator already executing'))
+ frame = self.frame
+ if frame is None: # already finished
+ return
+ self.running = True
+ try:
+ pycode = self.pycode
+ while True:
+ jitdriver.jit_merge_point(self=self, frame=frame,
+ results=results, pycode=pycode)
+ try:
+ w_result = frame.execute_frame(space.w_None)
+ except OperationError, e:
+ if not e.match(space, space.w_StopIteration):
+ raise
+ break
+ # if the frame is now marked as finished, it was RETURNed from
+ if frame.frame_finished_execution:
+ break
+ results.append(w_result) # YIELDed
+ finally:
+ frame.f_backref = jit.vref_None
+ self.running = False
+ self.frame = None
+ return unpack_into
+ unpack_into = _create_unpack_into()
+ unpack_into_w = _create_unpack_into()
\ No newline at end of file
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -10,7 +10,7 @@
from pypy.rlib.objectmodel import we_are_translated, instantiate
from pypy.rlib.jit import hint
from pypy.rlib.debug import make_sure_not_resized, check_nonneg
-from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.rarithmetic import intmask, r_uint
from pypy.rlib import jit
from pypy.tool import stdlib_opcode
from pypy.tool.stdlib_opcode import host_bytecode_spec
@@ -167,7 +167,7 @@
# Execution starts just after the last_instr. Initially,
# last_instr is -1. After a generator suspends it points to
# the YIELD_VALUE instruction.
- next_instr = self.last_instr + 1
+ next_instr = r_uint(self.last_instr + 1)
if next_instr != 0:
self.pushvalue(w_inputvalue)
#
@@ -691,6 +691,7 @@
handlerposition = space.int_w(w_handlerposition)
valuestackdepth = space.int_w(w_valuestackdepth)
assert valuestackdepth >= 0
+ assert handlerposition >= 0
blk = instantiate(get_block_class(opname))
blk.handlerposition = handlerposition
blk.valuestackdepth = valuestackdepth
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -837,6 +837,7 @@
raise Yield
def jump_absolute(self, jumpto, next_instr, ec):
+ check_nonneg(jumpto)
return jumpto
def JUMP_FORWARD(self, jumpby, next_instr):
@@ -1278,7 +1279,7 @@
def handle(self, frame, unroller):
next_instr = self.really_handle(frame, unroller) # JIT hack
- return next_instr
+ return r_uint(next_instr)
def really_handle(self, frame, unroller):
""" Purely abstract method
diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py
--- a/pypy/interpreter/test/test_executioncontext.py
+++ b/pypy/interpreter/test/test_executioncontext.py
@@ -292,7 +292,7 @@
import os, sys
print sys.executable, self.tmpfile
if sys.platform == "win32":
- cmdformat = '""%s" "%s""' # excellent! tons of "!
+ cmdformat = '"%s" "%s"'
else:
cmdformat = "'%s' '%s'"
g = os.popen(cmdformat % (sys.executable, self.tmpfile), 'r')
diff --git a/pypy/interpreter/test/test_function.py b/pypy/interpreter/test/test_function.py
--- a/pypy/interpreter/test/test_function.py
+++ b/pypy/interpreter/test/test_function.py
@@ -587,7 +587,7 @@
assert isinstance(meth2, Method)
assert meth2.call_args(args) == obj1
# Check method returned from unbound_method.__get__()
- w_meth3 = descr_function_get(space, func, None, space.type(obj2))
+ w_meth3 = descr_function_get(space, func, space.w_None, space.type(obj2))
meth3 = space.unwrap(w_meth3)
w_meth4 = meth3.descr_method_get(obj2, space.w_None)
meth4 = space.unwrap(w_meth4)
diff --git a/pypy/interpreter/test/test_objspace.py b/pypy/interpreter/test/test_objspace.py
--- a/pypy/interpreter/test/test_objspace.py
+++ b/pypy/interpreter/test/test_objspace.py
@@ -63,10 +63,13 @@
def test_unpackiterable(self):
space = self.space
w = space.wrap
- l = [w(1), w(2), w(3), w(4)]
+ l = [space.newlist([]) for l in range(4)]
w_l = space.newlist(l)
- assert space.unpackiterable(w_l) == l
- assert space.unpackiterable(w_l, 4) == l
+ l1 = space.unpackiterable(w_l)
+ l2 = space.unpackiterable(w_l, 4)
+ for i in range(4):
+ assert space.is_w(l1[i], l[i])
+ assert space.is_w(l2[i], l[i])
err = raises(OperationError, space.unpackiterable, w_l, 3)
assert err.value.match(space, space.w_ValueError)
err = raises(OperationError, space.unpackiterable, w_l, 5)
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -54,7 +54,11 @@
# Hash support
def default_identity_hash(space, w_obj):
- return space.wrap(compute_identity_hash(w_obj))
+ w_unique_id = w_obj.immutable_unique_id(space)
+ if w_unique_id is None: # common case
+ return space.wrap(compute_identity_hash(w_obj))
+ else:
+ return space.hash(w_unique_id)
# ____________________________________________________________
#
diff --git a/pypy/jit/backend/arm/arch.py b/pypy/jit/backend/arm/arch.py
--- a/pypy/jit/backend/arm/arch.py
+++ b/pypy/jit/backend/arm/arch.py
@@ -1,10 +1,9 @@
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.rlib.rarithmetic import r_uint
-from pypy.rpython.lltypesystem import lltype
-FUNC_ALIGN=8
-WORD=4
+FUNC_ALIGN = 8
+WORD = 4
# the number of registers that we need to save around malloc calls
N_REGISTERS_SAVED_BY_MALLOC = 9
@@ -27,18 +26,22 @@
}
"""])
-arm_int_div_sign = lltype.Ptr(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed))
+
def arm_int_div_emulator(a, b):
- return int(a/float(b))
+ return int(a / float(b))
+arm_int_div_sign = lltype.Ptr(
+ lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed))
arm_int_div = rffi.llexternal(
"pypy__arm_int_div", [lltype.Signed, lltype.Signed], lltype.Signed,
_callable=arm_int_div_emulator,
compilation_info=eci,
_nowrapper=True, elidable_function=True)
-arm_uint_div_sign = lltype.Ptr(lltype.FuncType([lltype.Unsigned, lltype.Unsigned], lltype.Unsigned))
+
def arm_uint_div_emulator(a, b):
- return r_uint(a)/r_uint(b)
+ return r_uint(a) / r_uint(b)
+arm_uint_div_sign = lltype.Ptr(
+ lltype.FuncType([lltype.Unsigned, lltype.Unsigned], lltype.Unsigned))
arm_uint_div = rffi.llexternal(
"pypy__arm_uint_div", [lltype.Unsigned, lltype.Unsigned], lltype.Unsigned,
_callable=arm_uint_div_emulator,
@@ -46,7 +49,6 @@
_nowrapper=True, elidable_function=True)
-arm_int_mod_sign = arm_int_div_sign
def arm_int_mod_emulator(a, b):
sign = 1
if a < 0:
@@ -56,9 +58,9 @@
b = -1 * b
res = a % b
return sign * res
+arm_int_mod_sign = arm_int_div_sign
arm_int_mod = rffi.llexternal(
"pypy__arm_int_mod", [lltype.Signed, lltype.Signed], lltype.Signed,
_callable=arm_int_mod_emulator,
compilation_info=eci,
_nowrapper=True, elidable_function=True)
-
diff --git a/pypy/jit/backend/arm/assembler.py b/pypy/jit/backend/arm/assembler.py
--- a/pypy/jit/backend/arm/assembler.py
+++ b/pypy/jit/backend/arm/assembler.py
@@ -1,41 +1,36 @@
from __future__ import with_statement
import os
-from pypy.jit.backend.arm.helper.assembler import saved_registers, count_reg_args, \
+from pypy.jit.backend.arm.helper.assembler import saved_registers, \
+ count_reg_args, \
decode32, encode32, \
- decode64, encode64
+ decode64
from pypy.jit.backend.arm import conditions as c
-from pypy.jit.backend.arm import locations
from pypy.jit.backend.arm import registers as r
-from pypy.jit.backend.arm.arch import WORD, FUNC_ALIGN, PC_OFFSET, N_REGISTERS_SAVED_BY_MALLOC
+from pypy.jit.backend.arm.arch import WORD, FUNC_ALIGN, \
+ PC_OFFSET, N_REGISTERS_SAVED_BY_MALLOC
from pypy.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder
-from pypy.jit.backend.arm.regalloc import (Regalloc, ARMFrameManager, ARMv7RegisterMananger,
- _check_imm_arg, TempInt,
- TempPtr,
- operations as regalloc_operations,
- operations_with_guard as regalloc_operations_with_guard)
+from pypy.jit.backend.arm.regalloc import (Regalloc, ARMFrameManager,
+ ARMv7RegisterManager, check_imm_arg,
+ operations as regalloc_operations,
+ operations_with_guard as regalloc_operations_with_guard)
from pypy.jit.backend.arm.jump import remap_frame_layout
-from pypy.jit.backend.llsupport.regalloc import compute_vars_longevity, TempBox
from pypy.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
from pypy.jit.backend.model import CompiledLoopToken
from pypy.jit.codewriter import longlong
-from pypy.jit.metainterp.history import (Const, ConstInt, ConstPtr,
- BoxInt, BoxPtr, AbstractFailDescr,
- INT, REF, FLOAT)
+from pypy.jit.metainterp.history import (AbstractFailDescr, INT, REF, FLOAT)
from pypy.jit.metainterp.resoperation import rop
from pypy.rlib import rgc
from pypy.rlib.objectmodel import we_are_translated
-from pypy.rlib.rarithmetic import r_uint, r_longlong
-from pypy.rlib.longlong2float import float2longlong, longlong2float
from pypy.rpython.annlowlevel import llhelper
from pypy.rpython.lltypesystem import lltype, rffi, llmemory
from pypy.rpython.lltypesystem.lloperation import llop
-from pypy.jit.backend.arm.opassembler import ResOpAssembler, GuardToken
-from pypy.rlib.debug import (debug_print, debug_start, debug_stop,
- have_debug_prints)
+from pypy.jit.backend.arm.opassembler import ResOpAssembler
+from pypy.rlib.debug import debug_print, debug_start, debug_stop
# XXX Move to llsupport
from pypy.jit.backend.x86.support import values_array, memcpy_fn
+
class AssemblerARM(ResOpAssembler):
"""
Encoding for locations in memory
@@ -52,8 +47,8 @@
\xFF = END_OF_LOCS
"""
FLOAT_TYPE = '\xED'
- REF_TYPE = '\xEE'
- INT_TYPE = '\xEF'
+ REF_TYPE = '\xEE'
+ INT_TYPE = '\xEF'
STACK_LOC = '\xFC'
IMM_LOC = '\xFD'
@@ -62,20 +57,18 @@
END_OF_LOCS = '\xFF'
+ STACK_FIXED_AREA = -1
def __init__(self, cpu, failargs_limit=1000):
self.cpu = cpu
self.fail_boxes_int = values_array(lltype.Signed, failargs_limit)
- self.fail_boxes_float = values_array(longlong.FLOATSTORAGE, failargs_limit)
+ self.fail_boxes_float = values_array(longlong.FLOATSTORAGE,
+ failargs_limit)
self.fail_boxes_ptr = values_array(llmemory.GCREF, failargs_limit)
self.fail_boxes_count = 0
self.fail_force_index = 0
self.setup_failure_recovery()
self.mc = None
- self.malloc_func_addr = 0
- self.malloc_array_func_addr = 0
- self.malloc_str_func_addr = 0
- self.malloc_unicode_func_addr = 0
self.memcpy_addr = 0
self.pending_guards = None
self._exit_code_addr = 0
@@ -84,10 +77,22 @@
self._regalloc = None
self.datablockwrapper = None
self.propagate_exception_path = 0
+ self._compute_stack_size()
+
+ def _compute_stack_size(self):
+ self.STACK_FIXED_AREA = len(r.callee_saved_registers) * WORD
+ self.STACK_FIXED_AREA += WORD # FORCE_TOKEN
+ self.STACK_FIXED_AREA += N_REGISTERS_SAVED_BY_MALLOC * WORD
+ if self.cpu.supports_floats:
+ self.STACK_FIXED_AREA += (len(r.callee_saved_vfp_registers)
+ * 2 * WORD)
+ if self.STACK_FIXED_AREA % 8 != 0:
+ self.STACK_FIXED_AREA += WORD # Stack alignment
+ assert self.STACK_FIXED_AREA % 8 == 0
def setup(self, looptoken, operations):
self.current_clt = looptoken.compiled_loop_token
- operations = self.cpu.gc_ll_descr.rewrite_assembler(self.cpu,
+ operations = self.cpu.gc_ll_descr.rewrite_assembler(self.cpu,
operations, self.current_clt.allgcrefs)
assert self.memcpy_addr != 0, 'setup_once() not called?'
self.mc = ARMv7Builder()
@@ -96,6 +101,7 @@
allblocks = self.get_asmmemmgr_blocks(looptoken)
self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr,
allblocks)
+ self.target_tokens_currently_compiling = {}
return operations
def teardown(self):
@@ -109,28 +115,15 @@
# Addresses of functions called by new_xxx operations
gc_ll_descr = self.cpu.gc_ll_descr
gc_ll_descr.initialize()
- ll_new = gc_ll_descr.get_funcptr_for_new()
- self.malloc_func_addr = rffi.cast(lltype.Signed, ll_new)
self._build_propagate_exception_path()
- if gc_ll_descr.get_funcptr_for_newarray is not None:
- ll_new_array = gc_ll_descr.get_funcptr_for_newarray()
- self.malloc_array_func_addr = rffi.cast(lltype.Signed,
- ll_new_array)
- if gc_ll_descr.get_funcptr_for_newstr is not None:
- ll_new_str = gc_ll_descr.get_funcptr_for_newstr()
- self.malloc_str_func_addr = rffi.cast(lltype.Signed,
- ll_new_str)
- if gc_ll_descr.get_funcptr_for_newunicode is not None:
- ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode()
- self.malloc_unicode_func_addr = rffi.cast(lltype.Signed,
- ll_new_unicode)
if gc_ll_descr.get_malloc_slowpath_addr is not None:
self._build_malloc_slowpath()
if gc_ll_descr.gcrootmap and gc_ll_descr.gcrootmap.is_shadow_stack:
self._build_release_gil(gc_ll_descr.gcrootmap)
self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn)
self._exit_code_addr = self._gen_exit_path()
- self._leave_jitted_hook_save_exc = self._gen_leave_jitted_hook_code(True)
+ self._leave_jitted_hook_save_exc = \
+ self._gen_leave_jitted_hook_code(True)
self._leave_jitted_hook = self._gen_leave_jitted_hook_code(False)
@staticmethod
@@ -146,16 +139,17 @@
after()
_NOARG_FUNC = lltype.Ptr(lltype.FuncType([], lltype.Void))
+
def _build_release_gil(self, gcrootmap):
assert gcrootmap.is_shadow_stack
releasegil_func = llhelper(self._NOARG_FUNC,
self._release_gil_shadowstack)
reacqgil_func = llhelper(self._NOARG_FUNC,
self._reacquire_gil_shadowstack)
- self.releasegil_addr = rffi.cast(lltype.Signed, releasegil_func)
+ self.releasegil_addr = rffi.cast(lltype.Signed, releasegil_func)
self.reacqgil_addr = rffi.cast(lltype.Signed, reacqgil_func)
- def _gen_leave_jitted_hook_code(self, save_exc=False):
+ def _gen_leave_jitted_hook_code(self, save_exc):
mc = ARMv7Builder()
# XXX add a check if cpu supports floats
with saved_registers(mc, r.caller_resp + [r.ip], r.caller_vfp_resp):
@@ -174,7 +168,8 @@
# call on_leave_jitted_save_exc()
# XXX add a check if cpu supports floats
with saved_registers(mc, r.caller_resp + [r.ip], r.caller_vfp_resp):
- addr = self.cpu.get_on_leave_jitted_int(save_exception=True)
+ addr = self.cpu.get_on_leave_jitted_int(save_exception=True,
+ default_to_memoryerror=True)
mc.BL(addr)
mc.gen_load_int(r.ip.value, self.cpu.propagate_exception_v)
mc.MOV_rr(r.r0.value, r.ip.value)
@@ -186,34 +181,37 @@
@rgc.no_collect
def failure_recovery_func(mem_loc, frame_pointer, stack_pointer):
"""mem_loc is a structure in memory describing where the values for
- the failargs are stored.
- frame loc is the address of the frame pointer for the frame to be
- decoded frame """
- return self.decode_registers_and_descr(mem_loc, frame_pointer, stack_pointer)
+ the failargs are stored. frame loc is the address of the frame
+ pointer for the frame to be decoded frame """
+ return self.decode_registers_and_descr(mem_loc,
+ frame_pointer, stack_pointer)
self.failure_recovery_func = failure_recovery_func
- recovery_func_sign = lltype.Ptr(lltype.FuncType([lltype.Signed, lltype.Signed, lltype.Signed], lltype.Signed))
+ recovery_func_sign = lltype.Ptr(lltype.FuncType([lltype.Signed,
+ lltype.Signed, lltype.Signed], lltype.Signed))
@rgc.no_collect
def decode_registers_and_descr(self, mem_loc, frame_loc, regs_loc):
- """Decode locations encoded in memory at mem_loc and write the values to
- the failboxes.
- Values for spilled vars and registers are stored on stack at frame_loc
- """
- #XXX check if units are correct here, when comparing words and bytes and stuff
- # assert 0, 'check if units are correct here, when comparing words and bytes and stuff'
+ """Decode locations encoded in memory at mem_loc and write the values
+ to the failboxes. Values for spilled vars and registers are stored on
+ stack at frame_loc """
+ # XXX check if units are correct here, when comparing words and bytes
+ # and stuff assert 0, 'check if units are correct here, when comparing
+ # words and bytes and stuff'
enc = rffi.cast(rffi.CCHARP, mem_loc)
- frame_depth = frame_loc - (regs_loc + len(r.all_regs)*WORD + len(r.all_vfp_regs)*2*WORD)
+ frame_depth = frame_loc - (regs_loc + len(r.all_regs)
+ * WORD + len(r.all_vfp_regs) * 2 * WORD)
assert (frame_loc - frame_depth) % 4 == 0
stack = rffi.cast(rffi.CCHARP, frame_loc - frame_depth)
assert regs_loc % 4 == 0
vfp_regs = rffi.cast(rffi.CCHARP, regs_loc)
- assert (regs_loc + len(r.all_vfp_regs)*2*WORD) % 4 == 0
+ assert (regs_loc + len(r.all_vfp_regs) * 2 * WORD) % 4 == 0
assert frame_depth >= 0
- regs = rffi.cast(rffi.CCHARP, regs_loc + len(r.all_vfp_regs)*2*WORD)
+ regs = rffi.cast(rffi.CCHARP,
+ regs_loc + len(r.all_vfp_regs) * 2 * WORD)
i = -1
fail_index = -1
while(True):
@@ -231,49 +229,52 @@
if res == self.IMM_LOC:
# imm value
if group == self.INT_TYPE or group == self.REF_TYPE:
- value = decode32(enc, i+1)
+ value = decode32(enc, i + 1)
i += 4
else:
assert group == self.FLOAT_TYPE
- adr = decode32(enc, i+1)
- value = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), adr)[0]
+ adr = decode32(enc, i + 1)
+ tp = rffi.CArrayPtr(longlong.FLOATSTORAGE)
+ value = rffi.cast(tp, adr)[0]
self.fail_boxes_float.setitem(fail_index, value)
i += 4
continue
elif res == self.STACK_LOC:
- stack_loc = decode32(enc, i+1)
+ stack_loc = decode32(enc, i + 1)
i += 4
if group == self.FLOAT_TYPE:
- value = decode64(stack, frame_depth - stack_loc*WORD)
+ value = decode64(stack,
+ frame_depth - (stack_loc + 1) * WORD)
+ fvalue = rffi.cast(longlong.FLOATSTORAGE, value)
+ self.fail_boxes_float.setitem(fail_index, fvalue)
+ continue
+ else:
+ value = decode32(stack, frame_depth - stack_loc * WORD)
+ else: # REG_LOC
+ reg = ord(enc[i])
+ if group == self.FLOAT_TYPE:
+ value = decode64(vfp_regs, reg * 2 * WORD)
self.fail_boxes_float.setitem(fail_index, value)
continue
else:
- value = decode32(stack, frame_depth - stack_loc*WORD)
- else: # REG_LOC
- reg = ord(enc[i])
- if group == self.FLOAT_TYPE:
- value = decode64(vfp_regs, reg*2*WORD)
- self.fail_boxes_float.setitem(fail_index, value)
- continue
- else:
- value = decode32(regs, reg*WORD)
+ value = decode32(regs, reg * WORD)
if group == self.INT_TYPE:
self.fail_boxes_int.setitem(fail_index, value)
elif group == self.REF_TYPE:
+ assert (value & 3) == 0, "misaligned pointer"
tgt = self.fail_boxes_ptr.get_addr_for_num(fail_index)
rffi.cast(rffi.LONGP, tgt)[0] = value
else:
assert 0, 'unknown type'
-
assert enc[i] == self.END_OF_LOCS
- descr = decode32(enc, i+1)
+ descr = decode32(enc, i + 1)
self.fail_boxes_count = fail_index
self.fail_force_index = frame_loc
return descr
- def decode_inputargs(self, enc, regalloc):
+ def decode_inputargs(self, enc):
locs = []
j = 0
while enc[j] != self.END_OF_LOCS:
@@ -282,7 +283,8 @@
j += 1
continue
- assert res in [self.FLOAT_TYPE, self.INT_TYPE, self.REF_TYPE], 'location type is not supported'
+ assert res in [self.FLOAT_TYPE, self.INT_TYPE, self.REF_TYPE], \
+ 'location type is not supported'
res_type = res
j += 1
res = enc[j]
@@ -296,10 +298,10 @@
t = INT
else:
t = REF
- stack_loc = decode32(enc, j+1)
- loc = regalloc.frame_manager.frame_pos(stack_loc, t)
+ stack_loc = decode32(enc, j + 1)
+ loc = ARMFrameManager.frame_pos(stack_loc, t)
j += 4
- else: # REG_LOC
+ else: # REG_LOC
if res_type == self.FLOAT_TYPE:
loc = r.all_vfp_regs[ord(res)]
else:
@@ -309,7 +311,6 @@
return locs
def _build_malloc_slowpath(self):
- gcrootmap = self.cpu.gc_ll_descr.gcrootmap
mc = ARMv7Builder()
assert self.cpu.supports_floats
# We need to push two registers here because we are going to make a
@@ -321,10 +322,10 @@
mc.SUB_rr(r.r0.value, r.r1.value, r.r0.value)
addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr()
# XXX replace with an STMxx operation
- for reg, ofs in ARMv7RegisterMananger.REGLOC_TO_COPY_AREA_OFS.items():
+ for reg, ofs in ARMv7RegisterManager.REGLOC_TO_COPY_AREA_OFS.items():
mc.STR_ri(reg.value, r.fp.value, imm=ofs)
mc.BL(addr)
- for reg, ofs in ARMv7RegisterMananger.REGLOC_TO_COPY_AREA_OFS.items():
+ for reg, ofs in ARMv7RegisterManager.REGLOC_TO_COPY_AREA_OFS.items():
mc.LDR_ri(reg.value, r.fp.value, imm=ofs)
mc.CMP_ri(r.r0.value, 0)
@@ -349,13 +350,16 @@
def _gen_exit_path(self):
mc = ARMv7Builder()
- decode_registers_addr = llhelper(self.recovery_func_sign, self.failure_recovery_func)
-
+ decode_registers_addr = llhelper(self.recovery_func_sign,
+ self.failure_recovery_func)
self._insert_checks(mc)
with saved_registers(mc, r.all_regs, r.all_vfp_regs):
- mc.MOV_rr(r.r0.value, r.ip.value) # move mem block address, to r0 to pass as
- mc.MOV_rr(r.r1.value, r.fp.value) # pass the current frame pointer as second param
- mc.MOV_rr(r.r2.value, r.sp.value) # pass the current stack pointer as third param
+ # move mem block address, to r0 to pass as
+ mc.MOV_rr(r.r0.value, r.ip.value)
+ # pass the current frame pointer as second param
+ mc.MOV_rr(r.r1.value, r.fp.value)
+ # pass the current stack pointer as third param
+ mc.MOV_rr(r.r2.value, r.sp.value)
self._insert_checks(mc)
mc.BL(rffi.cast(lltype.Signed, decode_registers_addr))
mc.MOV_rr(r.ip.value, r.r0.value)
@@ -374,15 +378,15 @@
# 1 separator byte
# 4 bytes for the faildescr
# const floats are stored in memory and the box contains the address
- memsize = (len(arglocs)-1)*6+5
+ memsize = (len(arglocs) - 1) * 6 + 5
memaddr = self.datablockwrapper.malloc_aligned(memsize, alignment=1)
mem = rffi.cast(rffi.CArrayPtr(lltype.Char), memaddr)
i = 0
j = 0
while i < len(args):
- if arglocs[i+1]:
+ if arglocs[i + 1]:
arg = args[i]
- loc = arglocs[i+1]
+ loc = arglocs[i + 1]
if arg.type == INT:
mem[j] = self.INT_TYPE
j += 1
@@ -402,12 +406,18 @@
assert (arg.type == INT or arg.type == REF
or arg.type == FLOAT)
mem[j] = self.IMM_LOC
- encode32(mem, j+1, loc.getint())
+ encode32(mem, j + 1, loc.getint())
j += 5
else:
assert loc.is_stack()
mem[j] = self.STACK_LOC
- encode32(mem, j+1, loc.position)
+ if arg.type == FLOAT:
+ # Float locs store the location number with an offset
+ # of 1 -.- so we need to take this into account here
+ # when generating the encoding
+ encode32(mem, j + 1, loc.position - 1)
+ else:
+ encode32(mem, j + 1, loc.position)
j += 5
else:
mem[j] = self.EMPTY_LOC
@@ -417,15 +427,18 @@
mem[j] = chr(0xFF)
n = self.cpu.get_fail_descr_number(descr)
- encode32(mem, j+1, n)
+ encode32(mem, j + 1, n)
return memaddr
- def _gen_path_to_exit_path(self, descr, args, arglocs, fcond=c.AL, save_exc=False):
+ def _gen_path_to_exit_path(self, descr, args, arglocs,
+ save_exc, fcond=c.AL):
+ assert isinstance(save_exc, bool)
memaddr = self.gen_descr_encoding(descr, args, arglocs)
- self.gen_exit_code(self.mc, memaddr, fcond, save_exc)
+ self.gen_exit_code(self.mc, memaddr, save_exc, fcond)
return memaddr
- def gen_exit_code(self, mc, memaddr, fcond=c.AL, save_exc=False):
+ def gen_exit_code(self, mc, memaddr, save_exc, fcond=c.AL):
+ assert isinstance(save_exc, bool)
self.mc.gen_load_int(r.ip.value, memaddr)
#mc.LDR_ri(r.ip.value, r.pc.value, imm=WORD)
if save_exc:
@@ -440,30 +453,36 @@
self.mc.writechar(chr(0))
def gen_func_epilog(self, mc=None, cond=c.AL):
+ stack_size = self.STACK_FIXED_AREA
+ stack_size -= len(r.callee_saved_registers) * WORD
+ if self.cpu.supports_floats:
+ stack_size -= len(r.callee_saved_vfp_registers) * 2 * WORD
+
gcrootmap = self.cpu.gc_ll_descr.gcrootmap
if mc is None:
mc = self.mc
if gcrootmap and gcrootmap.is_shadow_stack:
self.gen_footer_shadowstack(gcrootmap, mc)
- offset = 1
+ mc.MOV_rr(r.sp.value, r.fp.value, cond=cond)
+ mc.ADD_ri(r.sp.value, r.sp.value, stack_size, cond=cond)
if self.cpu.supports_floats:
- offset += 1 # to keep stack alignment
- mc.MOV_rr(r.sp.value, r.fp.value, cond=cond)
- mc.ADD_ri(r.sp.value, r.sp.value, (N_REGISTERS_SAVED_BY_MALLOC+offset)*WORD, cond=cond)
- if self.cpu.supports_floats:
- mc.VPOP([reg.value for reg in r.callee_saved_vfp_registers], cond=cond)
+ mc.VPOP([reg.value for reg in r.callee_saved_vfp_registers],
+ cond=cond)
mc.POP([reg.value for reg in r.callee_restored_registers], cond=cond)
def gen_func_prolog(self):
+ stack_size = self.STACK_FIXED_AREA
+ stack_size -= len(r.callee_saved_registers) * WORD
+ if self.cpu.supports_floats:
+ stack_size -= len(r.callee_saved_vfp_registers) * 2 * WORD
+
self.mc.PUSH([reg.value for reg in r.callee_saved_registers])
- offset = 1
if self.cpu.supports_floats:
self.mc.VPUSH([reg.value for reg in r.callee_saved_vfp_registers])
- offset +=1 # to keep stack alignment
# here we modify the stack pointer to leave room for the 9 registers
# that are going to be saved here around malloc calls and one word to
# store the force index
- self.mc.SUB_ri(r.sp.value, r.sp.value, (N_REGISTERS_SAVED_BY_MALLOC+offset)*WORD)
+ self.mc.SUB_ri(r.sp.value, r.sp.value, stack_size)
self.mc.MOV_rr(r.fp.value, r.sp.value)
gcrootmap = self.cpu.gc_ll_descr.gcrootmap
if gcrootmap and gcrootmap.is_shadow_stack:
@@ -475,191 +494,86 @@
# XXX add some comments
rst = gcrootmap.get_root_stack_top_addr()
self.mc.gen_load_int(r.ip.value, rst)
- self.mc.LDR_ri(r.r4.value, r.ip.value) # LDR r4, [rootstacktop]
- self.mc.ADD_ri(r.r5.value, r.r4.value, imm=2*WORD) # ADD r5, r4 [2*WORD]
+ self.mc.LDR_ri(r.r4.value, r.ip.value) # LDR r4, [rootstacktop]
+ self.mc.ADD_ri(r.r5.value, r.r4.value,
+ imm=2 * WORD) # ADD r5, r4 [2*WORD]
self.mc.gen_load_int(r.r6.value, gcrootmap.MARKER)
self.mc.STR_ri(r.r6.value, r.r4.value)
- self.mc.STR_ri(r.fp.value, r.r4.value, WORD)
+ self.mc.STR_ri(r.fp.value, r.r4.value, WORD)
self.mc.STR_ri(r.r5.value, r.ip.value)
def gen_footer_shadowstack(self, gcrootmap, mc):
rst = gcrootmap.get_root_stack_top_addr()
mc.gen_load_int(r.ip.value, rst)
- mc.LDR_ri(r.r4.value, r.ip.value) # LDR r4, [rootstacktop]
- mc.SUB_ri(r.r5.value, r.r4.value, imm=2*WORD) # ADD r5, r4 [2*WORD]
+ mc.LDR_ri(r.r4.value, r.ip.value) # LDR r4, [rootstacktop]
+ mc.SUB_ri(r.r5.value, r.r4.value, imm=2 * WORD) # ADD r5, r4 [2*WORD]
mc.STR_ri(r.r5.value, r.ip.value)
- def gen_bootstrap_code(self, nonfloatlocs, floatlocs, inputargs):
- for i in range(len(nonfloatlocs)):
- loc = nonfloatlocs[i]
- if loc is None:
- continue
- arg = inputargs[i]
- assert arg.type != FLOAT
- if arg.type == REF:
- addr = self.fail_boxes_ptr.get_addr_for_num(i)
- elif arg.type == INT:
- addr = self.fail_boxes_int.get_addr_for_num(i)
- else:
- assert 0
- if loc.is_reg():
- reg = loc
- else:
- reg = r.ip
- self.mc.gen_load_int(reg.value, addr)
- self.mc.LDR_ri(reg.value, reg.value)
- if loc.is_stack():
- self.mov_loc_loc(r.ip, loc)
- for i in range(len(floatlocs)):
- loc = floatlocs[i]
- if loc is None:
- continue
- arg = inputargs[i]
- assert arg.type == FLOAT
- addr = self.fail_boxes_float.get_addr_for_num(i)
- self.mc.gen_load_int(r.ip.value, addr)
- if loc.is_vfp_reg():
- self.mc.VLDR(loc.value, r.ip.value)
- else:
- self.mc.VLDR(r.vfp_ip.value, r.ip.value)
- self.mov_loc_loc(r.vfp_ip, loc)
-
- def gen_direct_bootstrap_code(self, loop_head, looptoken, inputargs):
- self.gen_func_prolog()
- nonfloatlocs, floatlocs = looptoken._arm_arglocs
-
- reg_args = count_reg_args(inputargs)
-
- stack_locs = len(inputargs) - reg_args
-
- selected_reg = 0
- count = 0
- float_args = []
- nonfloat_args = []
- nonfloat_regs = []
- # load reg args
- for i in range(reg_args):
- arg = inputargs[i]
- if arg.type == FLOAT and count % 2 != 0:
- selected_reg += 1
- count = 0
- reg = r.all_regs[selected_reg]
-
- if arg.type == FLOAT:
- float_args.append((reg, floatlocs[i]))
- else:
- nonfloat_args.append(reg)
- nonfloat_regs.append(nonfloatlocs[i])
-
- if arg.type == FLOAT:
- selected_reg += 2
- else:
- selected_reg += 1
- count += 1
-
- # move float arguments to vfp regsiters
- for loc, vfp_reg in float_args:
- self.mov_to_vfp_loc(loc, r.all_regs[loc.value+1], vfp_reg)
-
- # remap values stored in core registers
- remap_frame_layout(self, nonfloat_args, nonfloat_regs, r.ip)
-
- # load values passed on the stack to the corresponding locations
- stack_position = len(r.callee_saved_registers)*WORD + \
- len(r.callee_saved_vfp_registers)*2*WORD + \
- N_REGISTERS_SAVED_BY_MALLOC * WORD + \
- 2 * WORD # for the FAIL INDEX and the stack padding
- count = 0
- for i in range(reg_args, len(inputargs)):
- arg = inputargs[i]
- if arg.type == FLOAT:
- loc = floatlocs[i]
- else:
- loc = nonfloatlocs[i]
- if loc.is_reg():
- self.mc.LDR_ri(loc.value, r.fp.value, stack_position)
- count += 1
- elif loc.is_vfp_reg():
- if count % 2 != 0:
- stack_position += WORD
- count = 0
- self.mc.VLDR(loc.value, r.fp.value, stack_position)
- elif loc.is_stack():
- if loc.type == FLOAT:
- if count % 2 != 0:
- stack_position += WORD
- count = 0
- self.mc.VLDR(r.vfp_ip.value, r.fp.value, stack_position)
- self.mov_loc_loc(r.vfp_ip, loc)
- elif loc.type == INT or loc.type == REF:
- count += 1
- self.mc.LDR_ri(r.ip.value, r.fp.value, stack_position)
- self.mov_loc_loc(r.ip, loc)
- else:
- assert 0, 'invalid location'
- else:
- assert 0, 'invalid location'
- if loc.type == FLOAT:
- size = 2
- else:
- size = 1
- stack_position += size * WORD
-
- sp_patch_location = self._prepare_sp_patch_position()
- self.mc.B_offs(loop_head)
- self._patch_sp_offset(sp_patch_location, looptoken._arm_frame_depth)
-
def _dump(self, ops, type='loop'):
debug_start('jit-backend-ops')
debug_print(type)
for op in ops:
debug_print(op.repr())
debug_stop('jit-backend-ops')
+
+ def _call_header(self):
+ self.align()
+ self.gen_func_prolog()
+
# cpu interface
def assemble_loop(self, inputargs, operations, looptoken, log):
-
clt = CompiledLoopToken(self.cpu, looptoken.number)
clt.allgcrefs = []
looptoken.compiled_loop_token = clt
+ clt._debug_nbargs = len(inputargs)
+
+ if not we_are_translated():
+ # Arguments should be unique
+ assert len(set(inputargs)) == len(inputargs)
operations = self.setup(looptoken, operations)
self._dump(operations)
- longevity = compute_vars_longevity(inputargs, operations)
- regalloc = Regalloc(longevity, assembler=self, frame_manager=ARMFrameManager())
+ self._call_header()
+ sp_patch_location = self._prepare_sp_patch_position()
- self.align()
- self.gen_func_prolog()
- sp_patch_location = self._prepare_sp_patch_position()
- nonfloatlocs, floatlocs = regalloc.prepare_loop(inputargs, operations, looptoken)
- self.gen_bootstrap_code(nonfloatlocs, floatlocs, inputargs)
- looptoken._arm_arglocs = [nonfloatlocs, floatlocs]
+ regalloc = Regalloc(assembler=self, frame_manager=ARMFrameManager())
+ regalloc.prepare_loop(inputargs, operations)
+
loop_head = self.mc.currpos()
+ looptoken._arm_loop_code = loop_head
- looptoken._arm_loop_code = loop_head
- looptoken._arm_bootstrap_code = 0
-
- self._walk_operations(operations, regalloc)
-
- looptoken._arm_frame_depth = regalloc.frame_manager.frame_depth
- self._patch_sp_offset(sp_patch_location, looptoken._arm_frame_depth)
-
- self.align()
-
- direct_bootstrap_code = self.mc.currpos()
- self.gen_direct_bootstrap_code(loop_head, looptoken, inputargs)
+ clt.frame_depth = -1
+ frame_depth = self._assemble(operations, regalloc)
+ clt.frame_depth = frame_depth
+ self._patch_sp_offset(sp_patch_location, frame_depth)
self.write_pending_failure_recoveries()
- loop_start = self.materialize_loop(looptoken)
- looptoken._arm_bootstrap_code = loop_start
- looptoken._arm_direct_bootstrap_code = loop_start + direct_bootstrap_code
- self.process_pending_guards(loop_start)
+
+ rawstart = self.materialize_loop(looptoken)
+ looptoken._arm_func_addr = rawstart
+
+ self.process_pending_guards(rawstart)
+ self.fixup_target_tokens(rawstart)
+
if log and not we_are_translated():
print 'Loop', inputargs, operations
- self.mc._dump_trace(loop_start, 'loop_%s.asm' % self.cpu.total_compiled_loops)
+ self.mc._dump_trace(rawstart,
+ 'loop_%s.asm' % self.cpu.total_compiled_loops)
print 'Done assembling loop with token %r' % looptoken
self.teardown()
+ def _assemble(self, operations, regalloc):
+ regalloc.compute_hint_frame_locations(operations)
+ #self.mc.BKPT()
+ self._walk_operations(operations, regalloc)
+ frame_depth = regalloc.frame_manager.get_frame_depth()
+ jump_target_descr = regalloc.jump_target_descr
+ if jump_target_descr is not None:
+ frame_depth = max(frame_depth,
+ jump_target_descr._arm_clt.frame_depth)
+ return frame_depth
+
def assemble_bridge(self, faildescr, inputargs, operations,
original_loop_token, log):
operations = self.setup(original_loop_token, operations)
@@ -667,32 +581,47 @@
assert isinstance(faildescr, AbstractFailDescr)
code = faildescr._failure_recovery_code
enc = rffi.cast(rffi.CCHARP, code)
- longevity = compute_vars_longevity(inputargs, operations)
- regalloc = Regalloc(longevity, assembler=self,
- frame_manager=ARMFrameManager())
+ frame_depth = faildescr._arm_current_frame_depth
+ arglocs = self.decode_inputargs(enc)
+ if not we_are_translated():
+ assert len(inputargs) == len(arglocs)
+
+ regalloc = Regalloc(assembler=self, frame_manager=ARMFrameManager())
+ regalloc.prepare_bridge(inputargs, arglocs, operations)
sp_patch_location = self._prepare_sp_patch_position()
- frame_depth = faildescr._arm_frame_depth
- locs = self.decode_inputargs(enc, regalloc)
- assert len(inputargs) == len(locs)
- regalloc.update_bindings(locs, frame_depth, inputargs)
- self._walk_operations(operations, regalloc)
+ frame_depth = self._assemble(operations, regalloc)
- #original_loop_token._arm_frame_depth = regalloc.frame_manager.frame_depth
- self._patch_sp_offset(sp_patch_location, regalloc.frame_manager.frame_depth)
+ self._patch_sp_offset(sp_patch_location, frame_depth)
self.write_pending_failure_recoveries()
- bridge_start = self.materialize_loop(original_loop_token)
- self.process_pending_guards(bridge_start)
+ rawstart = self.materialize_loop(original_loop_token)
+ self.process_pending_guards(rawstart)
- self.patch_trace(faildescr, original_loop_token, bridge_start, regalloc)
- if log and not we_are_translated():
- print 'Bridge', inputargs, operations
- self.mc._dump_trace(bridge_start, 'bridge_%d.asm' %
- self.cpu.total_compiled_bridges)
+ self.patch_trace(faildescr, original_loop_token,
+ rawstart, regalloc)
+ self.fixup_target_tokens(rawstart)
+
+ if not we_are_translated():
+ # for the benefit of tests
+ faildescr._arm_bridge_frame_depth = frame_depth
+ if log:
+ print 'Bridge', inputargs, operations
+ self.mc._dump_trace(rawstart, 'bridge_%d.asm' %
+ self.cpu.total_compiled_bridges)
+ self.current_clt.frame_depth = max(self.current_clt.frame_depth,
+ frame_depth)
self.teardown()
+ def fixup_target_tokens(self, rawstart):
+ for targettoken in self.target_tokens_currently_compiling:
+ targettoken._arm_loop_code += rawstart
+ self.target_tokens_currently_compiling = None
+
+ def target_arglocs(self, loop_token):
+ return loop_token._arm_arglocs
+
def materialize_loop(self, looptoken):
self.datablockwrapper.done() # finish using cpu.asmmemmgr
self.datablockwrapper = None
@@ -705,12 +634,12 @@
descr = tok.descr
#generate the exit stub and the encoded representation
pos = self.mc.currpos()
- tok.pos_recovery_stub = pos
+ tok.pos_recovery_stub = pos
memaddr = self._gen_path_to_exit_path(descr, tok.failargs,
- tok.faillocs, save_exc=tok.save_exc)
+ tok.faillocs, save_exc=tok.save_exc)
# store info on the descr
- descr._arm_frame_depth = tok.faillocs[0].getint()
+ descr._arm_current_frame_depth = tok.faillocs[0].getint()
descr._failure_recovery_code = memaddr
descr._arm_guard_pos = pos
@@ -725,13 +654,15 @@
if not tok.is_invalidate:
#patch the guard jumpt to the stub
- # overwrite the generate NOP with a B_offs to the pos of the stub
+ # overwrite the generate NOP with a B_offs to the pos of the
+ # stub
mc = ARMv7Builder()
- mc.B_offs(descr._arm_guard_pos - tok.offset, c.get_opposite_of(tok.fcond))
+ mc.B_offs(descr._arm_guard_pos - tok.offset,
+ c.get_opposite_of(tok.fcond))
mc.copy_to_raw_memory(block_start + tok.offset)
else:
clt.invalidate_positions.append(
- (block_start + tok.offset, descr._arm_guard_pos - tok.offset))
+ (block_start + tok.offset, descr._arm_guard_pos - tok.offset))
def get_asmmemmgr_blocks(self, looptoken):
clt = looptoken.compiled_loop_token
@@ -740,21 +671,22 @@
return clt.asmmemmgr_blocks
def _prepare_sp_patch_position(self):
- """Generate NOPs as placeholder to patch the instruction(s) to update the
- sp according to the number of spilled variables"""
- size = (self.mc.size_of_gen_load_int+WORD)
+ """Generate NOPs as placeholder to patch the instruction(s) to update
+ the sp according to the number of spilled variables"""
+ size = (self.mc.size_of_gen_load_int + WORD)
l = self.mc.currpos()
- for _ in range(size//WORD):
+ for _ in range(size // WORD):
self.mc.NOP()
return l
def _patch_sp_offset(self, pos, frame_depth):
- cb = OverwritingBuilder(self.mc, pos, OverwritingBuilder.size_of_gen_load_int+WORD)
+ cb = OverwritingBuilder(self.mc, pos,
+ OverwritingBuilder.size_of_gen_load_int + WORD)
# Note: the frame_depth is one less than the value stored in the frame
# manager
if frame_depth == 1:
return
- n = (frame_depth-1)*WORD
+ n = (frame_depth - 1) * WORD
# ensure the sp is 8 byte aligned when patching it
if n % 8 != 0:
@@ -784,7 +716,7 @@
cb.SUB_rr(r.sp.value, base_reg.value, r.ip.value, cond=fcond)
def _walk_operations(self, operations, regalloc):
- fcond=c.AL
+ fcond = c.AL
self._regalloc = regalloc
while regalloc.position() < len(operations) - 1:
regalloc.next_instruction()
@@ -794,20 +726,28 @@
if op.has_no_side_effect() and op.result not in regalloc.longevity:
regalloc.possibly_free_vars_for_op(op)
elif self.can_merge_with_next_guard(op, i, operations):
+ guard = operations[i + 1]
+ assert guard.is_guard()
+ arglocs = regalloc_operations_with_guard[opnum](regalloc, op,
+ guard, fcond)
+ fcond = asm_operations_with_guard[opnum](self, op,
+ guard, arglocs, regalloc, fcond)
regalloc.next_instruction()
- arglocs = regalloc_operations_with_guard[opnum](regalloc, op,
- operations[i+1], fcond)
- fcond = asm_operations_with_guard[opnum](self, op,
- operations[i+1], arglocs, regalloc, fcond)
+ regalloc.possibly_free_vars_for_op(guard)
+ regalloc.possibly_free_vars(guard.getfailargs())
elif not we_are_translated() and op.getopnum() == -124:
regalloc.prepare_force_spill(op, fcond)
else:
arglocs = regalloc_operations[opnum](regalloc, op, fcond)
if arglocs is not None:
- fcond = asm_operations[opnum](self, op, arglocs, regalloc, fcond)
+ fcond = asm_operations[opnum](self, op, arglocs,
+ regalloc, fcond)
+ if op.is_guard():
+ regalloc.possibly_free_vars(op.getfailargs())
if op.result:
regalloc.possibly_free_var(op.result)
regalloc.possibly_free_vars_for_op(op)
+ regalloc.free_temp_vars()
regalloc._check_invariants()
# from ../x86/regalloc.py
@@ -847,7 +787,7 @@
if size == 4:
return
if size == 1:
- if not signed: #unsigned char
+ if not signed: # unsigned char
self.mc.AND_ri(resloc.value, resloc.value, 0xFF)
else:
self.mc.LSL_ri(resloc.value, resloc.value, 24)
@@ -856,9 +796,6 @@
if not signed:
self.mc.LSL_ri(resloc.value, resloc.value, 16)
self.mc.LSR_ri(resloc.value, resloc.value, 16)
- #self.mc.MOV_ri(r.ip.value, 0xFF)
- #self.mc.ORR_ri(r.ip.value, 0xCFF)
- #self.mc.AND_rr(resloc.value, resloc.value, r.ip.value)
else:
self.mc.LSL_ri(resloc.value, resloc.value, 16)
self.mc.ASR_ri(resloc.value, resloc.value, 16)
@@ -873,7 +810,7 @@
# regalloc support
def load(self, loc, value):
- assert (loc.is_reg() and value.is_imm()
+ assert (loc.is_reg() and value.is_imm()
or loc.is_vfp_reg() and value.is_imm_float())
if value.is_imm():
self.mc.gen_load_int(loc.value, value.getint())
@@ -907,44 +844,49 @@
temp = r.lr
else:
temp = r.ip
- offset = ConstInt(loc.position*WORD)
- if not _check_imm_arg(offset, size=0xFFF):
+ offset = loc.position * WORD
+ if not check_imm_arg(offset, size=0xFFF):
self.mc.PUSH([temp.value], cond=cond)
- self.mc.gen_load_int(temp.value, -offset.value, cond=cond)
- self.mc.STR_rr(prev_loc.value, r.fp.value, temp.value, cond=cond)
+ self.mc.gen_load_int(temp.value, -offset, cond=cond)
+ self.mc.STR_rr(prev_loc.value, r.fp.value,
+ temp.value, cond=cond)
self.mc.POP([temp.value], cond=cond)
else:
- self.mc.STR_ri(prev_loc.value, r.fp.value, imm=-1*offset.value, cond=cond)
+ self.mc.STR_ri(prev_loc.value, r.fp.value,
+ imm=-offset, cond=cond)
else:
assert 0, 'unsupported case'
def _mov_stack_to_loc(self, prev_loc, loc, cond=c.AL):
pushed = False
if loc.is_reg():
- assert prev_loc.type != FLOAT, 'trying to load from an incompatible location into a core register'
- assert loc is not r.lr, 'lr is not supported as a target when moving from the stack'
+ assert prev_loc.type != FLOAT, 'trying to load from an \
+ incompatible location into a core register'
+ assert loc is not r.lr, 'lr is not supported as a target \
+ when moving from the stack'
# unspill a core register
- offset = ConstInt(prev_loc.position*WORD)
- if not _check_imm_arg(offset, size=0xFFF):
+ offset = prev_loc.position * WORD
+ if not check_imm_arg(offset, size=0xFFF):
self.mc.PUSH([r.lr.value], cond=cond)
pushed = True
- self.mc.gen_load_int(r.lr.value, -offset.value, cond=cond)
+ self.mc.gen_load_int(r.lr.value, -offset, cond=cond)
self.mc.LDR_rr(loc.value, r.fp.value, r.lr.value, cond=cond)
else:
- self.mc.LDR_ri(loc.value, r.fp.value, imm=-offset.value, cond=cond)
+ self.mc.LDR_ri(loc.value, r.fp.value, imm=-offset, cond=cond)
if pushed:
self.mc.POP([r.lr.value], cond=cond)
elif loc.is_vfp_reg():
- assert prev_loc.type == FLOAT, 'trying to load from an incompatible location into a float register'
+ assert prev_loc.type == FLOAT, 'trying to load from an \
+ incompatible location into a float register'
# load spilled value into vfp reg
- offset = ConstInt(prev_loc.position*WORD)
+ offset = prev_loc.position * WORD
self.mc.PUSH([r.ip.value], cond=cond)
pushed = True
- if not _check_imm_arg(offset):
- self.mc.gen_load_int(r.ip.value, offset.value, cond=cond)
+ if not check_imm_arg(offset):
+ self.mc.gen_load_int(r.ip.value, offset, cond=cond)
self.mc.SUB_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond)
else:
- self.mc.SUB_ri(r.ip.value, r.fp.value, offset.value, cond=cond)
+ self.mc.SUB_ri(r.ip.value, r.fp.value, offset, cond=cond)
self.mc.VLDR(loc.value, r.ip.value, cond=cond)
if pushed:
self.mc.POP([r.ip.value], cond=cond)
@@ -963,15 +905,16 @@
if loc.is_vfp_reg():
self.mc.VMOV_cc(loc.value, prev_loc.value, cond=cond)
elif loc.is_stack():
- assert loc.type == FLOAT, 'trying to store to an incompatible location from a float register'
+ assert loc.type == FLOAT, 'trying to store to an \
+ incompatible location from a float register'
# spill vfp register
self.mc.PUSH([r.ip.value], cond=cond)
- offset = ConstInt(loc.position*WORD)
- if not _check_imm_arg(offset):
- self.mc.gen_load_int(r.ip.value, offset.value, cond=cond)
+ offset = loc.position * WORD
+ if not check_imm_arg(offset):
+ self.mc.gen_load_int(r.ip.value, offset, cond=cond)
self.mc.SUB_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond)
else:
- self.mc.SUB_ri(r.ip.value, r.fp.value, offset.value, cond=cond)
+ self.mc.SUB_ri(r.ip.value, r.fp.value, offset, cond=cond)
self.mc.VSTR(prev_loc.value, r.ip.value, cond=cond)
self.mc.POP([r.ip.value], cond=cond)
else:
@@ -1009,17 +952,18 @@
self.mc.POP([r.ip.value], cond=cond)
elif vfp_loc.is_stack() and vfp_loc.type == FLOAT:
# load spilled vfp value into two core registers
- offset = ConstInt((vfp_loc.position)*WORD)
- if not _check_imm_arg(offset, size=0xFFF):
+ offset = vfp_loc.position * WORD
+ if not check_imm_arg(offset, size=0xFFF):
self.mc.PUSH([r.ip.value], cond=cond)
- self.mc.gen_load_int(r.ip.value, -offset.value, cond=cond)
+ self.mc.gen_load_int(r.ip.value, -offset, cond=cond)
self.mc.LDR_rr(reg1.value, r.fp.value, r.ip.value, cond=cond)
self.mc.ADD_ri(r.ip.value, r.ip.value, imm=WORD, cond=cond)
self.mc.LDR_rr(reg2.value, r.fp.value, r.ip.value, cond=cond)
self.mc.POP([r.ip.value], cond=cond)
else:
- self.mc.LDR_ri(reg1.value, r.fp.value, imm=-offset.value, cond=cond)
- self.mc.LDR_ri(reg2.value, r.fp.value, imm=-offset.value+WORD, cond=cond)
+ self.mc.LDR_ri(reg1.value, r.fp.value, imm=-offset, cond=cond)
+ self.mc.LDR_ri(reg2.value, r.fp.value,
+ imm=-offset + WORD, cond=cond)
else:
assert 0, 'unsupported case'
@@ -1031,17 +975,18 @@
self.mc.VMOV_cr(vfp_loc.value, reg1.value, reg2.value, cond=cond)
elif vfp_loc.is_stack():
# move from two core registers to a float stack location
- offset = ConstInt((vfp_loc.position)*WORD)
- if not _check_imm_arg(offset, size=0xFFF):
+ offset = vfp_loc.position * WORD
+ if not check_imm_arg(offset, size=0xFFF):
self.mc.PUSH([r.ip.value], cond=cond)
- self.mc.gen_load_int(r.ip.value, -offset.value, cond=cond)
+ self.mc.gen_load_int(r.ip.value, -offset, cond=cond)
self.mc.STR_rr(reg1.value, r.fp.value, r.ip.value, cond=cond)
self.mc.ADD_ri(r.ip.value, r.ip.value, imm=WORD, cond=cond)
self.mc.STR_rr(reg2.value, r.fp.value, r.ip.value, cond=cond)
self.mc.POP([r.ip.value], cond=cond)
else:
- self.mc.STR_ri(reg1.value, r.fp.value, imm=-offset.value, cond=cond)
- self.mc.STR_ri(reg2.value, r.fp.value, imm=-offset.value+WORD, cond=cond)
+ self.mc.STR_ri(reg1.value, r.fp.value, imm=-offset, cond=cond)
+ self.mc.STR_ri(reg2.value, r.fp.value,
+ imm=-offset + WORD, cond=cond)
else:
assert 0, 'unsupported case'
@@ -1092,14 +1037,15 @@
llop.gc_assume_young_pointers(lltype.Void,
llmemory.cast_ptr_to_adr(ptrs))
- def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, tid):
+ def malloc_cond(self, nursery_free_adr, nursery_top_adr, size):
+ assert size & (WORD-1) == 0 # must be correctly aligned
size = max(size, self.cpu.gc_ll_descr.minimal_size_in_nursery)
- size = (size + WORD-1) & ~(WORD-1) # round up
+ size = (size + WORD - 1) & ~(WORD - 1) # round up
self.mc.gen_load_int(r.r0.value, nursery_free_adr)
self.mc.LDR_ri(r.r0.value, r.r0.value)
- if _check_imm_arg(ConstInt(size)):
+ if check_imm_arg(size):
self.mc.ADD_ri(r.r1.value, r.r0.value, size)
else:
self.mc.gen_load_int(r.r1.value, size)
@@ -1136,10 +1082,6 @@
self.mc.gen_load_int(r.ip.value, nursery_free_adr)
self.mc.STR_ri(r.r1.value, r.ip.value)
- self.mc.gen_load_int(r.ip.value, tid)
- self.mc.STR_ri(r.ip.value, r.r0.value)
-
-
def mark_gc_roots(self, force_index, use_copy_area=False):
if force_index < 0:
return # not needed
@@ -1163,14 +1105,18 @@
else:
return 0
+
def not_implemented(msg):
os.write(2, '[ARM/asm] %s\n' % msg)
raise NotImplementedError(msg)
+
def notimplemented_op(self, op, arglocs, regalloc, fcond):
- raise NotImplementedError, op
+ raise NotImplementedError(op)
+
+
def notimplemented_op_with_guard(self, op, guard_op, arglocs, regalloc, fcond):
- raise NotImplementedError, op
+ raise NotImplementedError(op)
asm_operations = [notimplemented_op] * (rop._LAST + 1)
asm_operations_with_guard = [notimplemented_op_with_guard] * (rop._LAST + 1)
@@ -1192,4 +1138,3 @@
if hasattr(AssemblerARM, methname):
func = getattr(AssemblerARM, methname).im_func
asm_operations_with_guard[value] = func
-
diff --git a/pypy/jit/backend/arm/codebuilder.py b/pypy/jit/backend/arm/codebuilder.py
--- a/pypy/jit/backend/arm/codebuilder.py
+++ b/pypy/jit/backend/arm/codebuilder.py
@@ -3,18 +3,22 @@
from pypy.jit.backend.arm import registers as reg
from pypy.jit.backend.arm.arch import (WORD, FUNC_ALIGN)
from pypy.jit.backend.arm.instruction_builder import define_instructions
-
-from pypy.rlib.rmmap import alloc, PTR
-from pypy.rpython.annlowlevel import llhelper
-from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.jit.metainterp.history import ConstInt, BoxInt, AbstractFailDescr
+from pypy.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
from pypy.rlib.objectmodel import we_are_translated
-from pypy.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
+from pypy.rpython.lltypesystem import lltype, rffi, llmemory
from pypy.tool.udir import udir
+clear_cache = rffi.llexternal(
+ "__clear_cache",
+ [llmemory.Address, llmemory.Address],
+ lltype.Void,
+ _nowrapper=True,
+ sandboxsafe=True)
+
+
def binary_helper_call(name):
- signature = getattr(arch, 'arm_%s_sign' % name)
function = getattr(arch, 'arm_%s' % name)
+
def f(self, c=cond.AL):
"""Generates a call to a helper function, takes its
arguments in r0 and r1, result is placed in r0"""
@@ -24,9 +28,10 @@
else:
self.PUSH(range(2, 4), cond=c)
self.BL(addr, c)
- self.POP(range(2,4), cond=c)
+ self.POP(range(2, 4), cond=c)
return f
+
class AbstractARMv7Builder(object):
def __init__(self):
@@ -35,6 +40,7 @@
def align(self):
while(self.currpos() % FUNC_ALIGN != 0):
self.writechar(chr(0))
+
def NOP(self):
self.MOV_rr(0, 0)
@@ -72,7 +78,7 @@
| 0xB << 8
| nregs)
self.write32(instr)
-
+
def VMOV_rc(self, rt, rt2, dm, cond=cond.AL):
"""This instruction copies two words from two ARM core registers into a
doubleword extension register, or from a doubleword extension register
@@ -109,7 +115,7 @@
self.write32(instr)
def VMOV_cc(self, dd, dm, cond=cond.AL):
- sz = 1 # for 64-bit mode
+ sz = 1 # for 64-bit mode
instr = (cond << 28
| 0xEB << 20
| (dd & 0xF) << 12
@@ -156,10 +162,8 @@
self.write32(cond << 28 | 0xEF1FA10)
def B(self, target, c=cond.AL):
- #assert self._fits_in_24bits(target)
- #return (c << 20 | 0xA << 24 | target & 0xFFFFFF)
if c == cond.AL:
- self.LDR_ri(reg.pc.value, reg.pc.value, -arch.PC_OFFSET/2)
+ self.LDR_ri(reg.pc.value, reg.pc.value, -arch.PC_OFFSET / 2)
self.write32(target)
else:
self.gen_load_int(reg.ip.value, target, cond=c)
@@ -173,8 +177,8 @@
def BL(self, target, c=cond.AL):
if c == cond.AL:
- self.ADD_ri(reg.lr.value, reg.pc.value, arch.PC_OFFSET/2)
- self.LDR_ri(reg.pc.value, reg.pc.value, imm=-arch.PC_OFFSET/2)
+ self.ADD_ri(reg.lr.value, reg.pc.value, arch.PC_OFFSET / 2)
+ self.LDR_ri(reg.pc.value, reg.pc.value, imm=-arch.PC_OFFSET / 2)
self.write32(target)
else:
self.gen_load_int(reg.ip.value, target, cond=c)
@@ -228,7 +232,6 @@
def currpos(self):
raise NotImplementedError
- size_of_gen_load_int = 2 * WORD
def gen_load_int(self, r, value, cond=cond.AL):
"""r is the register number, value is the value to be loaded to the
register"""
@@ -237,6 +240,8 @@
self.MOVW_ri(r, bottom, cond)
if top:
self.MOVT_ri(r, top, cond)
+ size_of_gen_load_int = 2 * WORD
+
class OverwritingBuilder(AbstractARMv7Builder):
def __init__(self, cb, start, size):
@@ -253,6 +258,7 @@
self.cb.overwrite(self.index, char)
self.index += 1
+
class ARMv7Builder(BlockBuilderMixin, AbstractARMv7Builder):
def __init__(self):
AbstractARMv7Builder.__init__(self)
@@ -272,7 +278,7 @@
# XXX remove and setup aligning in llsupport
def materialize(self, asmmemmgr, allblocks, gcrootmap=None):
size = self.get_relative_pos()
- malloced = asmmemmgr.malloc(size, size+7)
+ malloced = asmmemmgr.malloc(size, size + 7)
allblocks.append(malloced)
rawstart = malloced[0]
while(rawstart % FUNC_ALIGN != 0):
@@ -284,8 +290,16 @@
gcrootmap.put(rawstart + pos, mark)
return rawstart
+ def clear_cache(self, addr):
+ if we_are_translated():
+ startaddr = rffi.cast(llmemory.Address, addr)
+ endaddr = rffi.cast(llmemory.Address,
+ addr + self.get_relative_pos())
+ clear_cache(startaddr, endaddr)
+
def copy_to_raw_memory(self, addr):
self._copy_to_raw_memory(addr)
+ self.clear_cache(addr)
self._dump(addr, "jit-backend-dump", 'arm')
def currpos(self):
diff --git a/pypy/jit/backend/arm/conditions.py b/pypy/jit/backend/arm/conditions.py
--- a/pypy/jit/backend/arm/conditions.py
+++ b/pypy/jit/backend/arm/conditions.py
@@ -15,10 +15,12 @@
AL = 0xE
opposites = [NE, EQ, CC, CS, PL, MI, VC, VS, LS, HI, LT, GE, LE, GT, AL]
+
+
def get_opposite_of(operation):
return opposites[operation]
-# see mapping for floating poin according to
+# see mapping for floating poin according to
# http://blogs.arm.com/software-enablement/405-condition-codes-4-floating-point-comparisons-using-vfp/
VFP_LT = CC
VFP_LE = LS
diff --git a/pypy/jit/backend/arm/helper/assembler.py b/pypy/jit/backend/arm/helper/assembler.py
--- a/pypy/jit/backend/arm/helper/assembler.py
+++ b/pypy/jit/backend/arm/helper/assembler.py
@@ -29,7 +29,7 @@
guard_opnum = guard.getopnum()
if guard_opnum == rop.GUARD_FALSE:
cond = false_cond
- return self._emit_guard(guard, arglocs[1:], cond)
+ return self._emit_guard(guard, arglocs[1:], cond, save_exc=False)
f.__name__ = 'emit_guard_%s' % name
return f
@@ -92,7 +92,7 @@
cond = true_cond
if guard_opnum == rop.GUARD_FALSE:
cond = false_cond
- return self._emit_guard(guard, arglocs[2:], cond)
+ return self._emit_guard(guard, arglocs[2:], cond, save_exc=False)
f.__name__ = 'emit_guard_%s' % name
return f
@@ -137,7 +137,7 @@
guard_opnum = guard.getopnum()
if guard_opnum == rop.GUARD_FALSE:
cond = false_cond
- return self._emit_guard(guard, arglocs[2:], cond)
+ return self._emit_guard(guard, arglocs[2:], cond, save_exc=False)
f.__name__ = 'emit_guard_%s' % name
return f
diff --git a/pypy/jit/backend/arm/helper/regalloc.py b/pypy/jit/backend/arm/helper/regalloc.py
--- a/pypy/jit/backend/arm/helper/regalloc.py
+++ b/pypy/jit/backend/arm/helper/regalloc.py
@@ -3,42 +3,46 @@
from pypy.jit.backend.arm.codebuilder import AbstractARMv7Builder
from pypy.jit.metainterp.history import ConstInt, BoxInt, Box, FLOAT
from pypy.jit.metainterp.history import ConstInt
+from pypy.rlib.objectmodel import we_are_translated
-# XXX create a version that does not need a ConstInt
-def _check_imm_arg(arg, size=0xFF, allow_zero=True):
+def check_imm_arg(arg, size=0xFF, allow_zero=True):
+ assert not isinstance(arg, ConstInt)
+ if not we_are_translated():
+ if not isinstance(arg, int):
+ import pdb; pdb.set_trace()
+ i = arg
+ if allow_zero:
+ lower_bound = i >= 0
+ else:
+ lower_bound = i > 0
+ return i <= size and lower_bound
+
+def check_imm_box(arg, size=0xFF, allow_zero=True):
if isinstance(arg, ConstInt):
- i = arg.getint()
- if allow_zero:
- lower_bound = i >= 0
- else:
- lower_bound = i > 0
- return i <= size and lower_bound
+ return check_imm_arg(arg.getint(), size, allow_zero)
return False
+
def prepare_op_ri(name=None, imm_size=0xFF, commutative=True, allow_zero=True):
def f(self, op, fcond):
assert fcond is not None
a0 = op.getarg(0)
a1 = op.getarg(1)
boxes = list(op.getarglist())
- imm_a0 = _check_imm_arg(a0, imm_size, allow_zero=allow_zero)
- imm_a1 = _check_imm_arg(a1, imm_size, allow_zero=allow_zero)
+ imm_a0 = check_imm_box(a0, imm_size, allow_zero=allow_zero)
+ imm_a1 = check_imm_box(a1, imm_size, allow_zero=allow_zero)
if not imm_a0 and imm_a1:
- l0, box = self._ensure_value_is_boxed(a0)
- boxes.append(box)
+ l0 = self._ensure_value_is_boxed(a0)
l1 = self.make_sure_var_in_reg(a1, boxes)
elif commutative and imm_a0 and not imm_a1:
l1 = self.make_sure_var_in_reg(a0, boxes)
- l0, box = self._ensure_value_is_boxed(a1, boxes)
- boxes.append(box)
+ l0 = self._ensure_value_is_boxed(a1, boxes)
else:
- l0, box = self._ensure_value_is_boxed(a0, boxes)
- boxes.append(box)
- l1, box = self._ensure_value_is_boxed(a1, boxes)
- boxes.append(box)
- self.possibly_free_vars(boxes)
+ l0 = self._ensure_value_is_boxed(a0, boxes)
+ l1 = self._ensure_value_is_boxed(a1, boxes)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
res = self.force_allocate_reg(op.result, boxes)
- self.possibly_free_var(op.result)
return [l0, l1, res]
if name:
f.__name__ = name
@@ -48,36 +52,33 @@
if guard:
def f(self, op, guard_op, fcond):
locs = []
- loc1, box1 = self._ensure_value_is_boxed(op.getarg(0))
+ loc1 = self._ensure_value_is_boxed(op.getarg(0))
locs.append(loc1)
if base:
- loc2, box2 = self._ensure_value_is_boxed(op.getarg(1))
+ loc2 = self._ensure_value_is_boxed(op.getarg(1))
locs.append(loc2)
- self.possibly_free_var(box2)
- self.possibly_free_var(box1)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
if guard_op is None:
res = self.force_allocate_reg(op.result)
assert float_result == (op.result.type == FLOAT)
- self.possibly_free_var(op.result)
locs.append(res)
return locs
else:
args = self._prepare_guard(guard_op, locs)
- self.possibly_free_vars(guard_op.getfailargs())
return args
else:
def f(self, op, fcond):
locs = []
- loc1, box1 = self._ensure_value_is_boxed(op.getarg(0))
+ loc1 = self._ensure_value_is_boxed(op.getarg(0))
locs.append(loc1)
if base:
- loc2, box2 = self._ensure_value_is_boxed(op.getarg(1))
+ loc2 = self._ensure_value_is_boxed(op.getarg(1))
locs.append(loc2)
- self.possibly_free_var(box2)
- self.possibly_free_var(box1)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
res = self.force_allocate_reg(op.result)
assert float_result == (op.result.type == FLOAT)
- self.possibly_free_var(op.result)
locs.append(res)
return locs
if name:
@@ -108,23 +109,21 @@
assert fcond is not None
boxes = list(op.getarglist())
arg0, arg1 = boxes
- imm_a1 = _check_imm_arg(arg1)
+ imm_a1 = check_imm_box(arg1)
- l0, box = self._ensure_value_is_boxed(arg0, forbidden_vars=boxes)
- boxes.append(box)
+ l0 = self._ensure_value_is_boxed(arg0, forbidden_vars=boxes)
if imm_a1:
l1 = self.make_sure_var_in_reg(arg1, boxes)
else:
- l1, box = self._ensure_value_is_boxed(arg1, forbidden_vars=boxes)
- boxes.append(box)
- self.possibly_free_vars(boxes)
+ l1 = self._ensure_value_is_boxed(arg1, forbidden_vars=boxes)
+
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
if guard_op is None:
res = self.force_allocate_reg(op.result)
- self.possibly_free_var(op.result)
return [l0, l1, res]
else:
args = self._prepare_guard(guard_op, [l0, l1])
- self.possibly_free_vars(guard_op.getfailargs())
return args
if name:
f.__name__ = name
@@ -134,15 +133,14 @@
def f(self, op, guard_op, fcond):
assert fcond is not None
a0 = op.getarg(0)
- reg, box = self._ensure_value_is_boxed(a0)
+ assert isinstance(a0, Box)
+ reg = self.make_sure_var_in_reg(a0)
+ self.possibly_free_vars_for_op(op)
if guard_op is None:
- res = self.force_allocate_reg(op.result, [box])
- self.possibly_free_vars([a0, box, op.result])
+ res = self.force_allocate_reg(op.result, [a0])
return [reg, res]
else:
- args = self._prepare_guard(guard_op, [reg])
- self.possibly_free_vars(guard_op.getfailargs())
- return args
+ return self._prepare_guard(guard_op, [reg])
if name:
f.__name__ = name
return f
diff --git a/pypy/jit/backend/arm/instruction_builder.py b/pypy/jit/backend/arm/instruction_builder.py
--- a/pypy/jit/backend/arm/instruction_builder.py
+++ b/pypy/jit/backend/arm/instruction_builder.py
@@ -1,5 +1,7 @@
from pypy.jit.backend.arm import conditions as cond
from pypy.jit.backend.arm import instructions
+
+
# move table lookup out of generated functions
def define_load_store_func(name, table):
n = (0x1 << 26
@@ -13,6 +15,7 @@
rncond = ('rn' in table and table['rn'] == '!0xF')
if table['imm']:
assert not b_zero
+
def f(self, rt, rn, imm=0, cond=cond.AL):
assert not (rncond and rn == 0xF)
p = 1
@@ -20,7 +23,7 @@
u, imm = self._encode_imm(imm)
instr = (n
| cond << 28
- | (p & 0x1) << 24
+ | (p & 0x1) << 24
| (u & 0x1) << 23
| (w & 0x1) << 21
| imm_operation(rt, rn, imm))
@@ -34,7 +37,7 @@
u, imm = self._encode_imm(imm)
instr = (n
| cond << 28
- | (p & 0x1) << 24
+ | (p & 0x1) << 24
| (u & 0x1) << 23
| (w & 0x1) << 21
| reg_operation(rt, rn, rm, imm, s, shifttype))
@@ -44,6 +47,7 @@
self.write32(instr)
return f
+
def define_extra_load_store_func(name, table):
def check_registers(r1, r2):
assert r1 % 2 == 0
@@ -57,7 +61,7 @@
p = 1
w = 0
rncond = ('rn' in table and table['rn'] == '!0xF')
- dual = (name[-4] == 'D')
+ dual = (name[-4] == 'D')
if dual:
if name[-2:] == 'rr':
@@ -114,6 +118,7 @@
| (imm & 0xF))
return f
+
def define_data_proc_imm_func(name, table):
n = (0x1 << 25
| (table['op'] & 0x1F) << 20)
@@ -139,6 +144,7 @@
| imm_operation(0, rn, imm))
return imm_func
+
def define_data_proc_func(name, table):
n = ((table['op1'] & 0x1F) << 20
| (table['op2'] & 0x1F) << 7
@@ -175,6 +181,7 @@
| reg_operation(rd, rn, rm, imm, s, shifttype))
return f
+
def define_data_proc_reg_shift_reg_func(name, table):
n = ((0x1 << 4) | (table['op1'] & 0x1F) << 20 | (table['op2'] & 0x3) << 5)
if 'result' in table and not table['result']:
@@ -211,8 +218,10 @@
| (rn & 0xF))
return f
+
def define_supervisor_and_coproc_func(name, table):
n = (0x3 << 26 | (table['op1'] & 0x3F) << 20 | (table['op'] & 0x1) << 4)
+
def f(self, coproc, opc1, rt, crn, crm, opc2=0, cond=cond.AL):
self.write32(n
| cond << 28
@@ -224,6 +233,7 @@
| (crm & 0xF))
return f
+
def define_multiply_func(name, table):
n = (table['op'] & 0xF) << 20 | 0x9 << 4
if 'acc' in table and table['acc']:
@@ -246,14 +256,14 @@
| (rn & 0xF))
elif 'long' in table and table['long']:
- def f(self, rdlo, rdhi, rn, rm, cond=cond.AL):
+ def f(self, rdlo, rdhi, rn, rm, cond=cond.AL):
assert rdhi != rdlo
self.write32(n
- | cond << 28
- | (rdhi & 0xF) << 16
- | (rdlo & 0xF) << 12
- | (rm & 0xF) << 8
- | (rn & 0xF))
+ | cond << 28
+ | (rdhi & 0xF) << 16
+ | (rdlo & 0xF) << 12
+ | (rm & 0xF) << 8
+ | (rn & 0xF))
else:
def f(self, rd, rn, rm, cond=cond.AL, s=0):
self.write32(n
@@ -265,8 +275,10 @@
return f
+
def define_block_data_func(name, table):
n = (table['op'] & 0x3F) << 20
+
def f(self, rn, regs, w=0, cond=cond.AL):
# no R bit for now at bit 15
instr = (n
@@ -278,6 +290,8 @@
self.write32(instr)
return f
+
+
def define_float_load_store_func(name, table):
n = (0x3 << 26
| (table['opcode'] & 0x1F) << 20
@@ -288,9 +302,9 @@
# the value actually encoded is imm / 4
def f(self, dd, rn, imm=0, cond=cond.AL):
assert imm % 4 == 0
- imm = imm/4
+ imm = imm / 4
u, imm = self._encode_imm(imm)
- instr = ( n
+ instr = (n
| (cond & 0xF) << 28
| (u & 0x1) << 23
| (rn & 0xF) << 16
@@ -299,10 +313,11 @@
self.write32(instr)
return f
+
def define_float64_data_proc_instructions_func(name, table):
n = (0xE << 24
| 0x5 << 9
- | 0x1 << 8 # 64 bit flag
+ | 0x1 << 8 # 64 bit flag
| (table['opc3'] & 0x3) << 6)
if 'opc1' in table:
@@ -335,11 +350,13 @@
self.write32(instr)
return f
+
def imm_operation(rt, rn, imm):
return ((rn & 0xFF) << 16
| (rt & 0xFF) << 12
| (imm & 0xFFF))
+
def reg_operation(rt, rn, rm, imm, s, shifttype):
return ((s & 0x1) << 20
| (rn & 0xF) << 16
@@ -348,10 +365,12 @@
| (shifttype & 0x3) << 5
| (rm & 0xF))
+
def define_instruction(builder, key, val, target):
f = builder(key, val)
setattr(target, key, f)
+
def define_instructions(target):
inss = [k for k in instructions.__dict__.keys() if not k.startswith('__')]
for name in inss:
diff --git a/pypy/jit/backend/arm/instructions.py b/pypy/jit/backend/arm/instructions.py
--- a/pypy/jit/backend/arm/instructions.py
+++ b/pypy/jit/backend/arm/instructions.py
@@ -1,93 +1,94 @@
load_store = {
- 'STR_ri': {'A':0, 'op1': 0x0, 'op1not': 0x2, 'imm': True},
- 'STR_rr': {'A':1, 'op1': 0x0, 'op1not': 0x2, 'B': 0, 'imm': False},
- 'LDR_ri': {'A':0, 'op1': 0x1, 'op1not': 0x3, 'imm': True},
- 'LDR_rr': {'A':1, 'op1': 0x1, 'op1not': 0x3, 'B': 0, 'imm': False},
- 'STRB_ri': {'A':0, 'op1': 0x4, 'op1not': 0x6, 'rn':'!0xF', 'imm': True},
- 'STRB_rr': {'A':1, 'op1': 0x4, 'op1not': 0x6, 'B': 0, 'imm': False},
- 'LDRB_ri': {'A':0, 'op1': 0x5, 'op1not': 0x7, 'rn':'!0xF', 'imm': True},
- 'LDRB_rr': {'A':1, 'op1': 0x5, 'op1not': 0x7, 'B': 0, 'imm': False},
+ 'STR_ri': {'A': 0, 'op1': 0x0, 'op1not': 0x2, 'imm': True},
+ 'STR_rr': {'A': 1, 'op1': 0x0, 'op1not': 0x2, 'B': 0, 'imm': False},
+ 'LDR_ri': {'A': 0, 'op1': 0x1, 'op1not': 0x3, 'imm': True},
+ 'LDR_rr': {'A': 1, 'op1': 0x1, 'op1not': 0x3, 'B': 0, 'imm': False},
+ 'STRB_ri': {'A': 0, 'op1': 0x4, 'op1not': 0x6, 'rn': '!0xF', 'imm': True},
+ 'STRB_rr': {'A': 1, 'op1': 0x4, 'op1not': 0x6, 'B': 0, 'imm': False},
+ 'LDRB_ri': {'A': 0, 'op1': 0x5, 'op1not': 0x7, 'rn': '!0xF', 'imm': True},
+ 'LDRB_rr': {'A': 1, 'op1': 0x5, 'op1not': 0x7, 'B': 0, 'imm': False},
}
-extra_load_store = { #Section 5.2.8
+extra_load_store = { # Section 5.2.8
'STRH_rr': {'op2': 0x1, 'op1': 0x0},
'LDRH_rr': {'op2': 0x1, 'op1': 0x1},
'STRH_ri': {'op2': 0x1, 'op1': 0x4},
- 'LDRH_ri': {'op2': 0x1, 'op1': 0x5, 'rn':'!0xF'},
+ 'LDRH_ri': {'op2': 0x1, 'op1': 0x5, 'rn': '!0xF'},
'LDRD_rr': {'op2': 0x2, 'op1': 0x0},
'LDRSB_rr': {'op2': 0x2, 'op1': 0x1},
'LDRD_ri': {'op2': 0x2, 'op1': 0x4},
- 'LDRSB_ri': {'op2': 0x2, 'op1': 0x5, 'rn':'!0xF'},
+ 'LDRSB_ri': {'op2': 0x2, 'op1': 0x5, 'rn': '!0xF'},
'STRD_rr': {'op2': 0x3, 'op1': 0x0},
'LDRSH_rr': {'op2': 0x3, 'op1': 0x1},
'STRD_ri': {'op2': 0x3, 'op1': 0x4},
- 'LDRSH_ri': {'op2': 0x3, 'op1': 0x5, 'rn':'!0xF'},
+ 'LDRSH_ri': {'op2': 0x3, 'op1': 0x5, 'rn': '!0xF'},
}
data_proc = {
- 'AND_rr': {'op1':0x0, 'op2':0, 'op3':0, 'result':True, 'base':True},
- 'EOR_rr': {'op1':0x2, 'op2':0, 'op3':0, 'result':True, 'base':True},
- 'SUB_rr': {'op1':0x4, 'op2':0, 'op3':0, 'result':True, 'base':True},
- 'RSB_rr': {'op1':0x6, 'op2':0, 'op3':0, 'result':True, 'base':True},
- 'ADD_rr': {'op1':0x8, 'op2':0, 'op3':0, 'result':True, 'base':True},
- 'ADC_rr': {'op1':0xA, 'op2':0, 'op3':0, 'result':True, 'base':True},
- 'SBC_rr': {'op1':0xC, 'op2':0, 'op3':0, 'result':True, 'base':True},
- 'RSC_rr': {'op1':0xE, 'op2':0, 'op3':0, 'result':True, 'base':True},
- 'TST_rr': {'op1':0x11, 'op2':0, 'op3':0, 'result':False, 'base':True},
- 'TEQ_rr': {'op1':0x13, 'op2':0, 'op3':0, 'result':False, 'base':True},
- 'CMP_rr': {'op1':0x15, 'op2':0, 'op3':0, 'result':False, 'base':True},
- 'CMN_rr': {'op1':0x17, 'op2':0, 'op3':0, 'result':False, 'base':True},
- 'ORR_rr': {'op1':0x18, 'op2':0, 'op3':0, 'result':True, 'base':True},
- 'MOV_rr': {'op1':0x1A, 'op2':0, 'op3':0, 'result':True, 'base':False},
- 'LSL_ri': {'op1':0x1A, 'op2':0x0, 'op3':0, 'op2cond':'!0', 'result':False, 'base':True},
- 'LSR_ri': {'op1':0x1A, 'op2':0, 'op3':0x1, 'op2cond':'', 'result':False, 'base':True},
- 'ASR_ri': {'op1':0x1A, 'op2':0, 'op3':0x2, 'op2cond':'', 'result':False, 'base':True},
- #'RRX_ri': {'op1':0x1A, 'op2':0, 'op3':0x3, 'op2cond':'0', 'result':False, 'base':True},
- 'ROR_ri': {'op1':0x1A, 'op2':0x0, 'op3':0x3, 'op2cond':'!0', 'result':True, 'base':False},
- #BIC
- 'MVN_rr': {'op1':0x1E, 'op2':0x0, 'op3':0x0, 'result':True, 'base':False},
+ 'AND_rr': {'op1': 0x0, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+ 'EOR_rr': {'op1': 0x2, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+ 'SUB_rr': {'op1': 0x4, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+ 'RSB_rr': {'op1': 0x6, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+ 'ADD_rr': {'op1': 0x8, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+ 'ADC_rr': {'op1': 0xA, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+ 'SBC_rr': {'op1': 0xC, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+ 'RSC_rr': {'op1': 0xE, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+ 'TST_rr': {'op1': 0x11, 'op2': 0, 'op3': 0, 'result': False, 'base': True},
+ 'TEQ_rr': {'op1': 0x13, 'op2': 0, 'op3': 0, 'result': False, 'base': True},
+ 'CMP_rr': {'op1': 0x15, 'op2': 0, 'op3': 0, 'result': False, 'base': True},
+ 'CMN_rr': {'op1': 0x17, 'op2': 0, 'op3': 0, 'result': False, 'base': True},
+ 'ORR_rr': {'op1': 0x18, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+ 'MOV_rr': {'op1': 0x1A, 'op2': 0, 'op3': 0, 'result': True, 'base': False},
+ 'LSL_ri': {'op1': 0x1A, 'op2': 0x0, 'op3': 0, 'op2cond': '!0',
+ 'result': False, 'base': True},
+ 'LSR_ri': {'op1': 0x1A, 'op2': 0, 'op3': 0x1, 'op2cond': '',
+ 'result': False, 'base': True},
+ 'ASR_ri': {'op1': 0x1A, 'op2': 0, 'op3': 0x2, 'op2cond': '',
+ 'result': False, 'base': True},
+ 'ROR_ri': {'op1': 0x1A, 'op2': 0x0, 'op3': 0x3, 'op2cond': '!0',
+ 'result': True, 'base': False},
+ 'MVN_rr': {'op1': 0x1E, 'op2': 0x0, 'op3': 0x0, 'result': True,
+ 'base': False},
}
data_proc_reg_shift_reg = {
- 'AND_rr_sr': {'op1':0x0, 'op2':0},
- 'EOR_rr_sr': {'op1':0x2, 'op2':0},
- 'SUB_rr_sr': {'op1':0x4, 'op2':0},
- 'RSB_rr_sr': {'op1':0x6, 'op2':0},
- 'ADD_rr_sr': {'op1':0x8, 'op2':0},
- 'ADC_rr_sr': {'op1':0xA, 'op2':0},
- 'SBC_rr_sr': {'op1':0xC, 'op2':0},
- 'RSC_rr_sr': {'op1':0xE, 'op2':0},
- 'TST_rr_sr': {'op1':0x11, 'op2':0, 'result': False},
- 'TEQ_rr_sr': {'op1':0x13, 'op2':0, 'result': False},
- 'CMP_rr_sr': {'op1':0x15, 'op2':0, 'result': False},
- 'CMN_rr_sr': {'op1':0x17, 'op2':0, 'result': False},
- 'ORR_rr_sr': {'op1':0x18, 'op2':0},
- 'LSL_rr': {'op1':0x1A, 'op2':0, },
- 'LSR_rr': {'op1':0x1A, 'op2':0x1},
- 'ASR_rr': {'op1':0x1A, 'op2':0x2},
- #'RRX_rr': {'op1':0x1A, 'op2':0,},
- 'ROR_rr': {'op1':0x1A, 'op2':0x3},
- # BIC, MVN
+ 'AND_rr_sr': {'op1': 0x0, 'op2': 0},
+ 'EOR_rr_sr': {'op1': 0x2, 'op2': 0},
+ 'SUB_rr_sr': {'op1': 0x4, 'op2': 0},
+ 'RSB_rr_sr': {'op1': 0x6, 'op2': 0},
+ 'ADD_rr_sr': {'op1': 0x8, 'op2': 0},
+ 'ADC_rr_sr': {'op1': 0xA, 'op2': 0},
+ 'SBC_rr_sr': {'op1': 0xC, 'op2': 0},
+ 'RSC_rr_sr': {'op1': 0xE, 'op2': 0},
+ 'TST_rr_sr': {'op1': 0x11, 'op2': 0, 'result': False},
+ 'TEQ_rr_sr': {'op1': 0x13, 'op2': 0, 'result': False},
+ 'CMP_rr_sr': {'op1': 0x15, 'op2': 0, 'result': False},
+ 'CMN_rr_sr': {'op1': 0x17, 'op2': 0, 'result': False},
+ 'ORR_rr_sr': {'op1': 0x18, 'op2': 0},
+ 'LSL_rr': {'op1': 0x1A, 'op2': 0, },
+ 'LSR_rr': {'op1': 0x1A, 'op2': 0x1},
+ 'ASR_rr': {'op1': 0x1A, 'op2': 0x2},
+ 'ROR_rr': {'op1': 0x1A, 'op2': 0x3},
}
data_proc_imm = {
- 'AND_ri': {'op': 0, 'result':True, 'base':True},
- 'EOR_ri': {'op': 0x2, 'result':True, 'base':True},
- 'SUB_ri': {'op': 0x4, 'result':True, 'base':True},
- 'RSB_ri': {'op': 0x6, 'result':True, 'base':True},
- 'ADD_ri': {'op': 0x8, 'result':True, 'base':True},
- 'ADC_ri': {'op': 0xA, 'result':True, 'base':True},
- 'SBC_ri': {'op': 0xC, 'result':True, 'base':True},
- 'RSC_ri': {'op': 0xE, 'result':True, 'base':True},
- 'TST_ri': {'op': 0x11, 'result':False, 'base':True},
- 'TEQ_ri': {'op': 0x13, 'result':False, 'base':True},
- 'CMP_ri': {'op': 0x15, 'result':False, 'base':True},
- 'CMN_ri': {'op': 0x17, 'result':False, 'base':True},
- 'ORR_ri': {'op': 0x18, 'result':True, 'base':True},
- 'MOV_ri': {'op': 0x1A, 'result':True, 'base':False},
- 'BIC_ri': {'op': 0x1C, 'result':True, 'base':True},
- 'MVN_ri': {'op': 0x1E, 'result':True, 'base':False},
+ 'AND_ri': {'op': 0, 'result': True, 'base': True},
+ 'EOR_ri': {'op': 0x2, 'result': True, 'base': True},
+ 'SUB_ri': {'op': 0x4, 'result': True, 'base': True},
+ 'RSB_ri': {'op': 0x6, 'result': True, 'base': True},
+ 'ADD_ri': {'op': 0x8, 'result': True, 'base': True},
+ 'ADC_ri': {'op': 0xA, 'result': True, 'base': True},
+ 'SBC_ri': {'op': 0xC, 'result': True, 'base': True},
+ 'RSC_ri': {'op': 0xE, 'result': True, 'base': True},
+ 'TST_ri': {'op': 0x11, 'result': False, 'base': True},
+ 'TEQ_ri': {'op': 0x13, 'result': False, 'base': True},
+ 'CMP_ri': {'op': 0x15, 'result': False, 'base': True},
+ 'CMN_ri': {'op': 0x17, 'result': False, 'base': True},
+ 'ORR_ri': {'op': 0x18, 'result': True, 'base': True},
+ 'MOV_ri': {'op': 0x1A, 'result': True, 'base': False},
+ 'BIC_ri': {'op': 0x1C, 'result': True, 'base': True},
+ 'MVN_ri': {'op': 0x1E, 'result': True, 'base': False},
}
supervisor_and_coproc = {
diff --git a/pypy/jit/backend/arm/jump.py b/pypy/jit/backend/arm/jump.py
--- a/pypy/jit/backend/arm/jump.py
+++ b/pypy/jit/backend/arm/jump.py
@@ -1,7 +1,6 @@
# ../x86/jump.py
# XXX combine with ../x86/jump.py and move to llsupport
-import sys
-from pypy.tool.pairtype import extendabletype
+
def remap_frame_layout(assembler, src_locations, dst_locations, tmpreg):
pending_dests = len(dst_locations)
@@ -18,7 +17,10 @@
key = src.as_key()
if key in srccount:
if key == dst_locations[i].as_key():
- srccount[key] = -sys.maxint # ignore a move "x = x"
+ # ignore a move "x = x"
+ # setting any "large enough" negative value is ok, but
+ # be careful of overflows, don't use -sys.maxint
+ srccount[key] = -len(dst_locations) - 1
pending_dests -= 1
else:
srccount[key] += 1
@@ -65,12 +67,14 @@
assembler.regalloc_pop(dst)
assert pending_dests == 0
+
def _move(assembler, src, dst, tmpreg):
if dst.is_stack() and src.is_stack():
assembler.regalloc_mov(src, tmpreg)
src = tmpreg
assembler.regalloc_mov(src, dst)
+
def remap_frame_layout_mixed(assembler,
src_locations1, dst_locations1, tmpreg1,
src_locations2, dst_locations2, tmpreg2):
@@ -84,7 +88,7 @@
src_locations2red = []
dst_locations2red = []
for i in range(len(src_locations2)):
- loc = src_locations2[i]
+ loc = src_locations2[i]
dstloc = dst_locations2[i]
if loc.is_stack():
key = loc.as_key()
diff --git a/pypy/jit/backend/arm/locations.py b/pypy/jit/backend/arm/locations.py
--- a/pypy/jit/backend/arm/locations.py
+++ b/pypy/jit/backend/arm/locations.py
@@ -1,5 +1,7 @@
-from pypy.jit.metainterp.history import INT, FLOAT, REF
+from pypy.jit.metainterp.history import INT, FLOAT
from pypy.jit.backend.arm.arch import WORD
+
+
class AssemblerLocation(object):
_immutable_ = True
type = INT
@@ -22,6 +24,7 @@
def as_key(self):
raise NotImplementedError
+
class RegisterLocation(AssemblerLocation):
_immutable_ = True
width = WORD
@@ -38,13 +41,15 @@
def as_key(self):
return self.value
+
class VFPRegisterLocation(RegisterLocation):
_immutable_ = True
- type = FLOAT
- width = 2*WORD
+ type = FLOAT
+ width = 2 * WORD
def get_single_precision_regs(self):
- return [VFPRegisterLocation(i) for i in [self.value*2, self.value*2+1]]
+ return [VFPRegisterLocation(i) for i in
+ [self.value * 2, self.value * 2 + 1]]
def __repr__(self):
return 'vfp%d' % self.value
@@ -58,11 +63,11 @@
def as_key(self):
return self.value + 20
+
class ImmLocation(AssemblerLocation):
_immutable_ = True
width = WORD
-
def __init__(self, value):
self.value = value
@@ -78,11 +83,12 @@
def as_key(self):
return self.value + 40
+
class ConstFloatLoc(AssemblerLocation):
"""This class represents an imm float value which is stored in memory at
the address stored in the field value"""
_immutable_ = True
- width = 2*WORD
+ width = 2 * WORD
type = FLOAT
def __init__(self, value):
@@ -100,6 +106,7 @@
def as_key(self):
return -1 * self.value
+
class StackLocation(AssemblerLocation):
_immutable_ = True
@@ -123,5 +130,6 @@
def as_key(self):
return -self.position
+
def imm(i):
return ImmLocation(i)
diff --git a/pypy/jit/backend/arm/opassembler.py b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -1,51 +1,48 @@
from __future__ import with_statement
from pypy.jit.backend.arm import conditions as c
-from pypy.jit.backend.arm import locations
from pypy.jit.backend.arm import registers as r
from pypy.jit.backend.arm import shift
-from pypy.jit.backend.arm.arch import (WORD, FUNC_ALIGN, arm_int_div,
- arm_int_div_sign, arm_int_mod_sign,
- arm_int_mod, PC_OFFSET)
+from pypy.jit.backend.arm.arch import WORD, PC_OFFSET
from pypy.jit.backend.arm.helper.assembler import (gen_emit_op_by_helper_call,
- gen_emit_op_unary_cmp,
- gen_emit_guard_unary_cmp,
- gen_emit_op_ri,
- gen_emit_cmp_op,
- gen_emit_cmp_op_guard,
- gen_emit_float_op,
- gen_emit_float_cmp_op,
- gen_emit_float_cmp_op_guard,
- gen_emit_unary_float_op,
- saved_registers,
- count_reg_args)
+ gen_emit_op_unary_cmp,
+ gen_emit_guard_unary_cmp,
+ gen_emit_op_ri,
+ gen_emit_cmp_op,
+ gen_emit_cmp_op_guard,
+ gen_emit_float_op,
+ gen_emit_float_cmp_op,
+ gen_emit_float_cmp_op_guard,
+ gen_emit_unary_float_op,
+ saved_registers,
+ count_reg_args)
from pypy.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder
from pypy.jit.backend.arm.jump import remap_frame_layout
-from pypy.jit.backend.arm.regalloc import Regalloc, TempInt, TempPtr
+from pypy.jit.backend.arm.regalloc import TempInt, TempPtr
from pypy.jit.backend.arm.locations import imm
from pypy.jit.backend.llsupport import symbolic
-from pypy.jit.backend.llsupport.descr import BaseFieldDescr, BaseArrayDescr
-from pypy.jit.backend.llsupport.regalloc import compute_vars_longevity
-from pypy.jit.metainterp.history import (Const, ConstInt, BoxInt, Box,
- AbstractFailDescr, LoopToken, INT, FLOAT, REF)
+from pypy.jit.metainterp.history import (Box, AbstractFailDescr,
+ INT, FLOAT, REF)
+from pypy.jit.metainterp.history import JitCellToken, TargetToken
from pypy.jit.metainterp.resoperation import rop
-from pypy.rlib import rgc
from pypy.rlib.objectmodel import we_are_translated
-from pypy.rpython.annlowlevel import llhelper
-from pypy.rpython.lltypesystem import lltype, rffi, rstr, llmemory
+from pypy.rpython.lltypesystem import lltype, rffi, rstr
NO_FORCE_INDEX = -1
+
class GuardToken(object):
- def __init__(self, descr, failargs, faillocs, offset, fcond=c.AL,
- save_exc=False, is_invalidate=False):
+ def __init__(self, descr, failargs, faillocs, offset,
+ save_exc, fcond=c.AL, is_invalidate=False):
+ assert isinstance(save_exc, bool)
self.descr = descr
self.offset = offset
self.is_invalidate = is_invalidate
self.failargs = failargs
self.faillocs = faillocs
self.save_exc = save_exc
- self.fcond=fcond
+ self.fcond = fcond
+
class IntOpAsslember(object):
@@ -95,15 +92,17 @@
def emit_guard_int_mul_ovf(self, op, guard, arglocs, regalloc, fcond):
reg1 = arglocs[0]
reg2 = arglocs[1]
- res = arglocs[2]
+ res = arglocs[2]
failargs = arglocs[3:]
- self.mc.SMULL(res.value, r.ip.value, reg1.value, reg2.value, cond=fcond)
- self.mc.CMP_rr(r.ip.value, res.value, shifttype=shift.ASR, imm=31, cond=fcond)
+ self.mc.SMULL(res.value, r.ip.value, reg1.value, reg2.value,
+ cond=fcond)
+ self.mc.CMP_rr(r.ip.value, res.value, shifttype=shift.ASR,
+ imm=31, cond=fcond)
if guard.getopnum() == rop.GUARD_OVERFLOW:
- fcond = self._emit_guard(guard, failargs, c.NE)
+ fcond = self._emit_guard(guard, failargs, c.NE, save_exc=False)
elif guard.getopnum() == rop.GUARD_NO_OVERFLOW:
- fcond = self._emit_guard(guard, failargs, c.EQ)
+ fcond = self._emit_guard(guard, failargs, c.EQ, save_exc=False)
else:
assert 0
return fcond
@@ -112,7 +111,7 @@
self.emit_op_int_add(op, arglocs[0:3], regalloc, fcond, flags=True)
self._emit_guard_overflow(guard, arglocs[3:], fcond)
return fcond
-
+
def emit_guard_int_sub_ovf(self, op, guard, arglocs, regalloc, fcond):
self.emit_op_int_sub(op, arglocs[0:3], regalloc, fcond, flags=True)
self._emit_guard_overflow(guard, arglocs[3:], fcond)
@@ -136,8 +135,6 @@
emit_op_int_gt = gen_emit_cmp_op('int_gt', c.GT)
emit_op_int_ge = gen_emit_cmp_op('int_ge', c.GE)
-
-
emit_guard_int_lt = gen_emit_cmp_op_guard('int_lt', c.LT)
emit_guard_int_le = gen_emit_cmp_op_guard('int_le', c.LE)
emit_guard_int_eq = gen_emit_cmp_op_guard('int_eq', c.EQ)
@@ -155,16 +152,15 @@
emit_guard_uint_lt = gen_emit_cmp_op_guard('uint_lt', c.LO)
emit_guard_uint_ge = gen_emit_cmp_op_guard('uint_ge', c.HS)
- emit_op_ptr_eq = emit_op_int_eq
- emit_op_ptr_ne = emit_op_int_ne
- emit_guard_ptr_eq = emit_guard_int_eq
- emit_guard_ptr_ne = emit_guard_int_ne
+ emit_op_ptr_eq = emit_op_instance_ptr_eq = emit_op_int_eq
+ emit_op_ptr_ne = emit_op_instance_ptr_ne = emit_op_int_ne
+ emit_guard_ptr_eq = emit_guard_instance_ptr_eq = emit_guard_int_eq
+ emit_guard_ptr_ne = emit_guard_instance_ptr_ne = emit_guard_int_ne
emit_op_int_add_ovf = emit_op_int_add
emit_op_int_sub_ovf = emit_op_int_sub
-
class UnaryIntOpAssembler(object):
_mixin_ = True
@@ -186,34 +182,44 @@
self.mc.RSB_ri(resloc.value, l0.value, imm=0)
return fcond
+
class GuardOpAssembler(object):
_mixin_ = True
- def _emit_guard(self, op, arglocs, fcond, save_exc=False, is_guard_not_ivalidated=False):
+ def _emit_guard(self, op, arglocs, fcond, save_exc,
+ is_guard_not_invalidated=False):
+ assert isinstance(save_exc, bool)
+ assert isinstance(fcond, int)
descr = op.getdescr()
assert isinstance(descr, AbstractFailDescr)
-
if not we_are_translated() and hasattr(op, 'getfailargs'):
- print 'Failargs: ', op.getfailargs()
+ print 'Failargs: ', op.getfailargs()
pos = self.mc.currpos()
- self.mc.NOP()
+ # For all guards that are not GUARD_NOT_INVALIDATED we emit a
+ # breakpoint to ensure the location is patched correctly. In the case
+ # of GUARD_NOT_INVALIDATED we use just a NOP, because it is only
+ # eventually patched at a later point.
+ if is_guard_not_invalidated:
+ self.mc.NOP()
+ else:
+ self.mc.BKPT()
self.pending_guards.append(GuardToken(descr,
failargs=op.getfailargs(),
faillocs=arglocs,
offset=pos,
- fcond=fcond,
- is_invalidate=is_guard_not_ivalidated,
- save_exc=save_exc))
+ save_exc=save_exc,
+ is_invalidate=is_guard_not_invalidated,
+ fcond=fcond))
return c.AL
def _emit_guard_overflow(self, guard, failargs, fcond):
if guard.getopnum() == rop.GUARD_OVERFLOW:
- fcond = self._emit_guard(guard, failargs, c.VS)
+ fcond = self._emit_guard(guard, failargs, c.VS, save_exc=False)
elif guard.getopnum() == rop.GUARD_NO_OVERFLOW:
- fcond = self._emit_guard(guard, failargs, c.VC)
+ fcond = self._emit_guard(guard, failargs, c.VC, save_exc=False)
else:
assert 0
return fcond
@@ -222,14 +228,14 @@
l0 = arglocs[0]
failargs = arglocs[1:]
self.mc.CMP_ri(l0.value, 0)
- fcond = self._emit_guard(op, failargs, c.NE)
+ fcond = self._emit_guard(op, failargs, c.NE, save_exc=False)
return fcond
def emit_op_guard_false(self, op, arglocs, regalloc, fcond):
l0 = arglocs[0]
failargs = arglocs[1:]
self.mc.CMP_ri(l0.value, 0)
- fcond = self._emit_guard(op, failargs, c.EQ)
+ fcond = self._emit_guard(op, failargs, c.EQ, save_exc=False)
return fcond
def emit_op_guard_value(self, op, arglocs, regalloc, fcond):
@@ -246,17 +252,17 @@
assert l1.is_vfp_reg()
self.mc.VCMP(l0.value, l1.value)
self.mc.VMRS(cond=fcond)
- fcond = self._emit_guard(op, failargs, c.EQ)
+ fcond = self._emit_guard(op, failargs, c.EQ, save_exc=False)
return fcond
emit_op_guard_nonnull = emit_op_guard_true
emit_op_guard_isnull = emit_op_guard_false
def emit_op_guard_no_overflow(self, op, arglocs, regalloc, fcond):
- return self._emit_guard(op, arglocs, c.VC)
+ return self._emit_guard(op, arglocs, c.VC, save_exc=False)
def emit_op_guard_overflow(self, op, arglocs, regalloc, fcond):
- return self._emit_guard(op, arglocs, c.VS)
+ return self._emit_guard(op, arglocs, c.VS, save_exc=False)
# from ../x86/assembler.py:1265
def emit_op_guard_class(self, op, arglocs, regalloc, fcond):
@@ -268,14 +274,15 @@
self.mc.CMP_ri(arglocs[0].value, 0)
if offset is not None:
- self._emit_guard(op, arglocs[3:], c.NE)
+ self._emit_guard(op, arglocs[3:], c.NE, save_exc=False)
else:
raise NotImplementedError
self._cmp_guard_class(op, arglocs, regalloc, fcond)
return fcond
def emit_op_guard_not_invalidated(self, op, locs, regalloc, fcond):
- return self._emit_guard(op, locs, fcond, is_guard_not_ivalidated=True)
+ return self._emit_guard(op, locs, fcond, save_exc=False,
+ is_guard_not_invalidated=True)
def _cmp_guard_class(self, op, locs, regalloc, fcond):
offset = locs[2]
@@ -290,7 +297,7 @@
raise NotImplementedError
# XXX port from x86 backend once gc support is in place
- return self._emit_guard(op, locs[3:], c.EQ)
+ return self._emit_guard(op, locs[3:], c.EQ, save_exc=False)
class OpAssembler(object):
@@ -298,37 +305,86 @@
_mixin_ = True
def emit_op_jump(self, op, arglocs, regalloc, fcond):
+ # The backend's logic assumes that the target code is in a piece of
+ # assembler that was also called with the same number of arguments,
+ # so that the locations [ebp+8..] of the input arguments are valid
+ # stack locations both before and after the jump.
+ #
descr = op.getdescr()
- assert isinstance(descr, LoopToken)
+ assert isinstance(descr, TargetToken)
assert fcond == c.AL
+ my_nbargs = self.current_clt._debug_nbargs
+ target_nbargs = descr._arm_clt._debug_nbargs
+ assert my_nbargs == target_nbargs
self._insert_checks()
- if descr._arm_bootstrap_code == 0:
+ if descr in self.target_tokens_currently_compiling:
self.mc.B_offs(descr._arm_loop_code, fcond)
else:
- target = descr._arm_bootstrap_code + descr._arm_loop_code
- self.mc.B(target, fcond)
- new_fd = max(regalloc.frame_manager.frame_depth, descr._arm_frame_depth)
- regalloc.frame_manager.frame_depth = new_fd
+ self.mc.B(descr._arm_loop_code, fcond)
return fcond
def emit_op_finish(self, op, arglocs, regalloc, fcond):
- self._gen_path_to_exit_path(op.getdescr(), op.getarglist(), arglocs, c.AL)
+ for i in range(len(arglocs) - 1):
+ loc = arglocs[i]
+ box = op.getarg(i)
+ if loc is None:
+ continue
+ if loc.is_reg():
+ if box.type == REF:
+ adr = self.fail_boxes_ptr.get_addr_for_num(i)
+ elif box.type == INT:
+ adr = self.fail_boxes_int.get_addr_for_num(i)
+ else:
+ assert 0
+ self.mc.gen_load_int(r.ip.value, adr)
+ self.mc.STR_ri(loc.value, r.ip.value)
+ elif loc.is_vfp_reg():
+ assert box.type == FLOAT
+ adr = self.fail_boxes_float.get_addr_for_num(i)
+ self.mc.gen_load_int(r.ip.value, adr)
+ self.mc.VSTR(loc.value, r.ip.value)
+ elif loc.is_stack() or loc.is_imm() or loc.is_imm_float():
+ if box.type == FLOAT:
+ adr = self.fail_boxes_float.get_addr_for_num(i)
+ self.mov_loc_loc(loc, r.vfp_ip)
+ self.mc.gen_load_int(r.ip.value, adr)
+ self.mc.VSTR(r.vfp_ip.value, r.ip.value)
+ elif box.type == REF or box.type == INT:
+ if box.type == REF:
+ adr = self.fail_boxes_ptr.get_addr_for_num(i)
+ elif box.type == INT:
+ adr = self.fail_boxes_int.get_addr_for_num(i)
+ else:
+ assert 0
+ self.mov_loc_loc(loc, r.ip)
+ self.mc.gen_load_int(r.lr.value, adr)
+ self.mc.STR_ri(r.ip.value, r.lr.value)
+ else:
+ assert 0
+ # 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 arglocs[0]).
+ addr = self.cpu.get_on_leave_jitted_int(save_exception=False)
+ self.mc.BL(addr)
+ self.mc.gen_load_int(r.r0.value, arglocs[-1].value)
+ self.gen_func_epilog()
return fcond
- def emit_op_call(self, op, args, regalloc, fcond, force_index=-1):
+ def emit_op_call(self, op, args, regalloc, fcond,
+ force_index=NO_FORCE_INDEX):
adr = args[0].value
arglist = op.getarglist()[1:]
- if force_index == -1:
+ if force_index == NO_FORCE_INDEX:
force_index = self.write_new_force_index()
- cond = self._emit_call(force_index, adr, arglist,
+ cond = self._emit_call(force_index, adr, arglist,
regalloc, fcond, op.result)
descr = op.getdescr()
#XXX Hack, Hack, Hack
- if op.result and not we_are_translated() and not isinstance(descr, LoopToken):
+ if (op.result and not we_are_translated()):
#XXX check result type
loc = regalloc.rm.call_result_location(op.result)
- size = descr.get_result_size(False)
+ size = descr.get_result_size()
signed = descr.is_result_signed()
self._ensure_result_bit_extension(loc, size, signed)
return cond
@@ -336,11 +392,12 @@
# XXX improve this interface
# emit_op_call_may_force
# XXX improve freeing of stuff here
- def _emit_call(self, force_index, adr, args, regalloc, fcond=c.AL, result=None):
+ # XXX add an interface that takes locations instead of boxes
+ def _emit_call(self, force_index, adr, args, regalloc, fcond=c.AL,
+ result=None):
n_args = len(args)
reg_args = count_reg_args(args)
-
# all arguments past the 4th go on the stack
n = 0 # used to count the number of words pushed on the stack, so we
#can later modify the SP back to its original value
@@ -365,15 +422,15 @@
stack_args.append(None)
#then we push every thing on the stack
- for i in range(len(stack_args) -1, -1, -1):
+ for i in range(len(stack_args) - 1, -1, -1):
arg = stack_args[i]
if arg is None:
self.mc.PUSH([r.ip.value])
else:
self.regalloc_push(regalloc.loc(arg))
- # collect variables that need to go in registers
- # and the registers they will be stored in
+ # collect variables that need to go in registers and the registers they
+ # will be stored in
num = 0
count = 0
non_float_locs = []
@@ -405,7 +462,7 @@
remap_frame_layout(self, non_float_locs, non_float_regs, r.ip)
for loc, reg in float_locs:
- self.mov_from_vfp_loc(loc, reg, r.all_regs[reg.value+1])
+ self.mov_from_vfp_loc(loc, reg, r.all_regs[reg.value + 1])
#the actual call
self.mc.BL(adr)
@@ -448,7 +505,7 @@
self.mc.CMP_rr(r.ip.value, loc.value)
self._emit_guard(op, failargs, c.EQ, save_exc=True)
- self.mc.gen_load_int(loc.value, pos_exc_value.value, fcond)
+ self.mc.gen_load_int(loc.value, pos_exc_value.value)
if resloc:
self.mc.LDR_ri(resloc.value, loc.value)
self.mc.MOV_ri(r.ip.value, 0)
@@ -494,7 +551,7 @@
self.mc.TST_ri(r.ip.value, imm=ofs)
jz_location = self.mc.currpos()
- self.mc.NOP()
+ self.mc.BKPT()
# the following is supposed to be the slow path, so whenever possible
# we choose the most compact encoding over the most efficient one.
@@ -505,9 +562,8 @@
callargs = [r.r0, r.r1, r.r2]
remap_frame_layout(self, arglocs, callargs, r.ip)
func = rffi.cast(lltype.Signed, addr)
- #
- # misaligned stack in the call, but it's ok because the write barrier
- # is not going to call anything more.
+ # misaligned stack in the call, but it's ok because the write
+ # barrier is not going to call anything more.
self.mc.BL(func)
# patch the JZ above
@@ -518,6 +574,7 @@
emit_op_cond_call_gc_wb_array = emit_op_cond_call_gc_wb
+
class FieldOpAssembler(object):
_mixin_ = True
@@ -600,7 +657,8 @@
emit_op_getfield_gc_pure = emit_op_getfield_gc
def emit_op_getinteriorfield_gc(self, op, arglocs, regalloc, fcond):
- base_loc, index_loc, res_loc, ofs_loc, ofs, itemsize, fieldsize = arglocs
+ (base_loc, index_loc, res_loc,
+ ofs_loc, ofs, itemsize, fieldsize) = arglocs
self.mc.gen_load_int(r.ip.value, itemsize.value)
self.mc.MUL(r.ip.value, index_loc.value, r.ip.value)
if ofs.value > 0:
@@ -632,7 +690,8 @@
return fcond
def emit_op_setinteriorfield_gc(self, op, arglocs, regalloc, fcond):
- base_loc, index_loc, value_loc, ofs_loc, ofs, itemsize, fieldsize = arglocs
+ (base_loc, index_loc, value_loc,
+ ofs_loc, ofs, itemsize, fieldsize) = arglocs
self.mc.gen_load_int(r.ip.value, itemsize.value)
self.mc.MUL(r.ip.value, index_loc.value, r.ip.value)
if ofs.value > 0:
@@ -658,8 +717,6 @@
return fcond
-
-
class ArrayOpAssember(object):
_mixin_ = True
@@ -678,7 +735,7 @@
else:
scale_loc = ofs_loc
- # add the base offset
+ # add the base offset
if ofs.value > 0:
self.mc.ADD_ri(r.ip.value, scale_loc.value, imm=ofs.value)
scale_loc = r.ip
@@ -689,11 +746,14 @@
self.mc.ADD_rr(r.ip.value, base_loc.value, scale_loc.value)
self.mc.VSTR(value_loc.value, r.ip.value, cond=fcond)
elif scale.value == 2:
- self.mc.STR_rr(value_loc.value, base_loc.value, scale_loc.value, cond=fcond)
+ self.mc.STR_rr(value_loc.value, base_loc.value, scale_loc.value,
+ cond=fcond)
elif scale.value == 1:
- self.mc.STRH_rr(value_loc.value, base_loc.value, scale_loc.value, cond=fcond)
+ self.mc.STRH_rr(value_loc.value, base_loc.value, scale_loc.value,
+ cond=fcond)
elif scale.value == 0:
- self.mc.STRB_rr(value_loc.value, base_loc.value, scale_loc.value, cond=fcond)
+ self.mc.STRB_rr(value_loc.value, base_loc.value, scale_loc.value,
+ cond=fcond)
else:
assert 0
return fcond
@@ -709,7 +769,7 @@
else:
scale_loc = ofs_loc
- # add the base offset
+ # add the base offset
if ofs.value > 0:
self.mc.ADD_ri(r.ip.value, scale_loc.value, imm=ofs.value)
scale_loc = r.ip
@@ -720,18 +780,21 @@
self.mc.ADD_rr(r.ip.value, base_loc.value, scale_loc.value)
self.mc.VLDR(res.value, r.ip.value, cond=fcond)
elif scale.value == 2:
- self.mc.LDR_rr(res.value, base_loc.value, scale_loc.value, cond=fcond)
+ self.mc.LDR_rr(res.value, base_loc.value, scale_loc.value,
+ cond=fcond)
elif scale.value == 1:
- self.mc.LDRH_rr(res.value, base_loc.value, scale_loc.value, cond=fcond)
+ self.mc.LDRH_rr(res.value, base_loc.value, scale_loc.value,
+ cond=fcond)
elif scale.value == 0:
- self.mc.LDRB_rr(res.value, base_loc.value, scale_loc.value, cond=fcond)
+ self.mc.LDRB_rr(res.value, base_loc.value, scale_loc.value,
+ cond=fcond)
else:
assert 0
#XXX Hack, Hack, Hack
if not we_are_translated():
descr = op.getdescr()
- size = descr.get_item_size(False)
+ size = descr.itemsize
signed = descr.is_item_signed()
self._ensure_result_bit_extension(res, size, signed)
return fcond
@@ -755,9 +818,11 @@
def emit_op_strgetitem(self, op, arglocs, regalloc, fcond):
res, base_loc, ofs_loc, basesize = arglocs
if ofs_loc.is_imm():
- self.mc.ADD_ri(r.ip.value, base_loc.value, ofs_loc.getint(), cond=fcond)
+ self.mc.ADD_ri(r.ip.value, base_loc.value, ofs_loc.getint(),
+ cond=fcond)
else:
- self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value, cond=fcond)
+ self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value,
+ cond=fcond)
self.mc.LDRB_ri(res.value, r.ip.value, basesize.value, cond=fcond)
return fcond
@@ -765,11 +830,14 @@
def emit_op_strsetitem(self, op, arglocs, regalloc, fcond):
value_loc, base_loc, ofs_loc, basesize = arglocs
if ofs_loc.is_imm():
- self.mc.ADD_ri(r.ip.value, base_loc.value, ofs_loc.getint(), cond=fcond)
+ self.mc.ADD_ri(r.ip.value, base_loc.value, ofs_loc.getint(),
+ cond=fcond)
else:
- self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value, cond=fcond)
+ self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value,
+ cond=fcond)
- self.mc.STRB_ri(value_loc.value, r.ip.value, basesize.value, cond=fcond)
+ self.mc.STRB_ri(value_loc.value, r.ip.value, basesize.value,
+ cond=fcond)
return fcond
#from ../x86/regalloc.py:928 ff.
@@ -785,71 +853,78 @@
def _emit_copystrcontent(self, op, regalloc, fcond, is_unicode):
# compute the source address
- args = list(op.getarglist())
- base_loc, box = regalloc._ensure_value_is_boxed(args[0], args)
- args.append(box)
- ofs_loc, box = regalloc._ensure_value_is_boxed(args[2], args)
- args.append(box)
+ args = op.getarglist()
+ base_loc = regalloc._ensure_value_is_boxed(args[0], args)
+ ofs_loc = regalloc._ensure_value_is_boxed(args[2], args)
assert args[0] is not args[1] # forbidden case of aliasing
regalloc.possibly_free_var(args[0])
+ regalloc.free_temp_vars()
if args[3] is not args[2] is not args[4]: # MESS MESS MESS: don't free
- regalloc.possibly_free_var(args[2]) # it if ==args[3] or args[4]
+ regalloc.possibly_free_var(args[2]) # it if ==args[3] or args[4]
+ regalloc.free_temp_vars()
srcaddr_box = TempPtr()
forbidden_vars = [args[1], args[3], args[4], srcaddr_box]
- srcaddr_loc = regalloc.force_allocate_reg(srcaddr_box, selected_reg=r.r1)
+ srcaddr_loc = regalloc.force_allocate_reg(srcaddr_box,
+ selected_reg=r.r1)
self._gen_address_inside_string(base_loc, ofs_loc, srcaddr_loc,
is_unicode=is_unicode)
# compute the destination address
forbidden_vars = [args[4], args[3], srcaddr_box]
dstaddr_box = TempPtr()
- dstaddr_loc = regalloc.force_allocate_reg(dstaddr_box, selected_reg=r.r0)
+ dstaddr_loc = regalloc.force_allocate_reg(dstaddr_box,
+ selected_reg=r.r0)
forbidden_vars.append(dstaddr_box)
- base_loc, box = regalloc._ensure_value_is_boxed(args[1], forbidden_vars)
- args.append(box)
- forbidden_vars.append(box)
- ofs_loc, box = regalloc._ensure_value_is_boxed(args[3], forbidden_vars)
- args.append(box)
+ base_loc = regalloc._ensure_value_is_boxed(args[1], forbidden_vars)
+ ofs_loc = regalloc._ensure_value_is_boxed(args[3], forbidden_vars)
assert base_loc.is_reg()
assert ofs_loc.is_reg()
regalloc.possibly_free_var(args[1])
if args[3] is not args[4]: # more of the MESS described above
regalloc.possibly_free_var(args[3])
+ regalloc.free_temp_vars()
self._gen_address_inside_string(base_loc, ofs_loc, dstaddr_loc,
is_unicode=is_unicode)
# compute the length in bytes
forbidden_vars = [srcaddr_box, dstaddr_box]
- length_loc, length_box = regalloc._ensure_value_is_boxed(args[4], forbidden_vars)
- args.append(length_box)
+ # XXX basically duplicates regalloc.ensure_value_is_boxed, but we
+ # need the box here
+ if isinstance(args[4], Box):
+ length_box = args[4]
+ length_loc = regalloc.make_sure_var_in_reg(args[4], forbidden_vars)
+ else:
+ length_box = TempInt()
+ length_loc = regalloc.force_allocate_reg(length_box,
+ forbidden_vars, selected_reg=r.r2)
+ imm = regalloc.convert_to_imm(args[4])
+ self.load(length_loc, imm)
if is_unicode:
- forbidden_vars = [srcaddr_box, dstaddr_box]
bytes_box = TempPtr()
- bytes_loc = regalloc.force_allocate_reg(bytes_box, forbidden_vars)
+ bytes_loc = regalloc.force_allocate_reg(bytes_box,
+ forbidden_vars, selected_reg=r.r2)
scale = self._get_unicode_item_scale()
assert length_loc.is_reg()
- self.mc.MOV_ri(r.ip.value, 1<<scale)
+ self.mc.MOV_ri(r.ip.value, 1 << scale)
self.mc.MUL(bytes_loc.value, r.ip.value, length_loc.value)
length_box = bytes_box
length_loc = bytes_loc
# call memcpy()
- self._emit_call(NO_FORCE_INDEX, self.memcpy_addr, [dstaddr_box, srcaddr_box, length_box], regalloc)
+ self._emit_call(NO_FORCE_INDEX, self.memcpy_addr,
+ [dstaddr_box, srcaddr_box, length_box], regalloc)
- regalloc.possibly_free_vars(args)
regalloc.possibly_free_var(length_box)
regalloc.possibly_free_var(dstaddr_box)
regalloc.possibly_free_var(srcaddr_box)
-
def _gen_address_inside_string(self, baseloc, ofsloc, resloc, is_unicode):
- cpu = self.cpu
if is_unicode:
ofs_items, _, _ = symbolic.get_array_token(rstr.UNICODE,
- self.cpu.translate_support_code)
+ self.cpu.translate_support_code)
scale = self._get_unicode_item_scale()
else:
ofs_items, itemsize, _ = symbolic.get_array_token(rstr.STR,
- self.cpu.translate_support_code)
+ self.cpu.translate_support_code)
assert itemsize == 1
scale = 0
self._gen_address(ofsloc, ofs_items, scale, resloc, baseloc)
@@ -870,7 +945,7 @@
def _get_unicode_item_scale(self):
_, itemsize, _ = symbolic.get_array_token(rstr.UNICODE,
- self.cpu.translate_support_code)
+ self.cpu.translate_support_code)
if itemsize == 4:
return 2
elif itemsize == 2:
@@ -878,6 +953,7 @@
else:
raise AssertionError("bad unicode item size")
+
class UnicodeOpAssembler(object):
_mixin_ = True
@@ -887,7 +963,7 @@
def emit_op_unicodegetitem(self, op, arglocs, regalloc, fcond):
res, base_loc, ofs_loc, scale, basesize, itemsize = arglocs
self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value, cond=fcond,
- imm=scale.value, shifttype=shift.LSL)
+ imm=scale.value, shifttype=shift.LSL)
if scale.value == 2:
self.mc.LDR_ri(res.value, r.ip.value, basesize.value, cond=fcond)
elif scale.value == 1:
@@ -901,14 +977,17 @@
self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value, cond=fcond,
imm=scale.value, shifttype=shift.LSL)
if scale.value == 2:
- self.mc.STR_ri(value_loc.value, r.ip.value, basesize.value, cond=fcond)
+ self.mc.STR_ri(value_loc.value, r.ip.value, basesize.value,
+ cond=fcond)
elif scale.value == 1:
- self.mc.STRH_ri(value_loc.value, r.ip.value, basesize.value, cond=fcond)
+ self.mc.STRH_ri(value_loc.value, r.ip.value, basesize.value,
+ cond=fcond)
else:
assert 0, itemsize.value
return fcond
+
class ForceOpAssembler(object):
_mixin_ = True
@@ -920,18 +999,19 @@
# from: ../x86/assembler.py:1668
# XXX Split into some helper methods
- def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc, fcond):
+ def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc,
+ fcond):
faildescr = guard_op.getdescr()
fail_index = self.cpu.get_fail_descr_number(faildescr)
self._write_fail_index(fail_index)
descr = op.getdescr()
- assert isinstance(descr, LoopToken)
+ assert isinstance(descr, JitCellToken)
# XXX check this
- assert op.numargs() == len(descr._arm_arglocs[0])
+ # assert len(arglocs) - 2 == descr.compiled_loop_token._debug_nbargs
resbox = TempInt()
- self._emit_call(fail_index, descr._arm_direct_bootstrap_code, op.getarglist(),
- regalloc, fcond, result=resbox)
+ self._emit_call(fail_index, descr._arm_func_addr,
+ op.getarglist(), regalloc, fcond, result=resbox)
if op.result is None:
value = self.cpu.done_with_this_frame_void_v
else:
@@ -952,7 +1032,7 @@
regalloc.possibly_free_var(resbox)
fast_jmp_pos = self.mc.currpos()
- self.mc.NOP()
+ self.mc.BKPT()
# Path A: use assembler helper
#if values are equal we take the fast path
@@ -961,7 +1041,7 @@
jd = descr.outermost_jitdriver_sd
assert jd is not None
asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr)
- with saved_registers(self.mc, r.caller_resp[1:]+[r.ip],
+ with saved_registers(self.mc, r.caller_resp[1:] + [r.ip],
r.caller_vfp_resp):
# resbox is allready in r0
self.mov_loc_loc(arglocs[1], r.r1)
@@ -974,7 +1054,8 @@
# jump to merge point
jmp_pos = self.mc.currpos()
- #jmp_location = self.mc.curraddr()
+ # This location is not necessarily patched later, depending on how many
+ # instructions we emit from here to the merge point below.
self.mc.NOP()
# Path B: load return value and reset token
@@ -986,9 +1067,9 @@
# Reset the vable token --- XXX really too much special logic here:-(
if jd.index_of_virtualizable >= 0:
- from pypy.jit.backend.llsupport.descr import BaseFieldDescr
+ from pypy.jit.backend.llsupport.descr import FieldDescr
fielddescr = jd.vable_token_descr
- assert isinstance(fielddescr, BaseFieldDescr)
+ assert isinstance(fielddescr, FieldDescr)
ofs = fielddescr.offset
resloc = regalloc.force_allocate_reg(resbox)
self.mov_loc_loc(arglocs[1], r.ip)
@@ -1024,26 +1105,31 @@
self.mc.LDR_ri(r.ip.value, r.fp.value)
self.mc.CMP_ri(r.ip.value, 0)
- self._emit_guard(guard_op, regalloc._prepare_guard(guard_op), c.GE)
+ self._emit_guard(guard_op, regalloc._prepare_guard(guard_op),
+ c.GE, save_exc=True)
return fcond
-
# ../x86/assembler.py:668
def redirect_call_assembler(self, oldlooptoken, newlooptoken):
- # we overwrite the instructions at the old _x86_direct_bootstrap_code
- # to start with a JMP to the new _arm_direct_bootstrap_code.
+ # some minimal sanity checking
+ old_nbargs = oldlooptoken.compiled_loop_token._debug_nbargs
+ new_nbargs = newlooptoken.compiled_loop_token._debug_nbargs
+ assert old_nbargs == new_nbargs
+ # we overwrite the instructions at the old _arm_func_adddr
+ # to start with a JMP to the new _arm_func_addr.
# Ideally we should rather patch all existing CALLs, but well.
- oldadr = oldlooptoken._arm_direct_bootstrap_code
- target = newlooptoken._arm_direct_bootstrap_code
+ oldadr = oldlooptoken._arm_func_addr
+ target = newlooptoken._arm_func_addr
mc = ARMv7Builder()
mc.B(target)
mc.copy_to_raw_memory(oldadr)
- def emit_guard_call_may_force(self, op, guard_op, arglocs, regalloc, fcond):
+ def emit_guard_call_may_force(self, op, guard_op, arglocs, regalloc,
+ fcond):
self.mc.LDR_ri(r.ip.value, r.fp.value)
self.mc.CMP_ri(r.ip.value, 0)
- self._emit_guard(guard_op, arglocs, c.GE)
+ self._emit_guard(guard_op, arglocs, c.GE, save_exc=True)
return fcond
emit_guard_call_release_gil = emit_guard_call_may_force
@@ -1058,21 +1144,26 @@
regs_to_save.append(reg)
assert gcrootmap.is_shadow_stack
with saved_registers(self.mc, regs_to_save):
- self._emit_call(-1, self.releasegil_addr, [], self._regalloc, fcond)
+ self._emit_call(NO_FORCE_INDEX, self.releasegil_addr, [],
+ self._regalloc, fcond)
def call_reacquire_gil(self, gcrootmap, save_loc, fcond):
# save the previous result into the stack temporarily.
# XXX like with call_release_gil(), we assume that we don't need
- # to save vfp regs in this case.
+ # to save vfp regs in this case. Besides the result location
regs_to_save = []
+ vfp_regs_to_save = []
if save_loc.is_reg():
regs_to_save.append(save_loc)
+ if save_loc.is_vfp_reg():
+ vfp_regs_to_save.append(save_loc)
# call the reopenstack() function (also reacquiring the GIL)
- if len(regs_to_save) == 1:
- regs_to_save.append(r.ip) # for alingment
+ if len(regs_to_save) % 2 != 1:
+ regs_to_save.append(r.ip) # for alingment
assert gcrootmap.is_shadow_stack
- with saved_registers(self.mc, regs_to_save):
- self._emit_call(-1, self.reacqgil_addr, [], self._regalloc, fcond)
+ with saved_registers(self.mc, regs_to_save, vfp_regs_to_save):
+ self._emit_call(NO_FORCE_INDEX, self.reacqgil_addr, [],
+ self._regalloc, fcond)
def write_new_force_index(self):
# for shadowstack only: get a new, unused force_index number and
@@ -1092,54 +1183,16 @@
self.mc.gen_load_int(r.ip.value, fail_index)
self.mc.STR_ri(r.ip.value, r.fp.value)
+
class AllocOpAssembler(object):
_mixin_ = True
-
- # from: ../x86/regalloc.py:750
- # called from regalloc
- # XXX kill this function at some point
- def _regalloc_malloc_varsize(self, size, size_box, vloc, vbox, ofs_items_loc, regalloc, result):
- self.mc.MUL(size.value, size.value, vloc.value)
- if ofs_items_loc.is_imm():
- self.mc.ADD_ri(size.value, size.value, ofs_items_loc.value)
- else:
- self.mc.ADD_rr(size.value, size.value, ofs_items_loc.value)
- force_index = self.write_new_force_index()
- regalloc.force_spill_var(vbox)
- self._emit_call(force_index, self.malloc_func_addr, [size_box], regalloc,
- result=result)
-
- def emit_op_new(self, op, arglocs, regalloc, fcond):
+ def emit_op_call_malloc_gc(self, op, arglocs, regalloc, fcond):
+ self.emit_op_call(op, arglocs, regalloc, fcond)
self.propagate_memoryerror_if_r0_is_null()
return fcond
- def emit_op_new_with_vtable(self, op, arglocs, regalloc, fcond):
- classint = arglocs[0].value
- self.set_vtable(op.result, classint)
- return fcond
-
- def set_vtable(self, box, vtable):
- if self.cpu.vtable_offset is not None:
- adr = rffi.cast(lltype.Signed, vtable)
- self.mc.gen_load_int(r.ip.value, adr)
- self.mc.STR_ri(r.ip.value, r.r0.value, self.cpu.vtable_offset)
-
- def set_new_array_length(self, loc, ofs_length, loc_num_elem):
- assert loc.is_reg()
- self.mc.gen_load_int(r.ip.value, loc_num_elem)
- self.mc.STR_ri(r.ip.value, loc.value, imm=ofs_length)
-
- def emit_op_new_array(self, op, arglocs, regalloc, fcond):
- self.propagate_memoryerror_if_r0_is_null()
- if len(arglocs) > 0:
- value_loc, base_loc, ofs_length = arglocs
- self.mc.STR_ri(value_loc.value, base_loc.value, ofs_length.value)
- return fcond
-
- emit_op_newstr = emit_op_new_array
- emit_op_newunicode = emit_op_new_array
class FloatOpAssemlber(object):
_mixin_ = True
@@ -1182,6 +1235,7 @@
self.mc.VCVT_int_to_float(res.value, temp.value)
return fcond
+
class ResOpAssembler(GuardOpAssembler, IntOpAsslember,
OpAssembler, UnaryIntOpAssembler,
FieldOpAssembler, ArrayOpAssember,
@@ -1189,4 +1243,3 @@
ForceOpAssembler, AllocOpAssembler,
FloatOpAssemlber):
pass
-
diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -1,5 +1,5 @@
from pypy.jit.backend.llsupport.regalloc import FrameManager, \
- RegisterManager, compute_vars_longevity, TempBox, compute_loop_consts
+ RegisterManager, TempBox, compute_vars_longevity
from pypy.jit.backend.arm import registers as r
from pypy.jit.backend.arm import locations
from pypy.jit.backend.arm.locations import imm
@@ -8,22 +8,30 @@
prepare_op_ri,
prepare_cmp_op,
prepare_float_op,
- _check_imm_arg)
+ check_imm_arg,
+ check_imm_box
+ )
from pypy.jit.backend.arm.jump import remap_frame_layout_mixed
-from pypy.jit.backend.arm.arch import MY_COPY_OF_REGS, WORD
+from pypy.jit.backend.arm.arch import MY_COPY_OF_REGS
+from pypy.jit.backend.arm.arch import WORD, N_REGISTERS_SAVED_BY_MALLOC
from pypy.jit.codewriter import longlong
from pypy.jit.metainterp.history import (Const, ConstInt, ConstFloat, ConstPtr,
- Box, BoxInt, BoxPtr, AbstractFailDescr,
- INT, REF, FLOAT, LoopToken)
+ Box, BoxPtr,
+ INT, REF, FLOAT)
+from pypy.jit.metainterp.history import JitCellToken, TargetToken
from pypy.jit.metainterp.resoperation import rop
-from pypy.jit.backend.llsupport.descr import BaseFieldDescr, BaseArrayDescr, \
- BaseCallDescr, BaseSizeDescr, \
- InteriorFieldDescr
+from pypy.jit.backend.llsupport.descr import ArrayDescr
from pypy.jit.backend.llsupport import symbolic
-from pypy.rpython.lltypesystem import lltype, rffi, rstr, llmemory
-from pypy.jit.codewriter import heaptracker
+from pypy.rpython.lltypesystem import lltype, rffi, rstr
from pypy.jit.codewriter.effectinfo import EffectInfo
-from pypy.rlib.objectmodel import we_are_translated
+from pypy.jit.backend.llsupport.descr import unpack_arraydescr
+from pypy.jit.backend.llsupport.descr import unpack_fielddescr
+from pypy.jit.backend.llsupport.descr import unpack_interiorfielddescr
+
+
+# xxx hack: set a default value for TargetToken._arm_loop_code. If 0, we know
+# that it is a LABEL that was not compiled yet.
+TargetToken._arm_loop_code = 0
class TempInt(TempBox):
type = INT
@@ -31,27 +39,40 @@
def __repr__(self):
return "<TempInt at %s>" % (id(self),)
+
class TempPtr(TempBox):
type = REF
def __repr__(self):
return "<TempPtr at %s>" % (id(self),)
+
class TempFloat(TempBox):
type = FLOAT
def __repr__(self):
return "<TempFloat at %s>" % (id(self),)
+
class ARMFrameManager(FrameManager):
+
def __init__(self):
FrameManager.__init__(self)
- self.frame_depth = 1
+ self.used = [True] # keep first slot free
+ # XXX refactor frame to avoid this issue of keeping the first slot
+ # reserved
+
@staticmethod
def frame_pos(loc, type):
num_words = ARMFrameManager.frame_size(type)
if type == FLOAT:
- return locations.StackLocation(loc+1, num_words=num_words, type=type)
+ if loc > 0:
+ # Make sure that loc is an even value
+ # the frame layout requires loc to be even if it is a spilled
+ # value!!
+ assert (loc & 1) == 0
+ return locations.StackLocation(loc + 1,
+ num_words=num_words, type=type)
return locations.StackLocation(loc, num_words=num_words, type=type)
@staticmethod
@@ -60,9 +81,19 @@
return 2
return 1
+ @staticmethod
+ def get_loc_index(loc):
+ assert loc.is_stack()
+ if loc.type == FLOAT:
+ return loc.position - 1
+ else:
+ return loc.position
+
+
def void(self, op, fcond):
return []
+
class VFPRegisterManager(RegisterManager):
all_regs = r.all_vfp_regs
box_types = [FLOAT]
@@ -84,10 +115,33 @@
self._check_type(v)
r = self.force_allocate_reg(v)
return r
-class ARMv7RegisterMananger(RegisterManager):
- all_regs = r.all_regs
- box_types = None # or a list of acceptable types
- no_lower_byte_regs = all_regs
+
+ def ensure_value_is_boxed(self, thing, forbidden_vars=[]):
+ loc = None
+ if isinstance(thing, Const):
+ assert isinstance(thing, ConstFloat)
+ loc = self.get_scratch_reg(FLOAT, self.temp_boxes + forbidden_vars)
+ immvalue = self.convert_to_imm(thing)
+ self.assembler.load(loc, immvalue)
+ else:
+ loc = self.make_sure_var_in_reg(thing,
+ forbidden_vars=self.temp_boxes + forbidden_vars)
+ return loc
+
+ def get_scratch_reg(self, type=FLOAT, forbidden_vars=[],
+ selected_reg=None):
+ assert type == FLOAT # for now
+ box = TempFloat()
+ self.temp_boxes.append(box)
+ reg = self.force_allocate_reg(box, forbidden_vars=forbidden_vars,
+ selected_reg=selected_reg)
+ return reg
+
+
+class ARMv7RegisterManager(RegisterManager):
+ all_regs = r.all_regs
+ box_types = None # or a list of acceptable types
+ no_lower_byte_regs = all_regs
save_around_call_regs = r.caller_resp
REGLOC_TO_COPY_AREA_OFS = {
@@ -110,27 +164,53 @@
def convert_to_imm(self, c):
if isinstance(c, ConstInt):
- return locations.ImmLocation(c.value)
+ val = rffi.cast(rffi.INT, c.value)
+ return locations.ImmLocation(val)
else:
assert isinstance(c, ConstPtr)
return locations.ImmLocation(rffi.cast(lltype.Signed, c.value))
-
+ assert 0
+
+ def ensure_value_is_boxed(self, thing, forbidden_vars=None):
+ loc = None
+ if isinstance(thing, Const):
+ if isinstance(thing, ConstPtr):
+ tp = REF
+ else:
+ tp = INT
+ loc = self.get_scratch_reg(tp, forbidden_vars=self.temp_boxes
+ + forbidden_vars)
+ immvalue = self.convert_to_imm(thing)
+ self.assembler.load(loc, immvalue)
+ else:
+ loc = self.make_sure_var_in_reg(thing,
+ forbidden_vars=forbidden_vars)
+ return loc
+
+ def get_scratch_reg(self, type=INT, forbidden_vars=[], selected_reg=None):
+ assert type == INT or type == REF
+ box = TempBox()
+ self.temp_boxes.append(box)
+ reg = self.force_allocate_reg(box, forbidden_vars=forbidden_vars,
+ selected_reg=selected_reg)
+ return reg
+
+
class Regalloc(object):
- def __init__(self, longevity, frame_manager=None, assembler=None):
+ def __init__(self, frame_manager=None, assembler=None):
self.cpu = assembler.cpu
- self.longevity = longevity
+ self.assembler = assembler
self.frame_manager = frame_manager
- self.assembler = assembler
- self.vfprm = VFPRegisterManager(longevity, frame_manager, assembler)
- self.rm = ARMv7RegisterMananger(longevity, frame_manager, assembler)
+ self.jump_target_descr = None
+ self.final_jump_op = None
def loc(self, var):
if var.type == FLOAT:
return self.vfprm.loc(var)
else:
return self.rm.loc(var)
-
+
def position(self):
return self.rm.position
@@ -168,9 +248,11 @@
else:
return self.rm.force_allocate_reg(var, forbidden_vars,
selected_reg, need_lower_byte)
+
def try_allocate_reg(self, v, selected_reg=None, need_lower_byte=False):
if v.type == FLOAT:
- return self.vfprm.try_allocate_reg(v, selected_reg, need_lower_byte)
+ return self.vfprm.try_allocate_reg(v, selected_reg,
+ need_lower_byte)
else:
return self.rm.try_allocate_reg(v, selected_reg, need_lower_byte)
@@ -183,14 +265,25 @@
def possibly_free_vars_for_op(self, op):
for i in range(op.numargs()):
var = op.getarg(i)
- if var is not None: # xxx kludgy
+ if var is not None: # xxx kludgy
self.possibly_free_var(var)
def possibly_free_vars(self, vars):
for var in vars:
- if var is not None: # xxx kludgy
+ if var is not None: # xxx kludgy
self.possibly_free_var(var)
+ def get_scratch_reg(self, type, forbidden_vars=[], selected_reg=None):
+ if type == FLOAT:
+ return self.vfprm.get_scratch_reg(type, forbidden_vars,
+ selected_reg)
+ else:
+ return self.rm.get_scratch_reg(type, forbidden_vars, selected_reg)
+
+ def free_temp_vars(self):
+ self.rm.free_temp_vars()
+ self.vfprm.free_temp_vars()
+
def make_sure_var_in_reg(self, var, forbidden_vars=[],
selected_reg=None, need_lower_byte=False):
if var.type == FLOAT:
@@ -207,31 +300,68 @@
assert isinstance(value, ConstFloat)
return self.vfprm.convert_to_imm(value)
- def prepare_loop(self, inputargs, operations, looptoken):
- loop_consts = compute_loop_consts(inputargs, operations[-1], looptoken)
- floatlocs = [None] * len(inputargs)
- nonfloatlocs = [None] * len(inputargs)
- for i in range(len(inputargs)):
- arg = inputargs[i]
- assert not isinstance(arg, Const)
- reg = None
- loc = inputargs[i]
- if arg not in loop_consts and self.longevity[arg][1] > -1:
- reg = self.try_allocate_reg(loc)
+ def _prepare(self, inputargs, operations):
+ longevity, last_real_usage = compute_vars_longevity(
+ inputargs, operations)
+ self.longevity = longevity
+ self.last_real_usage = last_real_usage
+ fm = self.frame_manager
+ asm = self.assembler
+ self.vfprm = VFPRegisterManager(longevity, fm, asm)
+ self.rm = ARMv7RegisterManager(longevity, fm, asm)
- loc = self.loc(arg)
- if arg.type == FLOAT:
- floatlocs[i] = loc
+ def prepare_loop(self, inputargs, operations):
+ self._prepare(inputargs, operations)
+ self._set_initial_bindings(inputargs)
+ self.possibly_free_vars(list(inputargs))
+
+ def prepare_bridge(self, inputargs, arglocs, ops):
+ self._prepare(inputargs, ops)
+ self._update_bindings(arglocs, inputargs)
+
+ def _set_initial_bindings(self, inputargs):
+ # The first inputargs are passed in registers r0-r3
+ # we relly on the soft-float calling convention so we need to move
+ # float params to the coprocessor.
+
+ arg_index = 0
+ count = 0
+ n_register_args = len(r.argument_regs)
+ cur_frame_pos = - (self.assembler.STACK_FIXED_AREA / WORD) + 1
+ for box in inputargs:
+ assert isinstance(box, Box)
+ # handle inputargs in argument registers
+ if box.type == FLOAT and arg_index % 2 != 0:
+ arg_index += 1 # align argument index for float passed
+ # in register
+ if arg_index < n_register_args:
+ if box.type == FLOAT:
+ loc = r.argument_regs[arg_index]
+ loc2 = r.argument_regs[arg_index + 1]
+ vfpreg = self.try_allocate_reg(box)
+ # move soft-float argument to vfp
+ self.assembler.mov_to_vfp_loc(loc, loc2, vfpreg)
+ arg_index += 2 # this argument used to argument registers
+ else:
+ loc = r.argument_regs[arg_index]
+ self.try_allocate_reg(box, selected_reg=loc)
+ arg_index += 1
else:
- nonfloatlocs[i] = loc
- self.possibly_free_vars(list(inputargs))
-
- return nonfloatlocs, floatlocs
+ # treat stack args as stack locations with a negative offset
+ if box.type == FLOAT:
+ cur_frame_pos -= 2
+ if count % 2 != 0: # Stack argument alignment
+ cur_frame_pos -= 1
+ count = 0
+ else:
+ cur_frame_pos -= 1
+ count += 1
+ loc = self.frame_manager.frame_pos(cur_frame_pos, box.type)
+ self.frame_manager.set_binding(box, loc)
- def update_bindings(self, locs, frame_depth, inputargs):
+ def _update_bindings(self, locs, inputargs):
used = {}
i = 0
- self.frame_manager.frame_depth = frame_depth
for loc in locs:
arg = inputargs[i]
i += 1
@@ -241,7 +371,7 @@
self.vfprm.reg_bindings[arg] = loc
else:
assert loc.is_stack()
- self.frame_manager.frame_bindings[arg] = loc
+ self.frame_manager.set_binding(arg, loc)
used[loc] = None
# XXX combine with x86 code and move to llsupport
@@ -257,7 +387,6 @@
# is also used on op args, which is a non-resizable list
self.possibly_free_vars(list(inputargs))
-
def force_spill_var(self, var):
if var.type == FLOAT:
self.vfprm.force_spill_var(var)
@@ -267,28 +396,12 @@
def before_call(self, force_store=[], save_all_regs=False):
self.rm.before_call(force_store, save_all_regs)
self.vfprm.before_call(force_store, save_all_regs)
+
def _ensure_value_is_boxed(self, thing, forbidden_vars=[]):
- box = None
- loc = None
- if isinstance(thing, Const):
- if isinstance(thing, ConstPtr):
- box = TempPtr()
- elif isinstance(thing, ConstFloat):
- box = TempFloat()
- else:
- box = TempInt()
- loc = self.force_allocate_reg(box,
- forbidden_vars=forbidden_vars)
- if isinstance(thing, ConstFloat):
- imm = self.vfprm.convert_to_imm(thing)
- else:
- imm = self.rm.convert_to_imm(thing)
- self.assembler.load(loc, imm)
+ if thing.type == FLOAT:
+ return self.vfprm.ensure_value_is_boxed(thing, forbidden_vars)
else:
- loc = self.make_sure_var_in_reg(thing,
- forbidden_vars=forbidden_vars)
- box = thing
- return loc, box
+ return self.rm.ensure_value_is_boxed(thing, forbidden_vars)
def _sync_var(self, v):
if v.type == FLOAT:
@@ -299,52 +412,45 @@
def _prepare_op_int_add(self, op, fcond):
boxes = list(op.getarglist())
a0, a1 = boxes
- imm_a0 = _check_imm_arg(a0)
- imm_a1 = _check_imm_arg(a1)
+ imm_a0 = check_imm_box(a0)
+ imm_a1 = check_imm_box(a1)
if not imm_a0 and imm_a1:
- l0, box = self._ensure_value_is_boxed(a0)
- l1 = self.make_sure_var_in_reg(a1, [a0])
- boxes.append(box)
+ l0 = self._ensure_value_is_boxed(a0)
+ l1 = self.make_sure_var_in_reg(a1, boxes)
elif imm_a0 and not imm_a1:
l0 = self.make_sure_var_in_reg(a0)
- l1, box = self._ensure_value_is_boxed(a1, [a0])
- boxes.append(box)
+ l1 = self._ensure_value_is_boxed(a1, boxes)
else:
- l0, box = self._ensure_value_is_boxed(a0)
- boxes.append(box)
- l1, box = self._ensure_value_is_boxed(a1, [box])
- boxes.append(box)
- return [l0, l1], boxes
+ l0 = self._ensure_value_is_boxed(a0)
+ l1 = self._ensure_value_is_boxed(a1, boxes)
+ return [l0, l1]
def prepare_op_int_add(self, op, fcond):
- locs, boxes = self._prepare_op_int_add(op, fcond)
- self.possibly_free_vars(boxes)
+ locs = self._prepare_op_int_add(op, fcond)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
res = self.force_allocate_reg(op.result)
return locs + [res]
def _prepare_op_int_sub(self, op, fcond):
- boxes = list(op.getarglist())
- a0, a1 = boxes
- imm_a0 = _check_imm_arg(a0)
- imm_a1 = _check_imm_arg(a1)
+ a0, a1 = boxes = op.getarglist()
+ imm_a0 = check_imm_box(a0)
+ imm_a1 = check_imm_box(a1)
if not imm_a0 and imm_a1:
- l0, box = self._ensure_value_is_boxed(a0, boxes)
- l1 = self.make_sure_var_in_reg(a1, [a0])
- boxes.append(box)
+ l0 = self._ensure_value_is_boxed(a0, boxes)
+ l1 = self.make_sure_var_in_reg(a1, boxes)
elif imm_a0 and not imm_a1:
- l0 = self.make_sure_var_in_reg(a0)
- l1, box = self._ensure_value_is_boxed(a1, boxes)
- boxes.append(box)
+ l0 = self.make_sure_var_in_reg(a0, boxes)
+ l1 = self._ensure_value_is_boxed(a1, boxes)
else:
- l0, box = self._ensure_value_is_boxed(a0, boxes)
- boxes.append(box)
- l1, box = self._ensure_value_is_boxed(a1, boxes)
- boxes.append(box)
- return [l0, l1], boxes
+ l0 = self._ensure_value_is_boxed(a0, boxes)
+ l1 = self._ensure_value_is_boxed(a1, boxes)
+ return [l0, l1]
def prepare_op_int_sub(self, op, fcond):
- locs, boxes = self._prepare_op_int_sub(op, fcond)
- self.possibly_free_vars(boxes)
+ locs = self._prepare_op_int_sub(op, fcond)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
res = self.force_allocate_reg(op.result)
return locs + [res]
@@ -352,10 +458,8 @@
boxes = list(op.getarglist())
a0, a1 = boxes
- reg1, box = self._ensure_value_is_boxed(a0, forbidden_vars=boxes)
- boxes.append(box)
- reg2, box = self._ensure_value_is_boxed(a1, forbidden_vars=boxes)
- boxes.append(box)
+ reg1 = self._ensure_value_is_boxed(a0, forbidden_vars=boxes)
+ reg2 = self._ensure_value_is_boxed(a1, forbidden_vars=boxes)
self.possibly_free_vars(boxes)
self.possibly_free_vars_for_op(op)
@@ -364,42 +468,23 @@
return [reg1, reg2, res]
def prepare_guard_int_mul_ovf(self, op, guard, fcond):
- boxes = list(op.getarglist())
- a0, a1 = boxes
-
- reg1, box = self._ensure_value_is_boxed(a0, forbidden_vars=boxes)
- boxes.append(box)
- reg2, box = self._ensure_value_is_boxed(a1, forbidden_vars=boxes)
- boxes.append(box)
+ boxes = op.getarglist()
+ reg1 = self._ensure_value_is_boxed(boxes[0], forbidden_vars=boxes)
+ reg2 = self._ensure_value_is_boxed(boxes[1], forbidden_vars=boxes)
res = self.force_allocate_reg(op.result)
- args = self._prepare_guard(guard, [reg1, reg2, res])
-
- self.possibly_free_vars(boxes)
- self.possibly_free_vars_for_op(op)
- self.possibly_free_var(op.result)
- self.possibly_free_vars(guard.getfailargs())
- return args
-
+ return self._prepare_guard(guard, [reg1, reg2, res])
def prepare_guard_int_add_ovf(self, op, guard, fcond):
- locs, boxes = self._prepare_op_int_add(op, fcond)
+ locs = self._prepare_op_int_add(op, fcond)
res = self.force_allocate_reg(op.result)
locs.append(res)
- locs = self._prepare_guard(guard, locs)
- self.possibly_free_vars(boxes)
- self.possibly_free_vars_for_op(op)
- self.possibly_free_vars(guard.getfailargs())
- return locs
+ return self._prepare_guard(guard, locs)
def prepare_guard_int_sub_ovf(self, op, guard, fcond):
- locs, boxes = self._prepare_op_int_sub(op, fcond)
+ locs = self._prepare_op_int_sub(op, fcond)
res = self.force_allocate_reg(op.result)
locs.append(res)
- locs = self._prepare_guard(guard, locs)
- self.possibly_free_vars(boxes)
- self.possibly_free_vars_for_op(op)
- self.possibly_free_vars(guard.getfailargs())
- return locs
+ return self._prepare_guard(guard, locs)
prepare_op_int_floordiv = prepare_op_by_helper_call('int_floordiv')
prepare_op_int_mod = prepare_op_by_helper_call('int_mod')
@@ -408,9 +493,12 @@
prepare_op_int_and = prepare_op_ri('int_and')
prepare_op_int_or = prepare_op_ri('int_or')
prepare_op_int_xor = prepare_op_ri('int_xor')
- prepare_op_int_lshift = prepare_op_ri('int_lshift', imm_size=0x1F, allow_zero=False, commutative=False)
- prepare_op_int_rshift = prepare_op_ri('int_rshift', imm_size=0x1F, allow_zero=False, commutative=False)
- prepare_op_uint_rshift = prepare_op_ri('uint_rshift', imm_size=0x1F, allow_zero=False, commutative=False)
+ prepare_op_int_lshift = prepare_op_ri('int_lshift', imm_size=0x1F,
+ allow_zero=False, commutative=False)
+ prepare_op_int_rshift = prepare_op_ri('int_rshift', imm_size=0x1F,
+ allow_zero=False, commutative=False)
+ prepare_op_uint_rshift = prepare_op_ri('uint_rshift', imm_size=0x1F,
+ allow_zero=False, commutative=False)
prepare_op_int_lt = prepare_cmp_op('int_lt')
prepare_op_int_le = prepare_cmp_op('int_le')
@@ -425,8 +513,8 @@
prepare_op_uint_lt = prepare_cmp_op('uint_lt')
prepare_op_uint_ge = prepare_cmp_op('uint_ge')
- prepare_op_ptr_eq = prepare_op_int_eq
- prepare_op_ptr_ne = prepare_op_int_ne
+ prepare_op_ptr_eq = prepare_op_instance_ptr_eq = prepare_op_int_eq
+ prepare_op_ptr_ne = prepare_op_instance_ptr_ne = prepare_op_int_ne
prepare_guard_int_lt = prepare_cmp_op('guard_int_lt')
prepare_guard_int_le = prepare_cmp_op('guard_int_le')
@@ -441,13 +529,12 @@
prepare_guard_uint_lt = prepare_cmp_op('guard_uint_lt')
prepare_guard_uint_ge = prepare_cmp_op('guard_uint_ge')
- prepare_guard_ptr_eq = prepare_guard_int_eq
- prepare_guard_ptr_ne = prepare_guard_int_ne
+ prepare_guard_ptr_eq = prepare_guard_instance_ptr_eq = prepare_guard_int_eq
+ prepare_guard_ptr_ne = prepare_guard_instance_ptr_ne = prepare_guard_int_ne
prepare_op_int_add_ovf = prepare_op_int_add
prepare_op_int_sub_ovf = prepare_op_int_sub
-
prepare_op_int_is_true = prepare_op_unary_cmp('int_is_true')
prepare_op_int_is_zero = prepare_op_unary_cmp('int_is_zero')
@@ -455,10 +542,10 @@
prepare_guard_int_is_zero = prepare_op_unary_cmp('int_is_zero')
def prepare_op_int_neg(self, op, fcond):
- l0, box = self._ensure_value_is_boxed(op.getarg(0))
- self.possibly_free_var(box)
+ l0 = self._ensure_value_is_boxed(op.getarg(0))
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
resloc = self.force_allocate_reg(op.result)
- self.possibly_free_var(op.result)
return [l0, resloc]
prepare_op_int_invert = prepare_op_int_neg
@@ -474,10 +561,14 @@
args = [imm(rffi.cast(lltype.Signed, op.getarg(0).getint()))]
return args
+ def prepare_op_call_malloc_gc(self, op, fcond):
+ args = [imm(rffi.cast(lltype.Signed, op.getarg(0).getint()))]
+ return args
+
def _prepare_guard(self, op, args=None):
if args is None:
args = []
- args.append(imm(self.frame_manager.frame_depth))
+ args.append(imm(self.frame_manager.get_frame_depth()))
for arg in op.getfailargs():
if arg:
args.append(self.loc(arg))
@@ -486,21 +577,19 @@
return args
def prepare_op_finish(self, op, fcond):
- args = [imm(self.frame_manager.frame_depth)]
+ args = [None] * (op.numargs() + 1)
for i in range(op.numargs()):
arg = op.getarg(i)
if arg:
- args.append(self.loc(arg))
+ args[i] = self.loc(arg)
self.possibly_free_var(arg)
- else:
- args.append(None)
+ n = self.cpu.get_fail_descr_number(op.getdescr())
+ args[-1] = imm(n)
return args
def prepare_op_guard_true(self, op, fcond):
- l0, box = self._ensure_value_is_boxed(op.getarg(0))
+ l0 = self._ensure_value_is_boxed(op.getarg(0))
args = self._prepare_guard(op, [l0])
- self.possibly_free_var(box)
- self.possibly_free_vars(op.getfailargs())
return args
prepare_op_guard_false = prepare_op_guard_true
@@ -510,17 +599,15 @@
def prepare_op_guard_value(self, op, fcond):
boxes = list(op.getarglist())
a0, a1 = boxes
- imm_a1 = _check_imm_arg(a1)
- l0, box = self._ensure_value_is_boxed(a0, boxes)
- boxes.append(box)
+ imm_a1 = check_imm_box(a1)
+ l0 = self._ensure_value_is_boxed(a0, boxes)
if not imm_a1:
- l1, box = self._ensure_value_is_boxed(a1,boxes)
- boxes.append(box)
+ l1 = self._ensure_value_is_boxed(a1, boxes)
else:
- l1 = self.make_sure_var_in_reg(a1)
+ l1 = self.make_sure_var_in_reg(a1, boxes)
assert op.result is None
arglocs = self._prepare_guard(op, [l0, l1])
- self.possibly_free_vars(boxes)
+ self.possibly_free_vars(op.getarglist())
self.possibly_free_vars(op.getfailargs())
return arglocs
@@ -532,33 +619,26 @@
prepare_op_guard_overflow = prepare_op_guard_no_overflow
prepare_op_guard_not_invalidated = prepare_op_guard_no_overflow
-
def prepare_op_guard_exception(self, op, fcond):
boxes = list(op.getarglist())
arg0 = ConstInt(rffi.cast(lltype.Signed, op.getarg(0).getint()))
- loc, box = self._ensure_value_is_boxed(arg0)
- boxes.append(box)
- box = TempInt()
- loc1 = self.force_allocate_reg(box, boxes)
- boxes.append(box)
+ loc = self._ensure_value_is_boxed(arg0)
+ loc1 = self.get_scratch_reg(INT, boxes)
if op.result in self.longevity:
resloc = self.force_allocate_reg(op.result, boxes)
- boxes.append(op.result)
+ self.possibly_free_var(op.result)
else:
resloc = None
pos_exc_value = imm(self.cpu.pos_exc_value())
pos_exception = imm(self.cpu.pos_exception())
- arglocs = self._prepare_guard(op, [loc, loc1, resloc, pos_exc_value, pos_exception])
- self.possibly_free_vars(boxes)
- self.possibly_free_vars(op.getfailargs())
+ arglocs = self._prepare_guard(op,
+ [loc, loc1, resloc, pos_exc_value, pos_exception])
return arglocs
def prepare_op_guard_no_exception(self, op, fcond):
- loc, box = self._ensure_value_is_boxed(
+ loc = self._ensure_value_is_boxed(
ConstInt(self.cpu.pos_exception()))
arglocs = self._prepare_guard(op, [loc])
- self.possibly_free_var(box)
- self.possibly_free_vars(op.getfailargs())
return arglocs
def prepare_op_guard_class(self, op, fcond):
@@ -570,88 +650,111 @@
assert isinstance(op.getarg(0), Box)
boxes = list(op.getarglist())
- x, x_box = self._ensure_value_is_boxed(boxes[0], boxes)
- boxes.append(x_box)
-
- t = TempInt()
- y = self.force_allocate_reg(t, boxes)
- boxes.append(t)
+ x = self._ensure_value_is_boxed(boxes[0], boxes)
+ y = self.get_scratch_reg(REF, forbidden_vars=boxes)
y_val = rffi.cast(lltype.Signed, op.getarg(1).getint())
self.assembler.load(y, imm(y_val))
offset = self.cpu.vtable_offset
assert offset is not None
- offset_loc, offset_box = self._ensure_value_is_boxed(ConstInt(offset), boxes)
- boxes.append(offset_box)
+ offset_loc = self._ensure_value_is_boxed(ConstInt(offset), boxes)
arglocs = self._prepare_guard(op, [x, y, offset_loc])
- self.possibly_free_vars(boxes)
- self.possibly_free_vars(op.getfailargs())
return arglocs
+ def compute_hint_frame_locations(self, operations):
+ # optimization only: fill in the 'hint_frame_locations' dictionary
+ # of rm and xrm based on the JUMP at the end of the loop, by looking
+ # at where we would like the boxes to be after the jump.
+ op = operations[-1]
+ if op.getopnum() != rop.JUMP:
+ return
+ self.final_jump_op = op
+ descr = op.getdescr()
+ assert isinstance(descr, TargetToken)
+ if descr._arm_loop_code != 0:
+ # if the target LABEL was already compiled, i.e. if it belongs
+ # to some already-compiled piece of code
+ self._compute_hint_frame_locations_from_descr(descr)
+ #else:
+ # The loop ends in a JUMP going back to a LABEL in the same loop.
+ # We cannot fill 'hint_frame_locations' immediately, but we can
+ # wait until the corresponding prepare_op_label() to know where the
+ # we would like the boxes to be after the jump.
+
+ def _compute_hint_frame_locations_from_descr(self, descr):
+ arglocs = self.assembler.target_arglocs(descr)
+ jump_op = self.final_jump_op
+ assert len(arglocs) == jump_op.numargs()
+ for i in range(jump_op.numargs()):
+ box = jump_op.getarg(i)
+ if isinstance(box, Box):
+ loc = arglocs[i]
+ if loc is not None and loc.is_stack():
+ self.frame_manager.hint_frame_locations[box] = loc
def prepare_op_jump(self, op, fcond):
- assembler = self.assembler
descr = op.getdescr()
- assert isinstance(descr, LoopToken)
- nonfloatlocs, floatlocs = descr._arm_arglocs
+ assert isinstance(descr, TargetToken)
+ self.jump_target_descr = descr
+ arglocs = self.assembler.target_arglocs(descr)
# get temporary locs
tmploc = r.ip
- box = TempFloat()
- # compute 'vfptmploc' to be all_regs[0] by spilling what is there
- vfptmp = self.vfprm.all_regs[0]
- vfptmploc = self.vfprm.force_allocate_reg(box, selected_reg=vfptmp)
+ vfptmploc = r.vfp_ip
# Part about non-floats
- # XXX we don't need a copy, we only just the original list
- src_locations1 = [self.loc(op.getarg(i)) for i in range(op.numargs())
- if op.getarg(i).type != FLOAT]
- assert tmploc not in nonfloatlocs
- dst_locations1 = [loc for loc in nonfloatlocs if loc is not None]
+ src_locations1 = []
+ dst_locations1 = []
# Part about floats
- src_locations2 = [self.loc(op.getarg(i)) for i in range(op.numargs())
- if op.getarg(i).type == FLOAT]
- dst_locations2 = [loc for loc in floatlocs if loc is not None]
+ src_locations2 = []
+ dst_locations2 = []
+
+ # Build the four lists
+ for i in range(op.numargs()):
+ box = op.getarg(i)
+ src_loc = self.loc(box)
+ dst_loc = arglocs[i]
+ if box.type != FLOAT:
+ src_locations1.append(src_loc)
+ dst_locations1.append(dst_loc)
+ else:
+ src_locations2.append(src_loc)
+ dst_locations2.append(dst_loc)
+
remap_frame_layout_mixed(self.assembler,
src_locations1, dst_locations1, tmploc,
src_locations2, dst_locations2, vfptmploc)
- self.possibly_free_var(box)
return []
def prepare_op_setfield_gc(self, op, fcond):
boxes = list(op.getarglist())
a0, a1 = boxes
- ofs, size, ptr = self._unpack_fielddescr(op.getdescr())
- base_loc, base_box = self._ensure_value_is_boxed(a0, boxes)
- boxes.append(base_box)
- value_loc, value_box = self._ensure_value_is_boxed(a1, boxes)
- boxes.append(value_box)
- c_ofs = ConstInt(ofs)
- if _check_imm_arg(c_ofs):
+ ofs, size, sign = unpack_fielddescr(op.getdescr())
+ base_loc = self._ensure_value_is_boxed(a0, boxes)
+ value_loc = self._ensure_value_is_boxed(a1, boxes)
+ if check_imm_arg(ofs):
ofs_loc = imm(ofs)
else:
- ofs_loc, ofs_box = self._ensure_value_is_boxed(c_ofs, boxes)
- boxes.append(ofs_box)
- self.possibly_free_vars(boxes)
+ ofs_loc = self.get_scratch_reg(INT, boxes)
+ self.assembler.load(ofs_loc, imm(ofs))
return [value_loc, base_loc, ofs_loc, imm(size)]
prepare_op_setfield_raw = prepare_op_setfield_gc
def prepare_op_getfield_gc(self, op, fcond):
a0 = op.getarg(0)
- ofs, size, ptr = self._unpack_fielddescr(op.getdescr())
- base_loc, base_box = self._ensure_value_is_boxed(a0)
- c_ofs = ConstInt(ofs)
- if _check_imm_arg(c_ofs):
- ofs_loc = imm(ofs)
+ ofs, size, sign = unpack_fielddescr(op.getdescr())
+ base_loc = self._ensure_value_is_boxed(a0)
+ immofs = imm(ofs)
+ if check_imm_arg(ofs):
+ ofs_loc = immofs
else:
- ofs_loc, ofs_box = self._ensure_value_is_boxed(c_ofs, [base_box])
- self.possibly_free_var(ofs_box)
- self.possibly_free_var(a0)
- self.possibly_free_var(base_box)
+ ofs_loc = self.get_scratch_reg(INT, [a0])
+ self.assembler.load(ofs_loc, immofs)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
res = self.force_allocate_reg(op.result)
- self.possibly_free_var(op.result)
return [base_loc, ofs_loc, res, imm(size)]
prepare_op_getfield_raw = prepare_op_getfield_gc
@@ -659,126 +762,110 @@
prepare_op_getfield_gc_pure = prepare_op_getfield_gc
def prepare_op_getinteriorfield_gc(self, op, fcond):
- t = self._unpack_interiorfielddescr(op.getdescr())
+ t = unpack_interiorfielddescr(op.getdescr())
ofs, itemsize, fieldsize, sign = t
args = op.getarglist()
- base_loc, base_box = self._ensure_value_is_boxed(op.getarg(0), args)
- index_loc, index_box = self._ensure_value_is_boxed(op.getarg(1), args)
- c_ofs = ConstInt(ofs)
- if _check_imm_arg(c_ofs):
- ofs_loc = imm(ofs)
+ base_loc = self._ensure_value_is_boxed(op.getarg(0), args)
+ index_loc = self._ensure_value_is_boxed(op.getarg(1), args)
+ immofs = imm(ofs)
+ if check_imm_arg(ofs):
+ ofs_loc = immofs
else:
- ofs_loc, ofs_box = self._ensure_value_is_boxed(c_ofs, [base_box, index_box])
- self.possibly_free_var(ofs_box)
- self.possibly_free_vars(args)
- self.possibly_free_var(base_box)
- self.possibly_free_var(index_box)
+ ofs_loc = self.get_scratch_reg(INT, args)
+ self.assembler.load(ofs_loc, immofs)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
result_loc = self.force_allocate_reg(op.result)
- return [base_loc, index_loc, result_loc, ofs_loc, imm(ofs),
- imm(itemsize), imm(fieldsize)]
+ return [base_loc, index_loc, result_loc, ofs_loc, imm(ofs),
+ imm(itemsize), imm(fieldsize)]
-
def prepare_op_setinteriorfield_gc(self, op, fcond):
- t = self._unpack_interiorfielddescr(op.getdescr())
+ t = unpack_interiorfielddescr(op.getdescr())
ofs, itemsize, fieldsize, sign = t
- boxes = [None]*3
- base_loc, base_box = self._ensure_value_is_boxed(op.getarg(0), boxes)
- boxes[0] = base_box
- index_loc, index_box = self._ensure_value_is_boxed(op.getarg(1), boxes)
- boxes[1] = index_box
- value_loc, value_box = self._ensure_value_is_boxed(op.getarg(2), boxes)
- boxes[2] = value_box
- c_ofs = ConstInt(ofs)
- if _check_imm_arg(c_ofs):
- ofs_loc = imm(ofs)
+ args = op.getarglist()
+ base_loc = self._ensure_value_is_boxed(op.getarg(0), args)
+ index_loc = self._ensure_value_is_boxed(op.getarg(1), args)
+ value_loc = self._ensure_value_is_boxed(op.getarg(2), args)
+ immofs = imm(ofs)
+ if check_imm_arg(ofs):
+ ofs_loc = immofs
else:
- ofs_loc, ofs_box = self._ensure_value_is_boxed(c_ofs, boxes)
- self.possibly_free_var(ofs_box)
- self.possibly_free_vars(boxes)
+ ofs_loc = self.get_scratch_reg(INT, args)
+ self.assembler.load(ofs_loc, immofs)
return [base_loc, index_loc, value_loc, ofs_loc, imm(ofs),
imm(itemsize), imm(fieldsize)]
def prepare_op_arraylen_gc(self, op, fcond):
arraydescr = op.getdescr()
- assert isinstance(arraydescr, BaseArrayDescr)
- ofs = arraydescr.get_ofs_length(self.cpu.translate_support_code)
+ assert isinstance(arraydescr, ArrayDescr)
+ ofs = arraydescr.lendescr.offset
arg = op.getarg(0)
- base_loc, base_box = self._ensure_value_is_boxed(arg)
- self.possibly_free_vars([arg, base_box])
-
+ base_loc = self._ensure_value_is_boxed(arg)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
res = self.force_allocate_reg(op.result)
- self.possibly_free_var(op.result)
return [res, base_loc, imm(ofs)]
def prepare_op_setarrayitem_gc(self, op, fcond):
- a0, a1, a2 = boxes = list(op.getarglist())
- _, scale, base_ofs, _, ptr = self._unpack_arraydescr(op.getdescr())
-
- base_loc, base_box = self._ensure_value_is_boxed(a0, boxes)
- boxes.append(base_box)
- ofs_loc, ofs_box = self._ensure_value_is_boxed(a1, boxes)
- boxes.append(ofs_box)
- value_loc, value_box = self._ensure_value_is_boxed(a2, boxes)
- boxes.append(value_box)
- self.possibly_free_vars(boxes)
- assert _check_imm_arg(ConstInt(base_ofs))
- return [value_loc, base_loc, ofs_loc, imm(scale), imm(base_ofs)]
+ a0, a1, a2 = list(op.getarglist())
+ size, ofs, _ = unpack_arraydescr(op.getdescr())
+ scale = get_scale(size)
+ args = op.getarglist()
+ base_loc = self._ensure_value_is_boxed(a0, args)
+ ofs_loc = self._ensure_value_is_boxed(a1, args)
+ value_loc = self._ensure_value_is_boxed(a2, args)
+ assert check_imm_arg(ofs)
+ return [value_loc, base_loc, ofs_loc, imm(scale), imm(ofs)]
prepare_op_setarrayitem_raw = prepare_op_setarrayitem_gc
def prepare_op_getarrayitem_gc(self, op, fcond):
a0, a1 = boxes = list(op.getarglist())
- _, scale, base_ofs, _, ptr = self._unpack_arraydescr(op.getdescr())
-
- base_loc, base_box = self._ensure_value_is_boxed(a0, boxes)
- boxes.append(base_box)
- ofs_loc, ofs_box = self._ensure_value_is_boxed(a1, boxes)
- boxes.append(ofs_box)
- self.possibly_free_vars(boxes)
+ size, ofs, _ = unpack_arraydescr(op.getdescr())
+ scale = get_scale(size)
+ base_loc = self._ensure_value_is_boxed(a0, boxes)
+ ofs_loc = self._ensure_value_is_boxed(a1, boxes)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
res = self.force_allocate_reg(op.result)
- self.possibly_free_var(op.result)
- assert _check_imm_arg(ConstInt(base_ofs))
- return [res, base_loc, ofs_loc, imm(scale), imm(base_ofs)]
+ assert check_imm_arg(ofs)
+ return [res, base_loc, ofs_loc, imm(scale), imm(ofs)]
prepare_op_getarrayitem_raw = prepare_op_getarrayitem_gc
prepare_op_getarrayitem_gc_pure = prepare_op_getarrayitem_gc
def prepare_op_strlen(self, op, fcond):
- l0, box = self._ensure_value_is_boxed(op.getarg(0))
- boxes = [box]
-
-
+ args = op.getarglist()
+ l0 = self._ensure_value_is_boxed(op.getarg(0))
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
self.cpu.translate_support_code)
- ofs_box = ConstInt(ofs_length)
- imm_ofs = _check_imm_arg(ofs_box)
+ immofs = imm(ofs_length)
+ if check_imm_arg(ofs_length):
+ l1 = immofs
+ else:
+ l1 = self.get_scratch_reg(INT, args)
+ self.assembler.load(l1, immofs)
- if imm_ofs:
- l1 = self.make_sure_var_in_reg(ofs_box, boxes)
- else:
- l1, box1 = self._ensure_value_is_boxed(ofs_box, boxes)
- boxes.append(box1)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
- self.possibly_free_vars(boxes)
res = self.force_allocate_reg(op.result)
self.possibly_free_var(op.result)
return [l0, l1, res]
def prepare_op_strgetitem(self, op, fcond):
boxes = list(op.getarglist())
- base_loc, box = self._ensure_value_is_boxed(boxes[0])
- boxes.append(box)
+ base_loc = self._ensure_value_is_boxed(boxes[0])
a1 = boxes[1]
- imm_a1 = _check_imm_arg(a1)
+ imm_a1 = check_imm_box(a1)
if imm_a1:
ofs_loc = self.make_sure_var_in_reg(a1, boxes)
else:
- ofs_loc, box = self._ensure_value_is_boxed(a1, boxes)
- boxes.append(box)
+ ofs_loc = self._ensure_value_is_boxed(a1, boxes)
- self.possibly_free_vars(boxes)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
res = self.force_allocate_reg(op.result)
- self.possibly_free_var(op.result)
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
self.cpu.translate_support_code)
@@ -787,18 +874,9 @@
def prepare_op_strsetitem(self, op, fcond):
boxes = list(op.getarglist())
-
- base_loc, box = self._ensure_value_is_boxed(boxes[0], boxes)
- boxes.append(box)
-
- ofs_loc, box = self._ensure_value_is_boxed(boxes[1], boxes)
- boxes.append(box)
-
- value_loc, box = self._ensure_value_is_boxed(boxes[2], boxes)
- boxes.append(box)
-
- self.possibly_free_vars(boxes)
-
+ base_loc = self._ensure_value_is_boxed(boxes[0], boxes)
+ ofs_loc = self._ensure_value_is_boxed(boxes[1], boxes)
+ value_loc = self._ensure_value_is_boxed(boxes[2], boxes)
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
self.cpu.translate_support_code)
assert itemsize == 1
@@ -808,156 +886,86 @@
prepare_op_copyunicodecontent = void
def prepare_op_unicodelen(self, op, fcond):
- l0, box = self._ensure_value_is_boxed(op.getarg(0))
- boxes = [box]
+ l0 = self._ensure_value_is_boxed(op.getarg(0))
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
self.cpu.translate_support_code)
- ofs_box = ConstInt(ofs_length)
- imm_ofs = _check_imm_arg(ofs_box)
+ immofs = imm(ofs_length)
+ if check_imm_arg(ofs_length):
+ l1 = immofs
+ else:
+ l1 = self.get_scratch_reg(INT, [op.getarg(0)])
+ self.assembler.load(l1, immofs)
- if imm_ofs:
- l1 = imm(ofs_length)
- else:
- l1, box1 = self._ensure_value_is_boxed(ofs_box, boxes)
- boxes.append(box1)
-
- self.possibly_free_vars(boxes)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
res = self.force_allocate_reg(op.result)
- self.possibly_free_var(op.result)
return [l0, l1, res]
def prepare_op_unicodegetitem(self, op, fcond):
boxes = list(op.getarglist())
- base_loc, box = self._ensure_value_is_boxed(boxes[0], boxes)
- boxes.append(box)
- ofs_loc, box = self._ensure_value_is_boxed(boxes[1], boxes)
- boxes.append(box)
- self.possibly_free_vars(boxes)
+ base_loc = self._ensure_value_is_boxed(boxes[0], boxes)
+ ofs_loc = self._ensure_value_is_boxed(boxes[1], boxes)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
res = self.force_allocate_reg(op.result)
- self.possibly_free_var(op.result)
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
self.cpu.translate_support_code)
- scale = itemsize/2
- return [res, base_loc, ofs_loc, imm(scale), imm(basesize), imm(itemsize)]
+ scale = itemsize / 2
+ return [res, base_loc, ofs_loc,
+ imm(scale), imm(basesize), imm(itemsize)]
def prepare_op_unicodesetitem(self, op, fcond):
boxes = list(op.getarglist())
- base_loc, box = self._ensure_value_is_boxed(boxes[0], boxes)
- boxes.append(box)
- ofs_loc, box = self._ensure_value_is_boxed(boxes[1], boxes)
- boxes.append(box)
- value_loc, box = self._ensure_value_is_boxed(boxes[2], boxes)
- boxes.append(box)
-
- self.possibly_free_vars(boxes)
-
+ base_loc = self._ensure_value_is_boxed(boxes[0], boxes)
+ ofs_loc = self._ensure_value_is_boxed(boxes[1], boxes)
+ value_loc = self._ensure_value_is_boxed(boxes[2], boxes)
basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
self.cpu.translate_support_code)
- scale = itemsize/2
- return [value_loc, base_loc, ofs_loc, imm(scale), imm(basesize), imm(itemsize)]
+ scale = itemsize / 2
+ return [value_loc, base_loc, ofs_loc,
+ imm(scale), imm(basesize), imm(itemsize)]
def prepare_op_same_as(self, op, fcond):
arg = op.getarg(0)
- imm_arg = _check_imm_arg(arg)
+ imm_arg = check_imm_box(arg)
if imm_arg:
argloc = self.make_sure_var_in_reg(arg)
else:
- argloc, box = self._ensure_value_is_boxed(arg)
- self.possibly_free_var(box)
+ argloc = self._ensure_value_is_boxed(arg)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
+ resloc = self.force_allocate_reg(op.result)
+ return [argloc, resloc]
- resloc = self.force_allocate_reg(op.result)
- self.possibly_free_var(op.result)
- return [argloc, resloc]
prepare_op_cast_ptr_to_int = prepare_op_same_as
prepare_op_cast_int_to_ptr = prepare_op_same_as
- def prepare_op_new(self, op, fcond):
- gc_ll_descr = self.assembler.cpu.gc_ll_descr
- if gc_ll_descr.can_inline_malloc(op.getdescr()):
- self.fastpath_malloc_fixedsize(op, op.getdescr())
- else:
- arglocs = self._prepare_args_for_new_op(op.getdescr())
- force_index = self.assembler.write_new_force_index()
- self.assembler._emit_call(force_index, self.assembler.malloc_func_addr,
- arglocs, self, fcond, result=op.result)
- self.possibly_free_vars(arglocs)
- self.possibly_free_var(op.result)
- return []
+ def prepare_op_call_malloc_nursery(self, op, fcond):
+ size_box = op.getarg(0)
+ assert isinstance(size_box, ConstInt)
+ size = size_box.getint()
- def prepare_op_new_with_vtable(self, op, fcond):
- classint = op.getarg(0).getint()
- descrsize = heaptracker.vtable2descr(self.cpu, classint)
- if self.assembler.cpu.gc_ll_descr.can_inline_malloc(descrsize):
- self.fastpath_malloc_fixedsize(op, descrsize)
- else:
- callargs = self._prepare_args_for_new_op(descrsize)
- force_index = self.assembler.write_new_force_index()
- self.assembler._emit_call(force_index, self.assembler.malloc_func_addr,
- callargs, self, fcond, result=op.result)
- self.possibly_free_vars(callargs)
- self.possibly_free_var(op.result)
- return [imm(classint)]
-
- def prepare_op_new_array(self, op, fcond):
- gc_ll_descr = self.cpu.gc_ll_descr
- if gc_ll_descr.get_funcptr_for_newarray is not None:
- # framework GC
- box_num_elem = op.getarg(0)
- if isinstance(box_num_elem, ConstInt):
- num_elem = box_num_elem.value
- if gc_ll_descr.can_inline_malloc_varsize(op.getdescr(),
- num_elem):
- self.fastpath_malloc_varsize(op, op.getdescr(), num_elem)
- return []
- args = self.assembler.cpu.gc_ll_descr.args_for_new_array(
- op.getdescr())
- argboxes = [ConstInt(x) for x in args]
- argboxes.append(box_num_elem)
- force_index = self.assembler.write_new_force_index()
- self.assembler._emit_call(force_index, self.assembler.malloc_array_func_addr,
- argboxes, self, fcond, result=op.result)
- return []
- # boehm GC
- itemsize, scale, basesize, ofs_length, _ = (
- self._unpack_arraydescr(op.getdescr()))
- return self._malloc_varsize(basesize, ofs_length, itemsize, op)
-
- def fastpath_malloc_varsize(self, op, arraydescr, num_elem):
- assert isinstance(arraydescr, BaseArrayDescr)
- ofs_length = arraydescr.get_ofs_length(self.cpu.translate_support_code)
- basesize = arraydescr.get_base_size(self.cpu.translate_support_code)
- itemsize = arraydescr.get_item_size(self.cpu.translate_support_code)
- size = basesize + itemsize * num_elem
- self._do_fastpath_malloc(op, size, arraydescr.tid)
- # we know the resullt of the malloc call is in r0
- self.assembler.set_new_array_length(r.r0, ofs_length, num_elem)
-
- def fastpath_malloc_fixedsize(self, op, descr):
- assert isinstance(descr, BaseSizeDescr)
- self._do_fastpath_malloc(op, descr.size, descr.tid)
-
- def _do_fastpath_malloc(self, op, size, tid):
- gc_ll_descr = self.assembler.cpu.gc_ll_descr
self.rm.force_allocate_reg(op.result, selected_reg=r.r0)
t = TempInt()
self.rm.force_allocate_reg(t, selected_reg=r.r1)
self.possibly_free_var(op.result)
self.possibly_free_var(t)
+ gc_ll_descr = self.assembler.cpu.gc_ll_descr
self.assembler.malloc_cond(
gc_ll_descr.get_nursery_free_addr(),
gc_ll_descr.get_nursery_top_addr(),
- size, tid,
+ size
)
def get_mark_gc_roots(self, gcrootmap, use_copy_area=False):
shape = gcrootmap.get_basic_shape(False)
- for v, val in self.frame_manager.frame_bindings.items():
+ for v, val in self.frame_manager.bindings.items():
if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)):
assert val.is_stack()
- gcrootmap.add_frame_offset(shape, val.position*-WORD)
+ gcrootmap.add_frame_offset(shape, val.position * -WORD)
for v, reg in self.rm.reg_bindings.items():
if reg is r.r0:
continue
@@ -970,59 +978,6 @@
assert 0, 'sure??'
return gcrootmap.compress_callshape(shape,
self.assembler.datablockwrapper)
- def prepare_op_newstr(self, op, fcond):
- gc_ll_descr = self.cpu.gc_ll_descr
- if gc_ll_descr.get_funcptr_for_newstr is not None:
- force_index = self.assembler.write_new_force_index()
- self.assembler._emit_call(force_index,
- self.assembler.malloc_str_func_addr, [op.getarg(0)],
- self, fcond, op.result)
- return []
- # boehm GC
- ofs_items, itemsize, ofs = symbolic.get_array_token(rstr.STR,
- self.cpu.translate_support_code)
- assert itemsize == 1
- return self._malloc_varsize(ofs_items, ofs, itemsize, op)
-
- def prepare_op_newunicode(self, op, fcond):
- gc_ll_descr = self.cpu.gc_ll_descr
- if gc_ll_descr.get_funcptr_for_newunicode is not None:
- force_index = self.assembler.write_new_force_index()
- self.assembler._emit_call(force_index, self.assembler.malloc_unicode_func_addr,
- [op.getarg(0)], self, fcond, op.result)
- return []
- # boehm GC
- ofs_items, _, ofs = symbolic.get_array_token(rstr.UNICODE,
- self.cpu.translate_support_code)
- _, itemsize, _ = symbolic.get_array_token(rstr.UNICODE,
- self.cpu.translate_support_code)
- return self._malloc_varsize(ofs_items, ofs, itemsize, op)
-
- def _malloc_varsize(self, ofs_items, ofs_length, itemsize, op):
- v = op.getarg(0)
- res_v = op.result
- boxes = [v, res_v]
- itemsize_box = ConstInt(itemsize)
- ofs_items_box = ConstInt(ofs_items)
- if _check_imm_arg(ofs_items_box):
- ofs_items_loc = self.convert_to_imm(ofs_items_box)
- else:
- ofs_items_loc, ofs_items_box = self._ensure_value_is_boxed(ofs_items_box, boxes)
- boxes.append(ofs_items_box)
- vloc, vbox = self._ensure_value_is_boxed(v, [res_v])
- boxes.append(vbox)
- size, size_box = self._ensure_value_is_boxed(itemsize_box, boxes)
- boxes.append(size_box)
- self.assembler._regalloc_malloc_varsize(size, size_box,
- vloc, vbox, ofs_items_loc, self, res_v)
- base_loc = self.make_sure_var_in_reg(res_v)
-
- value_loc, vbox = self._ensure_value_is_boxed(v, [res_v])
- boxes.append(vbox)
- self.possibly_free_vars(boxes)
- assert value_loc.is_reg()
- assert base_loc.is_reg()
- return [value_loc, base_loc, imm(ofs_length)]
prepare_op_debug_merge_point = void
prepare_op_jit_debug = void
@@ -1034,12 +989,10 @@
# because it will be needed anyway by the following setfield_gc
# or setarrayitem_gc. It avoids loading it twice from the memory.
arglocs = []
- argboxes = []
+ args = op.getarglist()
for i in range(N):
- loc, box = self._ensure_value_is_boxed(op.getarg(i), argboxes)
+ loc = self._ensure_value_is_boxed(op.getarg(i), args)
arglocs.append(loc)
- argboxes.append(box)
- self.rm.possibly_free_vars(argboxes)
return arglocs
prepare_op_cond_call_gc_wb_array = prepare_op_cond_call_gc_wb
@@ -1049,6 +1002,46 @@
self.possibly_free_var(op.result)
return [res_loc]
+ def prepare_op_label(self, op, fcond):
+ # XXX big refactoring needed?
+ descr = op.getdescr()
+ assert isinstance(descr, TargetToken)
+ inputargs = op.getarglist()
+ arglocs = [None] * len(inputargs)
+ #
+ # we use force_spill() on the boxes that are not going to be really
+ # used any more in the loop, but that are kept alive anyway
+ # by being in a next LABEL's or a JUMP's argument or fail_args
+ # of some guard
+ position = self.rm.position
+ for arg in inputargs:
+ assert isinstance(arg, Box)
+ if self.last_real_usage.get(arg, -1) <= position:
+ self.force_spill_var(arg)
+
+ #
+ for i in range(len(inputargs)):
+ arg = inputargs[i]
+ assert isinstance(arg, Box)
+ loc = self.loc(arg)
+ arglocs[i] = loc
+ if loc.is_reg():
+ self.frame_manager.mark_as_free(arg)
+ #
+ descr._arm_arglocs = arglocs
+ descr._arm_loop_code = self.assembler.mc.currpos()
+ descr._arm_clt = self.assembler.current_clt
+ self.assembler.target_tokens_currently_compiling[descr] = None
+ self.possibly_free_vars_for_op(op)
+ #
+ # if the LABEL's descr is precisely the target of the JUMP at the
+ # end of the same loop, i.e. if what we are compiling is a single
+ # loop that ends up jumping to this LABEL, then we can now provide
+ # the hints about the expected position of the spilled variables.
+ jump_op = self.final_jump_op
+ if jump_op is not None and jump_op.getdescr() is descr:
+ self._compute_hint_frame_locations_from_descr(descr)
+
def prepare_guard_call_may_force(self, op, guard_op, fcond):
faildescr = guard_op.getdescr()
fail_index = self.cpu.get_fail_descr_number(faildescr)
@@ -1067,13 +1060,11 @@
gcrootmap = self.cpu.gc_ll_descr.gcrootmap
if gcrootmap:
arglocs = []
- argboxes = []
+ args = op.getarglist()
for i in range(op.numargs()):
- loc, box = self._ensure_value_is_boxed(op.getarg(i), argboxes)
+ loc = self._ensure_value_is_boxed(op.getarg(i), args)
arglocs.append(loc)
- argboxes.append(box)
self.assembler.call_release_gil(gcrootmap, arglocs, fcond)
- self.possibly_free_vars(argboxes)
# do the call
faildescr = guard_op.getdescr()
fail_index = self.cpu.get_fail_descr_number(faildescr)
@@ -1081,17 +1072,20 @@
self.assembler.emit_op_call(op, args, self, fcond, fail_index)
# then reopen the stack
if gcrootmap:
- self.assembler.call_reacquire_gil(gcrootmap, r.r0, fcond)
+ if op.result:
+ result_loc = self.call_result_location(op.result)
+ else:
+ result_loc = None
+ self.assembler.call_reacquire_gil(gcrootmap, result_loc, fcond)
locs = self._prepare_guard(guard_op)
- self.possibly_free_vars(guard_op.getfailargs())
return locs
def prepare_guard_call_assembler(self, op, guard_op, fcond):
descr = op.getdescr()
- assert isinstance(descr, LoopToken)
+ assert isinstance(descr, JitCellToken)
jd = descr.outermost_jitdriver_sd
assert jd is not None
- size = jd.portal_calldescr.get_result_size(self.cpu.translate_support_code)
+ size = jd.portal_calldescr.get_result_size()
vable_index = jd.index_of_virtualizable
if vable_index >= 0:
self._sync_var(op.getarg(vable_index))
@@ -1113,117 +1107,92 @@
arglocs.append(t)
return arglocs
- # from ../x86/regalloc.py:791
- def _unpack_fielddescr(self, fielddescr):
- assert isinstance(fielddescr, BaseFieldDescr)
- ofs = fielddescr.offset
- size = fielddescr.get_field_size(self.cpu.translate_support_code)
- ptr = fielddescr.is_pointer_field()
- return ofs, size, ptr
-
- # from ../x86/regalloc.py:779
- def _unpack_arraydescr(self, arraydescr):
- assert isinstance(arraydescr, BaseArrayDescr)
- cpu = self.cpu
- ofs_length = arraydescr.get_ofs_length(cpu.translate_support_code)
- ofs = arraydescr.get_base_size(cpu.translate_support_code)
- size = arraydescr.get_item_size(cpu.translate_support_code)
- ptr = arraydescr.is_array_of_pointers()
- scale = 0
- while (1 << scale) < size:
- scale += 1
- assert (1 << scale) == size
- return size, scale, ofs, ofs_length, ptr
-
- # from ../x86/regalloc.py:965
- def _unpack_interiorfielddescr(self, descr):
- assert isinstance(descr, InteriorFieldDescr)
- arraydescr = descr.arraydescr
- ofs = arraydescr.get_base_size(self.cpu.translate_support_code)
- itemsize = arraydescr.get_item_size(self.cpu.translate_support_code)
- fieldsize = descr.fielddescr.get_field_size(self.cpu.translate_support_code)
- sign = descr.fielddescr.is_field_signed()
- ofs += descr.fielddescr.offset
- return ofs, itemsize, fieldsize, sign
-
prepare_op_float_add = prepare_float_op(name='prepare_op_float_add')
prepare_op_float_sub = prepare_float_op(name='prepare_op_float_sub')
prepare_op_float_mul = prepare_float_op(name='prepare_op_float_mul')
- prepare_op_float_truediv = prepare_float_op(name='prepare_op_float_truediv')
- prepare_op_float_lt = prepare_float_op(float_result=False, name='prepare_op_float_lt')
- prepare_op_float_le = prepare_float_op(float_result=False, name='prepare_op_float_le')
- prepare_op_float_eq = prepare_float_op(float_result=False, name='prepare_op_float_eq')
- prepare_op_float_ne = prepare_float_op(float_result=False, name='prepare_op_float_ne')
- prepare_op_float_gt = prepare_float_op(float_result=False, name='prepare_op_float_gt')
- prepare_op_float_ge = prepare_float_op(float_result=False, name='prepare_op_float_ge')
- prepare_op_float_neg = prepare_float_op(base=False, name='prepare_op_float_neg')
- prepare_op_float_abs = prepare_float_op(base=False, name='prepare_op_float_abs')
+ prepare_op_float_truediv = prepare_float_op(
+ name='prepare_op_float_truediv')
+ prepare_op_float_lt = prepare_float_op(float_result=False,
+ name='prepare_op_float_lt')
+ prepare_op_float_le = prepare_float_op(float_result=False,
+ name='prepare_op_float_le')
+ prepare_op_float_eq = prepare_float_op(float_result=False,
+ name='prepare_op_float_eq')
+ prepare_op_float_ne = prepare_float_op(float_result=False,
+ name='prepare_op_float_ne')
+ prepare_op_float_gt = prepare_float_op(float_result=False,
+ name='prepare_op_float_gt')
+ prepare_op_float_ge = prepare_float_op(float_result=False,
+ name='prepare_op_float_ge')
+ prepare_op_float_neg = prepare_float_op(base=False,
+ name='prepare_op_float_neg')
+ prepare_op_float_abs = prepare_float_op(base=False,
+ name='prepare_op_float_abs')
- prepare_guard_float_lt = prepare_float_op(guard=True, float_result=False, name='prepare_guard_float_lt')
- prepare_guard_float_le = prepare_float_op(guard=True, float_result=False, name='prepare_guard_float_le')
- prepare_guard_float_eq = prepare_float_op(guard=True, float_result=False, name='prepare_guard_float_eq')
- prepare_guard_float_ne = prepare_float_op(guard=True, float_result=False, name='prepare_guard_float_ne')
- prepare_guard_float_gt = prepare_float_op(guard=True, float_result=False, name='prepare_guard_float_gt')
- prepare_guard_float_ge = prepare_float_op(guard=True, float_result=False, name='prepare_guard_float_ge')
+ prepare_guard_float_lt = prepare_float_op(guard=True,
+ float_result=False, name='prepare_guard_float_lt')
+ prepare_guard_float_le = prepare_float_op(guard=True,
+ float_result=False, name='prepare_guard_float_le')
+ prepare_guard_float_eq = prepare_float_op(guard=True,
+ float_result=False, name='prepare_guard_float_eq')
+ prepare_guard_float_ne = prepare_float_op(guard=True,
+ float_result=False, name='prepare_guard_float_ne')
+ prepare_guard_float_gt = prepare_float_op(guard=True,
+ float_result=False, name='prepare_guard_float_gt')
+ prepare_guard_float_ge = prepare_float_op(guard=True,
+ float_result=False, name='prepare_guard_float_ge')
def prepare_op_math_sqrt(self, op, fcond):
- loc, box = self._ensure_value_is_boxed(op.getarg(1))
- self.possibly_free_var(box)
+ loc = self._ensure_value_is_boxed(op.getarg(1))
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
res = self.vfprm.force_allocate_reg(op.result)
self.possibly_free_var(op.result)
return [loc, res]
def prepare_op_cast_float_to_int(self, op, fcond):
- locs = []
-
- loc1, box1 = self._ensure_value_is_boxed(op.getarg(0))
- locs.append(loc1)
- self.possibly_free_var(box1)
-
- t = TempFloat()
- temp_loc = self.vfprm.force_allocate_reg(t)
- locs.append(temp_loc)
- self.possibly_free_var(t)
-
- res = self.rm.force_allocate_reg(op.result)
- self.possibly_free_var(op.result)
- locs.append(res)
-
- return locs
+ loc1 = self._ensure_value_is_boxed(op.getarg(0))
+ temp_loc = self.get_scratch_reg(FLOAT)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
+ res = self.rm.force_allocate_reg(op.result)
+ return [loc1, temp_loc, res]
def prepare_op_cast_int_to_float(self, op, fcond):
- locs = []
-
- loc1, box1 = self._ensure_value_is_boxed(op.getarg(0))
- locs.append(loc1)
- self.possibly_free_var(box1)
-
- t = TempFloat()
- temp_loc = self.vfprm.force_allocate_reg(t)
- locs.append(temp_loc)
- self.possibly_free_var(t)
-
- res = self.vfprm.force_allocate_reg(op.result)
- self.possibly_free_var(op.result)
- locs.append(res)
-
- return locs
+ loc1 = self._ensure_value_is_boxed(op.getarg(0))
+ temp_loc = self.get_scratch_reg(FLOAT)
+ self.possibly_free_vars_for_op(op)
+ self.free_temp_vars()
+ res = self.vfprm.force_allocate_reg(op.result)
+ return [loc1, temp_loc, res]
def prepare_force_spill(self, op, fcond):
self.force_spill_var(op.getarg(0))
return []
+
def add_none_argument(fn):
return lambda self, op, fcond: fn(self, op, None, fcond)
+
def notimplemented(self, op, fcond):
- raise NotImplementedError, op
+ raise NotImplementedError(op)
+
+
def notimplemented_with_guard(self, op, guard_op, fcond):
- raise NotImplementedError, op
+ raise NotImplementedError(op)
operations = [notimplemented] * (rop._LAST + 1)
operations_with_guard = [notimplemented_with_guard] * (rop._LAST + 1)
+
+def get_scale(size):
+ scale = 0
+ while (1 << scale) < size:
+ scale += 1
+ assert (1 << scale) == size
+ return scale
+
for key, value in rop.__dict__.items():
key = key.lower()
if key.startswith('_'):
diff --git a/pypy/jit/backend/arm/registers.py b/pypy/jit/backend/arm/registers.py
--- a/pypy/jit/backend/arm/registers.py
+++ b/pypy/jit/backend/arm/registers.py
@@ -1,11 +1,14 @@
-from pypy.jit.backend.arm.locations import RegisterLocation, VFPRegisterLocation
+from pypy.jit.backend.arm.locations import VFPRegisterLocation
+from pypy.jit.backend.arm.locations import RegisterLocation
registers = [RegisterLocation(i) for i in range(16)]
vfpregisters = [VFPRegisterLocation(i) for i in range(16)]
-r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15 = registers
+[r0, r1, r2, r3, r4, r5, r6, r7,
+ r8, r9, r10, r11, r12, r13, r14, r15] = registers
#vfp registers interpreted as 64-bit registers
-d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15 = vfpregisters
+[d0, d1, d2, d3, d4, d5, d6, d7,
+ d8, d9, d10, d11, d12, d13, d14, d15] = vfpregisters
# aliases for registers
fp = r11
@@ -18,13 +21,12 @@
all_regs = [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10]
all_vfp_regs = vfpregisters[:-1]
-caller_resp = [r0, r1, r2, r3]
+argument_regs = caller_resp = [r0, r1, r2, r3]
callee_resp = [r4, r5, r6, r7, r8, r9, r10, fp]
-callee_saved_registers = callee_resp+[lr]
-callee_restored_registers = callee_resp+[pc]
+callee_saved_registers = callee_resp + [lr]
+callee_restored_registers = callee_resp + [pc]
caller_vfp_resp = [d0, d1, d2, d3, d4, d5, d6, d7]
callee_vfp_resp = [d8, d9, d10, d11, d12, d13, d14, d15]
callee_saved_vfp_registers = callee_vfp_resp
-
diff --git a/pypy/jit/backend/arm/runner.py b/pypy/jit/backend/arm/runner.py
--- a/pypy/jit/backend/arm/runner.py
+++ b/pypy/jit/backend/arm/runner.py
@@ -9,21 +9,24 @@
class ArmCPU(AbstractLLCPU):
- BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed)
supports_floats = True
def __init__(self, rtyper, stats, opts=None, translate_support_code=False,
gcdescr=None):
if gcdescr is not None:
gcdescr.force_index_ofs = FORCE_INDEX_OFS
+ # XXX for now the arm backend does not support the gcremovetypeptr
+ # translation option
+ assert gcdescr.config.translation.gcremovetypeptr is False
AbstractLLCPU.__init__(self, rtyper, stats, opts,
translate_support_code, gcdescr)
+
def setup(self):
if self.opts is not None:
failargs_limit = self.opts.failargs_limit
else:
failargs_limit = 1000
- self.assembler = AssemblerARM(self)
+ self.assembler = AssemblerARM(self, failargs_limit=failargs_limit)
def setup_once(self):
self.assembler.setup_once()
@@ -31,7 +34,8 @@
def finish_once(self):
pass
- def compile_loop(self, inputargs, operations, looptoken, log=True, name=''):
+ def compile_loop(self, inputargs, operations, looptoken,
+ log=True, name=''):
self.assembler.assemble_loop(inputargs, operations,
looptoken, log=log)
@@ -42,15 +46,6 @@
self.assembler.assemble_bridge(faildescr, inputargs, operations,
original_loop_token, log=log)
- def set_future_value_float(self, index, floatvalue):
- self.assembler.fail_boxes_float.setitem(index, floatvalue)
-
- def set_future_value_int(self, index, intvalue):
- self.assembler.fail_boxes_int.setitem(index, intvalue)
-
- def set_future_value_ref(self, index, ptrvalue):
- self.assembler.fail_boxes_ptr.setitem(index, ptrvalue)
-
def get_latest_value_float(self, index):
return self.assembler.fail_boxes_float.getitem(index)
@@ -63,9 +58,6 @@
def get_latest_value_count(self):
return self.assembler.fail_boxes_count
- def get_latest_value_count(self):
- return self.assembler.fail_boxes_count
-
def get_latest_force_token(self):
return self.assembler.fail_force_index
@@ -78,27 +70,29 @@
for index in range(count):
setitem(index, null)
- def execute_token(self, executable_token):
- #i = [self.get_latest_value_int(x) for x in range(10)]
- #print 'Inputargs: %r for token %r' % (i, executable_token)
- addr = executable_token._arm_bootstrap_code
- assert addr % 8 == 0
- func = rffi.cast(lltype.Ptr(self.BOOTSTRAP_TP), addr)
- fail_index = self._execute_call(func)
- return self.get_fail_descr_from_number(fail_index)
+ def make_execute_token(self, *ARGS):
+ FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, lltype.Signed))
- def _execute_call(self, func):
- prev_interpreter = None
- if not self.translate_support_code:
- prev_interpreter = LLInterpreter.current_interpreter
- LLInterpreter.current_interpreter = self.debug_ll_interpreter
- res = 0
- try:
- res = func()
- finally:
+ def execute_token(executable_token, *args):
+ clt = executable_token.compiled_loop_token
+ assert len(args) == clt._debug_nbargs
+ #
+ addr = executable_token._arm_func_addr
+ assert addr % 8 == 0
+ func = rffi.cast(FUNCPTR, addr)
+ #llop.debug_print(lltype.Void, ">>>> Entering", addr)
+ prev_interpreter = None # help flow space
if not self.translate_support_code:
- LLInterpreter.current_interpreter = prev_interpreter
- return res
+ prev_interpreter = LLInterpreter.current_interpreter
+ LLInterpreter.current_interpreter = self.debug_ll_interpreter
+ try:
+ fail_index = func(*args)
+ finally:
+ if not self.translate_support_code:
+ LLInterpreter.current_interpreter = prev_interpreter
+ #llop.debug_print(lltype.Void, "<<<< Back")
+ return self.get_fail_descr_from_number(fail_index)
+ return execute_token
def cast_ptr_to_int(x):
adr = llmemory.cast_ptr_to_adr(x)
@@ -111,13 +105,13 @@
fail_index = rffi.cast(TP, addr_of_force_index)[0]
assert fail_index >= 0, "already forced!"
faildescr = self.get_fail_descr_from_number(fail_index)
- rffi.cast(TP, addr_of_force_index)[0] = -1
+ rffi.cast(TP, addr_of_force_index)[0] = ~fail_index
# start of "no gc operation!" block
- frame_depth = faildescr._arm_frame_depth*WORD
+ frame_depth = faildescr._arm_current_frame_depth * WORD
addr_end_of_frame = (addr_of_force_index -
(frame_depth +
- len(all_regs)*WORD +
- len(all_vfp_regs)*2*WORD))
+ len(all_regs) * WORD +
+ len(all_vfp_regs) * 2 * WORD))
fail_index_2 = self.assembler.failure_recovery_func(
faildescr._failure_recovery_code,
addr_of_force_index,
diff --git a/pypy/jit/backend/arm/shift.py b/pypy/jit/backend/arm/shift.py
--- a/pypy/jit/backend/arm/shift.py
+++ b/pypy/jit/backend/arm/shift.py
@@ -3,4 +3,4 @@
LSR = 0x1
ASR = 0x2
ROR = 0x3
-RRX = 0x3 # with imm = 0
+RRX = 0x3 # with imm = 0
diff --git a/pypy/jit/backend/arm/test/test_assembler.py b/pypy/jit/backend/arm/test/test_assembler.py
--- a/pypy/jit/backend/arm/test/test_assembler.py
+++ b/pypy/jit/backend/arm/test/test_assembler.py
@@ -1,8 +1,6 @@
-from pypy.jit.backend.arm import arch
from pypy.jit.backend.arm import conditions as c
from pypy.jit.backend.arm import registers as r
-from pypy.jit.backend.arm.arch import WORD
-from pypy.jit.backend.arm.arch import arm_int_div, arm_int_div_sign
+from pypy.jit.backend.arm.arch import arm_int_div
from pypy.jit.backend.arm.assembler import AssemblerARM
from pypy.jit.backend.arm.locations import imm
from pypy.jit.backend.arm.test.support import skip_unless_arm, run_asm
@@ -10,21 +8,21 @@
from pypy.jit.metainterp.resoperation import rop
from pypy.rpython.annlowlevel import llhelper
-from pypy.rpython.lltypesystem import lltype, rffi, llmemory
-from pypy.jit.metainterp.history import LoopToken
+from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.jit.metainterp.history import JitCellToken
from pypy.jit.backend.model import CompiledLoopToken
skip_unless_arm()
CPU = getcpuclass()
+
+
class TestRunningAssembler(object):
def setup_method(self, method):
cpu = CPU(None, None)
- #lp = LoopToken()
- #lp.compiled_loop_token = CompiledLoopToken(cpu, None)
self.a = AssemblerARM(cpu)
self.a.setup_once()
- token = LoopToken()
+ token = JitCellToken()
clt = CompiledLoopToken(cpu, 0)
clt.allgcrefs = []
token.compiled_loop_token = clt
@@ -33,7 +31,8 @@
def test_make_operation_list(self):
i = rop.INT_ADD
from pypy.jit.backend.arm import assembler
- assert assembler.asm_operations[i] is AssemblerARM.emit_op_int_add.im_func
+ assert assembler.asm_operations[i] \
+ is AssemblerARM.emit_op_int_add.im_func
def test_load_small_int_to_reg(self):
self.a.gen_func_prolog()
@@ -77,7 +76,6 @@
self.a.gen_func_epilog()
assert run_asm(self.a) == 464
-
def test_or(self):
self.a.gen_func_prolog()
self.a.mc.MOV_ri(r.r1.value, 8)
@@ -115,7 +113,7 @@
self.a.gen_func_prolog()
self.a.mc.MOV_ri(r.r1.value, 1)
loop_head = self.a.mc.currpos()
- self.a.mc.CMP_ri(r.r1.value, 0) # z=0, z=1
+ self.a.mc.CMP_ri(r.r1.value, 0) # z=0, z=1
self.a.mc.MOV_ri(r.r1.value, 0, cond=c.NE)
self.a.mc.MOV_ri(r.r1.value, 7, cond=c.EQ)
self.a.mc.B_offs(loop_head, c.NE)
@@ -143,7 +141,8 @@
self.a.mc.MOV_ri(r.r0.value, 123, cond=c.NE)
for x in range(15):
- self.a.mc.POP([reg.value for reg in r.callee_restored_registers], cond=c.NE)
+ self.a.mc.POP(
+ [reg.value for reg in r.callee_restored_registers], cond=c.NE)
self.a.mc.MOV_ri(r.r1.value, 33)
self.a.mc.MOV_ri(r.r0.value, 23)
@@ -160,7 +159,8 @@
self.a.mc.MOV_ri(r.r0.value, 123, cond=c.NE)
for x in range(100):
- self.a.mc.POP([reg.value for reg in r.callee_restored_registers], cond=c.NE)
+ self.a.mc.POP(
+ [reg.value for reg in r.callee_restored_registers], cond=c.NE)
self.a.mc.MOV_ri(r.r1.value, 33)
self.a.mc.MOV_ri(r.r0.value, 23)
@@ -216,7 +216,6 @@
self.a.gen_func_epilog()
assert run_asm(self.a) == -36
-
def test_bl_with_conditional_exec(self):
functype = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
call_addr = rffi.cast(lltype.Signed, llhelper(functype, callme))
@@ -240,7 +239,7 @@
assert run_asm(self.a) == 2478
def test_load_store(self):
- x = 0x60002224
+ x = 0x60002224
self.a.gen_func_prolog()
self.a.mc.gen_load_int(r.r1.value, x)
self.a.mc.MOV_ri(r.r3.value, 8)
@@ -249,7 +248,7 @@
self.a.gen_func_epilog()
assert run_asm(self.a) == x
+
def callme(inp):
i = inp + 10
return i
-
diff --git a/pypy/jit/backend/arm/test/test_calling_convention.py b/pypy/jit/backend/arm/test/test_calling_convention.py
--- a/pypy/jit/backend/arm/test/test_calling_convention.py
+++ b/pypy/jit/backend/arm/test/test_calling_convention.py
@@ -1,13 +1,15 @@
from pypy.rpython.annlowlevel import llhelper
-from pypy.jit.metainterp.history import LoopToken
+from pypy.jit.metainterp.history import JitCellToken
from pypy.jit.backend.test.calling_convention_test import TestCallingConv, parse
from pypy.rpython.lltypesystem import lltype
from pypy.jit.codewriter.effectinfo import EffectInfo
from pypy.jit.backend.arm.test.support import skip_unless_arm
skip_unless_arm()
-# ../../test/calling_convention_test.py
+
class TestARMCallingConvention(TestCallingConv):
+ # ../../test/calling_convention_test.py
+
def test_call_argument_spilling(self):
# bug when we have a value in r0, that is overwritten by an argument
# and needed after the call, so that the register gets spilled after it
@@ -28,11 +30,10 @@
i99 = call(ConstClass(func_ptr), 22, descr=calldescr)
finish(%s, i99)""" % (args, args)
loop = parse(ops, namespace=locals())
- looptoken = LoopToken()
+ looptoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
- for x in range(11):
- self.cpu.set_future_value_int(x, x)
- self.cpu.execute_token(looptoken)
+ args = [x for x in range(11)]
+ self.cpu.execute_token(looptoken, *args)
for x in range(11):
assert self.cpu.get_latest_value_int(x) == x
assert self.cpu.get_latest_value_int(11) == 38
diff --git a/pypy/jit/backend/arm/test/test_gc_integration.py b/pypy/jit/backend/arm/test/test_gc_integration.py
--- a/pypy/jit/backend/arm/test/test_gc_integration.py
+++ b/pypy/jit/backend/arm/test/test_gc_integration.py
@@ -3,63 +3,74 @@
"""
import py
-from pypy.jit.metainterp.history import BoxInt, ConstInt,\
- BoxPtr, ConstPtr, TreeLoop
+from pypy.jit.metainterp.history import BoxInt, \
+ BoxPtr, TreeLoop, TargetToken
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.codewriter import heaptracker
from pypy.jit.backend.llsupport.descr import GcCache
from pypy.jit.backend.llsupport.gc import GcLLDescription
from pypy.jit.backend.detect_cpu import getcpuclass
-from pypy.jit.backend.arm.regalloc import Regalloc
from pypy.jit.backend.arm.arch import WORD
-from pypy.jit.tool.oparser import parse
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
from pypy.rpython.annlowlevel import llhelper
-from pypy.rpython.lltypesystem import rclass, rstr
-from pypy.jit.backend.llsupport.gc import GcLLDescr_framework, GcPtrFieldDescr
+from pypy.rpython.lltypesystem import rclass
+from pypy.jit.backend.llsupport.gc import GcLLDescr_framework
from pypy.jit.backend.arm.test.test_regalloc import MockAssembler
from pypy.jit.backend.arm.test.test_regalloc import BaseTestRegalloc
-from pypy.jit.backend.arm.regalloc import ARMv7RegisterMananger, ARMFrameManager,\
- VFPRegisterManager
+from pypy.jit.backend.arm.regalloc import ARMFrameManager, VFPRegisterManager
from pypy.jit.codewriter.effectinfo import EffectInfo
from pypy.jit.backend.arm.test.support import skip_unless_arm
+from pypy.jit.backend.arm.regalloc import Regalloc, ARMv7RegisterManager
skip_unless_arm()
CPU = getcpuclass()
+
class MockGcRootMap(object):
is_shadow_stack = False
+
def get_basic_shape(self, is_64_bit):
return ['shape']
+
def add_frame_offset(self, shape, offset):
shape.append(offset)
+
def add_callee_save_reg(self, shape, reg_index):
- index_to_name = { 1: 'ebx', 2: 'esi', 3: 'edi' }
+ index_to_name = {1: 'ebx', 2: 'esi', 3: 'edi'}
shape.append(index_to_name[reg_index])
+
def compress_callshape(self, shape, datablockwrapper):
assert datablockwrapper == 'fakedatablockwrapper'
assert shape[0] == 'shape'
return ['compressed'] + shape[1:]
+
class MockGcRootMap2(object):
is_shadow_stack = False
+
def get_basic_shape(self, is_64_bit):
return ['shape']
+
def add_frame_offset(self, shape, offset):
shape.append(offset)
+
def add_callee_save_reg(self, shape, reg_index):
- index_to_name = { 1: 'ebx', 2: 'esi', 3: 'edi' }
+ index_to_name = {1: 'ebx', 2: 'esi', 3: 'edi'}
shape.append(index_to_name[reg_index])
+
def compress_callshape(self, shape, datablockwrapper):
assert datablockwrapper == 'fakedatablockwrapper'
assert shape[0] == 'shape'
return ['compressed'] + shape[1:]
+
class MockGcDescr(GcCache):
is_shadow_stack = False
+
def get_funcptr_for_new(self):
return 123
+
get_funcptr_for_newarray = get_funcptr_for_new
get_funcptr_for_newstr = get_funcptr_for_new
get_funcptr_for_newunicode = get_funcptr_for_new
@@ -74,13 +85,14 @@
record_constptrs = GcLLDescr_framework.record_constptrs.im_func
rewrite_assembler = GcLLDescr_framework.rewrite_assembler.im_func
+
class TestRegallocDirectGcIntegration(object):
def test_mark_gc_roots(self):
py.test.skip('roots')
cpu = CPU(None, None)
cpu.setup_once()
- regalloc = RegAlloc(MockAssembler(cpu, MockGcDescr(False)))
+ regalloc = Regalloc(MockAssembler(cpu, MockGcDescr(False)))
regalloc.assembler.datablockwrapper = 'fakedatablockwrapper'
boxes = [BoxPtr() for i in range(len(ARMv7RegisterManager.all_regs))]
longevity = {}
@@ -95,7 +107,8 @@
for box in boxes:
regalloc.rm.try_allocate_reg(box)
TP = lltype.FuncType([], lltype.Signed)
- calldescr = cpu.calldescrof(TP, TP.ARGS, TP.RESULT, EffectInfo.MOST_GENERAL)
+ calldescr = cpu.calldescrof(TP, TP.ARGS, TP.RESULT,
+ EffectInfo.MOST_GENERAL)
regalloc.rm._check_invariants()
box = boxes[0]
regalloc.position = 0
@@ -129,6 +142,7 @@
descr0 = cpu.fielddescrof(S, 'int')
ptr0 = struct_ref
+ targettoken = TargetToken()
namespace = locals().copy()
@@ -153,6 +167,7 @@
def test_bug_0(self):
ops = '''
[i0, i1, i2, i3, i4, i5, i6, i7, i8]
+ label(i0, i1, i2, i3, i4, i5, i6, i7, i8, descr=targettoken)
guard_value(i2, 1) [i2, i3, i4, i5, i6, i7, i0, i1, i8]
guard_class(i4, 138998336) [i4, i5, i6, i7, i0, i1, i8]
i11 = getfield_gc(i4, descr=descr0)
@@ -180,7 +195,7 @@
guard_false(i32) [i4, i6, i7, i0, i1, i24]
i33 = getfield_gc(i0, descr=descr0)
guard_value(i33, ConstPtr(ptr0)) [i4, i6, i7, i0, i1, i33, i24]
- jump(i0, i1, 1, 17, i4, ConstPtr(ptr0), i6, i7, i24)
+ jump(i0, i1, 1, 17, i4, ConstPtr(ptr0), i6, i7, i24, descr=targettoken)
'''
self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0, 0], run=False)
@@ -322,17 +337,22 @@
class Seen(Exception):
pass
+
class GCDescrFastpathMallocVarsize(GCDescrFastpathMalloc):
def can_inline_malloc_varsize(self, arraydescr, num_elem):
return num_elem < 5
+
def get_funcptr_for_newarray(self):
return 52
+
def init_array_descr(self, A, descr):
descr.tid = self._counter
self._counter += 1
+
def args_for_new_array(self, descr):
raise Seen("args_for_new_array")
+
class TestMallocVarsizeFastpath(BaseTestRegalloc):
def setup_method(self, method):
cpu = CPU(None, None)
diff --git a/pypy/jit/backend/arm/test/test_generated.py b/pypy/jit/backend/arm/test/test_generated.py
--- a/pypy/jit/backend/arm/test/test_generated.py
+++ b/pypy/jit/backend/arm/test/test_generated.py
@@ -3,10 +3,10 @@
AbstractDescr,
BasicFailDescr,
BoxInt, Box, BoxPtr,
- LoopToken,
ConstInt, ConstPtr,
BoxObj, Const,
ConstObj, BoxFloat, ConstFloat)
+from pypy.jit.metainterp.history import JitCellToken
from pypy.jit.metainterp.resoperation import ResOperation, rop
from pypy.rpython.test.test_llinterp import interpret
from pypy.jit.backend.detect_cpu import getcpuclass
@@ -40,20 +40,11 @@
ResOperation(rop.GUARD_TRUE, [v12], None, descr=faildescr1),
ResOperation(rop.FINISH, [v9, v6, v10, v2, v8, v5, v1, v4], None, descr=faildescr2),
]
- looptoken = LoopToken()
+ looptoken = JitCellToken()
operations[2].setfailargs([v12, v8, v3, v2, v1, v11])
cpu.compile_loop(inputargs, operations, looptoken)
- cpu.set_future_value_int(0, -12)
- cpu.set_future_value_int(1, -26)
- cpu.set_future_value_int(2, -19)
- cpu.set_future_value_int(3, 7)
- cpu.set_future_value_int(4, -5)
- cpu.set_future_value_int(5, -24)
- cpu.set_future_value_int(6, -37)
- cpu.set_future_value_int(7, 62)
- cpu.set_future_value_int(8, 9)
- cpu.set_future_value_int(9, 12)
- op = cpu.execute_token(looptoken)
+ args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12]
+ op = cpu.execute_token(looptoken, *args)
assert cpu.get_latest_value_int(0) == 0
assert cpu.get_latest_value_int(1) == 62
assert cpu.get_latest_value_int(2) == -19
@@ -101,19 +92,10 @@
]
operations[2].setfailargs([v10, v6])
operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1])
- looptoken = LoopToken()
+ looptoken = JitCellToken()
cpu.compile_loop(inputargs, operations, looptoken)
- cpu.set_future_value_int(0, 16)
- cpu.set_future_value_int(1, 5)
- cpu.set_future_value_int(2, 5)
- cpu.set_future_value_int(3, 16)
- cpu.set_future_value_int(4, 46)
- cpu.set_future_value_int(5, 6)
- cpu.set_future_value_int(6, 63)
- cpu.set_future_value_int(7, 39)
- cpu.set_future_value_int(8, 78)
- cpu.set_future_value_int(9, 0)
- op = cpu.execute_token(looptoken)
+ args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0]
+ op = cpu.execute_token(looptoken, *args)
assert cpu.get_latest_value_int(0) == 105
assert cpu.get_latest_value_int(1) == 63
assert cpu.get_latest_value_int(2) == 0
@@ -152,18 +134,9 @@
]
operations[2].setfailargs([v8, v3])
operations[4].setfailargs([v2, v12, v1, v3, v4])
- looptoken = LoopToken()
+ looptoken = JitCellToken()
cpu.compile_loop(inputargs, operations, looptoken)
- cpu.set_future_value_int(0, -5)
- cpu.set_future_value_int(1, 24)
- cpu.set_future_value_int(2, 46)
- cpu.set_future_value_int(3, -15)
- cpu.set_future_value_int(4, 13)
- cpu.set_future_value_int(5, -8)
- cpu.set_future_value_int(6, 0)
- cpu.set_future_value_int(7, -6)
- cpu.set_future_value_int(8, 6)
- cpu.set_future_value_int(9, 6)
+ args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6]
op = cpu.execute_token(looptoken)
assert op.identifier == 2
assert cpu.get_latest_value_int(0) == 24
@@ -203,19 +176,10 @@
ResOperation(rop.FINISH, [v8, v2, v6, v5, v7, v1, v10], None, descr=faildescr2),
]
operations[5].setfailargs([])
- looptoken = LoopToken()
+ looptoken = JitCellToken()
cpu.compile_loop(inputargs, operations, looptoken)
- cpu.set_future_value_int(0, 19)
- cpu.set_future_value_int(1, -3)
- cpu.set_future_value_int(2, -58)
- cpu.set_future_value_int(3, -7)
- cpu.set_future_value_int(4, 12)
- cpu.set_future_value_int(5, 22)
- cpu.set_future_value_int(6, -54)
- cpu.set_future_value_int(7, -29)
- cpu.set_future_value_int(8, -19)
- cpu.set_future_value_int(9, -64)
- op = cpu.execute_token(looptoken)
+ args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64]
+ op = cpu.execute_token(looptoken, *args)
assert cpu.get_latest_value_int(0) == -29
assert cpu.get_latest_value_int(1) == -3
assert cpu.get_latest_value_int(2) == 22
@@ -254,20 +218,11 @@
ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1),
ResOperation(rop.FINISH, [v1, v4, v10, v8, v7, v3], None, descr=faildescr2),
]
- looptoken = LoopToken()
+ looptoken = JitCellToken()
operations[5].setfailargs([])
cpu.compile_loop(inputargs, operations, looptoken)
- cpu.set_future_value_int(0, 1073741824)
- cpu.set_future_value_int(1, 95)
- cpu.set_future_value_int(2, -16)
- cpu.set_future_value_int(3, 5)
- cpu.set_future_value_int(4, 92)
- cpu.set_future_value_int(5, 12)
- cpu.set_future_value_int(6, 32)
- cpu.set_future_value_int(7, 17)
- cpu.set_future_value_int(8, 37)
More information about the pypy-commit
mailing list