[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