Author: Ronan Lamy <ronan.l...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit