Skip to content

Commit

Permalink
check integer truncation (#5413) and make more operators follow T+T =…
Browse files Browse the repository at this point in the history
…> T (#3759)

the sysimg builds, but still need to:
  - check same-size signed<->unsigned conversion
  - make tests pass
  • Loading branch information
JeffBezanson committed Sep 17, 2014
1 parent 79ce765 commit effff39
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 164 deletions.
4 changes: 2 additions & 2 deletions base/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ all: pcre_h.jl errno_h.jl build_h.jl.phony fenv_constants.jl file_constants.jl u

pcre_h.jl:
ifeq ($(USE_SYSTEM_PCRE), 1)
@$(call PRINT_PERL, $(CPP) -dM $(shell $(PCRE_CONFIG) --prefix)/include/pcre.h | perl -nle '/^\s*#define\s+PCRE_(\w*)\s*\(?($(PCRE_CONST))\)?\s*$$/ and print "const $$1 = uint32($$2)"' | sort > $@)
@$(call PRINT_PERL, $(CPP) -dM $(shell $(PCRE_CONFIG) --prefix)/include/pcre.h | perl -nle '/^\s*#define\s+PCRE_(\w*)\s*\(?($(PCRE_CONST))\)?\s*$$/ and print "const $$1 = int32($$2)"' | sort > $@)
else
@$(call PRINT_PERL, $(CPP) -dM $(build_includedir)/pcre.h | perl -nle '/^\s*#define\s+PCRE_(\w*)\s*\(?($(PCRE_CONST))\)?\s*$$/ and print "const $$1 = uint32($$2)"' | sort > $@)
@$(call PRINT_PERL, $(CPP) -dM $(build_includedir)/pcre.h | perl -nle '/^\s*#define\s+PCRE_(\w*)\s*\(?($(PCRE_CONST))\)?\s*$$/ and print "const $$1 = int32($$2)"' | sort > $@)
endif

errno_h.jl:
Expand Down
2 changes: 1 addition & 1 deletion base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ function deserialize{K,V}(s, T::Type{Dict{K,V}})
return t
end

hashindex(key, sz) = (int(hash(key)) & (sz-1)) + 1
hashindex(key, sz) = (reinterpret(Int,hash(key)) & (sz-1)) + 1

isslotempty(h::Dict, i::Int) = h.slots[i] == 0x0
isslotfilled(h::Dict, i::Int) = h.slots[i] == 0x1
Expand Down
207 changes: 47 additions & 160 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,20 @@ end

## integer arithmetic ##

-(x::SmallSigned) = -int(x)
-(x::SmallUnsigned) = -uint(x)

+{T<:SmallSigned}(x::T, y::T) = int(x) + int(y)
-{T<:SmallSigned}(x::T, y::T) = int(x) - int(y)
*{T<:SmallSigned}(x::T, y::T) = int(x) * int(y)

+{T<:SmallUnsigned}(x::T, y::T) = uint(x) + uint(y)
-{T<:SmallUnsigned}(x::T, y::T) = uint(x) - uint(y)
*{T<:SmallUnsigned}(x::T, y::T) = uint(x) * uint(y)

-(x::Int) = box(Int,neg_int(unbox(Int,x)))
-(x::Uint) = box(Uint,neg_int(unbox(Uint,x)))
-(x::Int64) = box(Int64,neg_int(unbox(Int64,x)))
-(x::Uint64) = box(Uint64,neg_int(unbox(Uint64,x)))
-(x::Int128) = box(Int128,neg_int(unbox(Int128,x)))
-(x::Uint128) = box(Uint128,neg_int(unbox(Uint128,x)))

+(x::Int, y::Int) = box(Int,add_int(unbox(Int,x),unbox(Int,y)))
+(x::Uint, y::Uint) = box(Uint,add_int(unbox(Uint,x),unbox(Uint,y)))
+(x::Int64, y::Int64) = box(Int64,add_int(unbox(Int64,x),unbox(Int64,y)))
+(x::Uint64, y::Uint64) = box(Uint64,add_int(unbox(Uint64,x),unbox(Uint64,y)))
+(x::Int128, y::Int128) = box(Int128,add_int(unbox(Int128,x),unbox(Int128,y)))
+(x::Uint128, y::Uint128) = box(Uint128,add_int(unbox(Uint128,x),unbox(Uint128,y)))

-(x::Int, y::Int) = box(Int,sub_int(unbox(Int,x),unbox(Int,y)))
-(x::Uint, y::Uint) = box(Uint,sub_int(unbox(Uint,x),unbox(Uint,y)))
-(x::Int64, y::Int64) = box(Int64,sub_int(unbox(Int64,x),unbox(Int64,y)))
-(x::Uint64, y::Uint64) = box(Uint64,sub_int(unbox(Uint64,x),unbox(Uint64,y)))
-(x::Int128, y::Int128) = box(Int128,sub_int(unbox(Int128,x),unbox(Int128,y)))
-(x::Uint128, y::Uint128) = box(Uint128,sub_int(unbox(Uint128,x),unbox(Uint128,y)))

*(x::Int, y::Int) = box(Int,mul_int(unbox(Int,x),unbox(Int,y)))
*(x::Uint, y::Uint) = box(Uint,mul_int(unbox(Uint,x),unbox(Uint,y)))
*(x::Int64, y::Int64) = box(Int64,mul_int(unbox(Int64,x),unbox(Int64,y)))
*(x::Uint64, y::Uint64) = box(Uint64,mul_int(unbox(Uint64,x),unbox(Uint64,y)))
const IntTypes = (Int8, Uint8, Int16, Uint16, Int32, Uint32,
Int64, Uint64, Int128, Uint128)

+(x::Int, y::Int) = box(Int,add_int(unbox(Int,x),unbox(Int,y)))
<(x::Int, y::Int) = slt_int(unbox(Int,x),unbox(Int,y))

for T in IntTypes
@eval begin
-(x::$T) = box($T,neg_int(unbox($T,x)))
+(x::$T, y::$T) = box($T, add_int(unbox($T,x),unbox($T,y)))
-(x::$T, y::$T) = box($T, sub_int(unbox($T,x),unbox($T,y)))
*(x::$T, y::$T) = box($T, mul_int(unbox($T,x),unbox($T,y)))
end
end

/(x::Integer, y::Integer) = float(x)/float(y)
inv(x::Integer) = float(one(x))/float(x)
Expand Down Expand Up @@ -113,89 +91,19 @@ cld{T<:Integer }(x::T, y::T) = div(x,y)+(!signbit(x$y)&(rem(x,y)!=0))

## integer bitwise operations ##

~(x::Int8 ) = box(Int8,not_int(unbox(Int8,x)))
~(x::Int16) = box(Int16,not_int(unbox(Int16,x)))
~(x::Int32) = box(Int32,not_int(unbox(Int32,x)))
~(x::Int64) = box(Int64,not_int(unbox(Int64,x)))
~(x::Int128) = box(Int128,not_int(unbox(Int128,x)))

~(x::Uint8 ) = box(Uint8,not_int(unbox(Uint8,x)))
~(x::Uint16) = box(Uint16,not_int(unbox(Uint16,x)))
~(x::Uint32) = box(Uint32,not_int(unbox(Uint32,x)))
~(x::Uint64) = box(Uint64,not_int(unbox(Uint64,x)))
~(x::Uint128) = box(Uint128,not_int(unbox(Uint128,x)))

(&)(x::Int8, y::Int8 ) = box(Int8,and_int(unbox(Int8,x),unbox(Int8,y)))
(&)(x::Int16, y::Int16) = box(Int16,and_int(unbox(Int16,x),unbox(Int16,y)))
(&)(x::Int32, y::Int32) = box(Int32,and_int(unbox(Int32,x),unbox(Int32,y)))
(&)(x::Int64, y::Int64) = box(Int64,and_int(unbox(Int64,x),unbox(Int64,y)))
(&)(x::Int128, y::Int128) = box(Int128,and_int(unbox(Int128,x),unbox(Int128,y)))

(&)(x::Uint8, y::Uint8 ) = box(Uint8,and_int(unbox(Uint8,x),unbox(Uint8,y)))
(&)(x::Uint16, y::Uint16) = box(Uint16,and_int(unbox(Uint16,x),unbox(Uint16,y)))
(&)(x::Uint32, y::Uint32) = box(Uint32,and_int(unbox(Uint32,x),unbox(Uint32,y)))
(&)(x::Uint64, y::Uint64) = box(Uint64,and_int(unbox(Uint64,x),unbox(Uint64,y)))
(&)(x::Uint128, y::Uint128) = box(Uint128,and_int(unbox(Uint128,x),unbox(Uint128,y)))

|(x::Int8, y::Int8) = box(Int8,or_int(unbox(Int8,x),unbox(Int8,y)))
|(x::Int16, y::Int16) = box(Int16,or_int(unbox(Int16,x),unbox(Int16,y)))
|(x::Int32, y::Int32) = box(Int32,or_int(unbox(Int32,x),unbox(Int32,y)))
|(x::Int64, y::Int64) = box(Int64,or_int(unbox(Int64,x),unbox(Int64,y)))
|(x::Int128, y::Int128) = box(Int128,or_int(unbox(Int128,x),unbox(Int128,y)))

|(x::Uint8, y::Uint8) = box(Uint8,or_int(unbox(Uint8,x),unbox(Uint8,y)))
|(x::Uint16, y::Uint16) = box(Uint16,or_int(unbox(Uint16,x),unbox(Uint16,y)))
|(x::Uint32, y::Uint32) = box(Uint32,or_int(unbox(Uint32,x),unbox(Uint32,y)))
|(x::Uint64, y::Uint64) = box(Uint64,or_int(unbox(Uint64,x),unbox(Uint64,y)))
|(x::Uint128, y::Uint128) = box(Uint128,or_int(unbox(Uint128,x),unbox(Uint128,y)))

($)(x::Int8, y::Int8) = box(Int8,xor_int(unbox(Int8,x),unbox(Int8,y)))
($)(x::Int16, y::Int16) = box(Int16,xor_int(unbox(Int16,x),unbox(Int16,y)))
($)(x::Int32, y::Int32) = box(Int32,xor_int(unbox(Int32,x),unbox(Int32,y)))
($)(x::Int64, y::Int64) = box(Int64,xor_int(unbox(Int64,x),unbox(Int64,y)))
($)(x::Int128, y::Int128) = box(Int128,xor_int(unbox(Int128,x),unbox(Int128,y)))

($)(x::Uint8, y::Uint8) = box(Uint8,xor_int(unbox(Uint8,x),unbox(Uint8,y)))
($)(x::Uint16, y::Uint16) = box(Uint16,xor_int(unbox(Uint16,x),unbox(Uint16,y)))
($)(x::Uint32, y::Uint32) = box(Uint32,xor_int(unbox(Uint32,x),unbox(Uint32,y)))
($)(x::Uint64, y::Uint64) = box(Uint64,xor_int(unbox(Uint64,x),unbox(Uint64,y)))
($)(x::Uint128, y::Uint128) = box(Uint128,xor_int(unbox(Uint128,x),unbox(Uint128,y)))

<<(x::Int8, y::Int32) = box(Int8,shl_int(unbox(Int8,x),unbox(Int32,y)))
<<(x::Int16, y::Int32) = box(Int16,shl_int(unbox(Int16,x),unbox(Int32,y)))
<<(x::Int32, y::Int32) = box(Int32,shl_int(unbox(Int32,x),unbox(Int32,y)))
<<(x::Int64, y::Int32) = box(Int64,shl_int(unbox(Int64,x),unbox(Int32,y)))
<<(x::Int128, y::Int32) = box(Int128,shl_int(unbox(Int128,x),unbox(Int32,y)))

<<(x::Uint8, y::Int32) = box(Uint8,shl_int(unbox(Uint8,x),unbox(Int32,y)))
<<(x::Uint16, y::Int32) = box(Uint16,shl_int(unbox(Uint16,x),unbox(Int32,y)))
<<(x::Uint32, y::Int32) = box(Uint32,shl_int(unbox(Int32,x),unbox(Uint32,y)))
<<(x::Uint64, y::Int32) = box(Uint64,shl_int(unbox(Uint64,x),unbox(Int32,y)))
<<(x::Uint128, y::Int32) = box(Uint128,shl_int(unbox(Uint128,x),unbox(Int32,y)))

>>(x::Int8, y::Int32) = box(Int8,ashr_int(unbox(Int8,x),unbox(Int32,y)))
>>(x::Int16, y::Int32) = box(Int16,ashr_int(unbox(Int16,x),unbox(Int32,y)))
>>(x::Int32, y::Int32) = box(Int32,ashr_int(unbox(Int32,x),unbox(Int32,y)))
>>(x::Int64, y::Int32) = box(Int64,ashr_int(unbox(Int64,x),unbox(Int32,y)))
>>(x::Int128, y::Int32) = box(Int128,ashr_int(unbox(Int128,x),unbox(Int32,y)))

>>(x::Uint8, y::Int32) = box(Uint8,lshr_int(unbox(Uint8,x),unbox(Int32,y)))
>>(x::Uint16, y::Int32) = box(Uint16,lshr_int(unbox(Uint16,x),unbox(Int32,y)))
>>(x::Uint32, y::Int32) = box(Uint32,lshr_int(unbox(Int32,x),unbox(Uint32,y)))
>>(x::Uint64, y::Int32) = box(Uint64,lshr_int(unbox(Uint64,x),unbox(Int32,y)))
>>(x::Uint128, y::Int32) = box(Uint128,lshr_int(unbox(Uint128,x),unbox(Int32,y)))

>>>(x::Int8, y::Int32) = box(Int8,lshr_int(unbox(Int8,x),unbox(Int32,y)))
>>>(x::Int16, y::Int32) = box(Int16,lshr_int(unbox(Int16,x),unbox(Int32,y)))
>>>(x::Int32, y::Int32) = box(Int32,lshr_int(unbox(Int32,x),unbox(Int32,y)))
>>>(x::Int64, y::Int32) = box(Int64,lshr_int(unbox(Int64,x),unbox(Int32,y)))
>>>(x::Int128, y::Int32) = box(Int128,lshr_int(unbox(Int128,x),unbox(Int32,y)))

>>>(x::Uint8, y::Int32) = box(Uint8,lshr_int(unbox(Uint8,x),unbox(Int32,y)))
>>>(x::Uint16, y::Int32) = box(Uint16,lshr_int(unbox(Uint16,x),unbox(Int32,y)))
>>>(x::Uint32, y::Int32) = box(Uint32,lshr_int(unbox(Int32,x),unbox(Uint32,y)))
>>>(x::Uint64, y::Int32) = box(Uint64,lshr_int(unbox(Uint64,x),unbox(Int32,y)))
>>>(x::Uint128, y::Int32) = box(Uint128,lshr_int(unbox(Uint128,x),unbox(Int32,y)))
for T in IntTypes
@eval begin
~(x::$T) = box($T,not_int(unbox($T,x)))

(&)(x::$T, y::$T) = box($T,and_int(unbox($T,x),unbox($T,y)))
(|)(x::$T, y::$T) = box($T, or_int(unbox($T,x),unbox($T,y)))
($)(x::$T, y::$T) = box($T,xor_int(unbox($T,x),unbox($T,y)))

<<(x::$T, y::Int32) = box($T, shl_int(unbox($T,x),unbox(Int32,y)))
>>(x::$T, y::Int32) = box($T,ashr_int(unbox($T,x),unbox(Int32,y)))
>>>(x::$T, y::Int32) = box($T,lshr_int(unbox($T,x),unbox(Int32,y)))
end
end

bswap(x::Int8) = x
bswap(x::Uint8) = x
Expand All @@ -208,39 +116,13 @@ bswap(x::Uint64) = box(Uint64,bswap_int(unbox(Uint64,x)))
bswap(x::Int128) = box(Int128,bswap_int(unbox(Int128,x)))
bswap(x::Uint128) = box(Uint128,bswap_int(unbox(Uint128,x)))

count_ones(x::Int8) = int(box(Int8,ctpop_int(unbox(Int8,x))))
count_ones(x::Uint8) = int(box(Uint8,ctpop_int(unbox(Uint8,x))))
count_ones(x::Int16) = int(box(Int16,ctpop_int(unbox(Int16,x))))
count_ones(x::Uint16) = int(box(Uint16,ctpop_int(unbox(Uint16,x))))
count_ones(x::Int32) = int(box(Int32,ctpop_int(unbox(Int32,x))))
count_ones(x::Uint32) = int(box(Uint32,ctpop_int(unbox(Uint32,x))))
count_ones(x::Int64) = int(box(Int64,ctpop_int(unbox(Int64,x))))
count_ones(x::Uint64) = int(box(Uint64,ctpop_int(unbox(Uint64,x))))
count_ones(x::Int128) = int(box(Int128,ctpop_int(unbox(Int128,x))))
count_ones(x::Uint128) = int(box(Uint128,ctpop_int(unbox(Uint128,x))))

leading_zeros(x::Int8) = int(box(Int8,ctlz_int(unbox(Int8,x))))
leading_zeros(x::Uint8) = int(box(Uint8,ctlz_int(unbox(Uint8,x))))
leading_zeros(x::Int16) = int(box(Int16,ctlz_int(unbox(Int16,x))))
leading_zeros(x::Uint16) = int(box(Uint16,ctlz_int(unbox(Uint16,x))))
leading_zeros(x::Int32) = int(box(Int32,ctlz_int(unbox(Int32,x))))
leading_zeros(x::Uint32) = int(box(Uint32,ctlz_int(unbox(Uint32,x))))
leading_zeros(x::Int64) = int(box(Int64,ctlz_int(unbox(Int64,x))))
leading_zeros(x::Uint64) = int(box(Uint64,ctlz_int(unbox(Uint64,x))))
leading_zeros(x::Int128) = int(box(Int128,ctlz_int(unbox(Int128,x))))
leading_zeros(x::Uint128) = int(box(Uint128,ctlz_int(unbox(Uint128,x))))

trailing_zeros(x::Int8) = int(box(Int8,cttz_int(unbox(Int8,x))))
trailing_zeros(x::Uint8) = int(box(Uint8,cttz_int(unbox(Uint8,x))))
trailing_zeros(x::Int16) = int(box(Int16,cttz_int(unbox(Int16,x))))
trailing_zeros(x::Uint16) = int(box(Uint16,cttz_int(unbox(Uint16,x))))
trailing_zeros(x::Int32) = int(box(Int32,cttz_int(unbox(Int32,x))))
trailing_zeros(x::Uint32) = int(box(Uint32,cttz_int(unbox(Uint32,x))))
trailing_zeros(x::Int64) = int(box(Int64,cttz_int(unbox(Int64,x))))
trailing_zeros(x::Uint64) = int(box(Uint64,cttz_int(unbox(Uint64,x))))
trailing_zeros(x::Int128) = int(box(Int128,cttz_int(unbox(Int128,x))))
trailing_zeros(x::Uint128) = int(box(Uint128,cttz_int(unbox(Uint128,x))))

for T in IntTypes
@eval begin
count_ones(x::$T) = int(box($T,ctpop_int(unbox($T,x))))
leading_zeros(x::$T) = int(box($T,ctlz_int(unbox($T,x))))
trailing_zeros(x::$T) = int(box($T,cttz_int(unbox($T,x))))
end
end
count_zeros (x::Integer) = count_ones(~x)
leading_ones (x::Integer) = leading_zeros(~x)
trailing_ones(x::Integer) = trailing_zeros(~x)
Expand Down Expand Up @@ -284,9 +166,14 @@ const _inttypes = (Bool, Int8, Uint8, Int16, Uint16, Int32, Uint32, Char,
Int64, Uint64, Int128, Uint128)

for to in _inttypes, from in _inttypes
if !(to===from) && !(to===Bool)
if !(to === from) && !(to === Bool)
if to.size < from.size
@eval convert(::Type{$to}, x::($from)) = box($to,trunc_int($to,unbox($from,x)))
if issubtype(to, Signed)
@eval convert(::Type{$to}, x::($from)) = box($to,checked_trunc_sint($to,unbox($from,x)))
else
@eval convert(::Type{$to}, x::($from)) = box($to,checked_trunc_uint($to,unbox($from,x)))
end
@eval itrunc(::Type{$to}, x::($from)) = box($to,trunc_int($to,unbox($from,x)))
elseif from.size < to.size || from===Bool
if issubtype(from, Signed)
@eval convert(::Type{$to}, x::($from)) = box($to,sext_int($to,unbox($from,x)))
Expand Down Expand Up @@ -402,9 +289,9 @@ const WORD_SIZE = int(Int.size)*8

## integer promotions ##

promote_rule(::Type{Int16}, ::Type{Int8} ) = Int
promote_rule(::Type{Int32}, ::Type{Int8} ) = Int
promote_rule(::Type{Int32}, ::Type{Int16}) = Int
promote_rule(::Type{Int16}, ::Type{Int8} ) = Int16
promote_rule(::Type{Int32}, ::Type{Int8} ) = Int32
promote_rule(::Type{Int32}, ::Type{Int16}) = Int32
promote_rule(::Type{Int64}, ::Type{Int8} ) = Int64
promote_rule(::Type{Int64}, ::Type{Int16}) = Int64
promote_rule(::Type{Int64}, ::Type{Int32}) = Int64
Expand All @@ -413,9 +300,9 @@ promote_rule(::Type{Int128}, ::Type{Int16}) = Int128
promote_rule(::Type{Int128}, ::Type{Int32}) = Int128
promote_rule(::Type{Int128}, ::Type{Int64}) = Int128

promote_rule(::Type{Uint16}, ::Type{Uint8} ) = Uint
promote_rule(::Type{Uint32}, ::Type{Uint8} ) = Uint
promote_rule(::Type{Uint32}, ::Type{Uint16}) = Uint
promote_rule(::Type{Uint16}, ::Type{Uint8} ) = Uint16
promote_rule(::Type{Uint32}, ::Type{Uint8} ) = Uint32
promote_rule(::Type{Uint32}, ::Type{Uint16}) = Uint32
promote_rule(::Type{Uint64}, ::Type{Uint8} ) = Uint64
promote_rule(::Type{Uint64}, ::Type{Uint16}) = Uint64
promote_rule(::Type{Uint64}, ::Type{Uint32}) = Uint64
Expand Down
2 changes: 1 addition & 1 deletion base/string.jl
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ const memhash = Uint == Uint64 ? :memhash_seed : :memhash32_seed

function hash{T<:ByteString}(s::Union(T,SubString{T}), h::Uint)
h += uint(0x71e729fd56419c81)
ccall(memhash, Uint, (Ptr{Uint8}, Csize_t, Uint32), s, sizeof(s), h) + h
ccall(memhash, Uint, (Ptr{Uint8}, Csize_t, Uint32), s, sizeof(s), itrunc(Uint32,h)) + h
end
hash(s::String, h::Uint) = hash(bytestring(s), h)

Expand Down

0 comments on commit effff39

Please sign in to comment.