Author: Armin Rigo <[email protected]>
Branch: sandbox-lib
Changeset: r83180:8f9fd1f3b161
Date: 2016-03-20 09:06 +0100
http://bitbucket.org/pypy/pypy/changeset/8f9fd1f3b161/
Log: Kill the high-level sandboxing, keep only the low-level one
diff --git a/rpython/annotator/policy.py b/rpython/annotator/policy.py
--- a/rpython/annotator/policy.py
+++ b/rpython/annotator/policy.py
@@ -72,30 +72,3 @@
for callback in bk.pending_specializations:
callback()
del bk.pending_specializations[:]
- if annotator.added_blocks is not None:
- all_blocks = annotator.added_blocks
- else:
- all_blocks = annotator.annotated
- for block in list(all_blocks):
- for i, instr in enumerate(block.operations):
- if not isinstance(instr, (op.simple_call, op.call_args)):
- continue
- v_func = instr.args[0]
- s_func = annotator.annotation(v_func)
- if not hasattr(s_func, 'needs_sandboxing'):
- continue
- key = ('sandboxing', s_func.const)
- if key not in bk.emulated_pbc_calls:
- params_s = s_func.args_s
- s_result = s_func.s_result
- from rpython.translator.rsandbox.rsandbox import
make_sandbox_trampoline
- sandbox_trampoline = make_sandbox_trampoline(
- annotator.translator,
- s_func.name, params_s, s_result)
- sandbox_trampoline._signature_ =
[SomeTuple(items=params_s)], s_result
- bk.emulate_pbc_call(key,
bk.immutablevalue(sandbox_trampoline), params_s)
- else:
- s_trampoline = bk.emulated_pbc_calls[key][0]
- sandbox_trampoline = s_trampoline.const
- new = instr.replace({instr.args[0]:
Constant(sandbox_trampoline)})
- block.operations[i] = new
diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py
--- a/rpython/rlib/objectmodel.py
+++ b/rpython/rlib/objectmodel.py
@@ -292,17 +292,12 @@
def sc_we_are_translated(ctx):
return Constant(True)
-def register_replacement_for(replaced_function, sandboxed_name=None):
+def register_replacement_for(replaced_function):
def wrap(func):
from rpython.rtyper.extregistry import ExtRegistryEntry
class ExtRegistry(ExtRegistryEntry):
_about_ = replaced_function
def compute_annotation(self):
- if sandboxed_name:
- config = self.bookkeeper.annotator.translator.config
- if config.translation.rsandbox:
- func._sandbox_external_name = sandboxed_name
- func._dont_inline_ = True
return self.bookkeeper.immutablevalue(func)
return func
return wrap
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -346,9 +346,7 @@
func = getattr(os, name, None)
if func is None:
return lambda f: f
- return register_replacement_for(
- func,
- sandboxed_name='ll_os.ll_os_%s' % name)
+ return register_replacement_for(func)
@specialize.arg(0)
def handle_posix_error(name, result):
diff --git a/rpython/rlib/rtime.py b/rpython/rlib/rtime.py
--- a/rpython/rlib/rtime.py
+++ b/rpython/rlib/rtime.py
@@ -91,9 +91,7 @@
func = getattr(pytime, name, None)
if func is None:
return lambda f: f
- return register_replacement_for(
- func,
- sandboxed_name='ll_time.ll_time_%s' % name)
+ return register_replacement_for(func)
config = rffi_platform.configure(CConfig)
globals().update(config)
diff --git a/rpython/rtyper/extfunc.py b/rpython/rtyper/extfunc.py
--- a/rpython/rtyper/extfunc.py
+++ b/rpython/rtyper/extfunc.py
@@ -90,19 +90,15 @@
class ExtFuncEntry(ExtRegistryEntry):
- safe_not_sandboxed = False
def compute_annotation(self):
s_result = SomeExternalFunction(
self.name, self.signature_args, self.signature_result)
- if (self.bookkeeper.annotator.translator.config.translation.rsandbox
- and not self.safe_not_sandboxed):
- s_result.needs_sandboxing = True
return s_result
def register_external(function, args, result=None, export_name=None,
- llimpl=None, llfakeimpl=None, sandboxsafe=False):
+ llimpl=None, llfakeimpl=None, sandboxsafe=None):
"""
function: the RPython function that will be rendered as an external
function (e.g.: math.floor)
args: a list containing the annotation of the arguments
@@ -110,7 +106,7 @@
export_name: the name of the function as it will be seen by the backends
llimpl: optional; if provided, this RPython function is called instead of
the target function
llfakeimpl: optional; if provided, called by the llinterpreter
- sandboxsafe: use True if the function performs no I/O (safe for
--sandboxlib)
+ sandboxsafe: IGNORED at this level
"""
if export_name is None:
@@ -120,7 +116,6 @@
class FunEntry(ExtFuncEntry):
_about_ = function
- safe_not_sandboxed = sandboxsafe
signature_args = params_s
signature_result = s_result
name = export_name
diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py
--- a/rpython/rtyper/rtyper.py
+++ b/rpython/rtyper/rtyper.py
@@ -574,20 +574,6 @@
def getcallable(self, graph):
def getconcretetype(v):
return self.bindingrepr(v).lowleveltype
- if self.annotator.translator.config.translation.rsandbox:
- from rpython.translator.rsandbox.rsandbox import (
- make_sandbox_trampoline) # don't import this globally
- try:
- name = graph.func._sandbox_external_name
- except AttributeError:
- pass
- else:
- args_s = [v.annotation for v in graph.getargs()]
- s_result = graph.getreturnvar().annotation
- sandboxed = make_sandbox_trampoline(self.annotator.translator,
- name, args_s, s_result)
- return self.getannmixlevel().delayedfunction(
- sandboxed, args_s, s_result)
return getfunctionptr(graph, getconcretetype)
diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py
--- a/rpython/translator/c/genc.py
+++ b/rpython/translator/c/genc.py
@@ -742,6 +742,8 @@
print >> f
print >> f, "#ifndef _PYPY_FORWARDDECL_H"
print >> f, "#define _PYPY_FORWARDDECL_H"
+ if database.rsandbox:
+ print >> f, '#include "rsandbox.h"'
for node in database.globalcontainers():
for line in node.forward_declaration():
print >> f, line
@@ -853,9 +855,9 @@
print >>fi, "#define PYPY_INSTRUMENT_NCOUNTER %d" % n
fi.close()
- if 'RPY_SANDBOXED' in defines:
+ if database.rsandbox:
from rpython.translator.rsandbox.rsandbox import add_sandbox_files
- eci = add_sandbox_files(database, eci)
+ eci = add_sandbox_files(database, eci, targetdir)
eci = add_extra_files(eci)
eci = eci.convert_sources_to_files()
diff --git a/rpython/translator/c/node.py b/rpython/translator/c/node.py
--- a/rpython/translator/c/node.py
+++ b/rpython/translator/c/node.py
@@ -914,14 +914,6 @@
def new_funcnode(db, T, obj, forcename=None):
from rpython.rtyper.rtyper import llinterp_backend
- if db.rsandbox:
- if (getattr(obj, 'external', None) is not None and
- not obj._safe_not_sandboxed):
- from rpython.translator.rsandbox import rsandbox
- obj.__dict__['graph'] = rsandbox.get_sandbox_stub(
- obj, db.translator.rtyper)
- obj.__dict__.pop('_safe_not_sandboxed', None)
- obj.__dict__.pop('external', None)
if forcename:
name = forcename
else:
@@ -930,8 +922,9 @@
return FuncNode(db, T, obj, name)
elif getattr(obj, 'external', None) is not None:
assert obj.external == 'C'
- if db.rsandbox:
- assert obj._safe_not_sandboxed
+ if db.rsandbox and not obj._safe_not_sandboxed:
+ from rpython.translator.rsandbox import rsandbox
+ name = rsandbox.register_rsandbox_func(db, obj, name)
return ExternalFuncNode(db, T, obj, name)
elif hasattr(obj._callable, "c_name"):
return ExternalFuncNode(db, T, obj, name) # this case should only be
used for entrypoints
diff --git a/rpython/translator/rsandbox/rsandbox.py
b/rpython/translator/rsandbox/rsandbox.py
--- a/rpython/translator/rsandbox/rsandbox.py
+++ b/rpython/translator/rsandbox/rsandbox.py
@@ -1,124 +1,77 @@
import py
-from rpython.rlib import jit
-from rpython.annotator import model as annmodel
-from rpython.rtyper.extregistry import ExtRegistryEntry
from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
+from rpython.translator.c.support import cdecl
-class SandboxExternalFunc(object):
- def __init__(self, cfuncname):
- self.cfuncname = cfuncname
-
-
-def make_sandbox_trampoline(translator, fnname, args_s, s_result):
- """Create a trampoline function with the specified signature.
+def register_rsandbox_func(database, ll_func, fnname):
+ """Register a trampoline function for the given ll_func
+ and return its name.
The trampoline is meant to be used in place of real calls to the external
- function named 'fnname'. Instead, it calls a function pointer that is
+ function named 'fnname'. It calls a function pointer that is
under control of the main C program using the sandboxed library.
"""
try:
- extfuncs, seen = translator._sandboxlib_fnnames
+ extfuncs = database._sandboxlib_fnnames
except AttributeError:
- extfuncs, seen = translator._sandboxlib_fnnames = {}, set()
+ extfuncs = database._sandboxlib_fnnames = {}
if fnname not in extfuncs:
- # map from 'fnname' to the C function doing the call
- cfuncname = fnname
- if '.' in fnname:
- cfuncname = fnname.split('.', 1)[1] # drop the part before the
'.'
- cfuncname = 'sandbox_' + cfuncname
- assert cfuncname not in seen, "duplicate name %r" % (cfuncname,)
- seen.add(cfuncname)
- sandboxfunc = SandboxExternalFunc(cfuncname)
- extfuncs[fnname] = sandboxfunc
+ extfuncs[fnname] = lltype.typeOf(ll_func)
else:
- sandboxfunc = extfuncs[fnname]
- pargs_s, s_presult = sandboxfunc.args_s, sandboxfunc.s_result
- assert len(args_s) == len(pargs_s), (
- "non-constant argument length for %r" % (fnname,))
- args_s = [annmodel.unionof(s1, s2) for (s1, s2) in zip(args_s,
pargs_s)]
- s_result = annmodel.unionof(s_result, s_presult)
- sandboxfunc.args_s = args_s
- sandboxfunc.s_result = s_result
- #
- @jit.dont_look_inside
- def execute(*args):
- return _call_sandbox(fnname, *args)
- execute.__name__ = 'sandboxed_%s' % (fnname,)
- return execute
+ FUNC = extfuncs[fnname]
+ assert lltype.typeOf(ll_func) == FUNC, (
+ "seen two sandboxed functions called %r with different "
+ "signatures:\n %r\n %r" % (fnname, FUNC, lltype.typeOf(ll_func)))
+ return 'rsandbox_' + fnname
-def _call_sandbox(fnname, *args):
- "NOT_RPYTHON"
- raise NotImplementedError
-class ExtEntry(ExtRegistryEntry):
- _about_ = _call_sandbox
+def add_sandbox_files(database, eci, targetdir):
+ c_header = ['''
+#ifndef _RSANDBOX_H_
+#define _RSANDBOX_H_
- def compute_result_annotation(self, s_fnname, *args_s):
- fnname = s_fnname.const
- translator = self.bookkeeper.annotator.translator
- sandboxfunc = translator._sandboxlib_fnnames[0][fnname]
- return sandboxfunc.s_result
+#ifndef RPY_SANDBOX_EXPORTED
+/* common definitions when including this file from an external C project */
+#define RPY_SANDBOX_EXPORTED extern
+typedef long Signed;
+typedef unsigned long Unsigned;
+#endif
- def specialize_call(self, hop):
- fnname = hop.spaceop.args[1].value
- translator = hop.rtyper.annotator.translator
- sandboxfunc = translator._sandboxlib_fnnames[0][fnname]
- args_s, s_result = sandboxfunc.args_s, sandboxfunc.s_result
- nb_args = len(args_s)
- assert len(hop.spaceop.args) == 2 + nb_args
- assert len(hop.args_r) == 1 + nb_args
- args_r = [hop.rtyper.getrepr(s) for s in args_s]
- r_result = hop.rtyper.getrepr(s_result)
+''']
+ c_source = ['''
+#include <stdlib.h>
+#include <sys/utsname.h>
+#include "rsandbox.h"
- if not hasattr(sandboxfunc, 'externalfunc'):
- externalfunc = rffi.llexternal(sandboxfunc.cfuncname,
- [r.lowleveltype for r in args_r],
- r_result.lowleveltype,
- sandboxsafe=True,
- _nowrapper=True)
- sandboxfunc.externalfunc = externalfunc
- else:
- externalfunc = sandboxfunc.externalfunc
+''']
- c_externalfunc = hop.inputconst(lltype.typeOf(externalfunc),
- externalfunc)
+ fnnames = database._sandboxlib_fnnames
+ for fnname in sorted(fnnames):
+ FUNC = fnnames[fnname]
+ rsandboxname = 'rsandbox_' + fnname
- args_v = [hop.inputarg(args_r[i], 1 + i) for i in range(nb_args)]
- hop.exception_cannot_occur()
- return hop.genop("direct_call", [c_externalfunc] + args_v,
- resulttype = r_result)
+ vardecl = cdecl(database.gettype(lltype.Ptr(FUNC)), rsandboxname)
+ c_header.append('RPY_SANDBOX_EXPORTED %s;\n' % (vardecl,))
-
-def add_sandbox_files(database, eci):
- from rpython.translator.c.support import cdecl
-
- c_header = ['#include "common_header.h"\n']
- c_source = ['#include "rsandbox.h"\n']
- fnnames = database.translator._sandboxlib_fnnames[0]
- for fnname in sorted(fnnames):
- sandboxfunc = fnnames[fnname]
- if hasattr(sandboxfunc, 'externalfunc'):
- externalfunc = sandboxfunc.externalfunc
- TP = lltype.typeOf(externalfunc)
- vardecl = cdecl(database.gettype(TP), sandboxfunc.cfuncname)
- c_header.append('RPY_SANDBOX_EXPORTED %s;\n' % (vardecl,))
- #
- emptyfuncname = 'empty_' + sandboxfunc.cfuncname
- argnames = ['a%d' % i for i in range(len(TP.TO.ARGS))]
- c_source.append("""
+ emptyfuncname = 'rsand_def_' + fnname
+ argnames = ['a%d' % i for i in range(len(FUNC.ARGS))]
+ c_source.append("""
static %s {
abort();
};
%s = %s;
-""" % (cdecl(database.gettype(TP.TO, argnames=argnames), emptyfuncname),
+""" % (cdecl(database.gettype(FUNC, argnames=argnames), emptyfuncname),
vardecl, emptyfuncname))
- import pdb;pdb.set_trace()
-
- #srcdir = py.path.local(__file__).join('..', 'src')
- #files = [
- # srcdir / 'foo.c',
- #]
- #return eci.merge(ExternalCompilationInfo(separate_module_files=files))
+ c_header.append('''
+#endif /* _RSANDBOX_H_ */
+''')
+ targetdir.join('rsandbox.c').write(''.join(c_source))
+ targetdir.join('rsandbox.h').write(''.join(c_header))
+ # ^^^ a #include "rsandbox.h" is explicitly added to forwarddecl.h
+ # from genc.py
+
+ return eci.merge(ExternalCompilationInfo(
+ separate_module_files=[targetdir.join('rsandbox.c')]))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit