Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r63456:2207377f4cc9 Date: 2013-04-17 18:19 +0200 http://bitbucket.org/pypy/pypy/changeset/2207377f4cc9/
Log: merge diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py --- a/rpython/jit/backend/arm/assembler.py +++ b/rpython/jit/backend/arm/assembler.py @@ -13,7 +13,7 @@ operations as regalloc_operations, operations_with_guard as regalloc_operations_with_guard) from rpython.jit.backend.llsupport import jitframe -from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER, debug_bridge +from rpython.jit.backend.llsupport.assembler import DEBUG_COUNTER, debug_bridge, BaseAssembler from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper from rpython.jit.backend.model import CompiledLoopToken from rpython.jit.codewriter.effectinfo import EffectInfo @@ -25,7 +25,7 @@ from rpython.rlib.rarithmetic import r_uint from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref from rpython.rtyper.lltypesystem import lltype, rffi - +from rpython.jit.backend.arm.detect import detect_hardfloat class AssemblerARM(ResOpAssembler): @@ -49,6 +49,10 @@ self.loop_run_counters = [] self.gcrootmap_retaddr_forced = 0 + def setup_once(self): + BaseAssembler.setup_once(self) + self.hf_abi = detect_hardfloat() + def setup(self, looptoken): assert self.memcpy_addr != 0, 'setup_once() not called?' if we_are_translated(): @@ -274,7 +278,7 @@ mc.CMP_ri(r.r0.value, 0) mc.B(self.propagate_exception_path, c=c.EQ) # - self._reload_frame_if_necessary(mc, align_stack=True) + self._reload_frame_if_necessary(mc) self._pop_all_regs_from_jitframe(mc, [r.r0, r.r1], self.cpu.supports_floats) # nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() @@ -289,7 +293,7 @@ rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.malloc_slowpath = rawstart - def _reload_frame_if_necessary(self, mc, align_stack=False, can_collect=0): + def _reload_frame_if_necessary(self, mc): gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap and gcrootmap.is_shadow_stack: rst = gcrootmap.get_root_stack_top_addr() @@ -301,7 +305,7 @@ # frame never uses card marking, so we enforce this is not # an array self._write_barrier_fastpath(mc, wbdescr, [r.fp], array=False, - is_frame=True)#, align_stack=align_stack) + is_frame=True) def propagate_memoryerror_if_r0_is_null(self): # see ../x86/assembler.py:propagate_memoryerror_if_eax_is_null diff --git a/rpython/jit/backend/arm/detect.py b/rpython/jit/backend/arm/detect.py --- a/rpython/jit/backend/arm/detect.py +++ b/rpython/jit/backend/arm/detect.py @@ -1,5 +1,5 @@ from rpython.translator.tool.cbuild import ExternalCompilationInfo -from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rlib.clibffi import FFI_DEFAULT_ABI, FFI_SYSV, FFI_VFP from rpython.rtyper.tool import rffi_platform from rpython.translator.platform import CompilationError @@ -14,10 +14,7 @@ """]) def detect_hardfloat(): - # http://gcc.gnu.org/ml/gcc-patches/2010-10/msg02419.html - if rffi_platform.getdefined('__ARM_PCS_VFP', ''): - return rffi_platform.getconstantinteger('__ARM_PCS_VFP', '') - return False + return FFI_DEFAULT_ABI == FFI_VFP def detect_float(): """Check for hardware float support diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -3,7 +3,6 @@ from rpython.jit.backend.arm import registers as r from rpython.jit.backend.arm import shift from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, JITFRAME_FIXED_SIZE - from rpython.jit.backend.arm.helper.assembler import (gen_emit_op_by_helper_call, gen_emit_op_unary_cmp, gen_emit_guard_unary_cmp, @@ -351,10 +350,11 @@ return cond def _emit_call(self, adr, arglocs, fcond=c.AL, resloc=None, - result_info=(-1, -1), - can_collect=1, - reload_frame=False): - if self.cpu.hf_abi: + result_info=(-1, -1), + # whether to worry about a CALL that can collect; this + # is always true except in call_release_gil + can_collect=True): + if self.hf_abi: stack_args, adr = self._setup_call_hf(adr, arglocs, fcond, resloc, result_info) else: @@ -362,6 +362,9 @@ resloc, result_info) if can_collect: + # we push *now* the gcmap, describing the status of GC registers + # after the rearrangements done just above, ignoring the return + # value eax, if necessary noregs = self.cpu.gc_ll_descr.is_shadow_stack() gcmap = self._regalloc.get_gcmap([r.r0], noregs=noregs) self.push_gcmap(self.mc, gcmap, store=True) @@ -379,17 +382,15 @@ # ensure the result is wellformed and stored in the correct location if resloc is not None: - if resloc.is_vfp_reg() and not self.cpu.hf_abi: + if resloc.is_vfp_reg() and not self.hf_abi: # move result to the allocated register self.mov_to_vfp_loc(r.r0, r.r1, resloc) elif resloc.is_reg() and result_info != (-1, -1): self._ensure_result_bit_extension(resloc, result_info[0], result_info[1]) if can_collect: - self._reload_frame_if_necessary(self.mc, can_collect=can_collect) + self._reload_frame_if_necessary(self.mc) self.pop_gcmap(self.mc) - elif reload_frame: - self._reload_frame_if_necessary(self.mc) return fcond def _restore_sp(self, stack_args, fcond): @@ -1260,6 +1261,7 @@ def emit_guard_call_release_gil(self, op, guard_op, arglocs, regalloc, fcond): + self._store_force_index(guard_op) # first, close the stack in the sense of the asmgcc GC root tracker gcrootmap = self.cpu.gc_ll_descr.gcrootmap numargs = op.numargs() @@ -1268,24 +1270,27 @@ resloc = arglocs[0] if gcrootmap: - noregs = self.cpu.gc_ll_descr.is_shadow_stack() - assert noregs - gcmap = self._regalloc.get_gcmap([r.r0], noregs=noregs) + # we put the gcmap now into the frame before releasing the GIL, + # and pop it below after reacquiring the GIL. The assumption + # is that this gcmap describes correctly the situation at any + # point in-between: all values containing GC pointers should + # be safely saved out of registers by now, and will not be + # manipulated by any of the following CALLs. + gcmap = self._regalloc.get_gcmap(noregs=True) self.push_gcmap(self.mc, gcmap, store=True) self.call_release_gil(gcrootmap, arglocs, regalloc, fcond) # do the call - self._store_force_index(guard_op) - # descr = op.getdescr() size = descr.get_result_size() signed = descr.is_result_signed() # self._emit_call(adr, callargs, fcond, resloc, (size, signed), - can_collect=0) + can_collect=False) # then reopen the stack if gcrootmap: self.call_reacquire_gil(gcrootmap, resloc, regalloc, fcond) + self.pop_gcmap(self.mc) # remove the gcmap saved above self._emit_guard_may_force(guard_op, arglocs[numargs+1:], numargs) return fcond @@ -1314,7 +1319,7 @@ # call the reopenstack() function (also reacquiring the GIL) with saved_registers(self.mc, regs_to_save, vfp_regs_to_save): self._emit_call(imm(self.reacqgil_addr), [], fcond, - can_collect=False, reload_frame=True) + can_collect=False) def _store_force_index(self, guard_op): faildescr = guard_op.getdescr() diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py --- a/rpython/jit/backend/arm/runner.py +++ b/rpython/jit/backend/arm/runner.py @@ -6,6 +6,7 @@ from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER from rpython.rtyper.lltypesystem import lltype, llmemory +from rpython.jit.backend.arm.detect import detect_hardfloat jitframe.STATICSIZE = JITFRAME_FIXED_SIZE @@ -16,7 +17,7 @@ supports_floats = True supports_longlong = False # XXX requires an implementation of # read_timestamp that works in user mode - supports_singlefloats = True + supports_singlefloats = not detect_hardfloat() from rpython.jit.backend.arm.arch import JITFRAME_FIXED_SIZE all_reg_indexes = range(len(all_regs)) @@ -112,22 +113,10 @@ class CPU_ARM(AbstractARMCPU): - """ARM v7 uses softfp ABI, requires vfp""" + """ARM v7""" backend_name = "armv7" - -class CPU_ARMHF(AbstractARMCPU): - """ARM v7 uses hardfp ABI, requires vfp""" - hf_abi = True - backend_name = "armv7hf" - supports_floats = True - supports_singlefloats = False - - -class CPU_ARMv6HF(AbstractARMCPU): +class CPU_ARMv6(AbstractARMCPU): """ ARM v6, uses hardfp ABI, requires vfp""" - hf_abi = True arch_version = 6 - backend_name = "armv6hf" - supports_floats = True - supports_singlefloats = False + backend_name = "armv6" diff --git a/rpython/jit/backend/arm/test/conftest.py b/rpython/jit/backend/arm/test/conftest.py --- a/rpython/jit/backend/arm/test/conftest.py +++ b/rpython/jit/backend/arm/test/conftest.py @@ -16,6 +16,7 @@ dest="run_translation_tests", help="run tests that translate code") -def pytest_runtest_setup(item): +def pytest_collect_directory(path, parent): if not cpu.startswith('arm'): py.test.skip("ARM(v7) tests skipped: cpu is %r" % (cpu,)) +pytest_collect_file = pytest_collect_directory diff --git a/rpython/jit/backend/detect_cpu.py b/rpython/jit/backend/detect_cpu.py --- a/rpython/jit/backend/detect_cpu.py +++ b/rpython/jit/backend/detect_cpu.py @@ -61,8 +61,6 @@ model = 'x86-without-sse2' if model.startswith('arm'): from rpython.jit.backend.arm.detect import detect_hardfloat, detect_float - if detect_hardfloat(): - model += 'hf' assert detect_float(), 'the JIT-compiler requires a vfp unit' return model @@ -77,12 +75,10 @@ return "rpython.jit.backend.x86.runner", "CPU_X86_64" elif backend_name == 'cli': return "rpython.jit.backend.cli.runner", "CliCPU" - elif backend_name == 'armv6hf': - return "rpython.jit.backend.arm.runner", "CPU_ARMv6HF" - elif backend_name == 'armv7': + elif backend_name.startswith('armv6'): + return "rpython.jit.backend.arm.runner", "CPU_ARMv6" + elif backend_name.startswith('armv7'): return "rpython.jit.backend.arm.runner", "CPU_ARM" - elif backend_name == 'armv7hf': - return "rpython.jit.backend.arm.runner", "CPU_ARMHF" else: raise ProcessorAutodetectError, ( "we have no JIT backend for this cpu: '%s'" % backend_name) 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 @@ -34,7 +34,7 @@ ('t', lltype.Signed)) tdescr = get_size_descr(self.gc_ll_descr, T) tdescr.tid = 5678 - get_field_descr(self.gc_ll_descr, T, 'z') + tzdescr = get_field_descr(self.gc_ll_descr, T, 'z') # A = lltype.GcArray(lltype.Signed) adescr = get_array_descr(self.gc_ll_descr, A) diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -129,8 +129,6 @@ def __init__(self, translator): from rpython.memory.gc.base import choose_gc_from_config - from rpython.memory.gc.base import ARRAY_TYPEID_MAP - from rpython.memory.gc import inspector super(BaseFrameworkGCTransformer, self).__init__(translator, inline=True) @@ -232,7 +230,51 @@ classdef = bk.getuniqueclassdef(GCClass) s_gc = annmodel.SomeInstance(classdef) + + self._declare_functions(GCClass, getfn, s_gc, s_typeid16) + + # thread support + if translator.config.translation.continuation: + root_walker.stacklet_support = True + root_walker.need_stacklet_support(self, getfn) + if translator.config.translation.thread: + root_walker.need_thread_support(self, getfn) + + self.layoutbuilder.encode_type_shapes_now() + + annhelper.finish() # at this point, annotate all mix-level helpers + annhelper.backend_optimize() + + self.collect_analyzer = CollectAnalyzer(self.translator) + self.collect_analyzer.analyze_all() + + s_gc = self.translator.annotator.bookkeeper.valueoftype(GCClass) + r_gc = self.translator.rtyper.getrepr(s_gc) + self.c_const_gc = rmodel.inputconst(r_gc, self.gcdata.gc) + s_gc_data = self.translator.annotator.bookkeeper.valueoftype( + gctypelayout.GCData) + r_gc_data = self.translator.rtyper.getrepr(s_gc_data) + self.c_const_gcdata = rmodel.inputconst(r_gc_data, self.gcdata) + self.malloc_zero_filled = GCClass.malloc_zero_filled + + HDR = self.HDR = self.gcdata.gc.gcheaderbuilder.HDR + + size_gc_header = self.gcdata.gc.gcheaderbuilder.size_gc_header + vtableinfo = (HDR, size_gc_header, self.gcdata.gc.typeid_is_in_field) + self.c_vtableinfo = rmodel.inputconst(lltype.Void, vtableinfo) + tig = self.layoutbuilder.type_info_group._as_ptr() + self.c_type_info_group = rmodel.inputconst(lltype.typeOf(tig), tig) + sko = llmemory.sizeof(gcdata.TYPE_INFO) + self.c_vtinfo_skip_offset = rmodel.inputconst(lltype.typeOf(sko), sko) + + + def _declare_functions(self, GCClass, getfn, s_gc, s_typeid16): + from rpython.memory.gc.base import ARRAY_TYPEID_MAP + from rpython.memory.gc import inspector + s_gcref = annmodel.SomePtr(llmemory.GCREF) + gcdata = self.gcdata + translator = self.translator malloc_fixedsize_clear_meth = GCClass.malloc_fixedsize_clear.im_func self.malloc_fixedsize_clear_ptr = getfn( @@ -466,39 +508,6 @@ [annmodel.SomeAddress()], annmodel.s_None) - # thread support - if translator.config.translation.continuation: - root_walker.stacklet_support = True - root_walker.need_stacklet_support(self, getfn) - if translator.config.translation.thread: - root_walker.need_thread_support(self, getfn) - - self.layoutbuilder.encode_type_shapes_now() - - annhelper.finish() # at this point, annotate all mix-level helpers - annhelper.backend_optimize() - - self.collect_analyzer = CollectAnalyzer(self.translator) - self.collect_analyzer.analyze_all() - - s_gc = self.translator.annotator.bookkeeper.valueoftype(GCClass) - r_gc = self.translator.rtyper.getrepr(s_gc) - self.c_const_gc = rmodel.inputconst(r_gc, self.gcdata.gc) - s_gc_data = self.translator.annotator.bookkeeper.valueoftype( - gctypelayout.GCData) - r_gc_data = self.translator.rtyper.getrepr(s_gc_data) - self.c_const_gcdata = rmodel.inputconst(r_gc_data, self.gcdata) - self.malloc_zero_filled = GCClass.malloc_zero_filled - - HDR = self.HDR = self.gcdata.gc.gcheaderbuilder.HDR - - size_gc_header = self.gcdata.gc.gcheaderbuilder.size_gc_header - vtableinfo = (HDR, size_gc_header, self.gcdata.gc.typeid_is_in_field) - self.c_vtableinfo = rmodel.inputconst(lltype.Void, vtableinfo) - tig = self.layoutbuilder.type_info_group._as_ptr() - self.c_type_info_group = rmodel.inputconst(lltype.typeOf(tig), tig) - sko = llmemory.sizeof(gcdata.TYPE_INFO) - self.c_vtinfo_skip_offset = rmodel.inputconst(lltype.typeOf(sko), sko) def consider_constant(self, TYPE, value): self.layoutbuilder.consider_constant(TYPE, value, self.gcdata.gc) diff --git a/rpython/rlib/clibffi.py b/rpython/rlib/clibffi.py --- a/rpython/rlib/clibffi.py +++ b/rpython/rlib/clibffi.py @@ -4,6 +4,7 @@ from rpython.rtyper.tool import rffi_platform from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.tool import rffi_platform from rpython.rlib.unroll import unrolling_iterable from rpython.rlib.rarithmetic import intmask, is_emulated_long from rpython.rlib.objectmodel import we_are_translated @@ -15,6 +16,7 @@ from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.translator.platform import platform from rpython.conftest import cdir +from platform import machine import py import os import sys @@ -35,6 +37,8 @@ _LITTLE_ENDIAN = sys.byteorder == 'little' _BIG_ENDIAN = sys.byteorder == 'big' +_ARM = rffi_platform.getdefined('__arm__', '') + if _WIN32: from rpython.rlib import rwin32 @@ -154,6 +158,10 @@ if _WIN32 and not _WIN64: FFI_STDCALL = rffi_platform.ConstantInteger('FFI_STDCALL') + if _ARM: + FFI_SYSV = rffi_platform.ConstantInteger('FFI_SYSV') + FFI_VFP = rffi_platform.ConstantInteger('FFI_VFP') + FFI_TYPE_STRUCT = rffi_platform.ConstantInteger('FFI_TYPE_STRUCT') size_t = rffi_platform.SimpleType("size_t", rffi.ULONG) @@ -327,6 +335,9 @@ FFI_DEFAULT_ABI = cConfig.FFI_DEFAULT_ABI if _WIN32 and not _WIN64: FFI_STDCALL = cConfig.FFI_STDCALL +if _ARM: + FFI_SYSV = cConfig.FFI_SYSV + FFI_VFP = cConfig.FFI_VFP FFI_TYPE_STRUCT = cConfig.FFI_TYPE_STRUCT FFI_CIFP = lltype.Ptr(cConfig.ffi_cif) diff --git a/rpython/translator/c/database.py b/rpython/translator/c/database.py --- a/rpython/translator/c/database.py +++ b/rpython/translator/c/database.py @@ -64,9 +64,8 @@ self.instrument_ncounter = 0 - def gettypedefnode(self, T, varlength=1): - if varlength <= 1: - varlength = 1 # it's C after all + def gettypedefnode(self, T, varlength=None): + if varlength is None: key = T else: key = T, varlength @@ -94,7 +93,7 @@ self.pendingsetupnodes.append(node) return node - def gettype(self, T, varlength=1, who_asks=None, argnames=[]): + def gettype(self, T, varlength=None, who_asks=None, argnames=[]): if isinstance(T, Primitive) or T == GCREF: return PrimitiveType[T] elif isinstance(T, Typedef): diff --git a/rpython/translator/c/node.py b/rpython/translator/c/node.py --- a/rpython/translator/c/node.py +++ b/rpython/translator/c/node.py @@ -47,12 +47,12 @@ typetag = 'struct' extra_union_for_varlength = True - def __init__(self, db, STRUCT, varlength=1): + def __init__(self, db, STRUCT, varlength=None): NodeWithDependencies.__init__(self, db) self.STRUCT = STRUCT self.LLTYPE = STRUCT self.varlength = varlength - if varlength == 1: + if varlength is None: basename = STRUCT._name with_number = True else: @@ -93,7 +93,7 @@ self.fields = [] db = self.db STRUCT = self.STRUCT - if self.varlength != 1: + if self.varlength is not None: self.normalizedtypename = db.gettype(STRUCT, who_asks=self) if needs_gcheader(self.STRUCT): HDR = db.gcpolicy.struct_gcheader_definition(self) @@ -120,7 +120,7 @@ rtti = getRuntimeTypeInfo(STRUCT) except ValueError: pass - if self.varlength == 1: + if self.varlength is None: self.db.gcpolicy.struct_setup(self, rtti) return self.gcinfo gcinfo = defaultproperty(computegcinfo) @@ -160,12 +160,14 @@ if typename == PrimitiveType[Void]: line = '/* %s */' % line else: + if is_empty and typename.endswith('[RPY_VARLENGTH]'): + yield '\tRPY_DUMMY_VARLENGTH' is_empty = False yield '\t' + line if is_empty: yield '\t' + 'char _dummy; /* this struct is empty */' yield '};' - if self.varlength != 1: + if self.varlength is not None: assert self.typetag == 'struct' yield 'union %su {' % self.name yield ' struct %s a;' % self.name @@ -182,7 +184,7 @@ def debug_offsets(self): # generate number exprs giving the offset of the elements in the struct - assert self.varlength == 1 + assert self.varlength is None for name in self.fieldnames: FIELD_T = self.c_struct_field_type(name) if FIELD_T is Void: @@ -196,18 +198,25 @@ yield 'offsetof(%s %s, %s)' % (self.typetag, self.name, cname) +def deflength(varlength): + if varlength is None: + return 'RPY_VARLENGTH' + elif varlength == 0: + return 'RPY_LENGTH0' + else: + return varlength class ArrayDefNode(NodeWithDependencies): typetag = 'struct' extra_union_for_varlength = True - def __init__(self, db, ARRAY, varlength=1): + def __init__(self, db, ARRAY, varlength=None): NodeWithDependencies.__init__(self, db) self.ARRAY = ARRAY self.LLTYPE = ARRAY self.gcfields = [] self.varlength = varlength - if varlength == 1: + if varlength is None: basename = 'array' with_number = True else: @@ -226,7 +235,7 @@ db = self.db ARRAY = self.ARRAY self.gcinfo # force it to be computed - if self.varlength != 1: + if self.varlength is not None: self.normalizedtypename = db.gettype(ARRAY, who_asks=self) if needs_gcheader(ARRAY): HDR = db.gcpolicy.array_gcheader_definition(self) @@ -238,7 +247,7 @@ def computegcinfo(self): # let the gcpolicy do its own setup self.gcinfo = None # unless overwritten below - if self.varlength == 1: + if self.varlength is None: self.db.gcpolicy.array_setup(self) return self.gcinfo gcinfo = defaultproperty(computegcinfo) @@ -269,21 +278,22 @@ yield '\t' + cdecl(typename, fname) + ';' if not self.ARRAY._hints.get('nolength', False): yield '\tlong length;' - line = '%s;' % cdecl(self.itemtypename, 'items[%d]'% self.varlength) + line = '%s;' % cdecl(self.itemtypename, + 'items[%s]' % deflength(self.varlength)) if self.ARRAY.OF is Void: # strange line = '/* array of void */' if self.ARRAY._hints.get('nolength', False): line = 'char _dummy; ' + line yield '\t' + line yield '};' - if self.varlength != 1: + if self.varlength is not None: yield 'union %su {' % self.name yield ' struct %s a;' % self.name yield ' %s;' % cdecl(self.normalizedtypename, 'b') yield '};' def visitor_lines(self, prefix, on_item): - assert self.varlength == 1 + assert self.varlength is None ARRAY = self.ARRAY # we need a unique name for this C variable, or at least one that does # not collide with the expression in 'prefix' @@ -310,7 +320,7 @@ def debug_offsets(self): # generate three offsets for debugging inspection - assert self.varlength == 1 + assert self.varlength is None if not self.ARRAY._hints.get('nolength', False): yield 'offsetof(struct %s, length)' % (self.name,) else: @@ -333,7 +343,7 @@ forward_decl = None extra_union_for_varlength = False - def __init__(self, db, ARRAY, varlength=1): + def __init__(self, db, ARRAY, varlength=None): NodeWithDependencies.__init__(self, db) self.ARRAY = ARRAY self.LLTYPE = ARRAY @@ -342,8 +352,8 @@ # There is no such thing as an array of voids: # we use a an array of chars instead; only the pointer can be void*. self.itemtypename = db.gettype(contained_type, who_asks=self) - self.fulltypename = self.itemtypename.replace('@', '(@)[%d]' % - (self.varlength,)) + self.fulltypename = self.itemtypename.replace('@', '(@)[%s]' % + deflength(varlength)) if ARRAY._hints.get("render_as_void"): self.fullptrtypename = 'void *@' else: @@ -493,7 +503,8 @@ Node.__init__(self, db) self.obj = obj self.typename = db.gettype(T) #, who_asks=self) - self.implementationtypename = db.gettype(T, varlength=self.getlength()) + self.implementationtypename = db.gettype( + T, varlength=self.getvarlength()) parent, parentindex = parentlink(obj) if obj in exports.EXPORTS_obj2name: self.name = exports.EXPORTS_obj2name[obj] @@ -559,8 +570,8 @@ def startupcode(self): return [] - def getlength(self): - return 1 + def getvarlength(self): + return None assert not USESLOTS or '__dict__' not in dir(ContainerNode) @@ -578,10 +589,10 @@ for name in T._names: yield getattr(self.obj, name) - def getlength(self): + def getvarlength(self): T = self.getTYPE() if T._arrayfld is None: - return 1 + return None else: array = getattr(self.obj, T._arrayfld) return len(array.items) @@ -696,7 +707,7 @@ def enum_dependencies(self): return self.obj.items - def getlength(self): + def getvarlength(self): return len(self.obj.items) def initializationexpr(self, decoration=''): @@ -765,8 +776,8 @@ for i in range(self.obj.getlength()): yield self.obj.getitem(i) - def getlength(self): - return 1 # not variable-sized! + def getvarlength(self): + return None # not variable-sized! def initializationexpr(self, decoration=''): T = self.getTYPE() diff --git a/rpython/translator/c/src/g_prerequisite.h b/rpython/translator/c/src/g_prerequisite.h --- a/rpython/translator/c/src/g_prerequisite.h +++ b/rpython/translator/c/src/g_prerequisite.h @@ -14,8 +14,14 @@ #ifdef __GNUC__ /* other platforms too, probably */ typedef _Bool bool_t; +# define RPY_VARLENGTH /* nothing: [RPY_VARLENGTH] => [] */ +# define RPY_LENGTH0 0 /* array decl [0] are ok */ +# define RPY_DUMMY_VARLENGTH char _dummy[0]; #else typedef unsigned char bool_t; +# define RPY_VARLENGTH 1 /* [RPY_VARLENGTH] => [1] */ +# define RPY_LENGTH0 1 /* array decl [0] are bad */ +# define RPY_DUMMY_VARLENGTH /* nothing */ #endif diff --git a/rpython/translator/c/src/support.h b/rpython/translator/c/src/support.h --- a/rpython/translator/c/src/support.h +++ b/rpython/translator/c/src/support.h @@ -2,16 +2,6 @@ /************************************************************/ /*** C header subsection: support functions ***/ -/* a temporary(?) workaround for GCC 4.8. See: - http://stackoverflow.com/questions/16016627/ -*/ -#ifdef __GNUC__ -# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) -# pragma GCC optimize("no-aggressive-loop-optimizations") -# endif -#endif - - #define RUNNING_ON_LLINTERP 0 #define OP_JIT_RECORD_KNOWN_CLASS(i, c, r) /* nothing */ diff --git a/rpython/translator/c/test/test_lltyped.py b/rpython/translator/c/test/test_lltyped.py --- a/rpython/translator/c/test/test_lltyped.py +++ b/rpython/translator/c/test/test_lltyped.py @@ -919,3 +919,25 @@ return x fn = self.getcompiled(llf, [int]) assert fn(5) == 42 + + def test_raw_array_field_prebuilt(self): + from rpython.rtyper.lltypesystem import rffi + S = Struct('S', ('array', rffi.CArray(Signed))) + s0 = malloc(S, 0, flavor='raw', immortal=True) + s1 = malloc(S, 1, flavor='raw', immortal=True) + s1.array[0] = 521 + s2 = malloc(S, 2, flavor='raw', immortal=True) + s2.array[0] = 12 + s2.array[1] = 34 + def llf(i): + if i == 0: s = s0 + elif i == 1: s = s1 + else: s = s2 + x = 10 + if i > 0: + x += s.array[i-1] + return x + fn = self.getcompiled(llf, [int]) + assert fn(0) == 10 + assert fn(1) == 10 + 521 + assert fn(2) == 10 + 34 _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit