Author: Armin Rigo <[email protected]>
Branch: py3.5
Changeset: r90647:7c1314187e2f
Date: 2017-03-13 08:50 +0100
http://bitbucket.org/pypy/pypy/changeset/7c1314187e2f/
Log: hg merge default
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -200,3 +200,5 @@
asmgcc---close enough that we can now make shadowstack the default even
on Linux. This should remove a whole class of rare bugs introduced by
asmgcc.
+
+.. branch: fniephaus/fix-typo-1488123166752
diff --git a/pypy/module/_minimal_curses/__init__.py
b/pypy/module/_minimal_curses/__init__.py
--- a/pypy/module/_minimal_curses/__init__.py
+++ b/pypy/module/_minimal_curses/__init__.py
@@ -10,7 +10,6 @@
py.test.skip("no _curses or _minimal_curses module") # no _curses at
all
from pypy.interpreter.mixedmodule import MixedModule
-from pypy.module._minimal_curses import fficurses # for side effects
class Module(MixedModule):
diff --git a/pypy/module/_minimal_curses/fficurses.py
b/pypy/module/_minimal_curses/fficurses.py
--- a/pypy/module/_minimal_curses/fficurses.py
+++ b/pypy/module/_minimal_curses/fficurses.py
@@ -1,11 +1,8 @@
-""" The ffi for rpython, need to be imported for side effects
+""" The ffi for rpython
"""
from rpython.rtyper.lltypesystem import rffi
-from rpython.rtyper.lltypesystem import lltype
from rpython.rtyper.tool import rffi_platform
-from rpython.rtyper.extfunc import register_external
-from pypy.module._minimal_curses import interp_curses
from rpython.translator.tool.cbuild import ExternalCompilationInfo
# We cannot trust ncurses5-config, it's broken in various ways in
@@ -58,86 +55,73 @@
eci = guess_eci()
-INT = rffi.INT
-INTP = lltype.Ptr(lltype.Array(INT, hints={'nolength':True}))
-c_setupterm = rffi.llexternal('setupterm', [rffi.CCHARP, INT, INTP], INT,
- compilation_info=eci)
-c_tigetstr = rffi.llexternal('tigetstr', [rffi.CCHARP], rffi.CCHARP,
- compilation_info=eci)
-c_tparm = rffi.llexternal('tparm', [rffi.CCHARP, INT, INT, INT, INT, INT,
- INT, INT, INT, INT], rffi.CCHARP,
- compilation_info=eci)
+# We should not use this 'eci' directly because it causes the #include
+# of term.h to appear in all generated C sources, and term.h contains a
+# poisonous quantity of #defines for common lower-case names like
+# 'buttons' or 'lines' (!!!). It is basically dangerous to include
+# term.h in any C source file that may contain unrelated source code.
-ERR = rffi.CConstant('ERR', lltype.Signed)
-OK = rffi.CConstant('OK', lltype.Signed)
+include_lines = '\n'.join(['#include <%s>' % _incl for _incl in eci.includes])
+eci = eci.copy_without('includes')
-def curses_setupterm(term, fd):
- intp = lltype.malloc(INTP.TO, 1, flavor='raw')
- err = rffi.cast(lltype.Signed, c_setupterm(term, fd, intp))
- try:
- if err == ERR:
- errret = rffi.cast(lltype.Signed, intp[0])
- if errret == 0:
- msg = "setupterm: could not find terminal"
- elif errret == -1:
- msg = "setupterm: could not find terminfo database"
- else:
- msg = "setupterm: unknown error"
- raise interp_curses.curses_error(msg)
- interp_curses.module_info.setupterm_called = True
- finally:
- lltype.free(intp, flavor='raw')
-def curses_setupterm_null_llimpl(fd):
- curses_setupterm(lltype.nullptr(rffi.CCHARP.TO), fd)
+eci = eci.merge(ExternalCompilationInfo(
+ post_include_bits=[
+ "RPY_EXTERN char *rpy_curses_setupterm(char *, int);\n"
+ "RPY_EXTERN char *rpy_curses_tigetstr(char *);\n"
+ "RPY_EXTERN char *rpy_curses_tparm(char *, int, int, int, int,"
+ " int, int, int, int, int);"
+ ],
+ separate_module_sources=["""
-def curses_setupterm_llimpl(term, fd):
- ll_s = rffi.str2charp(term)
- try:
- curses_setupterm(ll_s, fd)
- finally:
- rffi.free_charp(ll_s)
+%(include_lines)s
-register_external(interp_curses._curses_setupterm_null,
- [int], llimpl=curses_setupterm_null_llimpl,
- export_name='_curses.setupterm_null')
-register_external(interp_curses._curses_setupterm,
- [str, int], llimpl=curses_setupterm_llimpl,
- export_name='_curses.setupterm')
+RPY_EXTERN
+char *rpy_curses_setupterm(char *term, int fd)
+{
+ int errret = -42;
+ if (setupterm(term, fd, &errret) == ERR) {
+ switch (errret) {
+ case 0:
+ return "setupterm: could not find terminal";
+ case -1:
+ return "setupterm: could not find terminfo database";
+ default:
+ return "setupterm: unknown error";
+ }
+ }
+ return NULL;
+}
-def check_setup_invoked():
- if not interp_curses.module_info.setupterm_called:
- raise interp_curses.curses_error("must call (at least) setupterm()
first")
+RPY_EXTERN
+char *rpy_curses_tigetstr(char *capname)
+{
+ char *res = tigetstr(capname);
+ if (res == (char *)-1)
+ res = NULL;
+ return res;
+}
-def tigetstr_llimpl(cap):
- check_setup_invoked()
- ll_cap = rffi.str2charp(cap)
- try:
- ll_res = c_tigetstr(ll_cap)
- num = lltype.cast_ptr_to_int(ll_res)
- if num == 0 or num == -1:
- raise interp_curses.TermError()
- res = rffi.charp2str(ll_res)
- return res
- finally:
- rffi.free_charp(ll_cap)
+RPY_EXTERN
+char *rpy_curses_tparm(char *str, int x0, int x1, int x2, int x3,
+ int x4, int x5, int x6, int x7, int x8)
+{
+ return tparm(str, x0, x1, x2, x3, x4, x5, x6, x7, x8);
+}
-register_external(interp_curses._curses_tigetstr, [str], str,
- export_name='_curses.tigetstr', llimpl=tigetstr_llimpl)
+""" % globals()]))
-def tparm_llimpl(s, args):
- check_setup_invoked()
- l = [0, 0, 0, 0, 0, 0, 0, 0, 0]
- for i in range(min(len(args), 9)):
- l[i] = args[i]
- ll_s = rffi.str2charp(s)
- # XXX nasty trick stolen from CPython
- ll_res = c_tparm(ll_s, l[0], l[1], l[2], l[3], l[4], l[5], l[6],
- l[7], l[8])
- rffi.free_charp(ll_s)
- res = rffi.charp2str(ll_res)
- return res
-register_external(interp_curses._curses_tparm, [str, [int]], str,
- export_name='_curses.tparm', llimpl=tparm_llimpl)
+rpy_curses_setupterm = rffi.llexternal(
+ "rpy_curses_setupterm", [rffi.CCHARP, rffi.INT], rffi.CCHARP,
+ compilation_info=eci)
+rpy_curses_tigetstr = rffi.llexternal(
+ "rpy_curses_tigetstr", [rffi.CCHARP], rffi.CCHARP,
+ compilation_info=eci)
+
+rpy_curses_tparm = rffi.llexternal(
+ "rpy_curses_tparm", [rffi.CCHARP, rffi.INT, rffi.INT, rffi.INT, rffi.INT,
+ rffi.INT, rffi.INT, rffi.INT, rffi.INT, rffi.INT],
+ rffi.CCHARP,
+ compilation_info=eci)
diff --git a/pypy/module/_minimal_curses/interp_curses.py
b/pypy/module/_minimal_curses/interp_curses.py
--- a/pypy/module/_minimal_curses/interp_curses.py
+++ b/pypy/module/_minimal_curses/interp_curses.py
@@ -1,44 +1,24 @@
-
from pypy.interpreter.gateway import unwrap_spec
from pypy.interpreter.error import OperationError
-from pypy.module._minimal_curses import _curses
+from pypy.module._minimal_curses import fficurses
+from rpython.rtyper.lltypesystem import lltype, rffi
+
class ModuleInfo:
- def __init__(self):
+ def __init__(self, space):
self.setupterm_called = False
-module_info = ModuleInfo()
+def check_setup_invoked(space):
+ if not space.fromcache(ModuleInfo).setupterm_called:
+ raise curses_error(space, "must call (at least) setupterm() first")
-class curses_error(Exception):
- def __init__(self, msg):
- self.msg = msg
-from rpython.annotator.classdesc import FORCE_ATTRIBUTES_INTO_CLASSES
-from rpython.annotator.model import SomeString
-
-# this is necessary due to annmixlevel
-FORCE_ATTRIBUTES_INTO_CLASSES[curses_error] = {'msg': SomeString()}
-
-def convert_error(space, error):
- msg = error.msg
+def curses_error(space, errmsg):
w_module = space.getbuiltinmodule('_minimal_curses')
w_exception_class = space.getattr(w_module, space.newtext('error'))
- w_exception = space.call_function(w_exception_class, space.newtext(msg))
+ w_exception = space.call_function(w_exception_class, space.newtext(errmsg))
return OperationError(w_exception_class, w_exception)
-def _curses_setupterm_null(fd):
- # NOT_RPYTHON
- try:
- _curses.setupterm(None, fd)
- except _curses.error as e:
- raise curses_error(e.args[0])
-
-def _curses_setupterm(termname, fd):
- # NOT_RPYTHON
- try:
- _curses.setupterm(termname, fd)
- except _curses.error as e:
- raise curses_error(e.args[0])
@unwrap_spec(fd=int)
def setupterm(space, w_termname=None, fd=-1):
@@ -47,48 +27,47 @@
space.newtext('stdout'))
fd = space.int_w(space.call_function(space.getattr(w_stdout,
space.newtext('fileno'))))
- try:
- if space.is_none(w_termname):
- _curses_setupterm_null(fd)
- else:
- _curses_setupterm(space.text_w(w_termname), fd)
- except curses_error as e:
- raise convert_error(space, e)
+ if space.is_none(w_termname):
+ termname = None
+ else:
+ termname = space.text_w(w_termname)
-class TermError(Exception):
- pass
+ with rffi.scoped_str2charp(termname) as ll_term:
+ fd = rffi.cast(rffi.INT, fd)
+ ll_errmsg = fficurses.rpy_curses_setupterm(ll_term, fd)
+ if ll_errmsg:
+ raise curses_error(space, rffi.charp2str(ll_errmsg))
-def _curses_tigetstr(capname):
- # NOT_RPYTHON
- try:
- res = _curses.tigetstr(capname)
- except _curses.error as e:
- raise curses_error(e.args[0])
- if res is None:
- raise TermError
- return res
-
-def _curses_tparm(s, args):
- # NOT_RPYTHON
- try:
- return _curses.tparm(s, *args)
- except _curses.error as e:
- raise curses_error(e.args[0])
+ space.fromcache(ModuleInfo).setupterm_called = True
@unwrap_spec(capname='text')
def tigetstr(space, capname):
- try:
- result = _curses_tigetstr(capname)
- except TermError:
- return space.w_None
- except curses_error as e:
- raise convert_error(space, e)
- return space.newbytes(result)
+ check_setup_invoked(space)
+ with rffi.scoped_str2charp(capname) as ll_capname:
+ ll_result = fficurses.rpy_curses_tigetstr(ll_capname)
+ if ll_result:
+ return space.newbytes(rffi.charp2str(ll_result))
+ else:
+ return space.w_None
@unwrap_spec(s='bufferstr')
def tparm(space, s, args_w):
+ check_setup_invoked(space)
args = [space.int_w(a) for a in args_w]
- try:
- return space.newbytes(_curses_tparm(s, args))
- except curses_error as e:
- raise convert_error(space, e)
+ # nasty trick stolen from CPython
+ x0 = args[0] if len(args) > 0 else 0
+ x1 = args[1] if len(args) > 1 else 0
+ x2 = args[2] if len(args) > 2 else 0
+ x3 = args[3] if len(args) > 3 else 0
+ x4 = args[4] if len(args) > 4 else 0
+ x5 = args[5] if len(args) > 5 else 0
+ x6 = args[6] if len(args) > 6 else 0
+ x7 = args[7] if len(args) > 7 else 0
+ x8 = args[8] if len(args) > 8 else 0
+ with rffi.scoped_str2charp(s) as ll_str:
+ ll_result = fficurses.rpy_curses_tparm(ll_str, x0, x1, x2, x3,
+ x4, x5, x6, x7, x8)
+ if ll_result:
+ return space.newbytes(rffi.charp2str(ll_result))
+ else:
+ raise curses_error(space, "tparm() returned NULL")
diff --git a/pypy/module/_minimal_curses/test/test_curses.py
b/pypy/module/_minimal_curses/test/test_curses.py
--- a/pypy/module/_minimal_curses/test/test_curses.py
+++ b/pypy/module/_minimal_curses/test/test_curses.py
@@ -76,19 +76,27 @@
"""
def test_csetupterm(self):
from rpython.translator.c.test.test_genc import compile
- from pypy.module._minimal_curses import interp_curses
+ from rpython.rtyper.lltypesystem import lltype, rffi
+ from pypy.module._minimal_curses import fficurses
+
def runs_setupterm():
- interp_curses._curses_setupterm_null(1)
+ null = lltype.nullptr(rffi.CCHARP.TO)
+ fficurses.rpy_curses_setupterm(null, 1)
fn = compile(runs_setupterm, [])
fn()
def test_ctgetstr(self):
from rpython.translator.c.test.test_genc import compile
- from pypy.module._minimal_curses import interp_curses
+ from rpython.rtyper.lltypesystem import lltype, rffi
+ from pypy.module._minimal_curses import fficurses
+
def runs_ctgetstr():
- interp_curses._curses_setupterm("xterm", 1)
- return interp_curses._curses_tigetstr('cup')
+ with rffi.scoped_str2charp("xterm") as ll_term:
+ fficurses.rpy_curses_setupterm(ll_term, 1)
+ with rffi.scoped_str2charp("cup") as ll_capname:
+ ll = fficurses.rpy_curses_tigetstr(ll_capname)
+ return rffi.charp2str(ll)
fn = compile(runs_ctgetstr, [])
res = fn()
@@ -96,11 +104,16 @@
def test_ctparm(self):
from rpython.translator.c.test.test_genc import compile
- from pypy.module._minimal_curses import interp_curses
+ from rpython.rtyper.lltypesystem import lltype, rffi
+ from pypy.module._minimal_curses import fficurses
+
def runs_tparm():
- interp_curses._curses_setupterm("xterm", 1)
- cup = interp_curses._curses_tigetstr('cup')
- return interp_curses._curses_tparm(cup, [5, 3])
+ with rffi.scoped_str2charp("xterm") as ll_term:
+ fficurses.rpy_curses_setupterm(ll_term, 1)
+ with rffi.scoped_str2charp("cup") as ll_capname:
+ cup = fficurses.rpy_curses_tigetstr(ll_capname)
+ res = fficurses.rpy_curses_tparm(cup, 5, 3, 0, 0, 0, 0, 0, 0,
0)
+ return rffi.charp2str(res)
fn = compile(runs_tparm, [])
res = fn()
diff --git a/pypy/module/cpyext/include/pymem.h
b/pypy/module/cpyext/include/pymem.h
--- a/pypy/module/cpyext/include/pymem.h
+++ b/pypy/module/cpyext/include/pymem.h
@@ -60,6 +60,25 @@
#define PyMem_Del PyMem_Free
#define PyMem_DEL PyMem_FREE
+
+/* From CPython 3.6, with a different goal. _PyTraceMalloc_Track()
+ * is equivalent to __pypy__.add_memory_pressure(size); it works with
+ * or without the GIL. _PyTraceMalloc_Untrack() is an empty stub.
+ * You can check if these functions are available by using:
+ *
+ * #if defined(PYPY_TRACEMALLOC) || \
+ * (PY_VERSION_HEX >= 0x03060000 && !defined(Py_LIMITED_API))
+ */
+#define PYPY_TRACEMALLOC 1
+
+typedef unsigned int _PyTraceMalloc_domain_t;
+
+PyAPI_FUNC(int) _PyTraceMalloc_Track(_PyTraceMalloc_domain_t domain,
+ uintptr_t ptr, size_t size);
+PyAPI_FUNC(int) _PyTraceMalloc_Untrack(_PyTraceMalloc_domain_t domain,
+ uintptr_t ptr);
+
+
#ifdef __cplusplus
}
#endif
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
@@ -457,3 +457,8 @@
with rffi.scoped_nonmovingbuffer(data) as buf:
fwrite(buf, 1, count, fp)
return 0
+
+@cpython_api([lltype.Signed], lltype.Void)
+def _PyPyGC_AddMemoryPressure(space, report):
+ from rpython.rlib import rgc
+ rgc.add_memory_pressure(report)
diff --git a/pypy/module/cpyext/src/pymem.c b/pypy/module/cpyext/src/pymem.c
--- a/pypy/module/cpyext/src/pymem.c
+++ b/pypy/module/cpyext/src/pymem.c
@@ -84,3 +84,46 @@
{
free(ptr);
}
+
+int _PyTraceMalloc_Track(_PyTraceMalloc_domain_t domain,
+ uintptr_t ptr, size_t size)
+{
+ /* to avoid acquiring/releasing the GIL too often, only do it
+ if the total reported size exceeds 64KB. */
+ static volatile long unreported_size = 0;
+ long prev, next, report;
+
+ size += sizeof(long);
+ /* ^^^ to account for some alignment. Important, otherwise we'd
+ * collect sizes of, say, 1-bytes mallocs in 1-bytes increment */
+
+ retry:
+ report = 0;
+ prev = unreported_size;
+ next = prev + size;
+ if (next >= 65536) {
+ report = next;
+ next = 0;
+ }
+ if (prev != next) {
+#ifdef _WIN32
+ if (InterlockedCompareExchange(&unreported_size, next, prev) != prev)
+ goto retry;
+#else
+ if (!__sync_bool_compare_and_swap(&unreported_size, prev, next))
+ goto retry;
+#endif
+ }
+
+ if (report) {
+ PyGILState_STATE state = PyGILState_Ensure();
+ _PyPyGC_AddMemoryPressure(report);
+ PyGILState_Release(state);
+ }
+}
+
+int _PyTraceMalloc_Untrack(_PyTraceMalloc_domain_t domain,
+ uintptr_t ptr)
+{
+ /* nothing */
+}
diff --git a/pypy/module/cpyext/test/test_object.py
b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -191,10 +191,40 @@
class AppTestObject(AppTestCpythonExtensionBase):
def setup_class(cls):
+ from rpython.rlib import rgc
+ from pypy.interpreter import gateway
+
AppTestCpythonExtensionBase.setup_class.im_func(cls)
tmpname = str(py.test.ensuretemp('out', dir=0))
cls.w_tmpname = cls.space.wrap(tmpname)
+ if not cls.runappdirect:
+ cls.total_mem = 0
+ def add_memory_pressure(estimate):
+ assert estimate >= 0
+ cls.total_mem += estimate
+ cls.orig_add_memory_pressure = [rgc.add_memory_pressure]
+ rgc.add_memory_pressure = add_memory_pressure
+
+ def _reset_memory_pressure(space):
+ cls.total_mem = 0
+ cls.w_reset_memory_pressure = cls.space.wrap(
+ gateway.interp2app(_reset_memory_pressure))
+
+ def _cur_memory_pressure(space):
+ return space.newint(cls.total_mem)
+ cls.w_cur_memory_pressure = cls.space.wrap(
+ gateway.interp2app(_cur_memory_pressure))
+ else:
+ def _skip_test(*ignored):
+ pytest.skip("not for -A testing")
+ cls.w_reset_memory_pressure = _skip_test
+
+ def teardown_class(cls):
+ from rpython.rlib import rgc
+ if hasattr(cls, 'orig_add_memory_pressure'):
+ [rgc.add_memory_pressure] = cls.orig_add_memory_pressure
+
def test_object_malloc(self):
module = self.import_extension('foo', [
("malloctest", "METH_NOARGS",
@@ -310,6 +340,31 @@
assert type(module.asbytes(sub1(b''))) is bytes
assert type(module.asbytes(sub2(b''))) is sub2
+ def test_add_memory_pressure(self):
+ self.reset_memory_pressure() # for the potential skip
+ module = self.import_extension('foo', [
+ ("foo", "METH_O",
+ """
+ _PyTraceMalloc_Track(0, 0, PyInt_AsLong(args) - sizeof(long));
+ Py_INCREF(Py_None);
+ return Py_None;
+ """)])
+ self.reset_memory_pressure()
+ module.foo(42)
+ assert self.cur_memory_pressure() == 0
+ module.foo(65000 - 42)
+ assert self.cur_memory_pressure() == 0
+ module.foo(536)
+ assert self.cur_memory_pressure() == 65536
+ module.foo(40000)
+ assert self.cur_memory_pressure() == 65536
+ module.foo(40000)
+ assert self.cur_memory_pressure() == 65536 + 80000
+ module.foo(35000)
+ assert self.cur_memory_pressure() == 65536 + 80000
+ module.foo(35000)
+ assert self.cur_memory_pressure() == 65536 + 80000 + 70000
+
class AppTestPyBuffer_FillInfo(AppTestCpythonExtensionBase):
"""
PyBuffer_FillInfo populates the fields of a Py_buffer from its arguments.
diff --git a/pypy/sandbox/test/test_pypy_interact.py
b/pypy/sandbox/test/test_pypy_interact.py
--- a/pypy/sandbox/test/test_pypy_interact.py
+++ b/pypy/sandbox/test/test_pypy_interact.py
@@ -74,7 +74,8 @@
def setup_module(mod):
- t = Translation(mini_pypy_like_entry_point, backend='c', sandbox=True)
+ t = Translation(mini_pypy_like_entry_point, backend='c', sandbox=True,
+ lldebug=True)
mod.executable = str(t.compile())
diff --git a/rpython/translator/c/src/stacklet/stacklet.c
b/rpython/translator/c/src/stacklet/stacklet.c
--- a/rpython/translator/c/src/stacklet/stacklet.c
+++ b/rpython/translator/c/src/stacklet/stacklet.c
@@ -16,6 +16,7 @@
* can redefine it to upwards growing, 1.
*/
#define STACK_DIRECTION 0
+#define STATIC_NOINLINE __attribute__((noinline)) static
#include "src/stacklet/slp_platformselect.h"
@@ -56,11 +57,6 @@
stacklet_thread_handle stack_thrd; /* the thread where the stacklet is */
};
-void *(*_stacklet_switchstack)(void*(*)(void*, void*),
- void*(*)(void*, void*), void*) = NULL;
-void (*_stacklet_initialstub)(struct stacklet_thread_s *,
- stacklet_run_fn, void *) = NULL;
-
struct stacklet_thread_s {
struct stacklet_s *g_stack_chain_head; /* NULL <=> running main */
char *g_current_stack_stop;
@@ -252,8 +248,17 @@
return EMPTY_STACKLET_HANDLE;
}
-static void g_initialstub(struct stacklet_thread_s *thrd,
- stacklet_run_fn run, void *run_arg)
+STATIC_NOINLINE
+void *_stacklet_switchstack(void *(*save_state)(void*, void*),
+ void *(*restore_state)(void*, void*),
+ void *extra)
+{
+ return slp_switch(save_state, restore_state, extra);
+}
+
+STATIC_NOINLINE
+void g_initialstub(struct stacklet_thread_s *thrd,
+ stacklet_run_fn run, void *run_arg)
{
struct stacklet_s *result;
@@ -284,13 +289,6 @@
{
struct stacklet_thread_s *thrd;
- if (_stacklet_switchstack == NULL) {
- /* set up the following global with an indirection, which is needed
- to prevent any inlining */
- _stacklet_initialstub = g_initialstub;
- _stacklet_switchstack = slp_switch;
- }
-
thrd = malloc(sizeof(struct stacklet_thread_s));
if (thrd != NULL)
memset(thrd, 0, sizeof(struct stacklet_thread_s));
@@ -311,7 +309,7 @@
thrd->g_current_stack_stop = ((char *)&stackmarker) + 1;
thrd->g_current_stack_marker = (char *)&stackmarker;
- _stacklet_initialstub(thrd, run, run_arg);
+ g_initialstub(thrd, run, run_arg);
return thrd->g_source;
}
diff --git a/rpython/translator/c/src/stacklet/switch_x64_msvc.h
b/rpython/translator/c/src/stacklet/switch_x64_msvc.h
--- a/rpython/translator/c/src/stacklet/switch_x64_msvc.h
+++ b/rpython/translator/c/src/stacklet/switch_x64_msvc.h
@@ -5,3 +5,5 @@
void *(*restore_state)(void*, void*),
void *extra);
+#undef STATIC_NOINLINE
+#define STATIC_NOINLINE static __declspec(noinline)
diff --git a/rpython/translator/c/src/stacklet/switch_x86_msvc.h
b/rpython/translator/c/src/stacklet/switch_x86_msvc.h
--- a/rpython/translator/c/src/stacklet/switch_x86_msvc.h
+++ b/rpython/translator/c/src/stacklet/switch_x86_msvc.h
@@ -5,6 +5,9 @@
void *(*restore_state)(void*, void*),
void *extra);
+#undef STATIC_NOINLINE
+#define STATIC_NOINLINE static __declspec(noinline)
+
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
diff --git a/rpython/translator/sandbox/test/test_sandbox.py
b/rpython/translator/sandbox/test/test_sandbox.py
--- a/rpython/translator/sandbox/test/test_sandbox.py
+++ b/rpython/translator/sandbox/test/test_sandbox.py
@@ -37,9 +37,9 @@
write_message(g, result, resulttype)
g.flush()
-def compile(f, gc='ref'):
+def compile(f, gc='ref', **kwds):
t = Translation(f, backend='c', sandbox=True, gc=gc,
- check_str_without_nul=True)
+ check_str_without_nul=True, **kwds)
return str(t.compile())
def run_in_subprocess(exe):
@@ -198,7 +198,7 @@
l.append("x" * int(argv[2]))
return int(len(l) > 1000)
- exe = compile(entry_point, gc='hybrid')
+ exe = compile(entry_point, gc='hybrid', lldebug=True)
pipe = subprocess.Popen([exe, '10', '10000'], stdout=subprocess.PIPE,
stdin=subprocess.PIPE)
g = pipe.stdin
diff --git a/rpython/translator/tool/cbuild.py
b/rpython/translator/tool/cbuild.py
--- a/rpython/translator/tool/cbuild.py
+++ b/rpython/translator/tool/cbuild.py
@@ -334,3 +334,9 @@
d['separate_module_files'] = ()
d['separate_module_sources'] = ()
return ExternalCompilationInfo(**d)
+
+ def copy_without(self, *names):
+ d = self._copy_attributes()
+ for name in names:
+ del d[name]
+ return ExternalCompilationInfo(**d)
diff --git a/testrunner/app_level_tests.py b/testrunner/app_level_tests.py
new file mode 100755
--- /dev/null
+++ b/testrunner/app_level_tests.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+"""
+This is what the buildbot runs to execute the app-level tests
+on top of pypy-c.
+"""
+
+import sys, os
+import subprocess
+
+rootdir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
+os.environ['PYTHONPATH'] = rootdir
+os.environ['PYTEST_PLUGINS'] = ''
+
+popen = subprocess.Popen(
+ [sys.executable, "testrunner/runner.py",
+ "--logfile=pytest-A.log",
+ "--config=pypy/pytest-A.cfg",
+ "--config=pypy/pytest-A.py",
+ "--config=~/machine-A_cfg.py",
+ "--root=pypy", "--timeout=3600",
+ ] + sys.argv[1:],
+ cwd=rootdir)
+
+try:
+ ret = popen.wait()
+except KeyboardInterrupt:
+ popen.kill()
+ print "\ninterrupted"
+ ret = 1
+
+sys.exit(ret)
diff --git a/testrunner/lib_python_tests.py b/testrunner/lib_python_tests.py
new file mode 100755
--- /dev/null
+++ b/testrunner/lib_python_tests.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+"""
+This is what the buildbot runs to execute the lib-python tests
+on top of pypy-c.
+"""
+
+import sys, os
+import subprocess
+
+rootdir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
+os.environ['PYTHONPATH'] = rootdir
+os.environ['PYTEST_PLUGINS'] = ''
+
+popen = subprocess.Popen(
+ [sys.executable, "pypy/test_all.py",
+ "--pypy=pypy/goal/pypy3-c",
+ "--timeout=3600",
+ "--resultlog=cpython.log", "lib-python",
+ ] + sys.argv[1:],
+ cwd=rootdir)
+
+try:
+ ret = popen.wait()
+except KeyboardInterrupt:
+ popen.kill()
+ print "\ninterrupted"
+ ret = 1
+
+sys.exit(ret)
diff --git a/testrunner/pypyjit_tests.py b/testrunner/pypyjit_tests.py
new file mode 100755
--- /dev/null
+++ b/testrunner/pypyjit_tests.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+"""
+This is what the buildbot runs to execute the pypyjit tests
+on top of pypy-c.
+"""
+
+import sys, os
+import subprocess
+
+rootdir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
+os.environ['PYTHONPATH'] = rootdir
+os.environ['PYTEST_PLUGINS'] = ''
+
+popen = subprocess.Popen(
+ [sys.executable, "pypy/test_all.py",
+ "--pypy=pypy/goal/pypy3-c",
+ "--resultlog=pypyjit_new.log",
+ "pypy/module/pypyjit/test_pypy_c",
+ ] + sys.argv[1:],
+ cwd=rootdir)
+
+try:
+ ret = popen.wait()
+except KeyboardInterrupt:
+ popen.kill()
+ print "\ninterrupted"
+ ret = 1
+
+sys.exit(ret)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit