[pypy-commit] pypy const-correctness: Progress
amauryfa
noreply at buildbot.pypy.org
Fri Sep 13 08:34:30 CEST 2013
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: const-correctness
Changeset: r66931:5d4e27857d0a
Date: 2013-09-11 00:19 +0200
http://bitbucket.org/pypy/pypy/changeset/5d4e27857d0a/
Log: Progress
diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py
--- a/rpython/annotator/binaryop.py
+++ b/rpython/annotator/binaryop.py
@@ -874,9 +874,7 @@
class __extend__(pairtype(SomePtr, SomePtr)):
def union((p1, p2)):
- assert p1.ll_ptrtype == p2.ll_ptrtype,("mixing of incompatible pointer types: %r, %r" %
- (p1.ll_ptrtype, p2.ll_ptrtype))
- return SomePtr(p1.ll_ptrtype)
+ return SomePtr(p1.ll_ptrtype.union(p2.ll_ptrtype))
class __extend__(pairtype(SomePtr, SomeInteger)):
diff --git a/rpython/rlib/rdtoa.py b/rpython/rlib/rdtoa.py
--- a/rpython/rlib/rdtoa.py
+++ b/rpython/rlib/rdtoa.py
@@ -39,7 +39,7 @@
)
dg_strtod = rffi.llexternal(
- '_PyPy_dg_strtod', [rffi.CCHARP, rffi.CCHARPP], rffi.DOUBLE,
+ '_PyPy_dg_strtod', [rffi.CONST_CCHARP, rffi.CCHARPP], rffi.DOUBLE,
compilation_info=eci, sandboxsafe=True)
dg_dtoa = rffi.llexternal(
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -636,7 +636,7 @@
if len(ARGS) != len(args_v):
raise TypeError("graph with %d args called with wrong func ptr type: %r" %(len(args_v), ARGS))
for T, v in zip(ARGS, args_v):
- if not lltype.isCompatibleType(T, v.concretetype):
+ if not lltype.isConvertibleFrom(T, v.concretetype):
raise TypeError("graph with %r args called with wrong func ptr type: %r" %
(tuple([v.concretetype for v in args_v]), ARGS))
frame = self.newsubframe(graph, args)
diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py
--- a/rpython/rtyper/lltypesystem/lltype.py
+++ b/rpython/rtyper/lltypesystem/lltype.py
@@ -103,7 +103,10 @@
def __ne__(self, other):
return not (self == other)
- _is_compatible = __eq__
+ def _is_convertible_from(self, other):
+ if self == other:
+ return True
+ return remove_const(self) == other
def __setattr__(self, attr, nvalue):
try:
@@ -766,6 +769,15 @@
hints={'interior_ptr_type':True})
return R
+ def union(self, other):
+ if self == other:
+ return self
+ if remove_const(self) == remove_const(other):
+ return add_const(self)
+ raise AssertionError(
+ "mixing of incompatible pointer types: %r, %r" % (self, other))
+
+
class InteriorPtr(LowLevelType):
def __init__(self, PARENTTYPE, TO, offsets):
self.PARENTTYPE = PARENTTYPE
@@ -984,14 +996,29 @@
"The same type as T, but with any top level const-qualifier removed."
if isinstance(T, Ptr):
return Ptr(remove_const(T.TO))
+ if not isinstance(T, (Array, Struct)):
+ return T
if not T._hints.get('render_as_const'):
return T
- hints = T._hints.copy()
- del hints['render_as_const']
T2 = object.__new__(type(T))
T2.__dict__.update(T.__dict__)
- T2._hints = T2._hints.copy()
- del T2._hints['render_as_const']
+ hints = T2._hints.copy()
+ del hints['render_as_const']
+ T2._hints = frozendict(hints)
+ return T2
+
+def add_const(T):
+ "The same type as T, but with any top level const-qualifier removed."
+ if isinstance(T, Ptr):
+ return Ptr(add_const(T.TO))
+ assert isinstance(T, (Array, Struct))
+ if T._hints.get('render_as_const'):
+ return T
+ T2 = object.__new__(type(T))
+ T2.__dict__.update(T.__dict__)
+ hints = T2._hints.copy()
+ hints['render_as_const'] = True
+ T2._hints = frozendict(hints)
return T2
def direct_fieldptr(structptr, fieldname):
@@ -1212,7 +1239,7 @@
if isinstance(T1, ContainerType):
raise TypeError("cannot directly assign to container array items")
T2 = typeOf(val)
- if T2 != T1:
+ if not isConvertibleFrom(T1, T2):
from rpython.rtyper.lltypesystem import rffi
if T1 is rffi.VOIDP and isinstance(T2, Ptr):
# Any pointer is convertible to void*
@@ -1262,7 +1289,7 @@
if len(args) != len(self._T.ARGS):
raise TypeError,"calling %r with wrong argument number: %r" % (self._T, args)
for i, a, ARG in zip(range(len(self._T.ARGS)), args, self._T.ARGS):
- if typeOf(a) != remove_const(ARG):
+ if not isConvertibleFrom(ARG, typeOf(a)):
# ARG could be Void
if ARG == Void:
try:
@@ -2134,8 +2161,8 @@
raise ValueError("init_identity_hash(): not for varsized types")
p._obj._hash_cache_ = intmask(value)
-def isCompatibleType(TYPE1, TYPE2):
- return TYPE1._is_compatible(TYPE2)
+def isConvertibleFrom(TYPE1, TYPE2):
+ return TYPE1._is_convertible_from(TYPE2)
def enforce(TYPE, value):
return TYPE._enforce(value)
diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py
--- a/rpython/rtyper/lltypesystem/rffi.py
+++ b/rpython/rtyper/lltypesystem/rffi.py
@@ -650,12 +650,14 @@
CCHARP = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True}))
# const char *
-CONST_CCHARP = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True,
- 'render_as_const': True}))
+CONST_CCHARP = lltype.add_const(CCHARP)
# wchar_t *
CWCHARP = lltype.Ptr(lltype.Array(lltype.UniChar, hints={'nolength': True}))
+# const wchar_t *
+CONST_CWCHARP = lltype.add_const(CWCHARP)
+
# int *, unsigned int *, etc.
#INTP = ... see setup() above
@@ -684,6 +686,7 @@
from rpython.rtyper.annlowlevel import llstr as llstrtype
from rpython.rtyper.annlowlevel import hlstr as hlstrtype
TYPEP = CCHARP
+ CONST_TYPEP = CONST_CCHARP
ll_char_type = lltype.Char
lastchar = '\x00'
builder_class = StringBuilder
@@ -694,6 +697,7 @@
from rpython.rtyper.annlowlevel import llunicode as llstrtype
from rpython.rtyper.annlowlevel import hlunicode as hlstrtype
TYPEP = CWCHARP
+ CONST_TYPEP = CONST_CWCHARP
ll_char_type = lltype.UniChar
lastchar = u'\x00'
builder_class = UnicodeBuilder
@@ -710,7 +714,7 @@
ll_s = llstrtype(s)
copy_string_to_raw(ll_s, array, 0, i)
array[i] = lastchar
- return array
+ return cast(CONST_TYPEP, array)
str2charp._annenforceargs_ = [strtype, bool]
def free_charp(cp, track_allocation=True):
@@ -867,6 +871,7 @@
# char**
CCHARPP = lltype.Ptr(lltype.Array(CCHARP, hints={'nolength': True}))
+CONST_CCHARPP = lltype.Ptr(lltype.Array(CONST_CCHARP, hints={'nolength': True}))
def liststr2charpp(l):
""" list[str] -> char**, NULL terminated
diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py b/rpython/rtyper/lltypesystem/test/test_rffi.py
--- a/rpython/rtyper/lltypesystem/test/test_rffi.py
+++ b/rpython/rtyper/lltypesystem/test/test_rffi.py
@@ -57,7 +57,7 @@
def test_string(self):
eci = ExternalCompilationInfo(includes=['string.h'])
- z = llexternal('strlen', [CCHARP], Signed, compilation_info=eci)
+ z = llexternal('strlen', [CONST_CCHARP], Signed, compilation_info=eci)
def f():
s = str2charp("xxx")
@@ -70,7 +70,7 @@
def test_unicode(self):
eci = ExternalCompilationInfo(includes=['string.h'])
- z = llexternal('wcslen', [CWCHARP], Signed, compilation_info=eci)
+ z = llexternal('wcslen', [CONST_CWCHARP], Signed, compilation_info=eci)
def f():
s = unicode2wcharp(u"xxx\xe9")
@@ -87,7 +87,7 @@
#include <src/allocator.h>
#include <src/mem.h>
- char *f(char* arg)
+ char *f(const char* arg)
{
char *ret;
/* lltype.free uses OP_RAW_FREE, we must allocate
@@ -99,8 +99,8 @@
}
""")
eci = ExternalCompilationInfo(separate_module_sources=[c_source],
- post_include_bits=['char *f(char*);'])
- z = llexternal('f', [CCHARP], CCHARP, compilation_info=eci)
+ post_include_bits=['char *f(const char*);'])
+ z = llexternal('f', [CONST_CCHARP], CCHARP, compilation_info=eci)
def f():
s = str2charp("xxx")
@@ -117,7 +117,7 @@
c_source = """
#include <string.h>
- int f(char *args[]) {
+ int f(const char *args[]) {
char **p = args;
int l = 0;
while (*p) {
@@ -128,11 +128,11 @@
}
"""
eci = ExternalCompilationInfo(separate_module_sources=[c_source])
- z = llexternal('f', [CCHARPP], Signed, compilation_info=eci)
+ z = llexternal('f', [CONST_CCHARPP], Signed, compilation_info=eci)
def f():
l = ["xxx", "x", "xxxx"]
- ss = liststr2charpp(l)
+ ss = liststr2charpp(cast(CONST_CCHARPP, l))
result = z(ss)
free_charpp(ss)
return result
@@ -617,14 +617,14 @@
def test_stringpolicy1(self):
eci = ExternalCompilationInfo(includes=['string.h'])
- strlen = llexternal('strlen', [CCHARP], SIZE_T, compilation_info=eci)
+ strlen = llexternal('strlen', [CONST_CCHARP], SIZE_T, compilation_info=eci)
def f():
return cast(SIGNED, strlen("Xxx"))
assert interpret(f, [], backendopt=True) == 3
def test_stringpolicy3(self):
eci = ExternalCompilationInfo(includes=['string.h'])
- strlen = llexternal('strlen', [CCHARP], INT, compilation_info=eci)
+ strlen = llexternal('strlen', [CONST_CCHARP], INT, compilation_info=eci)
def f():
ll_str = str2charp("Xxx")
res = strlen(ll_str)
@@ -635,7 +635,7 @@
def test_stringpolicy_mixed(self):
eci = ExternalCompilationInfo(includes=['string.h'])
- strlen = llexternal('strlen', [CCHARP], SIZE_T,
+ strlen = llexternal('strlen', [CONST_CCHARP], SIZE_T,
compilation_info=eci)
def f():
res1 = strlen("abcd")
diff --git a/rpython/rtyper/module/ll_os_environ.py b/rpython/rtyper/module/ll_os_environ.py
--- a/rpython/rtyper/module/ll_os_environ.py
+++ b/rpython/rtyper/module/ll_os_environ.py
@@ -115,13 +115,13 @@
def r_putenv(name, value):
just_a_placeholder
-os_getenv = rffi.llexternal('getenv', [rffi.CCHARP], rffi.CCHARP,
+os_getenv = rffi.llexternal('getenv', [rffi.CONST_CCHARP], rffi.CCHARP,
threadsafe=False)
-os_putenv = rffi.llexternal('putenv', [rffi.CCHARP], rffi.INT)
+os_putenv = rffi.llexternal('putenv', [rffi.CONST_CCHARP], rffi.INT)
if _WIN32:
- _wgetenv = rffi.llexternal('_wgetenv', [rffi.CWCHARP], rffi.CWCHARP,
+ _wgetenv = rffi.llexternal('_wgetenv', [rffi.CONST_CWCHARP], rffi.CWCHARP,
compilation_info=eci, threadsafe=False)
- _wputenv = rffi.llexternal('_wputenv', [rffi.CWCHARP], rffi.INT,
+ _wputenv = rffi.llexternal('_wputenv', [rffi.CONST_CWCHARP], rffi.INT,
compilation_info=eci)
class EnvKeepalive:
diff --git a/rpython/rtyper/rmodel.py b/rpython/rtyper/rmodel.py
--- a/rpython/rtyper/rmodel.py
+++ b/rpython/rtyper/rmodel.py
@@ -3,7 +3,7 @@
from rpython.rtyper.error import TyperError, MissingRTypeOperation
from rpython.rtyper.lltypesystem import lltype
from rpython.rtyper.lltypesystem.lltype import (Void, Bool, Float, typeOf,
- LowLevelType, isCompatibleType)
+ LowLevelType, isConvertibleFrom)
from rpython.tool.pairtype import pairtype, extendabletype, pair
@@ -125,7 +125,7 @@
realtype = typeOf(value)
except (AssertionError, AttributeError, TypeError):
realtype = '???'
- if realtype != self.lowleveltype:
+ if realtype != lltype.remove_const(self.lowleveltype):
raise TyperError("convert_const(self = %r, value = %r)" % (
self, value))
return value
@@ -400,7 +400,7 @@
realtype = typeOf(value)
except (AssertionError, AttributeError):
realtype = '???'
- if not isCompatibleType(realtype, lltype):
+ if not isConvertibleFrom(lltype, realtype):
raise TyperError("inputconst(reqtype = %s, value = %s):\n"
"expected a %r,\n"
" got a %r" % (reqtype, value,
diff --git a/rpython/translator/c/support.py b/rpython/translator/c/support.py
--- a/rpython/translator/c/support.py
+++ b/rpython/translator/c/support.py
@@ -66,7 +66,7 @@
# check. Something else will blow up instead, probably
# very confusingly.
if not is_pointer_to_forward_ref(ACTUAL_TYPE):
- assert ACTUAL_TYPE == T
+ assert lltype.isConvertibleFrom(T, ACTUAL_TYPE)
return c.value
More information about the pypy-commit
mailing list