[pypy-svn] r35009 - in pypy/dist/pypy: config objspace
arigo at codespeak.net
arigo at codespeak.net
Mon Nov 27 00:06:31 CET 2006
Author: arigo
Date: Mon Nov 27 00:06:10 2006
New Revision: 35009
Added:
pypy/dist/pypy/objspace/sand.py (contents, props changed)
Modified:
pypy/dist/pypy/config/pypyoption.py
Log:
Just an experiment. Not sure how useful this is, but it's fun
and not many lines of code.
Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py (original)
+++ pypy/dist/pypy/config/pypyoption.py Mon Nov 27 00:06:10 2006
@@ -21,7 +21,8 @@
pypy_optiondescription = OptionDescription("pypy", "All PyPy Options", [
OptionDescription("objspace", "Object Space Option", [
ChoiceOption("name", "Object Space name",
- ["std", "flow", "logic", "thunk", "cpy", "dump"], "std",
+ ["std", "flow", "logic", "thunk", "cpy", "dump", "sand"],
+ "std",
requires = {
"thunk": [("objspace.geninterp", False)],
"logic": [("objspace.geninterp", False),
Added: pypy/dist/pypy/objspace/sand.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/sand.py Mon Nov 27 00:06:10 2006
@@ -0,0 +1,145 @@
+"""
+Just an experiment.
+"""
+from pypy.objspace.std.objspace import StdObjSpace
+from pypy.objspace.proxy import patch_space_in_place
+from pypy.objspace.thunk import nb_forcing_args
+from pypy.interpreter.error import OperationError
+from pypy.interpreter import baseobjspace, gateway
+from pypy.tool.sourcetools import func_with_new_name
+from pypy.rlib.unroll import unrolling_iterable
+
+
+class W_Tainted(baseobjspace.W_Root):
+ def __init__(self, w_obj):
+ self.w_obj = w_obj
+
+## def getdict(self):
+## return taint(self.w_obj.getdict())
+
+## def getdictvalue_w(self, space, attr):
+## return taint(self.w_obj.getdictvalue_w(space, attr))
+
+## def getdictvalue(self, space, w_attr):
+## return taint(self.w_obj.getdictvalue(space, w_attr))
+
+## def setdictvalue(self, space, w_attr, w_value):
+## return self.w_obj.setdictvalue(space, w_attr, w_value)
+
+## ...
+
+class W_TaintBomb(baseobjspace.W_Root):
+ def __init__(self, operr):
+ self.operr = operr
+
+ def explode(self, space):
+ msg = self.operr.errorstr(space)
+ raise OperationError(space.w_TaintError, space.wrap(msg))
+
+
+def taint(w_obj):
+ if w_obj is None or isinstance(w_obj, W_Tainted):
+ return w_obj
+ else:
+ return W_Tainted(w_obj)
+taint.unwrap_spec = [gateway.W_Root]
+app_taint = gateway.interp2app(taint)
+
+def is_tainted(space, w_obj):
+ res = isinstance(w_obj, W_Tainted)
+ return space.wrap(res)
+app_is_tainted = gateway.interp2app(is_tainted)
+
+def untaint(space, w_obj, w_expectedtype):
+ if isinstance(w_obj, W_Tainted):
+ w_obj = w_obj.w_obj
+ elif isinstance(w_obj, W_TaintBomb):
+ w_obj.explode(space)
+ #if isinstance(w_expectedtype, W_Tainted):
+ # w_expectedtype = w_expectedtype.w_obj
+ w_realtype = space.type(w_obj)
+ if not space.is_w(w_realtype, w_expectedtype):
+ msg = "expected an object of type '%s', got '%s'" % (
+ w_expectedtype.getname(space, '?'),
+ w_realtype.getname(space, '?'))
+ raise OperationError(space.w_TaintError,
+ space.wrap(msg))
+ return w_obj
+app_untaint = gateway.interp2app(untaint)
+
+# ____________________________________________________________
+
+
+class SandSpace(StdObjSpace):
+
+ def __init__(self, *args, **kwds):
+ StdObjSpace.__init__(self, *args, **kwds)
+ self.w_TaintError = self.call_function(
+ self.w_type,
+ self.wrap("TaintError"),
+ self.newtuple([self.w_Exception]),
+ self.newdict())
+ w_pypymagic = self.getbuiltinmodule("pypymagic")
+ self.setattr(w_pypymagic, self.wrap('taint'),
+ self.wrap(app_taint))
+ self.setattr(w_pypymagic, self.wrap('is_tainted'),
+ self.wrap(app_is_tainted))
+ self.setattr(w_pypymagic, self.wrap('untaint'),
+ self.wrap(app_untaint))
+ patch_space_in_place(self, 'sand', proxymaker)
+
+
+Space = SandSpace
+
+
+def tainted_error(space, name):
+ msg = "operation '%s' forbidden on tainted object" % (name,)
+ raise OperationError(space.w_TaintError, space.wrap(msg))
+
+
+RegularMethods = dict.fromkeys(
+ [name for name, _, _, _ in baseobjspace.ObjSpace.MethodTable])
+
+def proxymaker(space, name, parentfn):
+ arity = nb_forcing_args[name]
+ indices = unrolling_iterable(range(arity))
+ if name in RegularMethods:
+
+ def proxy(*args_w):
+ newargs_w = ()
+ tainted = False
+ for i in indices:
+ w_arg = args_w[i]
+ if isinstance(w_arg, W_Tainted):
+ tainted = True
+ w_arg = w_arg.w_obj
+ elif isinstance(w_arg, W_TaintBomb):
+ return w_arg
+ newargs_w += (w_arg,)
+ newargs_w += args_w[arity:]
+ try:
+ w_res = parentfn(*newargs_w)
+ except OperationError, e:
+ if not tainted:
+ raise
+ return W_TaintBomb(e)
+ if tainted:
+ w_res = taint(w_res)
+ return w_res
+
+ elif arity == 0:
+ return None
+
+ else:
+
+ def proxy(*args_w):
+ for i in indices:
+ w_arg = args_w[i]
+ if isinstance(w_arg, W_Tainted):
+ tainted_error(space, name)
+ elif isinstance(w_arg, W_TaintBomb):
+ w_arg.explode(space)
+ return parentfn(*args_w)
+
+ proxy = func_with_new_name(proxy, '%s_proxy' % name)
+ return proxy
More information about the Pypy-commit
mailing list