[pypy-svn] rev 1332 - in pypy/branch/builtinrefactor/pypy: appspace interpreter interpreter/test module module/test objspace objspace/std objspace/std/attic objspace/std/test

arigo at codespeak.net arigo at codespeak.net
Wed Sep 17 13:38:07 CEST 2003


Author: arigo
Date: Wed Sep 17 13:38:03 2003
New Revision: 1332

Added:
   pypy/branch/builtinrefactor/pypy/interpreter/debug.py
   pypy/branch/builtinrefactor/pypy/interpreter/module.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/classobject_app.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/classobject_app.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/dictobject_app.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/dictobject_app.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/floatobject_app.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/floatobject_app.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/funcobject.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/funcobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/functype.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/functype.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/generatorobject.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/generatorobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/generatortype.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/generatortype.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/instmethobject.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/instmethobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/instmethtype.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/instmethtype.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/intobject_app.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/intobject_app.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/moduleobject.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/moduleobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/moduletype.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/moduletype.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/nullobject.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/nullobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/nulltype.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/nulltype.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/sliceobject_app.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/sliceobject_app.py
   pypy/branch/builtinrefactor/pypy/objspace/std/attic/stringobject_app.py   (props changed)
      - copied unchanged from rev 1322, pypy/branch/builtinrefactor/pypy/objspace/std/stringobject_app.py
Removed:
   pypy/branch/builtinrefactor/pypy/objspace/std/classobject_app.py
   pypy/branch/builtinrefactor/pypy/objspace/std/dictobject_app.py
   pypy/branch/builtinrefactor/pypy/objspace/std/floatobject_app.py
   pypy/branch/builtinrefactor/pypy/objspace/std/funcobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/functype.py
   pypy/branch/builtinrefactor/pypy/objspace/std/generatorobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/generatortype.py
   pypy/branch/builtinrefactor/pypy/objspace/std/instmethobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/instmethtype.py
   pypy/branch/builtinrefactor/pypy/objspace/std/intobject_app.py
   pypy/branch/builtinrefactor/pypy/objspace/std/moduleobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/moduletype.py
   pypy/branch/builtinrefactor/pypy/objspace/std/nullobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/nulltype.py
   pypy/branch/builtinrefactor/pypy/objspace/std/sliceobject_app.py
   pypy/branch/builtinrefactor/pypy/objspace/std/stringobject_app.py
Modified:
   pypy/branch/builtinrefactor/pypy/appspace/types.py
   pypy/branch/builtinrefactor/pypy/interpreter/baseobjspace.py
   pypy/branch/builtinrefactor/pypy/interpreter/error.py
   pypy/branch/builtinrefactor/pypy/interpreter/eval.py
   pypy/branch/builtinrefactor/pypy/interpreter/extmodule.py
   pypy/branch/builtinrefactor/pypy/interpreter/function.py
   pypy/branch/builtinrefactor/pypy/interpreter/gateway.py
   pypy/branch/builtinrefactor/pypy/interpreter/generator.py
   pypy/branch/builtinrefactor/pypy/interpreter/main.py
   pypy/branch/builtinrefactor/pypy/interpreter/miscutils.py
   pypy/branch/builtinrefactor/pypy/interpreter/nestedscope.py
   pypy/branch/builtinrefactor/pypy/interpreter/py.py
   pypy/branch/builtinrefactor/pypy/interpreter/pycode.py
   pypy/branch/builtinrefactor/pypy/interpreter/pyframe.py
   pypy/branch/builtinrefactor/pypy/interpreter/pyopcode.py
   pypy/branch/builtinrefactor/pypy/interpreter/test/test_interpreter.py
   pypy/branch/builtinrefactor/pypy/interpreter/test/test_main.py
   pypy/branch/builtinrefactor/pypy/interpreter/test/test_objspace.py
   pypy/branch/builtinrefactor/pypy/interpreter/unittest_w.py
   pypy/branch/builtinrefactor/pypy/module/builtin.py
   pypy/branch/builtinrefactor/pypy/module/sysmodule.py
   pypy/branch/builtinrefactor/pypy/module/test/test_builtin.py
   pypy/branch/builtinrefactor/pypy/module/test/test_sysmodule.py
   pypy/branch/builtinrefactor/pypy/objspace/std/cpythonobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/dictobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/dicttype.py
   pypy/branch/builtinrefactor/pypy/objspace/std/floatobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/intobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/listobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/multimethod.py
   pypy/branch/builtinrefactor/pypy/objspace/std/objspace.py
   pypy/branch/builtinrefactor/pypy/objspace/std/register_all.py
   pypy/branch/builtinrefactor/pypy/objspace/std/sliceobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/slicetype.py
   pypy/branch/builtinrefactor/pypy/objspace/std/stringobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/test/test_dictobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/test/test_instmethobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/test/test_sliceobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/tupleobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/typeobject.py
   pypy/branch/builtinrefactor/pypy/objspace/std/typetype.py
   pypy/branch/builtinrefactor/pypy/objspace/trivial.py
Log:
Big "final" check-in in this branch.
Individual comments about changes will be made during the merge.


Modified: pypy/branch/builtinrefactor/pypy/appspace/types.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/appspace/types.py	(original)
+++ pypy/branch/builtinrefactor/pypy/appspace/types.py	Wed Sep 17 13:38:03 2003
@@ -4,7 +4,7 @@
 
 Types that are part of optional modules (e.g. array) are not listed.
 """
-from __future__ import generators
+#from __future__ import generators
 
 import sys
 
@@ -101,4 +101,4 @@
 
 #DictProxyType = type(TypeType.__dict__)
 
-del sys, _f, _C, _x, generators                  # Not for export
+del sys, _f, _C, _x#, generators                  # Not for export

Modified: pypy/branch/builtinrefactor/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/baseobjspace.py	Wed Sep 17 13:38:03 2003
@@ -53,8 +53,7 @@
         self.sys._setmodule(self.w_sys)
 
     # XXX get rid of this. 
-    def get_builtin_module(self, w_name):
-        name = self.unwrap(w_name)
+    def get_builtin_module(self, name):
         if name == '__builtin__':
             return self.w_builtin
         elif name == 'sys':
@@ -301,7 +300,5 @@
 #      newstring([w_1, w_2,...]) -> w_string from ascii numbers (bytes)
 # newdict([(w_key,w_value),...]) -> w_dict
 # newslice(w_start,w_stop,w_end) -> w_slice     (w_end may be a real None)
-#               newfunction(...) -> w_function
-#              newmodule(w_name) -> w_module
 #                   next(w_iter) -> w_value or raise NoValue
 #

Added: pypy/branch/builtinrefactor/pypy/interpreter/debug.py
==============================================================================
--- (empty file)
+++ pypy/branch/builtinrefactor/pypy/interpreter/debug.py	Wed Sep 17 13:38:03 2003
@@ -0,0 +1,11 @@
+"""
+PyPy-oriented interface to pdb.
+"""
+
+import pdb, sys
+
+def fire(operationerr):
+    if not operationerr.debug_tbs:
+        return
+    tb = operationerr.debug_tbs[-1]
+    pdb.post_mortem(tb)

Modified: pypy/branch/builtinrefactor/pypy/interpreter/error.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/error.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/error.py	Wed Sep 17 13:38:03 2003
@@ -1,5 +1,7 @@
 import sys
 
+AUTO_DEBUG = 1
+
 
 class PyPyError(Exception):
     "Raise this when you encounter an exceptional situation in PyPy itself."
@@ -111,6 +113,9 @@
             print >> file, exc_typename
         else:
             print >> file, exc_typename+':', exc_value
+        if AUTO_DEBUG:
+            import debug
+            debug.fire(self)
 
 
 # Utilities

Modified: pypy/branch/builtinrefactor/pypy/interpreter/eval.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/eval.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/eval.py	Wed Sep 17 13:38:03 2003
@@ -30,9 +30,9 @@
         and possibly more locals."""
         argnames, varargname, kwargname = self.signature()
         if varargname is not None:
-            argnames.append(argname)
+            argnames = argnames + [varargname]
         if kwargname is not None:
-            argnames.append(kwargname)
+            argnames = argnames + [kwargname]
         return argnames
 
 
@@ -43,13 +43,14 @@
     """A frame is an environment supporting the execution of a code object.
     Abstract base class."""
 
-    def __init__(self, space, code, w_globals, numlocals=0):
+    def __init__(self, space, code, w_globals=None, numlocals=-1):
         self.space      = space
         self.code       = code       # Code instance
         self.w_globals  = w_globals  # wrapped dict of globals
         self.w_locals   = None       # wrapped dict of locals
-        # flat list of wrapped locals
-        self.fastlocals_w = [UNDEFINED]*numlocals
+        if numlocals < 0:  # compute the minimal size based on arguments
+            numlocals = len(code.getvarnames())
+        self.fastlocals_w = [UNDEFINED]*numlocals  # flat list of wrapped locals
 
     def run(self):
         "Run the frame."
@@ -83,7 +84,7 @@
         """Initialize the fast locals from a list of values,
         where the order is according to self.code.signature()."""
         if len(scope_w) > len(self.fastlocals_w):
-            raise ValueError, "too many fastlocals"
+            raise ValueError, "new fastscope is longer than the allocated area"
         self.fastlocals_w[:len(scope_w)] = scope_w
 
     def fast2locals(self):

Modified: pypy/branch/builtinrefactor/pypy/interpreter/extmodule.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/extmodule.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/extmodule.py	Wed Sep 17 13:38:03 2003
@@ -4,34 +4,37 @@
 
 """
 
-from pypy.interpreter.gateway import DictProxy
-from pypy.interpreter.miscutils import InitializedClass
-from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter import gateway
+from pypy.interpreter.miscutils import InitializedClass, RwDictProxy
+from pypy.interpreter.module import Module
 
 
-class ExtModule(Wrappable):
+class ExtModule(Module):
     """An empty extension module.
     Non-empty extension modules are made by subclassing ExtModule."""
 
     def __init__(self, space):
-        self.space = space
-        self.w_dict = self._appdict.makedict(space, self)
+        Module.__init__(self, space, space.wrap(self.__name__))
+        
+        # to build the dictionary of the module we get all the objects
+        # accessible as 'self.xxx'. Methods are bound.
+        d = {}
+        for cls in self.__class__.__mro__:
+            for name, value in cls.__dict__.iteritems():
+                # ignore names in '_xyz'
+                if not name.startswith('_') or name.endswith('_'):
+                    if isinstance(value, gateway.Gateway):
+                        name = value.name
+                        value = value.__get__(self)  # get a Method
+                    else:
+                        if hasattr(value, '__get__'):
+                            continue  # ignore CPython functions
+                    if name not in d:
+                        d[name] = value
+        for key, value in d.iteritems():
+            space.setitem(self.w_dict, space.wrap(key), space.wrap(value))
 
     __metaclass__ = InitializedClass
     def __initclass__(cls):
-        # make sure that the class has its own appdict
-        if '_appdict' not in cls.__dict__:
-            cls._appdict = DictProxy(implicitspace=True,
-                                     implicitself=True)
-        # automatically publish all functions from this class
-        cls._appdict.exportall(cls.__dict__)
-        # automatically import all app_ functions
-        cls._appdict.importall(cls.__dict__, cls)
-
-    def __getattr__(self, attr):
-        # XXX temporary, for use by objspace.trivial and
-        # objspace.std.cpythonobject
-        try:
-            return self.__class__._appdict.content[attr]
-        except KeyError:
-            raise AttributeError, attr
+        gateway.exportall(RwDictProxy(cls))   # xxx() -> app_xxx()
+        gateway.importall(RwDictProxy(cls))   # app_xxx() -> xxx()

Modified: pypy/branch/builtinrefactor/pypy/interpreter/function.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/function.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/function.py	Wed Sep 17 13:38:03 2003
@@ -13,15 +13,13 @@
     an object space, a dictionary of globals, default arguments,
     and an arbitrary 'closure' passed to the code object."""
     
-    def __init__(self, space, code, w_globals, w_defs=None, closure=None):
+    def __init__(self, space, code, w_globals=None, defs_w=[], closure=None):
         self.space     = space
         self.func_code = code       # Code instance
         self.w_globals = w_globals  # the globals dictionary
         self.closure   = closure    # normally, list of Cell instances or None
-        if w_defs is None:
-            self.defs_w = []
-        else:
-            self.defs_w = space.unpackiterable(w_defs)  # list of w_default's
+        self.defs_w    = defs_w     # list of w_default's
+        self.__name__  = self.func_code.co_name   # XXX
 
     def call(self, w_args, w_kwds=None):
         scope_w = self.parse_args(w_args, w_kwds)
@@ -29,6 +27,7 @@
                                             self.closure)
         frame.setfastscope(scope_w)
         return frame.run()
+    pypy_call = call
 
     def parse_args(self, w_args, w_kwds=None):
         """ parse args and kwargs to initialize the frame.
@@ -46,9 +45,10 @@
         # We try to give error messages following CPython's, which are
         # very informative.
         #
-        if w_kwds is None:
+        if w_kwds is None or not space.is_true(w_kwds):
             w_kwargs = space.newdict([])
         else:
+            # space.is_true() above avoids infinite recursion copy<->parse_args
             w_kwargs = space.call_method(w_kwds, "copy")
 
         co_argcount = len(argnames) # expected formal arguments, without */**
@@ -131,13 +131,13 @@
                 msg2,
                 plural,
                 nargs)
-        raise OperationError(self.space.w_TypeError, msg)
+        raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
 
     def raise_argerr_multiple_values(self, argname):
         msg = "%s() got multiple values for keyword argument %s" % (
             self.func_code.co_name,
             argname)
-        raise OperationError(self.space.w_TypeError, msg)
+        raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
 
     def raise_argerr_unknown_kwds(self, w_kwds):
         nkwds = self.space.unwrap(self.space.len(w_kwds))
@@ -151,22 +151,65 @@
             msg = "%s() got %d unexpected keyword arguments" % (
                 self.func_code.co_name,
                 nkwds)
-        raise OperationError(self.space.w_TypeError, msg)
+        raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
+
+    def __get__(self, obj, cls=None):
+        wrap = self.space.wrap
+        if obj is not None:
+            if cls is None:
+                cls = obj.__class__
+            return Method(self.space, wrap(self), wrap(obj), wrap(cls))
+        else:
+            return Method(self.space, wrap(self), None, wrap(cls))
+
+    def pypy_get(self, w_obj, w_cls):
+        wrap = self.space.wrap
+        if not self.space.is_true(self.space.is_(w_obj, self.space.w_None)):
+            if self.space.is_true(self.space.is_(w_cls, self.space.w_None)):
+                w_cls = self.space.type(w_obj)
+            return wrap(Method(self.space, wrap(self), w_obj, w_cls))
+        else:
+            return wrap(Method(self.space, wrap(self), None, w_cls))
 
+    def __call__(self, *args_w, **kwds_w):
+        wrap = self.space.wrap
+        w_args = self.space.newtuple(args_w)
+        w_kwds = self.space.newdict([(wrap(key), w_value)
+                                     for key, w_value in kwds_w.items()])
+        return self.call(w_args, w_kwds)
+
+
+class Method(object):
+    """A method is a function bound to a specific instance or class."""
+
+    def __init__(self, space, w_function, w_instance, w_class):
+        self.space = space
+        self.w_function = w_function
+        self.w_instance = w_instance   # or None
+        self.w_class = w_class
 
-    def __get__(self, inst, cls=None):
-        # for TrivialObjSpace only !!!
-        # use the mecanisms of gateway.py otherwise
-        import sys, new
-        assert 'pypy.objspace.trivial' in sys.modules, (
-            "don't try to __get__() Function instances out of classes")
-        self.__name__ = self.func_code.co_name
-        return new.instancemethod(self, inst, cls)
-
-    def __call__(self, *args, **kwds):
-        # for TrivialObjSpace only !!!
-        # use the mecanisms of gateway.py otherwise
-        import sys, new
-        assert 'pypy.objspace.trivial' in sys.modules, (
-            "don't try to __call__() Function instances directly")
-        return self.call(args, kwds)
+    def call(self, w_args, w_kwds=None):
+        args_w = self.space.unpacktuple(w_args)
+        if self.w_instance is not None:
+            # bound method
+            args_w = [self.w_instance] + args_w
+            w_args = self.space.newtuple(args_w)
+        else:
+            # unbound method
+            if (len(args_w) >= 1 and self.space.is_true(
+                    self.space.isinstance(args_w[0], self.w_class))):
+                pass  # ok
+            else:
+                msg = ("unbound method must be called with "
+                       "instance as first argument")     # XXX fix error msg
+                raise OperationError(self.space.w_TypeError,
+                                     self.space.wrap(msg))
+        return self.space.call(self.w_function, w_args, w_kwds)
+    pypy_call = call
+
+    def __call__(self, *args_w, **kwds_w):
+        wrap = self.space.wrap
+        w_args = self.space.newtuple(args_w)
+        w_kwds = self.space.newdict([(wrap(key), w_value)
+                                     for key, w_value in kwds_w.items()])
+        return self.call(w_args, w_kwds)

Modified: pypy/branch/builtinrefactor/pypy/interpreter/gateway.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/gateway.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/gateway.py	Wed Sep 17 13:38:03 2003
@@ -2,21 +2,19 @@
 
 Gateway between app-level and interpreter-level:
 * BuiltinCode (call interp-level code from app-level)
+* Gateway     (a space-independent gateway to a Code object)
 * app2interp  (embed an app-level function into an interp-level callable)
 * interp2app  (publish an interp-level object to be visible from app-level)
-* publishall  (mass-call interp2app on a whole list of objects)
+* exportall   (mass-call interp2app on a whole dict of objects)
+* importall   (mass-call app2interp on a whole dict of objects)
 
 """
 
-#
-# XXX warning, this module is a bit scary in the number of classes that
-#     all play a similar role but in slightly different contexts
-#
-
 import types
+from weakref import WeakKeyDictionary
 from pypy.interpreter import eval, pycode
 from pypy.interpreter.baseobjspace import Wrappable, ObjSpace
-from pypy.interpreter.function import Function
+from pypy.interpreter.function import Function, Method
 
 
 class BuiltinCode(eval.Code):
@@ -25,47 +23,23 @@
     # When a BuiltinCode is stored in a Function object,
     # you get the functionality of CPython's built-in function type.
 
-    def __init__(self, func, **argflags):
+    def __init__(self, func):
         # 'implfunc' is the interpreter-level function.
-        # See below for 'argflags'.
         # Note that this uses a lot of (construction-time) introspection.
         eval.Code.__init__(self, func.__name__)
         self.func = func
-        self.argflags = argflags
         # extract the signature from the (CPython-level) code object
         tmp = pycode.PyCode(None)
         tmp._from_code(func.func_code)
         self.sig = tmp.signature()
-        if isinstance(func, types.MethodType) and func.im_self is not None:
-            argnames, varargname, kwargname = self.sig
-            argnames = argnames[1:]  # implicit hidden self argument
-            self.sig = argnames, varargname, kwargname
-        self.nargs = len(self.getvarnames())
-
-    def bind_code(self, instance):
-        """Create another version of this code object that calls 'func'
-        as a method, with implicit first argument 'instance'."""
-        return BuiltinCode(self.func.__get__(instance, instance.__class__),
-                           **self.argflags)
+        self.ismethod = False
 
     def create_frame(self, space, w_globals, closure=None):
-        return BuiltinFrame(space, self, w_globals, numlocals=self.nargs)
+        return BuiltinFrame(space, self, w_globals)
 
     def signature(self):
         return self.sig
 
-# An application-level function always implicitely expects wrapped arguments,
-# but not an interpreter-level function not. The extra keywords given to the
-# constructor of BuiltinCode describes what kind of arguments 'func' expects.
-#
-# Default signature:
-#   def func(space, w_arg1, w_arg2...)            <- plain functions
-#   def func(self, space, w_arg1, w_arg2...)      <- methods
-#
-# Flags:  (XXX need more)
-#   implicitspace=True    method with no 'space' arg. We use 'self.space'
-#   implicitself=True     the app-level doesn't see any 'self' argument
-
 
 class BuiltinFrame(eval.Frame):
     "Frame emulation for BuiltinCode."
@@ -75,8 +49,10 @@
 
     def run(self):
         argarray = self.fastlocals_w
-        if not self.code.argflags.get('implicitspace'):
-            argarray = [space] + argarray
+        if self.code.ismethod:
+            argarray = [self.space.unwrap(argarray[0])] + argarray[1:]
+        else:
+            argarray = [self.space] + argarray
         return call_with_prepared_arguments(self.space, self.code.func,
                                             argarray)
 
@@ -103,198 +79,140 @@
 
 
 class Gateway(object):
-    # General-purpose utility for the interpreter-level to create callables
-    # that transparently invoke code objects (and thus possibly interpreted
-    # app-level code).
-
-    # 'argflags' controls how the Gateway instance should decode its
-    # arguments. It only influences calls made from interpreter-level.
-    # It has the same format as BuiltinCode.argflags.
+    """General-purpose utility for the interpreter-level to create callables
+    that transparently invoke code objects (and thus possibly interpreted
+    app-level code)."""
+
+    # This is similar to a Function object, but not bound to a particular
+    # object space. During the call, the object space is either given
+    # explicitely as the first argument (for plain function), or is read
+    # from 'self.space' for methods.
 
-    def __init__(self, code, staticglobals, staticdefs=[], **argflags):
+    def __init__(self, name, code, staticglobals=None, staticdefs=[]):
+        self.name = name
         self.code = code
-        self.staticglobals = staticglobals  # a DictProxy instance
+        self.staticglobals = staticglobals
         self.staticdefs = staticdefs
-        self.argflags = argflags
-
-    def make_function(self, space, bind_instance=None, w_globals=None):
-        if w_globals is None:
-            #w_globals = space.wrap(self.staticglobals)
-            w_globals = self.staticglobals.makedict(space, bind_instance)
-        defs_w = [space.wrap(def_value) for def_value in self.staticdefs]
-        code = self.code
-        if self.argflags.get('implicitself') and isinstance(code, BuiltinCode):
-            assert bind_instance is not None, ("built-in function can only "
-                                               "be used as a method")
-            code = code.bind_code(bind_instance)
-        return Function(space, code, w_globals, defs_w)
+        self.functioncache = WeakKeyDictionary()  # map {space: Function}
 
     def __wrap__(self, space):
         # to wrap a Gateway, we first make a real Function object out of it
         # and the result is a wrapped version of this Function.
-        return space.wrap(self.make_function(space))
+        return space.wrap(self.get_function(space))
 
-    def __call__(self, space, *args, **kwds):
-        wrap = space.wrap
-        w_args = [wrap(arg) for arg in args]
-        w_kwds = space.newdict([(wrap(key), wrap(value))
-                                for key, value in kwds.items()])
-        fn = self.make_function(space)
-        return fn.call(w_args, w_kwds)
+    def __call__(self, space, *args_w, **kwds_w):
+        # to call the Gateway as a non-method, 'space' must be explicitely
+        # supplied. We build the Function object and call it.
+        fn = self.get_function(space)
+        return fn(*args_w, **kwds_w)
 
     def __get__(self, obj, cls=None):
+        # to get the Gateway as a method out of an instance, we build a
+        # Function and get it.
         if obj is None:
-            return self
-        else:
-            return BoundGateway(self, obj)
-
-
-class BoundGateway(object):
-
-    def __init__(self, gateway, obj):
-        self.gateway = gateway
-        self.obj = obj
-
-    def __call__(self, *args, **kwds):
-        if self.gateway.argflags.get('implicitspace'):
-            # we read 'self.space' from the object we are bound to
-            space = self.obj.space
+            return self   # Gateways as unbound methods not implemented
         else:
-            space = args[0]  # explicit 'space' as a first argument
-            args = args[1:]
-            if not isinstance(space, ObjSpace):
-                raise TypeError, "'space' expected as first argument"
-        wrap = space.wrap
-        if self.gateway.argflags.get('implicitself'):
-            pass  # app-space gets no 'self' argument
-        else:
-            args = (wrap(self.obj),) + args  # insert 'w_self'
-        w_args = [wrap(arg) for arg in args]
-        w_kwds = space.newdict([(wrap(key), wrap(value))
-                                for key, value in kwds.items()])
-        fn = self.gateway.make_function(space, self.obj)
-        return fn.call(w_args, w_kwds)
-
-
-class DictProxy(Wrappable):
-    # This class exposes at app-level a read-only dict-like interface.
-    # The items in the DictProxy are not wrapped (they are independent
-    # of any object space, and are just interpreter-level objects) until
-    # app-level code reads them.
-
-    # Instances of DictProxy play the role of the 'globals' for app-level
-    # helpers. This is why app2interp and interp2app are methods of
-    # DictProxy. Calling them on the same DictProxy for several functions
-    # gives all these functions the same 'globals', allowing them to see
-    # and call each others.
-
-    # XXX a detail has been (temporarily?) changed because too many
-    # places (notably in pyopcode.py) assume that the globals should
-    # satisfy 'instance(globals, dict)'. Now wrapping a DictProxy
-    # gives you a real dict.
-
-    def __init__(self, basedict=None, **defaultargflags):
-        if basedict is None:
-            self.content = {}
-        else:
-            self.content = basedict.content.copy()
-        self.defaultargflags = defaultargflags
-
-    #def __getitem__(self, key):
-    #    return self.content[key]
-    #
-    #def __iter__(self):
-    #    return iter(self.content)
-    def __wrap__(self, space):
-        return self.makedict(space)
-
-    def app2interp(self, app, app_name=None, **argflags):
-        """Build a Gateway that calls 'app' at app-level and insert it
-        into the DictProxy."""
-        # app must be a function whose name starts with 'app_'
-        if not isinstance(app, types.FunctionType):
-            raise TypeError, "function expected, got %r instead" % app
-        if app_name is None:
-            if not app.func_name.startswith('app_'):
-                raise ValueError, ("function name must start with 'app_'; "
-                                   "%r does not" % app.func_name)
-            app_name = app.func_name[4:]
-        argflags1 = self.defaultargflags.copy()
-        argflags1.update(argflags)
-        code = pycode.PyCode(None)
-        code._from_code(app.func_code)
-        staticdefs = list(app.func_defaults or ())
-        gateway = Gateway(code, self, staticdefs, **argflags1)
-        self.content[app_name] = gateway
-        return gateway
-
-    def interp2app(self, f, **argflags):
-        """Insert an interp-level function into the DictProxy to make
-        it callable from app-level."""
-        # f must be a function whose name does NOT starts with 'app_'
-        if not isinstance(f, types.FunctionType):
-            raise TypeError, "function expected, got %r instead" % f
-        assert not f.func_name.startswith('app_'), (
-            "function name %r suspiciously starts with 'app_'" % f.func_name)
-        argflags1 = self.defaultargflags.copy()
-        argflags1.update(argflags)
-        builtincode = BuiltinCode(f, **argflags1)
-        staticdefs = list(f.func_defaults or ())
-        gateway = Gateway(builtincode, self, staticdefs, **argflags1)
-        self.content[f.func_name] = gateway
-
-    def exportname(self, name, obj, optional=0):
-        """Publish an object of the given name by inserting it into the
-        DictProxy. See implementation for the known types of 'obj'."""
-        if name.startswith('app_'):
-            publicname = name[4:]
-            optional = 0
-        else:
-            publicname = name
-        if isinstance(obj, types.FunctionType):
-            assert name == obj.func_name
-            if name == publicname:
-                # an interpreter-level function
-                self.interp2app(obj)
+            # the object space is implicitely fetched out of the instance
+            fn = self.get_function(obj.space)
+            self.code.ismethod = True   # that's a hack all right
+            return fn.__get__(obj, cls)
+
+    def get_function(self, space):
+        try:
+            return self.functioncache[space]
+        except KeyError:
+            # the construction is supposed to be done only once in advance,
+            # but must be done lazily when needed only, because
+            #   1) it depends on the object space
+            #   2) the w_globals must not be built before the underlying
+            #      staticglobals is completely initialized, because
+            #      w_globals must be built only once for all the Gateway
+            #      instances of staticglobals
+            if self.staticglobals is None:
+                w_globals = None
             else:
-                # an app-level function
-                self.app2interp(obj)
-        elif not optional:
-            # assume a simple, easily wrappable object
-            self.content[publicname] = obj
-        # else skip the object if we cannot recognize it
-
-    def exportall(self, d):
-        """Publish every object from a dict."""
-        for name, obj in d.items():
-            # ignore names in '_xyz'
-            if not name.startswith('_') or name.endswith('_'):
-                self.exportname(name, obj, optional=1)
-
-    def importall(self, d, cls=None):
-        """Import all app_-level functions as Gateways into a dict.
-        Also import literals whose name starts with 'app_'."""
-        for name, obj in d.items():
-            if name.startswith('app_') and name[4:] not in d:
-                if isinstance(obj, types.FunctionType):
-                    # an app-level function
-                    assert name == obj.func_name
-                    obj = self.app2interp(obj)
-                else:
-                    pass  # assume a simple, easily wrappable object
-                if cls is None:
-                    d[name[4:]] = obj
+                # is there another Gateway in staticglobals for which we
+                # already have a w_globals for this space ?
+                for value in self.staticglobals.itervalues():
+                    if isinstance(value, Gateway):
+                        if space in value.functioncache:
+                            # yes, we share its w_globals
+                            fn = value.functioncache[space]
+                            w_globals = fn.w_globals
+                            break
                 else:
-                    setattr(cls, name[4:], obj)
-
-    def makedict(self, space, bind_instance=None):
-        """Turn the proxy into a normal dict.
-        Gateways to interpreter-level functions that were defined
-        with 'implicitself' are bound to 'bind_instance', so that
-        calling them from app-space will add this extra hidden argument."""
-        w_dict = space.newdict([])
-        for key, value in self.content.items():
-            if isinstance(value, Gateway):
-                value = value.make_function(space, bind_instance, w_dict)
-            space.setitem(w_dict, space.wrap(key), space.wrap(value))
-        return w_dict
+                    # no, we build all Gateways in the staticglobals now.
+                    w_globals = build_dict(self.staticglobals, space)
+            return self.build_function(space, w_globals)
+
+    def build_function(self, space, w_globals):
+        if space in self.functioncache:
+            fn = self.functioncache[space]
+        else:
+            defs_w = [space.wrap(def_value) for def_value in self.staticdefs]
+            fn = Function(space, self.code, w_globals, defs_w)
+            self.functioncache[space] = fn
+        return fn
+
+
+def app2interp(app, app_name=None):
+    """Build a Gateway that calls 'app' at app-level."""
+    # app must be a function whose name starts with 'app_'.
+    if not isinstance(app, types.FunctionType):
+        if isinstance(app, Gateway):
+            return app
+        raise TypeError, "function expected, got %r instead" % app
+    if app_name is None:
+        if not app.func_name.startswith('app_'):
+            raise ValueError, ("function name must start with 'app_'; "
+                               "%r does not" % app.func_name)
+        app_name = app.func_name[4:]
+    code = pycode.PyCode(None)
+    code._from_code(app.func_code)
+    staticglobals = app.func_globals
+    staticdefs = list(app.func_defaults or ())
+    return Gateway(app_name, code, staticglobals, staticdefs)
+
+def interp2app(f, app_name=None):
+    """Build a Gateway that calls 'f' at interp-level."""
+    # f must be a function whose name does NOT starts with 'app_'
+    if not isinstance(f, types.FunctionType):
+        if isinstance(f, Gateway):
+            return f
+        raise TypeError, "function expected, got %r instead" % f
+    if app_name is None:
+        if f.func_name.startswith('app_'):
+            raise ValueError, ("function name %r suspiciously starts "
+                               "with 'app_'" % f.func_name)
+        app_name = f.func_name
+    builtincode = BuiltinCode(f)
+    staticdefs = list(f.func_defaults or ())
+    return Gateway(app_name, builtincode, None, staticdefs)
+
+
+def exportall(d):
+    """Publish every function from a dict."""
+    for name, obj in d.items():
+        # ignore names in '_xyz'
+        if not name.startswith('_') or name.endswith('_'):
+            if isinstance(obj, types.FunctionType):
+                if 'app_'+name not in d:
+                    d['app_'+name] = interp2app(obj, name)
+
+def importall(d):
+    """Import all app_-level functions as Gateways into a dict."""
+    for name, obj in d.items():
+        if name.startswith('app_') and name[4:] not in d:
+            if isinstance(obj, types.FunctionType):
+                d[name[4:]] = app2interp(obj, name[4:])
+
+def build_dict(d, space):
+    """Search all Gateways and put them into a wrapped dictionary."""
+    w_globals = space.newdict([])
+    for value in d.itervalues():
+        if isinstance(value, Gateway):
+            fn = value.build_function(space, w_globals)
+            w_name = space.wrap(value.name)
+            w_object = space.wrap(fn)
+            space.setitem(w_globals, w_name, w_object)
+    return w_globals

Modified: pypy/branch/builtinrefactor/pypy/interpreter/generator.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/generator.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/generator.py	Wed Sep 17 13:38:03 2003
@@ -2,6 +2,7 @@
 from pypy.interpreter.baseobjspace import NoValue
 from pypy.interpreter.eval import Frame
 from pypy.interpreter.pyframe import ControlFlowException, ExitFrame
+from pypy.interpreter import function, gateway
 
 #
 # Generator support. Note that GeneratorFrame is not a subclass of PyFrame.
@@ -18,7 +19,7 @@
     def run(self):
         "Build a generator-iterator."
         self.exhausted = False
-        return GeneratorIterator(self)
+        return self.space.wrap(GeneratorIterator(self))
 
     ### extra opcodes ###
 
@@ -39,10 +40,14 @@
     "An iterator created by a generator."
     
     def __init__(self, frame):
+        self.space = frame.space
         self.frame = frame
         self.running = False
 
-    def nextvalue(self):
+    def pypy_iter(self):
+        return self.space.wrap(self)
+
+    def pypy_next(self):
         # raise NoValue when exhausted
         if self.running:
             space = self.frame.space
@@ -56,19 +61,31 @@
         finally:
             self.running = False
 
-
-    # XXX trick for trivialobjspace
-    # XXX make these __iter__() and next() app-visible
-
-    def __iter__(self):
-        return self
-
     def next(self):
-        # XXX trivialobjspace only !!
         try:
-            return self.nextvalue()
+            return self.pypy_next()
         except NoValue:
-            raise StopIteration
+            raise OperationError(self.space.w_StopIteration,
+                                 self.space.w_None)
+    app_next = gateway.interp2app(next)
+
+    def pypy_getattr(self, w_attr):
+        # XXX boilerplate that should disappear at some point
+        attr = self.space.unwrap(w_attr)
+        if attr == 'next':
+            return self.space.wrap(self.app_next)
+        raise OperationError(self.space.w_AttributeError, w_attr)
+
+    # XXX the following is for TrivialObjSpace only, when iteration is
+    # done by C code (e.g. when calling 'list(g())').
+    def __iter__(self):
+        class hack:
+            def next(h):
+                try:
+                    return self.pypy_next()
+                except NoValue:
+                    raise StopIteration
+        return hack()
 
 #
 # the specific ControlFlowExceptions used by generators

Modified: pypy/branch/builtinrefactor/pypy/interpreter/main.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/main.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/main.py	Wed Sep 17 13:38:03 2003
@@ -1,6 +1,6 @@
 import autopath
 from pypy.tool import option
-from pypy.interpreter import executioncontext, baseobjspace, gateway
+from pypy.interpreter import executioncontext, baseobjspace, gateway, module
 import sys, os
 
 def _run_eval_string(source, filename, space, eval):
@@ -21,8 +21,8 @@
 
         ec = executioncontext.ExecutionContext(space)
 
-        w_mainmodule = space.newmodule(space.wrap("__main__"))
-        w_globals = space.getattr(w_mainmodule, space.wrap("__dict__"))
+        mainmodule = module.Module(space, space.wrap("__main__"))
+        w_globals = mainmodule.w_dict
        
     except baseobjspace.OperationError, operationerr:
         operationerr.record_interpreter_traceback()

Modified: pypy/branch/builtinrefactor/pypy/interpreter/miscutils.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/miscutils.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/miscutils.py	Wed Sep 17 13:38:03 2003
@@ -51,6 +51,26 @@
             self.__initclass__()
 
 
+class RwDictProxy(object):
+    """A dict-like class standing for 'cls.__dict__', to work around
+    the fact that the latter is a read-only proxy for new-style classes."""
+    
+    def __init__(self, cls):
+        self.cls = cls
+
+    def __getitem__(self, attr):
+        return self.cls.__dict__[attr]
+
+    def __setitem__(self, attr, value):
+        setattr(self.cls, attr, value)
+
+    def __contains__(self, value):
+        return value in self.cls.__dict__
+
+    def items(self):
+        return self.cls.__dict__.items()
+
+
 class ThreadLocals:
     """Thread-local storage."""
 

Added: pypy/branch/builtinrefactor/pypy/interpreter/module.py
==============================================================================
--- (empty file)
+++ pypy/branch/builtinrefactor/pypy/interpreter/module.py	Wed Sep 17 13:38:03 2003
@@ -0,0 +1,30 @@
+"""
+Module objects.
+"""
+
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.error import OperationError
+
+
+class Module(Wrappable):
+    """A module."""
+
+    def __init__(self, space, w_name):
+        self.space = space
+        self.w_dict = space.newdict([(space.wrap('__name__'), w_name)])
+        self.w_name = w_name
+
+    def pypy_getattr(self, w_attr):
+        space = self.space
+        if space.is_true(space.eq(w_attr, space.wrap('__dict__'))):
+            return self.w_dict
+        try:
+            return space.getitem(self.w_dict, w_attr)
+        except OperationError, e:
+            if not e.match(space, space.w_KeyError):
+                raise
+            # XXX fix error message
+            raise OperationError(space.w_AttributeError, w_attr)
+
+    def pypy_setattr(self, w_attr, w_value):
+        self.space.setitem(self.w_dict, w_attr, w_value)

Modified: pypy/branch/builtinrefactor/pypy/interpreter/nestedscope.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/nestedscope.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/nestedscope.py	Wed Sep 17 13:38:03 2003
@@ -1,6 +1,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.eval import UNDEFINED
 from pypy.interpreter.pyopcode import PyInterpFrame
+from pypy.interpreter import function, pycode
 
 
 class Cell(object):
@@ -157,12 +158,12 @@
     def MAKE_CLOSURE(f, numdefaults):
         w_codeobj = f.valuestack.pop()
         codeobj = f.space.unwrap(w_codeobj)
+        assert isinstance(codeobj, pycode.PyCode)
         nfreevars = len(codeobj.co_freevars)
-        freevars = [f.valuestack.pop() for i in range(nfreevars)]
+        freevars = [f.space.unwrap(f.valuestack.pop()) for i in range(nfreevars)]
         freevars.reverse()
         defaultarguments = [f.valuestack.pop() for i in range(numdefaults)]
         defaultarguments.reverse()
-        w_defaultarguments = f.space.newtuple(defaultarguments)
-        w_func = f.space.newfunction(f.space.unwrap(w_codeobj),
-                                     f.w_globals, w_defaultarguments, freevars)
-        f.valuestack.push(w_func)
+        fn = function.Function(f.space, codeobj, f.w_globals,
+                               defaultarguments, freevars)
+        f.valuestack.push(f.space.wrap(fn))

Modified: pypy/branch/builtinrefactor/pypy/interpreter/py.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/py.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/py.py	Wed Sep 17 13:38:03 2003
@@ -3,7 +3,7 @@
 import autopath
 from pypy.tool import option
 from pypy.tool.optik import make_option
-from pypy.interpreter import main, interactive, baseobjspace
+from pypy.interpreter import main, interactive, baseobjspace, error
 import sys
 
 class Options(option.Options):
@@ -35,12 +35,12 @@
     if Options.command:
         try:
             main.run_string(Options.command[0], '<string>', space)
-        except baseobjspace.PyPyError, pypyerr:
+        except error.PyPyError, pypyerr:
             pypyerr.operationerr.print_detailed_traceback(pypyerr.space)
     elif args:
         try:
             main.run_file(args[0], space)
-        except baseobjspace.PyPyError, pypyerr:
+        except error.PyPyError, pypyerr:
             pypyerr.operationerr.print_detailed_traceback(pypyerr.space)
     else:
         go_interactive = 1

Modified: pypy/branch/builtinrefactor/pypy/interpreter/pycode.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/pycode.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/pycode.py	Wed Sep 17 13:38:03 2003
@@ -72,7 +72,7 @@
     def signature(self):
         "([list-of-arg-names], vararg-name-or-None, kwarg-name-or-None)."
         argcount = self.co_argcount
-        argnames = self.co_varnames[:argcount]
+        argnames = list(self.co_varnames[:argcount])
         if self.co_flags & CO_VARARGS:
             varargname = self.co_varnames[argcount]
             argcount += 1

Modified: pypy/branch/builtinrefactor/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/pyframe.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/pyframe.py	Wed Sep 17 13:38:03 2003
@@ -1,10 +1,9 @@
 """ PyFrame class implementation with the interpreter main loop.
 """
 
-from pypy.interpreter import eval, baseobjspace
+from pypy.interpreter import eval, baseobjspace, gateway
 from pypy.interpreter.miscutils import Stack
 from pypy.interpreter.error import OperationError
-from pypy.interpreter.gateway import DictProxy
 
 
 class PyFrame(eval.Frame):
@@ -97,6 +96,17 @@
                 break
             self.exceptionstack.pop()
 
+    ### public attributes ###
+
+    def pypy_getattr(self, w_attr):
+        # XXX surely not the Right Way to do this
+        attr = self.space.unwrap(w_attr)
+        if attr == 'f_locals':   return self.w_locals
+        if attr == 'f_globals':  return self.w_globals
+        if attr == 'f_builtins': return self.w_builtins
+        if attr == 'f_code':     return self.space.wrap(self.code)
+        raise OperationError(self.space.w_AttributeError, w_attr)
+
 
 ### Frame Blocks ###
 
@@ -182,7 +192,7 @@
     else:
         raise Exception, "?!"   # XXX
     return etype, evalue
-normalize_exception = DictProxy().app2interp(app_normalize_exception)
+normalize_exception = gateway.app2interp(app_normalize_exception)
 
 
 class FinallyBlock(FrameBlock):

Modified: pypy/branch/builtinrefactor/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/pyopcode.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/pyopcode.py	Wed Sep 17 13:38:03 2003
@@ -6,9 +6,8 @@
 
 from pypy.interpreter.baseobjspace import OperationError, NoValue
 from pypy.interpreter.eval import UNDEFINED
-from pypy.interpreter import baseobjspace, pyframe
+from pypy.interpreter import baseobjspace, pyframe, gateway, function
 from pypy.interpreter.miscutils import InitializedClass
-from pypy.interpreter.gateway import DictProxy
 
 
 class unaryoperation:
@@ -34,7 +33,6 @@
 class PyInterpFrame(pyframe.PyFrame):
     """A PyFrame that knows about interpretation of standard Python opcodes
     minus the ones related to nested scopes."""
-    appdict = DictProxy(implicitspace=True)
     
     ### opcode dispatch ###
 
@@ -195,20 +193,20 @@
         f.valuestack.push(w_result)
 
     def SLICE_0(f):
-        slice(f, None, None)
+        f.slice(None, None)
 
     def SLICE_1(f):
         w_start = f.valuestack.pop()
-        slice(f, w_start, None)
+        f.slice(w_start, None)
 
     def SLICE_2(f):
         w_end = f.valuestack.pop()
-        slice(f, None, w_end)
+        f.slice(None, w_end)
 
     def SLICE_3(f):
         w_end = f.valuestack.pop()
         w_start = f.valuestack.pop()
-        slice(f, w_start, w_end)
+        f.slice(w_start, w_end)
 
     def storeslice(f, w_start, w_end):
         w_slice = f.space.newslice(w_start, w_end, None)
@@ -217,20 +215,20 @@
         f.space.setitem(w_obj, w_slice, w_newvalue)
 
     def STORE_SLICE_0(f):
-        storeslice(f, None, None)
+        f.storeslice(None, None)
 
     def STORE_SLICE_1(f):
         w_start = f.valuestack.pop()
-        storeslice(f, w_start, None)
+        f.storeslice(w_start, None)
 
     def STORE_SLICE_2(f):
         w_end = f.valuestack.pop()
-        storeslice(f, None, w_end)
+        f.storeslice(None, w_end)
 
     def STORE_SLICE_3(f):
         w_end = f.valuestack.pop()
         w_start = f.valuestack.pop()
-        storeslice(f, w_start, w_end)
+        f.storeslice(w_start, w_end)
 
     def deleteslice(f, w_start, w_end):
         w_slice = f.space.newslice(w_start, w_end, None)
@@ -238,20 +236,20 @@
         f.space.delitem(w_obj, w_slice)
 
     def DELETE_SLICE_0(f):
-        deleteslice(f, None, None)
+        f.deleteslice(None, None)
 
     def DELETE_SLICE_1(f):
         w_start = f.valuestack.pop()
-        deleteslice(f, w_start, None)
+        f.deleteslice(w_start, None)
 
     def DELETE_SLICE_2(f):
         w_end = f.valuestack.pop()
-        deleteslice(f, None, w_end)
+        f.deleteslice(None, w_end)
 
     def DELETE_SLICE_3(f):
         w_end = f.valuestack.pop()
         w_start = f.valuestack.pop()
-        deleteslice(f, w_start, w_end)
+        f.deleteslice(w_start, w_end)
 
     def STORE_SUBSCR(f):
         "obj[subscr] = newvalue"
@@ -339,15 +337,15 @@
                 locals = prog[2]
             prog = prog[0]
         if globals is None:
-            globals = f.w_globals    # XXX should be f.f_globals
+            globals = f.f_globals
             if locals is None:
-                locals = f.w_locals  # XXX should be f.f_locals
+                locals = f.f_locals
         if locals is None:
             locals = globals
         if not isinstance(globals, dict):
             raise TypeError("exec: arg 2 must be a dictionary or None")
         elif not globals.has_key('__builtins__'):
-            globals['__builtins__'] = f.w_builtins # XXX should be f.f_builtins
+            globals['__builtins__'] = f.f_builtins
         if not isinstance(locals, dict):
             raise TypeError("exec: arg 3 must be a dictionary or None")
         # XXX - HACK to check for code object
@@ -592,9 +590,9 @@
 
     def IMPORT_STAR(f):
         w_module = f.valuestack.pop()
-        w_locals = f.getfastscope()
+        w_locals = f.getdictscope()
         import_all_from(f.space, w_module, w_locals)
-        f.setfastscope(w_locals)
+        f.setdictscope(w_locals)
 
     def IMPORT_FROM(f, nameindex):
         name = f.getname(nameindex)
@@ -703,12 +701,11 @@
 
     def MAKE_FUNCTION(f, numdefaults):
         w_codeobj = f.valuestack.pop()
+        codeobj = f.space.unwrap(w_codeobj)
         defaultarguments = [f.valuestack.pop() for i in range(numdefaults)]
         defaultarguments.reverse()
-        w_defaultarguments = f.space.newtuple(defaultarguments)
-        w_func = f.space.newfunction(f.space.unwrap(w_codeobj),
-                                     f.w_globals, w_defaultarguments)
-        f.valuestack.push(w_func)
+        fn = function.Function(f.space, codeobj, f.w_globals, defaultarguments)
+        f.valuestack.push(f.space.wrap(fn))
 
     def BUILD_SLICE(f, numargs):
         if numargs == 3:
@@ -759,7 +756,7 @@
         cls.dispatch_table = dispatch_table
 
 
-    appdict.importall(locals())
+    gateway.importall(locals())   # app_xxx() -> xxx()
 
 
 ### helpers written at the application-level ###
@@ -885,5 +882,4 @@
         raise ImportError("cannot import name '%s'" % name)
 
 
-appdict = DictProxy()
-appdict.importall(globals())   # app_xxx() -> xxx()
+gateway.importall(globals())   # app_xxx() -> xxx()

Modified: pypy/branch/builtinrefactor/pypy/interpreter/test/test_interpreter.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/test/test_interpreter.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/test/test_interpreter.py	Wed Sep 17 13:38:03 2003
@@ -7,7 +7,8 @@
     def codetest(self, source, functionname, args):
         """Compile and run the given code string, and then call its function
         named by 'functionname' with arguments 'args'."""
-        from pypy.interpreter import baseobjspace, executioncontext, pyframe, gateway
+        from pypy.interpreter import baseobjspace, executioncontext
+        from pypy.interpreter import pyframe, gateway, module
         space = self.space
 
         compile = space.builtin.compile
@@ -16,8 +17,8 @@
 
         ec = executioncontext.ExecutionContext(space)
 
-        w_tempmodule = space.newmodule(w("__temp__"))
-        w_glob = space.getattr(w_tempmodule, w("__dict__"))
+        tempmodule = module.Module(space, w("__temp__"))
+        w_glob = tempmodule.w_dict
         space.setitem(w_glob, w("__builtins__"), space.w_builtins)
 
         code = space.unwrap(w_code)
@@ -260,6 +261,12 @@
             yield 1
         g = f()
         self.assertEquals(list(g), [1])
+
+    def test_generator4(self):
+        def f():
+            yield 1
+        g = f()
+        self.assertEquals([x for x in g], [1])
         
     def test_generator_restart(self):
         def g():

Modified: pypy/branch/builtinrefactor/pypy/interpreter/test/test_main.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/test/test_main.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/test/test_main.py	Wed Sep 17 13:38:03 2003
@@ -21,7 +21,7 @@
 
 def checkoutput(expected_output,f,*args):
     space = test.objspace()
-    w_sys = space.get_builtin_module(space.wrap("sys"))
+    w_sys = space.get_builtin_module("sys")
     w_oldout = space.getattr(w_sys, space.wrap("stdout"))
     capture.reset()
     space.setattr(w_sys, space.wrap("stdout"), space.wrap(capture))

Modified: pypy/branch/builtinrefactor/pypy/interpreter/test/test_objspace.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/test/test_objspace.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/test/test_objspace.py	Wed Sep 17 13:38:03 2003
@@ -58,23 +58,5 @@
         self.failUnless(self.space.is_true(w_true))
         self.failIf(self.space.is_true(w_false))
 
-    def test_newmodule(self):
-        # a shoddy test:
-        w_mod = self.space.newmodule(self.space.wrap("mod"))
-
-    def test_newfunction(self):
-        # this tests FAR more than newfunction, but that's probably
-        # unavoidable
-        def f(x):
-            return x
-
-        from pypy.interpreter.pycode import PyCode
-        cpycode = PyCode()._from_code(f.func_code)
-        w_globals = self.space.newdict([])
-        w_defs = self.space.newtuple([])
-        w_f = self.space.newfunction(cpycode, w_globals, w_defs)
-        self.assertEqual_w(self.space.call_function(w_f, self.space.wrap(1)),
-                           self.space.wrap(1))
-    
 if __name__ == '__main__':
     test.main()

Modified: pypy/branch/builtinrefactor/pypy/interpreter/unittest_w.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/interpreter/unittest_w.py	(original)
+++ pypy/branch/builtinrefactor/pypy/interpreter/unittest_w.py	Wed Sep 17 13:38:03 2003
@@ -2,23 +2,22 @@
 
 import sys, os
 import unittest
-from pypy.interpreter.gateway import DictProxy
+from pypy.interpreter import gateway
 
 def make_testcase_class(space, tc_w):
     # XXX this is all a bit insane (but it works)
 
-    # space-independent part: collect the test methods into
-    # a DictProxy.
-    d = DictProxy(implicitspace=True)
+    # collect the test methods into a dictionary
+    w = space.wrap
+    w_dict = space.newdict([])
     for name in dir(AppTestCase):
         if ( name.startswith('assert') or name.startswith('fail')
              and name != 'failureException'):
-            d.app2interp(getattr(tc_w, name).im_func, name)
+            fn = gateway.app2interp(getattr(tc_w, name).im_func, name)
+            space.setitem(w_dict, w(name), w(fn))
 
     # space-dependent part: make an object-space-level dictionary
     # and use it to build the class.
-    w = space.wrap
-    w_dict = d.makedict(space)
     space.setitem(w_dict, w('failureException'), space.w_AssertionError)
     w_tc = space.call_function(space.w_type,
                                w('TestCase'),
@@ -44,10 +43,8 @@
             setattr(space, w_tc_attr, w_tc)
 
         f = self.testMethod.im_func
-        gateway = DictProxy(implicitspace=True).app2interp(f, f.func_name)
-        w_f = space.wrap(gateway)
-        # w_f = wrap_func(space, self.testMethod.im_func)
-        space.call_function(w_f, w_tc)
+        gway = gateway.app2interp(f, f.func_name)
+        gway(space, w_tc)
 
 
 class IntTestCase(unittest.TestCase):

Modified: pypy/branch/builtinrefactor/pypy/module/builtin.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/module/builtin.py	(original)
+++ pypy/branch/builtinrefactor/pypy/module/builtin.py	Wed Sep 17 13:38:03 2003
@@ -1,5 +1,6 @@
 from __future__ import generators
 from pypy.interpreter import executioncontext
+from pypy.interpreter.module import Module
 from pypy.interpreter.extmodule import ExtModule
 from pypy.interpreter.error import OperationError
 
@@ -13,7 +14,10 @@
     """ Template for PyPy's '__builtin__' module.
     """
     
-    app___name__ = '__builtin__'
+    __name__ = '__builtin__'
+
+    open = cpy_builtin.open
+    file = cpy_builtin.file
 
     def _actframe(self, index=-1):
         return self.space.getexecutioncontext().framestack.items[index]
@@ -33,7 +37,7 @@
         except OperationError,e:
             if not e.match(space, space.w_KeyError):
                 raise
-            w_mod = space.get_builtin_module(w_modulename)
+            w_mod = space.get_builtin_module(space.unwrap(w_modulename))
             if w_mod is not None:
                 space.setitem(space.sys.w_modules, w_modulename, w_mod)
                 return w_mod
@@ -42,11 +46,10 @@
             for path in space.sys.path:
                 f = os.path.join(path, space.unwrap(w_modulename) + '.py')
                 if os.path.exists(f):
-                    w_mod = space.newmodule(w_modulename)
+                    w_mod = space.wrap(Module(space, w_modulename))
                     space.setitem(space.sys.w_modules, w_modulename, w_mod)
                     space.setattr(w_mod, w('__file__'), w(f))
                     w_dict = space.getattr(w_mod, w('__dict__'))
-                    import sys; print >> sys.stderr, self.__class__.__dict__['execfile']
                     self.execfile(w(f), w_dict, w_dict)
                     return w_mod
             
@@ -77,7 +80,7 @@
         from pypy.interpreter.pycode import PyCode
         return space.wrap(PyCode()._from_code(c))
 
-    def app_execfile(filename, glob=None, loc=None):
+    def app_execfile(self, filename, glob=None, loc=None):
         if glob is None:
             glob = globals()
             if loc is None:
@@ -141,11 +144,11 @@
 
     # app-level functions
 
-    def app_apply(function, args, kwds={}):
+    def app_apply(self, function, args, kwds={}):
         """call a function (or other callable object) and return its result"""
         return function(*args, **kwds)
 
-    def app_map(function, *collections):
+    def app_map(self, function, *collections):
         """does 3 separate things, hence this enormous docstring.
            1.  if function is None, return a list of tuples, each with one
                item from each collection.  If the collections have different
@@ -191,7 +194,7 @@
                   return res
               idx = idx + 1
 
-    def app_filter(function, collection):
+    def app_filter(self, function, collection):
         """construct a list of those elements of collection for which function
            is True.  If function is None, then return the items in the sequence
            which are True."""
@@ -208,7 +211,7 @@
         else:
            return res
 
-    def app_zip(*collections):
+    def app_zip(self, *collections):
         """return a list of tuples, where the nth tuple contains every
            nth item of each collection.  If the collections have different
            lengths, zip returns a list as long as the shortest collection,
@@ -229,7 +232,7 @@
            idx = idx + 1
         return res
 
-    def app_reduce(function, l, *initialt):
+    def app_reduce(self, function, l, *initialt):
         """ Apply function of two arguments cumulatively to the items of
             sequence, from left to right, so as to reduce the sequence to a
             single value.  Optionally begin with an initial value."""
@@ -251,7 +254,7 @@
              break
         return initial
 
-    def app_isinstance(obj, klass_or_tuple):
+    def app_isinstance(self, obj, klass_or_tuple):
         objcls = obj.__class__
         if issubclass(klass_or_tuple.__class__, tuple):
            for klass in klass_or_tuple:
@@ -264,7 +267,7 @@
            except TypeError:
                raise TypeError, "isinstance() arg 2 must be a class or type"
 
-    def app_range(x, y=None, step=1):
+    def app_range(self, x, y=None, step=1):
         """ returns a list of integers in arithmetic position from start (defaults
             to zero) to stop - 1 by step (defaults to 1).  Use a negative step to
             get a list in decending order."""
@@ -303,7 +306,7 @@
     # min and max could be one function if we had operator.__gt__ and
     # operator.__lt__  Perhaps later when we have operator.
 
-    def app_min(*arr):
+    def app_min(self, *arr):
         """return the smallest number in a list"""
 
         if not arr:
@@ -323,7 +326,7 @@
                 min = i
         return min
 
-    def app_max(*arr):
+    def app_max(self, *arr):
         """return the largest number in a list"""
 
         if not arr:
@@ -344,7 +347,7 @@
         return max
 
 
-    def app_cmp(x, y):
+    def app_cmp(self, x, y):
         """return 0 when x == y, -1 when x < y and 1 when x > y """
         if x < y:
             return -1
@@ -353,7 +356,7 @@
         else:
             return 1
 
-    def app_vars(*obj):
+    def app_vars(self, *obj):
         """return a dictionary of all the attributes currently bound in obj.  If
         called with no argument, return the variables bound in local scope."""
 
@@ -367,7 +370,7 @@
             except AttributeError:
                 raise TypeError, "vars() argument must have __dict__ attribute"
 
-    def app_hasattr(ob, attr):
+    def app_hasattr(self, ob, attr):
         try:
             getattr(ob, attr)
             return True
@@ -375,7 +378,7 @@
             return False
 
 
-    def app_xrange(start, stop=None, step=1):
+    def app_xrange(self, start, stop=None, step=1):
         class xrange:
             def __init__(self, start, stop=None, step=1):
                 if stop is None: 

Modified: pypy/branch/builtinrefactor/pypy/module/sysmodule.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/module/sysmodule.py	(original)
+++ pypy/branch/builtinrefactor/pypy/module/sysmodule.py	Wed Sep 17 13:38:03 2003
@@ -7,10 +7,10 @@
 class Sys(ExtModule):
     """ Template for PyPy's 'sys' module.
 
-    Currently we only provide 'path', 'modules', 'stdout' and 'displayhook'
+    Currently we only provide a handful of attributes.
     """
 
-    app___name__ = 'sys'
+    __name__ = 'sys'
 
     def __init__(self, space):
         opd = os.path.dirname
@@ -22,6 +22,7 @@
 
     stdout = cpy_sys.stdout
     stderr = cpy_sys.stderr
+    maxint = cpy_sys.maxint
 
     def _setmodule(self, w_module):
         """ put a module into the modules list """
@@ -31,7 +32,7 @@
     def displayhook(self, w_x):
         space = self.space
         w = space.wrap
-        if w_x != space.w_None:
+        if not space.is_true(space.is_(w_x, space.w_None)):
             try:
                 print space.unwrap(self.space.repr(w_x))
             except OperationError:

Modified: pypy/branch/builtinrefactor/pypy/module/test/test_builtin.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/module/test/test_builtin.py	(original)
+++ pypy/branch/builtinrefactor/pypy/module/test/test_builtin.py	Wed Sep 17 13:38:03 2003
@@ -7,10 +7,10 @@
         self.space = test.objspace()
     
     def test_import(self):
-        import types
         d = {}
-        m = __import__('quopri', d, d, [])
-        self.assertEquals(type(m), types.ModuleType)
+        m = __import__('types', d, d, [])
+        self.assertEquals(m.IntType, type(123))
+        self.assertEquals(m.__name__, "types")
 
     def test_chr(self):
         self.assertEquals(chr(65), 'A')

Modified: pypy/branch/builtinrefactor/pypy/module/test/test_sysmodule.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/module/test/test_sysmodule.py	(original)
+++ pypy/branch/builtinrefactor/pypy/module/test/test_sysmodule.py	Wed Sep 17 13:38:03 2003
@@ -4,7 +4,7 @@
 class SysTests(test.TestCase):
     def setUp(self):
         self.space = test.objspace()
-        self.sys_w = self.space.get_builtin_module(self.space.wrap("sys"))
+        self.sys_w = self.space.get_builtin_module("sys")
     def tearDown(self):
         pass
 

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/classobject_app.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/classobject_app.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,16 +0,0 @@
-
-
-class ClassType(object):
-    __slots__ = ['....']
-
-    def __init__(self, name, bases, dict):
-        self.__name__ = name
-        self.__bases__ = bases
-        self.__dict__ = dict
-
-    def __getattr__(self, attr):
-        try:
-            return self.__dict__[attr]
-        except KeyError:
-            raise AttributeError, "Class %s has no attribute %s" % (
-                self.__name__, attr)

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/cpythonobject.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/cpythonobject.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/cpythonobject.py	Wed Sep 17 13:38:03 2003
@@ -37,7 +37,9 @@
 # real-to-wrapped exceptions
 def wrap_exception(space):
     exc, value, tb = sys.exc_info()
-    raise OperationError(space.wrap(exc), space.wrap(value))
+    if exc is OperationError:
+        raise exc, value, tb   # just re-raise it
+    raise OperationError, OperationError(space.wrap(exc), space.wrap(value)), tb
 
 # in-place operators
 def inplace_pow(x1, x2):
@@ -81,11 +83,17 @@
     x1 ^= x2
     return x1
 
+def getter(o, i, c):
+    if hasattr(o, '__get__'):
+        return o.__get__(i, c)
+    else:
+        return o
+
 # regular part of the interface (minus 'next' and 'call')
 MethodImplementation = {
     'id':                 id,
     'type':               type,
-#    'issubtype':          issubclass,
+#    'issubtype':          see below,
     'repr':               repr,
     'str':                str,
     'len':                len,
@@ -93,10 +101,16 @@
     'getattr':            getattr,
     'setattr':            setattr,
     'delattr':            delattr,
+#    'getitem':            see below,
+#    'setitem':            see below,
+#    'delitem':            see below,
     'pos':                operator.pos,
     'neg':                operator.neg,
     'not_':               operator.not_,
     'abs':                operator.abs,
+    'hex':                hex,
+    'oct':                oct,
+    'ord':                ord,
     'invert':             operator.invert,
     'add':                operator.add,
     'sub':                operator.sub,
@@ -112,6 +126,8 @@
     'and_':               operator.and_,
     'or_':                operator.or_,
     'xor':                operator.xor,
+    'int':                int,
+    'float':              float,
     'inplace_add':        inplace_add,
     'inplace_sub':        inplace_sub,
     'inplace_mul':        inplace_mul,
@@ -133,22 +149,29 @@
     'ge':                 operator.ge,
     'contains':           operator.contains,
     'iter':               iter,
+    'get':                getter,
+#    'set':                setter,
+#    'delete':             deleter,
     }
 
 for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable:
     f = MethodImplementation.get(_name)
     if f:
         if _arity == 1:
-            def cpython_f(space, w_1, f=f):
+            def cpython_f(space, w_1, f=f, pypymethod='pypy_'+_name):
                 x = space.unwrap(w_1)
+                if hasattr(x, pypymethod):
+                    return getattr(x, pypymethod)()
                 try:
                     y = f(x)
                 except:
                     wrap_exception(space)
                 return space.wrap(y)
         elif _arity == 2:
-            def cpython_f(space, w_1, w_2, f=f):
+            def cpython_f(space, w_1, w_2, f=f, pypymethod='pypy_'+_name):
                 x1 = space.unwrap(w_1)
+                if hasattr(x1, pypymethod):
+                    return getattr(x1, pypymethod)(w_2)
                 x2 = space.unwrap(w_2)
                 try:
                     y = f(x1, x2)
@@ -156,8 +179,10 @@
                     wrap_exception(space)
                 return space.wrap(y)
         elif _arity == 3:
-            def cpython_f(space, w_1, w_2, w_3, f=f):
+            def cpython_f(space, w_1, w_2, w_3, f=f, pypymethod='pypy_'+_name):
                 x1 = space.unwrap(w_1)
+                if hasattr(x1, pypymethod):
+                    return getattr(x1, pypymethod)(w_2, w_3)
                 x2 = space.unwrap(w_2)
                 x3 = space.unwrap(w_3)
                 try:
@@ -234,6 +259,8 @@
 
 def next__CPython(space, w_obj):
     obj = space.unwrap(w_obj)
+    if hasattr(obj, 'pypy_next'):
+        return obj.pypy_next()
     try:
         result = obj.next()
     except StopIteration:
@@ -245,6 +272,8 @@
 def call__CPython_ANY_ANY(space, w_obj, w_arguments, w_keywords):
     # XXX temporary hack similar to objspace.trivial.call()
     callable = space.unwrap(w_obj)
+    if hasattr(callable, 'pypy_call'):
+        return callable.pypy_call(w_arguments, w_keywords)
     args = space.unwrap(w_arguments)
     keywords = space.unwrap(w_keywords)
     try:

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/dictobject.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/dictobject.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/dictobject.py	Wed Sep 17 13:38:03 2003
@@ -6,11 +6,8 @@
 """
 
 from pypy.objspace.std.objspace import *
-from dicttype import W_DictType, _no_object
+from dicttype import W_DictType
 from stringobject import W_StringObject
-from pypy.interpreter.extmodule import make_builtin_func
-
-applicationfile = StdObjSpace.AppFile(__name__)
 
 class _NoValueInCell: pass
 
@@ -106,7 +103,7 @@
     else:
         raise OperationError(space.w_TypeError,
                              space.wrap("dict() takes at most 1 argument"))
-    dict_update__Dict_Dict(space, w_dict, w_kwds)
+    space.call_method(w_dict, 'update', w_kwds)
 
 def getitem__Dict_ANY(space, w_dict, w_lookup):
     data = w_dict.non_empties()
@@ -144,9 +141,11 @@
     return iterobject.W_SeqIterObject(space, w_keys)
     
 def eq__Dict_Dict(space, w_left, w_right):
-    if len(w_left.data) != len(w_right.data):
+    dataleft = w_left.non_empties()
+    dataright = w_right.non_empties()
+    if len(dataleft) != len(dataright):
         return space.w_False
-    for w_key, cell in w_left.non_empties():
+    for w_key, cell in dataleft:
         try:
             w_rightval = space.getitem(w_right, w_key)
         except OperationError:
@@ -157,13 +156,15 @@
         
 def lt__Dict_Dict(space, w_left, w_right):
     # Different sizes, no problem
-    if len(w_left.data) < len(w_right.data):
+    dataleft = w_left.non_empties()
+    dataright = w_right.non_empties()
+    if len(dataleft) < len(dataright):
         return space.w_True
-    if len(w_left.data) > len(w_right.data):
+    if len(dataleft) > len(dataright):
         return space.w_False
 
     # Same size
-    for w_key, cell in w_left.non_empties():
+    for w_key, cell in dataleft:
         # This is incorrect, but we need to decide what comparisons on
         # dictionaries of equal size actually means
         # The Python language specification is silent on the subject
@@ -176,28 +177,6 @@
     # The dictionaries are equal. This is correct.
     return space.w_False
 
-
-def gt__Dict_Dict(space, w_left, w_right):
-    # Different sizes, no problem
-    if len(w_left.data) > len(w_right.data):
-        return space.w_True
-    if len(w_left.data) < len(w_right.data):
-        return space.w_False
-
-    # Same size
-    for w_key, cell in w_left.non_empties():
-        # This is incorrect, but we need to decide what comparisons on
-        # dictionaries of equal size actually means
-        # The Python language specification is silent on the subject
-        try:
-            w_rightval = space.getitem(w_right, w_key)
-        except OperationError:
-            return space.w_True
-        if space.is_true(space.gt(cell.w_value, w_rightval)):
-            return space.w_True
-    # The dictionaries are equal. This is correct.
-    return space.w_False
-
 def dict_copy__Dict(space, w_self):
     return W_DictObject(space, [(w_key,cell.get())
                                       for w_key,cell in
@@ -229,13 +208,6 @@
 def dict_clear__Dict(space, w_self):
     w_self.data = []
 
-def dict_update__Dict_Dict(space, w_self, w_other):
-    w_self.space.gethelper(applicationfile).call("dict_update", [w_self, w_other])
-    
-def dict_popitem__Dict(space, w_self):
-    w_item = w_self.space.gethelper(applicationfile).call("dict_popitem", [w_self])
-    return w_item
-    
 def dict_get__Dict_ANY_ANY(space, w_self, w_lookup, w_default):
     data = w_self.non_empties()
     for w_key, cell in data:
@@ -243,28 +215,4 @@
             return cell.get()
     return w_default
     
-def dict_setdefault__Dict_ANY_ANY(space, w_self, w_key, w_default):
-    w_value = w_self.space.gethelper(applicationfile).call("dict_setdefault", [w_self, w_key, w_default])
-    return w_value
-
-def dict_pop__Dict_ANY_ANY(space, w_self, w_key, w_default):
-    default = space.unwrap(w_default)
-    if default is _no_object:
-        w_value = w_self.space.gethelper(applicationfile).call("dict_pop_no_default", [w_self, w_key])
-    else:
-        w_value = w_self.space.gethelper(applicationfile).call("dict_pop_with_default", [w_self, w_key, w_default])
-    return w_value
-
-def dict_iteritems__Dict(space, w_self):
-    w_item = w_self.space.gethelper(applicationfile).call("dict_iteritems", [w_self])
-    return w_item
-
-def dict_iterkeys__Dict(space, w_self):
-    w_item = w_self.space.gethelper(applicationfile).call("dict_iterkeys", [w_self])
-    return w_item
-
-def dict_itervalues__Dict(space, w_self):
-    w_item = w_self.space.gethelper(applicationfile).call("dict_itervalues", [w_self])
-    return w_item
-
 register_all(vars(), W_DictType)

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/dictobject_app.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/dictobject_app.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,45 +0,0 @@
-
-
-def dict_update(d,o):
-    for k in o.keys():
-        d[k] = o[k]
-
-def dict_popitem(d):
-    k = d.keys()[0]
-    v = d[k]
-    del d[k]
-    return k, v
-
-def dict_get(d, k, v=None):
-    if d.has_key(k):
-        return d[k]
-    return v
-
-def dict_setdefault(d, k, v):
-    if d.has_key(k):
-        return d[k]
-    d[k] = v
-    return v
-
-def dict_pop_no_default(d, k):
-    v = d[k]
-    del d[k]
-    return v
-
-def dict_pop_with_default(d, k, v):
-    try:
-        v = d[k]
-        del d[k]
-    except KeyError:
-        pass
-    return v
-
-def dict_iteritems(d):
-    return iter(d.items())
-
-def dict_iterkeys(d):
-    return iter(d.keys())
-
-def dict_itervalues(d):
-    return iter(d.values())
-

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/dicttype.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/dicttype.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/dicttype.py	Wed Sep 17 13:38:03 2003
@@ -3,10 +3,9 @@
 """
 
 from pypy.objspace.std.objspace import *
+from pypy.interpreter import gateway
 from typeobject import W_TypeObject
 
-class _no_object: pass
-
 class W_DictType(W_TypeObject):
 
     typename = 'dict'
@@ -18,7 +17,7 @@
     dict_has_key    = MultiMethod('has_key',    2)
     dict_clear      = MultiMethod('clear',      1)
     dict_get        = MultiMethod('get',        3, defaults=(None,))
-    dict_pop        = MultiMethod('pop',        3, defaults=(_no_object,))
+    dict_pop        = MultiMethod('pop',        2, varargs=True)
     dict_popitem    = MultiMethod('popitem',    1)
     dict_setdefault = MultiMethod('setdefault', 3)
     dict_update     = MultiMethod('update',     2)
@@ -32,4 +31,53 @@
 def type_new__DictType_DictType_ANY_ANY(space, w_basetype, w_dicttype, w_args, w_kwds):
     return space.newdict([]), True
 
-register_all(vars())
+
+# default application-level implementations for some operations
+
+def app_dict_update__ANY_ANY(d, o):
+    for k in o.keys():
+        d[k] = o[k]
+
+def app_dict_popitem__ANY(d):
+    k = d.keys()[0]
+    v = d[k]
+    del d[k]
+    return k, v
+
+def app_dict_get__ANY_ANY_ANY(d, k, v=None):
+    if d.has_key(k):
+        return d[k]
+    return v
+
+def app_dict_setdefault__ANY_ANY_ANY(d, k, v):
+    if d.has_key(k):
+        return d[k]
+    d[k] = v
+    return v
+
+def app_dict_pop__ANY_ANY(d, k, default):
+    if len(default) > 1:
+        raise TypeError, "pop expected at most 2 arguments, got %d" % (
+            1 + len(default))
+    try:
+        v = d[k]
+        del d[k]
+    except KeyError, e:
+        if default:
+            return default[0]
+        else:
+            raise e
+    return v
+
+def app_dict_iteritems__ANY(d):
+    return iter(d.items())
+
+def app_dict_iterkeys__ANY(d):
+    return iter(d.keys())
+
+def app_dict_itervalues__ANY(d):
+    return iter(d.values())
+
+
+gateway.importall(globals())
+register_all(vars(), W_DictType)

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/floatobject.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/floatobject.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/floatobject.py	Wed Sep 17 13:38:03 2003
@@ -10,8 +10,6 @@
 import math
 from intobject import W_IntObject
 
-applicationfile = StdObjSpace.AppFile(__name__)
-
 class W_FloatObject(W_Object):
     """This is a reimplementation of the CPython "PyFloatObject" 
        it is assumed that the constructor takes a real Python float as
@@ -188,7 +186,7 @@
         return W_FloatObject(space, w_float.floatval)
 
 def abs__Float(space, w_float):
-    return W_FloatObject(space, fabs(w_float.floatval))
+    return W_FloatObject(space, abs(w_float.floatval))
 
 def is_true__Float(space, w_float):
     return w_float.floatval != 0.0

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/floatobject_app.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/floatobject_app.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,10 +0,0 @@
-from math import *
-
-def float_fmod(v,w):
-    return fmod(v,w)
-
-def float_floor(v):
-    return floor(v)
-
-def float_fabs(v):
-    return fabs(v)

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/funcobject.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/funcobject.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,59 +0,0 @@
-from __future__ import nested_scopes
-from pypy.objspace.std.objspace import *
-from functype import W_FuncType
-import pypy.interpreter.pyframe
-from pypy.objspace.std.instmethobject import W_InstMethObject
-
-
-class W_FuncObject(W_Object):
-    statictype = W_FuncType
-
-    def __init__(w_self, space, code, w_globals, w_defaultarguments, w_closure):
-        W_Object.__init__(w_self, space)
-        w_self.code = code
-        w_self.w_globals = w_globals
-        w_self.w_defaultarguments = w_defaultarguments
-        w_self.w_closure = w_closure
-
-
-registerimplementation(W_FuncObject)
-
-
-def unwrap__Func(space, w_function):
-    # XXX this is probably a temporary hack
-    def proxy_function(*args, **kw):
-        w_arguments = space.wrap(args)
-        w_keywords  = space.wrap(kw)
-        w_result = call__Func_ANY_ANY(space, w_function, w_arguments, w_keywords)
-        return space.unwrap(w_result)
-    # XXX no closure implemented
-    return proxy_function
-
-CO_GENERATOR = 0x0020
-
-def call__Func_ANY_ANY(space, w_function, w_arguments, w_keywords):
-    somecode = w_function.code
-    w_globals = w_function.w_globals
-    w_locals = somecode.build_arguments(space, w_arguments, w_keywords,
-                  w_defaults = w_function.w_defaultarguments,
-                  w_closure = w_function.w_closure)
-    if somecode.co_flags & CO_GENERATOR:
-        from generatorobject import W_GeneratorObject
-        from pypy.interpreter import pyframe
-        frame = pyframe.PyFrame()
-        frame.initialize(space, somecode, w_globals, w_locals)
-        w_ret = W_GeneratorObject(space, frame)
-    else:
-        w_ret = somecode.eval_code(space, w_globals, w_locals)
-    return w_ret
-
-def get__Func_ANY_ANY(space, w_function, w_instance, w_cls):
-    return W_InstMethObject(space, w_function, w_instance, w_cls)
-
-def getattr__Func_ANY(space, w_function, w_attr):
-    if space.is_true(space.eq(w_attr, space.wrap('func_code'))):
-        return space.wrap(w_function.code)
-    else:
-        raise FailedToImplement
-
-register_all(vars())

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/functype.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/functype.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,9 +0,0 @@
-from pypy.objspace.std.objspace import *
-from typeobject import W_TypeObject
-
-
-class W_FuncType(W_TypeObject):
-
-    typename = 'FunctionType'
-
-registerimplementation(W_FuncType)

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/generatorobject.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/generatorobject.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,31 +0,0 @@
-from pypy.objspace.std.objspace import *
-from generatortype import W_GeneratorType
-
-class W_GeneratorObject(W_Object):
-    statictype = W_GeneratorType
-
-    def __init__(self, space, frame):
-        self.frame = frame
-        self.running = 0
-
-registerimplementation(W_GeneratorObject)
-
-def next__Generator(space, w_gen):
-    if w_gen.running:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("generator already executing"))
-    ec = space.getexecutioncontext()
-
-    w_gen.running = 1
-    try:
-        w_ret = ec.eval_frame(w_gen.frame)
-    finally:
-        w_gen.running = 0
-
-    return w_ret
-
-
-def iter__Generator(space, w_gen):
-    return w_gen
-
-register_all(vars())

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/generatortype.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/generatortype.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,9 +0,0 @@
-from pypy.objspace.std.objspace import *
-from typeobject import W_TypeObject
-
-
-class W_GeneratorType(W_TypeObject):
-
-    typename = 'GeneratorType'
-
-registerimplementation(W_GeneratorType)

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/instmethobject.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/instmethobject.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,53 +0,0 @@
-"""
-Reviewed 03-06-21
-This object should implement both bound and unbound methods.
-Currently, the bound methods work:
-__call__   tested, OK.
-
-Unbound methods do not work yet (test is broken) at least in
-application space.  Changing this module to make them work
-would be easy: test in call__InstMeth_ANY_ANY if w_instmeth
-is None; if so, insert nothing in the arguments, but rather
-perform a typetest on the first argument.  However, this would
-not be testable until getattr on a typeobject will return an
-unbound-method, which, so far, it doesn't yet.
-"""
-
-from __future__ import nested_scopes
-from pypy.objspace.std.objspace import *
-from instmethtype import W_InstMethType
-
-
-class W_InstMethObject(W_Object):
-    statictype = W_InstMethType
-    
-    def __init__(w_self, space, w_im_func, w_im_self, w_im_class):
-        W_Object.__init__(w_self, space)
-        w_self.w_im_self = w_im_self
-        w_self.w_im_func = w_im_func
-        w_self.w_im_class = w_im_class
-
-
-registerimplementation(W_InstMethObject)
-
-def call__InstMeth_ANY_ANY(space, w_instmeth, w_args, w_keywords):
-    if w_instmeth.w_im_self == space.w_Null:
-        if space.is_true(space.eq(space.len(w_args), space.wrap(0))):
-            raise OperationError(space.w_TypeError, space.wrap('bleargh'))
-        w_self = space.getitem(w_args, space.wrap(0))
-        w_selftype = space.type(w_self)
-        w_issubtype = space.issubtype(w_selftype, w_instmeth.w_im_class)
-        if not space.is_true(w_issubtype):
-            raise OperationError(space.w_TypeError,
-                                 space.wrap("unbound method %s() must be "
-                                            "called with %s instance as first "
-                                            "argument (got %s instance instead)"))
-    else:
-        w_args = space.add(space.newtuple([w_instmeth.w_im_self]),
-                           w_args)
-    w_ret = space.call(w_instmeth.w_im_func, w_args, w_keywords)
-    return w_ret
-
-# XXX do __get__ for instance methods
-
-register_all(vars())

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/instmethtype.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/instmethtype.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,13 +0,0 @@
-"""
-Reviewed 03-06-21
-"""
-
-from pypy.objspace.std.objspace import *
-from typeobject import W_TypeObject
-
-
-class W_InstMethType(W_TypeObject):
-
-    typename = 'MethodType'
-
-registerimplementation(W_InstMethType)

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/intobject.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/intobject.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/intobject.py	Wed Sep 17 13:38:03 2003
@@ -3,8 +3,6 @@
 from noneobject import W_NoneObject
 from restricted_int import r_int, LONG_BIT
 
-applicationfile = StdObjSpace.AppFile(__name__)
-
 """
 The implementation of integers is a bit difficult,
 since integers are currently undergoing the change to turn

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/intobject_app.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/intobject_app.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1 +0,0 @@
-#empty

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/listobject.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/listobject.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/listobject.py	Wed Sep 17 13:38:03 2003
@@ -2,7 +2,8 @@
 from listtype import W_ListType
 from intobject import W_IntObject
 from sliceobject import W_SliceObject
-from pypy.interpreter.extmodule import make_builtin_func
+import slicetype
+from pypy.interpreter import gateway
 from restricted_int import r_int, r_uint
 
 
@@ -73,11 +74,8 @@
 
 def getitem__List_Slice(space, w_list, w_slice):
     items = w_list.ob_item
-    w_length = space.wrap(w_list.ob_size)
-    w_start, w_stop, w_step, w_slicelength = w_slice.indices(w_length)
-    start       = space.unwrap(w_start)
-    step        = space.unwrap(w_step)
-    slicelength = space.unwrap(w_slicelength)
+    length = w_list.ob_size
+    start, stop, step, slicelength = slicetype.indices4(space, w_slice, length)
     assert slicelength >= 0
     w_res = W_ListObject(space, [])
     _list_resize(w_res, slicelength)

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/moduleobject.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/moduleobject.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,62 +0,0 @@
-"""
-state of W_ModuleObject
-
-- old style registration
-
-getattr ok,tested
-setattr ok,tested
-delattr ok,tested
-"""
-from pypy.objspace.std.objspace import *
-from moduletype import W_ModuleType
-from dictobject import W_DictObject
-
-
-class W_ModuleObject(W_Object):
-    statictype = W_ModuleType
-
-    def __init__(w_self, space, w_name):
-        W_Object.__init__(w_self, space)
-        w_key_name = space.wrap('__name__')
-        w_key_doc  = space.wrap('__doc__')
-        items = [(w_key_name, w_name),
-                 (w_key_doc,  space.w_None)]
-        w_self.w_dict = W_DictObject(w_self.space, items)
-
-registerimplementation(W_ModuleObject)
-
-def getattr_module_any(space, w_module, w_attr):
-    if space.is_true(space.eq(w_attr, space.wrap('__dict__'))):
-        return w_module.w_dict
-    else:
-        try:
-            return space.getitem(w_module.w_dict, w_attr)
-        except OperationError, e:
-            if e.match(space, space.w_KeyError):
-                raise FailedToImplement(space.w_AttributeError)
-            else:
-                raise
-
-def setattr_module_any_any(space, w_module, w_attr, w_value):
-    if space.is_true(space.eq(w_attr, space.wrap('__dict__'))):
-        raise OperationError(space.w_TypeError,
-                             space.wrap("readonly attribute"))
-    else:
-        space.setitem(w_module.w_dict, w_attr, w_value)
-
-def delattr_module_any(space, w_module, w_attr):
-    if space.is_true(space.eq(w_attr, space.wrap('__dict__'))):
-        raise OperationError(space.w_TypeError,
-                             space.wrap("readonly attribute"))
-    else:
-        try:
-            space.delitem(w_module.w_dict, w_attr)
-        except OperationError, e:
-            if e.match(space, space.w_KeyError):
-                raise FailedToImplement(space.w_AttributeError)
-            else:
-                raise
-
-StdObjSpace.getattr.register(getattr_module_any,     W_ModuleObject, W_ANY)
-StdObjSpace.setattr.register(setattr_module_any_any, W_ModuleObject, W_ANY,W_ANY)
-StdObjSpace.delattr.register(delattr_module_any,     W_ModuleObject, W_ANY)

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/moduletype.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/moduletype.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,9 +0,0 @@
-from pypy.objspace.std.objspace import *
-from typeobject import W_TypeObject
-
-
-class W_ModuleType(W_TypeObject):
-
-    typename = 'module'
-
-registerimplementation(W_ModuleType)

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/multimethod.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/multimethod.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/multimethod.py	Wed Sep 17 13:38:03 2003
@@ -203,7 +203,7 @@
 
 
 class BoundMultiMethod:
-    #ASSERT_BASE_TYPE = None
+    ASSERT_BASE_TYPE = None
 
     def __init__(self, space, multimethod):
         self.space = space
@@ -237,11 +237,14 @@
         arity = self.multimethod.arity
         extraargs = args[arity:]
 
-##        if self.ASSERT_BASE_TYPE:
-##            for a in args[:arity]:
-##                assert issubclass(a.dispatchclass, self.ASSERT_BASE_TYPE), (
-##                    "multimethod '%s' call with non wrapped argument: %r" %
-##                    (self.multimethod.operatorsymbol, a))
+        if self.ASSERT_BASE_TYPE:
+            for a in args[:arity]:
+                assert hasattr(a, 'dispatchclass'), (
+                    "multimethod '%s' call with non wrapped argument: %r" %
+                    (self.multimethod.operatorsymbol, a))
+                assert issubclass(a.dispatchclass, self.ASSERT_BASE_TYPE), (
+                    "multimethod '%s' call with non wrapped argument: %r" %
+                    (self.multimethod.operatorsymbol, a))
 
         # look for an exact match first
         firstfailure = None

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/nullobject.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/nullobject.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,24 +0,0 @@
-"""
-  Null Object implementation
-
-  ok and tested
-""" 
-
-from pypy.objspace.std.objspace import *
-from nulltype import W_NullType
-
-class W_NullObject(W_Object):
-    statictype = W_NullType
-registerimplementation(W_NullObject)
-
-def unwrap__Null(space, w_null):
-    return Null
-
-def is_true__Null(space, w_null):
-    return False
-
-def repr__Null(space, w_null):
-    return space.wrap('Null')
-
-register_all(vars())
-

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/nulltype.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/nulltype.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,9 +0,0 @@
-from pypy.objspace.std.objspace import *
-from typeobject import W_TypeObject
-
-
-class W_NullType(W_TypeObject):
-
-    typename = 'NullType'
-
-registerimplementation(W_NullType)

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/objspace.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/objspace.py	Wed Sep 17 13:38:03 2003
@@ -1,10 +1,3 @@
-"""
-without intending to test objectspace, we discovered
-some unforeseen wrapping of PyByteCode.
-XXX further analysis needed.
-"""
-
-import pypy.interpreter.appfile
 from register_all import register_all
 from pypy.interpreter.baseobjspace import *
 from multimethod import *
@@ -23,7 +16,7 @@
 
 
 W_ANY = W_Object  # synonyms for use in .register()
-#BoundMultiMethod.ASSERT_BASE_TYPE = W_Object
+BoundMultiMethod.ASSERT_BASE_TYPE = W_Object
 MultiMethod.BASE_TYPE_OBJECT = W_AbstractTypeObject
 
 # delegation priorities
@@ -48,11 +41,6 @@
 
     PACKAGE_PATH = 'objspace.std'
 
-    class AppFile(pypy.interpreter.appfile.AppFile):
-        pass
-    AppFile.LOCAL_PATH = [PACKAGE_PATH]
-
-
     def standard_types(self):
         class result:
             "Import here the types you want to have appear in __builtin__."
@@ -72,17 +60,12 @@
 
     def clone_exception_hierarchy(self):
         from usertype import W_UserType
-        from funcobject import W_FuncObject
-        from pypy.interpreter.pycode import PyByteCode
+        from pypy.interpreter import gateway
         w = self.wrap
-        def __init__(self, *args):
+        def app___init__(self, *args):
             self.args = args
-        code = PyByteCode()
-        code._from_code(__init__.func_code)
-        w_init = W_FuncObject(self, code,
-                              self.newdict([]), self.newtuple([]), None)
-##        w_init = w(__init__) # should this work? --mwh
-        def __str__(self):
+        w_init = w(gateway.app2interp(app___init__))
+        def app___str__(self):
             l = len(self.args)
             if l == 0:
                 return ''
@@ -90,10 +73,7 @@
                 return str(self.args[0])
             else:
                 return str(self.args)
-        code = PyByteCode()
-        code._from_code(__str__.func_code)
-        w_str = W_FuncObject(self, code,
-                              self.newdict([]), self.newtuple([]), None)
+        w_str = w(gateway.app2interp(app___str__))
         import exceptions
 
         # to create types, we should call the standard type object;
@@ -146,13 +126,11 @@
                             
     def initialize(self):
         from noneobject    import W_NoneObject
-        from nullobject    import W_NullObject
         from boolobject    import W_BoolObject
         from cpythonobject import W_CPythonObject
 
         # singletons
         self.w_None  = W_NoneObject(self)
-        self.w_Null  = W_NullObject(self)
         self.w_False = W_BoolObject(self, False)
         self.w_True  = W_BoolObject(self, True)
         self.w_NotImplemented = self.wrap(NotImplemented)  # XXX do me
@@ -176,7 +154,6 @@
         for_builtins.update(self.clone_exception_hierarchy())
         
         self.make_builtins()
-        self.make_sys()
         
         # insert stuff into the newly-made builtins
         for key, w_value in for_builtins.items():
@@ -221,8 +198,9 @@
             wrappeditems = [self.wrap(item) for item in x]
             import listobject
             return listobject.W_ListObject(self, wrappeditems)
+        if hasattr(x, '__wrap__'):
+            return x.__wrap__(self)
         # print "wrapping %r (%s)" % (x, type(x))
-        # XXX unexpected wrapping of PyByteCode 
         import cpythonobject
         return cpythonobject.W_CPythonObject(self, x)
 
@@ -251,15 +229,6 @@
         import sliceobject
         return sliceobject.W_SliceObject(self, w_start, w_end, w_step)
 
-    def newfunction(self, code, w_globals, w_defaultarguments, w_closure=None):
-        import funcobject
-        return funcobject.W_FuncObject(self, code, w_globals,
-                                       w_defaultarguments, w_closure)
-
-    def newmodule(self, w_name):
-        import moduleobject
-        return moduleobject.W_ModuleObject(self, w_name)
-
     def newstring(self, chars_w):
         try:
             chars = [chr(self.unwrap(w_c)) for w_c in chars_w]

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/register_all.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/register_all.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/register_all.py	Wed Sep 17 13:38:03 2003
@@ -19,7 +19,7 @@
         namespaces.insert(0, alt_ns)
 
     for name, obj in module_dict.items():
-        if name.find('__')<1:
+        if name.find('__')<1 or name.startswith('app_'):
             continue
         funcname, sig = name.split('__')
         l=[]

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/sliceobject.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/sliceobject.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/sliceobject.py	Wed Sep 17 13:38:03 2003
@@ -6,13 +6,8 @@
 """
 
 from pypy.objspace.std.objspace import *
-from pypy.interpreter.appfile import AppFile
-from pypy.interpreter.extmodule import make_builtin_func
-from pypy.objspace.std.instmethobject import W_InstMethObject
 from slicetype import W_SliceType
 
-appfile = AppFile(__name__, ["objspace.std"])
-
 
 class W_SliceObject(W_Object):
     statictype = W_SliceType
@@ -22,15 +17,6 @@
         w_self.w_start = w_start
         w_self.w_stop = w_stop
         w_self.w_step = w_step
-    def indices(w_self, w_length):
-        # this is used internally, analogous to CPython's PySlice_GetIndicesEx
-        w_ret = w_self.space.gethelper(appfile).call("sliceindices", [w_self, w_length])
-        w_start, w_stop, w_step, w_slicelength = w_self.space.unpackiterable(w_ret, 4)
-        return w_start, w_stop, w_step, w_slicelength
-    def indices2(w_self, w_length):
-        # this is used to implement the user-visible method 'indices' of slice objects
-        return w_self.space.newtuple(w_self.indices(w_length)[:-1])
-
 
 registerimplementation(W_SliceObject)
 
@@ -51,10 +37,6 @@
             return space.w_None
         else:
             return w_slice.w_step
-    if space.is_true(space.eq(w_attr, space.wrap('indices'))):
-        w_builtinfn = make_builtin_func(space, W_SliceObject.indices2)
-        return W_InstMethObject(space, w_builtinfn, w_slice, w_slice.statictype)
-    
     raise FailedToImplement(space.w_AttributeError)
 
 register_all(vars())

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/sliceobject_app.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/sliceobject_app.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,50 +0,0 @@
-
-def sliceindices(slice, length):
-    step = slice.step
-    if step is None:
-        step = 1
-    elif step == 0:
-        raise ValueError, "slice step cannot be zero"
-    if step < 0:
-        defstart = length - 1
-        defstop = -1
-    else:
-        defstart = 0
-        defstop = length
-    
-    start = slice.start
-    if start is None:
-        start = defstart
-    else:
-        if start < 0:
-            start += length
-            if start < 0:
-                if step < 0:
-                    start = -1
-                else:
-                    start = 0
-            elif start >= length:
-                if step < 0:
-                    start = length - 1
-                else:
-                    start = length
-
-    stop = slice.stop
-    if stop is None:
-        stop = defstop
-    else:
-        if stop < 0:
-            stop += length
-        if stop < 0:
-            stop = -1
-        elif stop > length:
-            stop = length
-
-    if (step < 0 and stop >= start) or (step > 0 and start >= stop):
-        slicelength = 0
-    elif step < 0:
-        slicelength = (stop-start+1)//step + 1
-    else:
-        slicelength = (stop-start-1)//step + 1
-
-    return start, stop, step, slicelength

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/slicetype.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/slicetype.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/slicetype.py	Wed Sep 17 13:38:03 2003
@@ -1,4 +1,5 @@
 from pypy.objspace.std.objspace import *
+from pypy.interpreter import gateway
 from typeobject import W_TypeObject
 
 
@@ -6,6 +7,9 @@
 
     typename = 'slice'
 
+    slice_indices = MultiMethod('indices', 2)
+
+
 registerimplementation(W_SliceType)
 
 
@@ -31,4 +35,78 @@
                              space.wrap("slice() takes at least 1 argument"))
     return space.newslice(start, stop, step), True
 
-register_all(vars())
+
+# default application-level implementations for some operations
+
+def app_slice_indices3(slice, length):
+    # this is used internally, analogous to CPython's PySlice_GetIndicesEx
+    step = slice.step
+    if step is None:
+        step = 1
+    elif step == 0:
+        raise ValueError, "slice step cannot be zero"
+    if step < 0:
+        defstart = length - 1
+        defstop = -1
+    else:
+        defstart = 0
+        defstop = length
+
+    start = slice.start
+    if start is None:
+        start = defstart
+    else:
+        if start < 0:
+            start += length
+            if start < 0:
+                if step < 0:
+                    start = -1
+                else:
+                    start = 0
+        elif start >= length:
+            if step < 0:
+                start = length - 1
+            else:
+                start = length
+
+    stop = slice.stop
+    if stop is None:
+        stop = defstop
+    else:
+        if stop < 0:
+            stop += length
+            if stop < 0:
+                stop = -1
+        elif stop > length:
+            stop = length
+
+    return start, stop, step
+slice_indices__ANY_ANY = slice_indices3 = gateway.app2interp(app_slice_indices3)
+
+def app_slice_indices4(slice, length):
+    start, stop, step = slice_indices3(slice, length)
+
+    if (step < 0 and stop >= start) or (step > 0 and start >= stop):
+        slicelength = 0
+    elif step < 0:
+        slicelength = (stop-start+1)//step + 1
+    else:
+        slicelength = (stop-start-1)//step + 1
+
+    return start, stop, step, slicelength
+slice_indices4 = gateway.app2interp(app_slice_indices4)
+
+# utility functions
+def indices3(space, w_slice, length):
+    w_result = slice_indices3(space, w_slice, space.wrap(length))
+    w_1, w_2, w_3 = space.unpacktuple(w_result, 3)
+    return space.unwrap(w_1), space.unwrap(w_2), space.unwrap(w_3)
+
+def indices4(space, w_slice, length):
+    w_result = slice_indices4(space, w_slice, space.wrap(length))
+    w_1, w_2, w_3, w_4 = space.unpacktuple(w_result, 4)
+    return (space.unwrap(w_1), space.unwrap(w_2),
+            space.unwrap(w_3), space.unwrap(w_4))
+
+
+register_all(vars(), W_SliceType)

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/stringobject.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/stringobject.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/stringobject.py	Wed Sep 17 13:38:03 2003
@@ -75,12 +75,14 @@
 from stringtype import W_StringType
 from intobject   import W_IntObject
 from sliceobject import W_SliceObject
+import slicetype
 from listobject import W_ListObject
-from instmethobject import W_InstMethObject
 from noneobject import W_NoneObject
 from tupleobject import W_TupleObject
 
-applicationfile = StdObjSpace.AppFile(__name__)
+# XXX consider reimplementing _value to be a list of characters
+#     instead of a plain string
+
 
 class W_StringObject(W_Object):
     statictype = W_StringType
@@ -826,21 +828,14 @@
     return W_StringObject(space, str[ival])
 
 def getitem__String_Slice(space, w_str, w_slice):
-    return space.gethelper(applicationfile).call(
-        "getitem_string_slice", [w_str, w_slice])
+    # XXX this is really too slow for slices with no step argument
     w = space.wrap
-    u = space.unwrap
-    w_start, w_stop, w_step, w_sl = w_slice.indices(w(len(u(w_str._value))))
-    start = u(w_start)
-    stop = u(w_stop)
-    step = u(w_step)
-    sl = u(w_sl)
-    r = [None] * sl
-    for i in range(sl):
-        r[i] = space.getitem(w_str, w(start + i*step))
+    length = len(w_str._value)
+    start, stop, step, sl = slicetype.indices4(space, w_slice, length)
+    r = [space.getitem(w_str, w(start + i*step)) for i in range(sl)]
     w_r = space.newlist(r)
     w_empty = space.newstring([])
-    return str_join(space, w_empty, w_r)
+    return str_join__String_ANY(space, w_empty, w_r)
 
 def mul__String_Int(space, w_str, w_mul):
     u = space.unwrap

Deleted: /pypy/branch/builtinrefactor/pypy/objspace/std/stringobject_app.py
==============================================================================
--- /pypy/branch/builtinrefactor/pypy/objspace/std/stringobject_app.py	Wed Sep 17 13:38:03 2003
+++ (empty file)
@@ -1,6 +0,0 @@
-def getitem_string_slice(str, sliceob):
-     r = []
-     for i in range(*sliceob.indices(len(str))):
-         r.append(str[i])
-     return ''.join(r)
-

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/test/test_dictobject.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/test/test_dictobject.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/test/test_dictobject.py	Wed Sep 17 13:38:03 2003
@@ -61,6 +61,35 @@
        cell = space.unwrap(d.cell(space,wk2))
        self.assertEqual_w(cell.get(),space.wrap(2))
 
+    def test_empty_cell(self):
+        space = self.space
+        d = W_DictObject(space,
+                         [(space.wrap('colour'), space.wrap(0)),
+                          (space.wrap('of'),     space.wrap(2)),
+                          (space.wrap('magic'),  space.wrap(1))])
+        w_cell = d.cell(space, space.wrap('of'))
+        d2 = W_DictObject(space,
+                          [(space.wrap('colour'), space.wrap(0)),
+                           (space.wrap('magic'),  space.wrap(1))])
+        self.assertNotEqual_w(d, d2)
+        space.delitem(d, space.wrap('of'))
+        self.assertEqual_w(d, d2)
+
+    def test_empty_cell2(self):
+        space = self.space
+        d = W_DictObject(space,
+                         [(space.wrap('colour'), space.wrap(0)),
+                          (space.wrap('of'),     space.wrap(2)),
+                          (space.wrap('magic'),  space.wrap(1))])
+        w_cell = d.cell(space, space.wrap('of'))
+        d2 = W_DictObject(space,
+                          [(space.wrap('colour'), space.wrap(0)),
+                           (space.wrap('magic'),  space.wrap(1))])
+        self.assertNotEqual_w(d, d2)
+        cell = space.unwrap(w_cell)
+        cell.make_empty()
+        self.assertEqual_w(d, d2)
+
 
     def test_wrap_dict(self):
         self.assert_(isinstance(self.space.wrap({}), W_DictObject))

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/test/test_instmethobject.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/test/test_instmethobject.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/test/test_instmethobject.py	Wed Sep 17 13:38:03 2003
@@ -1,22 +1,8 @@
 import autopath
 from pypy.tool import test
 
-class TestInstMethObject(test.TestCase):
-    def setUp(self):
-        self.space = test.objspace('std')
-
-    def test_unbound(self):
-        from pypy.objspace.std.instmethobject import W_InstMethObject
-        space = self.space
-        w_list = space.newlist([])
-        w_boundmeth = space.getattr(w_list, space.wrap('__len__'))
-        w_unboundmeth = W_InstMethObject(space,
-                                         w_boundmeth.w_im_func,
-                                         space.w_Null,
-                                         w_boundmeth.w_im_class)
-        self.assertEqual_w(space.call_function(w_unboundmeth, w_list),
-                           space.wrap(0))
-        
+# NB. instmethobject.py has been removed,
+# but the following tests still make sense
 
 class TestInstMethObjectApp(test.AppTestCase):
     def setUp(self):

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/test/test_sliceobject.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/test/test_sliceobject.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/test/test_sliceobject.py	Wed Sep 17 13:38:03 2003
@@ -10,29 +10,30 @@
         pass
 
     def equal_indices(self, got, expected):
-        got = self.space.unwrap(got)
         self.assertEqual(len(got), len(expected))
         for g, e in zip(got, expected):
             self.assertEqual(g, e)
 
     def test_indices(self):
+        from pypy.objspace.std import slicetype
         space = self.space
         w = space.wrap
         w_None = space.w_None
         w_slice = space.newslice(w_None, w_None, w_None)
-        self.equal_indices(w_slice.indices2(w(6)), (0, 6, 1))
+        self.equal_indices(slicetype.indices3(space, w_slice, 6), (0, 6, 1))
         w_slice = space.newslice(w(0), w(6), w(1))
-        self.equal_indices(w_slice.indices2(w(6)), (0, 6, 1))
+        self.equal_indices(slicetype.indices3(space, w_slice, 6), (0, 6, 1))
         w_slice = space.newslice(w_None, w_None, w(-1))
-        self.equal_indices(w_slice.indices2(w(6)), (5, -1, -1))
+        self.equal_indices(slicetype.indices3(space, w_slice, 6), (5, -1, -1))
 
     def test_indices_fail(self):
+        from pypy.objspace.std import slicetype
         space = self.space
         w = space.wrap
         w_None = space.w_None
         w_slice = space.newslice(w_None, w_None, w(0))
         self.assertRaises_w(space.w_ValueError,
-                            w_slice.indices, w(10))
+                            slicetype.indices3, space, w_slice, 10)
 
 class Test_SliceObject(test.AppTestCase):
     def setUp(self):
@@ -49,5 +50,13 @@
         self.failUnless(cmp_slice(slice(23), slice(None, 23, None)))
         self.failUnless(cmp_slice(slice(23, 45), slice(23, 45, None)))
 
+    def test_indices(self):
+        self.assertEqual(slice(4,11,2).indices(28), (4, 11, 2))
+        self.assertEqual(slice(4,11,2).indices(8), (4, 8, 2))
+        self.assertEqual(slice(4,11,2).indices(2), (2, 2, 2))
+        self.assertEqual(slice(11,4,-2).indices(28), (11, 4, -2))
+        self.assertEqual(slice(11,4,-2).indices(8), (7, 4, -2))
+        self.assertEqual(slice(11,4,-2).indices(2), (1, 2, -2))
+
 if __name__ == '__main__':
     test.main()

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/tupleobject.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/tupleobject.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/tupleobject.py	Wed Sep 17 13:38:03 2003
@@ -2,6 +2,7 @@
 from tupletype import W_TupleType
 from intobject import W_IntObject
 from sliceobject import W_SliceObject
+import slicetype
 
 
 class W_TupleObject(W_Object):
@@ -39,11 +40,8 @@
 
 def getitem__Tuple_Slice(space, w_tuple, w_slice):
     items = w_tuple.wrappeditems
-    w_length = space.wrap(len(items))
-    w_start, w_stop, w_step, w_slicelength = w_slice.indices(w_length)
-    start       = space.unwrap(w_start)
-    step        = space.unwrap(w_step)
-    slicelength = space.unwrap(w_slicelength)
+    length = len(items)
+    start, stop, step, slicelength = slicetype.indices4(space, w_slice, length)
     assert slicelength >= 0
     subitems = [None] * slicelength
     for i in range(slicelength):

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/typeobject.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/typeobject.py	Wed Sep 17 13:38:03 2003
@@ -1,4 +1,4 @@
-from pypy.interpreter import pycode
+from pypy.interpreter import eval, function
 from pypy.objspace.std.objspace import *
 
 
@@ -58,7 +58,8 @@
             raise KeyError   # pass on the KeyError
         if code.slice().is_empty():
             raise KeyError
-        return space.newfunction(code, space.w_None, code.getdefaults(space))
+        fn = function.Function(space, code, defs_w=code.getdefaults(space))
+        return space.wrap(fn)
 
 
 import typetype, objecttype
@@ -86,7 +87,7 @@
         for multimethod in (hack_out_multimethods(typeclass) +
                             hack_out_multimethods(spaceclass)):
             for i in range(len(multimethod.specialnames)):
-                # each PyMultimethodCode embeds a multimethod
+                # each MultimethodCode embeds a multimethod
                 name = multimethod.specialnames[i]
                 if name in multimethods:
                     # conflict between e.g. __lt__ and
@@ -94,102 +95,96 @@
                     code = multimethods[name]
                     if code.bound_position < i:
                         continue
-                pycodeclass = multimethod.extras.get('pycodeclass')
-                if pycodeclass is None:
+                mmframeclass = multimethod.extras.get('mmframeclass')
+                if mmframeclass is None:
                     if len(multimethod.specialnames) > 1:
-                        pycodeclass = SpecialMultimethodCode
+                        mmframeclass = SpecialMmFrame
                     else:
-                        pycodeclass = PyMultimethodCode
-                code = pycodeclass(multimethod, typeclass, i)
+                        mmframeclass = MmFrame
+                code = MultimethodCode(multimethod, mmframeclass, typeclass, i)
                 multimethods[name] = code
         # add some more multimethods with a special interface
-        code = NextMultimethodCode(spaceclass.next, typeclass)
+        code = MultimethodCode(spaceclass.next, NextMmFrame, typeclass)
         multimethods['next'] = code
-        code = NonZeroMultimethodCode(spaceclass.is_true, typeclass)
+        code = MultimethodCode(spaceclass.is_true, NonZeroMmFrame, typeclass)
         multimethods['__nonzero__'] = code
     return multimethods
 
-class PyMultimethodCode(pycode.PyBaseCode):
-
-    def __init__(self, multimethod, typeclass, bound_position=0):
-        pycode.PyBaseCode.__init__(self)
-        argnames = ['x%d'%(i+1) for i in range(multimethod.arity)]
-        argnames.insert(0, argnames.pop(bound_position))
-        self.co_name = multimethod.operatorsymbol
-        self.co_varnames = tuple(argnames)
-        self.co_argcount = multimethod.arity
-        self.co_flags = 0
-        if multimethod.extras.get('varargs', False):
-            self.co_flags |= pycode.CO_VARARGS
-        if multimethod.extras.get('keywords', False):
-            self.co_flags |= pycode.CO_VARKEYWORDS
+class MultimethodCode(eval.Code):
+    """A code object that invokes a multimethod."""
+    
+    def __init__(self, multimethod, framecls, typeclass, bound_position=0):
+        eval.Code.__init__(self, multimethod.operatorsymbol)
         self.basemultimethod = multimethod
         self.typeclass = typeclass
         self.bound_position = bound_position
+        self.framecls = framecls
+        argnames = ['x%d'%(i+1) for i in range(multimethod.arity)]
+        argnames.insert(0, argnames.pop(self.bound_position))
+        varargname = kwargname = None
+        if multimethod.extras.get('varargs', False):
+            varargname = 'args'
+        if multimethod.extras.get('keywords', False):
+            kwargname = 'keywords'
+        self.sig = argnames, varargname, kwargname
+        
+    def signature(self):
+        return self.sig
 
     def getdefaults(self, space):
-        return space.wrap(self.basemultimethod.extras.get('defaults', ()))
+        return [space.wrap(x)
+                for x in self.basemultimethod.extras.get('defaults', ())]
 
     def slice(self):
         return self.basemultimethod.slice(self.typeclass, self.bound_position)
 
-    def prepare_args(self, space, w_globals, w_locals):
-        multimethod = self.slice()
-        dispatchargs = []
-        for i in range(multimethod.arity):
-            w_arg = space.getitem(w_locals, space.wrap('x%d'%(i+1)))
-            dispatchargs.append(w_arg)
-        dispatchargs = tuple(dispatchargs)
-        return multimethod.get(space), dispatchargs
+    def create_frame(self, space, w_globals, closure=None):
+        return self.framecls(space, self)
 
-    def do_call(self, space, w_globals, w_locals):
+class MmFrame(eval.Frame):
+    def run(self):
         "Call the multimethod, raising a TypeError if not implemented."
-        mm, args = self.prepare_args(space, w_globals, w_locals)
-        return mm(*args)
-
-    def eval_code(self, space, w_globals, w_locals):
-        "Call the multimethods, or raise a TypeError."
-        w_result = self.do_call(space, w_globals, w_locals)
+        mm = self.code.slice().get(self.space)
+        args = self.fastlocals_w
+        w_result = mm(*args)
         # we accept a real None from operations with no return value
         if w_result is None:
-            w_result = space.w_None
+            w_result = self.space.w_None
         return w_result
 
-class SpecialMultimethodCode(PyMultimethodCode):
-
-    def do_call(self, space, w_globals, w_locals):
+class SpecialMmFrame(eval.Frame):
+    def run(self):
         "Call the multimethods, possibly returning a NotImplemented."
-        mm, args = self.prepare_args(space, w_globals, w_locals)
+        mm = self.code.slice().get(self.space)
+        args = self.fastlocals_w
         try:
             return mm.perform_call(args)
         except FailedToImplement, e:
             if e.args:
                 raise OperationError(*e.args)
             else:
-                return space.w_NotImplemented
-
-class NextMultimethodCode(PyMultimethodCode):
+                return self.space.w_NotImplemented
 
-    def eval_code(self, space, w_globals, w_locals):
+class NextMmFrame(eval.Frame):
+    def run(self):
         "Call the next() multimethod."
+        mm = self.code.slice().get(self.space)
+        args = self.fastlocals_w
         try:
-            return self.do_call(space, w_globals, w_locals)
+            return mm(*args)
         except NoValue:
-            raise OperationError(space.w_StopIteration, space.w_None)
+            raise OperationError(self.space.w_StopIteration,
+                                 self.space.w_None)
 
-class NonZeroMultimethodCode(PyMultimethodCode):
-
-    def eval_code(self, space, w_globals, w_locals):
+class NonZeroMmFrame(eval.Frame):
+    def run(self):
         "Call the is_true() multimethods."
-        result = self.do_call(space, w_globals, w_locals)
-        return space.newbool(result)
-
-class NewMultimethodCode(PyMultimethodCode):
+        mm = self.code.slice().get(self.space)
+        args = self.fastlocals_w
+        result = mm(*args)
+        return self.space.newbool(result)
 
-    def eval_code(self, space, w_globals, w_locals):
-        "Call the __new__() method of typetype.py."
-        w_result, callinit = self.do_call(space, w_globals, w_locals)
-        return w_result
+# see also class NewMmFrame in typetype.py
 
 
 def call__Type_ANY_ANY(space, w_type, w_args, w_kwds):
@@ -205,7 +200,7 @@
     return space.newbool(w_type2 in w_type1.getmro())
 
 def repr__Type(space, w_obj):
-    return space.wrap("<type '%s'>" % w_obj.typename) 
+    return space.wrap("<pypy type '%s'>" % w_obj.typename)  # XXX remove 'pypy'
 
 def getattr__Type_ANY(space, w_type, w_attr):
     # XXX mwh doubts this is the Right Way to do this...
@@ -217,7 +212,7 @@
         desc = w_type.lookup(w_attr)
     except KeyError:
         raise FailedToImplement #OperationError(space.w_AttributeError,w_attr)
-    return space.get(desc, space.w_Null, w_type)
+    return space.get(desc, space.w_None, w_type)
 
 
 register_all(vars())

Modified: pypy/branch/builtinrefactor/pypy/objspace/std/typetype.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/std/typetype.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/std/typetype.py	Wed Sep 17 13:38:03 2003
@@ -1,11 +1,16 @@
 from pypy.objspace.std.objspace import *
 from pypy.objspace.std.register_all import register_all
+from pypy.interpreter import eval
 from typeobject import W_TypeObject
 
 
-def NewMultimethodCode_builder(*args):
-    from typeobject import NewMultimethodCode  # sadly necessary late import hack
-    return NewMultimethodCode(*args)
+class NewMmFrame(eval.Frame):
+    def run(self):
+        "Call the __new__() method of typetype.py."
+        mm = self.code.slice().get(self.space)
+        args = self.fastlocals_w
+        w_result, callinit = mm(*args)
+        return w_result
 
 
 class W_TypeType(W_TypeObject):
@@ -23,7 +28,7 @@
     # Attention, this internally returns a tuple (w_result, flag),
     # where 'flag' specifies whether we would like __init__() to be called.
     type_new = MultiMethod('__new__', 4, varargs=True, keywords=True,
-                                         pycodeclass=NewMultimethodCode_builder)
+                                         mmframeclass=NewMmFrame)
 
 registerimplementation(W_TypeType)
 

Modified: pypy/branch/builtinrefactor/pypy/objspace/trivial.py
==============================================================================
--- pypy/branch/builtinrefactor/pypy/objspace/trivial.py	(original)
+++ pypy/branch/builtinrefactor/pypy/objspace/trivial.py	Wed Sep 17 13:38:03 2003
@@ -177,9 +177,11 @@
 
     def _auto(name, sourcefn, classlocals):
         s = """
-def %(name)s(self, *args):
+def %(name)s(self, x, *args):
+    if hasattr(x, 'pypy_%(name)s'):
+        return x.pypy_%(name)s(*args)
     try:
-        value = %(sourcefn)s(*args)
+        value = %(sourcefn)s(x, *args)
     except:
         self.reraise()
     return self.wrap(value)
@@ -188,7 +190,6 @@
 
     # from the built-ins
     _auto('issubtype', 'issubclass', locals())
-    _auto('newmodule', 'new.module', locals())
     _auto('newtuple',  'tuple',      locals())
     _auto('newlist',   'list',       locals())
     _auto('newdict',   'dict',       locals())
@@ -262,7 +263,7 @@
                 if stop  is None: stop  = sys.maxint
                 return start, stop
         return None
-        
+
     def getitem(self, w_obj, w_index):
         obj = self.unwrap(w_obj)
         index = self.unwrap(w_index)
@@ -302,25 +303,13 @@
 
     # misc
     def next(self, w):
+        if hasattr(w, 'pypy_next'):
+            return w.pypy_next()
         try:
             return self.wrap(w.next())
         except StopIteration:
             raise NoValue
 
-    def newfunction(self, code, globals, defs, closure=None):
-        #from pypy.interpreter.gateway import Function
-        #return Function(self, code, globals, defaultarguments, closure)
-
-        #assert hasattr(code, 'co_name')
-        #assert hasattr(code, 'build_arguments')
-        #assert hasattr(code, 'eval_code')
-
-        # XXX the newxxx() interface should disappear at some point
-        # XXX because the interpreter can perfectly do the following
-        # XXX itself without bothering the object space
-        from pypy.interpreter.function import Function
-        return self.wrap(Function(self, code, globals, defs, closure))
-
     def newstring(self, asciilist):
         try:
             return ''.join([chr(ascii) for ascii in asciilist])
@@ -344,6 +333,8 @@
         assert not isinstance(callable, gateway.Gateway), (
             "trivial object space is detecting an object that has not "
             "been wrapped")
+        if hasattr(callable, 'pypy_call'):
+            return callable.pypy_call(args, kwds)
         try:
             return self.wrap(callable(*args, **(kwds or {})))
         except OperationError:


More information about the Pypy-commit mailing list