Author: Ronan Lamy <ronan.l...@gmail.com> Branch: ClassRepr Changeset: r73906:dbf051e242ff Date: 2014-10-12 19:20 +0100 http://bitbucket.org/pypy/pypy/changeset/dbf051e242ff/
Log: merge rtyper.rclass and rtyper.lltypesystem.rclass diff too long, truncating to 2000 out of 2571 lines 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 @@ -565,7 +566,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_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 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,9 +402,9 @@ # 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 from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance - from rpython.rtyper.lltypesystem import rclass + from rpython.rtyper 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 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 @@ -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 = getclassrepr(rtyper, None) + 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/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): @@ -56,7 +66,6 @@ try: result = rtyper.class_reprs[classdef] except KeyError: - from rpython.rtyper.lltypesystem.rclass import ClassRepr result = ClassRepr(rtyper, classdef) rtyper.class_reprs[classdef] = result rtyper.add_pendingsetup(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,13 +115,80 @@ 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 +# ____________________________________________________________ + + +# +# 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 AbstractClassRepr(Repr): def __init__(self, rtyper, classdef): self.rtyper = rtyper @@ -165,6 +241,208 @@ def get_ll_eq_function(self): return None + +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) + def get_type_repr(rtyper): return getclassrepr(rtyper, None) @@ -202,11 +480,11 @@ raise ImmutableConflictError( "class %r inherits from its parent _immutable_=True, " "so it should also declare _immutable_=True" % ( - self.classdef,)) + self.classdef,)) if loc.classdict.get('_immutable_').value is not True: raise TyperError( "class %r: _immutable_ = something else than True" % ( - self.classdef,)) + self.classdef,)) hints = hints.copy() hints['immutable'] = True self.immutable_field_set = set() # unless overwritten below @@ -293,14 +571,14 @@ if is_self_immutable: raise ImmutableConflictError( "class %r has _immutable_=True, but parent class %r " - "defines (at least) the mutable field %r" % ( - self, base, fieldname)) + "defines (at least) the mutable field %r" % + (self, base, fieldname)) if (fieldname in self.immutable_field_set or - (fieldname + '?') in self.immutable_field_set): + (fieldname + '?') in self.immutable_field_set): raise ImmutableConflictError( "field %r is defined mutable in class %r, but " - "listed in _immutable_fields_ in subclass %r" % ( - fieldname, base, self)) + "listed in _immutable_fields_ in subclass %r" % + (fieldname, base, self)) def hook_access_field(self, vinst, cname, llops, flags): pass # for virtualizables; see rvirtualizable.py @@ -316,7 +594,7 @@ rbase = self while rbase.classdef is not None: if (search1 in rbase.immutable_field_set or - search2 in rbase.immutable_field_set): + search2 in rbase.immutable_field_set): return True rbase = rbase.rbase return False @@ -461,8 +739,8 @@ g = seen.get(g) lst.append('') raise TyperError("the RPython-level __del__() method " - "in %r calls:%s" % ( - graph, '\n\t'.join(lst[::-1]))) + "in %r calls:%s" % + (graph, '\n\t'.join(lst[::-1]))) if getattr(func, '_cannot_really_call_random_things_', False): continue @@ -478,7 +756,356 @@ def rtype_setitem((r_ins, r_obj), hop): return r_ins._emulate_call(hop, "__setitem__") +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 = {} _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit