[pypy-commit] pypy default: merge
fijal
noreply at buildbot.pypy.org
Wed Apr 17 18:20:06 CEST 2013
Author: Maciej Fijalkowski <fijall at 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
More information about the pypy-commit
mailing list