Author: Philip Jenvey <pjen...@underboss.org> Branch: py3k Changeset: r74007:dfd4a9093328 Date: 2014-10-17 15:45 -0700 http://bitbucket.org/pypy/pypy/changeset/dfd4a9093328/
Log: merge default diff too long, truncating to 2000 out of 3968 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/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -258,6 +258,7 @@ enable_translationmodules(config) config.translation.suggest(check_str_without_nul=True) + config.translation.suggest(shared=True) if config.translation.thread: config.objspace.usemodules.thread = True 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/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -4,6 +4,7 @@ import_from_mixin, newlist_hint, resizelist_hint, specialize) from rpython.rlib.buffer import Buffer from rpython.rlib.rstring import StringBuilder, ByteListBuilder +from rpython.rlib.debug import check_list_of_chars from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError, oefmt @@ -23,6 +24,7 @@ import_from_mixin(StringMethods) def __init__(self, data): + check_list_of_chars(data) self.data = data def __repr__(self): diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py --- a/rpython/annotator/annrpython.py +++ b/rpython/annotator/annrpython.py @@ -249,10 +249,6 @@ assert s_value.contains(s_old) arg.annotation = s_value - def transfer_binding(self, v_target, v_source): - assert v_source.annotation is not None - v_target.annotation = v_source.annotation - def warning(self, msg, pos=None): if pos is None: try: @@ -579,7 +575,7 @@ for arg in op.args: if isinstance(self.annotation(arg), annmodel.SomeImpossibleValue): raise BlockedInference(self, op, -1) - resultcell = op.consider(self, *op.args) + resultcell = op.consider(self) if resultcell is None: resultcell = annmodel.s_ImpossibleValue elif resultcell == annmodel.s_ImpossibleValue: diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -559,10 +559,6 @@ assert self.annotator.binding(op.args[pos]) == s_type return op - def ondegenerated(self, what, s_value, where=None, called_from_graph=None): - self.annotator.ondegenerated(what, s_value, where=where, - called_from_graph=called_from_graph) - def whereami(self): return self.annotator.whereami(self.position_key) 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/annotator/description.py b/rpython/annotator/description.py --- a/rpython/annotator/description.py +++ b/rpython/annotator/description.py @@ -14,7 +14,6 @@ objects, where the equivalence relation is the transitive closure of 'd1~d2 if d1 and d2 might be called at the same call site'. """ - overridden = False normalized = False modified = True @@ -175,7 +174,6 @@ class FunctionDesc(Desc): knowntype = types.FunctionType - overridden = False def __init__(self, bookkeeper, pyobj=None, name=None, signature=None, defaults=None, diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -96,10 +96,10 @@ def constfold(self): return None - def consider(self, annotator, *args): - args_s = [annotator.annotation(arg) for arg in args] + def consider(self, annotator): + args_s = [annotator.annotation(arg) for arg in self.args] spec = type(self).get_specialization(*args_s) - return spec(annotator, *args) + return spec(annotator, *self.args) def get_can_only_throw(self, annotator): return None @@ -447,7 +447,7 @@ opname = 'newdict' canraise = [] - def consider(self, annotator, *args): + def consider(self, annotator): return annotator.bookkeeper.newdict() @@ -456,16 +456,17 @@ pyfunc = staticmethod(lambda *args: args) canraise = [] - def consider(self, annotator, *args): - return SomeTuple(items=[annotator.annotation(arg) for arg in args]) + def consider(self, annotator): + return SomeTuple(items=[annotator.annotation(arg) for arg in self.args]) class NewList(HLOperation): opname = 'newlist' canraise = [] - def consider(self, annotator, *args): - return annotator.bookkeeper.newlist(*[annotator.annotation(arg) for arg in args]) + def consider(self, annotator): + return annotator.bookkeeper.newlist( + *[annotator.annotation(arg) for arg in self.args]) class Pow(PureOperation): 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 @@ -548,12 +549,6 @@ type_id = self.layoutbuilder.get_type_id(A) descr.tid = llop.combine_ushort(lltype.Signed, type_id, 0) - def _set_tid(self, gcptr, tid): - hdr_addr = llmemory.cast_ptr_to_adr(gcptr) - hdr_addr -= self.gcheaderbuilder.size_gc_header - hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR) - hdr.tid = tid - def can_use_nursery_malloc(self, size): return size < self.max_size_of_young_obj @@ -565,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/debug.py b/rpython/rlib/debug.py --- a/rpython/rlib/debug.py +++ b/rpython/rlib/debug.py @@ -383,3 +383,35 @@ def specialize_call(self, hop): hop.exception_cannot_occur() return hop.inputarg(hop.args_r[0], arg=0) + +def check_list_of_chars(l): + if not we_are_translated(): + assert isinstance(l, list) + for x in l: + assert isinstance(x, (unicode, str)) and len(x) == 1 + return l + +class NotAListOfChars(Exception): + pass + +class Entry(ExtRegistryEntry): + _about_ = check_list_of_chars + + def compute_result_annotation(self, s_arg): + from rpython.annotator.model import SomeList, s_None + from rpython.annotator.model import SomeChar, SomeUnicodeCodePoint + from rpython.annotator.model import SomeImpossibleValue + if s_None.contains(s_arg): + return s_arg # only None: just return + assert isinstance(s_arg, SomeList) + if not isinstance( + s_arg.listdef.listitem.s_value, + (SomeChar, SomeUnicodeCodePoint, SomeImpossibleValue)): + raise NotAListOfChars + return s_arg + + def specialize_call(self, hop): + hop.exception_cannot_occur() + return hop.inputarg(hop.args_r[0], arg=0) + + 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/rbigint.py b/rpython/rlib/rbigint.py --- a/rpython/rlib/rbigint.py +++ b/rpython/rlib/rbigint.py @@ -44,6 +44,25 @@ MASK = int((1 << SHIFT) - 1) FLOAT_MULTIPLIER = float(1 << SHIFT) +# For BIGINT and INT mix. +# +# The VALID range of an int is different than a valid range of a bigint of length one. +# -1 << LONG_BIT is actually TWO digits, because they are stored without the sign. +if SHIFT == LONG_BIT - 1: + MIN_INT_VALUE = -1 << SHIFT + def int_in_valid_range(x): + if x == MIN_INT_VALUE: + return False + return True +else: + # Means we don't have INT128 on 64bit. + def int_in_valid_range(x): + if x > MASK or x < -MASK: + return False + return True + +int_in_valid_range._always_inline_ = True + # Debugging digit array access. # # False == no checking at all @@ -71,7 +90,6 @@ FIVEARY_CUTOFF = 8 - def _mask_digit(x): return UDIGIT_MASK(x & MASK) _mask_digit._annspecialcase_ = 'specialize:argtype(0)' @@ -384,12 +402,17 @@ digits = ''.join([digits[i] for i in range(length-1, -1, -1)]) return digits - @jit.elidable def toint(self): """ Get an integer from a bigint object. Raises OverflowError if overflow occurs. """ + if self.numdigits() > MAX_DIGITS_THAT_CAN_FIT_IN_INT: + raise OverflowError + return self._toint_helper() + + @jit.elidable + def _toint_helper(self): x = self._touint_helper() # Haven't lost any bits, but if the sign bit is set we're in # trouble *unless* this is the min negative number. So, @@ -422,8 +445,7 @@ prev = x x = (x << SHIFT) + self.udigit(i) if (x >> SHIFT) != prev: - raise OverflowError( - "long int too large to convert to unsigned int (%d, %d)" % (x >> SHIFT, prev)) + raise OverflowError("long int too large to convert to unsigned int") i -= 1 return x @@ -482,10 +504,27 @@ i += 1 return True + @jit.elidable + def int_eq(self, other): + """ eq with int """ + + if not int_in_valid_range(other): + # Fallback to Long. + return self.eq(rbigint.fromint(other)) + + if self.numdigits() > 1: + return False + + return (self.sign * self.digit(0)) == other + @jit.look_inside def ne(self, other): return not self.eq(other) + @jit.look_inside + def int_ne(self, other): + return not self.int_eq(other) + @jit.elidable def lt(self, other): if self.sign > other.sign: @@ -521,18 +560,67 @@ i -= 1 return False + @jit.elidable + def int_lt(self, other): + """ lt where other is an int """ + + if not int_in_valid_range(other): + # Fallback to Long. + return self.lt(rbigint.fromint(other)) + + osign = 1 + if other == 0: + osign = 0 + elif other < 0: + osign = -1 + + if self.sign > osign: + return False + elif self.sign < osign: + return True + + digits = self.numdigits() + + if digits > 1: + if osign == 1: + return False + else: + return True + + d1 = self.sign * self.digit(0) + if d1 < other: + return True + return False + @jit.look_inside def le(self, other): return not other.lt(self) @jit.look_inside + def int_le(self, other): + # Alternative that might be faster, reimplant this. as a check with other + 1. But we got to check for overflow + # or reduce valid range. + + if self.int_eq(other): + return True + return self.int_lt(other) + + @jit.look_inside def gt(self, other): return other.lt(self) @jit.look_inside + def int_gt(self, other): + return not self.int_le(other) + + @jit.look_inside def ge(self, other): return not self.lt(other) + @jit.look_inside + def int_ge(self, other): + return not self.int_lt(other) + @jit.elidable def hash(self): return _hash(self) @@ -551,12 +639,31 @@ return result @jit.elidable + def int_add(self, other): + if not int_in_valid_range(other): + # Fallback to long. + return self.add(rbigint.fromint(other)) + elif self.sign == 0: + return rbigint.fromint(other) + elif other == 0: + return self + + sign = -1 if other < 0 else 1 + if self.sign == sign: + result = _x_int_add(self, other) + else: + result = _x_int_sub(self, other) + result.sign *= -1 + result.sign *= sign + return result + + @jit.elidable def sub(self, other): if other.sign == 0: return self - if self.sign == 0: + elif self.sign == 0: return rbigint(other._digits[:other.size], -other.sign, other.size) - if self.sign == other.sign: + elif self.sign == other.sign: result = _x_sub(self, other) else: result = _x_add(self, other) @@ -564,6 +671,22 @@ return result @jit.elidable + def int_sub(self, other): + if not int_in_valid_range(other): + # Fallback to long. + return self.sub(rbigint.fromint(other)) + elif other == 0: + return self + elif self.sign == 0: + return rbigint.fromint(-other) + elif self.sign == (-1 if other < 0 else 1): + result = _x_int_sub(self, other) + else: + result = _x_int_add(self, other) + result.sign *= self.sign + return result + + @jit.elidable def mul(self, b): asize = self.numdigits() bsize = b.numdigits() @@ -609,6 +732,37 @@ return result @jit.elidable + def int_mul(self, b): + if not int_in_valid_range(b): + # Fallback to long. + return self.mul(rbigint.fromint(b)) + + if self.sign == 0 or b == 0: + return NULLRBIGINT + + asize = self.numdigits() + digit = abs(b) + bsign = -1 if b < 0 else 1 + + if digit == 1: + return rbigint(self._digits[:self.size], self.sign * bsign, asize) + elif asize == 1: + res = self.widedigit(0) * digit + carry = res >> SHIFT + if carry: + return rbigint([_store_digit(res & MASK), _store_digit(carry)], self.sign * bsign, 2) + else: + return rbigint([_store_digit(res & MASK)], self.sign * bsign, 1) + + elif digit & (digit - 1) == 0: + result = self.lqshift(ptwotable[digit]) + else: + result = _muladd1(self, digit) + + result.sign = self.sign * bsign + return result + + @jit.elidable def truediv(self, other): div = _bigint_true_divide(self, other) return div @@ -626,7 +780,7 @@ if mod.sign * other.sign == -1: if div.sign == 0: return ONENEGATIVERBIGINT - div = div.sub(ONERBIGINT) + div = div.int_sub(1) return div @@ -649,7 +803,7 @@ return ONENEGATIVERBIGINT if other.sign == -1 else ONERBIGINT return NULLRBIGINT elif digit & (digit - 1) == 0: - mod = self.and_(rbigint([_store_digit(digit - 1)], 1, 1)) + mod = self.int_and_(digit - 1) else: # Perform size = self.numdigits() - 1 @@ -672,6 +826,48 @@ return mod @jit.elidable + def int_mod(self, other): + if self.sign == 0: + return NULLRBIGINT + + elif not int_in_valid_range(other): + # Fallback to long. + return self.mod(rbigint.fromint(other)) + + elif other != 0: + digit = abs(other) + if digit == 1: + return NULLRBIGINT + elif digit == 2: + modm = self.digit(0) & 1 + if modm: + return ONENEGATIVERBIGINT if other < 0 else ONERBIGINT + return NULLRBIGINT + elif digit & (digit - 1) == 0: + mod = self.int_and_(digit - 1) + else: + # Perform + size = self.numdigits() - 1 + if size > 0: + rem = self.widedigit(size) + size -= 1 + while size >= 0: + rem = ((rem << SHIFT) + self.widedigit(size)) % digit + size -= 1 + else: + rem = self.digit(0) % digit + + if rem == 0: + return NULLRBIGINT + mod = rbigint([_store_digit(rem)], -1 if self.sign < 0 else 1, 1) + else: + raise ZeroDivisionError("long division or modulo by zero") + + if mod.sign * (-1 if other < 0 else 1) == -1: + mod = mod.int_add(other) + return mod + + @jit.elidable def divmod(v, w): """ The / and % operators are now defined in terms of divmod(). @@ -694,7 +890,7 @@ mod = mod.add(w) if div.sign == 0: return ONENEGATIVERBIGINT, mod - div = div.sub(ONERBIGINT) + div = div.int_sub(1) return div, mod @jit.elidable @@ -852,7 +1048,7 @@ if self.sign == 0: return ONENEGATIVERBIGINT - ret = self.add(ONERBIGINT) + ret = self.int_add(1) ret.sign = -ret.sign return ret @@ -997,14 +1193,26 @@ return _bitwise(self, '&', other) @jit.elidable + def int_and_(self, other): + return _int_bitwise(self, '&', other) + + @jit.elidable def xor(self, other): return _bitwise(self, '^', other) @jit.elidable + def int_xor(self, other): + return _int_bitwise(self, '^', other) + + @jit.elidable def or_(self, other): return _bitwise(self, '|', other) @jit.elidable + def int_or_(self, other): + return _int_bitwise(self, '|', other) + + @jit.elidable def oct(self): if self.sign == 0: return '0L' @@ -1084,6 +1292,11 @@ (2 * SHIFT) % 5, (1 * SHIFT) % 5] + +# if the bigint has more digits than this, it cannot fit into an int +MAX_DIGITS_THAT_CAN_FIT_IN_INT = rbigint.fromint(-sys.maxint - 1).numdigits() + + #_________________________________________________________________ # Helper Functions @@ -1182,6 +1395,25 @@ z._normalize() return z +def _x_int_add(a, b): + """ Add the absolute values of one bigint and one integer. """ + size_a = a.numdigits() + + z = rbigint([NULLDIGIT] * (size_a + 1), 1) + i = UDIGIT_TYPE(1) + carry = a.udigit(0) + abs(b) + z.setdigit(0, carry) + carry >>= SHIFT + + while i < size_a: + carry += a.udigit(i) + z.setdigit(i, carry) + carry >>= SHIFT + i += 1 + z.setdigit(i, carry) + z._normalize() + return z + def _x_sub(a, b): """ Subtract the absolute values of two integers. """ @@ -1228,6 +1460,42 @@ z._normalize() return z +def _x_int_sub(a, b): + """ Subtract the absolute values of two integers. """ + + size_a = a.numdigits() + + bdigit = abs(b) + + if size_a == 1: + # Find highest digit where a and b differ: + adigit = a.digit(0) + + if adigit == bdigit: + return NULLRBIGINT + + return rbigint.fromint(adigit - bdigit) + + z = rbigint([NULLDIGIT] * size_a, 1, size_a) + i = _load_unsigned_digit(1) + # The following assumes unsigned arithmetic + # works modulo 2**N for some N>SHIFT. + borrow = a.udigit(0) - bdigit + z.setdigit(0, borrow) + borrow >>= SHIFT + #borrow &= 1 # Keep only one sign bit + + while i < size_a: + borrow = a.udigit(i) - borrow + z.setdigit(i, borrow) + borrow >>= SHIFT + #borrow &= 1 + i += 1 + + assert borrow == 0 + z._normalize() + return z + # A neat little table of power of twos. ptwotable = {} for x in range(SHIFT-1): @@ -2335,6 +2603,89 @@ return z.invert() _bitwise._annspecialcase_ = "specialize:arg(1)" +def _int_bitwise(a, op, b): # '&', '|', '^' + """ Bitwise and/or/xor operations """ + + if not int_in_valid_range(b): + # Fallback to long. + return _bitwise(a, op, rbigint.fromint(b)) + + if a.sign < 0: + a = a.invert() + maska = MASK + else: + maska = 0 + if b < 0: + b = ~b + maskb = MASK + else: + maskb = 0 + + negz = 0 + if op == '^': + if maska != maskb: + maska ^= MASK + negz = -1 + elif op == '&': + if maska and maskb: + op = '|' + maska ^= MASK + maskb ^= MASK + negz = -1 + elif op == '|': + if maska or maskb: + op = '&' + maska ^= MASK + maskb ^= MASK + negz = -1 + + # JRH: The original logic here was to allocate the result value (z) + # as the longer of the two operands. However, there are some cases + # where the result is guaranteed to be shorter than that: AND of two + # positives, OR of two negatives: use the shorter number. AND with + # mixed signs: use the positive number. OR with mixed signs: use the + # negative number. After the transformations above, op will be '&' + # iff one of these cases applies, and mask will be non-0 for operands + # whose length should be ignored. + + size_a = a.numdigits() + if op == '&': + if maska: + size_z = 1 + else: + if maskb: + size_z = size_a + else: + size_z = 1 + else: + size_z = size_a + + z = rbigint([NULLDIGIT] * size_z, 1, size_z) + i = 0 + while i < size_z: + if i < size_a: + diga = a.digit(i) ^ maska + else: + diga = maska + if i == 0: + digb = b ^ maskb + else: + digb = maskb + + if op == '&': + z.setdigit(i, diga & digb) + elif op == '|': + z.setdigit(i, diga | digb) + elif op == '^': + z.setdigit(i, diga ^ digb) + i += 1 + + z._normalize() + if negz == 0: + return z + + return z.invert() +_int_bitwise._annspecialcase_ = "specialize:arg(1)" ULONGLONG_BOUND = r_ulonglong(1L << (r_longlong.BITS-1)) LONGLONG_MIN = r_longlong(-(1L << (r_longlong.BITS-1))) 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_debug.py b/rpython/rlib/test/test_debug.py --- a/rpython/rlib/test/test_debug.py +++ b/rpython/rlib/test/test_debug.py @@ -4,7 +4,9 @@ debug_print, debug_start, debug_stop, have_debug_prints, debug_offset, debug_flush, check_nonneg, IntegerCanBeNegative, - mark_dict_non_null) + mark_dict_non_null, + check_list_of_chars, + NotAListOfChars) from rpython.rlib import debug from rpython.rtyper.test.test_llinterp import interpret, gengraph @@ -72,6 +74,26 @@ assert sorted(graph.returnblock.inputargs[0].concretetype.TO.entries.TO.OF._flds.keys()) == ['key', 'value'] +def test_check_list_of_chars(): + def f(x): + result = [] + check_list_of_chars(result) + result = [chr(x), 'a'] + check_list_of_chars(result) + result = [unichr(x)] + check_list_of_chars(result) + return result + + interpret(f, [3]) + + def g(x): + result = ['a', 'b', 'c', ''] + check_list_of_chars(result) + return x + + py.test.raises(NotAListOfChars, "interpret(g, [3])") + + class DebugTests(object): def test_debug_print_start_stop(self): diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py --- a/rpython/rlib/test/test_rbigint.py +++ b/rpython/rlib/test/test_rbigint.py @@ -2,7 +2,8 @@ import operator import sys -from random import random, randint, sample +import math +from random import random, randint, sample, seed import py @@ -14,6 +15,14 @@ from rpython.rtyper.test.test_llinterp import interpret from rpython.translator.c.test.test_standalone import StandaloneTests +long_vals_not_too_big = range(17) + [ + 37, 50, + 127, 128, 129, 511, 512, 513, sys.maxint, sys.maxint + 1, + 123456789123456789000000L, + ] + +long_vals = long_vals_not_too_big + [ + 1 << 100, 3 ** 10000] class TestRLong(object): def test_simple(self): @@ -43,19 +52,23 @@ assert r2.str() == str(-n) def test_floordiv(self): - for op1 in [-12, -2, -1, 1, 2, 50]: - for op2 in [-4, -2, -1, 1, 2, 8]: - rl_op1 = rbigint.fromint(op1) - rl_op2 = rbigint.fromint(op2) + for op1 in gen_signs(long_vals): + for op2 in gen_signs(long_vals): + if not op2: + continue + rl_op1 = rbigint.fromlong(op1) + rl_op2 = rbigint.fromlong(op2) r1 = rl_op1.floordiv(rl_op2) r2 = op1 // op2 assert r1.tolong() == r2 def test_truediv(self): - for op1 in [-12, -2, -1, 1, 2, 50]: - for op2 in [-4, -2, -1, 1, 2, 8]: - rl_op1 = rbigint.fromint(op1) - rl_op2 = rbigint.fromint(op2) + for op1 in gen_signs(long_vals_not_too_big): + for op2 in gen_signs(long_vals): + if not op2: + continue + rl_op1 = rbigint.fromlong(op1) + rl_op2 = rbigint.fromlong(op2) r1 = rl_op1.truediv(rl_op2) r2 = op1 / op2 assert r1 == r2 @@ -98,19 +111,29 @@ assert f == -1.7976931348623157e+308 # exactly def test_mod(self): - for op1 in [-50, -12, -2, -1, 1, 2, 50, 52]: - for op2 in [-4, -2, -1, 1, 2, 8]: - rl_op1 = rbigint.fromint(op1) - rl_op2 = rbigint.fromint(op2) + for op1 in gen_signs(long_vals): + for op2 in gen_signs(long_vals): + if not op2: + continue + rl_op1 = rbigint.fromlong(op1) + rl_op2 = rbigint.fromlong(op2) r1 = rl_op1.mod(rl_op2) r2 = op1 % op2 print op1, op2 assert r1.tolong() == r2 + def test_int_mod(self): + for x in gen_signs(long_vals): + for y in gen_signs([1, 2, 4, 8, 8888, sys.maxint, 2 ** 19, 2 ** 18 - 1]): + op1 = rbigint.fromlong(x) + r1 = op1.int_mod(y) + r2 = x % y + assert r1.tolong() == r2 + def test_pow(self): - for op1 in [-50, -12, -2, -1, 1, 2, 50, 52]: + for op1 in gen_signs(long_vals_not_too_big): for op2 in [0, 1, 2, 8, 9, 10, 11]: - rl_op1 = rbigint.fromint(op1) + rl_op1 = rbigint.fromlong(op1) rl_op2 = rbigint.fromint(op2) r1 = rl_op1.pow(rl_op2) r2 = op1 ** op2 @@ -238,6 +261,13 @@ result = f1.add(f2) assert result.tolong() == x * i + y * j + def test_int_add(self): + for x in gen_signs(long_vals): + for y in gen_signs([0, 1, 9999, sys.maxint, 2 ** 19, 2 ** 18 - 1]): + f1 = rbigint.fromlong(x) + result = f1.int_add(y) + assert result.tolong() == x + y + def test_sub(self): x = 12378959520302182384345L y = 88961284756491823819191823L @@ -248,20 +278,34 @@ result = f1.sub(f2) assert result.tolong() == x * i - y * j + def test_int_sub(self): + for x in gen_signs([0, 123456789123456789000000L, 1 << 100, 3 ** 10000]): + for y in gen_signs([0, 1, 8888, sys.maxint, 2 ** 19, 2 ** 18 - 1]): + f1 = rbigint.fromlong(x) + result = f1.int_sub(y) + assert result.tolong() == x - y + def test_subzz(self): w_l0 = rbigint.fromint(0) assert w_l0.sub(w_l0).tolong() == 0 def test_mul(self): - x = -1238585838347L - y = 585839391919233L - f1 = rbigint.fromlong(x) - f2 = rbigint.fromlong(y) - result = f1.mul(f2) - assert result.tolong() == x * y - # also test a * a, it has special code - result = f1.mul(f1) - assert result.tolong() == x * x + for x in gen_signs(long_vals): + f1 = rbigint.fromlong(x) + for y in gen_signs(long_vals_not_too_big): + f2 = rbigint.fromlong(y) + result = f1.mul(f2) + assert result.tolong() == x * y + # there's a special case for a is b + result = f1.mul(f1) + assert result.tolong() == x * x + + def test_int_mul(self): + for x in gen_signs([39, 128, 111111111, 123456789123456789000000L, 1 << 100, 3 ** 10000]): + for y in gen_signs([0, 1, 8888, sys.maxint, 2 ** 19, 2 ** 18 - 1]): + f1 = rbigint.fromlong(x) + result = f1.int_mul(y) + assert result.tolong() == x * y def test_tofloat(self): x = 12345678901234567890L ** 10 @@ -309,6 +353,9 @@ f1 = rbigint.fromfloat(9007199254740991.0) assert f1.tolong() == 9007199254740991 + null = rbigint.fromfloat(-0.0) + assert null.int_eq(0) + def test_eq(self): x = 5858393919192332223L y = 585839391919233111223311112332L @@ -336,6 +383,17 @@ f2 = rbigint.fromlong(y) assert (x < y) == f1.lt(f2) + def test_int_comparison(self): + for x in gen_signs(long_vals): + for y in gen_signs([0, 1, 0x11111111, 0x11111112, 8888, sys.maxint, 2 ** 19, 2 ** 18 - 1]): + f1 = rbigint.fromlong(x) + assert (x < y) == f1.int_lt(y) + assert (x <= y) == f1.int_le(y) + assert (x > y) == f1.int_gt(y) + assert (x >= y) == f1.int_ge(y) + assert (x == y) == f1.int_eq(y) + assert (x != y) == f1.int_ne(y) + def test_order(self): f6 = rbigint.fromint(6) f7 = rbigint.fromint(7) @@ -344,6 +402,14 @@ assert (f6.gt(f6), f6.gt(f7), f7.gt(f6)) == (0,0,1) assert (f6.ge(f6), f6.ge(f7), f7.ge(f6)) == (1,0,1) + def test_int_order(self): + f6 = rbigint.fromint(6) + f7 = rbigint.fromint(7) + assert (f6.int_lt(6), f6.int_lt(7), f7.int_lt(6)) == (0,1,0) + assert (f6.int_le(6), f6.int_le(7), f7.int_le(6)) == (1,1,0) + assert (f6.int_gt(6), f6.int_gt(7), f7.int_gt(6)) == (0,0,1) + assert (f6.int_ge(6), f6.int_ge(7), f7.int_ge(6)) == (1,0,1) + def test_int_conversion(self): f1 = rbigint.fromlong(12332) f2 = rbigint.fromint(12332) @@ -389,7 +455,6 @@ def test_pow_lll(self): - return x = 10L y = 2L z = 13L @@ -514,12 +579,21 @@ res2 = getattr(operator, mod)(x, y) assert res1 == res2 + def test_int_bitwise(self): + for x in gen_signs([0, 1, 5, 11, 42, 43, 2 ** 30]): + for y in gen_signs([0, 1, 5, 11, 42, 43, 3 ** 30, 2 ** 31]): + lx = rbigint.fromlong(x) + for mod in "xor and_ or_".split(): + res1 = getattr(lx, 'int_' + mod)(y).tolong() + res2 = getattr(operator, mod)(x, y) + assert res1 == res2 + def test_mul_eq_shift(self): p2 = rbigint.fromlong(1).lshift(63) f1 = rbigint.fromlong(0).lshift(63) f2 = rbigint.fromlong(0).mul(p2) assert f1.eq(f2) - + def test_tostring(self): z = rbigint.fromlong(0) assert z.str() == '0' @@ -534,6 +608,11 @@ assert x.format('.!') == ( '-!....!!..!!..!.!!.!......!...!...!!!........!') assert x.format('abcdefghijkl', '<<', '>>') == '-<<cakdkgdijffjf>>' + x = rbigint.fromlong(-18471379832321000000000000000000000000000000000000000000) + assert x.str() == '-18471379832321000000000000000000000000000000000000000000' + assert x.repr() == '-18471379832321000000000000000000000000000000000000000000L' + assert x.hex() == '-0xc0d9a6f41fbcf1718b618443d45516a051e40000000000L' + assert x.oct() == '-014033151572037571705614266060420752125055201217100000000000000L' def test_format_caching(self): big = rbigint.fromlong(2 ** 1000) @@ -579,6 +658,18 @@ assert rbigint.fromlong(x).hash() == rbigint.fromlong(y).hash() assert rbigint.fromlong(-x).hash() == rbigint.fromlong(-y).hash() + def test_log(self): + from rpython.rlib.rfloat import ulps_check + for op in long_vals: + if not op: + continue + for base in [0, 2, 4, 8, 16, 10, math.e]: + l = rbigint.fromlong(op).log(base) + if base: + assert ulps_check(l, math.log(op, base), 1) is None + else: + assert ulps_check(l, math.log(op), 1) is None + class TestInternalFunctions(object): def test__inplace_divrem1(self): # signs are not handled in the helpers! @@ -834,6 +925,8 @@ assert s == bigint.tobytes(16, byteorder="big", signed=False) py.test.raises(InvalidEndiannessError, bigint.frombytes, '\xFF', 'foo', signed=True) + bigint = rbigint.frombytes('\x82', byteorder='big', signed=True) + assert bigint.tolong() == -126 def test_tobytes(self): assert rbigint.fromint(0).tobytes(1, 'big', signed=True) == '\x00' 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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit