Author: Wim Lavrijsen <[email protected]>
Branch: reflex-support
Changeset: r52598:63f05fc8565d
Date: 2012-02-17 17:45 -0800
http://bitbucket.org/pypy/pypy/changeset/63f05fc8565d/
Log: merge default into branch
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -105,7 +105,8 @@
BoolOption("sandbox", "Produce a fully-sandboxed executable",
default=False, cmdline="--sandbox",
requires=[("translation.thread", False)],
- suggests=[("translation.gc", "generation")]),
+ suggests=[("translation.gc", "generation"),
+ ("translation.gcrootfinder", "shadowstack")]),
BoolOption("rweakref", "The backend supports RPython-level weakrefs",
default=True),
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -60,11 +60,10 @@
self.pycode = code
eval.Frame.__init__(self, space, w_globals)
self.locals_stack_w = [None] * (code.co_nlocals + code.co_stacksize)
- self.nlocals = code.co_nlocals
self.valuestackdepth = code.co_nlocals
self.lastblock = None
make_sure_not_resized(self.locals_stack_w)
- check_nonneg(self.nlocals)
+ check_nonneg(self.valuestackdepth)
#
if space.config.objspace.honor__builtins__:
self.builtin = space.builtin.pick_builtin(w_globals)
@@ -144,8 +143,8 @@
def execute_frame(self, w_inputvalue=None, operr=None):
"""Execute this frame. Main entry point to the interpreter.
The optional arguments are there to handle a generator's frame:
- w_inputvalue is for generator.send()) and operr is for
- generator.throw()).
+ w_inputvalue is for generator.send() and operr is for
+ generator.throw().
"""
# the following 'assert' is an annotation hint: it hides from
# the annotator all methods that are defined in PyFrame but
@@ -195,7 +194,7 @@
def popvalue(self):
depth = self.valuestackdepth - 1
- assert depth >= self.nlocals, "pop from empty value stack"
+ assert depth >= self.pycode.co_nlocals, "pop from empty value stack"
w_object = self.locals_stack_w[depth]
self.locals_stack_w[depth] = None
self.valuestackdepth = depth
@@ -223,7 +222,7 @@
def peekvalues(self, n):
values_w = [None] * n
base = self.valuestackdepth - n
- assert base >= self.nlocals
+ assert base >= self.pycode.co_nlocals
while True:
n -= 1
if n < 0:
@@ -235,7 +234,8 @@
def dropvalues(self, n):
n = hint(n, promote=True)
finaldepth = self.valuestackdepth - n
- assert finaldepth >= self.nlocals, "stack underflow in dropvalues()"
+ assert finaldepth >= self.pycode.co_nlocals, (
+ "stack underflow in dropvalues()")
while True:
n -= 1
if n < 0:
@@ -267,13 +267,15 @@
# Contrast this with CPython where it's PEEK(-1).
index_from_top = hint(index_from_top, promote=True)
index = self.valuestackdepth + ~index_from_top
- assert index >= self.nlocals, "peek past the bottom of the stack"
+ assert index >= self.pycode.co_nlocals, (
+ "peek past the bottom of the stack")
return self.locals_stack_w[index]
def settopvalue(self, w_object, index_from_top=0):
index_from_top = hint(index_from_top, promote=True)
index = self.valuestackdepth + ~index_from_top
- assert index >= self.nlocals, "settop past the bottom of the stack"
+ assert index >= self.pycode.co_nlocals, (
+ "settop past the bottom of the stack")
self.locals_stack_w[index] = w_object
@jit.unroll_safe
@@ -320,12 +322,13 @@
else:
f_lineno = self.f_lineno
- values_w = self.locals_stack_w[self.nlocals:self.valuestackdepth]
+ nlocals = self.pycode.co_nlocals
+ values_w = self.locals_stack_w[nlocals:self.valuestackdepth]
w_valuestack = maker.slp_into_tuple_with_nulls(space, values_w)
w_blockstack = nt([block._get_state_(space) for block in
self.get_blocklist()])
w_fastlocals = maker.slp_into_tuple_with_nulls(
- space, self.locals_stack_w[:self.nlocals])
+ space, self.locals_stack_w[:nlocals])
if self.last_exception is None:
w_exc_value = space.w_None
w_tb = space.w_None
@@ -442,7 +445,7 @@
"""Initialize the fast locals from a list of values,
where the order is according to self.pycode.signature()."""
scope_len = len(scope_w)
- if scope_len > self.nlocals:
+ if scope_len > self.pycode.co_nlocals:
raise ValueError, "new fastscope is longer than the allocated area"
# don't assign directly to 'locals_stack_w[:scope_len]' to be
# virtualizable-friendly
@@ -456,7 +459,7 @@
pass
def getfastscopelength(self):
- return self.nlocals
+ return self.pycode.co_nlocals
def getclosure(self):
return None
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
@@ -2221,6 +2221,35 @@
print 'step 4 ok'
print '-'*79
+ def test_guard_not_invalidated_and_label(self):
+ # test that the guard_not_invalidated reserves enough room before
+ # the label. If it doesn't, then in this example after we invalidate
+ # the guard, jumping to the label will hit the invalidation code too
+ cpu = self.cpu
+ i0 = BoxInt()
+ faildescr = BasicFailDescr(1)
+ labeldescr = TargetToken()
+ ops = [
+ ResOperation(rop.GUARD_NOT_INVALIDATED, [], None, descr=faildescr),
+ ResOperation(rop.LABEL, [i0], None, descr=labeldescr),
+ ResOperation(rop.FINISH, [i0], None, descr=BasicFailDescr(3)),
+ ]
+ ops[0].setfailargs([])
+ looptoken = JitCellToken()
+ self.cpu.compile_loop([i0], ops, looptoken)
+ # mark as failing
+ self.cpu.invalidate_loop(looptoken)
+ # attach a bridge
+ i2 = BoxInt()
+ ops = [
+ ResOperation(rop.JUMP, [ConstInt(333)], None, descr=labeldescr),
+ ]
+ self.cpu.compile_bridge(faildescr, [], ops, looptoken)
+ # run: must not be caught in an infinite loop
+ fail = self.cpu.execute_token(looptoken, 16)
+ assert fail.identifier == 3
+ assert self.cpu.get_latest_value_int(0) == 333
+
# pure do_ / descr features
def test_do_operations(self):
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
@@ -165,7 +165,6 @@
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()
@@ -199,8 +198,13 @@
operations = self._prepare(inputargs, operations, allgcrefs)
self._update_bindings(arglocs, inputargs)
self.param_depth = prev_depths[1]
+ self.min_bytes_before_label = 0
return operations
+ def ensure_next_label_is_at_least_at_position(self, at_least_position):
+ self.min_bytes_before_label = max(self.min_bytes_before_label,
+ at_least_position)
+
def reserve_param(self, n):
self.param_depth = max(self.param_depth, n)
@@ -468,7 +472,11 @@
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
+ # rare case: if the loop is too short, or if we are just after
+ # a GUARD_NOT_INVALIDATED, pad with NOPs. Important! This must
+ # be called to ensure that there are enough bytes produced,
+ # because GUARD_NOT_INVALIDATED or redirect_call_assembler()
+ # will maybe overwrite them.
mc = self.assembler.mc
while mc.get_relative_pos() < self.min_bytes_before_label:
mc.NOP()
@@ -558,7 +566,15 @@
def consider_guard_no_exception(self, op):
self.perform_guard(op, [], None)
- consider_guard_not_invalidated = consider_guard_no_exception
+ def consider_guard_not_invalidated(self, op):
+ mc = self.assembler.mc
+ n = mc.get_relative_pos()
+ self.perform_guard(op, [], None)
+ assert n == mc.get_relative_pos()
+ # ensure that the next label is at least 5 bytes farther than
+ # the current position. Otherwise, when invalidating the guard,
+ # we would overwrite randomly the next label's position.
+ self.ensure_next_label_is_at_least_at_position(n + 5)
def consider_guard_exception(self, op):
loc = self.rm.make_sure_var_in_reg(op.getarg(0))
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -7760,6 +7760,42 @@
"""
self.optimize_loop(ops, expected)
+ def test_constant_failargs(self):
+ ops = """
+ [p1, i2, i3]
+ setfield_gc(p1, ConstPtr(myptr), descr=nextdescr)
+ p16 = getfield_gc(p1, descr=nextdescr)
+ guard_true(i2) [p16, i3]
+ jump(p1, i3, i2)
+ """
+ preamble = """
+ [p1, i2, i3]
+ setfield_gc(p1, ConstPtr(myptr), descr=nextdescr)
+ guard_true(i2) [i3]
+ jump(p1, i3)
+ """
+ expected = """
+ [p1, i3]
+ guard_true(i3) []
+ jump(p1, 1)
+ """
+ self.optimize_loop(ops, expected, preamble)
+
+ def test_issue1048(self):
+ ops = """
+ [p1, i2, i3]
+ p16 = getfield_gc(p1, descr=nextdescr)
+ guard_true(i2) [p16]
+ setfield_gc(p1, ConstPtr(myptr), descr=nextdescr)
+ jump(p1, i3, i2)
+ """
+ expected = """
+ [p1, i3]
+ guard_true(i3) []
+ jump(p1, 1)
+ """
+ self.optimize_loop(ops, expected)
+
class TestLLtype(OptimizeOptTest, LLtypeMixin):
pass
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -384,6 +384,7 @@
"Dict": "space.w_dict",
"Tuple": "space.w_tuple",
"List": "space.w_list",
+ "Set": "space.w_set",
"Int": "space.w_int",
"Bool": "space.w_bool",
"Float": "space.w_float",
@@ -434,16 +435,16 @@
('buf', rffi.VOIDP),
('obj', PyObject),
('len', Py_ssize_t),
- # ('itemsize', Py_ssize_t),
+ ('itemsize', Py_ssize_t),
- # ('readonly', lltype.Signed),
- # ('ndim', lltype.Signed),
- # ('format', rffi.CCHARP),
- # ('shape', Py_ssize_tP),
- # ('strides', Py_ssize_tP),
- # ('suboffets', Py_ssize_tP),
- # ('smalltable', rffi.CFixedArray(Py_ssize_t, 2)),
- # ('internal', rffi.VOIDP)
+ ('readonly', lltype.Signed),
+ ('ndim', lltype.Signed),
+ ('format', rffi.CCHARP),
+ ('shape', Py_ssize_tP),
+ ('strides', Py_ssize_tP),
+ ('suboffsets', Py_ssize_tP),
+ #('smalltable', rffi.CFixedArray(Py_ssize_t, 2)),
+ ('internal', rffi.VOIDP)
))
@specialize.memo()
diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py
--- a/pypy/module/cpyext/dictobject.py
+++ b/pypy/module/cpyext/dictobject.py
@@ -6,6 +6,7 @@
from pypy.module.cpyext.pyobject import RefcountState
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
from pypy.interpreter.error import OperationError
+from pypy.rlib.objectmodel import specialize
@cpython_api([], PyObject)
def PyDict_New(space):
@@ -191,3 +192,24 @@
raise
return 0
return 1
+
[email protected]()
+def make_frozendict(space):
+ return space.appexec([], '''():
+ import collections
+ class FrozenDict(collections.Mapping):
+ def __init__(self, *args, **kwargs):
+ self._d = dict(*args, **kwargs)
+ def __iter__(self):
+ return iter(self._d)
+ def __len__(self):
+ return len(self._d)
+ def __getitem__(self, key):
+ return self._d[key]
+ return FrozenDict''')
+
+@cpython_api([PyObject], PyObject)
+def PyDictProxy_New(space, w_dict):
+ w_frozendict = make_frozendict(space)
+ return space.call_function(w_frozendict, w_dict)
+
diff --git a/pypy/module/cpyext/include/object.h
b/pypy/module/cpyext/include/object.h
--- a/pypy/module/cpyext/include/object.h
+++ b/pypy/module/cpyext/include/object.h
@@ -131,18 +131,18 @@
/* This is Py_ssize_t so it can be
pointed to by strides in simple case.*/
- /* Py_ssize_t itemsize; */
- /* int readonly; */
- /* int ndim; */
- /* char *format; */
- /* Py_ssize_t *shape; */
- /* Py_ssize_t *strides; */
- /* Py_ssize_t *suboffsets; */
+ Py_ssize_t itemsize;
+ int readonly;
+ int ndim;
+ char *format;
+ Py_ssize_t *shape;
+ Py_ssize_t *strides;
+ Py_ssize_t *suboffsets;
/* static store for shape and strides of
mono-dimensional buffers. */
/* Py_ssize_t smalltable[2]; */
- /* void *internal; */
+ void *internal;
} Py_buffer;
diff --git a/pypy/module/cpyext/include/pystate.h
b/pypy/module/cpyext/include/pystate.h
--- a/pypy/module/cpyext/include/pystate.h
+++ b/pypy/module/cpyext/include/pystate.h
@@ -10,6 +10,7 @@
typedef struct _ts {
PyInterpreterState *interp;
+ PyObject *dict; /* Stores per-thread state */
} PyThreadState;
#define Py_BEGIN_ALLOW_THREADS { \
diff --git a/pypy/module/cpyext/include/pythread.h
b/pypy/module/cpyext/include/pythread.h
--- a/pypy/module/cpyext/include/pythread.h
+++ b/pypy/module/cpyext/include/pythread.h
@@ -1,6 +1,8 @@
#ifndef Py_PYTHREAD_H
#define Py_PYTHREAD_H
+#define WITH_THREAD
+
typedef void *PyThread_type_lock;
#define WAIT_LOCK 1
#define NOWAIT_LOCK 0
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -439,6 +439,8 @@
return 0
+PyBUF_WRITABLE = 0x0001 # Copied from object.h
+
@cpython_api([lltype.Ptr(Py_buffer), PyObject, rffi.VOIDP, Py_ssize_t,
lltype.Signed, lltype.Signed], rffi.INT, error=CANNOT_FAIL)
def PyBuffer_FillInfo(space, view, obj, buf, length, readonly, flags):
@@ -454,6 +456,18 @@
view.c_len = length
view.c_obj = obj
Py_IncRef(space, obj)
+ view.c_itemsize = 1
+ if flags & PyBUF_WRITABLE:
+ rffi.setintfield(view, 'c_readonly', 0)
+ else:
+ rffi.setintfield(view, 'c_readonly', 1)
+ rffi.setintfield(view, 'c_ndim', 0)
+ view.c_format = lltype.nullptr(rffi.CCHARP.TO)
+ view.c_shape = lltype.nullptr(Py_ssize_tP.TO)
+ view.c_strides = lltype.nullptr(Py_ssize_tP.TO)
+ view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO)
+ view.c_internal = lltype.nullptr(rffi.VOIDP.TO)
+
return 0
diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py
--- a/pypy/module/cpyext/pystate.py
+++ b/pypy/module/cpyext/pystate.py
@@ -1,12 +1,19 @@
from pypy.module.cpyext.api import (
cpython_api, generic_cpy_call, CANNOT_FAIL, CConfig, cpython_struct)
+from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, make_ref
from pypy.rpython.lltypesystem import rffi, lltype
PyInterpreterStateStruct = lltype.ForwardReference()
PyInterpreterState = lltype.Ptr(PyInterpreterStateStruct)
cpython_struct(
- "PyInterpreterState", [('next', PyInterpreterState)],
PyInterpreterStateStruct)
-PyThreadState = lltype.Ptr(cpython_struct("PyThreadState", [('interp',
PyInterpreterState)]))
+ "PyInterpreterState",
+ [('next', PyInterpreterState)],
+ PyInterpreterStateStruct)
+PyThreadState = lltype.Ptr(cpython_struct(
+ "PyThreadState",
+ [('interp', PyInterpreterState),
+ ('dict', PyObject),
+ ]))
@cpython_api([], PyThreadState, error=CANNOT_FAIL)
def PyEval_SaveThread(space):
@@ -38,41 +45,49 @@
return 1
# XXX: might be generally useful
-def encapsulator(T, flavor='raw'):
+def encapsulator(T, flavor='raw', dealloc=None):
class MemoryCapsule(object):
- def __init__(self, alloc=True):
- if alloc:
+ def __init__(self, space):
+ self.space = space
+ if space is not None:
self.memory = lltype.malloc(T, flavor=flavor)
else:
self.memory = lltype.nullptr(T)
def __del__(self):
if self.memory:
+ if dealloc and self.space:
+ dealloc(self.memory, self.space)
lltype.free(self.memory, flavor=flavor)
return MemoryCapsule
-ThreadStateCapsule = encapsulator(PyThreadState.TO)
+def ThreadState_dealloc(ts, space):
+ assert space is not None
+ Py_DecRef(space, ts.c_dict)
+ThreadStateCapsule = encapsulator(PyThreadState.TO,
+ dealloc=ThreadState_dealloc)
from pypy.interpreter.executioncontext import ExecutionContext
-ExecutionContext.cpyext_threadstate = ThreadStateCapsule(alloc=False)
+ExecutionContext.cpyext_threadstate = ThreadStateCapsule(None)
class InterpreterState(object):
def __init__(self, space):
self.interpreter_state = lltype.malloc(
PyInterpreterState.TO, flavor='raw', zero=True, immortal=True)
- def new_thread_state(self):
- capsule = ThreadStateCapsule()
+ def new_thread_state(self, space):
+ capsule = ThreadStateCapsule(space)
ts = capsule.memory
ts.c_interp = self.interpreter_state
+ ts.c_dict = make_ref(space, space.newdict())
return capsule
def get_thread_state(self, space):
ec = space.getexecutioncontext()
- return self._get_thread_state(ec).memory
+ return self._get_thread_state(space, ec).memory
- def _get_thread_state(self, ec):
+ def _get_thread_state(self, space, ec):
if ec.cpyext_threadstate.memory == lltype.nullptr(PyThreadState.TO):
- ec.cpyext_threadstate = self.new_thread_state()
+ ec.cpyext_threadstate = self.new_thread_state(space)
return ec.cpyext_threadstate
@@ -81,6 +96,11 @@
state = space.fromcache(InterpreterState)
return state.get_thread_state(space)
+@cpython_api([], PyObject, error=CANNOT_FAIL)
+def PyThreadState_GetDict(space):
+ state = space.fromcache(InterpreterState)
+ return state.get_thread_state(space).c_dict
+
@cpython_api([PyThreadState], PyThreadState, error=CANNOT_FAIL)
def PyThreadState_Swap(space, tstate):
"""Swap the current thread state with the thread state given by the
argument
diff --git a/pypy/module/cpyext/setobject.py b/pypy/module/cpyext/setobject.py
--- a/pypy/module/cpyext/setobject.py
+++ b/pypy/module/cpyext/setobject.py
@@ -54,6 +54,20 @@
return 0
+@cpython_api([PyObject], PyObject)
+def PySet_Pop(space, w_set):
+ """Return a new reference to an arbitrary object in the set, and removes
the
+ object from the set. Return NULL on failure. Raise KeyError if the
+ set is empty. Raise a SystemError if set is an not an instance of
+ set or its subtype."""
+ return space.call_method(w_set, "pop")
+
+@cpython_api([PyObject], rffi.INT_real, error=-1)
+def PySet_Clear(space, w_set):
+ """Empty an existing set of all elements."""
+ space.call_method(w_set, 'clear')
+ return 0
+
@cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
def PySet_GET_SIZE(space, w_s):
"""Macro form of PySet_Size() without error checking."""
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -185,6 +185,15 @@
space.fromcache(State).check_and_raise_exception(always=True)
return space.wrap(res)
+def wrap_delitem(space, w_self, w_args, func):
+ func_target = rffi.cast(objobjargproc, func)
+ check_num_args(space, w_args, 1)
+ w_key, = space.fixedview(w_args)
+ res = generic_cpy_call(space, func_target, w_self, w_key, None)
+ if rffi.cast(lltype.Signed, res) == -1:
+ space.fromcache(State).check_and_raise_exception(always=True)
+ return space.w_None
+
def wrap_ssizessizeargfunc(space, w_self, w_args, func):
func_target = rffi.cast(ssizessizeargfunc, func)
check_num_args(space, w_args, 2)
@@ -291,6 +300,14 @@
def slot_nb_int(space, w_self):
return space.int(w_self)
+@cpython_api([PyObject], PyObject, external=False)
+def slot_tp_iter(space, w_self):
+ return space.iter(w_self)
+
+@cpython_api([PyObject], PyObject, external=False)
+def slot_tp_iternext(space, w_self):
+ return space.next(w_self)
+
from pypy.rlib.nonconst import NonConstant
SLOTS = {}
@@ -632,6 +649,19 @@
TPSLOT("__buffer__", "tp_as_buffer.c_bf_getreadbuffer", None,
"wrap_getreadbuffer", ""),
)
+# partial sort to solve some slot conflicts:
+# Number slots before Mapping slots before Sequence slots.
+# These are the only conflicts between __name__ methods
+def slotdef_sort_key(slotdef):
+ if slotdef.slot_name.startswith('tp_as_number'):
+ return 1
+ if slotdef.slot_name.startswith('tp_as_mapping'):
+ return 2
+ if slotdef.slot_name.startswith('tp_as_sequence'):
+ return 3
+ return 0
+slotdefs = sorted(slotdefs, key=slotdef_sort_key)
+
slotdefs_for_tp_slots = unrolling_iterable(
[(x.method_name, x.slot_name, x.slot_names, x.slot_func)
for x in slotdefs])
diff --git a/pypy/module/cpyext/stringobject.py
b/pypy/module/cpyext/stringobject.py
--- a/pypy/module/cpyext/stringobject.py
+++ b/pypy/module/cpyext/stringobject.py
@@ -267,6 +267,7 @@
alias."""
w_str = from_ref(space, string[0])
w_str = space.new_interned_w_str(w_str)
+ Py_DecRef(space, string[0])
string[0] = make_ref(space, w_str)
@cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject)
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -1755,19 +1755,6 @@
building-up new frozensets with PySet_Add()."""
raise NotImplementedError
-@cpython_api([PyObject], PyObject)
-def PySet_Pop(space, set):
- """Return a new reference to an arbitrary object in the set, and removes
the
- object from the set. Return NULL on failure. Raise KeyError if the
- set is empty. Raise a SystemError if set is an not an instance of
- set or its subtype."""
- raise NotImplementedError
-
-@cpython_api([PyObject], rffi.INT_real, error=-1)
-def PySet_Clear(space, set):
- """Empty an existing set of all elements."""
- raise NotImplementedError
-
@cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, rffi.CCHARP], PyObject)
def PyString_Decode(space, s, size, encoding, errors):
"""Create an object by decoding size bytes of the encoded buffer s using
the
diff --git a/pypy/module/cpyext/test/test_arraymodule.py
b/pypy/module/cpyext/test/test_arraymodule.py
--- a/pypy/module/cpyext/test/test_arraymodule.py
+++ b/pypy/module/cpyext/test/test_arraymodule.py
@@ -43,6 +43,15 @@
assert arr[:2].tolist() == [1,2]
assert arr[1:3].tolist() == [2,3]
+ def test_slice_object(self):
+ module = self.import_module(name='array')
+ arr = module.array('i', [1,2,3,4])
+ assert arr[slice(1,3)].tolist() == [2,3]
+ arr[slice(1,3)] = module.array('i', [21, 22, 23])
+ assert arr.tolist() == [1, 21, 22, 23, 4]
+ del arr[slice(1, 3)]
+ assert arr.tolist() == [1, 23, 4]
+
def test_buffer(self):
module = self.import_module(name='array')
arr = module.array('i', [1,2,3,4])
diff --git a/pypy/module/cpyext/test/test_dictobject.py
b/pypy/module/cpyext/test/test_dictobject.py
--- a/pypy/module/cpyext/test/test_dictobject.py
+++ b/pypy/module/cpyext/test/test_dictobject.py
@@ -2,6 +2,7 @@
from pypy.module.cpyext.test.test_api import BaseApiTest
from pypy.module.cpyext.api import Py_ssize_tP, PyObjectP
from pypy.module.cpyext.pyobject import make_ref, from_ref
+from pypy.interpreter.error import OperationError
class TestDictObject(BaseApiTest):
def test_dict(self, space, api):
@@ -110,3 +111,13 @@
assert space.eq_w(space.len(w_copy), space.len(w_dict))
assert space.eq_w(w_copy, w_dict)
+
+ def test_dictproxy(self, space, api):
+ w_dict = space.sys.get('modules')
+ w_proxy = api.PyDictProxy_New(w_dict)
+ assert space.is_true(space.contains(w_proxy, space.wrap('sys')))
+ raises(OperationError, space.setitem,
+ w_proxy, space.wrap('sys'), space.w_None)
+ raises(OperationError, space.delitem,
+ w_proxy, space.wrap('sys'))
+ raises(OperationError, space.call_method, w_proxy, 'clear')
diff --git a/pypy/module/cpyext/test/test_pystate.py
b/pypy/module/cpyext/test/test_pystate.py
--- a/pypy/module/cpyext/test/test_pystate.py
+++ b/pypy/module/cpyext/test/test_pystate.py
@@ -2,6 +2,7 @@
from pypy.module.cpyext.test.test_api import BaseApiTest
from pypy.rpython.lltypesystem.lltype import nullptr
from pypy.module.cpyext.pystate import PyInterpreterState, PyThreadState
+from pypy.module.cpyext.pyobject import from_ref
class AppTestThreads(AppTestCpythonExtensionBase):
def test_allow_threads(self):
@@ -49,3 +50,10 @@
api.PyEval_AcquireThread(tstate)
api.PyEval_ReleaseThread(tstate)
+
+ def test_threadstate_dict(self, space, api):
+ ts = api.PyThreadState_Get()
+ ref = ts.c_dict
+ assert ref == api.PyThreadState_GetDict()
+ w_obj = from_ref(space, ref)
+ assert space.isinstance_w(w_obj, space.w_dict)
diff --git a/pypy/module/cpyext/test/test_setobject.py
b/pypy/module/cpyext/test/test_setobject.py
--- a/pypy/module/cpyext/test/test_setobject.py
+++ b/pypy/module/cpyext/test/test_setobject.py
@@ -32,3 +32,13 @@
w_set = api.PySet_New(space.wrap([1,2,3,4]))
assert api.PySet_Contains(w_set, space.wrap(1))
assert not api.PySet_Contains(w_set, space.wrap(0))
+
+ def test_set_pop_clear(self, space, api):
+ w_set = api.PySet_New(space.wrap([1,2,3,4]))
+ w_obj = api.PySet_Pop(w_set)
+ assert space.int_w(w_obj) in (1,2,3,4)
+ assert space.len_w(w_set) == 3
+ api.PySet_Clear(w_set)
+ assert space.len_w(w_set) == 0
+
+
diff --git a/pypy/module/cpyext/test/test_typeobject.py
b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -425,3 +425,32 @@
''')
obj = module.new_obj()
raises(ZeroDivisionError, obj.__setitem__, 5, None)
+
+ def test_tp_iter(self):
+ module = self.import_extension('foo', [
+ ("tp_iter", "METH_O",
+ '''
+ if (!args->ob_type->tp_iter)
+ {
+ PyErr_SetNone(PyExc_ValueError);
+ return NULL;
+ }
+ return args->ob_type->tp_iter(args);
+ '''
+ ),
+ ("tp_iternext", "METH_O",
+ '''
+ if (!args->ob_type->tp_iternext)
+ {
+ PyErr_SetNone(PyExc_ValueError);
+ return NULL;
+ }
+ return args->ob_type->tp_iternext(args);
+ '''
+ )
+ ])
+ l = [1]
+ it = module.tp_iter(l)
+ assert type(it) is type(iter([]))
+ assert module.tp_iternext(it) == 1
+ raises(StopIteration, module.tp_iternext, it)
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py
b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -420,3 +420,12 @@
w_seq = space.wrap([u'a', u'b'])
w_joined = api.PyUnicode_Join(w_sep, w_seq)
assert space.unwrap(w_joined) == u'a<sep>b'
+
+ def test_fromordinal(self, space, api):
+ w_char = api.PyUnicode_FromOrdinal(65)
+ assert space.unwrap(w_char) == u'A'
+ w_char = api.PyUnicode_FromOrdinal(0)
+ assert space.unwrap(w_char) == u'\0'
+ w_char = api.PyUnicode_FromOrdinal(0xFFFF)
+ assert space.unwrap(w_char) == u'\uFFFF'
+
diff --git a/pypy/module/cpyext/unicodeobject.py
b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -395,6 +395,16 @@
w_str = space.wrap(rffi.charpsize2str(s, size))
return space.call_method(w_str, 'decode', space.wrap("utf-8"))
+@cpython_api([rffi.INT_real], PyObject)
+def PyUnicode_FromOrdinal(space, ordinal):
+ """Create a Unicode Object from the given Unicode code point ordinal.
+
+ The ordinal must be in range(0x10000) on narrow Python builds
+ (UCS2), and range(0x110000) on wide builds (UCS4). A ValueError is
+ raised in case it is not."""
+ w_ordinal = space.wrap(rffi.cast(lltype.Signed, ordinal))
+ return space.call_function(space.builtin.get('unichr'), w_ordinal)
+
@cpython_api([PyObjectP, Py_ssize_t], rffi.INT_real, error=-1)
def PyUnicode_Resize(space, ref, newsize):
# XXX always create a new string so far
diff --git a/pypy/module/oracle/interp_error.py
b/pypy/module/oracle/interp_error.py
--- a/pypy/module/oracle/interp_error.py
+++ b/pypy/module/oracle/interp_error.py
@@ -72,7 +72,7 @@
get(space).w_InternalError,
space.wrap("No Oracle error?"))
- self.code = codeptr[0]
+ self.code = rffi.cast(lltype.Signed, codeptr[0])
self.w_message = config.w_string(space, textbuf)
finally:
lltype.free(codeptr, flavor='raw')
diff --git a/pypy/module/oracle/interp_variable.py
b/pypy/module/oracle/interp_variable.py
--- a/pypy/module/oracle/interp_variable.py
+++ b/pypy/module/oracle/interp_variable.py
@@ -359,14 +359,14 @@
# Verifies that truncation or other problems did not take place on
# retrieve.
if self.isVariableLength:
- if rffi.cast(lltype.Signed, self.returnCode[pos]) != 0:
+ error_code = rffi.cast(lltype.Signed, self.returnCode[pos])
+ if error_code != 0:
error = W_Error(space, self.environment,
"Variable_VerifyFetch()", 0)
- error.code = self.returnCode[pos]
+ error.code = error_code
error.message = space.wrap(
"column at array pos %d fetched with error: %d" %
- (pos,
- rffi.cast(lltype.Signed, self.returnCode[pos])))
+ (pos, error_code))
w_error = get(space).w_DatabaseError
raise OperationError(get(space).w_DatabaseError,
diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py
--- a/pypy/objspace/fake/objspace.py
+++ b/pypy/objspace/fake/objspace.py
@@ -326,4 +326,5 @@
return w_some_obj()
FakeObjSpace.sys = FakeModule()
FakeObjSpace.sys.filesystemencoding = 'foobar'
+FakeObjSpace.sys.defaultencoding = 'ascii'
FakeObjSpace.builtin = FakeModule()
diff --git a/pypy/objspace/flow/flowcontext.py
b/pypy/objspace/flow/flowcontext.py
--- a/pypy/objspace/flow/flowcontext.py
+++ b/pypy/objspace/flow/flowcontext.py
@@ -410,7 +410,7 @@
w_new = Constant(newvalue)
f = self.crnt_frame
stack_items_w = f.locals_stack_w
- for i in range(f.valuestackdepth-1, f.nlocals-1, -1):
+ for i in range(f.valuestackdepth-1, f.pycode.co_nlocals-1, -1):
w_v = stack_items_w[i]
if isinstance(w_v, Constant):
if w_v.value is oldvalue:
diff --git a/pypy/objspace/flow/test/test_framestate.py
b/pypy/objspace/flow/test/test_framestate.py
--- a/pypy/objspace/flow/test/test_framestate.py
+++ b/pypy/objspace/flow/test/test_framestate.py
@@ -25,7 +25,7 @@
dummy = Constant(None)
#dummy.dummy = True
arg_list = ([Variable() for i in range(formalargcount)] +
- [dummy] * (frame.nlocals - formalargcount))
+ [dummy] * (frame.pycode.co_nlocals - formalargcount))
frame.setfastscope(arg_list)
return frame
@@ -42,7 +42,7 @@
def test_neq_hacked_framestate(self):
frame = self.getframe(self.func_simple)
fs1 = FrameState(frame)
- frame.locals_stack_w[frame.nlocals-1] = Variable()
+ frame.locals_stack_w[frame.pycode.co_nlocals-1] = Variable()
fs2 = FrameState(frame)
assert fs1 != fs2
@@ -55,7 +55,7 @@
def test_union_on_hacked_framestates(self):
frame = self.getframe(self.func_simple)
fs1 = FrameState(frame)
- frame.locals_stack_w[frame.nlocals-1] = Variable()
+ frame.locals_stack_w[frame.pycode.co_nlocals-1] = Variable()
fs2 = FrameState(frame)
assert fs1.union(fs2) == fs2 # fs2 is more general
assert fs2.union(fs1) == fs2 # fs2 is more general
@@ -63,7 +63,7 @@
def test_restore_frame(self):
frame = self.getframe(self.func_simple)
fs1 = FrameState(frame)
- frame.locals_stack_w[frame.nlocals-1] = Variable()
+ frame.locals_stack_w[frame.pycode.co_nlocals-1] = Variable()
fs1.restoreframe(frame)
assert fs1 == FrameState(frame)
@@ -82,7 +82,7 @@
def test_getoutputargs(self):
frame = self.getframe(self.func_simple)
fs1 = FrameState(frame)
- frame.locals_stack_w[frame.nlocals-1] = Variable()
+ frame.locals_stack_w[frame.pycode.co_nlocals-1] = Variable()
fs2 = FrameState(frame)
outputargs = fs1.getoutputargs(fs2)
# 'x' -> 'x' is a Variable
@@ -92,16 +92,16 @@
def test_union_different_constants(self):
frame = self.getframe(self.func_simple)
fs1 = FrameState(frame)
- frame.locals_stack_w[frame.nlocals-1] = Constant(42)
+ frame.locals_stack_w[frame.pycode.co_nlocals-1] = Constant(42)
fs2 = FrameState(frame)
fs3 = fs1.union(fs2)
fs3.restoreframe(frame)
- assert isinstance(frame.locals_stack_w[frame.nlocals-1], Variable)
- # ^^^ generalized
+ assert isinstance(frame.locals_stack_w[frame.pycode.co_nlocals-1],
+ Variable) # generalized
def test_union_spectag(self):
frame = self.getframe(self.func_simple)
fs1 = FrameState(frame)
- frame.locals_stack_w[frame.nlocals-1] = Constant(SpecTag())
+ frame.locals_stack_w[frame.pycode.co_nlocals-1] = Constant(SpecTag())
fs2 = FrameState(frame)
assert fs1.union(fs2) is None # UnionError
diff --git a/pypy/translator/c/gcc/trackgcroot.py
b/pypy/translator/c/gcc/trackgcroot.py
--- a/pypy/translator/c/gcc/trackgcroot.py
+++ b/pypy/translator/c/gcc/trackgcroot.py
@@ -471,8 +471,8 @@
return []
IGNORE_OPS_WITH_PREFIXES = dict.fromkeys([
- 'cmp', 'test', 'set', 'sahf', 'lahf', 'cltd', 'cld', 'std',
- 'rep', 'movs', 'lods', 'stos', 'scas', 'cwtl', 'cwde', 'prefetch',
+ 'cmp', 'test', 'set', 'sahf', 'lahf', 'cld', 'std',
+ 'rep', 'movs', 'lods', 'stos', 'scas', 'cwde', 'prefetch',
# floating-point operations cannot produce GC pointers
'f',
'cvt', 'ucomi', 'comi', 'subs', 'subp' , 'adds', 'addp', 'xorp',
@@ -485,6 +485,8 @@
'bswap', 'bt', 'rdtsc',
'punpck', 'pshufd', 'pcmp', 'pand', 'psllw', 'pslld', 'psllq',
'paddq', 'pinsr',
+ # sign-extending moves should not produce GC pointers
+ 'cbtw', 'cwtl', 'cwtd', 'cltd', 'cltq', 'cqto',
# zero-extending moves should not produce GC pointers
'movz',
# locked operations should not move GC pointers, at least so far
@@ -1695,6 +1697,8 @@
}
"""
elif self.format in ('elf64', 'darwin64'):
+ if self.format == 'elf64': # gentoo patch: hardened systems
+ print >> output, "\t.section .note.GNU-stack,\"\",%progbits"
print >> output, "\t.text"
print >> output, "\t.globl %s" % _globalname('pypy_asm_stackwalk')
_variant(elf64='.type pypy_asm_stackwalk, @function',
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit