Author: Ronan Lamy <[email protected]>
Branch: less-stringly-ops
Changeset: r66771:3a5b76cb6051
Date: 2013-09-01 13:50 +0100
http://bitbucket.org/pypy/pypy/changeset/3a5b76cb6051/
Log: Move implementation of FlowObjSpace.getattr() to op.getatttr
diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py
--- a/rpython/flowspace/objspace.py
+++ b/rpython/flowspace/objspace.py
@@ -11,7 +11,7 @@
from rpython.flowspace.model import (Constant, Variable, WrapException,
UnwrapException, checkgraph, const, FSException)
from rpython.flowspace.bytecode import HostCode
-from rpython.flowspace.operation import op
+from rpython.flowspace.operation import op, NOT_REALLY_CONST
from rpython.flowspace.flowcontext import (FlowSpaceFrame, fixeggblocks,
FlowingError)
from rpython.flowspace.generator import (tweak_generator_graph,
@@ -21,22 +21,6 @@
from rpython.rlib import rstackovf
-# the following gives us easy access to declare more for applications:
-NOT_REALLY_CONST = {
- Constant(sys): {
- Constant('maxint'): True,
- Constant('maxunicode'): True,
- Constant('api_version'): True,
- Constant('exit'): True,
- Constant('exc_info'): True,
- Constant('getrefcount'): True,
- Constant('getdefaultencoding'): True,
- # this is an incomplete list of true constants.
- # if we add much more, a dedicated class
- # might be considered for special objects.
- }
- }
-
# built-ins that can always raise exceptions
builtins_exceptions = {
int: [ValueError],
@@ -80,10 +64,7 @@
# during flow graph construction
w_NameError = 'NameError'
w_UnboundLocalError = 'UnboundLocalError'
-
specialcases = SPECIAL_CASES
- # objects which should keep their SomeObjectness
- not_really_const = NOT_REALLY_CONST
def build_flow(self, func):
return build_flow(func, self)
@@ -202,28 +183,6 @@
return const(not self.frame.guessbool(self.bool(w_obj)))
- def getattr(self, w_obj, w_name):
- # handling special things like sys
- # unfortunately this will never vanish with a unique import logic :-(
- if w_obj in self.not_really_const:
- const_w = self.not_really_const[w_obj]
- if w_name not in const_w:
- return self.frame.do_op(op.getattr(w_obj, w_name))
- if w_obj.foldable() and w_name.foldable():
- obj, name = w_obj.value, w_name.value
- try:
- result = getattr(obj, name)
- except Exception, e:
- etype = e.__class__
- msg = "getattr(%s, %s) always raises %s: %s" % (
- obj, name, etype, e)
- raise FlowingError(msg)
- try:
- return const(result)
- except WrapException:
- pass
- return self.frame.do_op(op.getattr(w_obj, w_name))
-
def import_name(self, name, glob=None, loc=None, frm=None, level=-1):
try:
mod = __import__(name, glob, loc, frm, level)
@@ -235,8 +194,8 @@
assert isinstance(w_module, Constant)
assert isinstance(w_name, Constant)
# handle sys
- if w_module in self.not_really_const:
- const_w = self.not_really_const[w_module]
+ if w_module in NOT_REALLY_CONST:
+ const_w = NOT_REALLY_CONST[w_module]
if w_name not in const_w:
return self.frame.do_op(op.getattr(w_module, w_name))
try:
diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py
--- a/rpython/flowspace/operation.py
+++ b/rpython/flowspace/operation.py
@@ -6,12 +6,29 @@
import __builtin__
import __future__
import operator
+import sys
from rpython.rlib.unroll import unrolling_iterable, _unroller
from rpython.tool.sourcetools import compile2
from rpython.flowspace.model import (Constant, WrapException, const, Variable,
SpaceOperation)
from rpython.flowspace.specialcase import register_flow_sc
+NOT_REALLY_CONST = {
+ Constant(sys): {
+ Constant('maxint'): True,
+ Constant('maxunicode'): True,
+ Constant('api_version'): True,
+ Constant('exit'): True,
+ Constant('exc_info'): True,
+ Constant('getrefcount'): True,
+ Constant('getdefaultencoding'): True,
+ # this is an incomplete list of true constants.
+ # if we add much more, a dedicated class
+ # might be considered for special objects.
+ }
+ }
+
+
class _OpHolder(object): pass
op = _OpHolder()
@@ -218,7 +235,6 @@
add_operator('format', 2, 'format', pyfunc=unsupported)
add_operator('len', 1, 'len', pyfunc=len, pure=True)
add_operator('hash', 1, 'hash', pyfunc=hash)
-add_operator('getattr', 2, 'getattr', pyfunc=getattr, pure=True)
add_operator('setattr', 3, 'setattr', pyfunc=setattr)
add_operator('delattr', 2, 'delattr', pyfunc=delattr)
add_operator('getitem', 2, 'getitem', pure=True)
@@ -323,13 +339,43 @@
return w_item
op.next = Next
+class GetAttr(HLOperation):
+ opname = 'getattr'
+ arity = 2
+ can_overflow = False
+ canraise = []
+ pyfunc = staticmethod(getattr)
+
+ def constfold(self):
+ w_obj, w_name = self.args
+ # handling special things like sys
+ if (w_obj in NOT_REALLY_CONST and
+ w_name not in NOT_REALLY_CONST[w_obj]):
+ return
+ if w_obj.foldable() and w_name.foldable():
+ obj, name = w_obj.value, w_name.value
+ try:
+ result = getattr(obj, name)
+ except Exception as e:
+ from rpython.flowspace.flowcontext import FlowingError
+ etype = e.__class__
+ msg = "getattr(%s, %s) always raises %s: %s" % (
+ obj, name, etype, e)
+ raise FlowingError(msg)
+ try:
+ return const(result)
+ except WrapException:
+ pass
+op.getattr = GetAttr
+
+
# Other functions that get directly translated to SpaceOperators
func2op[type] = op.type
func2op[operator.truth] = op.bool
func2op[__builtin__.iter] = op.iter
-if hasattr(__builtin__, 'next'):
- func2op[__builtin__.next] = op.next
+func2op[getattr] = op.getattr
+func2op[__builtin__.next] = op.next
for fn, oper in func2op.items():
register_flow_sc(fn)(oper.make_sc())
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit