[pypy-commit] pypy arm-backend-2: merge default
bivab
noreply at buildbot.pypy.org
Fri Dec 30 17:12:58 CET 2011
Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r50958:16f44a7dcbb5
Date: 2011-12-29 10:24 +0100
http://bitbucket.org/pypy/pypy/changeset/16f44a7dcbb5/
Log: merge default
diff too long, truncating to 10000 out of 21761 lines
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/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -231,8 +231,10 @@
sqlite.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p]
sqlite.sqlite3_result_text.restype = None
-sqlite.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int]
-sqlite.sqlite3_enable_load_extension.restype = c_int
+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
@@ -708,13 +710,14 @@
from sqlite3.dump import _iterdump
return _iterdump(self)
- def enable_load_extension(self, enabled):
- self._check_thread()
- self._check_closed()
+ 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")
+ 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)
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/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/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/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
@@ -190,8 +190,8 @@
def is_w(self, space, w_other):
return self is w_other
- def unique_id(self, space):
- return space.wrap(compute_unique_id(self))
+ def immutable_unique_id(self, space):
+ return None
def str_w(self, space):
w_msg = typed_unwrap_error_msg(space, "string", self)
@@ -706,7 +706,10 @@
return w_two.is_w(self, w_one)
def id(self, w_obj):
- return w_obj.unique_id(self)
+ 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))"""
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/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/test/test_zrpy_gc.py b/pypy/jit/backend/arm/test/test_zrpy_gc.py
--- a/pypy/jit/backend/arm/test/test_zrpy_gc.py
+++ b/pypy/jit/backend/arm/test/test_zrpy_gc.py
@@ -71,16 +71,17 @@
def get_functions_to_patch():
from pypy.jit.backend.llsupport import gc
#
- can_inline_malloc1 = gc.GcLLDescr_framework.can_inline_malloc
- def can_inline_malloc2(*args):
+ can_use_nursery_malloc1 = gc.GcLLDescr_framework.can_use_nursery_malloc
+ def can_use_nursery_malloc2(*args):
try:
if os.environ['PYPY_NO_INLINE_MALLOC']:
return False
except KeyError:
pass
- return can_inline_malloc1(*args)
+ return can_use_nursery_malloc1(*args)
#
- return {(gc.GcLLDescr_framework, 'can_inline_malloc'): can_inline_malloc2}
+ return {(gc.GcLLDescr_framework, 'can_use_nursery_malloc'):
+ can_use_nursery_malloc2}
def compile(f, gc, enable_opts='', **kwds):
from pypy.annotation.listdef import s_list_of_strings
diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py
--- a/pypy/jit/backend/llgraph/llimpl.py
+++ b/pypy/jit/backend/llgraph/llimpl.py
@@ -328,6 +328,14 @@
_variables.append(v)
return r
+def compile_started_vars(clt):
+ if not hasattr(clt, '_debug_argtypes'): # only when compiling the loop
+ argtypes = [v.concretetype for v in _variables]
+ try:
+ clt._debug_argtypes = argtypes
+ except AttributeError: # when 'clt' is actually a translated
+ pass # GcStruct
+
def compile_add(loop, opnum):
loop = _from_opaque(loop)
loop.operations.append(Operation(opnum))
@@ -355,11 +363,13 @@
TARGET_TOKENS = weakref.WeakKeyDictionary()
-def compile_add_target_token(loop, descr):
+def compile_add_target_token(loop, descr, clt):
+ # here, 'clt' is the compiled_loop_token of the original loop that
+ # we are compiling
loop = _from_opaque(loop)
op = loop.operations[-1]
descrobj = _normalize(descr)
- TARGET_TOKENS[descrobj] = loop, len(loop.operations), op.args
+ TARGET_TOKENS[descrobj] = loop, len(loop.operations), op.args, clt
def compile_add_var(loop, intvar):
loop = _from_opaque(loop)
@@ -395,17 +405,25 @@
_variables.append(v)
return r
-def compile_add_jump_target(loop, targettoken):
+def compile_add_jump_target(loop, targettoken, source_clt):
loop = _from_opaque(loop)
descrobj = _normalize(targettoken)
- loop_target, target_opindex, target_inputargs = TARGET_TOKENS[descrobj]
+ (loop_target, target_opindex, target_inputargs, target_clt
+ ) = TARGET_TOKENS[descrobj]
+ #
+ try:
+ assert source_clt._debug_argtypes == target_clt._debug_argtypes
+ except AttributeError: # when translated
+ pass
#
op = loop.operations[-1]
op.jump_target = loop_target
op.jump_target_opindex = target_opindex
op.jump_target_inputargs = target_inputargs
assert op.opnum == rop.JUMP
- assert len(op.args) == len(target_inputargs)
+ assert [v.concretetype for v in op.args] == (
+ [v.concretetype for v in target_inputargs])
+ #
if loop_target == loop:
log.info("compiling new loop")
else:
@@ -987,6 +1005,7 @@
self._may_force = self.opindex
try:
inpargs = _from_opaque(ctl.compiled_version).inputargs
+ assert len(inpargs) == len(args)
for i, inparg in enumerate(inpargs):
TYPE = inparg.concretetype
if TYPE is lltype.Signed:
@@ -1816,6 +1835,7 @@
setannotation(compile_start_int_var, annmodel.SomeInteger())
setannotation(compile_start_ref_var, annmodel.SomeInteger())
setannotation(compile_start_float_var, annmodel.SomeInteger())
+setannotation(compile_started_vars, annmodel.s_None)
setannotation(compile_add, annmodel.s_None)
setannotation(compile_add_descr, annmodel.s_None)
setannotation(compile_add_descr_arg, annmodel.s_None)
diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -37,7 +37,7 @@
def get_arg_types(self):
return self.arg_types
- def get_return_type(self):
+ def get_result_type(self):
return self.typeinfo
def get_extra_info(self):
@@ -138,11 +138,12 @@
clt = original_loop_token.compiled_loop_token
clt.loop_and_bridges.append(c)
clt.compiling_a_bridge()
- self._compile_loop_or_bridge(c, inputargs, operations)
+ self._compile_loop_or_bridge(c, inputargs, operations, clt)
old, oldindex = faildescr._compiled_fail
llimpl.compile_redirect_fail(old, oldindex, c)
- def compile_loop(self, inputargs, operations, jitcell_token, log=True, name=''):
+ def compile_loop(self, inputargs, operations, jitcell_token,
+ log=True, name=''):
"""In a real assembler backend, this should assemble the given
list of operations. Here we just generate a similar CompiledLoop
instance. The code here is RPython, whereas the code in llimpl
@@ -153,14 +154,14 @@
clt.loop_and_bridges = [c]
clt.compiled_version = c
jitcell_token.compiled_loop_token = clt
- self._compile_loop_or_bridge(c, inputargs, operations)
+ self._compile_loop_or_bridge(c, inputargs, operations, clt)
def free_loop_and_bridges(self, compiled_loop_token):
for c in compiled_loop_token.loop_and_bridges:
llimpl.mark_as_free(c)
model.AbstractCPU.free_loop_and_bridges(self, compiled_loop_token)
- def _compile_loop_or_bridge(self, c, inputargs, operations):
+ def _compile_loop_or_bridge(self, c, inputargs, operations, clt):
var2index = {}
for box in inputargs:
if isinstance(box, history.BoxInt):
@@ -172,10 +173,11 @@
var2index[box] = llimpl.compile_start_float_var(c)
else:
raise Exception("box is: %r" % (box,))
- self._compile_operations(c, operations, var2index)
+ llimpl.compile_started_vars(clt)
+ self._compile_operations(c, operations, var2index, clt)
return c
- def _compile_operations(self, c, operations, var2index):
+ def _compile_operations(self, c, operations, var2index, clt):
for op in operations:
llimpl.compile_add(c, op.getopnum())
descr = op.getdescr()
@@ -187,7 +189,7 @@
assert op.getopnum() != rop.JUMP
llimpl.compile_add_loop_token(c, descr)
if isinstance(descr, history.TargetToken) and op.getopnum() == rop.LABEL:
- llimpl.compile_add_target_token(c, descr)
+ llimpl.compile_add_target_token(c, descr, clt)
if self.is_oo and isinstance(descr, (OODescr, MethDescr)):
# hack hack, not rpython
c._obj.externalobj.operations[-1].setdescr(descr)
@@ -241,7 +243,7 @@
assert op.is_final()
if op.getopnum() == rop.JUMP:
targettoken = op.getdescr()
- llimpl.compile_add_jump_target(c, targettoken)
+ llimpl.compile_add_jump_target(c, targettoken, clt)
elif op.getopnum() == rop.FINISH:
faildescr = op.getdescr()
index = self.get_fail_descr_number(faildescr)
@@ -260,23 +262,28 @@
self.latest_frame = frame
return fail_index
- def execute_token(self, loop_token):
- """Calls the fake 'assembler' generated for the given loop.
- Returns the descr of the last executed operation: either the one
- attached to the failing guard, or the one attached to the FINISH.
- Use set_future_value_xxx() before, and get_latest_value_xxx() after.
- """
- fail_index = self._execute_token(loop_token)
- return self.get_fail_descr_from_number(fail_index)
-
- def set_future_value_int(self, index, intvalue):
- llimpl.set_future_value_int(index, intvalue)
-
- def set_future_value_ref(self, index, objvalue):
- llimpl.set_future_value_ref(index, objvalue)
-
- def set_future_value_float(self, index, floatvalue):
- llimpl.set_future_value_float(index, floatvalue)
+ def make_execute_token(self, *argtypes):
+ nb_args = len(argtypes)
+ unroll_argtypes = unrolling_iterable(list(enumerate(argtypes)))
+ #
+ def execute_token(loop_token, *args):
+ assert len(args) == nb_args
+ for index, TYPE in unroll_argtypes:
+ x = args[index]
+ assert TYPE == lltype.typeOf(x)
+ if TYPE == lltype.Signed:
+ llimpl.set_future_value_int(index, x)
+ elif TYPE == llmemory.GCREF:
+ llimpl.set_future_value_ref(index, x)
+ elif TYPE == longlong.FLOATSTORAGE:
+ llimpl.set_future_value_float(index, x)
+ else:
+ assert 0
+ #
+ fail_index = self._execute_token(loop_token)
+ return self.get_fail_descr_from_number(fail_index)
+ #
+ return execute_token
def get_latest_value_int(self, index):
return llimpl.frame_int_getvalue(self.latest_frame, index)
diff --git a/pypy/jit/backend/llsupport/descr.py b/pypy/jit/backend/llsupport/descr.py
--- a/pypy/jit/backend/llsupport/descr.py
+++ b/pypy/jit/backend/llsupport/descr.py
@@ -5,11 +5,7 @@
from pypy.jit.metainterp.history import AbstractDescr, getkind
from pypy.jit.metainterp import history
from pypy.jit.codewriter import heaptracker, longlong
-
-# The point of the class organization in this file is to make instances
-# as compact as possible. This is done by not storing the field size or
-# the 'is_pointer_field' flag in the instance itself but in the class
-# (in methods actually) using a few classes instead of just one.
+from pypy.jit.codewriter.longlong import is_longlong
class GcCache(object):
@@ -19,6 +15,7 @@
self._cache_size = {}
self._cache_field = {}
self._cache_array = {}
+ self._cache_arraylen = {}
self._cache_call = {}
self._cache_interiorfield = {}
@@ -26,24 +23,15 @@
assert isinstance(STRUCT, lltype.GcStruct)
def init_array_descr(self, ARRAY, arraydescr):
- assert isinstance(ARRAY, lltype.GcArray)
+ assert (isinstance(ARRAY, lltype.GcArray) or
+ isinstance(ARRAY, lltype.GcStruct) and ARRAY._arrayfld)
-if lltype.SignedLongLong is lltype.Signed:
- def is_longlong(TYPE):
- return False
-else:
- assert rffi.sizeof(lltype.SignedLongLong) == rffi.sizeof(lltype.Float)
- def is_longlong(TYPE):
- return TYPE in (lltype.SignedLongLong, lltype.UnsignedLongLong)
-
# ____________________________________________________________
# SizeDescrs
class SizeDescr(AbstractDescr):
size = 0 # help translation
- is_immutable = False
-
tid = llop.combine_ushort(lltype.Signed, 0, 0)
def __init__(self, size, count_fields_if_immut=-1):
@@ -77,265 +65,247 @@
cache[STRUCT] = sizedescr
return sizedescr
+
# ____________________________________________________________
# FieldDescrs
-class BaseFieldDescr(AbstractDescr):
+FLAG_POINTER = 'P'
+FLAG_FLOAT = 'F'
+FLAG_UNSIGNED = 'U'
+FLAG_SIGNED = 'S'
+FLAG_STRUCT = 'X'
+FLAG_VOID = 'V'
+
+class FieldDescr(AbstractDescr):
+ name = ''
offset = 0 # help translation
- name = ''
- _clsname = ''
+ field_size = 0
+ flag = '\x00'
- def __init__(self, name, offset):
+ def __init__(self, name, offset, field_size, flag):
self.name = name
self.offset = offset
+ self.field_size = field_size
+ self.flag = flag
+
+ def is_pointer_field(self):
+ return self.flag == FLAG_POINTER
+
+ def is_float_field(self):
+ return self.flag == FLAG_FLOAT
+
+ def is_field_signed(self):
+ return self.flag == FLAG_SIGNED
def sort_key(self):
return self.offset
- def get_field_size(self, translate_support_code):
- raise NotImplementedError
+ def repr_of_descr(self):
+ return '<Field%s %s %s>' % (self.flag, self.name, self.offset)
- _is_pointer_field = False # unless overridden by GcPtrFieldDescr
- _is_float_field = False # unless overridden by FloatFieldDescr
- _is_field_signed = False # unless overridden by XxxFieldDescr
-
- def is_pointer_field(self):
- return self._is_pointer_field
-
- def is_float_field(self):
- return self._is_float_field
-
- def is_field_signed(self):
- return self._is_field_signed
-
- def repr_of_descr(self):
- return '<%s %s %s>' % (self._clsname, self.name, self.offset)
-
-class DynamicFieldDescr(BaseFieldDescr):
- def __init__(self, offset, fieldsize, is_pointer, is_float, is_signed):
- self.offset = offset
- self._fieldsize = fieldsize
- self._is_pointer_field = is_pointer
- self._is_float_field = is_float
- self._is_field_signed = is_signed
-
- def get_field_size(self, translate_support_code):
- return self._fieldsize
-
-class NonGcPtrFieldDescr(BaseFieldDescr):
- _clsname = 'NonGcPtrFieldDescr'
- def get_field_size(self, translate_support_code):
- return symbolic.get_size_of_ptr(translate_support_code)
-
-class GcPtrFieldDescr(NonGcPtrFieldDescr):
- _clsname = 'GcPtrFieldDescr'
- _is_pointer_field = True
-
-def getFieldDescrClass(TYPE):
- return getDescrClass(TYPE, BaseFieldDescr, GcPtrFieldDescr,
- NonGcPtrFieldDescr, 'Field', 'get_field_size',
- '_is_float_field', '_is_field_signed')
def get_field_descr(gccache, STRUCT, fieldname):
cache = gccache._cache_field
try:
return cache[STRUCT][fieldname]
except KeyError:
- offset, _ = symbolic.get_field_token(STRUCT, fieldname,
- gccache.translate_support_code)
+ offset, size = symbolic.get_field_token(STRUCT, fieldname,
+ gccache.translate_support_code)
FIELDTYPE = getattr(STRUCT, fieldname)
+ flag = get_type_flag(FIELDTYPE)
name = '%s.%s' % (STRUCT._name, fieldname)
- fielddescr = getFieldDescrClass(FIELDTYPE)(name, offset)
+ fielddescr = FieldDescr(name, offset, size, flag)
cachedict = cache.setdefault(STRUCT, {})
cachedict[fieldname] = fielddescr
return fielddescr
+def get_type_flag(TYPE):
+ if isinstance(TYPE, lltype.Ptr):
+ if TYPE.TO._gckind == 'gc':
+ return FLAG_POINTER
+ else:
+ return FLAG_UNSIGNED
+ if isinstance(TYPE, lltype.Struct):
+ return FLAG_STRUCT
+ if TYPE is lltype.Float or is_longlong(TYPE):
+ return FLAG_FLOAT
+ if (TYPE is not lltype.Bool and isinstance(TYPE, lltype.Number) and
+ rffi.cast(TYPE, -1) == -1):
+ return FLAG_SIGNED
+ return FLAG_UNSIGNED
+
+def get_field_arraylen_descr(gccache, ARRAY_OR_STRUCT):
+ cache = gccache._cache_arraylen
+ try:
+ return cache[ARRAY_OR_STRUCT]
+ except KeyError:
+ tsc = gccache.translate_support_code
+ (_, _, ofs) = symbolic.get_array_token(ARRAY_OR_STRUCT, tsc)
+ size = symbolic.get_size(lltype.Signed, tsc)
+ result = FieldDescr("len", ofs, size, get_type_flag(lltype.Signed))
+ cache[ARRAY_OR_STRUCT] = result
+ return result
+
+
# ____________________________________________________________
# ArrayDescrs
-_A = lltype.GcArray(lltype.Signed) # a random gcarray
-_AF = lltype.GcArray(lltype.Float) # an array of C doubles
+class ArrayDescr(AbstractDescr):
+ tid = 0
+ basesize = 0 # workaround for the annotator
+ itemsize = 0
+ lendescr = None
+ flag = '\x00'
-
-class BaseArrayDescr(AbstractDescr):
- _clsname = ''
- tid = llop.combine_ushort(lltype.Signed, 0, 0)
-
- def get_base_size(self, translate_support_code):
- basesize, _, _ = symbolic.get_array_token(_A, translate_support_code)
- return basesize
-
- def get_ofs_length(self, translate_support_code):
- _, _, ofslength = symbolic.get_array_token(_A, translate_support_code)
- return ofslength
-
- def get_item_size(self, translate_support_code):
- raise NotImplementedError
-
- _is_array_of_pointers = False # unless overridden by GcPtrArrayDescr
- _is_array_of_floats = False # unless overridden by FloatArrayDescr
- _is_array_of_structs = False # unless overridden by StructArrayDescr
- _is_item_signed = False # unless overridden by XxxArrayDescr
+ def __init__(self, basesize, itemsize, lendescr, flag):
+ self.basesize = basesize
+ self.itemsize = itemsize
+ self.lendescr = lendescr # or None, if no length
+ self.flag = flag
def is_array_of_pointers(self):
- return self._is_array_of_pointers
+ return self.flag == FLAG_POINTER
def is_array_of_floats(self):
- return self._is_array_of_floats
+ return self.flag == FLAG_FLOAT
+
+ def is_item_signed(self):
+ return self.flag == FLAG_SIGNED
def is_array_of_structs(self):
- return self._is_array_of_structs
-
- def is_item_signed(self):
- return self._is_item_signed
+ return self.flag == FLAG_STRUCT
def repr_of_descr(self):
- return '<%s>' % self._clsname
+ return '<Array%s %s>' % (self.flag, self.itemsize)
-class NonGcPtrArrayDescr(BaseArrayDescr):
- _clsname = 'NonGcPtrArrayDescr'
- def get_item_size(self, translate_support_code):
- return symbolic.get_size_of_ptr(translate_support_code)
-
-class GcPtrArrayDescr(NonGcPtrArrayDescr):
- _clsname = 'GcPtrArrayDescr'
- _is_array_of_pointers = True
-
-class FloatArrayDescr(BaseArrayDescr):
- _clsname = 'FloatArrayDescr'
- _is_array_of_floats = True
- def get_base_size(self, translate_support_code):
- basesize, _, _ = symbolic.get_array_token(_AF, translate_support_code)
- return basesize
- def get_item_size(self, translate_support_code):
- return symbolic.get_size(lltype.Float, translate_support_code)
-
-class StructArrayDescr(BaseArrayDescr):
- _clsname = 'StructArrayDescr'
- _is_array_of_structs = True
-
-class BaseArrayNoLengthDescr(BaseArrayDescr):
- def get_base_size(self, translate_support_code):
- return 0
-
- def get_ofs_length(self, translate_support_code):
- return -1
-
-class DynamicArrayNoLengthDescr(BaseArrayNoLengthDescr):
- def __init__(self, itemsize):
- self.itemsize = itemsize
-
- def get_item_size(self, translate_support_code):
- return self.itemsize
-
-class NonGcPtrArrayNoLengthDescr(BaseArrayNoLengthDescr):
- _clsname = 'NonGcPtrArrayNoLengthDescr'
- def get_item_size(self, translate_support_code):
- return symbolic.get_size_of_ptr(translate_support_code)
-
-class GcPtrArrayNoLengthDescr(NonGcPtrArrayNoLengthDescr):
- _clsname = 'GcPtrArrayNoLengthDescr'
- _is_array_of_pointers = True
-
-def getArrayDescrClass(ARRAY):
- if ARRAY.OF is lltype.Float:
- return FloatArrayDescr
- elif isinstance(ARRAY.OF, lltype.Struct):
- class Descr(StructArrayDescr):
- _clsname = '%sArrayDescr' % ARRAY.OF._name
- def get_item_size(self, translate_support_code):
- return symbolic.get_size(ARRAY.OF, translate_support_code)
- Descr.__name__ = Descr._clsname
- return Descr
- return getDescrClass(ARRAY.OF, BaseArrayDescr, GcPtrArrayDescr,
- NonGcPtrArrayDescr, 'Array', 'get_item_size',
- '_is_array_of_floats', '_is_item_signed')
-
-def getArrayNoLengthDescrClass(ARRAY):
- return getDescrClass(ARRAY.OF, BaseArrayNoLengthDescr, GcPtrArrayNoLengthDescr,
- NonGcPtrArrayNoLengthDescr, 'ArrayNoLength', 'get_item_size',
- '_is_array_of_floats', '_is_item_signed')
-
-def get_array_descr(gccache, ARRAY):
+def get_array_descr(gccache, ARRAY_OR_STRUCT):
cache = gccache._cache_array
try:
- return cache[ARRAY]
+ return cache[ARRAY_OR_STRUCT]
except KeyError:
- # we only support Arrays that are either GcArrays, or raw no-length
- # non-gc Arrays.
- if ARRAY._hints.get('nolength', False):
- assert not isinstance(ARRAY, lltype.GcArray)
- arraydescr = getArrayNoLengthDescrClass(ARRAY)()
+ tsc = gccache.translate_support_code
+ basesize, itemsize, _ = symbolic.get_array_token(ARRAY_OR_STRUCT, tsc)
+ if isinstance(ARRAY_OR_STRUCT, lltype.Array):
+ ARRAY_INSIDE = ARRAY_OR_STRUCT
else:
- assert isinstance(ARRAY, lltype.GcArray)
- arraydescr = getArrayDescrClass(ARRAY)()
- # verify basic assumption that all arrays' basesize and ofslength
- # are equal
- basesize, itemsize, ofslength = symbolic.get_array_token(ARRAY, False)
- assert basesize == arraydescr.get_base_size(False)
- assert itemsize == arraydescr.get_item_size(False)
- if not ARRAY._hints.get('nolength', False):
- assert ofslength == arraydescr.get_ofs_length(False)
- if isinstance(ARRAY, lltype.GcArray):
- gccache.init_array_descr(ARRAY, arraydescr)
- cache[ARRAY] = arraydescr
+ ARRAY_INSIDE = ARRAY_OR_STRUCT._flds[ARRAY_OR_STRUCT._arrayfld]
+ if ARRAY_INSIDE._hints.get('nolength', False):
+ lendescr = None
+ else:
+ lendescr = get_field_arraylen_descr(gccache, ARRAY_OR_STRUCT)
+ flag = get_type_flag(ARRAY_INSIDE.OF)
+ arraydescr = ArrayDescr(basesize, itemsize, lendescr, flag)
+ if ARRAY_OR_STRUCT._gckind == 'gc':
+ gccache.init_array_descr(ARRAY_OR_STRUCT, arraydescr)
+ cache[ARRAY_OR_STRUCT] = arraydescr
return arraydescr
+
# ____________________________________________________________
# InteriorFieldDescr
class InteriorFieldDescr(AbstractDescr):
- arraydescr = BaseArrayDescr() # workaround for the annotator
- fielddescr = BaseFieldDescr('', 0)
+ arraydescr = ArrayDescr(0, 0, None, '\x00') # workaround for the annotator
+ fielddescr = FieldDescr('', 0, 0, '\x00')
def __init__(self, arraydescr, fielddescr):
+ assert arraydescr.flag == FLAG_STRUCT
self.arraydescr = arraydescr
self.fielddescr = fielddescr
+ def sort_key(self):
+ return self.fielddescr.sort_key()
+
def is_pointer_field(self):
return self.fielddescr.is_pointer_field()
def is_float_field(self):
return self.fielddescr.is_float_field()
- def sort_key(self):
- return self.fielddescr.sort_key()
-
def repr_of_descr(self):
return '<InteriorFieldDescr %s>' % self.fielddescr.repr_of_descr()
-def get_interiorfield_descr(gc_ll_descr, ARRAY, FIELDTP, name):
+def get_interiorfield_descr(gc_ll_descr, ARRAY, name):
cache = gc_ll_descr._cache_interiorfield
try:
- return cache[(ARRAY, FIELDTP, name)]
+ return cache[(ARRAY, name)]
except KeyError:
arraydescr = get_array_descr(gc_ll_descr, ARRAY)
- fielddescr = get_field_descr(gc_ll_descr, FIELDTP, name)
+ fielddescr = get_field_descr(gc_ll_descr, ARRAY.OF, name)
descr = InteriorFieldDescr(arraydescr, fielddescr)
- cache[(ARRAY, FIELDTP, name)] = descr
+ cache[(ARRAY, name)] = descr
return descr
+def get_dynamic_interiorfield_descr(gc_ll_descr, offset, width, fieldsize,
+ is_pointer, is_float, is_signed):
+ arraydescr = ArrayDescr(0, width, None, FLAG_STRUCT)
+ if is_pointer:
+ assert not is_float
+ flag = FLAG_POINTER
+ elif is_float:
+ flag = FLAG_FLOAT
+ elif is_signed:
+ flag = FLAG_SIGNED
+ else:
+ flag = FLAG_UNSIGNED
+ fielddescr = FieldDescr('dynamic', offset, fieldsize, flag)
+ return InteriorFieldDescr(arraydescr, fielddescr)
+
+
# ____________________________________________________________
# CallDescrs
-class BaseCallDescr(AbstractDescr):
- _clsname = ''
- loop_token = None
+class CallDescr(AbstractDescr):
arg_classes = '' # <-- annotation hack
+ result_type = '\x00'
+ result_flag = '\x00'
ffi_flags = 1
+ call_stub_i = staticmethod(lambda func, args_i, args_r, args_f:
+ 0)
+ call_stub_r = staticmethod(lambda func, args_i, args_r, args_f:
+ lltype.nullptr(llmemory.GCREF.TO))
+ call_stub_f = staticmethod(lambda func,args_i,args_r,args_f:
+ longlong.ZEROF)
- def __init__(self, arg_classes, extrainfo=None, ffi_flags=1):
- self.arg_classes = arg_classes # string of "r" and "i" (ref/int)
+ def __init__(self, arg_classes, result_type, result_signed, result_size,
+ extrainfo=None, ffi_flags=1):
+ """
+ 'arg_classes' is a string of characters, one per argument:
+ 'i', 'r', 'f', 'L', 'S'
+
+ 'result_type' is one character from the same list or 'v'
+
+ 'result_signed' is a boolean True/False
+ """
+ self.arg_classes = arg_classes
+ self.result_type = result_type
+ self.result_size = result_size
self.extrainfo = extrainfo
self.ffi_flags = ffi_flags
# NB. the default ffi_flags is 1, meaning FUNCFLAG_CDECL, which
# makes sense on Windows as it's the one for all the C functions
# we are compiling together with the JIT. On non-Windows platforms
# it is just ignored anyway.
+ if result_type == 'v':
+ result_flag = FLAG_VOID
+ elif result_type == 'i':
+ if result_signed:
+ result_flag = FLAG_SIGNED
+ else:
+ result_flag = FLAG_UNSIGNED
+ elif result_type == history.REF:
+ result_flag = FLAG_POINTER
+ elif result_type == history.FLOAT or result_type == 'L':
+ result_flag = FLAG_FLOAT
+ elif result_type == 'S':
+ result_flag = FLAG_UNSIGNED
+ else:
+ raise NotImplementedError("result_type = '%s'" % (result_type,))
+ self.result_flag = result_flag
def __repr__(self):
- res = '%s(%s)' % (self.__class__.__name__, self.arg_classes)
+ res = 'CallDescr(%s)' % (self.arg_classes,)
extraeffect = getattr(self.extrainfo, 'extraeffect', None)
if extraeffect is not None:
res += ' EF=%r' % extraeffect
@@ -363,14 +333,14 @@
def get_arg_types(self):
return self.arg_classes
- def get_return_type(self):
- return self._return_type
+ def get_result_type(self):
+ return self.result_type
- def get_result_size(self, translate_support_code):
- raise NotImplementedError
+ def get_result_size(self):
+ return self.result_size
def is_result_signed(self):
- return False # unless overridden
+ return self.result_flag == FLAG_SIGNED
def create_call_stub(self, rtyper, RESULT):
from pypy.rlib.clibffi import FFI_DEFAULT_ABI
@@ -408,18 +378,26 @@
seen = {'i': 0, 'r': 0, 'f': 0}
args = ", ".join([process(c) for c in self.arg_classes])
- if self.get_return_type() == history.INT:
+ result_type = self.get_result_type()
+ if result_type == history.INT:
result = 'rffi.cast(lltype.Signed, res)'
- elif self.get_return_type() == history.REF:
+ category = 'i'
+ elif result_type == history.REF:
+ assert RESULT == llmemory.GCREF # should be ensured by the caller
result = 'lltype.cast_opaque_ptr(llmemory.GCREF, res)'
- elif self.get_return_type() == history.FLOAT:
+ category = 'r'
+ elif result_type == history.FLOAT:
result = 'longlong.getfloatstorage(res)'
- elif self.get_return_type() == 'L':
+ category = 'f'
+ elif result_type == 'L':
result = 'rffi.cast(lltype.SignedLongLong, res)'
- elif self.get_return_type() == history.VOID:
- result = 'None'
- elif self.get_return_type() == 'S':
+ category = 'f'
+ elif result_type == history.VOID:
+ result = '0'
+ category = 'i'
+ elif result_type == 'S':
result = 'longlong.singlefloat2int(res)'
+ category = 'i'
else:
assert 0
source = py.code.Source("""
@@ -433,10 +411,13 @@
d = globals().copy()
d.update(locals())
exec source.compile() in d
- self.call_stub = d['call_stub']
+ call_stub = d['call_stub']
+ # store the function into one of three attributes, to preserve
+ # type-correctness of the return value
+ setattr(self, 'call_stub_%s' % category, call_stub)
def verify_types(self, args_i, args_r, args_f, return_type):
- assert self._return_type in return_type
+ assert self.result_type in return_type
assert (self.arg_classes.count('i') +
self.arg_classes.count('S')) == len(args_i or ())
assert self.arg_classes.count('r') == len(args_r or ())
@@ -444,161 +425,56 @@
self.arg_classes.count('L')) == len(args_f or ())
def repr_of_descr(self):
- return '<%s>' % self._clsname
+ res = 'Call%s %d' % (self.result_type, self.result_size)
+ if self.arg_classes:
+ res += ' ' + self.arg_classes
+ if self.extrainfo:
+ res += ' EF=%d' % self.extrainfo.extraeffect
+ oopspecindex = self.extrainfo.oopspecindex
+ if oopspecindex:
+ res += ' OS=%d' % oopspecindex
+ return '<%s>' % res
-class BaseIntCallDescr(BaseCallDescr):
- # Base class of the various subclasses of descrs corresponding to
- # calls having a return kind of 'int' (including non-gc pointers).
- # The inheritance hierarchy is a bit different than with other Descr
- # classes because of the 'call_stub' attribute, which is of type
- #
- # lambda func, args_i, args_r, args_f --> int/ref/float/void
- #
- # The purpose of BaseIntCallDescr is to be the parent of all classes
- # in which 'call_stub' has a return kind of 'int'.
- _return_type = history.INT
- call_stub = staticmethod(lambda func, args_i, args_r, args_f: 0)
-
- _is_result_signed = False # can be overridden in XxxCallDescr
- def is_result_signed(self):
- return self._is_result_signed
-
-class DynamicIntCallDescr(BaseIntCallDescr):
- """
- calldescr that works for every integer type, by explicitly passing it the
- size of the result. Used only by get_call_descr_dynamic
- """
- _clsname = 'DynamicIntCallDescr'
-
- def __init__(self, arg_classes, result_size, result_sign, extrainfo, ffi_flags):
- BaseIntCallDescr.__init__(self, arg_classes, extrainfo, ffi_flags)
- assert isinstance(result_sign, bool)
- self._result_size = chr(result_size)
- self._result_sign = result_sign
-
- def get_result_size(self, translate_support_code):
- return ord(self._result_size)
-
- def is_result_signed(self):
- return self._result_sign
-
-
-class NonGcPtrCallDescr(BaseIntCallDescr):
- _clsname = 'NonGcPtrCallDescr'
- def get_result_size(self, translate_support_code):
- return symbolic.get_size_of_ptr(translate_support_code)
-
-class GcPtrCallDescr(BaseCallDescr):
- _clsname = 'GcPtrCallDescr'
- _return_type = history.REF
- call_stub = staticmethod(lambda func, args_i, args_r, args_f:
- lltype.nullptr(llmemory.GCREF.TO))
- def get_result_size(self, translate_support_code):
- return symbolic.get_size_of_ptr(translate_support_code)
-
-class FloatCallDescr(BaseCallDescr):
- _clsname = 'FloatCallDescr'
- _return_type = history.FLOAT
- call_stub = staticmethod(lambda func,args_i,args_r,args_f: longlong.ZEROF)
- def get_result_size(self, translate_support_code):
- return symbolic.get_size(lltype.Float, translate_support_code)
-
-class LongLongCallDescr(FloatCallDescr):
- _clsname = 'LongLongCallDescr'
- _return_type = 'L'
-
-class VoidCallDescr(BaseCallDescr):
- _clsname = 'VoidCallDescr'
- _return_type = history.VOID
- call_stub = staticmethod(lambda func, args_i, args_r, args_f: None)
- def get_result_size(self, translate_support_code):
- return 0
-
-_SingleFloatCallDescr = None # built lazily
-
-def getCallDescrClass(RESULT):
- if RESULT is lltype.Void:
- return VoidCallDescr
- if RESULT is lltype.Float:
- return FloatCallDescr
- if RESULT is lltype.SingleFloat:
- global _SingleFloatCallDescr
- if _SingleFloatCallDescr is None:
- assert rffi.sizeof(rffi.UINT) == rffi.sizeof(RESULT)
- class SingleFloatCallDescr(getCallDescrClass(rffi.UINT)):
- _clsname = 'SingleFloatCallDescr'
- _return_type = 'S'
- _SingleFloatCallDescr = SingleFloatCallDescr
- return _SingleFloatCallDescr
- if is_longlong(RESULT):
- return LongLongCallDescr
- return getDescrClass(RESULT, BaseIntCallDescr, GcPtrCallDescr,
- NonGcPtrCallDescr, 'Call', 'get_result_size',
- Ellipsis, # <= floatattrname should not be used here
- '_is_result_signed')
-getCallDescrClass._annspecialcase_ = 'specialize:memo'
+def map_type_to_argclass(ARG, accept_void=False):
+ kind = getkind(ARG)
+ if kind == 'int':
+ if ARG is lltype.SingleFloat: return 'S'
+ else: return 'i'
+ elif kind == 'ref': return 'r'
+ elif kind == 'float':
+ if is_longlong(ARG): return 'L'
+ else: return 'f'
+ elif kind == 'void':
+ if accept_void: return 'v'
+ raise NotImplementedError('ARG = %r' % (ARG,))
def get_call_descr(gccache, ARGS, RESULT, extrainfo=None):
- arg_classes = []
- for ARG in ARGS:
- kind = getkind(ARG)
- if kind == 'int':
- if ARG is lltype.SingleFloat:
- arg_classes.append('S')
+ arg_classes = map(map_type_to_argclass, ARGS)
+ arg_classes = ''.join(arg_classes)
+ result_type = map_type_to_argclass(RESULT, accept_void=True)
+ RESULT_ERASED = RESULT
+ if RESULT is lltype.Void:
+ result_size = 0
+ result_signed = False
+ else:
+ if isinstance(RESULT, lltype.Ptr):
+ # avoid too many CallDescrs
+ if result_type == 'r':
+ RESULT_ERASED = llmemory.GCREF
else:
- arg_classes.append('i')
- elif kind == 'ref': arg_classes.append('r')
- elif kind == 'float':
- if is_longlong(ARG):
- arg_classes.append('L')
- else:
- arg_classes.append('f')
- else:
- raise NotImplementedError('ARG = %r' % (ARG,))
- arg_classes = ''.join(arg_classes)
- cls = getCallDescrClass(RESULT)
- key = (cls, arg_classes, extrainfo)
+ RESULT_ERASED = llmemory.Address
+ result_size = symbolic.get_size(RESULT_ERASED,
+ gccache.translate_support_code)
+ result_signed = get_type_flag(RESULT) == FLAG_SIGNED
+ key = (arg_classes, result_type, result_signed, RESULT_ERASED, extrainfo)
cache = gccache._cache_call
try:
- return cache[key]
+ calldescr = cache[key]
except KeyError:
- calldescr = cls(arg_classes, extrainfo)
- calldescr.create_call_stub(gccache.rtyper, RESULT)
+ calldescr = CallDescr(arg_classes, result_type, result_signed,
+ result_size, extrainfo)
+ calldescr.create_call_stub(gccache.rtyper, RESULT_ERASED)
cache[key] = calldescr
- return calldescr
-
-
-# ____________________________________________________________
-
-def getDescrClass(TYPE, BaseDescr, GcPtrDescr, NonGcPtrDescr,
- nameprefix, methodname, floatattrname, signedattrname,
- _cache={}):
- if isinstance(TYPE, lltype.Ptr):
- if TYPE.TO._gckind == 'gc':
- return GcPtrDescr
- else:
- return NonGcPtrDescr
- if TYPE is lltype.SingleFloat:
- assert rffi.sizeof(rffi.UINT) == rffi.sizeof(TYPE)
- TYPE = rffi.UINT
- try:
- return _cache[nameprefix, TYPE]
- except KeyError:
- #
- class Descr(BaseDescr):
- _clsname = '%s%sDescr' % (TYPE._name, nameprefix)
- Descr.__name__ = Descr._clsname
- #
- def method(self, translate_support_code):
- return symbolic.get_size(TYPE, translate_support_code)
- setattr(Descr, methodname, method)
- #
- if TYPE is lltype.Float or is_longlong(TYPE):
- setattr(Descr, floatattrname, True)
- elif (TYPE is not lltype.Bool and isinstance(TYPE, lltype.Number) and
- rffi.cast(TYPE, -1) == -1):
- setattr(Descr, signedattrname, True)
- #
- _cache[nameprefix, TYPE] = Descr
- return Descr
+ assert repr(calldescr.result_size) == repr(result_size)
+ return calldescr
diff --git a/pypy/jit/backend/llsupport/ffisupport.py b/pypy/jit/backend/llsupport/ffisupport.py
--- a/pypy/jit/backend/llsupport/ffisupport.py
+++ b/pypy/jit/backend/llsupport/ffisupport.py
@@ -1,9 +1,7 @@
from pypy.rlib.rarithmetic import intmask
from pypy.jit.metainterp import history
from pypy.rpython.lltypesystem import rffi
-from pypy.jit.backend.llsupport.descr import (
- DynamicIntCallDescr, NonGcPtrCallDescr, FloatCallDescr, VoidCallDescr,
- LongLongCallDescr, getCallDescrClass)
+from pypy.jit.backend.llsupport.descr import CallDescr
class UnsupportedKind(Exception):
pass
@@ -16,29 +14,13 @@
argkinds = [get_ffi_type_kind(cpu, arg) for arg in ffi_args]
except UnsupportedKind:
return None
- arg_classes = ''.join(argkinds)
- if reskind == history.INT:
- size = intmask(ffi_result.c_size)
- signed = is_ffi_type_signed(ffi_result)
- return DynamicIntCallDescr(arg_classes, size, signed, extrainfo,
- ffi_flags=ffi_flags)
- elif reskind == history.REF:
- return NonGcPtrCallDescr(arg_classes, extrainfo,
- ffi_flags=ffi_flags)
- elif reskind == history.FLOAT:
- return FloatCallDescr(arg_classes, extrainfo,
- ffi_flags=ffi_flags)
- elif reskind == history.VOID:
- return VoidCallDescr(arg_classes, extrainfo,
- ffi_flags=ffi_flags)
- elif reskind == 'L':
- return LongLongCallDescr(arg_classes, extrainfo,
- ffi_flags=ffi_flags)
- elif reskind == 'S':
- SingleFloatCallDescr = getCallDescrClass(rffi.FLOAT)
- return SingleFloatCallDescr(arg_classes, extrainfo,
- ffi_flags=ffi_flags)
- assert False
+ if reskind == history.VOID:
+ result_size = 0
+ else:
+ result_size = intmask(ffi_result.c_size)
+ argkinds = ''.join(argkinds)
+ return CallDescr(argkinds, reskind, is_ffi_type_signed(ffi_result),
+ result_size, extrainfo, ffi_flags=ffi_flags)
def get_ffi_type_kind(cpu, ffi_type):
from pypy.rlib.libffi import types
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -1,6 +1,6 @@
import os
from pypy.rlib import rgc
-from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.objectmodel import we_are_translated, specialize
from pypy.rlib.debug import fatalerror
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr
@@ -8,52 +8,93 @@
from pypy.rpython.lltypesystem.lloperation import llop
from pypy.rpython.annlowlevel import llhelper
from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.jit.metainterp.history import BoxInt, BoxPtr, ConstInt, ConstPtr
-from pypy.jit.metainterp.history import AbstractDescr
+from pypy.jit.codewriter import heaptracker
+from pypy.jit.metainterp.history import ConstPtr, AbstractDescr
from pypy.jit.metainterp.resoperation import ResOperation, rop
from pypy.jit.backend.llsupport import symbolic
from pypy.jit.backend.llsupport.symbolic import WORD
-from pypy.jit.backend.llsupport.descr import BaseSizeDescr, BaseArrayDescr
+from pypy.jit.backend.llsupport.descr import SizeDescr, ArrayDescr
from pypy.jit.backend.llsupport.descr import GcCache, get_field_descr
-from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr
+from pypy.jit.backend.llsupport.descr import get_array_descr
from pypy.jit.backend.llsupport.descr import get_call_descr
+from pypy.jit.backend.llsupport.rewrite import GcRewriterAssembler
from pypy.rpython.memory.gctransform import asmgcroot
# ____________________________________________________________
class GcLLDescription(GcCache):
- minimal_size_in_nursery = 0
- get_malloc_slowpath_addr = None
def __init__(self, gcdescr, translator=None, rtyper=None):
GcCache.__init__(self, translator is not None, rtyper)
self.gcdescr = gcdescr
+ if translator and translator.config.translation.gcremovetypeptr:
+ self.fielddescr_vtable = None
+ else:
+ self.fielddescr_vtable = get_field_descr(self, rclass.OBJECT,
+ 'typeptr')
+ self._generated_functions = []
+
+ def _setup_str(self):
+ self.str_descr = get_array_descr(self, rstr.STR)
+ self.unicode_descr = get_array_descr(self, rstr.UNICODE)
+
+ def generate_function(self, funcname, func, ARGS, RESULT=llmemory.GCREF):
+ """Generates a variant of malloc with the given name and the given
+ arguments. It should return NULL if out of memory. If it raises
+ anything, it must be an optional MemoryError.
+ """
+ FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, RESULT))
+ descr = get_call_descr(self, ARGS, RESULT)
+ setattr(self, funcname, func)
+ setattr(self, funcname + '_FUNCPTR', FUNCPTR)
+ setattr(self, funcname + '_descr', descr)
+ self._generated_functions.append(funcname)
+
+ @specialize.arg(1)
+ def get_malloc_fn(self, funcname):
+ func = getattr(self, funcname)
+ FUNC = getattr(self, funcname + '_FUNCPTR')
+ return llhelper(FUNC, func)
+
+ @specialize.arg(1)
+ def get_malloc_fn_addr(self, funcname):
+ ll_func = self.get_malloc_fn(funcname)
+ return heaptracker.adr2int(llmemory.cast_ptr_to_adr(ll_func))
+
def _freeze_(self):
return True
def initialize(self):
pass
def do_write_barrier(self, gcref_struct, gcref_newptr):
pass
- def rewrite_assembler(self, cpu, operations, gcrefs_output_list):
- return operations
- def can_inline_malloc(self, descr):
- return False
- def can_inline_malloc_varsize(self, descr, num_elem):
+ def can_use_nursery_malloc(self, size):
return False
def has_write_barrier_class(self):
return None
def freeing_block(self, start, stop):
pass
+ def get_nursery_free_addr(self):
+ raise NotImplementedError
+ def get_nursery_top_addr(self):
+ raise NotImplementedError
- def get_funcptr_for_newarray(self):
- return llhelper(self.GC_MALLOC_ARRAY, self.malloc_array)
- def get_funcptr_for_newstr(self):
- return llhelper(self.GC_MALLOC_STR_UNICODE, self.malloc_str)
- def get_funcptr_for_newunicode(self):
- return llhelper(self.GC_MALLOC_STR_UNICODE, self.malloc_unicode)
+ def gc_malloc(self, sizedescr):
+ """Blackhole: do a 'bh_new'. Also used for 'bh_new_with_vtable',
+ with the vtable pointer set manually afterwards."""
+ assert isinstance(sizedescr, SizeDescr)
+ return self._bh_malloc(sizedescr)
+ def gc_malloc_array(self, arraydescr, num_elem):
+ assert isinstance(arraydescr, ArrayDescr)
+ return self._bh_malloc_array(arraydescr, num_elem)
- def record_constptrs(self, op, gcrefs_output_list):
+ def gc_malloc_str(self, num_elem):
+ return self._bh_malloc_array(self.str_descr, num_elem)
+
+ def gc_malloc_unicode(self, num_elem):
+ return self._bh_malloc_array(self.unicode_descr, num_elem)
+
+ def _record_constptrs(self, op, gcrefs_output_list):
for i in range(op.numargs()):
v = op.getarg(i)
if isinstance(v, ConstPtr) and bool(v.value):
@@ -61,11 +102,27 @@
rgc._make_sure_does_not_move(p)
gcrefs_output_list.append(p)
+ def rewrite_assembler(self, cpu, operations, gcrefs_output_list):
+ rewriter = GcRewriterAssembler(self, cpu)
+ newops = rewriter.rewrite(operations)
+ # record all GCREFs, because the GC (or Boehm) cannot see them and
+ # keep them alive if they end up as constants in the assembler
+ for op in newops:
+ self._record_constptrs(op, gcrefs_output_list)
+ return newops
+
# ____________________________________________________________
class GcLLDescr_boehm(GcLLDescription):
- moving_gc = False
- gcrootmap = None
+ kind = 'boehm'
+ moving_gc = False
+ round_up = False
+ gcrootmap = None
+ write_barrier_descr = None
+ fielddescr_tid = None
+ str_type_id = 0
+ unicode_type_id = 0
+ get_malloc_slowpath_addr = None
@classmethod
def configure_boehm_once(cls):
@@ -76,6 +133,16 @@
from pypy.rpython.tool import rffi_platform
compilation_info = rffi_platform.configure_boehm()
+ # on some platform GC_init is required before any other
+ # GC_* functions, call it here for the benefit of tests
+ # XXX move this to tests
+ init_fn_ptr = rffi.llexternal("GC_init",
+ [], lltype.Void,
+ compilation_info=compilation_info,
+ sandboxsafe=True,
+ _nowrapper=True)
+ init_fn_ptr()
+
# Versions 6.x of libgc needs to use GC_local_malloc().
# Versions 7.x of libgc removed this function; GC_malloc() has
# the same behavior if libgc was compiled with
@@ -95,96 +162,42 @@
sandboxsafe=True,
_nowrapper=True)
cls.malloc_fn_ptr = malloc_fn_ptr
- cls.compilation_info = compilation_info
return malloc_fn_ptr
def __init__(self, gcdescr, translator, rtyper):
GcLLDescription.__init__(self, gcdescr, translator, rtyper)
# grab a pointer to the Boehm 'malloc' function
- malloc_fn_ptr = self.configure_boehm_once()
- self.funcptr_for_new = malloc_fn_ptr
+ self.malloc_fn_ptr = self.configure_boehm_once()
+ self._setup_str()
+ self._make_functions()
- def malloc_array(basesize, itemsize, ofs_length, num_elem):
+ def _make_functions(self):
+
+ def malloc_fixedsize(size):
+ return self.malloc_fn_ptr(size)
+ self.generate_function('malloc_fixedsize', malloc_fixedsize,
+ [lltype.Signed])
+
+ def malloc_array(basesize, num_elem, itemsize, ofs_length):
try:
- size = ovfcheck(basesize + ovfcheck(itemsize * num_elem))
+ totalsize = ovfcheck(basesize + ovfcheck(itemsize * num_elem))
except OverflowError:
return lltype.nullptr(llmemory.GCREF.TO)
- res = self.funcptr_for_new(size)
- if not res:
- return res
- rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem
+ res = self.malloc_fn_ptr(totalsize)
+ if res:
+ arrayptr = rffi.cast(rffi.CArrayPtr(lltype.Signed), res)
+ arrayptr[ofs_length/WORD] = num_elem
return res
- self.malloc_array = malloc_array
- self.GC_MALLOC_ARRAY = lltype.Ptr(lltype.FuncType(
- [lltype.Signed] * 4, llmemory.GCREF))
+ self.generate_function('malloc_array', malloc_array,
+ [lltype.Signed] * 4)
+ def _bh_malloc(self, sizedescr):
+ return self.malloc_fixedsize(sizedescr.size)
- (str_basesize, str_itemsize, str_ofs_length
- ) = symbolic.get_array_token(rstr.STR, self.translate_support_code)
- (unicode_basesize, unicode_itemsize, unicode_ofs_length
- ) = symbolic.get_array_token(rstr.UNICODE, self.translate_support_code)
- def malloc_str(length):
- return self.malloc_array(
- str_basesize, str_itemsize, str_ofs_length, length
- )
- def malloc_unicode(length):
- return self.malloc_array(
- unicode_basesize, unicode_itemsize, unicode_ofs_length, length
- )
- self.malloc_str = malloc_str
- self.malloc_unicode = malloc_unicode
- self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType(
- [lltype.Signed], llmemory.GCREF))
-
-
- # on some platform GC_init is required before any other
- # GC_* functions, call it here for the benefit of tests
- # XXX move this to tests
- init_fn_ptr = rffi.llexternal("GC_init",
- [], lltype.Void,
- compilation_info=self.compilation_info,
- sandboxsafe=True,
- _nowrapper=True)
-
- init_fn_ptr()
-
- def gc_malloc(self, sizedescr):
- assert isinstance(sizedescr, BaseSizeDescr)
- return self.funcptr_for_new(sizedescr.size)
-
- def gc_malloc_array(self, arraydescr, num_elem):
- assert isinstance(arraydescr, BaseArrayDescr)
- ofs_length = arraydescr.get_ofs_length(self.translate_support_code)
- basesize = arraydescr.get_base_size(self.translate_support_code)
- itemsize = arraydescr.get_item_size(self.translate_support_code)
- return self.malloc_array(basesize, itemsize, ofs_length, num_elem)
-
- def gc_malloc_str(self, num_elem):
- return self.malloc_str(num_elem)
-
- def gc_malloc_unicode(self, num_elem):
- return self.malloc_unicode(num_elem)
-
- def args_for_new(self, sizedescr):
- assert isinstance(sizedescr, BaseSizeDescr)
- return [sizedescr.size]
-
- def args_for_new_array(self, arraydescr):
- ofs_length = arraydescr.get_ofs_length(self.translate_support_code)
- basesize = arraydescr.get_base_size(self.translate_support_code)
- itemsize = arraydescr.get_item_size(self.translate_support_code)
- return [basesize, itemsize, ofs_length]
-
- def get_funcptr_for_new(self):
- return self.funcptr_for_new
-
- def rewrite_assembler(self, cpu, operations, gcrefs_output_list):
- # record all GCREFs too, because Boehm cannot see them and keep them
- # alive if they end up as constants in the assembler
- for op in operations:
- self.record_constptrs(op, gcrefs_output_list)
- return GcLLDescription.rewrite_assembler(self, cpu, operations,
- gcrefs_output_list)
+ def _bh_malloc_array(self, arraydescr, num_elem):
+ return self.malloc_array(arraydescr.basesize, num_elem,
+ arraydescr.itemsize,
+ arraydescr.lendescr.offset)
# ____________________________________________________________
@@ -554,12 +567,14 @@
class WriteBarrierDescr(AbstractDescr):
def __init__(self, gc_ll_descr):
- GCClass = gc_ll_descr.GCClass
self.llop1 = gc_ll_descr.llop1
self.WB_FUNCPTR = gc_ll_descr.WB_FUNCPTR
self.WB_ARRAY_FUNCPTR = gc_ll_descr.WB_ARRAY_FUNCPTR
- self.fielddescr_tid = get_field_descr(gc_ll_descr, GCClass.HDR, 'tid')
+ self.fielddescr_tid = gc_ll_descr.fielddescr_tid
#
+ GCClass = gc_ll_descr.GCClass
+ if GCClass is None: # for tests
+ return
self.jit_wb_if_flag = GCClass.JIT_WB_IF_FLAG
self.jit_wb_if_flag_byteofs, self.jit_wb_if_flag_singlebyte = (
self.extract_flag_byte(self.jit_wb_if_flag))
@@ -596,48 +611,74 @@
funcaddr = llmemory.cast_ptr_to_adr(funcptr)
return cpu.cast_adr_to_int(funcaddr) # this may return 0
+ def has_write_barrier_from_array(self, cpu):
+ return self.get_write_barrier_from_array_fn(cpu) != 0
+
class GcLLDescr_framework(GcLLDescription):
DEBUG = False # forced to True by x86/test/test_zrpy_gc.py
+ kind = 'framework'
+ round_up = True
- def __init__(self, gcdescr, translator, rtyper, llop1=llop):
- from pypy.rpython.memory.gctypelayout import check_typeid
- from pypy.rpython.memory.gcheader import GCHeaderBuilder
- from pypy.rpython.memory.gctransform import framework
+ def __init__(self, gcdescr, translator, rtyper, llop1=llop,
+ really_not_translated=False):
GcLLDescription.__init__(self, gcdescr, translator, rtyper)
- assert self.translate_support_code, "required with the framework GC"
self.translator = translator
self.llop1 = llop1
+ if really_not_translated:
+ assert not self.translate_support_code # but half does not work
+ self._initialize_for_tests()
+ else:
+ assert self.translate_support_code,"required with the framework GC"
+ self._check_valid_gc()
+ self._make_gcrootmap()
+ self._make_layoutbuilder()
+ self._setup_gcclass()
+ self._setup_tid()
+ self._setup_write_barrier()
+ self._setup_str()
+ self._make_functions(really_not_translated)
+ def _initialize_for_tests(self):
+ self.layoutbuilder = None
+ self.fielddescr_tid = AbstractDescr()
+ self.max_size_of_young_obj = 1000
+ self.GCClass = None
+
+ def _check_valid_gc(self):
# we need the hybrid or minimark GC for rgc._make_sure_does_not_move()
# to work
- if gcdescr.config.translation.gc not in ('hybrid', 'minimark'):
+ if self.gcdescr.config.translation.gc not in ('hybrid', 'minimark'):
raise NotImplementedError("--gc=%s not implemented with the JIT" %
(gcdescr.config.translation.gc,))
+ def _make_gcrootmap(self):
# to find roots in the assembler, make a GcRootMap
- name = gcdescr.config.translation.gcrootfinder
+ name = self.gcdescr.config.translation.gcrootfinder
try:
cls = globals()['GcRootMap_' + name]
except KeyError:
raise NotImplementedError("--gcrootfinder=%s not implemented"
" with the JIT" % (name,))
- gcrootmap = cls(gcdescr)
+ gcrootmap = cls(self.gcdescr)
self.gcrootmap = gcrootmap
+ def _make_layoutbuilder(self):
# make a TransformerLayoutBuilder and save it on the translator
# where it can be fished and reused by the FrameworkGCTransformer
+ from pypy.rpython.memory.gctransform import framework
+ translator = self.translator
self.layoutbuilder = framework.TransformerLayoutBuilder(translator)
self.layoutbuilder.delay_encoding()
- self.translator._jit2gc = {'layoutbuilder': self.layoutbuilder}
- gcrootmap.add_jit2gc_hooks(self.translator._jit2gc)
+ translator._jit2gc = {'layoutbuilder': self.layoutbuilder}
+ self.gcrootmap.add_jit2gc_hooks(translator._jit2gc)
+ def _setup_gcclass(self):
+ from pypy.rpython.memory.gcheader import GCHeaderBuilder
self.GCClass = self.layoutbuilder.GCClass
self.moving_gc = self.GCClass.moving_gc
self.HDRPTR = lltype.Ptr(self.GCClass.HDR)
self.gcheaderbuilder = GCHeaderBuilder(self.HDRPTR.TO)
- (self.array_basesize, _, self.array_length_ofs) = \
- symbolic.get_array_token(lltype.GcArray(lltype.Signed), True)
self.max_size_of_young_obj = self.GCClass.JIT_max_size_of_young_obj()
self.minimal_size_in_nursery=self.GCClass.JIT_minimal_size_in_nursery()
@@ -645,89 +686,126 @@
assert self.GCClass.inline_simple_malloc
assert self.GCClass.inline_simple_malloc_varsize
- # make a malloc function, with two arguments
- def malloc_basic(size, tid):
- assert size > 0, 'size should be > 0'
- type_id = llop.extract_ushort(llgroup.HALFWORD, tid)
- check_typeid(type_id)
- res = llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
- type_id, size,
- False, False, False)
- # In case the operation above failed, we are returning NULL
- # from this function to assembler. There is also an RPython
- # exception set, typically MemoryError; but it's easier and
- # faster to check for the NULL return value, as done by
- # translator/exceptiontransform.py.
- #llop.debug_print(lltype.Void, "\tmalloc_basic", size, type_id,
- # "-->", res)
- return res
- self.malloc_basic = malloc_basic
- self.GC_MALLOC_BASIC = lltype.Ptr(lltype.FuncType(
- [lltype.Signed, lltype.Signed], llmemory.GCREF))
+ def _setup_tid(self):
+ self.fielddescr_tid = get_field_descr(self, self.GCClass.HDR, 'tid')
+
+ def _setup_write_barrier(self):
self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
[llmemory.Address, llmemory.Address], lltype.Void))
self.WB_ARRAY_FUNCPTR = lltype.Ptr(lltype.FuncType(
[llmemory.Address, lltype.Signed, llmemory.Address], lltype.Void))
self.write_barrier_descr = WriteBarrierDescr(self)
- #
+
+ def _make_functions(self, really_not_translated):
+ from pypy.rpython.memory.gctypelayout import check_typeid
+ llop1 = self.llop1
+ (self.standard_array_basesize, _, self.standard_array_length_ofs) = \
+ symbolic.get_array_token(lltype.GcArray(lltype.Signed),
+ not really_not_translated)
+
+ def malloc_nursery_slowpath(size):
+ """Allocate 'size' null bytes out of the nursery.
+ Note that the fast path is typically inlined by the backend."""
+ assert size >= self.minimal_size_in_nursery
+ if self.DEBUG:
+ self._random_usage_of_xmm_registers()
+ type_id = rffi.cast(llgroup.HALFWORD, 0) # missing here
+ return llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
+ type_id, size,
+ False, False, False)
+ self.generate_function('malloc_nursery', malloc_nursery_slowpath,
+ [lltype.Signed])
+
def malloc_array(itemsize, tid, num_elem):
- assert num_elem >= 0, 'num_elem should be >= 0'
+ """Allocate an array with a variable-size num_elem.
+ Only works for standard arrays."""
+ assert num_elem >= 0, 'num_elem should be >= 0'
type_id = llop.extract_ushort(llgroup.HALFWORD, tid)
check_typeid(type_id)
return llop1.do_malloc_varsize_clear(
llmemory.GCREF,
- type_id, num_elem, self.array_basesize, itemsize,
- self.array_length_ofs)
- self.malloc_array = malloc_array
- self.GC_MALLOC_ARRAY = lltype.Ptr(lltype.FuncType(
- [lltype.Signed] * 3, llmemory.GCREF))
- #
- (str_basesize, str_itemsize, str_ofs_length
- ) = symbolic.get_array_token(rstr.STR, True)
- (unicode_basesize, unicode_itemsize, unicode_ofs_length
- ) = symbolic.get_array_token(rstr.UNICODE, True)
- str_type_id = self.layoutbuilder.get_type_id(rstr.STR)
- unicode_type_id = self.layoutbuilder.get_type_id(rstr.UNICODE)
- #
+ type_id, num_elem, self.standard_array_basesize, itemsize,
+ self.standard_array_length_ofs)
+ self.generate_function('malloc_array', malloc_array,
+ [lltype.Signed] * 3)
+
+ def malloc_array_nonstandard(basesize, itemsize, lengthofs, tid,
+ num_elem):
+ """For the rare case of non-standard arrays, i.e. arrays where
+ self.standard_array_{basesize,length_ofs} is wrong. It can
+ occur e.g. with arrays of floats on Win32."""
+ type_id = llop.extract_ushort(llgroup.HALFWORD, tid)
+ check_typeid(type_id)
+ return llop1.do_malloc_varsize_clear(
+ llmemory.GCREF,
+ type_id, num_elem, basesize, itemsize, lengthofs)
+ self.generate_function('malloc_array_nonstandard',
+ malloc_array_nonstandard,
+ [lltype.Signed] * 5)
+
+ str_type_id = self.str_descr.tid
+ str_basesize = self.str_descr.basesize
+ str_itemsize = self.str_descr.itemsize
+ str_ofs_length = self.str_descr.lendescr.offset
+ unicode_type_id = self.unicode_descr.tid
+ unicode_basesize = self.unicode_descr.basesize
+ unicode_itemsize = self.unicode_descr.itemsize
+ unicode_ofs_length = self.unicode_descr.lendescr.offset
+
def malloc_str(length):
return llop1.do_malloc_varsize_clear(
llmemory.GCREF,
str_type_id, length, str_basesize, str_itemsize,
str_ofs_length)
+ self.generate_function('malloc_str', malloc_str,
+ [lltype.Signed])
+
def malloc_unicode(length):
return llop1.do_malloc_varsize_clear(
llmemory.GCREF,
- unicode_type_id, length, unicode_basesize,unicode_itemsize,
+ unicode_type_id, length, unicode_basesize, unicode_itemsize,
unicode_ofs_length)
- self.malloc_str = malloc_str
- self.malloc_unicode = malloc_unicode
- self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType(
- [lltype.Signed], llmemory.GCREF))
- #
- class ForTestOnly:
- pass
- for_test_only = ForTestOnly()
- for_test_only.x = 1.23
- def random_usage_of_xmm_registers():
- x0 = for_test_only.x
- x1 = x0 * 0.1
- x2 = x0 * 0.2
- x3 = x0 * 0.3
- for_test_only.x = x0 + x1 + x2 + x3
- #
- def malloc_slowpath(size):
- if self.DEBUG:
- random_usage_of_xmm_registers()
- assert size >= self.minimal_size_in_nursery
- # NB. although we call do_malloc_fixedsize_clear() here,
- # it's a bit of a hack because we set tid to 0 and may
- # also use it to allocate varsized objects. The tid
- # and possibly the length are both set afterward.
- gcref = llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
- 0, size, False, False, False)
- return rffi.cast(lltype.Signed, gcref)
- self.malloc_slowpath = malloc_slowpath
- self.MALLOC_SLOWPATH = lltype.FuncType([lltype.Signed], lltype.Signed)
+ self.generate_function('malloc_unicode', malloc_unicode,
+ [lltype.Signed])
+
+ # Rarely called: allocate a fixed-size amount of bytes, but
+ # not in the nursery, because it is too big. Implemented like
+ # malloc_nursery_slowpath() above.
+ self.generate_function('malloc_fixedsize', malloc_nursery_slowpath,
+ [lltype.Signed])
+
+ def _bh_malloc(self, sizedescr):
+ from pypy.rpython.memory.gctypelayout import check_typeid
+ llop1 = self.llop1
+ type_id = llop.extract_ushort(llgroup.HALFWORD, sizedescr.tid)
+ check_typeid(type_id)
+ return llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
+ type_id, sizedescr.size,
+ False, False, False)
+
+ def _bh_malloc_array(self, arraydescr, num_elem):
+ from pypy.rpython.memory.gctypelayout import check_typeid
+ llop1 = self.llop1
+ type_id = llop.extract_ushort(llgroup.HALFWORD, arraydescr.tid)
+ check_typeid(type_id)
+ return llop1.do_malloc_varsize_clear(llmemory.GCREF,
+ type_id, num_elem,
+ arraydescr.basesize,
+ arraydescr.itemsize,
+ arraydescr.lendescr.offset)
+
+
+ class ForTestOnly:
+ pass
+ for_test_only = ForTestOnly()
+ for_test_only.x = 1.23
+
+ def _random_usage_of_xmm_registers(self):
+ x0 = self.for_test_only.x
+ x1 = x0 * 0.1
+ x2 = x0 * 0.2
+ x3 = x0 * 0.3
+ self.for_test_only.x = x0 + x1 + x2 + x3
def get_nursery_free_addr(self):
nurs_addr = llop.gc_adr_of_nursery_free(llmemory.Address)
@@ -737,49 +815,26 @@
nurs_top_addr = llop.gc_adr_of_nursery_top(llmemory.Address)
return rffi.cast(lltype.Signed, nurs_top_addr)
- def get_malloc_slowpath_addr(self):
- fptr = llhelper(lltype.Ptr(self.MALLOC_SLOWPATH), self.malloc_slowpath)
- return rffi.cast(lltype.Signed, fptr)
-
def initialize(self):
self.gcrootmap.initialize()
def init_size_descr(self, S, descr):
- type_id = self.layoutbuilder.get_type_id(S)
- assert not self.layoutbuilder.is_weakref_type(S)
- assert not self.layoutbuilder.has_finalizer(S)
- descr.tid = llop.combine_ushort(lltype.Signed, type_id, 0)
+ if self.layoutbuilder is not None:
+ type_id = self.layoutbuilder.get_type_id(S)
+ assert not self.layoutbuilder.is_weakref_type(S)
+ assert not self.layoutbuilder.has_finalizer(S)
+ descr.tid = llop.combine_ushort(lltype.Signed, type_id, 0)
def init_array_descr(self, A, descr):
- type_id = self.layoutbuilder.get_type_id(A)
- descr.tid = llop.combine_ushort(lltype.Signed, type_id, 0)
+ if self.layoutbuilder is not None:
+ type_id = self.layoutbuilder.get_type_id(A)
+ descr.tid = llop.combine_ushort(lltype.Signed, type_id, 0)
- def gc_malloc(self, sizedescr):
- assert isinstance(sizedescr, BaseSizeDescr)
- return self.malloc_basic(sizedescr.size, sizedescr.tid)
-
- def gc_malloc_array(self, arraydescr, num_elem):
- assert isinstance(arraydescr, BaseArrayDescr)
- itemsize = arraydescr.get_item_size(self.translate_support_code)
- return self.malloc_array(itemsize, arraydescr.tid, num_elem)
-
- def gc_malloc_str(self, num_elem):
- return self.malloc_str(num_elem)
-
- def gc_malloc_unicode(self, num_elem):
- return self.malloc_unicode(num_elem)
-
- def args_for_new(self, sizedescr):
- assert isinstance(sizedescr, BaseSizeDescr)
- return [sizedescr.size, sizedescr.tid]
-
- def args_for_new_array(self, arraydescr):
- assert isinstance(arraydescr, BaseArrayDescr)
- itemsize = arraydescr.get_item_size(self.translate_support_code)
- return [itemsize, arraydescr.tid]
-
- def get_funcptr_for_new(self):
- return llhelper(self.GC_MALLOC_BASIC, self.malloc_basic)
+ def _set_tid(self, gcptr, tid):
+ hdr_addr = llmemory.cast_ptr_to_adr(gcptr)
+ hdr_addr -= self.gcheaderbuilder.size_gc_header
+ hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR)
+ hdr.tid = tid
def do_write_barrier(self, gcref_struct, gcref_newptr):
hdr_addr = llmemory.cast_ptr_to_adr(gcref_struct)
@@ -793,108 +848,8 @@
funcptr(llmemory.cast_ptr_to_adr(gcref_struct),
llmemory.cast_ptr_to_adr(gcref_newptr))
- def rewrite_assembler(self, cpu, operations, gcrefs_output_list):
- # Perform two kinds of rewrites in parallel:
- #
- # - Add COND_CALLs to the write barrier before SETFIELD_GC and
- # SETARRAYITEM_GC operations.
- #
- # - Record the ConstPtrs from the assembler.
- #
- newops = []
- known_lengths = {}
- # we can only remember one malloc since the next malloc can possibly
- # collect
- last_malloc = None
- for op in operations:
- if op.getopnum() == rop.DEBUG_MERGE_POINT:
- continue
- # ---------- record the ConstPtrs ----------
- self.record_constptrs(op, gcrefs_output_list)
- if op.is_malloc():
- last_malloc = op.result
- elif op.can_malloc():
- last_malloc = None
- # ---------- write barrier for SETFIELD_GC ----------
- if op.getopnum() == rop.SETFIELD_GC:
- val = op.getarg(0)
- # no need for a write barrier in the case of previous malloc
- if val is not last_malloc:
- v = op.getarg(1)
- if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
- bool(v.value)): # store a non-NULL
- self._gen_write_barrier(newops, op.getarg(0), v)
- op = op.copy_and_change(rop.SETFIELD_RAW)
- # ---------- write barrier for SETINTERIORFIELD_GC ------
- if op.getopnum() == rop.SETINTERIORFIELD_GC:
- val = op.getarg(0)
- if val is not last_malloc:
- v = op.getarg(2)
- if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
- bool(v.value)): # store a non-NULL
- self._gen_write_barrier(newops, op.getarg(0), v)
- op = op.copy_and_change(rop.SETINTERIORFIELD_RAW)
- # ---------- write barrier for SETARRAYITEM_GC ----------
- if op.getopnum() == rop.SETARRAYITEM_GC:
- val = op.getarg(0)
- # no need for a write barrier in the case of previous malloc
- if val is not last_malloc:
- v = op.getarg(2)
- if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
- bool(v.value)): # store a non-NULL
- self._gen_write_barrier_array(newops, op.getarg(0),
- op.getarg(1), v,
- cpu, known_lengths)
- op = op.copy_and_change(rop.SETARRAYITEM_RAW)
- elif op.getopnum() == rop.NEW_ARRAY:
- v_length = op.getarg(0)
- if isinstance(v_length, ConstInt):
- known_lengths[op.result] = v_length.getint()
- # ----------
- newops.append(op)
- return newops
-
- def _gen_write_barrier(self, newops, v_base, v_value):
- args = [v_base, v_value]
- newops.append(ResOperation(rop.COND_CALL_GC_WB, args, None,
- descr=self.write_barrier_descr))
-
- def _gen_write_barrier_array(self, newops, v_base, v_index, v_value,
- cpu, known_lengths):
- if self.write_barrier_descr.get_write_barrier_from_array_fn(cpu) != 0:
- # If we know statically the length of 'v', and it is not too
- # big, then produce a regular write_barrier. If it's unknown or
- # too big, produce instead a write_barrier_from_array.
- LARGE = 130
- length = known_lengths.get(v_base, LARGE)
- if length >= LARGE:
- # unknown or too big: produce a write_barrier_from_array
- args = [v_base, v_index, v_value]
- newops.append(ResOperation(rop.COND_CALL_GC_WB_ARRAY, args,
- None,
- descr=self.write_barrier_descr))
- return
- # fall-back case: produce a write_barrier
- self._gen_write_barrier(newops, v_base, v_value)
-
- def can_inline_malloc(self, descr):
- assert isinstance(descr, BaseSizeDescr)
- if descr.size < self.max_size_of_young_obj:
- has_finalizer = bool(descr.tid & (1<<llgroup.HALFSHIFT))
- if has_finalizer:
- return False
- return True
- return False
-
- def can_inline_malloc_varsize(self, arraydescr, num_elem):
- assert isinstance(arraydescr, BaseArrayDescr)
- basesize = arraydescr.get_base_size(self.translate_support_code)
- itemsize = arraydescr.get_item_size(self.translate_support_code)
- try:
- size = ovfcheck(basesize + ovfcheck(itemsize * num_elem))
- return size < self.max_size_of_young_obj
- except OverflowError:
- return False
+ def can_use_nursery_malloc(self, size):
+ return size < self.max_size_of_young_obj
def has_write_barrier_class(self):
return WriteBarrierDescr
@@ -902,6 +857,9 @@
def freeing_block(self, start, stop):
self.gcrootmap.freeing_block(start, stop)
+ def get_malloc_slowpath_addr(self):
+ return self.get_malloc_fn_addr('malloc_nursery')
+
# ____________________________________________________________
def get_ll_description(gcdescr, translator=None, rtyper=None):
diff --git a/pypy/jit/backend/llsupport/llmodel.py b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -8,11 +8,10 @@
from pypy.jit.backend.model import AbstractCPU
from pypy.jit.backend.llsupport import symbolic
from pypy.jit.backend.llsupport.symbolic import WORD, unroll_basic_sizes
-from pypy.jit.backend.llsupport.descr import (get_size_descr,
- get_field_descr, BaseFieldDescr, DynamicFieldDescr, get_array_descr,
- BaseArrayDescr, DynamicArrayNoLengthDescr, get_call_descr,
- BaseIntCallDescr, GcPtrCallDescr, FloatCallDescr, VoidCallDescr,
- InteriorFieldDescr, get_interiorfield_descr)
+from pypy.jit.backend.llsupport.descr import (
+ get_size_descr, get_field_descr, get_array_descr,
+ get_call_descr, get_interiorfield_descr, get_dynamic_interiorfield_descr,
+ FieldDescr, ArrayDescr, CallDescr, InteriorFieldDescr)
from pypy.jit.backend.llsupport.asmmemmgr import AsmMemoryManager
@@ -107,9 +106,15 @@
_exception_emulator[1] = 0
self.saved_exc_value = rffi.cast(llmemory.GCREF, v_i)
+ def save_exception_memoryerr():
+ save_exception()
+ if not self.saved_exc_value:
+ self.saved_exc_value = "memoryerror!" # for tests
+
self.pos_exception = pos_exception
self.pos_exc_value = pos_exc_value
self.save_exception = save_exception
+ self.save_exception_memoryerr = save_exception_memoryerr
self.insert_stack_check = lambda: (0, 0, 0)
@@ -134,6 +139,15 @@
# in the assignment to self.saved_exc_value, as needed.
self.saved_exc_value = exc_value
+ def save_exception_memoryerr():
+ from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
+ save_exception()
+ if not self.saved_exc_value:
+ exc = MemoryError()
+ exc = cast_instance_to_base_ptr(exc)
+ exc = lltype.cast_opaque_ptr(llmemory.GCREF, exc)
+ self.saved_exc_value = exc
+
from pypy.rlib import rstack
STACK_CHECK_SLOWPATH = lltype.Ptr(lltype.FuncType([lltype.Signed],
lltype.Void))
@@ -147,16 +161,19 @@
self.pos_exception = pos_exception
self.pos_exc_value = pos_exc_value
self.save_exception = save_exception
+ self.save_exception_memoryerr = save_exception_memoryerr
self.insert_stack_check = insert_stack_check
def _setup_on_leave_jitted_untranslated(self):
# assume we don't need a backend leave in this case
self.on_leave_jitted_save_exc = self.save_exception
+ self.on_leave_jitted_memoryerr = self.save_exception_memoryerr
self.on_leave_jitted_noexc = lambda : None
def _setup_on_leave_jitted_translated(self):
on_leave_jitted_hook = self.get_on_leave_jitted_hook()
save_exception = self.save_exception
+ save_exception_memoryerr = self.save_exception_memoryerr
def on_leave_jitted_noexc():
on_leave_jitted_hook()
@@ -165,8 +182,13 @@
save_exception()
on_leave_jitted_hook()
+ def on_leave_jitted_memoryerr():
+ save_exception_memoryerr()
+ on_leave_jitted_hook()
+
self.on_leave_jitted_noexc = on_leave_jitted_noexc
self.on_leave_jitted_save_exc = on_leave_jitted_save_exc
+ self.on_leave_jitted_memoryerr = on_leave_jitted_memoryerr
def get_on_leave_jitted_hook(self):
# this function needs to be overridden for things to work with
@@ -175,8 +197,11 @@
_ON_JIT_LEAVE_FUNC = lltype.Ptr(lltype.FuncType([], lltype.Void))
- def get_on_leave_jitted_int(self, save_exception):
- if save_exception:
+ def get_on_leave_jitted_int(self, save_exception,
+ default_to_memoryerror=False):
+ if default_to_memoryerror:
+ f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_memoryerr)
+ elif save_exception:
f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_save_exc)
else:
f = llhelper(self._ON_JIT_LEAVE_FUNC, self.on_leave_jitted_noexc)
@@ -223,14 +248,14 @@
return get_field_descr(self.gc_ll_descr, STRUCT, fieldname)
def unpack_fielddescr(self, fielddescr):
- assert isinstance(fielddescr, BaseFieldDescr)
+ assert isinstance(fielddescr, FieldDescr)
return fielddescr.offset
unpack_fielddescr._always_inline_ = True
def unpack_fielddescr_size(self, fielddescr):
- assert isinstance(fielddescr, BaseFieldDescr)
+ assert isinstance(fielddescr, FieldDescr)
ofs = fielddescr.offset
- size = fielddescr.get_field_size(self.translate_support_code)
+ size = fielddescr.field_size
sign = fielddescr.is_field_signed()
return ofs, size, sign
unpack_fielddescr_size._always_inline_ = True
@@ -239,23 +264,23 @@
return get_array_descr(self.gc_ll_descr, A)
def interiorfielddescrof(self, A, fieldname):
- return get_interiorfield_descr(self.gc_ll_descr, A, A.OF, fieldname)
+ return get_interiorfield_descr(self.gc_ll_descr, A, fieldname)
def interiorfielddescrof_dynamic(self, offset, width, fieldsize,
- is_pointer, is_float, is_signed):
- arraydescr = DynamicArrayNoLengthDescr(width)
- fielddescr = DynamicFieldDescr(offset, fieldsize, is_pointer, is_float, is_signed)
- return InteriorFieldDescr(arraydescr, fielddescr)
+ is_pointer, is_float, is_signed):
+ return get_dynamic_interiorfield_descr(self.gc_ll_descr,
+ offset, width, fieldsize,
+ is_pointer, is_float, is_signed)
def unpack_arraydescr(self, arraydescr):
- assert isinstance(arraydescr, BaseArrayDescr)
- return arraydescr.get_base_size(self.translate_support_code)
+ assert isinstance(arraydescr, ArrayDescr)
+ return arraydescr.basesize
unpack_arraydescr._always_inline_ = True
def unpack_arraydescr_size(self, arraydescr):
- assert isinstance(arraydescr, BaseArrayDescr)
- ofs = arraydescr.get_base_size(self.translate_support_code)
- size = arraydescr.get_item_size(self.translate_support_code)
+ assert isinstance(arraydescr, ArrayDescr)
+ ofs = arraydescr.basesize
+ size = arraydescr.itemsize
sign = arraydescr.is_item_signed()
return ofs, size, sign
unpack_arraydescr_size._always_inline_ = True
@@ -283,8 +308,8 @@
# ____________________________________________________________
def bh_arraylen_gc(self, arraydescr, array):
- assert isinstance(arraydescr, BaseArrayDescr)
- ofs = arraydescr.get_ofs_length(self.translate_support_code)
+ assert isinstance(arraydescr, ArrayDescr)
+ ofs = arraydescr.lendescr.offset
return rffi.cast(rffi.CArrayPtr(lltype.Signed), array)[ofs/WORD]
@specialize.argtype(2)
@@ -369,7 +394,7 @@
arraydescr = descr.arraydescr
ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
ofs += descr.fielddescr.offset
- fieldsize = descr.fielddescr.get_field_size(self.translate_support_code)
+ fieldsize = descr.fielddescr.field_size
sign = descr.fielddescr.is_field_signed()
fullofs = itemindex * size + ofs
# --- start of GC unsafe code (no GC operation!) ---
@@ -420,7 +445,7 @@
arraydescr = descr.arraydescr
ofs, size, _ = self.unpack_arraydescr_size(arraydescr)
ofs += descr.fielddescr.offset
- fieldsize = descr.fielddescr.get_field_size(self.translate_support_code)
+ fieldsize = descr.fielddescr.field_size
ofs = itemindex * size + ofs
# --- start of GC unsafe code (no GC operation!) ---
items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs)
@@ -606,25 +631,26 @@
rstr.copy_unicode_contents(src, dst, srcstart, dststart, length)
def bh_call_i(self, func, calldescr, args_i, args_r, args_f):
- assert isinstance(calldescr, BaseIntCallDescr)
+ assert isinstance(calldescr, CallDescr)
if not we_are_translated():
calldescr.verify_types(args_i, args_r, args_f, history.INT + 'S')
- return calldescr.call_stub(func, args_i, args_r, args_f)
+ return calldescr.call_stub_i(func, args_i, args_r, args_f)
def bh_call_r(self, func, calldescr, args_i, args_r, args_f):
- assert isinstance(calldescr, GcPtrCallDescr)
+ assert isinstance(calldescr, CallDescr)
if not we_are_translated():
calldescr.verify_types(args_i, args_r, args_f, history.REF)
- return calldescr.call_stub(func, args_i, args_r, args_f)
+ return calldescr.call_stub_r(func, args_i, args_r, args_f)
def bh_call_f(self, func, calldescr, args_i, args_r, args_f):
- assert isinstance(calldescr, FloatCallDescr) # or LongLongCallDescr
+ assert isinstance(calldescr, CallDescr)
if not we_are_translated():
calldescr.verify_types(args_i, args_r, args_f, history.FLOAT + 'L')
- return calldescr.call_stub(func, args_i, args_r, args_f)
+ return calldescr.call_stub_f(func, args_i, args_r, args_f)
def bh_call_v(self, func, calldescr, args_i, args_r, args_f):
- assert isinstance(calldescr, VoidCallDescr)
+ assert isinstance(calldescr, CallDescr)
if not we_are_translated():
calldescr.verify_types(args_i, args_r, args_f, history.VOID)
- return calldescr.call_stub(func, args_i, args_r, args_f)
+ # the 'i' return value is ignored (and nonsense anyway)
+ calldescr.call_stub_i(func, args_i, args_r, args_f)
diff --git a/pypy/jit/backend/llsupport/regalloc.py b/pypy/jit/backend/llsupport/regalloc.py
--- a/pypy/jit/backend/llsupport/regalloc.py
+++ b/pypy/jit/backend/llsupport/regalloc.py
@@ -70,6 +70,8 @@
self.bindings[box] = loc
#
index = self.get_loc_index(loc)
+ if index < 0:
+ return
endindex = index + self.frame_size(box.type)
while len(self.used) < endindex:
self.used.append(False)
@@ -92,6 +94,8 @@
#
size = self.frame_size(box.type)
baseindex = self.get_loc_index(loc)
+ if baseindex < 0:
+ return
for i in range(size):
index = baseindex + i
assert 0 <= index < len(self.used)
@@ -99,7 +103,8 @@
def try_to_reuse_location(self, box, loc):
index = self.get_loc_index(loc)
- assert index >= 0
+ if index < 0:
+ return False
size = self.frame_size(box.type)
for i in range(size):
while (index + i) >= len(self.used):
diff --git a/pypy/jit/backend/llsupport/rewrite.py b/pypy/jit/backend/llsupport/rewrite.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/llsupport/rewrite.py
@@ -0,0 +1,328 @@
+import sys
+from pypy.rlib.rarithmetic import ovfcheck
+from pypy.jit.metainterp.history import ConstInt, BoxPtr, ConstPtr
+from pypy.jit.metainterp.resoperation import ResOperation, rop
+from pypy.jit.codewriter import heaptracker
+from pypy.jit.backend.llsupport.symbolic import WORD
+from pypy.jit.backend.llsupport.descr import SizeDescr, ArrayDescr
+
+
+class GcRewriterAssembler(object):
+ # This class performs the following rewrites on the list of operations:
+ #
+ # - Remove the DEBUG_MERGE_POINTs.
+ #
+ # - Turn all NEW_xxx to either a CALL_MALLOC_GC, or a CALL_MALLOC_NURSERY
+ # followed by SETFIELDs in order to initialize their GC fields. The
+ # two advantages of CALL_MALLOC_NURSERY is that it inlines the common
+ # path, and we need only one such operation to allocate several blocks
+ # of memory at once.
+ #
+ # - Add COND_CALLs to the write barrier before SETFIELD_GC and
+ # SETARRAYITEM_GC operations.
+
+ _previous_size = -1
+ _op_malloc_nursery = None
+ _v_last_malloced_nursery = None
+ c_zero = ConstInt(0)
+
+ def __init__(self, gc_ll_descr, cpu):
+ self.gc_ll_descr = gc_ll_descr
+ self.cpu = cpu
+ self.newops = []
+ self.known_lengths = {}
+ self.recent_mallocs = {} # set of variables
+
+ def rewrite(self, operations):
+ # we can only remember one malloc since the next malloc can possibly
+ # collect; but we can try to collapse several known-size mallocs into
+ # one, both for performance and to reduce the number of write
+ # barriers. We do this on each "basic block" of operations, which in
+ # this case means between CALLs or unknown-size mallocs.
+ #
+ for op in operations:
+ if op.getopnum() == rop.DEBUG_MERGE_POINT:
+ continue
+ # ---------- turn NEWxxx into CALL_MALLOC_xxx ----------
+ if op.is_malloc():
+ self.handle_malloc_operation(op)
+ continue
+ elif op.can_malloc():
+ self.emitting_an_operation_that_can_collect()
+ elif op.getopnum() == rop.LABEL:
+ self.emitting_an_operation_that_can_collect()
+ self.known_lengths.clear()
+ # ---------- write barriers ----------
+ if self.gc_ll_descr.write_barrier_descr is not None:
+ if op.getopnum() == rop.SETFIELD_GC:
+ self.handle_write_barrier_setfield(op)
+ continue
+ if op.getopnum() == rop.SETINTERIORFIELD_GC:
+ self.handle_write_barrier_setinteriorfield(op)
+ continue
+ if op.getopnum() == rop.SETARRAYITEM_GC:
+ self.handle_write_barrier_setarrayitem(op)
+ continue
+ # ----------
+ self.newops.append(op)
+ return self.newops
+
+ # ----------
+
+ def handle_malloc_operation(self, op):
+ opnum = op.getopnum()
+ if opnum == rop.NEW:
+ self.handle_new_fixedsize(op.getdescr(), op)
+ elif opnum == rop.NEW_WITH_VTABLE:
+ classint = op.getarg(0).getint()
+ descr = heaptracker.vtable2descr(self.cpu, classint)
+ self.handle_new_fixedsize(descr, op)
+ if self.gc_ll_descr.fielddescr_vtable is not None:
+ op = ResOperation(rop.SETFIELD_GC,
+ [op.result, ConstInt(classint)], None,
+ descr=self.gc_ll_descr.fielddescr_vtable)
+ self.newops.append(op)
+ elif opnum == rop.NEW_ARRAY:
+ descr = op.getdescr()
+ assert isinstance(descr, ArrayDescr)
+ self.handle_new_array(descr, op)
+ elif opnum == rop.NEWSTR:
+ self.handle_new_array(self.gc_ll_descr.str_descr, op)
+ elif opnum == rop.NEWUNICODE:
+ self.handle_new_array(self.gc_ll_descr.unicode_descr, op)
+ else:
+ raise NotImplementedError(op.getopname())
+
+ def handle_new_fixedsize(self, descr, op):
+ assert isinstance(descr, SizeDescr)
+ size = descr.size
+ self.gen_malloc_nursery(size, op.result)
+ self.gen_initialize_tid(op.result, descr.tid)
+
+ def handle_new_array(self, arraydescr, op):
+ v_length = op.getarg(0)
+ total_size = -1
+ if isinstance(v_length, ConstInt):
+ num_elem = v_length.getint()
+ self.known_lengths[op.result] = num_elem
+ try:
+ var_size = ovfcheck(arraydescr.itemsize * num_elem)
+ total_size = ovfcheck(arraydescr.basesize + var_size)
+ except OverflowError:
+ pass # total_size is still -1
+ elif arraydescr.itemsize == 0:
+ total_size = arraydescr.basesize
+ if 0 <= total_size <= 0xffffff: # up to 16MB, arbitrarily
+ self.gen_malloc_nursery(total_size, op.result)
+ self.gen_initialize_tid(op.result, arraydescr.tid)
+ self.gen_initialize_len(op.result, v_length, arraydescr.lendescr)
+ elif self.gc_ll_descr.kind == 'boehm':
+ self.gen_boehm_malloc_array(arraydescr, v_length, op.result)
+ else:
+ opnum = op.getopnum()
+ if opnum == rop.NEW_ARRAY:
+ self.gen_malloc_array(arraydescr, v_length, op.result)
+ elif opnum == rop.NEWSTR:
+ self.gen_malloc_str(v_length, op.result)
+ elif opnum == rop.NEWUNICODE:
+ self.gen_malloc_unicode(v_length, op.result)
+ else:
+ raise NotImplementedError(op.getopname())
+
+ # ----------
+
+ def emitting_an_operation_that_can_collect(self):
+ # must be called whenever we emit an operation that can collect:
+ # forgets the previous MALLOC_NURSERY, if any; and empty the
+ # set 'recent_mallocs', so that future SETFIELDs will generate
+ # a write barrier as usual.
+ self._op_malloc_nursery = None
+ self.recent_mallocs.clear()
+
+ def _gen_call_malloc_gc(self, args, v_result, descr):
+ """Generate a CALL_MALLOC_GC with the given args."""
+ self.emitting_an_operation_that_can_collect()
+ op = ResOperation(rop.CALL_MALLOC_GC, args, v_result, descr)
+ self.newops.append(op)
+ # mark 'v_result' as freshly malloced
+ self.recent_mallocs[v_result] = None
+
+ def gen_malloc_fixedsize(self, size, v_result):
+ """Generate a CALL_MALLOC_GC(malloc_fixedsize_fn, Const(size)).
+ Note that with the framework GC, this should be called very rarely.
+ """
+ addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_fixedsize')
+ self._gen_call_malloc_gc([ConstInt(addr), ConstInt(size)], v_result,
+ self.gc_ll_descr.malloc_fixedsize_descr)
+
+ def gen_boehm_malloc_array(self, arraydescr, v_num_elem, v_result):
+ """Generate a CALL_MALLOC_GC(malloc_array_fn, ...) for Boehm."""
+ addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_array')
+ self._gen_call_malloc_gc([ConstInt(addr),
+ ConstInt(arraydescr.basesize),
+ v_num_elem,
+ ConstInt(arraydescr.itemsize),
+ ConstInt(arraydescr.lendescr.offset)],
+ v_result,
+ self.gc_ll_descr.malloc_array_descr)
+
+ def gen_malloc_array(self, arraydescr, v_num_elem, v_result):
+ """Generate a CALL_MALLOC_GC(malloc_array_fn, ...) going either
+ to the standard or the nonstandard version of the function."""
+ #
+ if (arraydescr.basesize == self.gc_ll_descr.standard_array_basesize
+ and arraydescr.lendescr.offset ==
+ self.gc_ll_descr.standard_array_length_ofs):
+ # this is a standard-looking array, common case
+ addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_array')
+ args = [ConstInt(addr),
+ ConstInt(arraydescr.itemsize),
+ ConstInt(arraydescr.tid),
+ v_num_elem]
+ calldescr = self.gc_ll_descr.malloc_array_descr
+ else:
+ # rare case, so don't care too much about the number of arguments
+ addr = self.gc_ll_descr.get_malloc_fn_addr(
+ 'malloc_array_nonstandard')
+ args = [ConstInt(addr),
+ ConstInt(arraydescr.basesize),
+ ConstInt(arraydescr.itemsize),
+ ConstInt(arraydescr.lendescr.offset),
+ ConstInt(arraydescr.tid),
+ v_num_elem]
+ calldescr = self.gc_ll_descr.malloc_array_nonstandard_descr
+ self._gen_call_malloc_gc(args, v_result, calldescr)
+
+ def gen_malloc_str(self, v_num_elem, v_result):
+ """Generate a CALL_MALLOC_GC(malloc_str_fn, ...)."""
+ addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_str')
+ self._gen_call_malloc_gc([ConstInt(addr), v_num_elem], v_result,
+ self.gc_ll_descr.malloc_str_descr)
+
+ def gen_malloc_unicode(self, v_num_elem, v_result):
+ """Generate a CALL_MALLOC_GC(malloc_unicode_fn, ...)."""
+ addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_unicode')
+ self._gen_call_malloc_gc([ConstInt(addr), v_num_elem], v_result,
+ self.gc_ll_descr.malloc_unicode_descr)
+
+ def gen_malloc_nursery(self, size, v_result):
+ """Try to generate or update a CALL_MALLOC_NURSERY.
+ If that fails, generate a plain CALL_MALLOC_GC instead.
+ """
+ size = self.round_up_for_allocation(size)
+ if not self.gc_ll_descr.can_use_nursery_malloc(size):
+ self.gen_malloc_fixedsize(size, v_result)
+ return
+ #
+ op = None
+ if self._op_malloc_nursery is not None:
+ # already a MALLOC_NURSERY: increment its total size
+ total_size = self._op_malloc_nursery.getarg(0).getint()
+ total_size += size
+ if self.gc_ll_descr.can_use_nursery_malloc(total_size):
+ # if the total size is still reasonable, merge it
+ self._op_malloc_nursery.setarg(0, ConstInt(total_size))
+ op = ResOperation(rop.INT_ADD,
+ [self._v_last_malloced_nursery,
+ ConstInt(self._previous_size)],
+ v_result)
+ if op is None:
+ # if we failed to merge with a previous MALLOC_NURSERY, emit one
+ self.emitting_an_operation_that_can_collect()
+ op = ResOperation(rop.CALL_MALLOC_NURSERY,
+ [ConstInt(size)],
+ v_result)
+ self._op_malloc_nursery = op
+ #
+ self.newops.append(op)
+ self._previous_size = size
+ self._v_last_malloced_nursery = v_result
+ self.recent_mallocs[v_result] = None
+
+ def gen_initialize_tid(self, v_newgcobj, tid):
+ if self.gc_ll_descr.fielddescr_tid is not None:
+ # produce a SETFIELD to initialize the GC header
+ op = ResOperation(rop.SETFIELD_GC,
+ [v_newgcobj, ConstInt(tid)], None,
+ descr=self.gc_ll_descr.fielddescr_tid)
+ self.newops.append(op)
+
+ def gen_initialize_len(self, v_newgcobj, v_length, arraylen_descr):
+ # produce a SETFIELD to initialize the array length
+ op = ResOperation(rop.SETFIELD_GC,
+ [v_newgcobj, v_length], None,
+ descr=arraylen_descr)
+ self.newops.append(op)
+
+ # ----------
+
+ def handle_write_barrier_setfield(self, op):
+ val = op.getarg(0)
+ # no need for a write barrier in the case of previous malloc
+ if val not in self.recent_mallocs:
+ v = op.getarg(1)
+ if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
+ bool(v.value)): # store a non-NULL
+ self.gen_write_barrier(op.getarg(0), v)
+ op = op.copy_and_change(rop.SETFIELD_RAW)
+ self.newops.append(op)
+
+ def handle_write_barrier_setinteriorfield(self, op):
+ val = op.getarg(0)
+ # no need for a write barrier in the case of previous malloc
+ if val not in self.recent_mallocs:
+ v = op.getarg(2)
+ if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
+ bool(v.value)): # store a non-NULL
+ self.gen_write_barrier(op.getarg(0), v)
+ op = op.copy_and_change(rop.SETINTERIORFIELD_RAW)
+ self.newops.append(op)
+
+ def handle_write_barrier_setarrayitem(self, op):
+ val = op.getarg(0)
+ # no need for a write barrier in the case of previous malloc
+ if val not in self.recent_mallocs:
+ v = op.getarg(2)
+ if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
+ bool(v.value)): # store a non-NULL
+ self.gen_write_barrier_array(op.getarg(0),
+ op.getarg(1), v)
+ op = op.copy_and_change(rop.SETARRAYITEM_RAW)
+ self.newops.append(op)
+
+ def gen_write_barrier(self, v_base, v_value):
+ write_barrier_descr = self.gc_ll_descr.write_barrier_descr
+ args = [v_base, v_value]
+ self.newops.append(ResOperation(rop.COND_CALL_GC_WB, args, None,
+ descr=write_barrier_descr))
+
+ def gen_write_barrier_array(self, v_base, v_index, v_value):
+ write_barrier_descr = self.gc_ll_descr.write_barrier_descr
+ if write_barrier_descr.has_write_barrier_from_array(self.cpu):
+ # If we know statically the length of 'v', and it is not too
+ # big, then produce a regular write_barrier. If it's unknown or
+ # too big, produce instead a write_barrier_from_array.
+ LARGE = 130
+ length = self.known_lengths.get(v_base, LARGE)
+ if length >= LARGE:
+ # unknown or too big: produce a write_barrier_from_array
+ args = [v_base, v_index, v_value]
+ self.newops.append(
+ ResOperation(rop.COND_CALL_GC_WB_ARRAY, args, None,
+ descr=write_barrier_descr))
+ return
+ # fall-back case: produce a write_barrier
+ self.gen_write_barrier(v_base, v_value)
+
+ def round_up_for_allocation(self, size):
+ if not self.gc_ll_descr.round_up:
+ return size
+ if self.gc_ll_descr.translate_support_code:
+ from pypy.rpython.lltypesystem import llarena
+ return llarena.round_up_for_allocation(
+ size, self.gc_ll_descr.minimal_size_in_nursery)
+ else:
+ # non-translated: do it manually
+ # assume that "self.gc_ll_descr.minimal_size_in_nursery" is 2 WORDs
+ size = max(size, 2 * WORD)
+ return (size + WORD-1) & ~(WORD-1) # round up
diff --git a/pypy/jit/backend/llsupport/test/test_descr.py b/pypy/jit/backend/llsupport/test/test_descr.py
--- a/pypy/jit/backend/llsupport/test/test_descr.py
+++ b/pypy/jit/backend/llsupport/test/test_descr.py
@@ -1,4 +1,4 @@
-from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.rpython.lltypesystem import lltype, rffi, rstr
from pypy.jit.backend.llsupport.descr import *
from pypy.jit.backend.llsupport import symbolic
from pypy.rlib.objectmodel import Symbolic
@@ -53,18 +53,6 @@
('z', lltype.Ptr(U)),
('f', lltype.Float),
('s', lltype.SingleFloat))
- assert getFieldDescrClass(lltype.Ptr(T)) is GcPtrFieldDescr
- assert getFieldDescrClass(lltype.Ptr(U)) is NonGcPtrFieldDescr
- cls = getFieldDescrClass(lltype.Char)
- assert cls != getFieldDescrClass(lltype.Signed)
- assert cls == getFieldDescrClass(lltype.Char)
- clsf = getFieldDescrClass(lltype.Float)
- assert clsf != cls
- assert clsf == getFieldDescrClass(lltype.Float)
- clss = getFieldDescrClass(lltype.SingleFloat)
- assert clss not in (cls, clsf)
- assert clss == getFieldDescrClass(lltype.SingleFloat)
- assert clss == getFieldDescrClass(rffi.UINT) # for now
#
c0 = GcCache(False)
c1 = GcCache(True)
@@ -77,11 +65,7 @@
descr_z = get_field_descr(c2, S, 'z')
descr_f = get_field_descr(c2, S, 'f')
descr_s = get_field_descr(c2, S, 's')
- assert descr_x.__class__ is cls
- assert descr_y.__class__ is GcPtrFieldDescr
- assert descr_z.__class__ is NonGcPtrFieldDescr
- assert descr_f.__class__ is clsf
- assert descr_s.__class__ is clss
+ assert isinstance(descr_x, FieldDescr)
assert descr_x.name == 'S.x'
assert descr_y.name == 'S.y'
assert descr_z.name == 'S.z'
@@ -90,33 +74,27 @@
if not tsc:
assert descr_x.offset < descr_y.offset < descr_z.offset
assert descr_x.sort_key() < descr_y.sort_key() < descr_z.sort_key()
- assert descr_x.get_field_size(False) == rffi.sizeof(lltype.Char)
- assert descr_y.get_field_size(False) == rffi.sizeof(lltype.Ptr(T))
- assert descr_z.get_field_size(False) == rffi.sizeof(lltype.Ptr(U))
- assert descr_f.get_field_size(False) == rffi.sizeof(lltype.Float)
- assert descr_s.get_field_size(False) == rffi.sizeof(
- lltype.SingleFloat)
+ assert descr_x.field_size == rffi.sizeof(lltype.Char)
+ assert descr_y.field_size == rffi.sizeof(lltype.Ptr(T))
+ assert descr_z.field_size == rffi.sizeof(lltype.Ptr(U))
+ assert descr_f.field_size == rffi.sizeof(lltype.Float)
+ assert descr_s.field_size == rffi.sizeof(lltype.SingleFloat)
else:
assert isinstance(descr_x.offset, Symbolic)
assert isinstance(descr_y.offset, Symbolic)
assert isinstance(descr_z.offset, Symbolic)
assert isinstance(descr_f.offset, Symbolic)
assert isinstance(descr_s.offset, Symbolic)
- assert isinstance(descr_x.get_field_size(True), Symbolic)
- assert isinstance(descr_y.get_field_size(True), Symbolic)
- assert isinstance(descr_z.get_field_size(True), Symbolic)
- assert isinstance(descr_f.get_field_size(True), Symbolic)
- assert isinstance(descr_s.get_field_size(True), Symbolic)
- assert not descr_x.is_pointer_field()
- assert descr_y.is_pointer_field()
- assert not descr_z.is_pointer_field()
- assert not descr_f.is_pointer_field()
- assert not descr_s.is_pointer_field()
- assert not descr_x.is_float_field()
- assert not descr_y.is_float_field()
- assert not descr_z.is_float_field()
- assert descr_f.is_float_field()
- assert not descr_s.is_float_field()
+ assert isinstance(descr_x.field_size, Symbolic)
+ assert isinstance(descr_y.field_size, Symbolic)
+ assert isinstance(descr_z.field_size, Symbolic)
+ assert isinstance(descr_f.field_size, Symbolic)
+ assert isinstance(descr_s.field_size, Symbolic)
+ assert descr_x.flag == FLAG_UNSIGNED
+ assert descr_y.flag == FLAG_POINTER
+ assert descr_z.flag == FLAG_UNSIGNED
+ assert descr_f.flag == FLAG_FLOAT
+ assert descr_s.flag == FLAG_UNSIGNED
def test_get_field_descr_sign():
@@ -128,7 +106,8 @@
for tsc in [False, True]:
c2 = GcCache(tsc)
descr_x = get_field_descr(c2, S, 'x')
- assert descr_x.is_field_signed() == signed
+ assert descr_x.flag == {False: FLAG_UNSIGNED,
+ True: FLAG_SIGNED }[signed]
def test_get_field_descr_longlong():
if sys.maxint > 2147483647:
@@ -136,9 +115,8 @@
c0 = GcCache(False)
S = lltype.GcStruct('S', ('y', lltype.UnsignedLongLong))
descr = get_field_descr(c0, S, 'y')
- assert not descr.is_pointer_field()
- assert descr.is_float_field()
- assert descr.get_field_size(False) == 8
+ assert descr.flag == FLAG_FLOAT
+ assert descr.field_size == 8
def test_get_array_descr():
@@ -149,19 +127,8 @@
A3 = lltype.GcArray(lltype.Ptr(U))
A4 = lltype.GcArray(lltype.Float)
A5 = lltype.GcArray(lltype.Struct('x', ('v', lltype.Signed),
- ('k', lltype.Signed)))
+ ('k', lltype.Signed)))
A6 = lltype.GcArray(lltype.SingleFloat)
- assert getArrayDescrClass(A2) is GcPtrArrayDescr
- assert getArrayDescrClass(A3) is NonGcPtrArrayDescr
- cls = getArrayDescrClass(A1)
- assert cls != getArrayDescrClass(lltype.GcArray(lltype.Signed))
- assert cls == getArrayDescrClass(lltype.GcArray(lltype.Char))
- clsf = getArrayDescrClass(A4)
- assert clsf != cls
- assert clsf == getArrayDescrClass(lltype.GcArray(lltype.Float))
- clss = getArrayDescrClass(A6)
- assert clss not in (clsf, cls)
- assert clss == getArrayDescrClass(lltype.GcArray(rffi.UINT))
#
c0 = GcCache(False)
descr1 = get_array_descr(c0, A1)
@@ -170,82 +137,61 @@
descr4 = get_array_descr(c0, A4)
descr5 = get_array_descr(c0, A5)
descr6 = get_array_descr(c0, A6)
- assert descr1.__class__ is cls
- assert descr2.__class__ is GcPtrArrayDescr
- assert descr3.__class__ is NonGcPtrArrayDescr
- assert descr4.__class__ is clsf
- assert descr6.__class__ is clss
+ assert isinstance(descr1, ArrayDescr)
assert descr1 == get_array_descr(c0, lltype.GcArray(lltype.Char))
- assert not descr1.is_array_of_pointers()
- assert descr2.is_array_of_pointers()
- assert not descr3.is_array_of_pointers()
- assert not descr4.is_array_of_pointers()
- assert not descr5.is_array_of_pointers()
- assert not descr1.is_array_of_floats()
- assert not descr2.is_array_of_floats()
- assert not descr3.is_array_of_floats()
- assert descr4.is_array_of_floats()
- assert not descr5.is_array_of_floats()
+ assert descr1.flag == FLAG_UNSIGNED
+ assert descr2.flag == FLAG_POINTER
+ assert descr3.flag == FLAG_UNSIGNED
+ assert descr4.flag == FLAG_FLOAT
+ assert descr5.flag == FLAG_STRUCT
+ assert descr6.flag == FLAG_UNSIGNED
#
def get_alignment(code):
# Retrieve default alignment for the compiler/platform
return struct.calcsize('l' + code) - struct.calcsize(code)
- assert descr1.get_base_size(False) == get_alignment('c')
- assert descr2.get_base_size(False) == get_alignment('p')
- assert descr3.get_base_size(False) == get_alignment('p')
- assert descr4.get_base_size(False) == get_alignment('d')
- assert descr5.get_base_size(False) == get_alignment('f')
- assert descr1.get_ofs_length(False) == 0
- assert descr2.get_ofs_length(False) == 0
- assert descr3.get_ofs_length(False) == 0
- assert descr4.get_ofs_length(False) == 0
- assert descr5.get_ofs_length(False) == 0
- assert descr1.get_item_size(False) == rffi.sizeof(lltype.Char)
- assert descr2.get_item_size(False) == rffi.sizeof(lltype.Ptr(T))
- assert descr3.get_item_size(False) == rffi.sizeof(lltype.Ptr(U))
- assert descr4.get_item_size(False) == rffi.sizeof(lltype.Float)
- assert descr5.get_item_size(False) == rffi.sizeof(lltype.Signed) * 2
- assert descr6.get_item_size(False) == rffi.sizeof(lltype.SingleFloat)
+ assert descr1.basesize == get_alignment('c')
+ assert descr2.basesize == get_alignment('p')
+ assert descr3.basesize == get_alignment('p')
+ assert descr4.basesize == get_alignment('d')
+ assert descr5.basesize == get_alignment('f')
+ assert descr1.lendescr.offset == 0
+ assert descr2.lendescr.offset == 0
+ assert descr3.lendescr.offset == 0
+ assert descr4.lendescr.offset == 0
+ assert descr5.lendescr.offset == 0
+ assert descr1.itemsize == rffi.sizeof(lltype.Char)
+ assert descr2.itemsize == rffi.sizeof(lltype.Ptr(T))
+ assert descr3.itemsize == rffi.sizeof(lltype.Ptr(U))
+ assert descr4.itemsize == rffi.sizeof(lltype.Float)
+ assert descr5.itemsize == rffi.sizeof(lltype.Signed) * 2
+ assert descr6.itemsize == rffi.sizeof(lltype.SingleFloat)
#
- assert isinstance(descr1.get_base_size(True), Symbolic)
- assert isinstance(descr2.get_base_size(True), Symbolic)
- assert isinstance(descr3.get_base_size(True), Symbolic)
- assert isinstance(descr4.get_base_size(True), Symbolic)
- assert isinstance(descr5.get_base_size(True), Symbolic)
- assert isinstance(descr1.get_ofs_length(True), Symbolic)
- assert isinstance(descr2.get_ofs_length(True), Symbolic)
- assert isinstance(descr3.get_ofs_length(True), Symbolic)
- assert isinstance(descr4.get_ofs_length(True), Symbolic)
- assert isinstance(descr5.get_ofs_length(True), Symbolic)
- assert isinstance(descr1.get_item_size(True), Symbolic)
- assert isinstance(descr2.get_item_size(True), Symbolic)
- assert isinstance(descr3.get_item_size(True), Symbolic)
- assert isinstance(descr4.get_item_size(True), Symbolic)
- assert isinstance(descr5.get_item_size(True), Symbolic)
CA = rffi.CArray(lltype.Signed)
descr = get_array_descr(c0, CA)
- assert not descr.is_array_of_floats()
- assert descr.get_base_size(False) == 0
- assert descr.get_ofs_length(False) == -1
+ assert descr.flag == FLAG_SIGNED
+ assert descr.basesize == 0
+ assert descr.lendescr is None
CA = rffi.CArray(lltype.Ptr(lltype.GcStruct('S')))
descr = get_array_descr(c0, CA)
- assert descr.is_array_of_pointers()
- assert descr.get_base_size(False) == 0
- assert descr.get_ofs_length(False) == -1
+ assert descr.flag == FLAG_POINTER
+ assert descr.basesize == 0
+ assert descr.lendescr is None
CA = rffi.CArray(lltype.Ptr(lltype.Struct('S')))
descr = get_array_descr(c0, CA)
- assert descr.get_base_size(False) == 0
- assert descr.get_ofs_length(False) == -1
+ assert descr.flag == FLAG_UNSIGNED
+ assert descr.basesize == 0
+ assert descr.lendescr is None
CA = rffi.CArray(lltype.Float)
descr = get_array_descr(c0, CA)
- assert descr.is_array_of_floats()
- assert descr.get_base_size(False) == 0
- assert descr.get_ofs_length(False) == -1
+ assert descr.flag == FLAG_FLOAT
+ assert descr.basesize == 0
+ assert descr.lendescr is None
CA = rffi.CArray(rffi.FLOAT)
descr = get_array_descr(c0, CA)
- assert not descr.is_array_of_floats()
- assert descr.get_base_size(False) == 0
- assert descr.get_ofs_length(False) == -1
+ assert descr.flag == FLAG_UNSIGNED
+ assert descr.basesize == 0
+ assert descr.itemsize == rffi.sizeof(lltype.SingleFloat)
+ assert descr.lendescr is None
def test_get_array_descr_sign():
@@ -257,46 +203,55 @@
for tsc in [False, True]:
c2 = GcCache(tsc)
arraydescr = get_array_descr(c2, A)
- assert arraydescr.is_item_signed() == signed
+ assert arraydescr.flag == {False: FLAG_UNSIGNED,
+ True: FLAG_SIGNED }[signed]
#
RA = rffi.CArray(RESTYPE)
for tsc in [False, True]:
c2 = GcCache(tsc)
arraydescr = get_array_descr(c2, RA)
- assert arraydescr.is_item_signed() == signed
+ assert arraydescr.flag == {False: FLAG_UNSIGNED,
+ True: FLAG_SIGNED }[signed]
+
+
+def test_get_array_descr_str():
+ c0 = GcCache(False)
+ descr1 = get_array_descr(c0, rstr.STR)
+ assert descr1.itemsize == rffi.sizeof(lltype.Char)
+ assert descr1.flag == FLAG_UNSIGNED
def test_get_call_descr_not_translated():
c0 = GcCache(False)
descr1 = get_call_descr(c0, [lltype.Char, lltype.Signed], lltype.Char)
- assert descr1.get_result_size(False) == rffi.sizeof(lltype.Char)
- assert descr1.get_return_type() == history.INT
+ assert descr1.get_result_size() == rffi.sizeof(lltype.Char)
+ assert descr1.get_result_type() == history.INT
assert descr1.arg_classes == "ii"
#
T = lltype.GcStruct('T')
descr2 = get_call_descr(c0, [lltype.Ptr(T)], lltype.Ptr(T))
- assert descr2.get_result_size(False) == rffi.sizeof(lltype.Ptr(T))
- assert descr2.get_return_type() == history.REF
+ assert descr2.get_result_size() == rffi.sizeof(lltype.Ptr(T))
+ assert descr2.get_result_type() == history.REF
assert descr2.arg_classes == "r"
#
U = lltype.GcStruct('U', ('x', lltype.Signed))
assert descr2 == get_call_descr(c0, [lltype.Ptr(U)], lltype.Ptr(U))
#
V = lltype.Struct('V', ('x', lltype.Signed))
- assert (get_call_descr(c0, [], lltype.Ptr(V)).get_return_type() ==
+ assert (get_call_descr(c0, [], lltype.Ptr(V)).get_result_type() ==
history.INT)
#
- assert (get_call_descr(c0, [], lltype.Void).get_return_type() ==
+ assert (get_call_descr(c0, [], lltype.Void).get_result_type() ==
history.VOID)
#
descr4 = get_call_descr(c0, [lltype.Float, lltype.Float], lltype.Float)
- assert descr4.get_result_size(False) == rffi.sizeof(lltype.Float)
- assert descr4.get_return_type() == history.FLOAT
+ assert descr4.get_result_size() == rffi.sizeof(lltype.Float)
+ assert descr4.get_result_type() == history.FLOAT
assert descr4.arg_classes == "ff"
#
descr5 = get_call_descr(c0, [lltype.SingleFloat], lltype.SingleFloat)
- assert descr5.get_result_size(False) == rffi.sizeof(lltype.SingleFloat)
- assert descr5.get_return_type() == "S"
+ assert descr5.get_result_size() == rffi.sizeof(lltype.SingleFloat)
+ assert descr5.get_result_type() == "S"
assert descr5.arg_classes == "S"
def test_get_call_descr_not_translated_longlong():
@@ -305,13 +260,13 @@
c0 = GcCache(False)
#
descr5 = get_call_descr(c0, [lltype.SignedLongLong], lltype.Signed)
- assert descr5.get_result_size(False) == 4
- assert descr5.get_return_type() == history.INT
+ assert descr5.get_result_size() == 4
+ assert descr5.get_result_type() == history.INT
assert descr5.arg_classes == "L"
#
descr6 = get_call_descr(c0, [lltype.Signed], lltype.SignedLongLong)
- assert descr6.get_result_size(False) == 8
- assert descr6.get_return_type() == "L"
+ assert descr6.get_result_size() == 8
+ assert descr6.get_result_type() == "L"
assert descr6.arg_classes == "i"
def test_get_call_descr_translated():
@@ -319,18 +274,18 @@
T = lltype.GcStruct('T')
U = lltype.GcStruct('U', ('x', lltype.Signed))
descr3 = get_call_descr(c1, [lltype.Ptr(T)], lltype.Ptr(U))
- assert isinstance(descr3.get_result_size(True), Symbolic)
- assert descr3.get_return_type() == history.REF
+ assert isinstance(descr3.get_result_size(), Symbolic)
+ assert descr3.get_result_type() == history.REF
assert descr3.arg_classes == "r"
#
descr4 = get_call_descr(c1, [lltype.Float, lltype.Float], lltype.Float)
- assert isinstance(descr4.get_result_size(True), Symbolic)
- assert descr4.get_return_type() == history.FLOAT
+ assert isinstance(descr4.get_result_size(), Symbolic)
+ assert descr4.get_result_type() == history.FLOAT
assert descr4.arg_classes == "ff"
#
descr5 = get_call_descr(c1, [lltype.SingleFloat], lltype.SingleFloat)
- assert isinstance(descr5.get_result_size(True), Symbolic)
- assert descr5.get_return_type() == "S"
+ assert isinstance(descr5.get_result_size(), Symbolic)
+ assert descr5.get_result_type() == "S"
assert descr5.arg_classes == "S"
def test_call_descr_extra_info():
@@ -358,6 +313,10 @@
def test_repr_of_descr():
+ def repr_of_descr(descr):
+ s = descr.repr_of_descr()
+ assert ',' not in s # makes the life easier for pypy.tool.jitlogparser
+ return s
c0 = GcCache(False)
T = lltype.GcStruct('T')
S = lltype.GcStruct('S', ('x', lltype.Char),
@@ -365,33 +324,34 @@
('z', lltype.Ptr(T)))
descr1 = get_size_descr(c0, S)
s = symbolic.get_size(S, False)
- assert descr1.repr_of_descr() == '<SizeDescr %d>' % s
+ assert repr_of_descr(descr1) == '<SizeDescr %d>' % s
#
descr2 = get_field_descr(c0, S, 'y')
o, _ = symbolic.get_field_token(S, 'y', False)
- assert descr2.repr_of_descr() == '<GcPtrFieldDescr S.y %d>' % o
+ assert repr_of_descr(descr2) == '<FieldP S.y %d>' % o
#
descr2i = get_field_descr(c0, S, 'x')
o, _ = symbolic.get_field_token(S, 'x', False)
- assert descr2i.repr_of_descr() == '<CharFieldDescr S.x %d>' % o
+ assert repr_of_descr(descr2i) == '<FieldU S.x %d>' % o
#
descr3 = get_array_descr(c0, lltype.GcArray(lltype.Ptr(S)))
- assert descr3.repr_of_descr() == '<GcPtrArrayDescr>'
+ o = symbolic.get_size(lltype.Ptr(S), False)
+ assert repr_of_descr(descr3) == '<ArrayP %d>' % o
#
descr3i = get_array_descr(c0, lltype.GcArray(lltype.Char))
- assert descr3i.repr_of_descr() == '<CharArrayDescr>'
+ assert repr_of_descr(descr3i) == '<ArrayU 1>'
#
descr4 = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Ptr(S))
- assert 'GcPtrCallDescr' in descr4.repr_of_descr()
+ assert repr_of_descr(descr4) == '<Callr %d ir>' % o
#
descr4i = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Char)
- assert 'CharCallDescr' in descr4i.repr_of_descr()
+ assert repr_of_descr(descr4i) == '<Calli 1 ir>'
#
descr4f = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Float)
- assert 'FloatCallDescr' in descr4f.repr_of_descr()
+ assert repr_of_descr(descr4f) == '<Callf 8 ir>'
#
descr5f = get_call_descr(c0, [lltype.Char], lltype.SingleFloat)
- assert 'SingleFloatCallDescr' in descr5f.repr_of_descr()
+ assert repr_of_descr(descr5f) == '<CallS 4 i>'
def test_call_stubs_1():
c0 = GcCache(False)
@@ -401,10 +361,10 @@
def f(a, b):
return 'c'
- call_stub = descr1.call_stub
fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f)
- res = call_stub(rffi.cast(lltype.Signed, fnptr), [1, 2], None, None)
+ res = descr1.call_stub_i(rffi.cast(lltype.Signed, fnptr),
+ [1, 2], None, None)
assert res == ord('c')
def test_call_stubs_2():
@@ -421,8 +381,8 @@
a = lltype.malloc(ARRAY, 3)
opaquea = lltype.cast_opaque_ptr(llmemory.GCREF, a)
a[0] = 1
- res = descr2.call_stub(rffi.cast(lltype.Signed, fnptr),
- [], [opaquea], [longlong.getfloatstorage(3.5)])
+ res = descr2.call_stub_f(rffi.cast(lltype.Signed, fnptr),
+ [], [opaquea], [longlong.getfloatstorage(3.5)])
assert longlong.getrealfloat(res) == 4.5
def test_call_stubs_single_float():
@@ -445,6 +405,22 @@
a = intmask(singlefloat2uint(r_singlefloat(-10.0)))
b = intmask(singlefloat2uint(r_singlefloat(3.0)))
c = intmask(singlefloat2uint(r_singlefloat(2.0)))
- res = descr2.call_stub(rffi.cast(lltype.Signed, fnptr),
- [a, b, c], [], [])
+ res = descr2.call_stub_i(rffi.cast(lltype.Signed, fnptr),
+ [a, b, c], [], [])
assert float(uint2singlefloat(rffi.r_uint(res))) == -11.5
+
+def test_field_arraylen_descr():
+ c0 = GcCache(True)
+ A1 = lltype.GcArray(lltype.Signed)
+ fielddescr = get_field_arraylen_descr(c0, A1)
+ assert isinstance(fielddescr, FieldDescr)
+ ofs = fielddescr.offset
+ assert repr(ofs) == '< ArrayLengthOffset <GcArray of Signed > >'
+ #
+ fielddescr = get_field_arraylen_descr(c0, rstr.STR)
+ ofs = fielddescr.offset
+ assert repr(ofs) == ("< <FieldOffset <GcStruct rpy_string { hash, chars }>"
+ " 'chars'> + < ArrayLengthOffset"
+ " <Array of Char > > >")
+ # caching:
+ assert fielddescr is get_field_arraylen_descr(c0, rstr.STR)
diff --git a/pypy/jit/backend/llsupport/test/test_ffisupport.py b/pypy/jit/backend/llsupport/test/test_ffisupport.py
--- a/pypy/jit/backend/llsupport/test/test_ffisupport.py
+++ b/pypy/jit/backend/llsupport/test/test_ffisupport.py
@@ -1,5 +1,6 @@
from pypy.rlib.libffi import types
from pypy.jit.codewriter.longlong import is_64_bit
+from pypy.jit.backend.llsupport.descr import *
from pypy.jit.backend.llsupport.ffisupport import *
@@ -15,7 +16,9 @@
args = [types.sint, types.pointer]
descr = get_call_descr_dynamic(FakeCPU(), args, types.sint, None,
ffi_flags=42)
- assert isinstance(descr, DynamicIntCallDescr)
+ assert isinstance(descr, CallDescr)
+ assert descr.result_type == 'i'
+ assert descr.result_flag == FLAG_SIGNED
assert descr.arg_classes == 'ii'
assert descr.get_ffi_flags() == 42
@@ -24,18 +27,20 @@
assert descr is None # missing floats
descr = get_call_descr_dynamic(FakeCPU(supports_floats=True),
args, types.void, None, ffi_flags=43)
- assert isinstance(descr, VoidCallDescr)
+ assert descr.result_type == 'v'
+ assert descr.result_flag == FLAG_VOID
assert descr.arg_classes == 'ifi'
assert descr.get_ffi_flags() == 43
descr = get_call_descr_dynamic(FakeCPU(), [], types.sint8, None, 42)
- assert isinstance(descr, DynamicIntCallDescr)
- assert descr.get_result_size(False) == 1
+ assert descr.get_result_size() == 1
+ assert descr.result_flag == FLAG_SIGNED
assert descr.is_result_signed() == True
descr = get_call_descr_dynamic(FakeCPU(), [], types.uint8, None, 42)
- assert isinstance(descr, DynamicIntCallDescr)
- assert descr.get_result_size(False) == 1
+ assert isinstance(descr, CallDescr)
+ assert descr.get_result_size() == 1
+ assert descr.result_flag == FLAG_UNSIGNED
assert descr.is_result_signed() == False
if not is_64_bit:
@@ -44,7 +49,9 @@
assert descr is None # missing longlongs
descr = get_call_descr_dynamic(FakeCPU(supports_longlong=True),
[], types.slonglong, None, ffi_flags=43)
- assert isinstance(descr, LongLongCallDescr)
+ assert isinstance(descr, CallDescr)
+ assert descr.result_flag == FLAG_FLOAT
+ assert descr.result_type == 'L'
assert descr.get_ffi_flags() == 43
else:
assert types.slonglong is types.slong
@@ -53,6 +60,6 @@
assert descr is None # missing singlefloats
descr = get_call_descr_dynamic(FakeCPU(supports_singlefloats=True),
[], types.float, None, ffi_flags=44)
- SingleFloatCallDescr = getCallDescrClass(rffi.FLOAT)
- assert isinstance(descr, SingleFloatCallDescr)
+ assert descr.result_flag == FLAG_UNSIGNED
+ assert descr.result_type == 'S'
assert descr.get_ffi_flags() == 44
diff --git a/pypy/jit/backend/llsupport/test/test_gc.py b/pypy/jit/backend/llsupport/test/test_gc.py
--- a/pypy/jit/backend/llsupport/test/test_gc.py
+++ b/pypy/jit/backend/llsupport/test/test_gc.py
@@ -6,6 +6,7 @@
from pypy.jit.backend.llsupport.gc import *
from pypy.jit.backend.llsupport import symbolic
from pypy.jit.metainterp.gc import get_description
+from pypy.jit.metainterp.history import BoxPtr, BoxInt, ConstPtr
from pypy.jit.metainterp.resoperation import get_deep_immutable_oplist
from pypy.jit.tool.oparser import parse
from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
@@ -15,12 +16,12 @@
gc_ll_descr = GcLLDescr_boehm(None, None, None)
#
record = []
- prev_funcptr_for_new = gc_ll_descr.funcptr_for_new
- def my_funcptr_for_new(size):
- p = prev_funcptr_for_new(size)
+ prev_malloc_fn_ptr = gc_ll_descr.malloc_fn_ptr
+ def my_malloc_fn_ptr(size):
+ p = prev_malloc_fn_ptr(size)
record.append((size, p))
return p
- gc_ll_descr.funcptr_for_new = my_funcptr_for_new
+ gc_ll_descr.malloc_fn_ptr = my_malloc_fn_ptr
#
# ---------- gc_malloc ----------
S = lltype.GcStruct('S', ('x', lltype.Signed))
@@ -32,8 +33,8 @@
A = lltype.GcArray(lltype.Signed)
arraydescr = get_array_descr(gc_ll_descr, A)
p = gc_ll_descr.gc_malloc_array(arraydescr, 10)
- assert record == [(arraydescr.get_base_size(False) +
- 10 * arraydescr.get_item_size(False), p)]
+ assert record == [(arraydescr.basesize +
+ 10 * arraydescr.itemsize, p)]
del record[:]
# ---------- gc_malloc_str ----------
p = gc_ll_descr.gc_malloc_str(10)
@@ -246,24 +247,28 @@
def __init__(self):
self.record = []
+ def _malloc(self, type_id, size):
+ tid = llop.combine_ushort(lltype.Signed, type_id, 0)
+ x = llmemory.raw_malloc(self.gcheaderbuilder.size_gc_header + size)
+ x += self.gcheaderbuilder.size_gc_header
+ return x, tid
+
def do_malloc_fixedsize_clear(self, RESTYPE, type_id, size,
has_finalizer, has_light_finalizer,
contains_weakptr):
assert not contains_weakptr
- assert not has_finalizer # in these tests
- assert not has_light_finalizer # in these tests
- p = llmemory.raw_malloc(size)
+ assert not has_finalizer
+ assert not has_light_finalizer
+ p, tid = self._malloc(type_id, size)
p = llmemory.cast_adr_to_ptr(p, RESTYPE)
- tid = llop.combine_ushort(lltype.Signed, type_id, 0)
self.record.append(("fixedsize", repr(size), tid, p))
return p
def do_malloc_varsize_clear(self, RESTYPE, type_id, length, size,
itemsize, offset_to_length):
- p = llmemory.raw_malloc(size + itemsize * length)
+ p, tid = self._malloc(type_id, size + itemsize * length)
(p + offset_to_length).signed[0] = length
p = llmemory.cast_adr_to_ptr(p, RESTYPE)
- tid = llop.combine_ushort(lltype.Signed, type_id, 0)
self.record.append(("varsize", tid, length,
repr(size), repr(itemsize),
repr(offset_to_length), p))
@@ -322,43 +327,40 @@
gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), None,
llop1)
gc_ll_descr.initialize()
+ llop1.gcheaderbuilder = gc_ll_descr.gcheaderbuilder
self.llop1 = llop1
self.gc_ll_descr = gc_ll_descr
self.fake_cpu = FakeCPU()
- def test_args_for_new(self):
- S = lltype.GcStruct('S', ('x', lltype.Signed))
- sizedescr = get_size_descr(self.gc_ll_descr, S)
- args = self.gc_ll_descr.args_for_new(sizedescr)
- for x in args:
- assert lltype.typeOf(x) == lltype.Signed
- A = lltype.GcArray(lltype.Signed)
- arraydescr = get_array_descr(self.gc_ll_descr, A)
- args = self.gc_ll_descr.args_for_new(sizedescr)
- for x in args:
- assert lltype.typeOf(x) == lltype.Signed
+## def test_args_for_new(self):
+## S = lltype.GcStruct('S', ('x', lltype.Signed))
+## sizedescr = get_size_descr(self.gc_ll_descr, S)
+## args = self.gc_ll_descr.args_for_new(sizedescr)
+## for x in args:
+## assert lltype.typeOf(x) == lltype.Signed
+## A = lltype.GcArray(lltype.Signed)
+## arraydescr = get_array_descr(self.gc_ll_descr, A)
+## args = self.gc_ll_descr.args_for_new(sizedescr)
+## for x in args:
+## assert lltype.typeOf(x) == lltype.Signed
def test_gc_malloc(self):
S = lltype.GcStruct('S', ('x', lltype.Signed))
sizedescr = get_size_descr(self.gc_ll_descr, S)
p = self.gc_ll_descr.gc_malloc(sizedescr)
- assert self.llop1.record == [("fixedsize",
- repr(sizedescr.size),
+ assert lltype.typeOf(p) == llmemory.GCREF
+ assert self.llop1.record == [("fixedsize", repr(sizedescr.size),
sizedescr.tid, p)]
- assert repr(self.gc_ll_descr.args_for_new(sizedescr)) == repr(
- [sizedescr.size, sizedescr.tid])
def test_gc_malloc_array(self):
A = lltype.GcArray(lltype.Signed)
arraydescr = get_array_descr(self.gc_ll_descr, A)
p = self.gc_ll_descr.gc_malloc_array(arraydescr, 10)
assert self.llop1.record == [("varsize", arraydescr.tid, 10,
- repr(arraydescr.get_base_size(True)),
- repr(arraydescr.get_item_size(True)),
- repr(arraydescr.get_ofs_length(True)),
+ repr(arraydescr.basesize),
+ repr(arraydescr.itemsize),
+ repr(arraydescr.lendescr.offset),
p)]
- assert repr(self.gc_ll_descr.args_for_new_array(arraydescr)) == repr(
- [arraydescr.get_item_size(True), arraydescr.tid])
def test_gc_malloc_str(self):
p = self.gc_ll_descr.gc_malloc_str(10)
@@ -404,10 +406,11 @@
gc_ll_descr = self.gc_ll_descr
llop1 = self.llop1
#
- newops = []
+ rewriter = GcRewriterAssembler(gc_ll_descr, None)
+ newops = rewriter.newops
v_base = BoxPtr()
v_value = BoxPtr()
- gc_ll_descr._gen_write_barrier(newops, v_base, v_value)
+ rewriter.gen_write_barrier(v_base, v_value)
assert llop1.record == []
assert len(newops) == 1
assert newops[0].getopnum() == rop.COND_CALL_GC_WB
@@ -427,8 +430,7 @@
operations = gc_ll_descr.rewrite_assembler(None, operations, [])
assert len(operations) == 0
- def test_rewrite_assembler_1(self):
- # check recording of ConstPtrs
+ def test_record_constptrs(self):
class MyFakeCPU(object):
def cast_adr_to_int(self, adr):
assert adr == "some fake address"
@@ -455,211 +457,6 @@
assert operations2 == operations
assert gcrefs == [s_gcref]
- def test_rewrite_assembler_2(self):
- # check write barriers before SETFIELD_GC
- v_base = BoxPtr()
- v_value = BoxPtr()
- field_descr = AbstractDescr()
- operations = [
- ResOperation(rop.SETFIELD_GC, [v_base, v_value], None,
- descr=field_descr),
- ]
- gc_ll_descr = self.gc_ll_descr
- operations = get_deep_immutable_oplist(operations)
- operations = gc_ll_descr.rewrite_assembler(self.fake_cpu, operations,
- [])
- assert len(operations) == 2
- #
- assert operations[0].getopnum() == rop.COND_CALL_GC_WB
- assert operations[0].getarg(0) == v_base
- assert operations[0].getarg(1) == v_value
- assert operations[0].result is None
- #
- assert operations[1].getopnum() == rop.SETFIELD_RAW
- assert operations[1].getarg(0) == v_base
- assert operations[1].getarg(1) == v_value
- assert operations[1].getdescr() == field_descr
-
- def test_rewrite_assembler_3(self):
- # check write barriers before SETARRAYITEM_GC
- for v_new_length in (None, ConstInt(5), ConstInt(5000), BoxInt()):
- v_base = BoxPtr()
- v_index = BoxInt()
- v_value = BoxPtr()
- array_descr = AbstractDescr()
- operations = [
- ResOperation(rop.SETARRAYITEM_GC, [v_base, v_index, v_value],
- None, descr=array_descr),
- ]
- if v_new_length is not None:
- operations.insert(0, ResOperation(rop.NEW_ARRAY,
- [v_new_length], v_base,
- descr=array_descr))
- # we need to insert another, unrelated NEW_ARRAY here
- # to prevent the initialization_store optimization
- operations.insert(1, ResOperation(rop.NEW_ARRAY,
- [ConstInt(12)], BoxPtr(),
- descr=array_descr))
- gc_ll_descr = self.gc_ll_descr
- operations = get_deep_immutable_oplist(operations)
- operations = gc_ll_descr.rewrite_assembler(self.fake_cpu,
- operations, [])
- if v_new_length is not None:
- assert operations[0].getopnum() == rop.NEW_ARRAY
- assert operations[1].getopnum() == rop.NEW_ARRAY
- del operations[:2]
- assert len(operations) == 2
- #
- assert operations[0].getopnum() == rop.COND_CALL_GC_WB
- assert operations[0].getarg(0) == v_base
- assert operations[0].getarg(1) == v_value
- assert operations[0].result is None
- #
- assert operations[1].getopnum() == rop.SETARRAYITEM_RAW
- assert operations[1].getarg(0) == v_base
- assert operations[1].getarg(1) == v_index
- assert operations[1].getarg(2) == v_value
- assert operations[1].getdescr() == array_descr
-
- def test_rewrite_assembler_4(self):
- # check write barriers before SETARRAYITEM_GC,
- # if we have actually a write_barrier_from_array.
- self.llop1._have_wb_from_array = True
- for v_new_length in (None, ConstInt(5), ConstInt(5000), BoxInt()):
- v_base = BoxPtr()
- v_index = BoxInt()
- v_value = BoxPtr()
- array_descr = AbstractDescr()
- operations = [
- ResOperation(rop.SETARRAYITEM_GC, [v_base, v_index, v_value],
- None, descr=array_descr),
- ]
- if v_new_length is not None:
- operations.insert(0, ResOperation(rop.NEW_ARRAY,
- [v_new_length], v_base,
- descr=array_descr))
- # we need to insert another, unrelated NEW_ARRAY here
- # to prevent the initialization_store optimization
- operations.insert(1, ResOperation(rop.NEW_ARRAY,
- [ConstInt(12)], BoxPtr(),
- descr=array_descr))
- gc_ll_descr = self.gc_ll_descr
- operations = get_deep_immutable_oplist(operations)
- operations = gc_ll_descr.rewrite_assembler(self.fake_cpu,
- operations, [])
- if v_new_length is not None:
- assert operations[0].getopnum() == rop.NEW_ARRAY
- assert operations[1].getopnum() == rop.NEW_ARRAY
- del operations[:2]
- assert len(operations) == 2
- #
- if isinstance(v_new_length, ConstInt) and v_new_length.value < 130:
- assert operations[0].getopnum() == rop.COND_CALL_GC_WB
- assert operations[0].getarg(0) == v_base
- assert operations[0].getarg(1) == v_value
- else:
- assert operations[0].getopnum() == rop.COND_CALL_GC_WB_ARRAY
- assert operations[0].getarg(0) == v_base
- assert operations[0].getarg(1) == v_index
- assert operations[0].getarg(2) == v_value
- assert operations[0].result is None
- #
- assert operations[1].getopnum() == rop.SETARRAYITEM_RAW
- assert operations[1].getarg(0) == v_base
- assert operations[1].getarg(1) == v_index
- assert operations[1].getarg(2) == v_value
- assert operations[1].getdescr() == array_descr
-
- def test_rewrite_assembler_5(self):
- S = lltype.GcStruct('S')
- A = lltype.GcArray(lltype.Struct('A', ('x', lltype.Ptr(S))))
- interiordescr = get_interiorfield_descr(self.gc_ll_descr, A,
- A.OF, 'x')
- wbdescr = self.gc_ll_descr.write_barrier_descr
- ops = parse("""
- [p1, p2]
- setinteriorfield_gc(p1, 0, p2, descr=interiordescr)
- jump(p1, p2)
- """, namespace=locals())
- expected = parse("""
- [p1, p2]
- cond_call_gc_wb(p1, p2, descr=wbdescr)
- setinteriorfield_raw(p1, 0, p2, descr=interiordescr)
- jump(p1, p2)
- """, namespace=locals())
- operations = get_deep_immutable_oplist(ops.operations)
- operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
- operations, [])
- equaloplists(operations, expected.operations)
-
- def test_rewrite_assembler_initialization_store(self):
- S = lltype.GcStruct('S', ('parent', OBJECT),
- ('x', lltype.Signed))
- s_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
- xdescr = get_field_descr(self.gc_ll_descr, S, 'x')
- ops = parse("""
- [p1]
- p0 = new_with_vtable(ConstClass(s_vtable))
- setfield_gc(p0, p1, descr=xdescr)
- jump()
- """, namespace=locals())
- expected = parse("""
- [p1]
- p0 = new_with_vtable(ConstClass(s_vtable))
- # no write barrier
- setfield_gc(p0, p1, descr=xdescr)
- jump()
- """, namespace=locals())
- operations = get_deep_immutable_oplist(ops.operations)
- operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
- operations, [])
- equaloplists(operations, expected.operations)
-
- def test_rewrite_assembler_initialization_store_2(self):
- S = lltype.GcStruct('S', ('parent', OBJECT),
- ('x', lltype.Signed))
- s_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
- wbdescr = self.gc_ll_descr.write_barrier_descr
- xdescr = get_field_descr(self.gc_ll_descr, S, 'x')
- ops = parse("""
- [p1]
- p0 = new_with_vtable(ConstClass(s_vtable))
- p3 = new_with_vtable(ConstClass(s_vtable))
- setfield_gc(p0, p1, descr=xdescr)
- jump()
- """, namespace=locals())
- expected = parse("""
- [p1]
- p0 = new_with_vtable(ConstClass(s_vtable))
- p3 = new_with_vtable(ConstClass(s_vtable))
- cond_call_gc_wb(p0, p1, descr=wbdescr)
- setfield_raw(p0, p1, descr=xdescr)
- jump()
- """, namespace=locals())
- operations = get_deep_immutable_oplist(ops.operations)
- operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
- operations, [])
- equaloplists(operations, expected.operations)
-
- def test_rewrite_assembler_initialization_store_3(self):
- A = lltype.GcArray(lltype.Ptr(lltype.GcStruct('S')))
- arraydescr = get_array_descr(self.gc_ll_descr, A)
- ops = parse("""
- [p1]
- p0 = new_array(3, descr=arraydescr)
- setarrayitem_gc(p0, 0, p1, descr=arraydescr)
- jump()
- """, namespace=locals())
- expected = parse("""
- [p1]
- p0 = new_array(3, descr=arraydescr)
- setarrayitem_gc(p0, 0, p1, descr=arraydescr)
- jump()
- """, namespace=locals())
- operations = get_deep_immutable_oplist(ops.operations)
- operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
- operations, [])
- equaloplists(operations, expected.operations)
class TestFrameworkMiniMark(TestFramework):
gc = 'minimark'
diff --git a/pypy/jit/backend/llsupport/test/test_rewrite.py b/pypy/jit/backend/llsupport/test/test_rewrite.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/llsupport/test/test_rewrite.py
@@ -0,0 +1,668 @@
+from pypy.jit.backend.llsupport.descr import *
+from pypy.jit.backend.llsupport.gc import *
+from pypy.jit.metainterp.gc import get_description
+from pypy.jit.tool.oparser import parse
+from pypy.jit.metainterp.optimizeopt.util import equaloplists
+from pypy.jit.codewriter.heaptracker import register_known_gctype
+
+
+class Evaluator(object):
+ def __init__(self, scope):
+ self.scope = scope
+ def __getitem__(self, key):
+ return eval(key, self.scope)
+
+
+class RewriteTests(object):
+ def check_rewrite(self, frm_operations, to_operations, **namespace):
+ S = lltype.GcStruct('S', ('x', lltype.Signed),
+ ('y', lltype.Signed))
+ sdescr = get_size_descr(self.gc_ll_descr, S)
+ sdescr.tid = 1234
+ #
+ T = lltype.GcStruct('T', ('y', lltype.Signed),
+ ('z', lltype.Ptr(S)),
+ ('t', lltype.Signed))
+ tdescr = get_size_descr(self.gc_ll_descr, T)
+ tdescr.tid = 5678
+ tzdescr = get_field_descr(self.gc_ll_descr, T, 'z')
+ #
+ A = lltype.GcArray(lltype.Signed)
+ adescr = get_array_descr(self.gc_ll_descr, A)
+ adescr.tid = 4321
+ alendescr = adescr.lendescr
+ #
+ B = lltype.GcArray(lltype.Char)
+ bdescr = get_array_descr(self.gc_ll_descr, B)
+ bdescr.tid = 8765
+ blendescr = bdescr.lendescr
+ #
+ C = lltype.GcArray(lltype.Ptr(S))
+ cdescr = get_array_descr(self.gc_ll_descr, C)
+ cdescr.tid = 8111
+ clendescr = cdescr.lendescr
+ #
+ E = lltype.GcStruct('Empty')
+ edescr = get_size_descr(self.gc_ll_descr, E)
+ edescr.tid = 9000
+ #
+ vtable_descr = self.gc_ll_descr.fielddescr_vtable
+ O = lltype.GcStruct('O', ('parent', rclass.OBJECT),
+ ('x', lltype.Signed))
+ o_vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True)
+ register_known_gctype(self.cpu, o_vtable, O)
+ #
+ tiddescr = self.gc_ll_descr.fielddescr_tid
+ wbdescr = self.gc_ll_descr.write_barrier_descr
+ WORD = globals()['WORD']
+ #
+ strdescr = self.gc_ll_descr.str_descr
+ unicodedescr = self.gc_ll_descr.unicode_descr
+ strlendescr = strdescr.lendescr
+ unicodelendescr = unicodedescr.lendescr
+ #
+ namespace.update(locals())
+ #
+ for funcname in self.gc_ll_descr._generated_functions:
+ namespace[funcname] = self.gc_ll_descr.get_malloc_fn(funcname)
+ namespace[funcname + '_descr'] = getattr(self.gc_ll_descr,
+ '%s_descr' % funcname)
+ #
+ ops = parse(frm_operations, namespace=namespace)
+ expected = parse(to_operations % Evaluator(namespace),
+ namespace=namespace)
+ operations = self.gc_ll_descr.rewrite_assembler(self.cpu,
+ ops.operations,
+ [])
+ equaloplists(operations, expected.operations)
+
+
+class TestBoehm(RewriteTests):
+ def setup_method(self, meth):
+ class FakeCPU(object):
+ def sizeof(self, STRUCT):
+ return SizeDescrWithVTable(102)
+ self.cpu = FakeCPU()
+ self.gc_ll_descr = GcLLDescr_boehm(None, None, None)
+
+ def test_new(self):
+ self.check_rewrite("""
+ []
+ p0 = new(descr=sdescr)
+ jump()
+ """, """
+ [p1]
+ p0 = call_malloc_gc(ConstClass(malloc_fixedsize), %(sdescr.size)d,\
+ descr=malloc_fixedsize_descr)
+ jump()
+ """)
+
+ def test_no_collapsing(self):
+ self.check_rewrite("""
+ []
+ p0 = new(descr=sdescr)
+ p1 = new(descr=sdescr)
+ jump()
+ """, """
+ []
+ p0 = call_malloc_gc(ConstClass(malloc_fixedsize), %(sdescr.size)d,\
+ descr=malloc_fixedsize_descr)
+ p1 = call_malloc_gc(ConstClass(malloc_fixedsize), %(sdescr.size)d,\
+ descr=malloc_fixedsize_descr)
+ jump()
+ """)
+
+ def test_new_array_fixed(self):
+ self.check_rewrite("""
+ []
+ p0 = new_array(10, descr=adescr)
+ jump()
+ """, """
+ []
+ p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
+ %(adescr.basesize + 10 * adescr.itemsize)d, \
+ descr=malloc_fixedsize_descr)
+ setfield_gc(p0, 10, descr=alendescr)
+ jump()
+ """)
+
+ def test_new_array_variable(self):
+ self.check_rewrite("""
+ [i1]
+ p0 = new_array(i1, descr=adescr)
+ jump()
+ """, """
+ [i1]
+ p0 = call_malloc_gc(ConstClass(malloc_array), \
+ %(adescr.basesize)d, \
+ i1, \
+ %(adescr.itemsize)d, \
+ %(adescr.lendescr.offset)d, \
+ descr=malloc_array_descr)
+ jump()
+ """)
+
+ def test_new_with_vtable(self):
+ self.check_rewrite("""
+ []
+ p0 = new_with_vtable(ConstClass(o_vtable))
+ jump()
+ """, """
+ [p1]
+ p0 = call_malloc_gc(ConstClass(malloc_fixedsize), 102, \
+ descr=malloc_fixedsize_descr)
+ setfield_gc(p0, ConstClass(o_vtable), descr=vtable_descr)
+ jump()
+ """)
+
+ def test_newstr(self):
+ self.check_rewrite("""
+ [i1]
+ p0 = newstr(i1)
+ jump()
+ """, """
+ [i1]
+ p0 = call_malloc_gc(ConstClass(malloc_array), \
+ %(strdescr.basesize)d, \
+ i1, \
+ %(strdescr.itemsize)d, \
+ %(strlendescr.offset)d, \
+ descr=malloc_array_descr)
+ jump()
+ """)
+
+ def test_newunicode(self):
+ self.check_rewrite("""
+ [i1]
+ p0 = newunicode(10)
+ jump()
+ """, """
+ [i1]
+ p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
+ %(unicodedescr.basesize + \
+ 10 * unicodedescr.itemsize)d, \
+ descr=malloc_fixedsize_descr)
+ setfield_gc(p0, 10, descr=unicodelendescr)
+ jump()
+ """)
+
+
+class TestFramework(RewriteTests):
+ def setup_method(self, meth):
+ class config_(object):
+ class translation(object):
+ gc = 'hybrid'
+ gcrootfinder = 'asmgcc'
+ gctransformer = 'framework'
+ gcremovetypeptr = False
+ gcdescr = get_description(config_)
+ self.gc_ll_descr = GcLLDescr_framework(gcdescr, None, None, None,
+ really_not_translated=True)
+ self.gc_ll_descr.write_barrier_descr.has_write_barrier_from_array = (
+ lambda cpu: True)
+ #
+ class FakeCPU(object):
+ def sizeof(self, STRUCT):
+ descr = SizeDescrWithVTable(102)
+ descr.tid = 9315
+ return descr
+ self.cpu = FakeCPU()
+
+ def test_rewrite_assembler_new_to_malloc(self):
+ self.check_rewrite("""
+ [p1]
+ p0 = new(descr=sdescr)
+ jump()
+ """, """
+ [p1]
+ p0 = call_malloc_nursery(%(sdescr.size)d)
+ setfield_gc(p0, 1234, descr=tiddescr)
+ jump()
+ """)
+
+ def test_rewrite_assembler_new3_to_malloc(self):
+ self.check_rewrite("""
+ []
+ p0 = new(descr=sdescr)
+ p1 = new(descr=tdescr)
+ p2 = new(descr=sdescr)
+ jump()
+ """, """
+ []
+ p0 = call_malloc_nursery( \
+ %(sdescr.size + tdescr.size + sdescr.size)d)
+ setfield_gc(p0, 1234, descr=tiddescr)
+ p1 = int_add(p0, %(sdescr.size)d)
+ setfield_gc(p1, 5678, descr=tiddescr)
+ p2 = int_add(p1, %(tdescr.size)d)
+ setfield_gc(p2, 1234, descr=tiddescr)
+ jump()
+ """)
+
+ def test_rewrite_assembler_new_array_fixed_to_malloc(self):
+ self.check_rewrite("""
+ []
+ p0 = new_array(10, descr=adescr)
+ jump()
+ """, """
+ []
+ p0 = call_malloc_nursery( \
+ %(adescr.basesize + 10 * adescr.itemsize)d)
+ setfield_gc(p0, 4321, descr=tiddescr)
+ setfield_gc(p0, 10, descr=alendescr)
+ jump()
+ """)
+
+ def test_rewrite_assembler_new_and_new_array_fixed_to_malloc(self):
+ self.check_rewrite("""
+ []
+ p0 = new(descr=sdescr)
+ p1 = new_array(10, descr=adescr)
+ jump()
+ """, """
+ []
+ p0 = call_malloc_nursery( \
+ %(sdescr.size + \
+ adescr.basesize + 10 * adescr.itemsize)d)
+ setfield_gc(p0, 1234, descr=tiddescr)
+ p1 = int_add(p0, %(sdescr.size)d)
+ setfield_gc(p1, 4321, descr=tiddescr)
+ setfield_gc(p1, 10, descr=alendescr)
+ jump()
+ """)
+
+ def test_rewrite_assembler_round_up(self):
+ self.check_rewrite("""
+ []
+ p0 = new_array(6, descr=bdescr)
+ jump()
+ """, """
+ []
+ p0 = call_malloc_nursery(%(bdescr.basesize + 8)d)
+ setfield_gc(p0, 8765, descr=tiddescr)
+ setfield_gc(p0, 6, descr=blendescr)
+ jump()
+ """)
+
+ def test_rewrite_assembler_round_up_always(self):
+ self.check_rewrite("""
+ []
+ p0 = new_array(5, descr=bdescr)
+ p1 = new_array(5, descr=bdescr)
+ p2 = new_array(5, descr=bdescr)
+ p3 = new_array(5, descr=bdescr)
+ jump()
+ """, """
+ []
+ p0 = call_malloc_nursery(%(4 * (bdescr.basesize + 8))d)
+ setfield_gc(p0, 8765, descr=tiddescr)
+ setfield_gc(p0, 5, descr=blendescr)
+ p1 = int_add(p0, %(bdescr.basesize + 8)d)
+ setfield_gc(p1, 8765, descr=tiddescr)
+ setfield_gc(p1, 5, descr=blendescr)
+ p2 = int_add(p1, %(bdescr.basesize + 8)d)
+ setfield_gc(p2, 8765, descr=tiddescr)
+ setfield_gc(p2, 5, descr=blendescr)
+ p3 = int_add(p2, %(bdescr.basesize + 8)d)
+ setfield_gc(p3, 8765, descr=tiddescr)
+ setfield_gc(p3, 5, descr=blendescr)
+ jump()
+ """)
+
+ def test_rewrite_assembler_minimal_size(self):
+ self.check_rewrite("""
+ []
+ p0 = new(descr=edescr)
+ p1 = new(descr=edescr)
+ jump()
+ """, """
+ []
+ p0 = call_malloc_nursery(%(4*WORD)d)
+ setfield_gc(p0, 9000, descr=tiddescr)
+ p1 = int_add(p0, %(2*WORD)d)
+ setfield_gc(p1, 9000, descr=tiddescr)
+ jump()
+ """)
+
+ def test_rewrite_assembler_variable_size(self):
+ self.check_rewrite("""
+ [i0]
+ p0 = new_array(i0, descr=bdescr)
+ jump(i0)
+ """, """
+ [i0]
+ p0 = call_malloc_gc(ConstClass(malloc_array), 1, \
+ %(bdescr.tid)d, i0, \
+ descr=malloc_array_descr)
+ jump(i0)
+ """)
+
+ def test_rewrite_assembler_nonstandard_array(self):
+ # a non-standard array is a bit hard to get; e.g. GcArray(Float)
+ # is like that on Win32, but not on Linux. Build one manually...
+ NONSTD = lltype.GcArray(lltype.Float)
+ nonstd_descr = get_array_descr(self.gc_ll_descr, NONSTD)
+ nonstd_descr.tid = 6464
+ nonstd_descr.basesize = 64 # <= hacked
+ nonstd_descr.itemsize = 8
+ nonstd_descr_gcref = 123
+ self.check_rewrite("""
+ [i0]
+ p0 = new_array(i0, descr=nonstd_descr)
+ jump(i0)
+ """, """
+ [i0]
+ p0 = call_malloc_gc(ConstClass(malloc_array_nonstandard), \
+ 64, 8, \
+ %(nonstd_descr.lendescr.offset)d, \
+ 6464, i0, \
+ descr=malloc_array_nonstandard_descr)
+ jump(i0)
+ """, nonstd_descr=nonstd_descr)
+
+ def test_rewrite_assembler_maximal_size_1(self):
+ self.gc_ll_descr.max_size_of_young_obj = 100
+ self.check_rewrite("""
+ []
+ p0 = new_array(103, descr=bdescr)
+ jump()
+ """, """
+ []
+ p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
+ %(bdescr.basesize + 104)d, \
+ descr=malloc_fixedsize_descr)
+ setfield_gc(p0, 8765, descr=tiddescr)
+ setfield_gc(p0, 103, descr=blendescr)
+ jump()
+ """)
+
+ def test_rewrite_assembler_maximal_size_2(self):
+ self.gc_ll_descr.max_size_of_young_obj = 300
+ self.check_rewrite("""
+ []
+ p0 = new_array(101, descr=bdescr)
+ p1 = new_array(102, descr=bdescr) # two new_arrays can be combined
+ p2 = new_array(103, descr=bdescr) # but not all three
+ jump()
+ """, """
+ []
+ p0 = call_malloc_nursery( \
+ %(2 * (bdescr.basesize + 104))d)
+ setfield_gc(p0, 8765, descr=tiddescr)
+ setfield_gc(p0, 101, descr=blendescr)
+ p1 = int_add(p0, %(bdescr.basesize + 104)d)
+ setfield_gc(p1, 8765, descr=tiddescr)
+ setfield_gc(p1, 102, descr=blendescr)
+ p2 = call_malloc_nursery( \
+ %(bdescr.basesize + 104)d)
+ setfield_gc(p2, 8765, descr=tiddescr)
+ setfield_gc(p2, 103, descr=blendescr)
+ jump()
+ """)
+
+ def test_rewrite_assembler_huge_size(self):
+ # "huge" is defined as "larger than 0xffffff bytes, or 16MB"
+ self.check_rewrite("""
+ []
+ p0 = new_array(20000000, descr=bdescr)
+ jump()
+ """, """
+ []
+ p0 = call_malloc_gc(ConstClass(malloc_array), 1, \
+ %(bdescr.tid)d, 20000000, \
+ descr=malloc_array_descr)
+ jump()
+ """)
+
+ def test_new_with_vtable(self):
+ self.check_rewrite("""
+ []
+ p0 = new_with_vtable(ConstClass(o_vtable))
+ jump()
+ """, """
+ [p1]
+ p0 = call_malloc_nursery(104) # rounded up
+ setfield_gc(p0, 9315, descr=tiddescr)
+ setfield_gc(p0, ConstClass(o_vtable), descr=vtable_descr)
+ jump()
+ """)
+
+ def test_new_with_vtable_too_big(self):
+ self.gc_ll_descr.max_size_of_young_obj = 100
+ self.check_rewrite("""
+ []
+ p0 = new_with_vtable(ConstClass(o_vtable))
+ jump()
+ """, """
+ [p1]
+ p0 = call_malloc_gc(ConstClass(malloc_fixedsize), 104, \
+ descr=malloc_fixedsize_descr)
+ setfield_gc(p0, 9315, descr=tiddescr)
+ setfield_gc(p0, ConstClass(o_vtable), descr=vtable_descr)
+ jump()
+ """)
+
+ def test_rewrite_assembler_newstr_newunicode(self):
+ self.check_rewrite("""
+ [i2]
+ p0 = newstr(14)
+ p1 = newunicode(10)
+ p2 = newunicode(i2)
+ p3 = newstr(i2)
+ jump()
+ """, """
+ [i2]
+ p0 = call_malloc_nursery( \
+ %(strdescr.basesize + 16 * strdescr.itemsize + \
+ unicodedescr.basesize + 10 * unicodedescr.itemsize)d)
+ setfield_gc(p0, %(strdescr.tid)d, descr=tiddescr)
+ setfield_gc(p0, 14, descr=strlendescr)
+ p1 = int_add(p0, %(strdescr.basesize + 16 * strdescr.itemsize)d)
+ setfield_gc(p1, %(unicodedescr.tid)d, descr=tiddescr)
+ setfield_gc(p1, 10, descr=unicodelendescr)
+ p2 = call_malloc_gc(ConstClass(malloc_unicode), i2, \
+ descr=malloc_unicode_descr)
+ p3 = call_malloc_gc(ConstClass(malloc_str), i2, \
+ descr=malloc_str_descr)
+ jump()
+ """)
+
+ def test_write_barrier_before_setfield_gc(self):
+ self.check_rewrite("""
+ [p1, p2]
+ setfield_gc(p1, p2, descr=tzdescr)
+ jump()
+ """, """
+ [p1, p2]
+ cond_call_gc_wb(p1, p2, descr=wbdescr)
+ setfield_raw(p1, p2, descr=tzdescr)
+ jump()
+ """)
+
+ def test_write_barrier_before_array_without_from_array(self):
+ self.gc_ll_descr.write_barrier_descr.has_write_barrier_from_array = (
+ lambda cpu: False)
+ self.check_rewrite("""
+ [p1, i2, p3]
+ setarrayitem_gc(p1, i2, p3, descr=cdescr)
+ jump()
+ """, """
+ [p1, i2, p3]
+ cond_call_gc_wb(p1, p3, descr=wbdescr)
+ setarrayitem_raw(p1, i2, p3, descr=cdescr)
+ jump()
+ """)
+
+ def test_write_barrier_before_short_array(self):
+ self.gc_ll_descr.max_size_of_young_obj = 2000
+ self.check_rewrite("""
+ [i2, p3]
+ p1 = new_array(129, descr=cdescr)
+ call(123456)
+ setarrayitem_gc(p1, i2, p3, descr=cdescr)
+ jump()
+ """, """
+ [i2, p3]
+ p1 = call_malloc_nursery( \
+ %(cdescr.basesize + 129 * cdescr.itemsize)d)
+ setfield_gc(p1, 8111, descr=tiddescr)
+ setfield_gc(p1, 129, descr=clendescr)
+ call(123456)
+ cond_call_gc_wb(p1, p3, descr=wbdescr)
+ setarrayitem_raw(p1, i2, p3, descr=cdescr)
+ jump()
+ """)
+
+ def test_write_barrier_before_long_array(self):
+ # the limit of "being too long" is fixed, arbitrarily, at 130
+ self.gc_ll_descr.max_size_of_young_obj = 2000
+ self.check_rewrite("""
+ [i2, p3]
+ p1 = new_array(130, descr=cdescr)
+ call(123456)
+ setarrayitem_gc(p1, i2, p3, descr=cdescr)
+ jump()
+ """, """
+ [i2, p3]
+ p1 = call_malloc_nursery( \
+ %(cdescr.basesize + 130 * cdescr.itemsize)d)
+ setfield_gc(p1, 8111, descr=tiddescr)
+ setfield_gc(p1, 130, descr=clendescr)
+ call(123456)
+ cond_call_gc_wb_array(p1, i2, p3, descr=wbdescr)
+ setarrayitem_raw(p1, i2, p3, descr=cdescr)
+ jump()
+ """)
+
+ def test_write_barrier_before_unknown_array(self):
+ self.check_rewrite("""
+ [p1, i2, p3]
+ setarrayitem_gc(p1, i2, p3, descr=cdescr)
+ jump()
+ """, """
+ [p1, i2, p3]
+ cond_call_gc_wb_array(p1, i2, p3, descr=wbdescr)
+ setarrayitem_raw(p1, i2, p3, descr=cdescr)
+ jump()
+ """)
+
+ def test_label_makes_size_unknown(self):
+ self.check_rewrite("""
+ [i2, p3]
+ p1 = new_array(5, descr=cdescr)
+ label(p1, i2, p3)
+ setarrayitem_gc(p1, i2, p3, descr=cdescr)
+ jump()
+ """, """
+ [i2, p3]
+ p1 = call_malloc_nursery( \
+ %(cdescr.basesize + 5 * cdescr.itemsize)d)
+ setfield_gc(p1, 8111, descr=tiddescr)
+ setfield_gc(p1, 5, descr=clendescr)
+ label(p1, i2, p3)
+ cond_call_gc_wb_array(p1, i2, p3, descr=wbdescr)
+ setarrayitem_raw(p1, i2, p3, descr=cdescr)
+ jump()
+ """)
+
+ def test_write_barrier_before_setinteriorfield_gc(self):
+ S1 = lltype.GcStruct('S1')
+ INTERIOR = lltype.GcArray(('z', lltype.Ptr(S1)))
+ interiordescr = get_array_descr(self.gc_ll_descr, INTERIOR)
+ interiordescr.tid = 1291
+ interiorlendescr = interiordescr.lendescr
+ interiorzdescr = get_interiorfield_descr(self.gc_ll_descr,
+ INTERIOR, 'z')
+ self.check_rewrite("""
+ [p1, p2]
+ setinteriorfield_gc(p1, 0, p2, descr=interiorzdescr)
+ jump(p1, p2)
+ """, """
+ [p1, p2]
+ cond_call_gc_wb(p1, p2, descr=wbdescr)
+ setinteriorfield_raw(p1, 0, p2, descr=interiorzdescr)
+ jump(p1, p2)
+ """, interiorzdescr=interiorzdescr)
+
+ def test_initialization_store(self):
+ self.check_rewrite("""
+ [p1]
+ p0 = new(descr=tdescr)
+ setfield_gc(p0, p1, descr=tzdescr)
+ jump()
+ """, """
+ [p1]
+ p0 = call_malloc_nursery(%(tdescr.size)d)
+ setfield_gc(p0, 5678, descr=tiddescr)
+ setfield_gc(p0, p1, descr=tzdescr)
+ jump()
+ """)
+
+ def test_initialization_store_2(self):
+ self.check_rewrite("""
+ []
+ p0 = new(descr=tdescr)
+ p1 = new(descr=sdescr)
+ setfield_gc(p0, p1, descr=tzdescr)
+ jump()
+ """, """
+ []
+ p0 = call_malloc_nursery(%(tdescr.size + sdescr.size)d)
+ setfield_gc(p0, 5678, descr=tiddescr)
+ p1 = int_add(p0, %(tdescr.size)d)
+ setfield_gc(p1, 1234, descr=tiddescr)
+ # <<<no cond_call_gc_wb here>>>
+ setfield_gc(p0, p1, descr=tzdescr)
+ jump()
+ """)
+
+ def test_initialization_store_array(self):
+ self.check_rewrite("""
+ [p1, i2]
+ p0 = new_array(5, descr=cdescr)
+ setarrayitem_gc(p0, i2, p1, descr=cdescr)
+ jump()
+ """, """
+ [p1, i2]
+ p0 = call_malloc_nursery( \
+ %(cdescr.basesize + 5 * cdescr.itemsize)d)
+ setfield_gc(p0, 8111, descr=tiddescr)
+ setfield_gc(p0, 5, descr=clendescr)
+ setarrayitem_gc(p0, i2, p1, descr=cdescr)
+ jump()
+ """)
+
+ def test_non_initialization_store(self):
+ self.check_rewrite("""
+ [i0]
+ p0 = new(descr=tdescr)
+ p1 = newstr(i0)
+ setfield_gc(p0, p1, descr=tzdescr)
+ jump()
+ """, """
+ [i0]
+ p0 = call_malloc_nursery(%(tdescr.size)d)
+ setfield_gc(p0, 5678, descr=tiddescr)
+ p1 = call_malloc_gc(ConstClass(malloc_str), i0, \
+ descr=malloc_str_descr)
+ cond_call_gc_wb(p0, p1, descr=wbdescr)
+ setfield_raw(p0, p1, descr=tzdescr)
+ jump()
+ """)
+
+ def test_non_initialization_store_label(self):
+ self.check_rewrite("""
+ [p1]
+ p0 = new(descr=tdescr)
+ label(p0, p1)
+ setfield_gc(p0, p1, descr=tzdescr)
+ jump()
+ """, """
+ [p1]
+ p0 = call_malloc_nursery(%(tdescr.size)d)
+ setfield_gc(p0, 5678, descr=tiddescr)
+ label(p0, p1)
+ cond_call_gc_wb(p0, p1, descr=wbdescr)
+ setfield_raw(p0, p1, descr=tzdescr)
+ jump()
+ """)
diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py
--- a/pypy/jit/backend/model.py
+++ b/pypy/jit/backend/model.py
@@ -1,5 +1,6 @@
from pypy.rlib.debug import debug_start, debug_print, debug_stop
from pypy.jit.metainterp import history
+from pypy.rpython.lltypesystem import lltype
class AbstractCPU(object):
@@ -89,24 +90,21 @@
"""Print a disassembled version of looptoken to stdout"""
raise NotImplementedError
- def execute_token(self, looptoken):
- """Execute the generated code referenced by the looptoken.
+ def execute_token(self, looptoken, *args):
+ """NOT_RPYTHON (for tests only)
+ Execute the generated code referenced by the looptoken.
Returns the descr of the last executed operation: either the one
attached to the failing guard, or the one attached to the FINISH.
- Use set_future_value_xxx() before, and get_latest_value_xxx() after.
+ Use get_latest_value_xxx() afterwards to read the result(s).
"""
- raise NotImplementedError
+ argtypes = [lltype.typeOf(x) for x in args]
+ execute = self.make_execute_token(*argtypes)
+ return execute(looptoken, *args)
- def set_future_value_int(self, index, intvalue):
- """Set the value for the index'th argument for the loop to run."""
- raise NotImplementedError
-
- def set_future_value_float(self, index, floatvalue):
- """Set the value for the index'th argument for the loop to run."""
- raise NotImplementedError
-
- def set_future_value_ref(self, index, objvalue):
- """Set the value for the index'th argument for the loop to run."""
+ def make_execute_token(self, *argtypes):
+ """Must make and return an execute_token() function that will be
+ called with the given argtypes.
+ """
raise NotImplementedError
def get_latest_value_int(self, index):
diff --git a/pypy/jit/backend/test/calling_convention_test.py b/pypy/jit/backend/test/calling_convention_test.py
--- a/pypy/jit/backend/test/calling_convention_test.py
+++ b/pypy/jit/backend/test/calling_convention_test.py
@@ -41,17 +41,18 @@
local_floats = list(floats)
local_ints = list(ints)
expected_result = 0.0
+ arguments = []
for i in range(len(args)):
x = args[i]
if x[0] == 'f':
x = local_floats.pop()
t = longlong.getfloatstorage(x)
- self.cpu.set_future_value_float(i, t)
+ arguments.append(t)
else:
x = local_ints.pop()
- self.cpu.set_future_value_int(i, x)
+ arguments.append(x)
expected_result += x
- return expected_result
+ return arguments, expected_result
@classmethod
def get_funcbox(cls, cpu, func_ptr):
@@ -111,9 +112,9 @@
looptoken = JitCellToken()
done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr())
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
- expected_result = self._prepare_args(args, floats, ints)
+ argvals, expected_result = self._prepare_args(args, floats, ints)
- res = self.cpu.execute_token(looptoken)
+ res = self.cpu.execute_token(looptoken, *argvals)
x = longlong.getrealfloat(cpu.get_latest_value_float(0))
assert abs(x - expected_result) < 0.0001
@@ -259,8 +260,8 @@
done_number = self.cpu.get_fail_descr_number(called_loop.operations[-1].getdescr())
self.cpu.compile_loop(called_loop.inputargs, called_loop.operations, called_looptoken)
- expected_result = self._prepare_args(args, floats, ints)
- res = cpu.execute_token(called_looptoken)
+ argvals, expected_result = self._prepare_args(args, floats, ints)
+ res = cpu.execute_token(called_looptoken, *argvals)
assert res.identifier == 3
t = longlong.getrealfloat(cpu.get_latest_value_float(0))
assert abs(t - expected_result) < 0.0001
@@ -289,8 +290,8 @@
self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
# prepare call to called_loop
- self._prepare_args(args, floats, ints)
- res = cpu.execute_token(othertoken)
+ argvals, _ = self._prepare_args(args, floats, ints)
+ res = cpu.execute_token(othertoken, *argvals)
x = longlong.getrealfloat(cpu.get_latest_value_float(0))
assert res.identifier == 4
assert abs(x - expected_result) < 0.0001
diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -34,20 +34,17 @@
descr)
looptoken = JitCellToken()
self.cpu.compile_loop(inputargs, operations, looptoken)
- j = 0
+ args = []
for box in inputargs:
if isinstance(box, BoxInt):
- self.cpu.set_future_value_int(j, box.getint())
- j += 1
+ args.append(box.getint())
elif isinstance(box, (BoxPtr, BoxObj)):
- self.cpu.set_future_value_ref(j, box.getref_base())
- j += 1
+ args.append(box.getref_base())
elif isinstance(box, BoxFloat):
- self.cpu.set_future_value_float(j, box.getfloatstorage())
- j += 1
+ args.append(box.getfloatstorage())
else:
raise NotImplementedError(box)
- res = self.cpu.execute_token(looptoken)
+ res = self.cpu.execute_token(looptoken, *args)
if res is operations[-1].getdescr():
self.guard_failed = False
else:
@@ -108,8 +105,7 @@
inputargs = [i0]
looptoken = JitCellToken()
self.cpu.compile_loop(inputargs, operations, looptoken)
- self.cpu.set_future_value_int(0, 2)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 2)
res = self.cpu.get_latest_value_int(0)
assert res == 3
assert fail.identifier == 1
@@ -124,8 +120,7 @@
inputargs = [i0]
looptoken = JitCellToken()
self.cpu.compile_loop(inputargs, operations, looptoken)
- self.cpu.set_future_value_float(0, longlong.getfloatstorage(2.8))
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, longlong.getfloatstorage(2.8))
res = self.cpu.get_latest_value_float(0)
assert longlong.getrealfloat(res) == 5.1
assert fail.identifier == 1
@@ -147,8 +142,7 @@
operations[3].setfailargs([i1])
self.cpu.compile_loop(inputargs, operations, looptoken)
- self.cpu.set_future_value_int(0, 2)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 2)
assert fail.identifier == 2
res = self.cpu.get_latest_value_int(0)
assert res == 10
@@ -172,8 +166,7 @@
operations[4].setfailargs([None, None, i1, None])
self.cpu.compile_loop(inputargs, operations, looptoken)
- self.cpu.set_future_value_int(0, 44)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 44)
assert fail.identifier == 2
res = self.cpu.get_latest_value_int(2)
assert res == 10
@@ -238,8 +231,7 @@
self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken)
- self.cpu.set_future_value_int(0, 2)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 2)
assert fail.identifier == 2
res = self.cpu.get_latest_value_int(0)
assert res == 20
@@ -280,8 +272,7 @@
self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken)
- self.cpu.set_future_value_int(0, 2)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 2)
assert fail.identifier == 2
res = self.cpu.get_latest_value_int(0)
assert res == 20
@@ -304,8 +295,7 @@
operations[3].setfailargs([None, i1, None])
self.cpu.compile_loop(inputargs, operations, looptoken)
- self.cpu.set_future_value_int(0, 2)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 2)
assert fail is faildescr1
count = self.cpu.get_latest_value_count()
@@ -327,8 +317,7 @@
ResOperation(rop.FINISH, [i0], None, descr=faildescr)
]
self.cpu.compile_loop([i0], operations, looptoken)
- self.cpu.set_future_value_int(0, 99)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 99)
assert fail is faildescr
res = self.cpu.get_latest_value_int(0)
assert res == 99
@@ -359,8 +348,7 @@
]
self.cpu.compile_loop([f0], operations, looptoken)
value = longlong.getfloatstorage(-61.25)
- self.cpu.set_future_value_float(0, value)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, value)
assert fail is faildescr
res = self.cpu.get_latest_value_float(0)
assert longlong.getrealfloat(res) == -61.25
@@ -395,9 +383,7 @@
]
operations[-2].setfailargs([t, z])
cpu.compile_loop([x, y], operations, looptoken)
- self.cpu.set_future_value_int(0, 0)
- self.cpu.set_future_value_int(1, 10)
- res = self.cpu.execute_token(looptoken)
+ res = self.cpu.execute_token(looptoken, 0, 10)
assert self.cpu.get_latest_value_int(0) == 0
assert self.cpu.get_latest_value_int(1) == 55
@@ -458,9 +444,7 @@
for x, y, z in testcases:
excvalue = self.cpu.grab_exc_value()
assert not excvalue
- self.cpu.set_future_value_int(0, x)
- self.cpu.set_future_value_int(1, y)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, x, y)
if (z == boom) ^ reversed:
assert fail.identifier == 1
else:
@@ -1161,17 +1145,7 @@
assert 0
values[index_counter] = 11
#
- for i, (box, val) in enumerate(zip(inputargs, values)):
- if isinstance(box, BoxInt):
- self.cpu.set_future_value_int(i, val)
- elif isinstance(box, BoxPtr):
- self.cpu.set_future_value_ref(i, val)
- elif isinstance(box, BoxFloat):
- self.cpu.set_future_value_float(i, val)
- else:
- assert 0
- #
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, *values)
assert fail.identifier == 15
#
dstvalues = values[:]
@@ -1223,10 +1197,11 @@
self.cpu.compile_bridge(faildescr1, fboxes2, bridge, looptoken)
+ args = []
for i in range(len(fboxes)):
x = 13.5 + 6.73 * i
- self.cpu.set_future_value_float(i, longlong.getfloatstorage(x))
- fail = self.cpu.execute_token(looptoken)
+ args.append(longlong.getfloatstorage(x))
+ fail = self.cpu.execute_token(looptoken, *args)
assert fail.identifier == 2
res = self.cpu.get_latest_value_float(0)
assert longlong.getrealfloat(res) == 8.5
@@ -1250,10 +1225,10 @@
loop = parse(loopops)
looptoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
- self.cpu.set_future_value_int(0, 1)
- self.cpu.set_future_value_float(1, longlong.getfloatstorage(132.25))
- self.cpu.set_future_value_float(2, longlong.getfloatstorage(0.75))
- fail = self.cpu.execute_token(looptoken)
+ args = [1]
+ args.append(longlong.getfloatstorage(132.25))
+ args.append(longlong.getfloatstorage(0.75))
+ fail = self.cpu.execute_token(looptoken, *args) #xxx check
assert loop.operations[-2].getdescr() == fail
f1 = self.cpu.get_latest_value_float(0)
f2 = self.cpu.get_latest_value_float(1)
@@ -1352,14 +1327,12 @@
if test1 == -42 or combinaison[0] == 'b':
for test2 in [-65, -42, -11, 0, 1, 10]:
if test2 == -42 or combinaison[1] == 'b':
- n = 0
+ args = []
if combinaison[0] == 'b':
- cpu.set_future_value_int(n, test1)
- n += 1
+ args.append(test1)
if combinaison[1] == 'b':
- cpu.set_future_value_int(n, test2)
- n += 1
- fail = cpu.execute_token(looptoken)
+ args.append(test2)
+ fail = cpu.execute_token(looptoken, *args)
#
expected = compare(test1, test2)
expected ^= guard_case
@@ -1405,14 +1378,12 @@
if test1 == 42 or combinaison[0] == 'b':
for test2 in [65, 42, 11, 0, 1]:
if test2 == 42 or combinaison[1] == 'b':
- n = 0
+ args = []
if combinaison[0] == 'b':
- cpu.set_future_value_int(n, test1)
- n += 1
+ args.append(test1)
if combinaison[1] == 'b':
- cpu.set_future_value_int(n, test2)
- n += 1
- fail = cpu.execute_token(looptoken)
+ args.append(test2)
+ fail = cpu.execute_token(looptoken, *args)
#
expected = compare(test1, test2)
expected ^= guard_case
@@ -1464,16 +1435,14 @@
if test1 == -4.5 or combinaison[0] == 'b':
for test2 in [-6.5, -4.5, -2.5, nan]:
if test2 == -4.5 or combinaison[1] == 'b':
- n = 0
+ args = []
if combinaison[0] == 'b':
- cpu.set_future_value_float(
- n, longlong.getfloatstorage(test1))
- n += 1
+ args.append(
+ longlong.getfloatstorage(test1))
if combinaison[1] == 'b':
- cpu.set_future_value_float(
- n, longlong.getfloatstorage(test2))
- n += 1
- fail = cpu.execute_token(looptoken)
+ args.append(
+ longlong.getfloatstorage(test2))
+ fail = cpu.execute_token(looptoken, *args)
#
expected = compare(test1, test2)
expected ^= guard_case
@@ -1517,15 +1486,16 @@
#
self.cpu.compile_loop(inputargs, operations, looptoken)
#
- for i, box in enumerate(inputargs):
+ args = []
+ for box in inputargs:
if isinstance(box, BoxInt):
- self.cpu.set_future_value_int(i, box.getint())
+ args.append(box.getint())
elif isinstance(box, BoxFloat):
- self.cpu.set_future_value_float(i, box.getfloatstorage())
+ args.append(box.getfloatstorage())
else:
assert 0
#
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, *args)
assert fail.identifier == 1
def test_nan_and_infinity(self):
@@ -1588,10 +1558,9 @@
unique_testcase_list = list(set(testcase))
self.cpu.compile_loop(unique_testcase_list, operations,
looptoken)
- for i, box in enumerate(unique_testcase_list):
- self.cpu.set_future_value_float(
- i, box.getfloatstorage())
- fail = self.cpu.execute_token(looptoken)
+ args = [box.getfloatstorage()
+ for box in unique_testcase_list]
+ fail = self.cpu.execute_token(looptoken, *args)
if fail.identifier != 5 - (expected_id^expected):
if fail.identifier == 4:
msg = "was taken"
@@ -1863,14 +1832,12 @@
loop = parse(ops, self.cpu, namespace=locals())
looptoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
- self.cpu.set_future_value_int(0, 1)
- self.cpu.execute_token(looptoken)
+ self.cpu.execute_token(looptoken, 1)
assert self.cpu.get_latest_value_int(0) == 0
assert self.cpu.get_latest_value_ref(1) == xptr
excvalue = self.cpu.grab_exc_value()
assert not excvalue
- self.cpu.set_future_value_int(0, 0)
- self.cpu.execute_token(looptoken)
+ self.cpu.execute_token(looptoken, 0)
assert self.cpu.get_latest_value_int(0) == 1
excvalue = self.cpu.grab_exc_value()
assert not excvalue
@@ -1889,8 +1856,7 @@
loop = parse(ops, self.cpu, namespace=locals())
looptoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
- self.cpu.set_future_value_int(0, 1)
- self.cpu.execute_token(looptoken)
+ self.cpu.execute_token(looptoken, 1)
assert self.cpu.get_latest_value_int(0) == 1
excvalue = self.cpu.grab_exc_value()
assert excvalue == yptr
@@ -1908,13 +1874,11 @@
loop = parse(ops, self.cpu, namespace=locals())
looptoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
- self.cpu.set_future_value_int(0, 1)
- self.cpu.execute_token(looptoken)
+ self.cpu.execute_token(looptoken, 1)
assert self.cpu.get_latest_value_int(0) == 1
excvalue = self.cpu.grab_exc_value()
assert excvalue == xptr
- self.cpu.set_future_value_int(0, 0)
- self.cpu.execute_token(looptoken)
+ self.cpu.execute_token(looptoken, 0)
assert self.cpu.get_latest_value_int(0) == 0
excvalue = self.cpu.grab_exc_value()
assert not excvalue
@@ -2086,16 +2050,12 @@
ops[2].setfailargs([i1, i0])
looptoken = JitCellToken()
self.cpu.compile_loop([i0, i1], ops, looptoken)
- self.cpu.set_future_value_int(0, 20)
- self.cpu.set_future_value_int(1, 0)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 20, 0)
assert fail.identifier == 0
assert self.cpu.get_latest_value_int(0) == 20
assert values == []
- self.cpu.set_future_value_int(0, 10)
- self.cpu.set_future_value_int(1, 1)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 10, 1)
assert fail.identifier == 1
assert self.cpu.get_latest_value_int(0) == 1
assert self.cpu.get_latest_value_int(1) == 10
@@ -2131,16 +2091,12 @@
ops[2].setfailargs([i1, i2, i0])
looptoken = JitCellToken()
self.cpu.compile_loop([i0, i1], ops, looptoken)
- self.cpu.set_future_value_int(0, 20)
- self.cpu.set_future_value_int(1, 0)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 20, 0)
assert fail.identifier == 0
assert self.cpu.get_latest_value_int(0) == 42
assert values == []
- self.cpu.set_future_value_int(0, 10)
- self.cpu.set_future_value_int(1, 1)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 10, 1)
assert fail.identifier == 1
assert self.cpu.get_latest_value_int(0) == 1
assert self.cpu.get_latest_value_int(1) == 42
@@ -2179,17 +2135,13 @@
ops[2].setfailargs([i1, f2, i0])
looptoken = JitCellToken()
self.cpu.compile_loop([i0, i1], ops, looptoken)
- self.cpu.set_future_value_int(0, 20)
- self.cpu.set_future_value_int(1, 0)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 20, 0)
assert fail.identifier == 0
x = self.cpu.get_latest_value_float(0)
assert longlong.getrealfloat(x) == 42.5
assert values == []
- self.cpu.set_future_value_int(0, 10)
- self.cpu.set_future_value_int(1, 1)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 10, 1)
assert fail.identifier == 1
assert self.cpu.get_latest_value_int(0) == 1
x = self.cpu.get_latest_value_float(1)
@@ -2224,8 +2176,7 @@
ops[1].setfailargs([i1, i2])
looptoken = JitCellToken()
self.cpu.compile_loop([i1], ops, looptoken)
- self.cpu.set_future_value_int(0, ord('G'))
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, ord('G'))
assert fail.identifier == 0
assert self.cpu.get_latest_value_int(0) == ord('g')
@@ -2284,12 +2235,12 @@
ops[1].setfailargs([])
looptoken = JitCellToken()
self.cpu.compile_loop([i0, i1, i2, i3], ops, looptoken)
- self.cpu.set_future_value_int(0, rffi.cast(lltype.Signed, raw))
- self.cpu.set_future_value_int(1, 2)
- self.cpu.set_future_value_int(2, 4)
- self.cpu.set_future_value_int(3, rffi.cast(lltype.Signed, fn))
+ args = [rffi.cast(lltype.Signed, raw),
+ 2,
+ 4,
+ rffi.cast(lltype.Signed, fn)]
assert glob.lst == []
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, *args)
assert fail.identifier == 0
assert len(glob.lst) > 0
lltype.free(raw, flavor='raw')
@@ -2342,9 +2293,8 @@
self.cpu.compile_loop([i1, i2], ops, looptoken)
buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw')
- self.cpu.set_future_value_int(0, buflen)
- self.cpu.set_future_value_int(1, rffi.cast(lltype.Signed, buffer))
- fail = self.cpu.execute_token(looptoken)
+ args = [buflen, rffi.cast(lltype.Signed, buffer)]
+ fail = self.cpu.execute_token(looptoken, *args)
assert fail.identifier == 0
assert self.cpu.get_latest_value_int(0) == len(cwd)
assert rffi.charp2strn(buffer, buflen) == cwd
@@ -2363,9 +2313,7 @@
looptoken = JitCellToken()
self.cpu.compile_loop([i0, i1], ops, looptoken)
- self.cpu.set_future_value_int(0, -42)
- self.cpu.set_future_value_int(1, 9)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, -42, 9)
assert fail.identifier == 0
assert self.cpu.get_latest_value_int(0) == -42
print 'step 1 ok'
@@ -2374,9 +2322,7 @@
# mark as failing
self.cpu.invalidate_loop(looptoken)
- self.cpu.set_future_value_int(0, -42)
- self.cpu.set_future_value_int(1, 9)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, -42, 9)
assert fail is faildescr
assert self.cpu.get_latest_value_int(0) == 9
print 'step 2 ok'
@@ -2392,9 +2338,7 @@
ops[0].setfailargs([])
self.cpu.compile_bridge(faildescr, [i2], ops, looptoken)
- self.cpu.set_future_value_int(0, -42)
- self.cpu.set_future_value_int(1, 9)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, -42, 9)
assert fail.identifier == 3
assert self.cpu.get_latest_value_int(0) == 9
print 'step 3 ok'
@@ -2403,9 +2347,7 @@
# mark as failing again
self.cpu.invalidate_loop(looptoken)
- self.cpu.set_future_value_int(0, -42)
- self.cpu.set_future_value_int(1, 9)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, -42, 9)
assert fail is faildescr2
print 'step 4 ok'
print '-'*79
@@ -2618,9 +2560,8 @@
FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES,
EffectInfo.MOST_GENERAL)
- for i in range(10):
- self.cpu.set_future_value_int(i, i+1)
- res = self.cpu.execute_token(looptoken)
+ args = [i+1 for i in range(10)]
+ res = self.cpu.execute_token(looptoken, *args)
assert self.cpu.get_latest_value_int(0) == 55
ops = '''
[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
@@ -2632,9 +2573,8 @@
loop = parse(ops, namespace=locals())
othertoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
- for i in range(10):
- self.cpu.set_future_value_int(i, i+1)
- res = self.cpu.execute_token(othertoken)
+ args = [i+1 for i in range(10)]
+ res = self.cpu.execute_token(othertoken, *args)
assert self.cpu.get_latest_value_int(0) == 13
assert called == [done_number]
@@ -2644,9 +2584,8 @@
try:
othertoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
- for i in range(10):
- self.cpu.set_future_value_int(i, i+1)
- res = self.cpu.execute_token(othertoken)
+ args = [i+1 for i in range(10)]
+ res = self.cpu.execute_token(othertoken, *args)
assert self.cpu.get_latest_value_int(0) == 97
assert not called
finally:
@@ -2686,9 +2625,9 @@
looptoken = JitCellToken()
looptoken.outermost_jitdriver_sd = FakeJitDriverSD()
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
- self.cpu.set_future_value_float(0, longlong.getfloatstorage(1.2))
- self.cpu.set_future_value_float(1, longlong.getfloatstorage(2.3))
- res = self.cpu.execute_token(looptoken)
+ args = [longlong.getfloatstorage(1.2),
+ longlong.getfloatstorage(2.3)]
+ res = self.cpu.execute_token(looptoken, *args)
x = self.cpu.get_latest_value_float(0)
assert longlong.getrealfloat(x) == 1.2 + 2.3
ops = '''
@@ -2700,9 +2639,9 @@
loop = parse(ops, namespace=locals())
othertoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
- self.cpu.set_future_value_float(0, longlong.getfloatstorage(1.2))
- self.cpu.set_future_value_float(1, longlong.getfloatstorage(3.2))
- res = self.cpu.execute_token(othertoken)
+ args = [longlong.getfloatstorage(1.2),
+ longlong.getfloatstorage(3.2)]
+ res = self.cpu.execute_token(othertoken, *args)
x = self.cpu.get_latest_value_float(0)
assert longlong.getrealfloat(x) == 13.5
assert called == [done_number]
@@ -2713,9 +2652,9 @@
try:
othertoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
- self.cpu.set_future_value_float(0, longlong.getfloatstorage(1.2))
- self.cpu.set_future_value_float(1, longlong.getfloatstorage(3.2))
- res = self.cpu.execute_token(othertoken)
+ args = [longlong.getfloatstorage(1.2),
+ longlong.getfloatstorage(3.2)]
+ res = self.cpu.execute_token(othertoken, *args)
x = self.cpu.get_latest_value_float(0)
assert longlong.getrealfloat(x) == 1.2 + 3.2
assert not called
@@ -2780,9 +2719,9 @@
looptoken.outermost_jitdriver_sd = FakeJitDriverSD()
self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr())
- self.cpu.set_future_value_float(0, longlong.getfloatstorage(1.25))
- self.cpu.set_future_value_float(1, longlong.getfloatstorage(2.35))
- res = self.cpu.execute_token(looptoken)
+ args = [longlong.getfloatstorage(1.25),
+ longlong.getfloatstorage(2.35)]
+ res = self.cpu.execute_token(looptoken, *args)
x = self.cpu.get_latest_value_float(0)
assert longlong.getrealfloat(x) == 1.25 + 2.35
assert not called
@@ -2798,9 +2737,9 @@
self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
# normal call_assembler: goes to looptoken
- self.cpu.set_future_value_float(0, longlong.getfloatstorage(1.25))
- self.cpu.set_future_value_float(1, longlong.getfloatstorage(3.25))
- res = self.cpu.execute_token(othertoken)
+ args = [longlong.getfloatstorage(1.25),
+ longlong.getfloatstorage(3.25)]
+ res = self.cpu.execute_token(othertoken, *args)
x = self.cpu.get_latest_value_float(0)
assert longlong.getrealfloat(x) == 13.5
assert called == [done_number]
@@ -2821,10 +2760,9 @@
self.cpu.redirect_call_assembler(looptoken, looptoken2)
# now, our call_assembler should go to looptoken2
- self.cpu.set_future_value_float(0, longlong.getfloatstorage(6.0))
- self.cpu.set_future_value_float(1, longlong.getfloatstorage(1.5))
- # 6.0-1.5 == 1.25+3.25
- res = self.cpu.execute_token(othertoken)
+ args = [longlong.getfloatstorage(6.0),
+ longlong.getfloatstorage(1.5)] # 6.0-1.5 == 1.25+3.25
+ res = self.cpu.execute_token(othertoken, *args)
x = self.cpu.get_latest_value_float(0)
assert longlong.getrealfloat(x) == 13.5
assert called == [done_number]
@@ -3178,9 +3116,11 @@
looptoken = JitCellToken()
self.cpu.compile_loop(inputargs, operations, looptoken)
# overflowing value:
- self.cpu.set_future_value_int(0, sys.maxint // 4 + 1)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, sys.maxint // 4 + 1)
assert fail.identifier == excdescr.identifier
+ exc = self.cpu.grab_exc_value()
+ assert exc == "memoryerror!"
+
def test_math_sqrt(self):
if not self.cpu.supports_floats:
py.test.skip("requires floats")
@@ -3228,8 +3168,7 @@
operations[6].setfailargs([i1])
self.cpu.compile_loop(inputargs, operations, looptoken)
- self.cpu.set_future_value_int(0, 2)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 2)
assert fail.identifier == 2
res = self.cpu.get_latest_value_int(0)
assert res == 10
@@ -3241,8 +3180,7 @@
]
self.cpu.compile_bridge(faildescr, inputargs, operations, looptoken)
- self.cpu.set_future_value_int(0, 2)
- fail = self.cpu.execute_token(looptoken)
+ fail = self.cpu.execute_token(looptoken, 2)
assert fail.identifier == 3
res = self.cpu.get_latest_value_int(0)
assert res == -10
@@ -3322,13 +3260,13 @@
self.cpu.compile_bridge(faildescr1, inputargs, operations, looptoken1)
looptoken2 = JitCellToken()
- inputargs = []
+ inputargs = [BoxInt()]
operations = [
ResOperation(rop.JUMP, [ConstInt(0)], None, descr=targettoken1),
]
self.cpu.compile_loop(inputargs, operations, looptoken2)
- fail = self.cpu.execute_token(looptoken2)
+ fail = self.cpu.execute_token(looptoken2, -9)
assert fail.identifier == 42
diff --git a/pypy/jit/backend/test/test_random.py b/pypy/jit/backend/test/test_random.py
--- a/pypy/jit/backend/test/test_random.py
+++ b/pypy/jit/backend/test/test_random.py
@@ -6,6 +6,7 @@
from pypy.jit.metainterp.history import BoxInt, ConstInt, JitCellToken
from pypy.jit.metainterp.history import BoxPtr, ConstPtr, TargetToken
from pypy.jit.metainterp.history import BoxFloat, ConstFloat, Const
+from pypy.jit.metainterp.history import INT, FLOAT
from pypy.jit.metainterp.resoperation import ResOperation, rop
from pypy.jit.metainterp.executor import execute_nonspec
from pypy.jit.metainterp.resoperation import opname
@@ -616,8 +617,13 @@
return self.loop._jitcelltoken
if not hasattr(self, '_initialjumploop_celltoken'):
self._initialjumploop_celltoken = JitCellToken()
- self.cpu.compile_loop(self.startvars[:],
- [ResOperation(rop.JUMP, self.startvars[:], None,
+ args = []
+ for box in self.startvars:
+ if box not in self.loop.inputargs:
+ box = box.constbox()
+ args.append(box)
+ self.cpu.compile_loop(self.loop.inputargs,
+ [ResOperation(rop.JUMP, args, None,
descr=self.loop._targettoken)],
self._initialjumploop_celltoken)
return self._initialjumploop_celltoken
@@ -649,14 +655,8 @@
exc = cpu.grab_exc_value()
assert not exc
- for i, box in enumerate(self.startvars):
- if isinstance(box, BoxInt):
- cpu.set_future_value_int(i, box.value)
- elif isinstance(box, BoxFloat):
- cpu.set_future_value_float(i, box.value)
- else:
- raise NotImplementedError(box)
- fail = cpu.execute_token(self.runjitcelltoken())
+ arguments = [box.value for box in self.loop.inputargs]
+ fail = cpu.execute_token(self.runjitcelltoken(), *arguments)
assert fail is self.should_fail_by.getdescr()
for i, v in enumerate(self.get_fail_args()):
if isinstance(v, (BoxFloat, ConstFloat)):
@@ -717,10 +717,21 @@
# to build_bridge().)
# First make up the other loop...
- subset = bridge_builder.subset_of_intvars(r)
- subset = [i for i in subset if i in fail_args]
- if len(subset) == 0:
- return False
+ #
+ # New restriction: must have the same argument count and types
+ # as the original loop
+ subset = []
+ for box in self.loop.inputargs:
+ srcbox = r.choice(fail_args)
+ if srcbox.type != box.type:
+ if box.type == INT:
+ srcbox = ConstInt(r.random_integer())
+ elif box.type == FLOAT:
+ srcbox = ConstFloat(r.random_float_storage())
+ else:
+ raise AssertionError(box.type)
+ subset.append(srcbox)
+ #
args = [x.clonebox() for x in subset]
rl = RandomLoop(self.builder.cpu, self.builder.fork,
r, args)
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -38,6 +38,8 @@
from pypy.jit.backend.x86.jump import remap_frame_layout
from pypy.jit.codewriter.effectinfo import EffectInfo
from pypy.jit.codewriter import longlong
+from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.objectmodel import compute_unique_id
# darwin requires the stack to be 16 bytes aligned on calls. Same for gcc 4.5.0,
# better safe than sorry
@@ -57,7 +59,8 @@
self.is_guard_not_invalidated = is_guard_not_invalidated
DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed),
- ('bridge', lltype.Signed), # 0 or 1
+ ('type', lltype.Char), # 'b'ridge, 'l'abel or
+ # 'e'ntry point
('number', lltype.Signed))
class Assembler386(object):
@@ -69,10 +72,6 @@
self.cpu = cpu
self.verbose = False
self.rtyper = cpu.rtyper
- self.malloc_func_addr = 0
- self.malloc_array_func_addr = 0
- self.malloc_str_func_addr = 0
- self.malloc_unicode_func_addr = 0
self.fail_boxes_int = values_array(lltype.Signed, failargs_limit)
self.fail_boxes_ptr = values_array(llmemory.GCREF, failargs_limit)
self.fail_boxes_float = values_array(longlong.FLOATSTORAGE,
@@ -107,20 +106,6 @@
# the address of the function called by 'new'
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)
- 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)
self.memcpy_addr = self.cpu.cast_ptr_to_int(support.memcpy_fn)
self._build_failure_recovery(False)
self._build_failure_recovery(True)
@@ -164,12 +149,15 @@
def finish_once(self):
if self._debug:
debug_start('jit-backend-counts')
- for struct in self.loop_run_counters:
- if struct.bridge:
- prefix = 'bridge '
+ for i in range(len(self.loop_run_counters)):
+ struct = self.loop_run_counters[i]
+ if struct.type == 'l':
+ prefix = 'TargetToken(%d)' % struct.number
+ elif struct.type == 'b':
+ prefix = 'bridge ' + str(struct.number)
else:
- prefix = 'loop '
- debug_print(prefix + str(struct.number) + ':' + str(struct.i))
+ prefix = 'entry ' + str(struct.number)
+ debug_print(prefix + ':' + str(struct.i))
debug_stop('jit-backend-counts')
def _build_float_constants(self):
@@ -274,7 +262,8 @@
#
self.mc = codebuf.MachineCodeBlockWrapper()
# call on_leave_jitted_save_exc()
- 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)
self.mc.CALL(imm(addr))
self.mc.MOV_ri(eax.value, self.cpu.propagate_exception_v)
self._call_footer()
@@ -309,12 +298,11 @@
mc.MOVSD_sx(8*i, i) # xmm0 to xmm7
#
if IS_X86_32:
- mc.LEA_rb(eax.value, +8)
stack_size += 2*WORD
mc.PUSH_r(eax.value) # alignment
- mc.PUSH_r(eax.value)
+ mc.PUSH_r(esp.value)
elif IS_X86_64:
- mc.LEA_rb(edi.value, +16)
+ mc.MOV_rr(edi.value, esp.value)
#
# esp is now aligned to a multiple of 16 again
mc.CALL(imm(slowpathaddr))
@@ -325,7 +313,7 @@
jnz_location = mc.get_relative_pos()
#
if IS_X86_32:
- mc.ADD_ri(esp.value, 2*WORD)
+ mc.ADD_ri(esp.value, 2*WORD) # cancel the two PUSHes above
elif IS_X86_64:
# restore the registers
for i in range(7, -1, -1):
@@ -421,10 +409,8 @@
def assemble_loop(self, loopname, inputargs, operations, looptoken, log):
'''adds the following attributes to looptoken:
- _x86_loop_code (an integer giving an address)
- _x86_bootstrap_code (an integer giving an address)
- _x86_direct_bootstrap_code ( " " " " )
- _x86_arglocs
+ _x86_function_addr (address of the generated func, as an int)
+ _x86_loop_code (debug: addr of the start of the ResOps)
_x86_debug_checksum
'''
# XXX this function is too longish and contains some code
@@ -441,16 +427,16 @@
self.setup(looptoken)
if log:
- self._register_counter(False, looptoken.number)
- operations = self._inject_debugging_code(looptoken, operations)
+ operations = self._inject_debugging_code(looptoken, operations,
+ 'e', looptoken.number)
regalloc = RegAlloc(self, self.cpu.translate_support_code)
- arglocs, operations = regalloc.prepare_loop(inputargs, operations,
- looptoken, clt.allgcrefs)
- looptoken._x86_arglocs = arglocs
-
- bootstrappos = self.mc.get_relative_pos()
- stackadjustpos = self._assemble_bootstrap_code(inputargs, arglocs)
+ #
+ self._call_header_with_stack_check()
+ stackadjustpos = self._patchable_stackadjust()
+ clt._debug_nbargs = len(inputargs)
+ operations = regalloc.prepare_loop(inputargs, operations,
+ looptoken, clt.allgcrefs)
looppos = self.mc.get_relative_pos()
looptoken._x86_loop_code = looppos
clt.frame_depth = -1 # temporarily
@@ -458,19 +444,17 @@
frame_depth, param_depth = self._assemble(regalloc, operations)
clt.frame_depth = frame_depth
clt.param_depth = param_depth
-
- directbootstrappos = self.mc.get_relative_pos()
- self._assemble_bootstrap_direct_call(arglocs, looppos,
- frame_depth+param_depth)
+ #
+ size_excluding_failure_stuff = self.mc.get_relative_pos()
self.write_pending_failure_recoveries()
- fullsize = self.mc.get_relative_pos()
+ full_size = self.mc.get_relative_pos()
#
rawstart = self.materialize_loop(looptoken)
debug_start("jit-backend-addr")
debug_print("Loop %d (%s) has address %x to %x (bootstrap %x)" % (
looptoken.number, loopname,
rawstart + looppos,
- rawstart + directbootstrappos,
+ rawstart + size_excluding_failure_stuff,
rawstart))
debug_stop("jit-backend-addr")
self._patch_stackadjust(rawstart + stackadjustpos,
@@ -481,18 +465,17 @@
if not we_are_translated():
# used only by looptoken.dump() -- useful in tests
looptoken._x86_rawstart = rawstart
- looptoken._x86_fullsize = fullsize
+ looptoken._x86_fullsize = full_size
looptoken._x86_ops_offset = ops_offset
+ looptoken._x86_function_addr = rawstart
- looptoken._x86_bootstrap_code = rawstart + bootstrappos
- looptoken._x86_direct_bootstrap_code = rawstart + directbootstrappos
self.fixup_target_tokens(rawstart)
self.teardown()
# oprofile support
if self.cpu.profile_agent is not None:
name = "Loop # %s: %s" % (looptoken.number, loopname)
self.cpu.profile_agent.native_code_written(name,
- rawstart, fullsize)
+ rawstart, full_size)
return ops_offset
def assemble_bridge(self, faildescr, inputargs, operations,
@@ -511,8 +494,8 @@
self.setup(original_loop_token)
if log:
- self._register_counter(True, descr_number)
- operations = self._inject_debugging_code(faildescr, operations)
+ operations = self._inject_debugging_code(faildescr, operations,
+ 'b', descr_number)
arglocs = self.rebuild_faillocs_from_descr(failure_recovery)
if not we_are_translated():
@@ -619,17 +602,21 @@
return self.mc.materialize(self.cpu.asmmemmgr, allblocks,
self.cpu.gc_ll_descr.gcrootmap)
- def _register_counter(self, bridge, number):
- if self._debug:
- # YYY very minor leak -- we need the counters to stay alive
- # forever, just because we want to report them at the end
- # of the process
- struct = lltype.malloc(DEBUG_COUNTER, flavor='raw',
- track_allocation=False)
- struct.i = 0
- struct.bridge = int(bridge)
+ def _register_counter(self, tp, number, token):
+ # YYY very minor leak -- we need the counters to stay alive
+ # forever, just because we want to report them at the end
+ # of the process
+ struct = lltype.malloc(DEBUG_COUNTER, flavor='raw',
+ track_allocation=False)
+ struct.i = 0
+ struct.type = tp
+ if tp == 'b' or tp == 'e':
struct.number = number
- self.loop_run_counters.append(struct)
+ else:
+ assert token
+ struct.number = compute_unique_id(token)
+ self.loop_run_counters.append(struct)
+ return struct
def _find_failure_recovery_bytecode(self, faildescr):
adr_jump_offset = faildescr._x86_adr_jump_offset
@@ -673,27 +660,36 @@
targettoken._x86_loop_code += rawstart
self.target_tokens_currently_compiling = None
+ def _append_debugging_code(self, operations, tp, number, token):
+ counter = self._register_counter(tp, number, token)
+ c_adr = ConstInt(rffi.cast(lltype.Signed, counter))
+ box = BoxInt()
+ box2 = BoxInt()
+ ops = [ResOperation(rop.GETFIELD_RAW, [c_adr],
+ box, descr=self.debug_counter_descr),
+ ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2),
+ ResOperation(rop.SETFIELD_RAW, [c_adr, box2],
+ None, descr=self.debug_counter_descr)]
+ operations.extend(ops)
+
@specialize.argtype(1)
- def _inject_debugging_code(self, looptoken, operations):
+ def _inject_debugging_code(self, looptoken, operations, tp, number):
if self._debug:
# before doing anything, let's increase a counter
s = 0
for op in operations:
s += op.getopnum()
looptoken._x86_debug_checksum = s
- c_adr = ConstInt(rffi.cast(lltype.Signed,
- self.loop_run_counters[-1]))
- box = BoxInt()
- box2 = BoxInt()
- ops = [ResOperation(rop.GETFIELD_RAW, [c_adr],
- box, descr=self.debug_counter_descr),
- ResOperation(rop.INT_ADD, [box, ConstInt(1)], box2),
- ResOperation(rop.SETFIELD_RAW, [c_adr, box2],
- None, descr=self.debug_counter_descr)]
- if operations[0].getopnum() == rop.LABEL:
- operations = [operations[0]] + ops + operations[1:]
- else:
- operations = ops + operations
+
+ newoperations = []
+ self._append_debugging_code(newoperations, tp, number,
+ None)
+ for op in operations:
+ newoperations.append(op)
+ if op.getopnum() == rop.LABEL:
+ self._append_debugging_code(newoperations, 'l', number,
+ op.getdescr())
+ operations = newoperations
return operations
def _assemble(self, regalloc, operations):
@@ -802,152 +798,21 @@
self.mc.MOV_ri(ebx.value, rst) # MOV ebx, rootstacktop
self.mc.SUB_mi8((ebx.value, 0), 2*WORD) # SUB [ebx], 2*WORD
- def _assemble_bootstrap_direct_call(self, arglocs, jmppos, stackdepth):
- if IS_X86_64:
- return self._assemble_bootstrap_direct_call_64(arglocs, jmppos, stackdepth)
- # XXX pushing ebx esi and edi is a bit pointless, since we store
- # all regsiters anyway, for the case of guard_not_forced
- # XXX this can be improved greatly. Right now it'll behave like
- # a normal call
- nonfloatlocs, floatlocs = arglocs
- self._call_header_with_stack_check()
- self.mc.LEA_rb(esp.value, self._get_offset_of_ebp_from_esp(stackdepth))
- offset = 2 * WORD
- tmp = eax
- xmmtmp = xmm0
- for i in range(len(nonfloatlocs)):
- loc = nonfloatlocs[i]
- if loc is not None:
- if isinstance(loc, RegLoc):
- assert not loc.is_xmm
- self.mc.MOV_rb(loc.value, offset)
- else:
- self.mc.MOV_rb(tmp.value, offset)
- self.mc.MOV(loc, tmp)
- offset += WORD
- loc = floatlocs[i]
- if loc is not None:
- if isinstance(loc, RegLoc):
- assert loc.is_xmm
- self.mc.MOVSD_xb(loc.value, offset)
- else:
- self.mc.MOVSD_xb(xmmtmp.value, offset)
- assert isinstance(loc, StackLoc)
- self.mc.MOVSD_bx(loc.value, xmmtmp.value)
- offset += 2 * WORD
- endpos = self.mc.get_relative_pos() + 5
- self.mc.JMP_l(jmppos - endpos)
- assert endpos == self.mc.get_relative_pos()
-
- def _assemble_bootstrap_direct_call_64(self, arglocs, jmppos, stackdepth):
- # XXX: Very similar to _emit_call_64
-
- src_locs = []
- dst_locs = []
- xmm_src_locs = []
- xmm_dst_locs = []
- get_from_stack = []
-
- # In reverse order for use with pop()
- unused_gpr = [r9, r8, ecx, edx, esi, edi]
- unused_xmm = [xmm7, xmm6, xmm5, xmm4, xmm3, xmm2, xmm1, xmm0]
-
- nonfloatlocs, floatlocs = arglocs
- self._call_header_with_stack_check()
- self.mc.LEA_rb(esp.value, self._get_offset_of_ebp_from_esp(stackdepth))
-
- # The lists are padded with Nones
- assert len(nonfloatlocs) == len(floatlocs)
-
- for i in range(len(nonfloatlocs)):
- loc = nonfloatlocs[i]
- if loc is not None:
- if len(unused_gpr) > 0:
- src_locs.append(unused_gpr.pop())
- dst_locs.append(loc)
- else:
- get_from_stack.append((loc, False))
-
- floc = floatlocs[i]
- if floc is not None:
- if len(unused_xmm) > 0:
- xmm_src_locs.append(unused_xmm.pop())
- xmm_dst_locs.append(floc)
- else:
- get_from_stack.append((floc, True))
-
- remap_frame_layout(self, src_locs, dst_locs, X86_64_SCRATCH_REG)
- remap_frame_layout(self, xmm_src_locs, xmm_dst_locs, X86_64_XMM_SCRATCH_REG)
-
- for i in range(len(get_from_stack)):
- loc, is_xmm = get_from_stack[i]
- if is_xmm:
- self.mc.MOVSD_xb(X86_64_XMM_SCRATCH_REG.value, (2 + i) * WORD)
- self.mc.MOVSD(loc, X86_64_XMM_SCRATCH_REG)
- else:
- self.mc.MOV_rb(X86_64_SCRATCH_REG.value, (2 + i) * WORD)
- # XXX: We're assuming that "loc" won't require regloc to
- # clobber the scratch register
- self.mc.MOV(loc, X86_64_SCRATCH_REG)
-
- endpos = self.mc.get_relative_pos() + 5
- self.mc.JMP_l(jmppos - endpos)
- assert endpos == self.mc.get_relative_pos()
-
def redirect_call_assembler(self, oldlooptoken, newlooptoken):
# some minimal sanity checking
- oldnonfloatlocs, oldfloatlocs = oldlooptoken._x86_arglocs
- newnonfloatlocs, newfloatlocs = newlooptoken._x86_arglocs
- assert len(oldnonfloatlocs) == len(newnonfloatlocs)
- assert len(oldfloatlocs) == len(newfloatlocs)
+ 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 _x86_direct_bootstrap_code
# to start with a JMP to the new _x86_direct_bootstrap_code.
# Ideally we should rather patch all existing CALLs, but well.
- oldadr = oldlooptoken._x86_direct_bootstrap_code
- target = newlooptoken._x86_direct_bootstrap_code
+ oldadr = oldlooptoken._x86_function_addr
+ target = newlooptoken._x86_function_addr
mc = codebuf.MachineCodeBlockWrapper()
mc.JMP(imm(target))
+ assert mc.get_relative_pos() <= 13 # keep in sync with prepare_loop()
mc.copy_to_raw_memory(oldadr)
- def _assemble_bootstrap_code(self, inputargs, arglocs):
- nonfloatlocs, floatlocs = arglocs
- self._call_header()
- stackadjustpos = self._patchable_stackadjust()
- tmp = eax
- xmmtmp = xmm0
- self.mc.begin_reuse_scratch_register()
- for i in range(len(nonfloatlocs)):
- loc = nonfloatlocs[i]
- if loc is None:
- continue
- if isinstance(loc, RegLoc):
- target = loc
- else:
- target = tmp
- if inputargs[i].type == REF:
- adr = self.fail_boxes_ptr.get_addr_for_num(i)
- self.mc.MOV(target, heap(adr))
- self.mc.MOV(heap(adr), imm0)
- else:
- adr = self.fail_boxes_int.get_addr_for_num(i)
- self.mc.MOV(target, heap(adr))
- if target is not loc:
- assert isinstance(loc, StackLoc)
- self.mc.MOV_br(loc.value, target.value)
- for i in range(len(floatlocs)):
- loc = floatlocs[i]
- if loc is None:
- continue
- adr = self.fail_boxes_float.get_addr_for_num(i)
- if isinstance(loc, RegLoc):
- self.mc.MOVSD(loc, heap(adr))
- else:
- self.mc.MOVSD(xmmtmp, heap(adr))
- assert isinstance(loc, StackLoc)
- self.mc.MOVSD_bx(loc.value, xmmtmp.value)
- self.mc.end_reuse_scratch_register()
- return stackadjustpos
-
def dump(self, text):
if not self.verbose:
return
@@ -974,7 +839,7 @@
if isinstance(loc, RegLoc) and loc.is_xmm:
self.mc.SUB_ri(esp.value, 8) # = size of doubles
self.mc.MOVSD_sx(0, loc.value)
- elif WORD == 4 and isinstance(loc, StackLoc) and loc.width == 8:
+ elif WORD == 4 and isinstance(loc, StackLoc) and loc.get_width() == 8:
# XXX evil trick
self.mc.PUSH_b(get_ebp_ofs(loc.position))
self.mc.PUSH_b(get_ebp_ofs(loc.position + 1))
@@ -985,13 +850,25 @@
if isinstance(loc, RegLoc) and loc.is_xmm:
self.mc.MOVSD_xs(loc.value, 0)
self.mc.ADD_ri(esp.value, 8) # = size of doubles
- elif WORD == 4 and isinstance(loc, StackLoc) and loc.width == 8:
+ elif WORD == 4 and isinstance(loc, StackLoc) and loc.get_width() == 8:
# XXX evil trick
self.mc.POP_b(get_ebp_ofs(loc.position + 1))
self.mc.POP_b(get_ebp_ofs(loc.position))
else:
self.mc.POP(loc)
+ def regalloc_immedmem2mem(self, from_loc, to_loc):
+ # move a ConstFloatLoc directly to a StackLoc, as two MOVs
+ # (even on x86-64, because the immediates are encoded as 32 bits)
+ assert isinstance(from_loc, ConstFloatLoc)
+ assert isinstance(to_loc, StackLoc)
+ low_part = rffi.cast(rffi.CArrayPtr(rffi.INT), from_loc.value)[0]
+ high_part = rffi.cast(rffi.CArrayPtr(rffi.INT), from_loc.value)[1]
+ low_part = intmask(low_part)
+ high_part = intmask(high_part)
+ self.mc.MOV32_bi(to_loc.value, low_part)
+ self.mc.MOV32_bi(to_loc.value + 4, high_part)
+
def regalloc_perform(self, op, arglocs, resloc):
genop_list[op.getopnum()](self, op, arglocs, resloc)
@@ -1143,18 +1020,18 @@
self.mc.MOVSD_sx(p, loc.value)
else:
self.mc.MOV_sr(p, loc.value)
- p += round_up_to_4(loc.width)
+ p += loc.get_width()
p = 0
for i in range(start, n):
loc = arglocs[i]
if not isinstance(loc, RegLoc):
- if loc.width == 8:
+ if loc.get_width() == 8:
self.mc.MOVSD(xmm0, loc)
self.mc.MOVSD_sx(p, xmm0.value)
else:
self.mc.MOV(tmp, loc)
self.mc.MOV_sr(p, tmp.value)
- p += round_up_to_4(loc.width)
+ p += loc.get_width()
self._regalloc.reserve_param(p//WORD)
# x is a location
self.mc.CALL(x)
@@ -1481,46 +1358,10 @@
self.mc.SHR_ri(resloc.value, 7)
self.mc.AND_ri(resloc.value, 1)
- def genop_new_with_vtable(self, op, arglocs, result_loc):
- assert result_loc is eax
- loc_vtable = arglocs[-1]
- assert isinstance(loc_vtable, ImmedLoc)
- arglocs = arglocs[:-1]
- self.call(self.malloc_func_addr, arglocs, eax)
- self.propagate_memoryerror_if_eax_is_null()
- self.set_vtable(eax, loc_vtable)
+ # ----------
- def set_vtable(self, loc, loc_vtable):
- if self.cpu.vtable_offset is not None:
- assert isinstance(loc, RegLoc)
- assert isinstance(loc_vtable, ImmedLoc)
- self.mc.MOV(mem(loc, self.cpu.vtable_offset), loc_vtable)
-
- def set_new_array_length(self, loc, ofs_length, loc_num_elem):
- assert isinstance(loc, RegLoc)
- assert isinstance(loc_num_elem, ImmedLoc)
- self.mc.MOV(mem(loc, ofs_length), loc_num_elem)
-
- # XXX genop_new is abused for all varsized mallocs with Boehm, for now
- # (instead of genop_new_array, genop_newstr, genop_newunicode)
- def genop_new(self, op, arglocs, result_loc):
- assert result_loc is eax
- self.call(self.malloc_func_addr, arglocs, eax)
- self.propagate_memoryerror_if_eax_is_null()
-
- def genop_new_array(self, op, arglocs, result_loc):
- assert result_loc is eax
- self.call(self.malloc_array_func_addr, arglocs, eax)
- self.propagate_memoryerror_if_eax_is_null()
-
- def genop_newstr(self, op, arglocs, result_loc):
- assert result_loc is eax
- self.call(self.malloc_str_func_addr, arglocs, eax)
- self.propagate_memoryerror_if_eax_is_null()
-
- def genop_newunicode(self, op, arglocs, result_loc):
- assert result_loc is eax
- self.call(self.malloc_unicode_func_addr, arglocs, eax)
+ def genop_call_malloc_gc(self, op, arglocs, result_loc):
+ self.genop_call(op, arglocs, result_loc)
self.propagate_memoryerror_if_eax_is_null()
def propagate_memoryerror_if_eax_is_null(self):
@@ -1891,10 +1732,10 @@
DESCR_INT = 0x01
DESCR_FLOAT = 0x02
DESCR_SPECIAL = 0x03
- # XXX: 4*8 works on i386, should we optimize for that case?
- CODE_FROMSTACK = 4*16
+ CODE_FROMSTACK = 4 * (8 + 8*IS_X86_64)
CODE_STOP = 0 | DESCR_SPECIAL
CODE_HOLE = 4 | DESCR_SPECIAL
+ CODE_INPUTARG = 8 | DESCR_SPECIAL
def write_failure_recovery_description(self, mc, failargs, locs):
for i in range(len(failargs)):
@@ -1910,7 +1751,11 @@
raise AssertionError("bogus kind")
loc = locs[i]
if isinstance(loc, StackLoc):
- n = self.CODE_FROMSTACK//4 + loc.position
+ pos = loc.position
+ if pos < 0:
+ mc.writechar(chr(self.CODE_INPUTARG))
+ pos = ~pos
+ n = self.CODE_FROMSTACK//4 + pos
else:
assert isinstance(loc, RegLoc)
n = loc.value
@@ -1930,6 +1775,7 @@
descr_to_box_type = [REF, INT, FLOAT]
bytecode = rffi.cast(rffi.UCHARP, bytecode)
arglocs = []
+ code_inputarg = False
while 1:
# decode the next instruction from the bytecode
code = rffi.cast(lltype.Signed, bytecode[0])
@@ -1948,11 +1794,17 @@
break
kind = code & 3
code = (code - self.CODE_FROMSTACK) >> 2
+ if code_inputarg:
+ code = ~code
+ code_inputarg = False
loc = X86FrameManager.frame_pos(code, descr_to_box_type[kind])
elif code == self.CODE_STOP:
break
elif code == self.CODE_HOLE:
continue
+ elif code == self.CODE_INPUTARG:
+ code_inputarg = True
+ continue
else:
# 'code' identifies a register
kind = code & 3
@@ -1968,6 +1820,7 @@
def grab_frame_values(self, bytecode, frame_addr, allregisters):
# no malloc allowed here!!
self.fail_ebp = allregisters[16 + ebp.value]
+ code_inputarg = False
num = 0
value_hi = 0
while 1:
@@ -1988,6 +1841,9 @@
# load the value from the stack
kind = code & 3
code = (code - self.CODE_FROMSTACK) >> 2
+ if code_inputarg:
+ code = ~code
+ code_inputarg = False
stackloc = frame_addr + get_ebp_ofs(code)
value = rffi.cast(rffi.LONGP, stackloc)[0]
if kind == self.DESCR_FLOAT and WORD == 4:
@@ -2000,6 +1856,9 @@
if code == self.CODE_HOLE:
num += 1
continue
+ if code == self.CODE_INPUTARG:
+ code_inputarg = True
+ continue
assert code == self.CODE_STOP
break
code >>= 2
@@ -2104,9 +1963,9 @@
# returns in eax the fail_index
# now we return from the complete frame, which starts from
- # _assemble_bootstrap_code(). The LEA in _call_footer below throws
- # away most of the frame, including all the PUSHes that we did just
- # above.
+ # _call_header_with_stack_check(). The LEA in _call_footer below
+ # throws away most of the frame, including all the PUSHes that we
+ # did just above.
self._call_footer()
rawstart = mc.materialize(self.cpu.asmmemmgr, [])
@@ -2171,6 +2030,8 @@
self._genop_call(op, arglocs, resloc, force_index)
def _genop_call(self, op, arglocs, resloc, force_index):
+ from pypy.jit.backend.llsupport.descr import CallDescr
+
sizeloc = arglocs[0]
assert isinstance(sizeloc, ImmedLoc)
size = sizeloc.value
@@ -2185,13 +2046,16 @@
else:
tmp = eax
+ descr = op.getdescr()
+ assert isinstance(descr, CallDescr)
+
self._emit_call(force_index, x, arglocs, 3, tmp=tmp,
- argtypes=op.getdescr().get_arg_types(),
- callconv=op.getdescr().get_call_conv())
+ argtypes=descr.get_arg_types(),
+ callconv=descr.get_call_conv())
- if IS_X86_32 and isinstance(resloc, StackLoc) and resloc.width == 8:
+ if IS_X86_32 and isinstance(resloc, StackLoc) and resloc.type == FLOAT:
# a float or a long long return
- if op.getdescr().get_return_type() == 'L':
+ if descr.get_result_type() == 'L':
self.mc.MOV_br(resloc.value, eax.value) # long long
self.mc.MOV_br(resloc.value + 4, edx.value)
# XXX should ideally not move the result on the stack,
@@ -2200,7 +2064,7 @@
# can just be always a stack location
else:
self.mc.FSTPL_b(resloc.value) # float return
- elif op.getdescr().get_return_type() == 'S':
+ elif descr.get_result_type() == 'S':
# singlefloat return
assert resloc is eax
if IS_X86_32:
@@ -2354,10 +2218,10 @@
self.mc.MOV_bi(FORCE_INDEX_OFS, fail_index)
descr = op.getdescr()
assert isinstance(descr, JitCellToken)
- assert len(arglocs) - 2 == len(descr._x86_arglocs[0])
+ assert len(arglocs) - 2 == descr.compiled_loop_token._debug_nbargs
#
- # Write a call to the direct_bootstrap_code of the target assembler
- self._emit_call(fail_index, imm(descr._x86_direct_bootstrap_code),
+ # Write a call to the target assembler
+ self._emit_call(fail_index, imm(descr._x86_function_addr),
arglocs, 2, tmp=eax)
if op.result is None:
assert result_loc is None
@@ -2398,9 +2262,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
self.mc.MOV(eax, arglocs[1])
self.mc.MOV_mi((eax.value, ofs), 0)
@@ -2588,6 +2452,14 @@
self.gcrootmap_retaddr_forced = -1
def closing_jump(self, target_token):
+ # 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.
+ my_nbargs = self.current_clt._debug_nbargs
+ target_nbargs = target_token._x86_clt._debug_nbargs
+ assert my_nbargs == target_nbargs
+ #
target = target_token._x86_loop_code
if target_token in self.target_tokens_currently_compiling:
curpos = self.mc.get_relative_pos() + 5
@@ -2595,9 +2467,8 @@
else:
self.mc.JMP(imm(target))
- def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, tid):
- size = max(size, self.cpu.gc_ll_descr.minimal_size_in_nursery)
- size = (size + WORD-1) & ~(WORD-1) # round up
+ def malloc_cond(self, nursery_free_adr, nursery_top_adr, size):
+ assert size & (WORD-1) == 0 # must be correctly aligned
self.mc.MOV(eax, heap(nursery_free_adr))
self.mc.LEA_rm(edx.value, (eax.value, size))
self.mc.CMP(edx, heap(nursery_top_adr))
@@ -2633,9 +2504,6 @@
offset = self.mc.get_relative_pos() - jmp_adr
assert 0 < offset <= 127
self.mc.overwrite(jmp_adr-1, chr(offset))
- # on 64-bits, 'tid' is a value that fits in 31 bits
- assert rx86.fits_in_32bits(tid)
- self.mc.MOV_mi((eax.value, 0), tid)
self.mc.MOV(heap(nursery_free_adr), edx)
genop_discard_list = [Assembler386.not_implemented_op_discard] * rop._LAST
@@ -2666,11 +2534,6 @@
num = getattr(rop, opname.upper())
genop_list[num] = value
-def round_up_to_4(size):
- if size < 4:
- return 4
- return size
-
# XXX: ri386 migration shims:
def addr_add(reg_or_imm1, reg_or_imm2, offset=0, scale=0):
return AddressLoc(reg_or_imm1, reg_or_imm2, scale, offset)
diff --git a/pypy/jit/backend/x86/jump.py b/pypy/jit/backend/x86/jump.py
--- a/pypy/jit/backend/x86/jump.py
+++ b/pypy/jit/backend/x86/jump.py
@@ -1,6 +1,6 @@
import sys
from pypy.tool.pairtype import extendabletype
-from pypy.jit.backend.x86.regloc import ImmedLoc, StackLoc
+from pypy.jit.backend.x86.regloc import ImmediateAssemblerLocation, StackLoc
def remap_frame_layout(assembler, src_locations, dst_locations, tmpreg):
pending_dests = len(dst_locations)
@@ -12,12 +12,15 @@
srccount[key] = 0
for i in range(len(dst_locations)):
src = src_locations[i]
- if isinstance(src, ImmedLoc):
+ if isinstance(src, ImmediateAssemblerLocation):
continue
key = src._getregkey()
if key in srccount:
if key == dst_locations[i]._getregkey():
- 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
@@ -31,7 +34,7 @@
srccount[key] = -1 # means "it's done"
pending_dests -= 1
src = src_locations[i]
- if not isinstance(src, ImmedLoc):
+ if not isinstance(src, ImmediateAssemblerLocation):
key = src._getregkey()
if key in srccount:
srccount[key] -= 1
@@ -66,6 +69,13 @@
def _move(assembler, src, dst, tmpreg):
if dst.is_memory_reference() and src.is_memory_reference():
+ if isinstance(src, ImmediateAssemblerLocation):
+ assembler.regalloc_immedmem2mem(src, dst)
+ return
+ if tmpreg is None:
+ assembler.regalloc_push(src)
+ assembler.regalloc_pop(dst)
+ return
assembler.regalloc_mov(src, tmpreg)
src = tmpreg
assembler.regalloc_mov(src, dst)
@@ -87,7 +97,7 @@
dstloc = dst_locations2[i]
if isinstance(loc, StackLoc):
key = loc._getregkey()
- if (key in dst_keys or (loc.width > WORD and
+ if (key in dst_keys or (loc.get_width() > WORD and
(key + WORD) in dst_keys)):
assembler.regalloc_push(loc)
extrapushes.append(dstloc)
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -16,8 +16,8 @@
from pypy.jit.codewriter import heaptracker, longlong
from pypy.jit.codewriter.effectinfo import EffectInfo
from pypy.jit.metainterp.resoperation import rop
-from pypy.jit.backend.llsupport.descr import BaseFieldDescr, BaseArrayDescr
-from pypy.jit.backend.llsupport.descr import BaseCallDescr, BaseSizeDescr
+from pypy.jit.backend.llsupport.descr import FieldDescr, ArrayDescr
+from pypy.jit.backend.llsupport.descr import CallDescr, SizeDescr
from pypy.jit.backend.llsupport.descr import InteriorFieldDescr
from pypy.jit.backend.llsupport.regalloc import FrameManager, RegisterManager,\
TempBox, compute_vars_longevity, is_comparison_or_ovf_op
@@ -28,7 +28,7 @@
class X86RegisterManager(RegisterManager):
box_types = [INT, REF]
- all_regs = [eax, ecx, edx, ebx, esi, edi]
+ all_regs = [ecx, eax, edx, ebx, esi, edi]
no_lower_byte_regs = [esi, edi]
save_around_call_regs = [eax, edx, ecx]
frame_reg = ebp
@@ -60,7 +60,7 @@
class X86_64_RegisterManager(X86RegisterManager):
# r11 omitted because it's used as scratch
- all_regs = [eax, ecx, edx, ebx, esi, edi, r8, r9, r10, r12, r13, r14, r15]
+ all_regs = [ecx, eax, edx, ebx, esi, edi, r8, r9, r10, r12, r13, r14, r15]
no_lower_byte_regs = []
save_around_call_regs = [eax, ecx, edx, esi, edi, r8, r9, r10]
@@ -130,9 +130,9 @@
@staticmethod
def frame_pos(i, box_type):
if IS_X86_32 and box_type == FLOAT:
- return StackLoc(i, get_ebp_ofs(i+1), 2, box_type)
+ return StackLoc(i, get_ebp_ofs(i+1), box_type)
else:
- return StackLoc(i, get_ebp_ofs(i), 1, box_type)
+ return StackLoc(i, get_ebp_ofs(i), box_type)
@staticmethod
def frame_size(box_type):
if IS_X86_32 and box_type == FLOAT:
@@ -165,6 +165,7 @@
self.jump_target_descr = None
self.close_stack_struct = 0
self.final_jump_op = None
+ self.min_bytes_before_label = 0
def _prepare(self, inputargs, operations, allgcrefs):
self.fm = X86FrameManager()
@@ -173,22 +174,26 @@
operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations,
allgcrefs)
# compute longevity of variables
- longevity, useful = self._compute_vars_longevity(inputargs, operations)
- self.longevity = longevity
- self.rm = gpr_reg_mgr_cls(longevity,
+ self._compute_vars_longevity(inputargs, operations)
+ self.rm = gpr_reg_mgr_cls(self.longevity,
frame_manager = self.fm,
assembler = self.assembler)
- self.xrm = xmm_reg_mgr_cls(longevity, frame_manager = self.fm,
+ self.xrm = xmm_reg_mgr_cls(self.longevity, frame_manager = self.fm,
assembler = self.assembler)
- return operations, useful
+ return operations
def prepare_loop(self, inputargs, operations, looptoken, allgcrefs):
- operations, useful = self._prepare(inputargs, operations, allgcrefs)
- return self._process_inputargs(inputargs, useful), operations
+ operations = self._prepare(inputargs, operations, allgcrefs)
+ self._set_initial_bindings(inputargs)
+ # note: we need to make a copy of inputargs because possibly_free_vars
+ # is also used on op args, which is a non-resizable list
+ self.possibly_free_vars(list(inputargs))
+ self.min_bytes_before_label = 13
+ return operations
def prepare_bridge(self, prev_depths, inputargs, arglocs, operations,
allgcrefs):
- operations, _ = self._prepare(inputargs, operations, allgcrefs)
+ operations = self._prepare(inputargs, operations, allgcrefs)
self._update_bindings(arglocs, inputargs)
self.param_depth = prev_depths[1]
return operations
@@ -196,46 +201,56 @@
def reserve_param(self, n):
self.param_depth = max(self.param_depth, n)
- def _process_inputargs(self, inputargs, useful):
- # XXX we can sort out here by longevity if we need something
- # more optimal
- floatlocs = [None] * len(inputargs)
- nonfloatlocs = [None] * len(inputargs)
- # Don't use all_regs[0] for passing arguments around a loop.
- # Must be kept in sync with consider_jump().
- # XXX this should probably go to llsupport/regalloc.py
- xmmtmp = self.xrm.free_regs.pop(0)
- tmpreg = self.rm.free_regs.pop(0)
- assert tmpreg == X86RegisterManager.all_regs[0]
- assert xmmtmp == X86XMMRegisterManager.all_regs[0]
- for i in range(len(inputargs)):
- arg = inputargs[i]
- assert not isinstance(arg, Const)
- reg = None
- if self.longevity[arg][1] > -1 and arg in useful:
- if arg.type == FLOAT:
- # xxx is it really a good idea? at the first CALL they
- # will all be flushed anyway
- reg = self.xrm.try_allocate_reg(arg)
+ def _set_initial_bindings(self, inputargs):
+ if IS_X86_64:
+ inputargs = self._set_initial_bindings_regs_64(inputargs)
+ # ...
+ # stack layout: arg2
+ # arg1
+ # arg0
+ # return address
+ # saved ebp <-- ebp points here
+ # ...
+ cur_frame_pos = - 1 - FRAME_FIXED_SIZE
+ assert get_ebp_ofs(cur_frame_pos-1) == 2*WORD
+ assert get_ebp_ofs(cur_frame_pos-2) == 3*WORD
+ #
+ for box in inputargs:
+ assert isinstance(box, Box)
+ #
+ if IS_X86_32 and box.type == FLOAT:
+ cur_frame_pos -= 2
+ else:
+ cur_frame_pos -= 1
+ loc = self.fm.frame_pos(cur_frame_pos, box.type)
+ self.fm.set_binding(box, loc)
+
+ def _set_initial_bindings_regs_64(self, inputargs):
+ # In reverse order for use with pop()
+ unused_gpr = [r9, r8, ecx, edx, esi, edi]
+ unused_xmm = [xmm7, xmm6, xmm5, xmm4, xmm3, xmm2, xmm1, xmm0]
+ #
+ pass_on_stack = []
+ #
+ for box in inputargs:
+ assert isinstance(box, Box)
+ #
+ if box.type == FLOAT:
+ if len(unused_xmm) > 0:
+ ask = unused_xmm.pop()
+ got = self.xrm.try_allocate_reg(box, selected_reg=ask)
+ assert ask == got
else:
- reg = self.rm.try_allocate_reg(arg)
- if reg:
- loc = reg
+ pass_on_stack.append(box)
else:
- loc = self.fm.loc(arg)
- if arg.type == FLOAT:
- floatlocs[i] = loc
- else:
- nonfloatlocs[i] = loc
- # otherwise we have it saved on stack, so no worry
- self.rm.free_regs.insert(0, tmpreg)
- self.xrm.free_regs.insert(0, xmmtmp)
- assert tmpreg not in nonfloatlocs
- assert xmmtmp not in floatlocs
- # note: we need to make a copy of inputargs because possibly_free_vars
- # is also used on op args, which is a non-resizable list
- self.possibly_free_vars(list(inputargs))
- return nonfloatlocs, floatlocs
+ if len(unused_gpr) > 0:
+ ask = unused_gpr.pop()
+ got = self.rm.try_allocate_reg(box, selected_reg=ask)
+ assert ask == got
+ else:
+ pass_on_stack.append(box)
+ #
+ return pass_on_stack
def possibly_free_var(self, var):
if var.type == FLOAT:
@@ -436,10 +451,16 @@
i += 1
assert not self.rm.reg_bindings
assert not self.xrm.reg_bindings
+ self.flush_loop()
self.assembler.mc.mark_op(None) # end of the loop
+ def flush_loop(self):
+ # rare case: if the loop is too short, pad with NOPs
+ mc = self.assembler.mc
+ while mc.get_relative_pos() < self.min_bytes_before_label:
+ mc.NOP()
- def loc(self, v):
+ def loc(self, v):
if v is None: # xxx kludgy
return None
if v.type == FLOAT:
@@ -785,9 +806,9 @@
def _consider_call(self, op, guard_not_forced_op=None):
calldescr = op.getdescr()
- assert isinstance(calldescr, BaseCallDescr)
+ assert isinstance(calldescr, CallDescr)
assert len(calldescr.arg_classes) == op.numargs() - 1
- size = calldescr.get_result_size(self.translate_support_code)
+ size = calldescr.get_result_size()
sign = calldescr.is_result_signed()
if sign:
sign_loc = imm1
@@ -832,12 +853,15 @@
consider_call_release_gil = consider_call_may_force
+ def consider_call_malloc_gc(self, op):
+ self._consider_call(op)
+
def consider_call_assembler(self, op, guard_op):
descr = op.getdescr()
assert isinstance(descr, JitCellToken)
jd = descr.outermost_jitdriver_sd
assert jd is not None
- size = jd.portal_calldescr.get_result_size(self.translate_support_code)
+ size = jd.portal_calldescr.get_result_size()
vable_index = jd.index_of_virtualizable
if vable_index >= 0:
self.rm._sync_var(op.getarg(vable_index))
@@ -872,21 +896,10 @@
consider_cond_call_gc_wb_array = consider_cond_call_gc_wb
- def fastpath_malloc_fixedsize(self, op, descr):
- assert isinstance(descr, BaseSizeDescr)
- self._do_fastpath_malloc(op, descr.size, descr.tid)
-
- def fastpath_malloc_varsize(self, op, arraydescr, num_elem):
- assert isinstance(arraydescr, BaseArrayDescr)
- ofs_length = arraydescr.get_ofs_length(self.translate_support_code)
- basesize = arraydescr.get_base_size(self.translate_support_code)
- itemsize = arraydescr.get_item_size(self.translate_support_code)
- size = basesize + itemsize * num_elem
- self._do_fastpath_malloc(op, size, arraydescr.tid)
- self.assembler.set_new_array_length(eax, ofs_length, imm(num_elem))
-
- def _do_fastpath_malloc(self, op, size, tid):
- gc_ll_descr = self.assembler.cpu.gc_ll_descr
+ def consider_call_malloc_nursery(self, op):
+ size_box = op.getarg(0)
+ assert isinstance(size_box, ConstInt)
+ size = size_box.getint()
self.rm.force_allocate_reg(op.result, selected_reg=eax)
#
# We need edx as a temporary, but otherwise don't save any more
@@ -895,86 +908,39 @@
self.rm.force_allocate_reg(tmp_box, selected_reg=edx)
self.rm.possibly_free_var(tmp_box)
#
+ 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,
- )
-
- def consider_new(self, op):
- 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:
- args = gc_ll_descr.args_for_new(op.getdescr())
- arglocs = [imm(x) for x in args]
- return self._call(op, arglocs)
-
- def consider_new_with_vtable(self, op):
- classint = op.getarg(0).getint()
- descrsize = heaptracker.vtable2descr(self.assembler.cpu, classint)
- if self.assembler.cpu.gc_ll_descr.can_inline_malloc(descrsize):
- self.fastpath_malloc_fixedsize(op, descrsize)
- self.assembler.set_vtable(eax, imm(classint))
- # result of fastpath malloc is in eax
- else:
- args = self.assembler.cpu.gc_ll_descr.args_for_new(descrsize)
- arglocs = [imm(x) for x in args]
- arglocs.append(self.loc(op.getarg(0)))
- return self._call(op, arglocs)
-
- def consider_newstr(self, op):
- loc = self.loc(op.getarg(0))
- return self._call(op, [loc])
-
- def consider_newunicode(self, op):
- loc = self.loc(op.getarg(0))
- return self._call(op, [loc])
-
- def consider_new_array(self, op):
- gc_ll_descr = self.assembler.cpu.gc_ll_descr
- 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())
- arglocs = [imm(x) for x in args]
- arglocs.append(self.loc(box_num_elem))
- self._call(op, arglocs)
+ size)
def _unpack_arraydescr(self, arraydescr):
- assert isinstance(arraydescr, BaseArrayDescr)
- ofs_length = arraydescr.get_ofs_length(self.translate_support_code)
- ofs = arraydescr.get_base_size(self.translate_support_code)
- size = arraydescr.get_item_size(self.translate_support_code)
- ptr = arraydescr.is_array_of_pointers()
+ assert isinstance(arraydescr, ArrayDescr)
+ ofs = arraydescr.basesize
+ size = arraydescr.itemsize
sign = arraydescr.is_item_signed()
- return size, ofs, ofs_length, ptr, sign
+ return size, ofs, sign
def _unpack_fielddescr(self, fielddescr):
- assert isinstance(fielddescr, BaseFieldDescr)
+ assert isinstance(fielddescr, FieldDescr)
ofs = fielddescr.offset
- size = fielddescr.get_field_size(self.translate_support_code)
- ptr = fielddescr.is_pointer_field()
+ size = fielddescr.field_size
sign = fielddescr.is_field_signed()
- return imm(ofs), imm(size), ptr, sign
+ return imm(ofs), imm(size), sign
+ _unpack_fielddescr._always_inline_ = True
def _unpack_interiorfielddescr(self, descr):
assert isinstance(descr, InteriorFieldDescr)
arraydescr = descr.arraydescr
- ofs = arraydescr.get_base_size(self.translate_support_code)
- itemsize = arraydescr.get_item_size(self.translate_support_code)
- fieldsize = descr.fielddescr.get_field_size(self.translate_support_code)
+ ofs = arraydescr.basesize
+ itemsize = arraydescr.itemsize
+ fieldsize = descr.fielddescr.field_size
sign = descr.fielddescr.is_field_signed()
ofs += descr.fielddescr.offset
return imm(ofs), imm(itemsize), imm(fieldsize), sign
def consider_setfield_gc(self, op):
- ofs_loc, size_loc, _, _ = self._unpack_fielddescr(op.getdescr())
+ ofs_loc, size_loc, _ = self._unpack_fielddescr(op.getdescr())
assert isinstance(size_loc, ImmedLoc)
if size_loc.value == 1:
need_lower_byte = True
@@ -1032,7 +998,7 @@
consider_unicodesetitem = consider_strsetitem
def consider_setarrayitem_gc(self, op):
- itemsize, ofs, _, _, _ = self._unpack_arraydescr(op.getdescr())
+ itemsize, ofs, _ = self._unpack_arraydescr(op.getdescr())
args = op.getarglist()
base_loc = self.rm.make_sure_var_in_reg(op.getarg(0), args)
if itemsize == 1:
@@ -1049,7 +1015,7 @@
consider_setarrayitem_raw = consider_setarrayitem_gc
def consider_getfield_gc(self, op):
- ofs_loc, size_loc, _, sign = self._unpack_fielddescr(op.getdescr())
+ ofs_loc, size_loc, sign = self._unpack_fielddescr(op.getdescr())
args = op.getarglist()
base_loc = self.rm.make_sure_var_in_reg(op.getarg(0), args)
self.rm.possibly_free_vars(args)
@@ -1065,7 +1031,7 @@
consider_getfield_gc_pure = consider_getfield_gc
def consider_getarrayitem_gc(self, op):
- itemsize, ofs, _, _, sign = self._unpack_arraydescr(op.getdescr())
+ itemsize, ofs, sign = self._unpack_arraydescr(op.getdescr())
args = op.getarglist()
base_loc = self.rm.make_sure_var_in_reg(op.getarg(0), args)
ofs_loc = self.rm.make_sure_var_in_reg(op.getarg(1), args)
@@ -1144,8 +1110,8 @@
def consider_arraylen_gc(self, op):
arraydescr = op.getdescr()
- assert isinstance(arraydescr, BaseArrayDescr)
- ofs = arraydescr.get_ofs_length(self.translate_support_code)
+ assert isinstance(arraydescr, ArrayDescr)
+ ofs = arraydescr.lendescr.offset
args = op.getarglist()
base_loc = self.rm.make_sure_var_in_reg(op.getarg(0), args)
self.rm.possibly_free_vars_for_op(op)
@@ -1285,51 +1251,51 @@
# we would like the boxes to be after the jump.
def _compute_hint_frame_locations_from_descr(self, descr):
- nonfloatlocs, floatlocs = descr._x86_arglocs
+ arglocs = descr._x86_arglocs
jump_op = self.final_jump_op
- assert len(nonfloatlocs) == jump_op.numargs()
+ assert len(arglocs) == jump_op.numargs()
for i in range(jump_op.numargs()):
box = jump_op.getarg(i)
if isinstance(box, Box):
- loc = nonfloatlocs[i]
+ loc = arglocs[i]
if isinstance(loc, StackLoc):
- assert box.type != FLOAT
self.fm.hint_frame_locations[box] = loc
- else:
- loc = floatlocs[i]
- if isinstance(loc, StackLoc):
- assert box.type == FLOAT
- self.fm.hint_frame_locations[box] = loc
def consider_jump(self, op):
assembler = self.assembler
assert self.jump_target_descr is None
descr = op.getdescr()
assert isinstance(descr, TargetToken)
- nonfloatlocs, floatlocs = descr._x86_arglocs
+ arglocs = descr._x86_arglocs
self.jump_target_descr = descr
- # compute 'tmploc' to be all_regs[0] by spilling what is there
- box = TempBox()
- box1 = TempBox()
- tmpreg = X86RegisterManager.all_regs[0]
- tmploc = self.rm.force_allocate_reg(box, selected_reg=tmpreg)
- xmmtmp = X86XMMRegisterManager.all_regs[0]
- self.xrm.force_allocate_reg(box1, selected_reg=xmmtmp)
# 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)
+ # Do we have a temp var?
+ if IS_X86_64:
+ tmpreg = X86_64_SCRATCH_REG
+ xmmtmp = X86_64_XMM_SCRATCH_REG
+ else:
+ tmpreg = None
+ xmmtmp = None
+ # Do the remapping
remap_frame_layout_mixed(assembler,
- src_locations1, dst_locations1, tmploc,
+ src_locations1, dst_locations1, tmpreg,
src_locations2, dst_locations2, xmmtmp)
- self.rm.possibly_free_var(box)
- self.xrm.possibly_free_var(box1)
self.possibly_free_vars_for_op(op)
assembler.closing_jump(self.jump_target_descr)
@@ -1381,23 +1347,20 @@
self.rm.force_allocate_frame_reg(op.result)
def consider_label(self, op):
- # XXX big refactoring needed?
descr = op.getdescr()
assert isinstance(descr, TargetToken)
inputargs = op.getarglist()
- floatlocs = [None] * len(inputargs)
- nonfloatlocs = [None] * len(inputargs)
+ arglocs = [None] * len(inputargs)
#
- # we need to make sure that the tmpreg and xmmtmp are free
- tmpreg = X86RegisterManager.all_regs[0]
- tmpvar = TempBox()
- self.rm.force_allocate_reg(tmpvar, selected_reg=tmpreg)
- self.rm.possibly_free_var(tmpvar)
- #
- xmmtmp = X86XMMRegisterManager.all_regs[0]
- tmpvar = TempBox()
- self.xrm.force_allocate_reg(tmpvar, selected_reg=xmmtmp)
- self.xrm.possibly_free_var(tmpvar)
+ # 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)
#
# we need to make sure that no variable is stored in ebp
for arg in inputargs:
@@ -1408,16 +1371,18 @@
#
for i in range(len(inputargs)):
arg = inputargs[i]
- assert not isinstance(arg, Const)
+ assert isinstance(arg, Box)
loc = self.loc(arg)
- assert not (loc is tmpreg or loc is xmmtmp or loc is ebp)
- if arg.type == FLOAT:
- floatlocs[i] = loc
- else:
- nonfloatlocs[i] = loc
+ assert loc is not ebp
+ arglocs[i] = loc
if isinstance(loc, RegLoc):
self.fm.mark_as_free(arg)
- descr._x86_arglocs = nonfloatlocs, floatlocs
+ #
+ # if we are too close to the start of the loop, the label's target may
+ # get overridden by redirect_call_assembler(). (rare case)
+ self.flush_loop()
+ #
+ descr._x86_arglocs = arglocs
descr._x86_loop_code = self.assembler.mc.get_relative_pos()
descr._x86_clt = self.assembler.current_clt
self.assembler.target_tokens_currently_compiling[descr] = None
@@ -1431,23 +1396,6 @@
if jump_op is not None and jump_op.getdescr() is descr:
self._compute_hint_frame_locations_from_descr(descr)
-## from pypy.rpython.annlowlevel import llhelper
-## def fn(addr):
-## print '...label:', hex(addr), nonfloatlocs
-## FUNC = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
-## ll_disp = llhelper(FUNC, fn)
-## faddr = rffi.cast(lltype.Signed, ll_disp)
-## for i in range(16):
-## self.assembler.mc.PUSH_r(i)
-## self.assembler.mc.CALL_l(0)
-## self.assembler.mc.POP(edi)
-## self.assembler.mc.MOV(r11, imm(faddr))
-## self.assembler.mc.CALL(r11)
-## for i in range(15, -1, -1):
-## if i == esp.value:
-## i -= 1
-## self.assembler.mc.POP_r(i)
-
def not_implemented_op(self, op):
not_implemented("not implemented operation: %s" % op.getopname())
diff --git a/pypy/jit/backend/x86/regloc.py b/pypy/jit/backend/x86/regloc.py
--- a/pypy/jit/backend/x86/regloc.py
+++ b/pypy/jit/backend/x86/regloc.py
@@ -16,8 +16,7 @@
#
class AssemblerLocation(object):
- # XXX: Is adding "width" here correct?
- _attrs_ = ('value', 'width', '_location_code')
+ _attrs_ = ('value', '_location_code')
_immutable_ = True
def _getregkey(self):
return self.value
@@ -28,6 +27,9 @@
def location_code(self):
return self._location_code
+ def get_width(self):
+ raise NotImplementedError
+
def value_r(self): return self.value
def value_b(self): return self.value
def value_s(self): return self.value
@@ -43,14 +45,21 @@
_immutable_ = True
_location_code = 'b'
- def __init__(self, position, ebp_offset, num_words, type):
- assert ebp_offset < 0 # so no confusion with RegLoc.value
+ def __init__(self, position, ebp_offset, type):
+ # _getregkey() returns self.value; the value returned must not
+ # conflict with RegLoc._getregkey(). It doesn't a bit by chance,
+ # so let it fail the following assert if it no longer does.
+ assert not (0 <= ebp_offset < 8 + 8 * IS_X86_64)
self.position = position
self.value = ebp_offset
- self.width = num_words * WORD
# One of INT, REF, FLOAT
self.type = type
+ def get_width(self):
+ if self.type == FLOAT:
+ return 8
+ return WORD
+
def __repr__(self):
return '%d(%%ebp)' % (self.value,)
@@ -64,10 +73,8 @@
self.value = regnum
self.is_xmm = is_xmm
if self.is_xmm:
- self.width = 8
self._location_code = 'x'
else:
- self.width = WORD
self._location_code = 'r'
def __repr__(self):
if self.is_xmm:
@@ -75,6 +82,11 @@
else:
return rx86.R.names[self.value]
+ def get_width(self):
+ if self.is_xmm:
+ return 8
+ return WORD
+
def lowest8bits(self):
assert not self.is_xmm
return RegLoc(rx86.low_byte(self.value), False)
@@ -92,9 +104,11 @@
else:
return eax
-class ImmedLoc(AssemblerLocation):
+class ImmediateAssemblerLocation(AssemblerLocation):
_immutable_ = True
- width = WORD
+
+class ImmedLoc(ImmediateAssemblerLocation):
+ _immutable_ = True
_location_code = 'i'
def __init__(self, value):
@@ -105,6 +119,9 @@
def getint(self):
return self.value
+ def get_width(self):
+ return WORD
+
def __repr__(self):
More information about the pypy-commit
mailing list