[pypy-commit] pypy default: merge branch 'ClassRepr'

rlamy noreply at buildbot.pypy.org
Tue Oct 14 23:47:44 CEST 2014


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: 
Changeset: r73961:857f34cd4254
Date: 2014-10-14 22:47 +0100
http://bitbucket.org/pypy/pypy/changeset/857f34cd4254/

Log:	merge branch 'ClassRepr'

	Refactor ClassRepr and make normalizecalls independent of the
	rtyper.

diff too long, truncating to 2000 out of 2864 lines

diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -19,3 +19,6 @@
 .. branch: var-in-Some
 Store annotations on the Variable objects, rather than in a big dict.
 Introduce a new framework for double-dispatched annotation implementations.
+
+.. branch: ClassRepr
+Refactor ClassRepr and make normalizecalls independent of the rtyper.
diff --git a/pypy/module/pypyjit/interp_resop.py b/pypy/module/pypyjit/interp_resop.py
--- a/pypy/module/pypyjit/interp_resop.py
+++ b/pypy/module/pypyjit/interp_resop.py
@@ -7,7 +7,7 @@
 from pypy.interpreter.error import OperationError
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance, hlstr
-from rpython.rtyper.lltypesystem.rclass import OBJECT
+from rpython.rtyper.rclass import OBJECT
 from rpython.jit.metainterp.resoperation import rop
 from rpython.rlib.nonconst import NonConstant
 from rpython.rlib import jit_hooks
diff --git a/pypy/module/pypyjit/test/test_jit_hook.py b/pypy/module/pypyjit/test/test_jit_hook.py
--- a/pypy/module/pypyjit/test/test_jit_hook.py
+++ b/pypy/module/pypyjit/test/test_jit_hook.py
@@ -9,7 +9,7 @@
 from rpython.rtyper.annlowlevel import (cast_instance_to_base_ptr,
                                       cast_base_ptr_to_instance)
 from rpython.rtyper.lltypesystem import lltype, llmemory
-from rpython.rtyper.lltypesystem.rclass import OBJECT
+from rpython.rtyper.rclass import OBJECT
 from pypy.module.pypyjit.interp_jit import pypyjitdriver
 from pypy.module.pypyjit.policy import pypy_hooks
 from rpython.jit.tool.oparser import parse
diff --git a/rpython/annotator/classdef.py b/rpython/annotator/classdef.py
--- a/rpython/annotator/classdef.py
+++ b/rpython/annotator/classdef.py
@@ -154,6 +154,8 @@
         self.subdefs = []
         self.attr_sources = {}   # {name: list-of-sources}
         self.read_locations_of__class__ = {}
+        self.repr = None
+        self.extra_access_sets = {}
 
         if classdesc.basedesc:
             self.basedef = classdesc.basedesc.getuniqueclassdef()
diff --git a/rpython/jit/backend/arm/test/test_regalloc.py b/rpython/jit/backend/arm/test/test_regalloc.py
--- a/rpython/jit/backend/arm/test/test_regalloc.py
+++ b/rpython/jit/backend/arm/test/test_regalloc.py
@@ -15,7 +15,8 @@
 from rpython.jit.tool.oparser import parse
 from rpython.rtyper.lltypesystem import lltype, llmemory
 from rpython.rtyper.annlowlevel import llhelper
-from rpython.rtyper.lltypesystem import rclass, rstr
+from rpython.rtyper.lltypesystem import rstr
+from rpython.rtyper import rclass
 from rpython.jit.codewriter.effectinfo import EffectInfo
 from rpython.jit.codewriter import longlong
 from rpython.jit.backend.llsupport.test.test_regalloc_integration import BaseTestRegalloc
@@ -333,7 +334,7 @@
         '''
         self.interpret(ops, [0, 0, 3, 0])
         assert self.getints(3) == [1, -3, 10]
-        
+
     def test_compare_memory_result_survives(self):
         ops = '''
         [i0, i1, i2, i3]
diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py
--- a/rpython/jit/backend/arm/test/test_runner.py
+++ b/rpython/jit/backend/arm/test/test_runner.py
@@ -6,7 +6,8 @@
                                             BoxInt)
 from rpython.jit.metainterp.resoperation import ResOperation, rop
 from rpython.jit.tool.oparser import parse
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass
+from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rtyper import rclass
 from rpython.rtyper.annlowlevel import llhelper
 from rpython.jit.codewriter.effectinfo import EffectInfo
 from rpython.jit.metainterp.history import JitCellToken, TargetToken
diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -11,7 +11,8 @@
 from rpython.jit.codewriter.effectinfo import EffectInfo
 
 from rpython.rtyper.llinterp import LLInterpreter, LLException
-from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rclass, rstr
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr
+from rpython.rtyper import rclass
 
 from rpython.rlib.clibffi import FFI_DEFAULT_ABI
 from rpython.rlib.rarithmetic import ovfcheck, r_uint, r_ulonglong
diff --git a/rpython/jit/backend/llgraph/symbolic.py b/rpython/jit/backend/llgraph/symbolic.py
--- a/rpython/jit/backend/llgraph/symbolic.py
+++ b/rpython/jit/backend/llgraph/symbolic.py
@@ -1,4 +1,5 @@
-from rpython.rtyper.lltypesystem import lltype, rffi, rclass
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rtyper import rclass
 
 
 Size2Type = [None] * 100
diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -2,7 +2,8 @@
 from rpython.rlib import rgc
 from rpython.rlib.objectmodel import we_are_translated, specialize
 from rpython.rlib.rarithmetic import ovfcheck
-from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rclass, rstr
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr
+from rpython.rtyper import rclass
 from rpython.rtyper.lltypesystem import llgroup
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref
@@ -559,7 +560,7 @@
 
     def get_malloc_slowpath_array_addr(self):
         return self.get_malloc_fn_addr('malloc_array')
-    
+
 # ____________________________________________________________
 
 def get_ll_description(gcdescr, translator=None, rtyper=None):
diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py
--- a/rpython/jit/backend/llsupport/llmodel.py
+++ b/rpython/jit/backend/llsupport/llmodel.py
@@ -1,4 +1,5 @@
-from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rclass, rstr
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr
+from rpython.rtyper import rclass
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.rtyper.llinterp import LLInterpreter
 from rpython.rtyper.annlowlevel import llhelper, MixLevelHelperAnnotator
diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
@@ -12,7 +12,8 @@
 from rpython.jit.tool.oparser import parse
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 from rpython.rtyper.annlowlevel import llhelper
-from rpython.rtyper.lltypesystem import rclass, rstr
+from rpython.rtyper.lltypesystem import rstr
+from rpython.rtyper import rclass
 from rpython.jit.codewriter import longlong
 from rpython.jit.codewriter.effectinfo import EffectInfo
 
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -9,7 +9,8 @@
 from rpython.jit.metainterp.optimizeopt.util import equaloplists
 from rpython.jit.codewriter.heaptracker import register_known_gctype
 from rpython.jit.metainterp.history import JitCellToken, FLOAT
-from rpython.rtyper.lltypesystem import lltype, rclass, rffi
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rtyper import rclass
 from rpython.jit.backend.x86.arch import WORD
 
 class Evaluator(object):
diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -11,7 +11,8 @@
 from rpython.jit.metainterp.typesystem import deref
 from rpython.jit.codewriter.effectinfo import EffectInfo
 from rpython.jit.tool.oparser import parse
-from rpython.rtyper.lltypesystem import lltype, llmemory, rstr, rffi, rclass
+from rpython.rtyper.lltypesystem import lltype, llmemory, rstr, rffi
+from rpython.rtyper import rclass
 from rpython.rtyper.annlowlevel import llhelper
 from rpython.rtyper.llinterp import LLException
 from rpython.jit.codewriter import heaptracker, longlong
@@ -2296,7 +2297,7 @@
 
         for i in range(5):
             called = []
-        
+
             FUNC = self.FuncType([lltype.Signed] * i, lltype.Void)
             func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
             calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
@@ -4450,7 +4451,7 @@
 
     def test_zero_ptr_field(self):
         from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU
-        
+
         if not isinstance(self.cpu, AbstractLLCPU):
             py.test.skip("llgraph can't do zero_ptr_field")
         T = lltype.GcStruct('T')
@@ -4478,7 +4479,7 @@
 
         if not isinstance(self.cpu, AbstractLLCPU):
             py.test.skip("llgraph does not do zero_ptr_field")
-        
+
         from rpython.jit.backend.llsupport import symbolic
         S = lltype.GcStruct('S', ('x', lltype.Signed),
                                  ('p', llmemory.GCREF),
@@ -4503,7 +4504,7 @@
 
         if not isinstance(self.cpu, AbstractLLCPU):
             py.test.skip("llgraph does not do zero_array")
-        
+
         PAIR = lltype.Struct('PAIR', ('a', lltype.Signed), ('b', lltype.Signed))
         for OF in [lltype.Signed, rffi.INT, rffi.SHORT, rffi.UCHAR, PAIR]:
             A = lltype.GcArray(OF)
diff --git a/rpython/jit/backend/test/test_ll_random.py b/rpython/jit/backend/test/test_ll_random.py
--- a/rpython/jit/backend/test/test_ll_random.py
+++ b/rpython/jit/backend/test/test_ll_random.py
@@ -1,5 +1,6 @@
 import py
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rffi, rstr
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr
+from rpython.rtyper import rclass
 from rpython.jit.backend.test import test_random
 from rpython.jit.metainterp.resoperation import ResOperation, rop
 from rpython.jit.metainterp.history import ConstInt, ConstPtr
@@ -561,7 +562,7 @@
         subset = builder.subset_of_intvars(r)
         funcargs = ", ".join(['arg_%d' % i for i in range(len(subset))])
         S, v = builder.get_structptr_var(r, must_have_vtable=True)
-        
+
         code = py.code.Source("""
         def f(%s):
             raise LLException(vtable, ptr)
diff --git a/rpython/jit/backend/test/test_random.py b/rpython/jit/backend/test/test_random.py
--- a/rpython/jit/backend/test/test_random.py
+++ b/rpython/jit/backend/test/test_random.py
@@ -10,7 +10,8 @@
 from rpython.jit.metainterp.executor import execute_nonspec
 from rpython.jit.metainterp.resoperation import opname
 from rpython.jit.codewriter import longlong
-from rpython.rtyper.lltypesystem import lltype, rstr, rclass
+from rpython.rtyper.lltypesystem import lltype, rstr
+from rpython.rtyper import rclass
 
 class PleaseRewriteMe(Exception):
     pass
@@ -234,7 +235,7 @@
                 ', '.join([names[v] for v in fail_args]))
         print >>s, '    operations = ['
         for op in self.loop.operations:
-            self.process_operation(s, op, names) 
+            self.process_operation(s, op, names)
         print >>s, '        ]'
         for i, op in enumerate(self.loop.operations):
             if op.is_guard():
diff --git a/rpython/jit/backend/x86/test/test_regalloc2.py b/rpython/jit/backend/x86/test/test_regalloc2.py
--- a/rpython/jit/backend/x86/test/test_regalloc2.py
+++ b/rpython/jit/backend/x86/test/test_regalloc2.py
@@ -5,7 +5,8 @@
 from rpython.jit.backend.detect_cpu import getcpuclass
 from rpython.jit.backend.x86.arch import WORD
 from rpython.jit.tool.oparser import parse
-from rpython.rtyper.lltypesystem import lltype, rffi, rclass, llmemory, rstr
+from rpython.rtyper.lltypesystem import lltype, rffi, llmemory, rstr
+from rpython.rtyper import rclass
 from rpython.rtyper.llinterp import LLException
 from rpython.rtyper.annlowlevel import llhelper
 from rpython.jit.codewriter.effectinfo import EffectInfo
@@ -319,7 +320,7 @@
         raise LLException(vtableptr, xptr)
 
     fptr, funcdescr = getllhelper(cpu, f, [lltype.Signed] * count, lltype.Void)
-    
+
     return heaptracker.adr2int(llmemory.cast_ptr_to_adr(vtableptr)), fptr, funcdescr
 
 def getnoexception(cpu, count):
diff --git a/rpython/jit/codewriter/assembler.py b/rpython/jit/codewriter/assembler.py
--- a/rpython/jit/codewriter/assembler.py
+++ b/rpython/jit/codewriter/assembler.py
@@ -6,7 +6,8 @@
 from rpython.jit.codewriter import heaptracker, longlong
 from rpython.rlib.objectmodel import ComputedIntSymbolic
 from rpython.flowspace.model import Constant
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rffi
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
+from rpython.rtyper import rclass
 
 
 class AssemblerError(Exception):
diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -1,5 +1,5 @@
 from rpython.jit.metainterp.typesystem import deref, fieldType, arrayItem
-from rpython.rtyper.lltypesystem.rclass import OBJECT
+from rpython.rtyper.rclass import OBJECT
 from rpython.rtyper.lltypesystem import lltype, llmemory
 from rpython.translator.backendopt.graphanalyze import BoolGraphAnalyzer
 
diff --git a/rpython/jit/codewriter/heaptracker.py b/rpython/jit/codewriter/heaptracker.py
--- a/rpython/jit/codewriter/heaptracker.py
+++ b/rpython/jit/codewriter/heaptracker.py
@@ -1,4 +1,5 @@
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass
+from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rtyper import rclass
 from rpython.rlib.objectmodel import we_are_translated
 
 
@@ -125,7 +126,7 @@
     vtable = descr.as_vtable_size_descr()._corresponding_vtable
     vtable = llmemory.cast_ptr_to_adr(vtable)
     return adr2int(vtable)
-    
+
 def gc_fielddescrs(gccache, STRUCT, res=None):
     from rpython.jit.backend.llsupport import descr
 
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -12,8 +12,9 @@
 from rpython.rlib import objectmodel
 from rpython.rlib.jit import _we_are_jitted
 from rpython.rlib.rgc import lltype_is_gc
-from rpython.rtyper.lltypesystem import lltype, llmemory, rstr, rclass, rffi
+from rpython.rtyper.lltypesystem import lltype, llmemory, rstr, rffi
 from rpython.rtyper.lltypesystem import rbytearray
+from rpython.rtyper import rclass
 from rpython.rtyper.rclass import IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY
 from rpython.translator.unsimplify import varoftype
 
diff --git a/rpython/jit/codewriter/support.py b/rpython/jit/codewriter/support.py
--- a/rpython/jit/codewriter/support.py
+++ b/rpython/jit/codewriter/support.py
@@ -14,7 +14,8 @@
 from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator
 from rpython.rtyper.extregistry import ExtRegistryEntry
 from rpython.rtyper.llinterp import LLInterpreter
-from rpython.rtyper.lltypesystem import lltype, rclass, rffi, llmemory, rstr as ll_rstr, rdict as ll_rdict
+from rpython.rtyper.lltypesystem import lltype, rffi, llmemory, rstr as ll_rstr, rdict as ll_rdict
+from rpython.rtyper import rclass
 from rpython.rtyper.lltypesystem import rordereddict
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.rtyper.lltypesystem.module import ll_math
diff --git a/rpython/jit/codewriter/test/test_effectinfo.py b/rpython/jit/codewriter/test/test_effectinfo.py
--- a/rpython/jit/codewriter/test/test_effectinfo.py
+++ b/rpython/jit/codewriter/test/test_effectinfo.py
@@ -4,7 +4,7 @@
     EffectInfo, VirtualizableAnalyzer)
 from rpython.rlib import jit
 from rpython.rtyper.lltypesystem import lltype
-from rpython.rtyper.lltypesystem.rclass import OBJECT
+from rpython.rtyper.rclass import OBJECT
 from rpython.translator.translator import TranslationContext, graphof
 
 
diff --git a/rpython/jit/codewriter/test/test_flatten.py b/rpython/jit/codewriter/test/test_flatten.py
--- a/rpython/jit/codewriter/test/test_flatten.py
+++ b/rpython/jit/codewriter/test/test_flatten.py
@@ -6,7 +6,8 @@
 from rpython.jit.codewriter import longlong
 from rpython.jit.codewriter.effectinfo import EffectInfo
 from rpython.jit.metainterp.history import AbstractDescr
-from rpython.rtyper.lltypesystem import lltype, rclass, rstr, rffi
+from rpython.rtyper.lltypesystem import lltype, rstr, rffi
+from rpython.rtyper import rclass
 from rpython.flowspace.model import SpaceOperation, Variable, Constant
 from rpython.translator.unsimplify import varoftype
 from rpython.rlib.rarithmetic import ovfcheck, r_uint, r_longlong, r_ulonglong
diff --git a/rpython/jit/codewriter/test/test_jtransform.py b/rpython/jit/codewriter/test/test_jtransform.py
--- a/rpython/jit/codewriter/test/test_jtransform.py
+++ b/rpython/jit/codewriter/test/test_jtransform.py
@@ -17,7 +17,8 @@
 
 from rpython.flowspace.model import FunctionGraph, Block, Link
 from rpython.flowspace.model import SpaceOperation, Variable, Constant
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rstr, rffi
+from rpython.rtyper.lltypesystem import lltype, llmemory, rstr, rffi
+from rpython.rtyper import rclass
 from rpython.rtyper.lltypesystem.module import ll_math
 from rpython.translator.unsimplify import varoftype
 from rpython.jit.codewriter import heaptracker, effectinfo
@@ -1346,7 +1347,7 @@
     assert op2 is None
 
 def test_threadlocalref_get():
-    from rpython.rtyper.lltypesystem import rclass
+    from rpython.rtyper import rclass
     from rpython.rlib.rthread import ThreadLocalReference
     OS_THREADLOCALREF_GET = effectinfo.EffectInfo.OS_THREADLOCALREF_GET
     class Foo: pass
diff --git a/rpython/jit/codewriter/test/test_regalloc.py b/rpython/jit/codewriter/test/test_regalloc.py
--- a/rpython/jit/codewriter/test/test_regalloc.py
+++ b/rpython/jit/codewriter/test/test_regalloc.py
@@ -7,7 +7,8 @@
 from rpython.flowspace.model import Variable, Constant, SpaceOperation
 from rpython.flowspace.model import FunctionGraph, Block, Link
 from rpython.flowspace.model import c_last_exception
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass
+from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rtyper import rclass
 from rpython.rlib.rarithmetic import ovfcheck
 
 
diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -8,7 +8,8 @@
 from rpython.rlib.objectmodel import we_are_translated
 from rpython.rlib.rarithmetic import intmask, LONG_BIT, r_uint, ovfcheck
 from rpython.rlib.unroll import unrolling_iterable
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rffi
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
+from rpython.rtyper import rclass
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.rlib.jit_libffi import CIF_DESCRIPTION_P
 
@@ -1172,7 +1173,7 @@
 
     @arguments("cpu", "i", "d", returns="r")
     def bhimpl_new_array_clear(cpu, length, arraydescr):
-        return cpu.bh_new_array_clear(length, arraydescr)        
+        return cpu.bh_new_array_clear(length, arraydescr)
 
     @arguments("cpu", "r", "i", "d", returns="i")
     def bhimpl_getarrayitem_gc_i(cpu, array, index, arraydescr):
diff --git a/rpython/jit/metainterp/jitexc.py b/rpython/jit/metainterp/jitexc.py
--- a/rpython/jit/metainterp/jitexc.py
+++ b/rpython/jit/metainterp/jitexc.py
@@ -1,6 +1,7 @@
 from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr
 from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance
-from rpython.rtyper.lltypesystem import lltype, rclass
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rtyper import rclass
 from rpython.rtyper.llinterp import LLException
 from rpython.rlib.objectmodel import we_are_translated
 from rpython.jit.codewriter import longlong
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -1,8 +1,9 @@
 import py, random
 
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rffi
-from rpython.rtyper.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
-from rpython.rtyper.rclass import FieldListAccessor, IR_QUASIIMMUTABLE
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
+from rpython.rtyper import rclass
+from rpython.rtyper.rclass import (
+    OBJECT, OBJECT_VTABLE, FieldListAccessor, IR_QUASIIMMUTABLE)
 
 from rpython.jit.backend.llgraph import runner
 from rpython.jit.metainterp.history import (BoxInt, BoxPtr, ConstInt, ConstPtr,
diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -18,7 +18,8 @@
 from rpython.rlib.jit import Counters
 from rpython.rlib.objectmodel import we_are_translated, specialize
 from rpython.rlib.unroll import unrolling_iterable
-from rpython.rtyper.lltypesystem import lltype, rclass, rffi
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rtyper import rclass
 
 
 
diff --git a/rpython/jit/metainterp/quasiimmut.py b/rpython/jit/metainterp/quasiimmut.py
--- a/rpython/jit/metainterp/quasiimmut.py
+++ b/rpython/jit/metainterp/quasiimmut.py
@@ -1,4 +1,5 @@
-from rpython.rtyper.lltypesystem import lltype, rclass
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rtyper import rclass
 from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance
 from rpython.jit.metainterp.history import AbstractDescr
 from rpython.rlib.objectmodel import we_are_translated
diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py
--- a/rpython/jit/metainterp/resume.py
+++ b/rpython/jit/metainterp/resume.py
@@ -10,7 +10,7 @@
     debug_stop, debug_print)
 from rpython.rtyper import annlowlevel
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr
-from rpython.rtyper.lltypesystem.rclass import OBJECTPTR
+from rpython.rtyper.rclass import OBJECTPTR
 from rpython.jit.metainterp.walkvirtual import VirtualVisitor
 
 
diff --git a/rpython/jit/metainterp/test/test_quasiimmut.py b/rpython/jit/metainterp/test/test_quasiimmut.py
--- a/rpython/jit/metainterp/test/test_quasiimmut.py
+++ b/rpython/jit/metainterp/test/test_quasiimmut.py
@@ -1,7 +1,8 @@
 
 import py
 
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass
+from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rtyper import rclass
 from rpython.rtyper.rclass import FieldListAccessor, IR_QUASIIMMUTABLE
 from rpython.jit.metainterp import typesystem
 from rpython.jit.metainterp.quasiimmut import QuasiImmut
@@ -568,7 +569,7 @@
                 if a.x == 1:
                     a = two
                 elif a.x == 2:
-                    a = one                    
+                    a = one
                 n -= 1
             return sa
         res = self.meta_interp(main, [10])
diff --git a/rpython/jit/metainterp/test/test_virtual.py b/rpython/jit/metainterp/test/test_virtual.py
--- a/rpython/jit/metainterp/test/test_virtual.py
+++ b/rpython/jit/metainterp/test/test_virtual.py
@@ -3,7 +3,8 @@
 from rpython.rlib.objectmodel import compute_unique_id
 from rpython.jit.codewriter.policy import StopAtXPolicy
 from rpython.jit.metainterp.test.support import LLJitMixin
-from rpython.rtyper.lltypesystem import lltype, rclass, rffi
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rtyper import rclass
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.jit.codewriter import heaptracker
 
diff --git a/rpython/jit/metainterp/test/test_virtualizable.py b/rpython/jit/metainterp/test/test_virtualizable.py
--- a/rpython/jit/metainterp/test/test_virtualizable.py
+++ b/rpython/jit/metainterp/test/test_virtualizable.py
@@ -11,7 +11,8 @@
 from rpython.rtyper.annlowlevel import hlstr
 from rpython.rtyper.llannotation import lltype_to_annotation
 from rpython.rtyper.extregistry import ExtRegistryEntry
-from rpython.rtyper.lltypesystem import lltype, lloperation, rclass, llmemory
+from rpython.rtyper.lltypesystem import lltype, lloperation, llmemory
+from rpython.rtyper import rclass
 from rpython.rtyper.rclass import IR_IMMUTABLE, IR_IMMUTABLE_ARRAY, FieldListAccessor
 
 
diff --git a/rpython/jit/metainterp/test/test_warmspot.py b/rpython/jit/metainterp/test/test_warmspot.py
--- a/rpython/jit/metainterp/test/test_warmspot.py
+++ b/rpython/jit/metainterp/test/test_warmspot.py
@@ -568,7 +568,7 @@
         from rpython.jit.metainterp.typesystem import llhelper
         from rpython.jit.codewriter.support import annotate
         from rpython.jit.metainterp.warmspot import WarmRunnerDesc
-        from rpython.rtyper.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
+        from rpython.rtyper.rclass import OBJECT, OBJECT_VTABLE
         from rpython.rtyper.lltypesystem import lltype, llmemory
         exc_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
         cls.exc_vtable = exc_vtable
diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py
--- a/rpython/jit/metainterp/typesystem.py
+++ b/rpython/jit/metainterp/typesystem.py
@@ -1,4 +1,5 @@
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass
+from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rtyper import rclass
 from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance, llstr
 from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr
 from rpython.jit.metainterp import history
diff --git a/rpython/jit/metainterp/virtualref.py b/rpython/jit/metainterp/virtualref.py
--- a/rpython/jit/metainterp/virtualref.py
+++ b/rpython/jit/metainterp/virtualref.py
@@ -1,5 +1,6 @@
 from rpython.rtyper.rmodel import inputconst, log
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass
+from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rtyper import rclass
 from rpython.jit.metainterp import history
 from rpython.jit.metainterp.virtualizable import TOKEN_NONE
 from rpython.jit.metainterp.virtualizable import TOKEN_TRACING_RESCALL
diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py
--- a/rpython/memory/gctypelayout.py
+++ b/rpython/memory/gctypelayout.py
@@ -1,5 +1,5 @@
 from rpython.rtyper.lltypesystem import lltype, llmemory, llarena, llgroup
-from rpython.rtyper.lltypesystem import rclass
+from rpython.rtyper import rclass
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.rlib.debug import ll_assert
 from rpython.rlib.rarithmetic import intmask
diff --git a/rpython/memory/test/test_gctypelayout.py b/rpython/memory/test/test_gctypelayout.py
--- a/rpython/memory/test/test_gctypelayout.py
+++ b/rpython/memory/test/test_gctypelayout.py
@@ -2,9 +2,10 @@
 from rpython.memory.gctypelayout import TypeLayoutBuilder, GCData
 from rpython.memory.gctypelayout import offsets_to_gc_pointers
 from rpython.memory.gctypelayout import gc_pointers_inside
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass
+from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rtyper import rclass
+from rpython.rtyper.rclass import IR_IMMUTABLE, IR_QUASIIMMUTABLE
 from rpython.rtyper.test.test_llinterp import get_interpreter
-from rpython.rtyper.rclass import IR_IMMUTABLE, IR_QUASIIMMUTABLE
 from rpython.flowspace.model import Constant
 
 class FakeGC:
@@ -23,7 +24,7 @@
 GC_A = lltype.GcArray(S)
 
 S2 = lltype.Struct('SPTRS',
-                   *[(getname(TYPE), lltype.Ptr(TYPE)) for TYPE in (GC_S, GC_A)])  
+                   *[(getname(TYPE), lltype.Ptr(TYPE)) for TYPE in (GC_S, GC_A)])
 GC_S2 = lltype.GcStruct('GC_S2', ('S2', S2))
 
 A2 = lltype.Array(S2)
diff --git a/rpython/rlib/_jit_vref.py b/rpython/rlib/_jit_vref.py
--- a/rpython/rlib/_jit_vref.py
+++ b/rpython/rlib/_jit_vref.py
@@ -1,8 +1,7 @@
 from rpython.annotator import model as annmodel
 from rpython.tool.pairtype import pairtype
-from rpython.rtyper.rclass import getinstancerepr
 from rpython.rtyper.rmodel import Repr
-from rpython.rtyper.lltypesystem.rclass import OBJECTPTR
+from rpython.rtyper.rclass import (getinstancerepr, OBJECTPTR)
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.error import TyperError
 
diff --git a/rpython/rlib/_rweakkeydict.py b/rpython/rlib/_rweakkeydict.py
--- a/rpython/rlib/_rweakkeydict.py
+++ b/rpython/rlib/_rweakkeydict.py
@@ -1,6 +1,7 @@
 from rpython.flowspace.model import Constant
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rdict
+from rpython.rtyper.lltypesystem import lltype, llmemory, rdict
 from rpython.rtyper.lltypesystem.llmemory import weakref_create, weakref_deref
+from rpython.rtyper import rclass
 from rpython.rtyper.rclass import getinstancerepr
 from rpython.rtyper.rmodel import Repr
 from rpython.rlib.rweakref import RWeakKeyDictionary
diff --git a/rpython/rlib/_rweakvaldict.py b/rpython/rlib/_rweakvaldict.py
--- a/rpython/rlib/_rweakvaldict.py
+++ b/rpython/rlib/_rweakvaldict.py
@@ -1,6 +1,7 @@
 from rpython.flowspace.model import Constant
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rdict
+from rpython.rtyper.lltypesystem import lltype, llmemory, rdict
 from rpython.rtyper.lltypesystem.llmemory import weakref_create, weakref_deref
+from rpython.rtyper import rclass
 from rpython.rtyper.rclass import getinstancerepr
 from rpython.rtyper.rmodel import Repr
 from rpython.rlib.rweakref import RWeakValueDictionary
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -1001,7 +1001,8 @@
         assert isinstance(s_inst, annmodel.SomeInstance)
 
     def specialize_call(self, hop):
-        from rpython.rtyper.lltypesystem import rclass, lltype
+        from rpython.rtyper.lltypesystem import lltype
+        from rpython.rtyper import rclass
 
         classrepr = rclass.get_type_repr(hop.rtyper)
 
diff --git a/rpython/rlib/jit_hooks.py b/rpython/rlib/jit_hooks.py
--- a/rpython/rlib/jit_hooks.py
+++ b/rpython/rlib/jit_hooks.py
@@ -4,7 +4,8 @@
 from rpython.rtyper.annlowlevel import (cast_instance_to_base_ptr,
     cast_base_ptr_to_instance, llstr)
 from rpython.rtyper.extregistry import ExtRegistryEntry
-from rpython.rtyper.lltypesystem import llmemory, lltype, rclass
+from rpython.rtyper.lltypesystem import llmemory, lltype
+from rpython.rtyper import rclass
 
 
 def register_helper(s_result):
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -402,14 +402,13 @@
     # Before translation, unwraps the RPython instance contained in a _GcRef.
     # After translation, it is a type-check performed by the GC.
     if we_are_translated():
-        from rpython.rtyper.lltypesystem.rclass import OBJECTPTR
+        from rpython.rtyper.rclass import OBJECTPTR, ll_isinstance
         from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance
-        from rpython.rtyper.lltypesystem import rclass
         if _is_rpy_instance(gcref):
             objptr = lltype.cast_opaque_ptr(OBJECTPTR, gcref)
             if objptr.typeptr:   # may be NULL, e.g. in rdict's dummykeyobj
                 clsptr = _get_llcls_from_cls(Class)
-                if rclass.ll_isinstance(objptr, clsptr):
+                if ll_isinstance(objptr, clsptr):
                     return cast_base_ptr_to_instance(Class, objptr)
         return None
     else:
@@ -500,21 +499,20 @@
     _about_ = _get_llcls_from_cls
     def compute_result_annotation(self, s_Class):
         from rpython.rtyper.llannotation import SomePtr
-        from rpython.rtyper.lltypesystem import rclass
+        from rpython.rtyper.rclass import CLASSTYPE
         assert s_Class.is_constant()
-        return SomePtr(rclass.CLASSTYPE)
+        return SomePtr(CLASSTYPE)
 
     def specialize_call(self, hop):
-        from rpython.rtyper.rclass import getclassrepr
+        from rpython.rtyper.rclass import getclassrepr, CLASSTYPE
         from rpython.flowspace.model import Constant
-        from rpython.rtyper.lltypesystem import rclass
         Class = hop.args_s[0].const
         classdef = hop.rtyper.annotator.bookkeeper.getuniqueclassdef(Class)
         classrepr = getclassrepr(hop.rtyper, classdef)
         vtable = classrepr.getvtable()
-        assert lltype.typeOf(vtable) == rclass.CLASSTYPE
+        assert lltype.typeOf(vtable) == CLASSTYPE
         hop.exception_cannot_occur()
-        return Constant(vtable, concretetype=rclass.CLASSTYPE)
+        return Constant(vtable, concretetype=CLASSTYPE)
 
 class Entry(ExtRegistryEntry):
     _about_ = dump_rpy_heap
diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py
--- a/rpython/rlib/rthread.py
+++ b/rpython/rlib/rthread.py
@@ -296,7 +296,7 @@
 
         def get():
             if we_are_translated():
-                from rpython.rtyper.lltypesystem import rclass
+                from rpython.rtyper import rclass
                 from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance
                 ptr = llop.threadlocalref_get(rclass.OBJECTPTR, opaque_id)
                 return cast_base_ptr_to_instance(Cls, ptr)
diff --git a/rpython/rlib/test/test__jit_vref.py b/rpython/rlib/test/test__jit_vref.py
--- a/rpython/rlib/test/test__jit_vref.py
+++ b/rpython/rlib/test/test__jit_vref.py
@@ -4,7 +4,7 @@
 from rpython.rlib._jit_vref import SomeVRef
 from rpython.annotator import model as annmodel
 from rpython.annotator.annrpython import RPythonAnnotator
-from rpython.rtyper.lltypesystem.rclass import OBJECTPTR
+from rpython.rtyper.rclass import OBJECTPTR
 from rpython.rtyper.lltypesystem import lltype
 
 from rpython.rtyper.test.tool import BaseRtypingTest
diff --git a/rpython/rlib/test/test_rerased.py b/rpython/rlib/test/test_rerased.py
--- a/rpython/rlib/test/test_rerased.py
+++ b/rpython/rlib/test/test_rerased.py
@@ -5,7 +5,7 @@
 from rpython.rlib.rerased import *
 from rpython.annotator import model as annmodel
 from rpython.annotator.annrpython import RPythonAnnotator
-from rpython.rtyper.lltypesystem.rclass import OBJECTPTR
+from rpython.rtyper.rclass import OBJECTPTR
 from rpython.rtyper.lltypesystem import lltype, llmemory
 
 from rpython.rtyper.test.tool import BaseRtypingTest
diff --git a/rpython/rtyper/annlowlevel.py b/rpython/rtyper/annlowlevel.py
--- a/rpython/rtyper/annlowlevel.py
+++ b/rpython/rtyper/annlowlevel.py
@@ -250,7 +250,7 @@
         rtyper = self.rtyper
         translator = rtyper.annotator.translator
         original_graph_count = len(translator.graphs)
-        perform_normalizations(rtyper)
+        perform_normalizations(rtyper.annotator)
         for r in self.delayedreprs:
             r.set_setup_delayed(False)
         rtyper.call_all_setups()
@@ -464,7 +464,7 @@
 
 @specialize.argtype(0)
 def cast_instance_to_base_ptr(instance):
-    from rpython.rtyper.lltypesystem.rclass import OBJECTPTR
+    from rpython.rtyper.rclass import OBJECTPTR
     return cast_object_to_ptr(OBJECTPTR, instance)
 
 @specialize.argtype(0)
diff --git a/rpython/rtyper/exceptiondata.py b/rpython/rtyper/exceptiondata.py
--- a/rpython/rtyper/exceptiondata.py
+++ b/rpython/rtyper/exceptiondata.py
@@ -1,9 +1,8 @@
 from rpython.annotator import model as annmodel
 from rpython.rtyper.llannotation import SomePtr
 from rpython.rlib import rstackovf
-from rpython.rtyper import rclass
-from rpython.rtyper.lltypesystem.rclass import (ll_issubclass, ll_type,
-        ll_cast_to_object)
+from rpython.rtyper.rclass import (
+    ll_issubclass, ll_type, ll_cast_to_object, getclassrepr, getinstancerepr)
 
 # the exceptions that can be implicitely raised by some operations
 standardexceptions = set([TypeError, OverflowError, ValueError,
@@ -23,8 +22,8 @@
     def __init__(self, rtyper):
         self.make_standard_exceptions(rtyper)
         # (NB. rclass identifies 'Exception' and 'object')
-        r_type = rclass.getclassrepr(rtyper, None)
-        r_instance = rclass.getinstancerepr(rtyper, None)
+        r_type = rtyper.rootclass_repr
+        r_instance = getinstancerepr(rtyper, None)
         r_type.setup()
         r_instance.setup()
         self.r_exception_type = r_type
@@ -42,10 +41,9 @@
         bk = rtyper.annotator.bookkeeper
         for cls in self.standardexceptions:
             classdef = bk.getuniqueclassdef(cls)
-            rclass.getclassrepr(rtyper, classdef).setup()
+            getclassrepr(rtyper, classdef).setup()
 
     def get_standard_ll_exc_instance(self, rtyper, clsdef):
-        from rpython.rtyper.lltypesystem.rclass import getinstancerepr
         r_inst = getinstancerepr(rtyper, clsdef)
         example = r_inst.get_reusable_prebuilt_instance()
         example = ll_cast_to_object(example)
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -13,7 +13,8 @@
 # intmask is used in an exec'd code block
 from rpython.rlib.rarithmetic import (ovfcheck, is_valid_int, intmask,
     r_uint, r_longlong, r_ulonglong, r_longlonglong)
-from rpython.rtyper.lltypesystem import lltype, llmemory, lloperation, llheap, rclass
+from rpython.rtyper.lltypesystem import lltype, llmemory, lloperation, llheap
+from rpython.rtyper import rclass
 
 
 log = py.log.Producer('llinterp')
diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py b/rpython/rtyper/lltypesystem/ll2ctypes.py
--- a/rpython/rtyper/lltypesystem/ll2ctypes.py
+++ b/rpython/rtyper/lltypesystem/ll2ctypes.py
@@ -25,7 +25,7 @@
 from rpython.rtyper.llannotation import lltype_to_annotation
 from rpython.rtyper.llannotation import SomePtr
 from rpython.rtyper.llinterp import LLInterpreter, LLException
-from rpython.rtyper.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
+from rpython.rtyper.rclass import OBJECT, OBJECT_VTABLE
 from rpython.rtyper import raddress
 from rpython.translator.platform import platform
 from array import array
diff --git a/rpython/rtyper/lltypesystem/rclass.py b/rpython/rtyper/lltypesystem/rclass.py
deleted file mode 100644
--- a/rpython/rtyper/lltypesystem/rclass.py
+++ /dev/null
@@ -1,736 +0,0 @@
-import sys
-import types
-from rpython.tool.pairtype import pairtype, pair
-from rpython.flowspace.model import Constant
-from rpython.rtyper.error import TyperError
-from rpython.rtyper.rmodel import Repr, inputconst, warning, mangle
-from rpython.rtyper.rclass import AbstractClassRepr,\
-                                AbstractInstanceRepr,\
-                                MissingRTypeAttribute,\
-                                getclassrepr, getinstancerepr,\
-                                get_type_repr, rtype_new_instance
-from rpython.rtyper.lltypesystem.lltype import \
-     Ptr, Struct, GcStruct, malloc, \
-     cast_pointer, cast_ptr_to_int, castable, nullptr, \
-     RuntimeTypeInfo, getRuntimeTypeInfo, typeOf, \
-     Array, Char, Void, \
-     FuncType, Bool, Signed, functionptr
-from rpython.rtyper.lltypesystem import lltype
-from rpython.rtyper.extregistry import ExtRegistryEntry
-from rpython.annotator import model as annmodel
-from rpython.rlib.rarithmetic import intmask
-from rpython.rlib import objectmodel
-from rpython.tool.identity_dict import identity_dict
-from rpython.rtyper.lltypesystem.lloperation import llop
-from rpython.rtyper.lltypesystem import rstr
-
-#
-#  There is one "vtable" per user class, with the following structure:
-#  A root class "object" has:
-#
-#      struct object_vtable {
-#          // struct object_vtable* parenttypeptr;  not used any more
-#          RuntimeTypeInfo * rtti;
-#          Signed subclassrange_min;  //this is also the id of the class itself
-#          Signed subclassrange_max;
-#          RPyString * name;
-#          struct object * instantiate();
-#      }
-#
-#  Every other class X, with parent Y, has the structure:
-#
-#      struct vtable_X {
-#          struct vtable_Y super;   // inlined
-#          ...                      // extra class attributes
-#      }
-
-# The type of the instances is:
-#
-#     struct object {       // for the root class
-#         struct object_vtable* typeptr;
-#     }
-#
-#     struct X {
-#         struct Y super;   // inlined
-#         ...               // extra instance attributes
-#     }
-#
-# there's also a nongcobject
-
-OBJECT_VTABLE = lltype.ForwardReference()
-CLASSTYPE = Ptr(OBJECT_VTABLE)
-OBJECT = GcStruct('object', ('typeptr', CLASSTYPE),
-                  hints = {'immutable': True, 'shouldntbenull': True,
-                           'typeptr': True},
-                  rtti = True)
-OBJECTPTR = Ptr(OBJECT)
-OBJECT_VTABLE.become(Struct('object_vtable',
-                            #('parenttypeptr', CLASSTYPE),
-                            ('subclassrange_min', Signed),
-                            ('subclassrange_max', Signed),
-                            ('rtti', Ptr(RuntimeTypeInfo)),
-                            ('name', Ptr(rstr.STR)),
-                            ('hash', Signed),
-                            ('instantiate', Ptr(FuncType([], OBJECTPTR))),
-                            hints = {'immutable': True}))
-# non-gc case
-NONGCOBJECT = Struct('nongcobject', ('typeptr', CLASSTYPE))
-NONGCOBJECTPTR = Ptr(NONGCOBJECT)
-
-OBJECT_BY_FLAVOR = {'gc': OBJECT,
-                    'raw': NONGCOBJECT}
-
-LLFLAVOR = {'gc'   : 'gc',
-            'raw'  : 'raw',
-            'stack': 'raw',
-            }
-
-def cast_vtable_to_typeptr(vtable):
-    while typeOf(vtable).TO != OBJECT_VTABLE:
-        vtable = vtable.super
-    return vtable
-
-def alloc_array_name(name):
-    return rstr.string_repr.convert_const(name)
-
-
-class ClassRepr(AbstractClassRepr):
-    def __init__(self, rtyper, classdef):
-        AbstractClassRepr.__init__(self, rtyper, classdef)
-        if classdef is None:
-            # 'object' root type
-            self.vtable_type = OBJECT_VTABLE
-        else:
-            self.vtable_type = lltype.ForwardReference()
-        self.lowleveltype = Ptr(self.vtable_type)
-
-    def _setup_repr(self):
-        # NOTE: don't store mutable objects like the dicts below on 'self'
-        #       before they are fully built, to avoid strange bugs in case
-        #       of recursion where other code would uses these
-        #       partially-initialized dicts.
-        clsfields = {}
-        pbcfields = {}
-        allmethods = {}
-        if self.classdef is not None:
-            # class attributes
-            llfields = []
-            attrs = self.classdef.attrs.items()
-            attrs.sort()
-            for name, attrdef in attrs:
-                if attrdef.readonly:
-                    s_value = attrdef.s_value
-                    s_unboundmethod = self.prepare_method(s_value)
-                    if s_unboundmethod is not None:
-                        allmethods[name] = True
-                        s_value = s_unboundmethod
-                    r = self.rtyper.getrepr(s_value)
-                    mangled_name = 'cls_' + name
-                    clsfields[name] = mangled_name, r
-                    llfields.append((mangled_name, r.lowleveltype))
-            # attributes showing up in getattrs done on the class as a PBC
-            extra_access_sets = self.rtyper.class_pbc_attributes.get(
-                self.classdef, {})
-            for access_set, (attr, counter) in extra_access_sets.items():
-                r = self.rtyper.getrepr(access_set.s_value)
-                mangled_name = mangle('pbc%d' % counter, attr)
-                pbcfields[access_set, attr] = mangled_name, r
-                llfields.append((mangled_name, r.lowleveltype))
-            #
-            self.rbase = getclassrepr(self.rtyper, self.classdef.basedef)
-            self.rbase.setup()
-            kwds = {'hints': {'immutable': True}}
-            vtable_type = Struct('%s_vtable' % self.classdef.name,
-                                 ('super', self.rbase.vtable_type),
-                                 *llfields, **kwds)
-            self.vtable_type.become(vtable_type)
-            allmethods.update(self.rbase.allmethods)
-        self.clsfields = clsfields
-        self.pbcfields = pbcfields
-        self.allmethods = allmethods
-        self.vtable = None
-
-#    def convert_const(self, value):
-#        if not isinstance(value, (type, types.ClassType)):
-#            raise TyperError("not a class: %r" % (value,))
-#        try:
-#            subclassdef = self.rtyper.annotator.getuserclasses()[value]
-#        except KeyError:
-#            raise TyperError("no classdef: %r" % (value,))
-#        if self.classdef is not None:
-#            if self.classdef.commonbase(subclassdef) != self.classdef:
-#                raise TyperError("not a subclass of %r: %r" % (
-#                    self.classdef.cls, value))
-#        #
-#        return getclassrepr(self.rtyper, subclassdef).getvtable()
-
-    def getvtable(self, cast_to_typeptr=True):
-        """Return a ptr to the vtable of this type."""
-        if self.vtable is None:
-            self.vtable = malloc(self.vtable_type, immortal=True)
-            self.setup_vtable(self.vtable, self)
-        #
-        vtable = self.vtable
-        if cast_to_typeptr:
-            vtable = cast_vtable_to_typeptr(vtable)
-        return vtable
-
-    def getruntime(self, expected_type):
-        assert expected_type == CLASSTYPE
-        return self.getvtable()
-
-    def setup_vtable(self, vtable, rsubcls):
-        """Initialize the 'self' portion of the 'vtable' belonging to the
-        given subclass."""
-        if self.classdef is None:
-            vtable.hash = hash(rsubcls)
-            # initialize the 'subclassrange_*' and 'name' fields
-            if rsubcls.classdef is not None:
-                #vtable.parenttypeptr = rsubcls.rbase.getvtable()
-                vtable.subclassrange_min = rsubcls.classdef.minid
-                vtable.subclassrange_max = rsubcls.classdef.maxid
-            else: #for the root class
-                vtable.subclassrange_min = 0
-                vtable.subclassrange_max = sys.maxint
-            rinstance = getinstancerepr(self.rtyper, rsubcls.classdef)
-            rinstance.setup()
-            if rinstance.gcflavor == 'gc':
-                vtable.rtti = getRuntimeTypeInfo(rinstance.object_type)
-            if rsubcls.classdef is None:
-                name = 'object'
-            else:
-                name = rsubcls.classdef.shortname
-            vtable.name = alloc_array_name(name)
-            if hasattr(rsubcls.classdef, 'my_instantiate_graph'):
-                graph = rsubcls.classdef.my_instantiate_graph
-                vtable.instantiate = self.rtyper.getcallable(graph)
-            #else: the classdef was created recently, so no instantiate()
-            #      could reach it
-        else:
-            # setup class attributes: for each attribute name at the level
-            # of 'self', look up its value in the subclass rsubcls
-            def assign(mangled_name, value):
-                if isinstance(value, Constant) and isinstance(value.value, staticmethod):
-                    value = Constant(value.value.__get__(42))   # staticmethod => bare function
-                llvalue = r.convert_desc_or_const(value)
-                setattr(vtable, mangled_name, llvalue)
-
-            mro = list(rsubcls.classdef.getmro())
-            for fldname in self.clsfields:
-                mangled_name, r = self.clsfields[fldname]
-                if r.lowleveltype is Void:
-                    continue
-                value = rsubcls.classdef.classdesc.read_attribute(fldname, None)
-                if value is not None:
-                    assign(mangled_name, value)
-            # extra PBC attributes
-            for (access_set, attr), (mangled_name, r) in self.pbcfields.items():
-                if rsubcls.classdef.classdesc not in access_set.descs:
-                    continue   # only for the classes in the same pbc access set
-                if r.lowleveltype is Void:
-                    continue
-                attrvalue = rsubcls.classdef.classdesc.read_attribute(attr, None)
-                if attrvalue is not None:
-                    assign(mangled_name, attrvalue)
-
-            # then initialize the 'super' portion of the vtable
-            self.rbase.setup_vtable(vtable.super, rsubcls)
-
-    #def fromparentpart(self, v_vtableptr, llops):
-    #    """Return the vtable pointer cast from the parent vtable's type
-    #    to self's vtable type."""
-
-    def fromtypeptr(self, vcls, llops):
-        """Return the type pointer cast to self's vtable type."""
-        self.setup()
-        castable(self.lowleveltype, vcls.concretetype) # sanity check
-        return llops.genop('cast_pointer', [vcls],
-                           resulttype=self.lowleveltype)
-
-    fromclasstype = fromtypeptr
-
-    def getclsfield(self, vcls, attr, llops):
-        """Read the given attribute of 'vcls'."""
-        if attr in self.clsfields:
-            mangled_name, r = self.clsfields[attr]
-            v_vtable = self.fromtypeptr(vcls, llops)
-            cname = inputconst(Void, mangled_name)
-            return llops.genop('getfield', [v_vtable, cname], resulttype=r)
-        else:
-            if self.classdef is None:
-                raise MissingRTypeAttribute(attr)
-            return self.rbase.getclsfield(vcls, attr, llops)
-
-    def setclsfield(self, vcls, attr, vvalue, llops):
-        """Write the given attribute of 'vcls'."""
-        if attr in self.clsfields:
-            mangled_name, r = self.clsfields[attr]
-            v_vtable = self.fromtypeptr(vcls, llops)
-            cname = inputconst(Void, mangled_name)
-            llops.genop('setfield', [v_vtable, cname, vvalue])
-        else:
-            if self.classdef is None:
-                raise MissingRTypeAttribute(attr)
-            self.rbase.setclsfield(vcls, attr, vvalue, llops)
-
-    def getpbcfield(self, vcls, access_set, attr, llops):
-        if (access_set, attr) not in self.pbcfields:
-            raise TyperError("internal error: missing PBC field")
-        mangled_name, r = self.pbcfields[access_set, attr]
-        v_vtable = self.fromtypeptr(vcls, llops)
-        cname = inputconst(Void, mangled_name)
-        return llops.genop('getfield', [v_vtable, cname], resulttype=r)
-
-    def rtype_issubtype(self, hop):
-        class_repr = get_type_repr(self.rtyper)
-        v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
-        if isinstance(v_cls2, Constant):
-            cls2 = v_cls2.value
-            minid = hop.inputconst(Signed, cls2.subclassrange_min)
-            maxid = hop.inputconst(Signed, cls2.subclassrange_max)
-            return hop.gendirectcall(ll_issubclass_const, v_cls1, minid,
-                                     maxid)
-        else:
-            v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
-            return hop.gendirectcall(ll_issubclass, v_cls1, v_cls2)
-
-# ____________________________________________________________
-
-
-class InstanceRepr(AbstractInstanceRepr):
-    def __init__(self, rtyper, classdef, gcflavor='gc'):
-        AbstractInstanceRepr.__init__(self, rtyper, classdef)
-        if classdef is None:
-            self.object_type = OBJECT_BY_FLAVOR[LLFLAVOR[gcflavor]]
-        else:
-            ForwardRef = lltype.FORWARDREF_BY_FLAVOR[LLFLAVOR[gcflavor]]
-            self.object_type = ForwardRef()
-
-        self.iprebuiltinstances = identity_dict()
-        self.lowleveltype = Ptr(self.object_type)
-        self.gcflavor = gcflavor
-
-    def _setup_repr(self, llfields=None, hints=None, adtmeths=None):
-        # NOTE: don't store mutable objects like the dicts below on 'self'
-        #       before they are fully built, to avoid strange bugs in case
-        #       of recursion where other code would uses these
-        #       partially-initialized dicts.
-        AbstractInstanceRepr._setup_repr(self)
-        self.rclass = getclassrepr(self.rtyper, self.classdef)
-        fields = {}
-        allinstancefields = {}
-        if self.classdef is None:
-            fields['__class__'] = 'typeptr', get_type_repr(self.rtyper)
-        else:
-            # instance attributes
-            attrs = self.classdef.attrs.items()
-            attrs.sort()
-            myllfields = []
-            for name, attrdef in attrs:
-                if not attrdef.readonly:
-                    r = self.rtyper.getrepr(attrdef.s_value)
-                    mangled_name = 'inst_' + name
-                    fields[name] = mangled_name, r
-                    myllfields.append((mangled_name, r.lowleveltype))
-
-            # Sort the instance attributes by decreasing "likely size",
-            # as reported by rffi.sizeof(), to minimize padding holes in C.
-            # Fields of the same size are sorted by name (by attrs.sort()
-            # above) just to minimize randomness.
-            def keysize((_, T)):
-                if T is lltype.Void:
-                    return None
-                from rpython.rtyper.lltypesystem.rffi import sizeof
-                try:
-                    return -sizeof(T)
-                except StandardError:
-                    return None
-            myllfields.sort(key = keysize)
-            if llfields is None:
-                llfields = myllfields
-            else:
-                llfields = llfields + myllfields
-
-            self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef,
-                                         self.gcflavor)
-            self.rbase.setup()
-
-            MkStruct = lltype.STRUCT_BY_FLAVOR[LLFLAVOR[self.gcflavor]]
-            if adtmeths is None:
-                adtmeths = {}
-            if hints is None:
-                hints = {}
-            hints = self._check_for_immutable_hints(hints)
-            kwds = {}
-            if self.gcflavor == 'gc':
-                kwds['rtti'] = True
-
-            for name, attrdef in attrs:
-                if not attrdef.readonly and self.is_quasi_immutable(name):
-                    llfields.append(('mutate_' + name, OBJECTPTR))
-
-            object_type = MkStruct(self.classdef.name,
-                                   ('super', self.rbase.object_type),
-                                   hints=hints,
-                                   adtmeths=adtmeths,
-                                   *llfields,
-                                   **kwds)
-            self.object_type.become(object_type)
-            allinstancefields.update(self.rbase.allinstancefields)
-        allinstancefields.update(fields)
-        self.fields = fields
-        self.allinstancefields = allinstancefields
-
-    def _setup_repr_final(self):
-        AbstractInstanceRepr._setup_repr_final(self)
-        if self.gcflavor == 'gc':
-            if (self.classdef is not None and
-                self.classdef.classdesc.lookup('__del__') is not None):
-                s_func = self.classdef.classdesc.s_read_attribute('__del__')
-                source_desc = self.classdef.classdesc.lookup('__del__')
-                source_classdef = source_desc.getclassdef(None)
-                source_repr = getinstancerepr(self.rtyper, source_classdef)
-                assert len(s_func.descriptions) == 1
-                funcdesc, = s_func.descriptions
-                graph = funcdesc.getuniquegraph()
-                self.check_graph_of_del_does_not_call_too_much(graph)
-                FUNCTYPE = FuncType([Ptr(source_repr.object_type)], Void)
-                destrptr = functionptr(FUNCTYPE, graph.name,
-                                       graph=graph,
-                                       _callable=graph.func)
-            else:
-                destrptr = None
-            OBJECT = OBJECT_BY_FLAVOR[LLFLAVOR[self.gcflavor]]
-            self.rtyper.attachRuntimeTypeInfoFunc(self.object_type,
-                                                  ll_runtime_type_info,
-                                                  OBJECT, destrptr)
-            vtable = self.rclass.getvtable()
-            self.rtyper.set_type_for_typeptr(vtable, self.lowleveltype.TO)
-
-    def common_repr(self): # -> object or nongcobject reprs
-        return getinstancerepr(self.rtyper, None, self.gcflavor)
-
-    def _get_field(self, attr):
-        return self.fields[attr]
-
-    def null_instance(self):
-        return nullptr(self.object_type)
-
-    def upcast(self, result):
-        return cast_pointer(self.lowleveltype, result)
-
-    def create_instance(self):
-        return malloc(self.object_type, flavor=self.gcflavor, immortal=True)
-
-    def initialize_prebuilt_data(self, value, classdef, result):
-        if self.classdef is not None:
-            # recursively build the parent part of the instance
-            self.rbase.initialize_prebuilt_data(value, classdef, result.super)
-            # then add instance attributes from this level
-            for name, (mangled_name, r) in self.fields.items():
-                if r.lowleveltype is Void:
-                    llattrvalue = None
-                else:
-                    try:
-                        attrvalue = getattr(value, name)
-                    except AttributeError:
-                        attrvalue = self.classdef.classdesc.read_attribute(name, None)
-                        if attrvalue is None:
-                            # Ellipsis from get_reusable_prebuilt_instance()
-                            if value is not Ellipsis:
-                                warning("prebuilt instance %r has no "
-                                        "attribute %r" % (value, name))
-                            llattrvalue = r.lowleveltype._defl()
-                        else:
-                            llattrvalue = r.convert_desc_or_const(attrvalue)
-                    else:
-                        llattrvalue = r.convert_const(attrvalue)
-                setattr(result, mangled_name, llattrvalue)
-        else:
-            # OBJECT part
-            rclass = getclassrepr(self.rtyper, classdef)
-            result.typeptr = rclass.getvtable()
-
-    def initialize_prebuilt_hash(self, value, result):
-        llattrvalue = getattr(value, '__precomputed_identity_hash', None)
-        if llattrvalue is not None:
-            lltype.init_identity_hash(result, llattrvalue)
-
-    def getfieldrepr(self, attr):
-        """Return the repr used for the given attribute."""
-        if attr in self.fields:
-            mangled_name, r = self.fields[attr]
-            return r
-        else:
-            if self.classdef is None:
-                raise MissingRTypeAttribute(attr)
-            return self.rbase.getfieldrepr(attr)
-
-    def getfield(self, vinst, attr, llops, force_cast=False, flags={}):
-        """Read the given attribute (or __class__ for the type) of 'vinst'."""
-        if attr in self.fields:
-            mangled_name, r = self.fields[attr]
-            cname = inputconst(Void, mangled_name)
-            if force_cast:
-                vinst = llops.genop('cast_pointer', [vinst], resulttype=self)
-            self.hook_access_field(vinst, cname, llops, flags)
-            return llops.genop('getfield', [vinst, cname], resulttype=r)
-        else:
-            if self.classdef is None:
-                raise MissingRTypeAttribute(attr)
-            return self.rbase.getfield(vinst, attr, llops, force_cast=True,
-                                       flags=flags)
-
-    def setfield(self, vinst, attr, vvalue, llops, force_cast=False,
-                 flags={}):
-        """Write the given attribute (or __class__ for the type) of 'vinst'."""
-        if attr in self.fields:
-            mangled_name, r = self.fields[attr]
-            cname = inputconst(Void, mangled_name)
-            if force_cast:
-                vinst = llops.genop('cast_pointer', [vinst], resulttype=self)
-            self.hook_access_field(vinst, cname, llops, flags)
-            self.hook_setfield(vinst, attr, llops)
-            llops.genop('setfield', [vinst, cname, vvalue])
-        else:
-            if self.classdef is None:
-                raise MissingRTypeAttribute(attr)
-            self.rbase.setfield(vinst, attr, vvalue, llops, force_cast=True,
-                                flags=flags)
-
-    def new_instance(self, llops, classcallhop=None):
-        """Build a new instance, without calling __init__."""
-        flavor = self.gcflavor
-        flags = {'flavor': flavor }
-        ctype = inputconst(Void, self.object_type)
-        cflags = inputconst(Void, flags)
-        vlist = [ctype, cflags]
-        vptr = llops.genop('malloc', vlist,
-                           resulttype = Ptr(self.object_type))
-        ctypeptr = inputconst(CLASSTYPE, self.rclass.getvtable())
-        self.setfield(vptr, '__class__', ctypeptr, llops)
-        # initialize instance attributes from their defaults from the class
-        if self.classdef is not None:
-            flds = self.allinstancefields.keys()
-            flds.sort()
-            for fldname in flds:
-                if fldname == '__class__':
-                    continue
-                mangled_name, r = self.allinstancefields[fldname]
-                if r.lowleveltype is Void:
-                    continue
-                value = self.classdef.classdesc.read_attribute(fldname, None)
-                if value is not None:
-                    cvalue = inputconst(r.lowleveltype,
-                                        r.convert_desc_or_const(value))
-                    self.setfield(vptr, fldname, cvalue, llops,
-                                  flags={'access_directly': True})
-        return vptr
-
-    def rtype_type(self, hop):
-        if hop.s_result.is_constant():
-            return hop.inputconst(hop.r_result, hop.s_result.const)
-        instance_repr = self.common_repr()
-        vinst, = hop.inputargs(instance_repr)
-        if hop.args_s[0].can_be_none():
-            return hop.gendirectcall(ll_inst_type, vinst)
-        else:
-            return instance_repr.getfield(vinst, '__class__', hop.llops)
-
-    def rtype_getattr(self, hop):
-        if hop.s_result.is_constant():
-            return hop.inputconst(hop.r_result, hop.s_result.const)
-        attr = hop.args_s[1].const
-        vinst, vattr = hop.inputargs(self, Void)
-        if attr == '__class__' and hop.r_result.lowleveltype is Void:
-            # special case for when the result of '.__class__' is a constant
-            [desc] = hop.s_result.descriptions
-            return hop.inputconst(Void, desc.pyobj)
-        if attr in self.allinstancefields:
-            return self.getfield(vinst, attr, hop.llops,
-                                 flags=hop.args_s[0].flags)
-        elif attr in self.rclass.allmethods:
-            # special case for methods: represented as their 'self' only
-            # (see MethodsPBCRepr)
-            return hop.r_result.get_method_from_instance(self, vinst,
-                                                         hop.llops)
-        else:
-            vcls = self.getfield(vinst, '__class__', hop.llops)
-            return self.rclass.getclsfield(vcls, attr, hop.llops)
-
-    def rtype_setattr(self, hop):
-        attr = hop.args_s[1].const
-        r_value = self.getfieldrepr(attr)
-        vinst, vattr, vvalue = hop.inputargs(self, Void, r_value)
-        self.setfield(vinst, attr, vvalue, hop.llops,
-                      flags=hop.args_s[0].flags)
-
-    def rtype_bool(self, hop):
-        vinst, = hop.inputargs(self)
-        return hop.genop('ptr_nonzero', [vinst], resulttype=Bool)
-
-    def ll_str(self, i): # doesn't work for non-gc classes!
-        from rpython.rtyper.lltypesystem.ll_str import ll_int2hex
-        from rpython.rlib.rarithmetic import r_uint
-        if not i:
-            return rstr.null_str
-        instance = cast_pointer(OBJECTPTR, i)
-        # Two choices: the first gives a fast answer but it can change
-        # (typically only once) during the life of the object.
-        #uid = r_uint(cast_ptr_to_int(i))
-        uid = r_uint(llop.gc_id(lltype.Signed, i))
-        #
-        res =                        rstr.instance_str_prefix
-        res = rstr.ll_strconcat(res, instance.typeptr.name)
-        res = rstr.ll_strconcat(res, rstr.instance_str_infix)
-        res = rstr.ll_strconcat(res, ll_int2hex(uid, False))
-        res = rstr.ll_strconcat(res, rstr.instance_str_suffix)
-        return res
-
-    def rtype_isinstance(self, hop):
-        class_repr = get_type_repr(hop.rtyper)
-        instance_repr = self.common_repr()
-
-        v_obj, v_cls = hop.inputargs(instance_repr, class_repr)
-        if isinstance(v_cls, Constant):
-            cls = v_cls.value
-            # XXX re-implement the following optimization
-            #if cls.subclassrange_max == cls.subclassrange_min:
-            #    # a class with no subclass
-            #    return hop.gendirectcall(rclass.ll_isinstance_exact, v_obj, v_cls)
-            #else:
-            minid = hop.inputconst(Signed, cls.subclassrange_min)
-            maxid = hop.inputconst(Signed, cls.subclassrange_max)
-            return hop.gendirectcall(ll_isinstance_const, v_obj, minid, maxid)
-        else:
-            return hop.gendirectcall(ll_isinstance, v_obj, v_cls)
-
-
-
-class __extend__(pairtype(InstanceRepr, InstanceRepr)):
-    def convert_from_to((r_ins1, r_ins2), v, llops):
-        # which is a subclass of which?
-        if r_ins1.classdef is None or r_ins2.classdef is None:
-            basedef = None
-        else:
-            basedef = r_ins1.classdef.commonbase(r_ins2.classdef)
-        if basedef == r_ins2.classdef:
-            # r_ins1 is an instance of the subclass: converting to parent
-            v = llops.genop('cast_pointer', [v],
-                            resulttype = r_ins2.lowleveltype)
-            return v
-        elif basedef == r_ins1.classdef:
-            # r_ins2 is an instance of the subclass: potentially unsafe
-            # casting, but we do it anyway (e.g. the annotator produces
-            # such casts after a successful isinstance() check)
-            v = llops.genop('cast_pointer', [v],
-                            resulttype = r_ins2.lowleveltype)
-            return v
-        else:
-            return NotImplemented
-
-    def rtype_is_((r_ins1, r_ins2), hop):
-        if r_ins1.gcflavor != r_ins2.gcflavor:
-            # obscure logic, the is can be true only if both are None
-            v_ins1, v_ins2 = hop.inputargs(r_ins1.common_repr(), r_ins2.common_repr())
-            return hop.gendirectcall(ll_both_none, v_ins1, v_ins2)
-        if r_ins1.classdef is None or r_ins2.classdef is None:
-            basedef = None
-        else:
-            basedef = r_ins1.classdef.commonbase(r_ins2.classdef)
-        r_ins = getinstancerepr(r_ins1.rtyper, basedef, r_ins1.gcflavor)
-        return pairtype(Repr, Repr).rtype_is_(pair(r_ins, r_ins), hop)
-
-    rtype_eq = rtype_is_
-
-    def rtype_ne(rpair, hop):
-        v = rpair.rtype_eq(hop)
-        return hop.genop("bool_not", [v], resulttype=Bool)
-
-# ____________________________________________________________
-#
-#  Low-level implementation of operations on classes and instances
-
-# doesn't work for non-gc stuff!
-def ll_cast_to_object(obj):
-    return cast_pointer(OBJECTPTR, obj)
-
-# doesn't work for non-gc stuff!
-def ll_type(obj):
-    return cast_pointer(OBJECTPTR, obj).typeptr
-
-def ll_issubclass(subcls, cls):
-    return llop.int_between(Bool, cls.subclassrange_min,
-                                  subcls.subclassrange_min,
-                                  cls.subclassrange_max)
-
-def ll_issubclass_const(subcls, minid, maxid):
-    return llop.int_between(Bool, minid, subcls.subclassrange_min, maxid)
-
-
-def ll_isinstance(obj, cls): # obj should be cast to OBJECT or NONGCOBJECT
-    if not obj:
-        return False
-    obj_cls = obj.typeptr
-    return ll_issubclass(obj_cls, cls)
-
-def ll_isinstance_const(obj, minid, maxid):
-    if not obj:
-        return False
-    return ll_issubclass_const(obj.typeptr, minid, maxid)
-
-def ll_isinstance_exact(obj, cls):
-    if not obj:
-        return False
-    obj_cls = obj.typeptr
-    return obj_cls == cls
-
-def ll_runtime_type_info(obj):
-    return obj.typeptr.rtti
-
-def ll_inst_type(obj):
-    if obj:
-        return obj.typeptr
-    else:
-        # type(None) -> NULL  (for now)
-        return nullptr(typeOf(obj).TO.typeptr.TO)
-
-def ll_both_none(ins1, ins2):
-    return not ins1 and not ins2
-
-# ____________________________________________________________
-
-def feedllattr(inst, name, llvalue):
-    p = widest = lltype.normalizeptr(inst)
-    while True:
-        try:
-            return setattr(p, 'inst_' + name, llvalue)
-        except AttributeError:
-            pass
-        try:
-            p = p.super
-        except AttributeError:
-            break
-    raise AttributeError("%s has no field %s" % (lltype.typeOf(widest),
-                                                 name))
-
-def declare_type_for_typeptr(vtable, TYPE):
-    """Hack for custom low-level-only 'subclasses' of OBJECT:
-    call this somewhere annotated, in order to declare that it is
-    of the given TYPE and has got the corresponding vtable."""
-
-class Entry(ExtRegistryEntry):
-    _about_ = declare_type_for_typeptr
-    def compute_result_annotation(self, s_vtable, s_TYPE):
-        assert s_vtable.is_constant()
-        assert s_TYPE.is_constant()
-        return annmodel.s_None
-    def specialize_call(self, hop):
-        vtable = hop.args_v[0].value
-        TYPE   = hop.args_v[1].value
-        assert lltype.typeOf(vtable) == CLASSTYPE
-        assert isinstance(TYPE, GcStruct)
-        assert lltype._castdepth(TYPE, OBJECT) > 0
-        hop.rtyper.set_type_for_typeptr(vtable, TYPE)
-        hop.exception_cannot_occur()
-        return hop.inputconst(lltype.Void, None)
diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -1151,7 +1151,7 @@
 
         argsiter = iter(sourcevarsrepr)
 
-        from rpython.rtyper.lltypesystem.rclass import InstanceRepr
+        from rpython.rtyper.rclass import InstanceRepr
         for i, thing in enumerate(things):
             if isinstance(thing, tuple):
                 code = thing[0]
diff --git a/rpython/rtyper/lltypesystem/rtagged.py b/rpython/rtyper/lltypesystem/rtagged.py
--- a/rpython/rtyper/lltypesystem/rtagged.py
+++ b/rpython/rtyper/lltypesystem/rtagged.py
@@ -1,9 +1,7 @@
-from rpython.flowspace.model import Constant
-from rpython.rtyper.rclass import getclassrepr, getinstancerepr, get_type_repr
 from rpython.rtyper.lltypesystem import lltype
-from rpython.rtyper.lltypesystem.rclass import InstanceRepr, CLASSTYPE, ll_inst_type
-from rpython.rtyper.lltypesystem.rclass import MissingRTypeAttribute
-from rpython.rtyper.lltypesystem.rclass import ll_issubclass_const
+from rpython.rtyper.rclass import (
+    InstanceRepr, CLASSTYPE, ll_inst_type, MissingRTypeAttribute,
+    ll_issubclass_const, getclassrepr, getinstancerepr, get_type_repr)
 from rpython.rtyper.rmodel import TyperError, inputconst
 
 
diff --git a/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py b/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py
--- a/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py
+++ b/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py
@@ -106,7 +106,7 @@
         #     s1.ptr = & s1.buf;
         S2 = lltype.Struct('S2', ('y', lltype.Signed))
         S1 = lltype.Struct('S',
-                           ('sub', lltype.Struct('SUB', 
+                           ('sub', lltype.Struct('SUB',
                                                  ('ptr', lltype.Ptr(S2)))),
                            ('ptr', lltype.Ptr(S2)),
                            ('buf', S2), # Works when this field is first!
@@ -1232,7 +1232,7 @@
         assert adr1 == adr1_2
 
     def test_object_subclass(self):
-        from rpython.rtyper.lltypesystem import rclass
+        from rpython.rtyper import rclass
         from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr
         from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance
         class S:
@@ -1250,7 +1250,7 @@
         assert res == 123
 
     def test_object_subclass_2(self):
-        from rpython.rtyper.lltypesystem import rclass
+        from rpython.rtyper import rclass
         SCLASS = lltype.GcStruct('SCLASS',
                                  ('parent', rclass.OBJECT),
                                  ('n', lltype.Signed))
@@ -1270,7 +1270,7 @@
         assert res == 123
 
     def test_object_subclass_3(self):
-        from rpython.rtyper.lltypesystem import rclass
+        from rpython.rtyper import rclass
         from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr
         from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance
         class S:
@@ -1289,7 +1289,7 @@
         assert res == 123
 
     def test_object_subclass_4(self):
-        from rpython.rtyper.lltypesystem import rclass
+        from rpython.rtyper import rclass
         SCLASS = lltype.GcStruct('SCLASS',
                                  ('parent', rclass.OBJECT),
                                  ('n', lltype.Signed))
@@ -1310,7 +1310,7 @@
         assert res == 123
 
     def test_object_subclass_5(self):
-        from rpython.rtyper.lltypesystem import rclass
+        from rpython.rtyper import rclass
         from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr
         from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance
         class S:
@@ -1366,7 +1366,7 @@
     def test_opaque_tagged_pointers(self):
         from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance
         from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr
-        from rpython.rtyper.lltypesystem import rclass
+        from rpython.rtyper import rclass
 
         class Opaque(object):
             llopaque = True
diff --git a/rpython/rtyper/normalizecalls.py b/rpython/rtyper/normalizecalls.py
--- a/rpython/rtyper/normalizecalls.py
+++ b/rpython/rtyper/normalizecalls.py
@@ -216,12 +216,12 @@
 
 # ____________________________________________________________
 
-def merge_classpbc_getattr_into_classdef(rtyper):
+def merge_classpbc_getattr_into_classdef(annotator):
     # code like 'some_class.attr' will record an attribute access in the
     # PBC access set of the family of classes of 'some_class'.  If the classes
     # have corresponding ClassDefs, they are not updated by the annotator.
     # We have to do it now.
-    all_families = rtyper.annotator.bookkeeper.classpbc_attr_families
+    all_families = annotator.bookkeeper.classpbc_attr_families
     for attrname, access_sets in all_families.items():
         for access_set in access_sets.infos():
             descs = access_set.descs
@@ -236,9 +236,8 @@
                 if commonbase is None:
                     raise TyperError("reading attribute %r: no common base "
                                      "class for %r" % (attrname, descs.keys()))
-            extra_access_sets = rtyper.class_pbc_attributes.setdefault(
-                commonbase, {})
-            if commonbase in rtyper.class_reprs:
+            extra_access_sets = commonbase.extra_access_sets
+            if commonbase.repr is not None:
                 assert access_set in extra_access_sets # minimal sanity check
                 continue
             access_set.commonbase = commonbase
@@ -387,13 +386,13 @@
 
 # ____________________________________________________________
 
-def perform_normalizations(rtyper):
-    create_class_constructors(rtyper.annotator)
-    rtyper.annotator.frozen += 1
+def perform_normalizations(annotator):
+    create_class_constructors(annotator)
+    annotator.frozen += 1
     try:
-        normalize_call_familes(rtyper.annotator)
-        merge_classpbc_getattr_into_classdef(rtyper)
-        assign_inheritance_ids(rtyper.annotator)
+        normalize_call_familes(annotator)
+        merge_classpbc_getattr_into_classdef(annotator)
+        assign_inheritance_ids(annotator)
     finally:
-        rtyper.annotator.frozen -= 1
-    create_instantiate_functions(rtyper.annotator)
+        annotator.frozen -= 1
+    create_instantiate_functions(annotator)
diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py
--- a/rpython/rtyper/rbuiltin.py
+++ b/rpython/rtyper/rbuiltin.py
@@ -3,7 +3,8 @@
 from rpython.rlib import rarithmetic, objectmodel
 from rpython.rtyper import raddress, rptr, extregistry, rrange
 from rpython.rtyper.error import TyperError
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rstr
+from rpython.rtyper.lltypesystem import lltype, llmemory, rstr
+from rpython.rtyper import rclass
 from rpython.rtyper.rmodel import Repr
 from rpython.tool.pairtype import pairtype
 
diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py
--- a/rpython/rtyper/rclass.py
+++ b/rpython/rtyper/rclass.py
@@ -1,13 +1,23 @@
+import sys
 import types
 
 from rpython.flowspace.model import Constant
 from rpython.flowspace.operation import op
 from rpython.annotator import description, model as annmodel
+from rpython.rlib.objectmodel import UnboxedValue
+from rpython.tool.pairtype import pairtype, pair
+from rpython.tool.identity_dict import identity_dict
+from rpython.rtyper.extregistry import ExtRegistryEntry
 from rpython.rtyper.error import TyperError
-from rpython.rtyper.lltypesystem.lltype import Void
-from rpython.rtyper.rmodel import Repr, getgcflavor, inputconst
-from rpython.rlib.objectmodel import UnboxedValue
-from rpython.tool.pairtype import pairtype
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rtyper.lltypesystem.lltype import (
+    Ptr, Struct, GcStruct, malloc, cast_pointer, castable, nullptr,
+    RuntimeTypeInfo, getRuntimeTypeInfo, typeOf, Void, FuncType, Bool, Signed,
+    functionptr)
+from rpython.rtyper.lltypesystem.lloperation import llop
+from rpython.rtyper.lltypesystem import rstr
+from rpython.rtyper.rmodel import (
+    Repr, getgcflavor, inputconst, warning, mangle)
 
 
 class FieldListAccessor(object):
@@ -53,12 +63,11 @@
 
 
 def getclassrepr(rtyper, classdef):
-    try:
-        result = rtyper.class_reprs[classdef]
-    except KeyError:
-        from rpython.rtyper.lltypesystem.rclass import ClassRepr
-        result = ClassRepr(rtyper, classdef)
-        rtyper.class_reprs[classdef] = result
+    if classdef is None:
+        return rtyper.rootclass_repr
+    result = classdef.repr
+    if result is None:
+        result = classdef.repr = ClassRepr(rtyper, classdef)
         rtyper.add_pendingsetup(result)
     return result
 
@@ -84,11 +93,11 @@
         unboxed = []
         virtualizable = False
     else:
-        unboxed = [subdef for subdef in classdef.getallsubdefs()
-                          if subdef.classdesc.pyobj is not None and
-                             issubclass(subdef.classdesc.pyobj, UnboxedValue)]
-        virtualizable = classdef.classdesc.read_attribute('_virtualizable_',
-                                                           Constant(False)).value
+        unboxed = [subdef for subdef in classdef.getallsubdefs() if
+            subdef.classdesc.pyobj is not None and
+            issubclass(subdef.classdesc.pyobj, UnboxedValue)]
+        virtualizable = classdef.classdesc.read_attribute(
+            '_virtualizable_', Constant(False)).value
     config = rtyper.annotator.translator.config
     usetagging = len(unboxed) != 0 and config.translation.taggedpointers
 
@@ -106,20 +115,86 @@
         from rpython.rtyper.lltypesystem import rtagged
         return rtagged.TaggedInstanceRepr(rtyper, classdef, unboxed[0])
     else:
-        from rpython.rtyper.lltypesystem.rclass import InstanceRepr
         return InstanceRepr(rtyper, classdef, gcflavor)
 
 
 class MissingRTypeAttribute(TyperError):
     pass
 
-class AbstractClassRepr(Repr):
+# ____________________________________________________________
+
+
+#
+#  There is one "vtable" per user class, with the following structure:
+#  A root class "object" has:
+#
+#      struct object_vtable {
+#          // struct object_vtable* parenttypeptr;  not used any more
+#          RuntimeTypeInfo * rtti;
+#          Signed subclassrange_min;  //this is also the id of the class itself
+#          Signed subclassrange_max;
+#          RPyString * name;
+#          struct object * instantiate();
+#      }
+#
+#  Every other class X, with parent Y, has the structure:
+#
+#      struct vtable_X {
+#          struct vtable_Y super;   // inlined
+#          ...                      // extra class attributes
+#      }
+
+# The type of the instances is:
+#
+#     struct object {       // for the root class
+#         struct object_vtable* typeptr;
+#     }
+#
+#     struct X {
+#         struct Y super;   // inlined
+#         ...               // extra instance attributes
+#     }
+#
+# there's also a nongcobject
+
+OBJECT_VTABLE = lltype.ForwardReference()
+CLASSTYPE = Ptr(OBJECT_VTABLE)
+OBJECT = GcStruct('object', ('typeptr', CLASSTYPE),
+                  hints={'immutable': True, 'shouldntbenull': True,
+                         'typeptr': True},
+                  rtti=True)
+OBJECTPTR = Ptr(OBJECT)
+OBJECT_VTABLE.become(Struct('object_vtable',
+                            #('parenttypeptr', CLASSTYPE),
+                            ('subclassrange_min', Signed),
+                            ('subclassrange_max', Signed),
+                            ('rtti', Ptr(RuntimeTypeInfo)),
+                            ('name', Ptr(rstr.STR)),
+                            ('hash', Signed),
+                            ('instantiate', Ptr(FuncType([], OBJECTPTR))),
+                            hints={'immutable': True}))
+# non-gc case
+NONGCOBJECT = Struct('nongcobject', ('typeptr', CLASSTYPE))
+NONGCOBJECTPTR = Ptr(NONGCOBJECT)
+
+OBJECT_BY_FLAVOR = {'gc': OBJECT, 'raw': NONGCOBJECT}
+LLFLAVOR = {'gc': 'gc', 'raw': 'raw', 'stack': 'raw'}
+
+def cast_vtable_to_typeptr(vtable):
+    while typeOf(vtable).TO != OBJECT_VTABLE:
+        vtable = vtable.super
+    return vtable
+
+def alloc_array_name(name):
+    return rstr.string_repr.convert_const(name)
+
+
+class ClassRepr(Repr):
     def __init__(self, rtyper, classdef):
         self.rtyper = rtyper
         self.classdef = classdef
-
-    def _setup_repr(self):
-        pass
+        self.vtable_type = lltype.ForwardReference()
+        self.lowleveltype = Ptr(self.vtable_type)
 
     def __repr__(self):
         if self.classdef is None:
@@ -165,8 +240,201 @@
     def get_ll_eq_function(self):
         return None
 
+    def _setup_repr(self):
+        # NOTE: don't store mutable objects like the dicts below on 'self'
+        #       before they are fully built, to avoid strange bugs in case
+        #       of recursion where other code would uses these
+        #       partially-initialized dicts.
+        clsfields = {}
+        pbcfields = {}
+        allmethods = {}
+        # class attributes
+        llfields = []
+        attrs = self.classdef.attrs.items()
+        attrs.sort()
+        for name, attrdef in attrs:
+            if attrdef.readonly:
+                s_value = attrdef.s_value
+                s_unboundmethod = self.prepare_method(s_value)
+                if s_unboundmethod is not None:
+                    allmethods[name] = True
+                    s_value = s_unboundmethod
+                r = self.rtyper.getrepr(s_value)
+                mangled_name = 'cls_' + name
+                clsfields[name] = mangled_name, r
+                llfields.append((mangled_name, r.lowleveltype))
+        # attributes showing up in getattrs done on the class as a PBC
+        extra_access_sets = self.classdef.extra_access_sets
+        for access_set, (attr, counter) in extra_access_sets.items():
+            r = self.rtyper.getrepr(access_set.s_value)
+            mangled_name = mangle('pbc%d' % counter, attr)
+            pbcfields[access_set, attr] = mangled_name, r
+            llfields.append((mangled_name, r.lowleveltype))
+        #
+        self.rbase = getclassrepr(self.rtyper, self.classdef.basedef)
+        self.rbase.setup()
+        kwds = {'hints': {'immutable': True}}
+        vtable_type = Struct('%s_vtable' % self.classdef.name,
+                                ('super', self.rbase.vtable_type),
+                                *llfields, **kwds)
+        self.vtable_type.become(vtable_type)
+        allmethods.update(self.rbase.allmethods)
+        self.clsfields = clsfields
+        self.pbcfields = pbcfields
+        self.allmethods = allmethods
+        self.vtable = None
+
+    def getvtable(self):
+        """Return a ptr to the vtable of this type."""
+        if self.vtable is None:
+            self.init_vtable()
+        return cast_vtable_to_typeptr(self.vtable)
+
+    def getruntime(self, expected_type):
+        assert expected_type == CLASSTYPE
+        return self.getvtable()
+
+    def init_vtable(self):
+        """Create the actual vtable"""
+        self.vtable = malloc(self.vtable_type, immortal=True)
+        vtable_part = self.vtable
+        r_parentcls = self
+        while r_parentcls.classdef is not None:
+            self.setup_vtable(vtable_part, r_parentcls)
+            vtable_part = vtable_part.super
+            r_parentcls = r_parentcls.rbase
+        self.fill_vtable_root(vtable_part)
+
+    def setup_vtable(self, vtable, r_parentcls):
+        """Initialize the vtable portion corresponding to 'r_parentcls'."""
+        # setup class attributes: for each attribute name at the level
+        # of 'r_parentcls', look up its value in the class
+        def assign(mangled_name, value):
+            if (isinstance(value, Constant) and
+                    isinstance(value.value, staticmethod)):
+                value = Constant(value.value.__get__(42))   # staticmethod => bare function
+            llvalue = r.convert_desc_or_const(value)
+            setattr(vtable, mangled_name, llvalue)
+
+        for fldname in r_parentcls.clsfields:
+            mangled_name, r = r_parentcls.clsfields[fldname]
+            if r.lowleveltype is Void:
+                continue
+            value = self.classdef.classdesc.read_attribute(fldname, None)
+            if value is not None:
+                assign(mangled_name, value)
+        # extra PBC attributes
+        for (access_set, attr), (mangled_name, r) in r_parentcls.pbcfields.items():
+            if self.classdef.classdesc not in access_set.descs:
+                continue   # only for the classes in the same pbc access set
+            if r.lowleveltype is Void:
+                continue
+            attrvalue = self.classdef.classdesc.read_attribute(attr, None)
+            if attrvalue is not None:
+                assign(mangled_name, attrvalue)
+
+    def fill_vtable_root(self, vtable):
+        """Initialize the head of the vtable."""
+        vtable.hash = hash(self)
+        # initialize the 'subclassrange_*' and 'name' fields
+        if self.classdef is not None:
+            #vtable.parenttypeptr = self.rbase.getvtable()
+            vtable.subclassrange_min = self.classdef.minid
+            vtable.subclassrange_max = self.classdef.maxid
+        else:  # for the root class
+            vtable.subclassrange_min = 0


More information about the pypy-commit mailing list