def prepare_database(db): FUNCPTR = lltype.Ptr(lltype.FuncType([revdb._CMDPTR, lltype.Ptr(rstr.STR)], lltype.Void)) ALLOCFUNCPTR = lltype.Ptr(lltype.FuncType([rffi.LONGLONG, llmemory.GCREF], lltype.Void)) bk = db.translator.annotator.bookkeeper cmds = getattr(db.translator, 'revdb_commands', {}) numcmds = [(num, func) for (num, func) in cmds.items() if isinstance(num, int)] S = lltype.Struct('RPY_REVDB_COMMANDS', ('names', lltype.FixedSizeArray(rffi.INT, len(numcmds) + 1)), ('funcs', lltype.FixedSizeArray(FUNCPTR, len(numcmds))), ('alloc', ALLOCFUNCPTR)) s = lltype.malloc(S, flavor='raw', immortal=True, zero=True) i = 0 for name, func in cmds.items(): fnptr = lltype.getfunctionptr(bk.getdesc(func).getuniquegraph()) if isinstance(name, int): assert name != 0 s.names[i] = rffi.cast(rffi.INT, name) s.funcs[i] = fnptr i += 1 elif name == "ALLOCATING": s.alloc = fnptr else: raise AssertionError("bad tag in register_debug_command(): %r" % (name,)) exports.EXPORTS_obj2name[s._as_obj()] = 'rpy_revdb_commands' db.get(s) db.stack_bottom_funcnames = []
def test_cast_subarray_pointer(): for a in [ lltype.malloc(lltype.GcArray(lltype.Signed), 5), lltype.malloc(lltype.FixedSizeArray(lltype.Signed, 5), immortal=True) ]: A = lltype.typeOf(a).TO SUBARRAY = lltype.FixedSizeArray(lltype.Signed, 1) a[3] = 132 adr = cast_ptr_to_adr(a) + itemoffsetof(A, 3) subarray = cast_adr_to_ptr(adr, lltype.Ptr(SUBARRAY)) assert subarray[0] == 132 subarray[0] += 2 assert a[3] == 134
def test_keep_all_keepalives(self): SIZE = llmemory.sizeof(lltype.Signed) PARRAY = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1)) class A: def __init__(self): self.addr = llmemory.raw_malloc(SIZE) def __del__(self): llmemory.raw_free(self.addr) class B: pass def myfunc(): b = B() b.keep = A() b.data = llmemory.cast_adr_to_ptr(b.keep.addr, PARRAY) b.data[0] = 42 ptr = b.data # normally 'b' could go away as early as here, which would free # the memory held by the instance of A in b.keep... res = ptr[0] # ...so we explicitly keep 'b' alive until here objectmodel.keepalive_until_here(b) return res graph = self.check(myfunc, [], [], 42, must_be_removed=False) # 'A' instance left # there is a getarrayitem near the end of the graph of myfunc. # However, the memory it accesses must still be protected by the # following keepalive, even after malloc removal entrymap = mkentrymap(graph) [link] = entrymap[graph.returnblock] assert link.prevblock.operations[-1].opname == 'keepalive'
def test_raw_memclear_on_empty_array(): py.test.skip("Fails") A = lltype.FixedSizeArray(lltype.Signed, 0) a = lltype.malloc(A, flavor='raw') src = cast_ptr_to_adr(a) + itemoffsetof(A, 0) raw_memclear(src, sizeof(lltype.Signed) * 0) lltype.free(a, flavor="raw")
class CConfig: _compilation_info_ = ExternalCompilationInfo( includes=['windows.h', 'winbase.h', 'sys/stat.h'], ) WIN32_FIND_DATA = platform.Struct( 'struct _WIN32_FIND_DATA' + suffix, # Only interesting fields [('dwFileAttributes', rwin32.DWORD), ('nFileSizeHigh', rwin32.DWORD), ('nFileSizeLow', rwin32.DWORD), ('ftCreationTime', rwin32.FILETIME), ('ftLastAccessTime', rwin32.FILETIME), ('ftLastWriteTime', rwin32.FILETIME), ('cFileName', lltype.FixedSizeArray(traits.CHAR, 250))]) ERROR_FILE_NOT_FOUND = platform.ConstantInteger('ERROR_FILE_NOT_FOUND') ERROR_NO_MORE_FILES = platform.ConstantInteger('ERROR_NO_MORE_FILES') GetFileExInfoStandard = platform.ConstantInteger( 'GetFileExInfoStandard') FILE_ATTRIBUTE_DIRECTORY = platform.ConstantInteger( 'FILE_ATTRIBUTE_DIRECTORY') FILE_ATTRIBUTE_READONLY = platform.ConstantInteger( 'FILE_ATTRIBUTE_READONLY') INVALID_FILE_ATTRIBUTES = platform.ConstantInteger( 'INVALID_FILE_ATTRIBUTES') ERROR_SHARING_VIOLATION = platform.ConstantInteger( 'ERROR_SHARING_VIOLATION') _S_IFDIR = platform.ConstantInteger('_S_IFDIR') _S_IFREG = platform.ConstantInteger('_S_IFREG') _S_IFCHR = platform.ConstantInteger('_S_IFCHR') _S_IFIFO = platform.ConstantInteger('_S_IFIFO') FILE_TYPE_UNKNOWN = platform.ConstantInteger('FILE_TYPE_UNKNOWN') FILE_TYPE_CHAR = platform.ConstantInteger('FILE_TYPE_CHAR') FILE_TYPE_PIPE = platform.ConstantInteger('FILE_TYPE_PIPE') FILE_WRITE_ATTRIBUTES = platform.ConstantInteger( 'FILE_WRITE_ATTRIBUTES') OPEN_EXISTING = platform.ConstantInteger('OPEN_EXISTING') FILE_FLAG_BACKUP_SEMANTICS = platform.ConstantInteger( 'FILE_FLAG_BACKUP_SEMANTICS') VOLUME_NAME_DOS = platform.ConstantInteger('VOLUME_NAME_DOS') VOLUME_NAME_NT = platform.ConstantInteger('VOLUME_NAME_NT') WIN32_FILE_ATTRIBUTE_DATA = platform.Struct( 'WIN32_FILE_ATTRIBUTE_DATA', [('dwFileAttributes', rwin32.DWORD), ('nFileSizeHigh', rwin32.DWORD), ('nFileSizeLow', rwin32.DWORD), ('ftCreationTime', rwin32.FILETIME), ('ftLastAccessTime', rwin32.FILETIME), ('ftLastWriteTime', rwin32.FILETIME)]) BY_HANDLE_FILE_INFORMATION = platform.Struct( 'BY_HANDLE_FILE_INFORMATION', [('dwFileAttributes', rwin32.DWORD), ('ftCreationTime', rwin32.FILETIME), ('ftLastAccessTime', rwin32.FILETIME), ('ftLastWriteTime', rwin32.FILETIME), ('dwVolumeSerialNumber', rwin32.DWORD), ('nFileSizeHigh', rwin32.DWORD), ('nFileSizeLow', rwin32.DWORD), ('nNumberOfLinks', rwin32.DWORD), ('nFileIndexHigh', rwin32.DWORD), ('nFileIndexLow', rwin32.DWORD)])
def flatten(self, S): start = 0 if S._names and self.equivalent_substruct(S, S._names[0]): SUBTYPE = S._flds[S._names[0]] if isinstance(SUBTYPE, lltype.Struct): self.flatten(SUBTYPE) start = 1 else: ARRAY = lltype.FixedSizeArray(SUBTYPE, 1) self.direct_fieldptr_key[ARRAY, 'item0'] = S, S._names[0] for name in S._names[start:]: key = S, name FIELDTYPE = S._flds[name] if key in self.accessed_substructs: self.needsubmallocs.append(key) self.flatnames.append(key) self.newvarstype[key] = lltype.Ptr(lltype.GcStruct('wrapper', ('data', FIELDTYPE))) elif not isinstance(FIELDTYPE, lltype.ContainerType): example = FIELDTYPE._defl() constant = Constant(example) constant.concretetype = FIELDTYPE self.flatconstants[key] = constant self.flatnames.append(key) self.newvarstype[key] = FIELDTYPE
def test_cast_structfield_pointer(): S = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed)) s = lltype.malloc(S) SUBARRAY = lltype.FixedSizeArray(lltype.Signed, 1) adr = cast_ptr_to_adr(s) + offsetof(S, 'y') subarray = cast_adr_to_ptr(adr, lltype.Ptr(SUBARRAY)) subarray[0] = 121 assert s.y == 121
def op_gc_store(p, ofs, newvalue): from rpython.rtyper.lltypesystem import rffi if lltype.typeOf(p) is not llmemory.Address: p = llmemory.cast_ptr_to_adr(p) TVAL = lltype.typeOf(newvalue) p = llmemory.cast_adr_to_ptr(p + ofs, lltype.Ptr(lltype.FixedSizeArray(TVAL, 1))) p[0] = newvalue
def register_time_clock(self): if sys.platform == 'win32': # hacking to avoid LARGE_INTEGER which is a union... A = lltype.FixedSizeArray(lltype.SignedLongLong, 1) QueryPerformanceCounter = self.llexternal( 'QueryPerformanceCounter', [lltype.Ptr(A)], lltype.Void, releasegil=False) QueryPerformanceFrequency = self.llexternal( 'QueryPerformanceFrequency', [lltype.Ptr(A)], rffi.INT, releasegil=False) class State(object): pass state = State() state.divisor = 0.0 state.counter_start = 0 def time_clock_llimpl(): a = lltype.malloc(A, flavor='raw') if state.divisor == 0.0: QueryPerformanceCounter(a) state.counter_start = a[0] QueryPerformanceFrequency(a) state.divisor = float(a[0]) QueryPerformanceCounter(a) diff = a[0] - state.counter_start lltype.free(a, flavor='raw') return float(diff) / state.divisor elif self.CLOCK_PROCESS_CPUTIME_ID is not None: # Linux and other POSIX systems with clock_gettime() self.configure(CConfigForClockGetTime) TIMESPEC = self.TIMESPEC CLOCK_PROCESS_CPUTIME_ID = self.CLOCK_PROCESS_CPUTIME_ID c_clock_gettime = self.llexternal('clock_gettime', [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT, releasegil=False) def time_clock_llimpl(): a = lltype.malloc(TIMESPEC, flavor='raw') c_clock_gettime(CLOCK_PROCESS_CPUTIME_ID, a) result = (float(rffi.getintfield(a, 'c_tv_sec')) + float(rffi.getintfield(a, 'c_tv_nsec')) * 0.000000001) lltype.free(a, flavor='raw') return result else: RUSAGE = self.RUSAGE RUSAGE_SELF = self.RUSAGE_SELF or 0 c_getrusage = self.llexternal('getrusage', [rffi.INT, lltype.Ptr(RUSAGE)], lltype.Void, releasegil=False) def time_clock_llimpl(): a = lltype.malloc(RUSAGE, flavor='raw') c_getrusage(RUSAGE_SELF, a) result = (decode_timeval(a.c_ru_utime) + decode_timeval(a.c_ru_stime)) lltype.free(a, flavor='raw') return result return extdef([], float, llimpl=time_clock_llimpl, export_name='ll_time.ll_time_clock')
def test_raw_malloc_signed(): adr = raw_malloc(sizeof(lltype.Signed)) p = cast_adr_to_ptr(adr, lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1))) p[0] = 123 assert adr.signed[0] == 123 adr.signed[0] = 124 assert p[0] == 124 py.test.raises(IndexError, "adr.signed[-1]") py.test.raises(IndexError, "adr.signed[1]")
def test_raw_malloc_signed_bunch(): adr = raw_malloc(sizeof(lltype.Signed) * 50) p = cast_adr_to_ptr(adr, lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1))) for i in range(50): p[i] = 123 + i assert adr.signed[i] == 123 + i adr.signed[i] = 124 - i assert p[i] == 124 - i py.test.raises(IndexError, "adr.signed[50]")
def test_addr_keeps_object_alive(): A = lltype.Array(Address) ptr = lltype.malloc(A, 10, immortal=True) adr = cast_ptr_to_adr(ptr) + ArrayItemsOffset(A) del ptr import gc gc.collect() gc.collect() # the following line crashes if the array is dead ptr1 = cast_adr_to_ptr(adr, lltype.Ptr(lltype.FixedSizeArray(Address, 1))) ptr1[0] = NULL
def fixup_ctype(fieldtype, fieldname, expected_size_and_sign): for typeclass in [integer_class, float_class]: if fieldtype in typeclass: for ctype in typeclass: if rffi.size_and_sign(ctype) == expected_size_and_sign: return ctype if isinstance(fieldtype, lltype.FixedSizeArray): size, _ = expected_size_and_sign return lltype.FixedSizeArray(fieldtype.OF, size/_sizeof(fieldtype.OF)) raise TypeError("conflict between translating python and compiler field" " type %r for %r" % (fieldtype, fieldname))
def test_getarraysubstruct(self): py.test.skip("fails because of the interior structure changes") U = lltype.Struct('U', ('n', lltype.Signed)) for length in [1, 2]: S = lltype.GcStruct('S', ('a', lltype.FixedSizeArray(U, length))) for index in range(length): def fn(): s = lltype.malloc(S) s.a[index].n = 12 return s.a[index].n self.check(fn, [], [], 12)
class CConfig: _compilation_info_ = ExternalCompilationInfo( includes=['windows.h', 'winbase.h', 'sys/stat.h'], ) WIN32_FIND_DATA = platform.Struct( 'struct _WIN32_FIND_DATA' + suffix, # Only interesting fields [('dwFileAttributes', rwin32.DWORD), ('nFileSizeHigh', rwin32.DWORD), ('nFileSizeLow', rwin32.DWORD), ('ftCreationTime', rwin32.FILETIME), ('ftLastAccessTime', rwin32.FILETIME), ('ftLastWriteTime', rwin32.FILETIME), ('cFileName', lltype.FixedSizeArray(traits.CHAR, 250))])
def test_structarray_add(): S = lltype.Struct("S", ("x", lltype.Signed)) for a in [ lltype.malloc(lltype.GcArray(S), 5), lltype.malloc(lltype.FixedSizeArray(S, 5), immortal=True) ]: a[3].x = 42 adr_s = cast_ptr_to_adr(a) adr_s += itemoffsetof(lltype.typeOf(a).TO, 0) adr_s += sizeof(S) * 3 s = cast_adr_to_ptr(adr_s, lltype.Ptr(S)) assert s.x == 42
def test_confusion_with_fixedarray_item_0(): A = lltype.FixedSizeArray(lltype.Signed, 5) B = lltype.FixedSizeArray(A, 3) myoffset = itemoffsetof(A, 4) global_b = lltype.malloc(B, immortal=True) global_b[0][4] = 1000 global_b[1][4] = 1010 global_b[2][4] = 1200 def f(n): a = global_b[n] # bug: with n=0, this was considered as the # first inlined substructure, confusing # normalizeptr(a) into returning global_b adr_a = cast_ptr_to_adr(a) return (adr_a + myoffset).signed[0] assert f(2) == 1200 assert f(1) == 1010 assert f(0) == 1000 res = interpret(f, [0]) assert res == 1000
def test_fixedsizearray(self): A = lltype.FixedSizeArray(lltype.Signed, 3) S = lltype.GcStruct('S', ('a', A)) def fn(n1, n2): s = lltype.malloc(S) a = s.a a[0] = n1 a[2] = n2 return a[0] - a[2] self.check(fn, [int, int], [100, 42], 58, expected_mallocs=1) # no support for interior arrays
def test_getarraysubstruct(self): py.test.skip("llptr support not really useful any more") U = lltype.Struct('U', ('n', lltype.Signed)) for length in [1, 2]: S = lltype.GcStruct('S', ('a', lltype.FixedSizeArray(U, length))) for index in range(length): def fn(): s = lltype.malloc(S) s.a[index].n = 12 return s.a[index].n self.check(fn, [], [], 12)
def test_array(): dirent = rffi_platform.getstruct( "struct dirent", """ struct dirent /* for this example only, not the exact dirent */ { long d_ino; int d_off; unsigned short d_reclen; char d_name[32]; }; """, [("d_name", lltype.FixedSizeArray(rffi.CHAR, 1))]) assert dirent.c_d_name.length == 32
class CConfig(object): timelib_special = platform.Struct('timelib_special', [ ('type', lltype.Unsigned), ('amount', lltype.Signed), ]) tlocinfo = platform.Struct('tlocinfo', [ ('country_code', lltype.FixedSizeArray(lltype.Char, 3)), ('latitude', lltype.Float), ('longitude', lltype.Float), ('comments', rffi.CCHARP), ]) _compilation_info_ = eci
def test_force_cast(self): from rpython.rtyper.annlowlevel import llstr from rpython.rtyper.lltypesystem.rstr import STR from rpython.rtyper.lltypesystem import rffi, llmemory, lltype P = lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1)) def f(): a = llstr("xyz") b = (llmemory.cast_ptr_to_adr(a) + llmemory.offsetof(STR, 'chars') + llmemory.itemoffsetof(STR.chars, 0)) buf = rffi.cast(rffi.VOIDP, b) return buf[2] fn = self.getcompiled(f, []) res = fn() assert res == 'z'
def _raw_malloc(self, rest, zero): assert not rest if (isinstance(self.TYPE, lltype.ContainerType) and self.TYPE._gckind == 'gc'): assert self.repeat == 1 p = lltype.malloc(self.TYPE, flavor='raw', zero=zero, track_allocation=False) return cast_ptr_to_adr(p) else: T = lltype.FixedSizeArray(self.TYPE, self.repeat) p = lltype.malloc(T, flavor='raw', zero=zero, track_allocation=False) array_adr = cast_ptr_to_adr(p) return array_adr + ArrayItemsOffset(T)
def test_fakeaccessor(): S = lltype.GcStruct("S", ("x", lltype.Signed), ("y", lltype.Signed)) s = lltype.malloc(S) s.x = 123 s.y = 456 adr = cast_ptr_to_adr(s) adr += FieldOffset(S, "y") assert adr.signed[0] == 456 adr.signed[0] = 789 assert s.y == 789 A = lltype.GcArray(lltype.Signed) a = lltype.malloc(A, 5) a[3] = 123 adr = cast_ptr_to_adr(a) assert (adr + ArrayLengthOffset(A)).signed[0] == 5 assert (adr + ArrayItemsOffset(A)).signed[3] == 123 (adr + ArrayItemsOffset(A)).signed[3] = 456 assert a[3] == 456 adr1000 = (adr + ArrayItemsOffset(A) + ItemOffset(lltype.Signed, 1000)) assert adr1000.signed[-997] == 456 A = lltype.GcArray(lltype.Char) a = lltype.malloc(A, 5) a[3] = '*' adr = cast_ptr_to_adr(a) assert (adr + ArrayLengthOffset(A)).signed[0] == 5 assert (adr + ArrayItemsOffset(A)).char[3] == '*' (adr + ArrayItemsOffset(A)).char[3] = '+' assert a[3] == '+' adr1000 = (adr + ArrayItemsOffset(A) + ItemOffset(lltype.Char, 1000)) assert adr1000.char[-997] == '+' T = lltype.FixedSizeArray(lltype.Char, 10) S = lltype.GcStruct('S', ('z', lltype.Ptr(T))) s = lltype.malloc(S) s.z = lltype.malloc(T, immortal=True) adr = cast_ptr_to_adr(s) assert (adr + offsetof(S, 'z')).address[0] == cast_ptr_to_adr(s.z) (adr + offsetof(S, 'z')).address[0] = NULL assert s.z == lltype.nullptr(T) t = lltype.malloc(T, immortal=True) (adr + offsetof(S, 'z')).address[0] = cast_ptr_to_adr(t) assert s.z == t
def test_raw_memcopy_nonrec(): T = lltype.GcStruct('T', ('x', lltype.Signed)) A = lltype.FixedSizeArray(lltype.Ptr(T), 1) t1 = lltype.malloc(T) t2 = lltype.malloc(T) t1.x = 1 t2.x = 2 at1 = raw_malloc(sizeof(A)) at2 = raw_malloc(sizeof(A)) p1 = cast_adr_to_ptr(at1, lltype.Ptr(A)) p2 = cast_adr_to_ptr(at2, lltype.Ptr(A)) p1[0] = t1 p2[0] = t2 raw_memcopy(at1, at2, sizeof(A)) assert p1[0] == t1 assert p2[0] == t1 assert t1.x == 1 # not assert t2.x == 2 # modified
def raw_memcopy(self, srcadr, dstadr): repeat = self.repeat if repeat == 0: return if isinstance(self.TYPE, lltype.ContainerType): PTR = lltype.Ptr(self.TYPE) elif self.TYPE == GCREF: self._raw_memcopy_gcrefs(srcadr, dstadr) return else: PTR = lltype.Ptr(lltype.FixedSizeArray(self.TYPE, 1)) while True: src = cast_adr_to_ptr(srcadr, PTR) dst = cast_adr_to_ptr(dstadr, PTR) _reccopy(src, dst) repeat -= 1 if repeat <= 0: break srcadr += ItemOffset(self.TYPE) dstadr += ItemOffset(self.TYPE)
def test_itemoffsetof_fixedsizearray(): ARRAY = lltype.FixedSizeArray(lltype.Signed, 5) itemoffsets = [llmemory.itemoffsetof(ARRAY, i) for i in range(5)] a = lltype.malloc(ARRAY, immortal=True) def f(): adr = llmemory.cast_ptr_to_adr(a) result = 0 for i in range(5): a[i] = i + 1 for i in range(5): result = result * 10 + (adr + itemoffsets[i]).signed[0] for i in range(5): (adr + itemoffsets[i]).signed[0] = i for i in range(5): result = 10 * result + a[i] return result fn = compile(f, []) res = fn() assert res == 1234501234
def setup(): INSPECT = { 'b': 'signed char', 'h': 'signed short', 'i': 'signed int', 'l': 'signed long', 'q': 'signed long long', 'n': 'ssize_t', 'B': 'unsigned char', 'H': 'unsigned short', 'I': 'unsigned int', 'L': 'unsigned long', 'Q': 'unsigned long long', 'N': 'size_t', 'P': 'char *', 'f': 'float', 'd': 'double', '?': '_Bool', } pre_include_bits = [ """ #include <sys/types.h> #ifdef _MSC_VER #define _Bool char typedef int ssize_t; /* XXX fixme for 64 bit*/ typedef unsigned int size_t; /* XXX fixme for 64 bit*/ #endif""" ] field_names = dict.fromkeys(INSPECT) for fmtchar, ctype in INSPECT.iteritems(): field_name = ctype.replace(" ", "_").replace("*", "star") field_names[fmtchar] = field_name pre_include_bits.append(""" struct about_%s { char pad; %s field; }; """ % (field_name, ctype)) class CConfig: _compilation_info_ = ExternalCompilationInfo( pre_include_bits=pre_include_bits) for fmtchar, ctype in INSPECT.items(): setattr( CConfig, field_names[fmtchar], rffi_platform.Struct( "struct about_%s" % (field_names[fmtchar], ), [('field', lltype.FixedSizeArray(rffi.CHAR, 1))])) cConfig = rffi_platform.configure(CConfig) for fmtchar, ctype in INSPECT.items(): S = cConfig[field_names[fmtchar]] alignment = rffi.offsetof(S, 'c_field') size = rffi.sizeof(S.c_field) signed = 'a' <= fmtchar <= 'z' if fmtchar == 'f': pack = pack_float unpack = std.unpack_float elif fmtchar == 'd': pack = pack_double unpack = std.unpack_double elif fmtchar == '?': pack = std.pack_bool unpack = std.unpack_bool else: pack = std.make_int_packer(size, signed) unpack = std.make_int_unpacker(size, signed) native_fmttable[fmtchar] = { 'size': size, 'alignment': alignment, 'pack': pack, 'unpack': unpack }
pos = utf8.find("\xed", pos) if pos < 0: return -1 assert pos <= len(utf8) - 1 # otherwise invalid utf-8 ordch2 = ord(utf8[pos + 1]) if _invalid_byte_2_of_3(0xed, ordch2, allow_surrogates=False): return pos pos += 1 return -1 UTF8_INDEX_STORAGE = lltype.GcArray( lltype.Struct( 'utf8_loc_elem', ('baseindex', lltype.Signed), ('ofs', lltype.FixedSizeArray(lltype.Char, 16)), )) def null_storage(): return lltype.nullptr(UTF8_INDEX_STORAGE) def create_utf8_index_storage(utf8, utf8len): """ Create an index storage which stores index of each 4th character in utf8 encoded unicode string. """ arraysize = utf8len // 64 + 1 storage = lltype.malloc(UTF8_INDEX_STORAGE, arraysize) baseindex = 0 current = 0
class CConfig: _compilation_info_ = eci DIRENT = platform.Struct( "struct dirent", [("d_name", lltype.FixedSizeArray(rffi.CHAR, 1))])