[pypy-svn] r12558 - in pypy/dist/pypy: annotation interpreter module/builtin module/recparser objspace/flow objspace/std translator translator/test

tismer at codespeak.net tismer at codespeak.net
Thu May 19 19:29:22 CEST 2005


Author: tismer
Date: Thu May 19 19:29:22 2005
New Revision: 12558

Modified:
   pypy/dist/pypy/annotation/builtin.py
   pypy/dist/pypy/interpreter/gateway.py
   pypy/dist/pypy/interpreter/pyopcode.py
   pypy/dist/pypy/module/builtin/app_inspect.py
   pypy/dist/pypy/module/recparser/pyparser.py
   pypy/dist/pypy/objspace/flow/objspace.py
   pypy/dist/pypy/objspace/flow/specialcase.py
   pypy/dist/pypy/objspace/std/stringobject.py
   pypy/dist/pypy/translator/geninterplevel.py
   pypy/dist/pypy/translator/test/rpystone.py
   pypy/dist/pypy/translator/translator.py
Log:
issue46 resolved
issue10 resulved

- sys import works and behaves as expected

- print works in flow space, and probably many other things

- do_imports flag has vanished. The is no more any difference
  between flowing geninterp or anything else


Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py	(original)
+++ pypy/dist/pypy/annotation/builtin.py	Thu May 19 19:29:22 2005
@@ -195,9 +195,6 @@
 def time_func():
     return SomeFloat()
 
-def write_func(*args):
-    return SomeBool()
-     # XXX I would like to use SomeNone here. How?
 
 # collect all functions
 import __builtin__
@@ -236,9 +233,6 @@
 BUILTIN_ANALYZERS[time.time] = time_func
 BUILTIN_ANALYZERS[time.clock] = time_func
 
-# sys.stdout
-BUILTIN_ANALYZERS[sys.stdout.write] = write_func
-
 # annotation of low-level types
 from pypy.annotation.model import SomePtr
 from pypy.rpython import lltypes

Modified: pypy/dist/pypy/interpreter/gateway.py
==============================================================================
--- pypy/dist/pypy/interpreter/gateway.py	(original)
+++ pypy/dist/pypy/interpreter/gateway.py	Thu May 19 19:29:22 2005
@@ -508,11 +508,10 @@
     hidden_applevel = True
     use_geninterp = True    # change this to disable geninterp globally
 
-    def __init__(self, source, filename = None, modname = '__builtin__', do_imports=False):
+    def __init__(self, source, filename = None, modname = '__builtin__'):
         self.filename = filename
         self.source = source
         self.modname = modname
-        self.do_imports = do_imports
         # look at the first three lines for a NOT_RPYTHON tag
         first = source.split("\n", 3)[:3]
         for line in first:
@@ -535,6 +534,13 @@
         def appcaller(space, *args_w):
             if not isinstance(space, ObjSpace): 
                 raise TypeError("first argument must be a space instance.")
+            # redirect if the space handles this specially
+            if hasattr(space, 'specialcases'):
+                sc = space.specialcases
+                if ApplevelClass in sc:
+                    ret_w = sc[ApplevelClass](space, self, name, args_w)
+                    if ret_w is not None: # it was RPython
+                        return ret_w
             args = Arguments(space, list(args_w))
             w_func = self.wget(space, name) 
             return space.call_args(w_func, args)
@@ -612,7 +618,7 @@
         if not initfunc:
             # build it and put it into a file
             initfunc, newsrc = translate_as_module(
-                self.source, self.filename, self.modname, self.do_imports)
+                self.source, self.filename, self.modname)
             fname = cls.cache_path.join(name+".py").strpath
             f = file(fname, "w")
             print >> f, """\

Modified: pypy/dist/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyopcode.py	(original)
+++ pypy/dist/pypy/interpreter/pyopcode.py	Thu May 19 19:29:22 2005
@@ -742,20 +742,15 @@
 app = gateway.applevel(r'''
     """ applevel implementation of certain system properties, imports
     and other helpers"""
-    # import sys
-    # note that sys must be imported inside of
-    # the functions, or attributes will be
-    # bound too early by flow space!
+    import sys
     
     def sys_stdout():
-        import sys
         try: 
             return sys.stdout
         except AttributeError:
             raise RuntimeError("lost sys.stdout")
 
     def print_expr(obj):
-        import sys
         try:
             displayhook = sys.displayhook
         except AttributeError:

Modified: pypy/dist/pypy/module/builtin/app_inspect.py
==============================================================================
--- pypy/dist/pypy/module/builtin/app_inspect.py	(original)
+++ pypy/dist/pypy/module/builtin/app_inspect.py	Thu May 19 19:29:22 2005
@@ -1,4 +1,5 @@
 """
+NOT_RPYTHON
 Plain Python definition of the builtin functions related to run-time
 program introspection.
 """
@@ -82,7 +83,10 @@
     import __builtin__
     for c in type(ob).__mro__:
         if '__call__' in c.__dict__:
-            if isinstance(ob, __builtin__._instance): # old style instance!
+            # after do_imports_immediately is always true,
+            # this is no longer RPython, because _instance
+            # does not exist at compile time.
+	    if isinstance(ob, __builtin__._instance): # old style instance!
                 return getattr(ob, '__call__', None) is not None
             return True
     else:

Modified: pypy/dist/pypy/module/recparser/pyparser.py
==============================================================================
--- pypy/dist/pypy/module/recparser/pyparser.py	(original)
+++ pypy/dist/pypy/module/recparser/pyparser.py	Thu May 19 19:29:22 2005
@@ -88,7 +88,7 @@
         import compiler
         gen = compiler.pycodegen.ModuleCodeGenerator(compileAST)
         return gen.getCode() 
-""", filename=__file__, do_imports=False)
+""", filename=__file__)
 
 mycompile = app.interphook("mycompile")
 exprcompile = app.interphook("exprcompile")

Modified: pypy/dist/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/objspace.py	(original)
+++ pypy/dist/pypy/objspace/flow/objspace.py	Thu May 19 19:29:22 2005
@@ -32,8 +32,6 @@
 
     builtins_can_raise_exceptions = False
 
-    do_imports_immediately = True  # overridden in geninterplevel
-
     def initialize(self):
         import __builtin__
         self.concrete_mode = 1
@@ -62,6 +60,19 @@
         self.specialcases = {}
         #self.make_builtins()
         #self.make_sys()
+        # objects which should keep their SomeObjectness
+        self.not_really_const = {
+            Constant(sys): {
+                Constant('maxint'): True,
+                Constant('maxunicode'): True,
+                Constant('api_version'): True,
+                Constant('exit'): True,
+                Constant('exc_info'): True,
+                # this is an incomplete list of true constants.
+                # if we add much more, a dedicated class
+                # might be considered for special objects.
+                }
+            }
 
     def enter_cache_building_mode(self):
         # when populating the caches, the flow space switches to
@@ -330,7 +341,6 @@
             except UnwrapException:
                 pass
         return self.do_operation('setitem', w_obj, w_key, w_val)
-                
 
     def call_args(self, w_callable, args):
         try:
@@ -541,5 +551,27 @@
 for line in ObjSpace.MethodTable:
     make_op(*line)
 
+# override getattr for not really const objects
+
+def unspecialize(obj):
+    # turn a constant into SomeObject
+    # XXX this may become harder when the annotator gets smarter
+    # maybe we need to add a special treatment like for ovfcheck.
+    if id(0) != id(None):
+        return obj
+
+def override():
+    def getattr(self, w_obj, w_name):
+        if w_obj in self.not_really_const:
+            const_w = self.not_really_const[w_obj]
+            if w_name not in const_w:
+                w_obj = self.do_operation('simple_call',
+                                          Constant(unspecialize), w_obj)
+        return self.regular_getattr(w_obj, w_name)
+    FlowObjSpace.regular_getattr = FlowObjSpace.getattr
+    FlowObjSpace.getattr = getattr
+
+override()
+
 # ______________________________________________________________________
 # End of objspace.py

Modified: pypy/dist/pypy/objspace/flow/specialcase.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/specialcase.py	(original)
+++ pypy/dist/pypy/objspace/flow/specialcase.py	Thu May 19 19:29:22 2005
@@ -2,32 +2,23 @@
 from pypy.interpreter import pyframe, baseobjspace
 from pypy.interpreter.error import OperationError
 from pypy.objspace.flow.objspace import UnwrapException
-from pypy.objspace.flow.model import Constant
+from pypy.objspace.flow.model import Constant, Variable
 from pypy.objspace.flow.operation import OperationName, Arity
-
-def unspecialize(obj):
-    # turn a constant into SomeObject
-    # XXX this may become harder when the annotator gets smarter
-    # maybe we need to add a special function like ovfcheck.
-    if id(0) != id(None):
-        return obj
+from pypy.interpreter import pyopcode
+from pypy.interpreter.gateway import ApplevelClass
+from pypy.tool.cache import Cache
+from pypy.tool.sourcetools import NiceCompile, compile2
 
 def sc_import(space, fn, args):
     w_name, w_glob, w_loc, w_frm = args.fixedunpack(4)
-    mod = __import__(space.unwrap(w_name), space.unwrap(w_glob),
-                     space.unwrap(w_loc), space.unwrap(w_frm))
-    if mod is sys:
-        return space.do_operation('simple_call', Constant(unspecialize),
-                                  Constant(sys))
-    else:
-        return space.wrap(mod)
-
-def sc_write(space, fn, args):
-    args_w, kwds_w = args.unpack()
-    assert kwds_w == {}, "should not call %r with keyword arguments" % (fn,)
-    # make sure that we write to the basic sys.__stdout__
-    syswrite = sys.__stdout__.write
-    return space.do_operation('simple_call', Constant(syswrite), *args_w)
+    try:
+        mod = __import__(space.unwrap(w_name), space.unwrap(w_glob),
+                         space.unwrap(w_loc), space.unwrap(w_frm))
+    except UnwrapException:
+        # import * in a function gives us the locals as Variable
+        # we forbid it as a SyntaxError
+        raise SyntaxError, "RPython: import * is not allowed in functions"
+    return space.wrap(mod)
 
 def sc_operator(space, fn, args):
     args_w, kwds_w = args.unpack()
@@ -52,15 +43,45 @@
         return getattr(space, opname)(*args_w)
 
 
+# This is not a space cache.
+# It is just collecting the compiled functions from all the source snippets.
+
+class FunctionCache(Cache):
+    """A cache mapping applevel instances to dicts with simple functions"""
+
+    def _build(app):
+        """NOT_RPYTHON.
+        Called indirectly by ApplevelClass.interphook().appcaller()."""
+        dic = {}
+        first = "\n".join(app.source.split("\n", 3)[:3])
+        if "NOT_RPYTHON" in first:
+            return None
+        if app.filename is None:
+            code = py.code.Source(app.source).compile()
+        else:
+            code = NiceCompile(app.filename)(app.source)
+            dic['__file__'] = app.filename
+        dic['__name__'] = app.modname
+        exec code in dic
+        return dic
+    _build = staticmethod(_build)
+
+compiled_funcs = FunctionCache()
+
+def sc_applevel(space, app, name, args_w):
+    dic = compiled_funcs.getorbuild(app)
+    if not dic:
+        return None # signal that this is not RPython
+    func = dic[name]
+    return space.do_operation('simple_call', Constant(func), *args_w)
+
 def setup(space):
     # fn = pyframe.normalize_exception.get_function(space)
     # this is now routed through the objspace, directly.
     # space.specialcases[fn] = sc_normalize_exception
-    if space.do_imports_immediately:
-        space.specialcases[__import__] = sc_import
-    # support sys.stdout
-    space.specialcases[sys.stdout.write] = sc_write
-    space.specialcases[sys.__stdout__.write] = sc_write
+    space.specialcases[__import__] = sc_import
+    # redirect ApplevelClass for print et al.
+    space.specialcases[ApplevelClass] = sc_applevel
     # turn calls to built-in functions to the corresponding operation,
     # if possible
     for fn in OperationName:

Modified: pypy/dist/pypy/objspace/std/stringobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/stringobject.py	(original)
+++ pypy/dist/pypy/objspace/std/stringobject.py	Thu May 19 19:29:22 2005
@@ -1019,7 +1019,7 @@
                 return _formatting.format(format, (values,), values)
             else:
                 return _formatting.format(format, (values,), None)
-''', filename=__file__, do_imports=True)
+''', filename=__file__)
 
 str_translate__String_ANY_ANY = app.interphook('str_translate__String_ANY_ANY') 
 str_decode__String_ANY_ANY = app.interphook('str_decode__String_ANY_ANY') 

Modified: pypy/dist/pypy/translator/geninterplevel.py
==============================================================================
--- pypy/dist/pypy/translator/geninterplevel.py	(original)
+++ pypy/dist/pypy/translator/geninterplevel.py	Thu May 19 19:29:22 2005
@@ -50,7 +50,7 @@
 import pypy # __path__
 import py.path
 
-GI_VERSION = '1.0.6'  # bump this for substantial changes
+GI_VERSION = '1.0.7'  # bump this for substantial changes
 # ____________________________________________________________
 
 def eval_helper(self, typename, expr):
@@ -772,9 +772,6 @@
 
     def nameof_dict(self, dic):
         assert dic is not __builtins__
-        if dic is not self.entrypoint:
-            assert '__builtins__' not in dic, 'Seems to be the globals of %s' %(
-                dic.get('__name__', '?'),)
         name = self.uniquename('g%ddict' % len(dic))
         self.register_early(dic, name)
         self.initcode.append('%s = space.newdict([])' % (name,))
@@ -1087,7 +1084,8 @@
 
         if not self.translator.frozen:
             # this is only to keep the RAM consumption under control
-            del self.translator.flowgraphs[func]
+            pass # del self.translator.flowgraphs[func]
+        # got duplicate flowgraphs when doing this!
 
     def rpyfunction_body(self, func, localscope):
         try:
@@ -1441,8 +1439,7 @@
     # and put this into tools/compile_exceptions, maybe???
     dic, entrypoint = exceptions_helper()
     t = Translator(None, verbose=False, simplifying=needed_passes,
-                   builtins_can_raise_exceptions=True,
-                   do_imports_immediately=False)
+                   builtins_can_raise_exceptions=True)
     gen = GenRpy(t, entrypoint)
     gen.moddict = dic
     gen.gen_source('/tmp/look.py')
@@ -1480,8 +1477,7 @@
         entrypoint()
         
     t = Translator(test, verbose=False, simplifying=needed_passes,
-                   builtins_can_raise_exceptions=True,
-                   do_imports_immediately=False)
+                   builtins_can_raise_exceptions=True)
     gen2 = GenRpy(t)
     gen2.gen_source("/tmp/look2.py")
 
@@ -1509,7 +1505,7 @@
         pass
 
 def translate_as_module(sourcetext, filename=None, modname="app2interpexec",
-                        do_imports=False, tmpname=None):
+                        tmpname=None):
     """ compile sourcetext as a module, translating to interp level.
     The result is the init function that creates the wrapped module dict,
     together with the generated source text.
@@ -1531,13 +1527,9 @@
         code = NiceCompile(filename)(sourcetext)
     dic = {'__name__': modname}
     exec code in dic
-    #del dic['__builtins__']
     entrypoint = dic
     t = Translator(None, verbose=False, simplifying=needed_passes,
-                   builtins_can_raise_exceptions=True,
-                   do_imports_immediately=do_imports)
-    hold = sys.path
-    libdir = os.path.join(pypy.__path__[0], "lib")
+                   builtins_can_raise_exceptions=True)
     gen = GenRpy(t, entrypoint, modname, dic)
     if tmpname:
         _file = file
@@ -1546,6 +1538,7 @@
         tmpname = 'nada'
     out = _file(tmpname, 'w')
     gen.f = out
+    libdir = os.path.join(pypy.__path__[0], "lib")
     hold = sys.path[:]
     sys.path.insert(0, libdir)
     gen.gen_source(tmpname, file=_file)

Modified: pypy/dist/pypy/translator/test/rpystone.py
==============================================================================
--- pypy/dist/pypy/translator/test/rpystone.py	(original)
+++ pypy/dist/pypy/translator/test/rpystone.py	Thu May 19 19:29:22 2005
@@ -54,9 +54,7 @@
 class G:pass
 g = G()
 
-# import sys
-# we cannot import sys here
-# because flow space must produce a late lookup
+import sys
 
 from time import clock
 
@@ -84,10 +82,9 @@
 def main(loops=LOOPS):
     benchtime, stones = pystones(abs(loops))
     if loops >= 0:
-        import sys
-        sys.stdout.write("Pystone(%s) time for %d passes = %g\n" % \
-              (__version__, loops, benchtime) )
-        sys.stdout.write("This machine benchmarks at %g pystones/second\n" % stones)
+        print "Pystone(%s) time for %d passes = %g" % \
+              (__version__, loops, benchtime)
+        print "This machine benchmarks at %g pystones/second" % stones
 
 
 def pystones(loops=LOOPS):
@@ -277,13 +274,11 @@
     return FALSE
 
 def error(msg):
-    import sys
-    sys.stderr.write(msg+" ")
-    sys.stderr.write("usage: %s [number_of_loops]\n" % sys.argv[0])
+    print >> sys.stderr, msg,
+    print >> sys.stderr, "usage: %s [number_of_loops]" % sys.argv[0]
     sys.exit(100)
 
 def entrypoint(loops=None):
-    import sys
     if loops is None:
         loops = LOOPS  # initialize early, for slow space
         nargs = len(sys.argv) - 1

Modified: pypy/dist/pypy/translator/translator.py
==============================================================================
--- pypy/dist/pypy/translator/translator.py	(original)
+++ pypy/dist/pypy/translator/translator.py	Thu May 19 19:29:22 2005
@@ -22,13 +22,11 @@
 class Translator:
 
     def __init__(self, func=None, verbose=False, simplifying=True,
-                 builtins_can_raise_exceptions=False,
-                 do_imports_immediately=True):
+                 builtins_can_raise_exceptions=False):
         self.entrypoint = func
         self.verbose = verbose
         self.simplifying = simplifying
         self.builtins_can_raise_exceptions = builtins_can_raise_exceptions
-        self.do_imports_immediately = do_imports_immediately
         self.clear()
 
     def clear(self):
@@ -58,7 +56,6 @@
             assert not self.frozen
             space = FlowObjSpace()
             space.builtins_can_raise_exceptions = self.builtins_can_raise_exceptions
-            space.do_imports_immediately = self.do_imports_immediately
             graph = space.build_flow(func)
             if self.simplifying:
                 simplify_graph(graph, self.simplifying)



More information about the Pypy-commit mailing list