Skip to content

Commit

Permalink
Merge c59459c into 0df3f7d
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson authored Aug 15, 2017
2 parents 0df3f7d + c59459c commit 3d74919
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 62 deletions.
2 changes: 1 addition & 1 deletion base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ for (fname, felt) in ((:zeros,:zero), (:ones,:one))
$fname(a::AbstractArray, T::Type, dims...) = fill!(similar(a,T,dims...), $felt(T))
$fname(a::AbstractArray, T::Type=eltype(a)) = fill!(similar(a,T), $felt(T))

$fname(T::Type, dims::Tuple) = fill!(Array{T}(Dims(dims)), $felt(T))
$fname(T::Type, dims::Tuple) = fill!(Array{T}(convert(Dims, dims)), $felt(T))
$fname(dims::Tuple) = ($fname)(Float64, dims)
$fname(T::Type, dims...) = $fname(T, dims)
$fname(dims...) = $fname(dims)
Expand Down
155 changes: 155 additions & 0 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ mutable struct ErrorException <: Exception
ErrorException(msg::AbstractString) = new(msg)
end

macro _inline_meta()
Expr(:meta, :inline)
end

macro _noinline_meta()
Expr(:meta, :noinline)
end
Expand Down Expand Up @@ -437,4 +441,155 @@ show(@nospecialize a) = show(STDOUT, a)
print(@nospecialize a...) = print(STDOUT, a...)
println(@nospecialize a...) = println(STDOUT, a...)

# constructors for built-in types

import .Intrinsics: eq_int, trunc_int, lshr_int, sub_int, shl_int, bitcast, sext_int, zext_int, and_int

throw_inexacterror(f::Symbol, T::Type, val) = (@_noinline_meta; throw(InexactError(f, T, val)))

function is_top_bit_set(x)
@_inline_meta
eq_int(trunc_int(Int8, lshr_int(x, sub_int(shl_int(sizeof(x), 3), 1))), trunc_int(Int8, 1))
end

function check_top_bit(x)
@_inline_meta
is_top_bit_set(x) && throw_inexacterror(:check_top_bit, typeof(x), x)
x
end

function checked_trunc_sint(::Type{To}, x::From) where {To,From}
@_inline_meta
y = trunc_int(To, x)
back = sext_int(From, y)
eq_int(x, back) || throw_inexacterror(:trunc, To, x)
y
end

function checked_trunc_uint(::Type{To}, x::From) where {To,From}
@_inline_meta
y = trunc_int(To, x)
back = zext_int(From, y)
eq_int(x, back) || throw_inexacterror(:trunc, To, x)
y
end

Int8(x::Int8) = x
Int8(x::Int16) = checked_trunc_sint(Int8, x)
Int8(x::Int32) = checked_trunc_sint(Int8, x)
Int8(x::Int64) = checked_trunc_sint(Int8, x)
Int8(x::Int128) = checked_trunc_sint(Int8, x)
Int8(x::UInt8) = bitcast(Int8, check_top_bit(x))
Int8(x::UInt16) = checked_trunc_sint(Int8, check_top_bit(x))
Int8(x::UInt32) = checked_trunc_sint(Int8, check_top_bit(x))
Int8(x::UInt64) = checked_trunc_sint(Int8, check_top_bit(x))
Int8(x::UInt128) = checked_trunc_sint(Int8, check_top_bit(x))
Int8(x::Bool) = and_int(zext_int(Int8, x), Int8(1))
Int16(x::Int8) = sext_int(Int16, x)
Int16(x::Int16) = x
Int16(x::Int32) = checked_trunc_sint(Int16, x)
Int16(x::Int64) = checked_trunc_sint(Int16, x)
Int16(x::Int128) = checked_trunc_sint(Int16, x)
Int16(x::UInt8) = zext_int(Int16, x)
Int16(x::UInt16) = bitcast(Int16, check_top_bit(x))
Int16(x::UInt32) = checked_trunc_sint(Int16, check_top_bit(x))
Int16(x::UInt64) = checked_trunc_sint(Int16, check_top_bit(x))
Int16(x::UInt128) = checked_trunc_sint(Int16, check_top_bit(x))
Int16(x::Bool) = and_int(zext_int(Int16, x), Int16(1))
Int32(x::Int8) = sext_int(Int32, x)
Int32(x::Int16) = sext_int(Int32, x)
Int32(x::Int32) = x
Int32(x::Int64) = checked_trunc_sint(Int32, x)
Int32(x::Int128) = checked_trunc_sint(Int32, x)
Int32(x::UInt8) = zext_int(Int32, x)
Int32(x::UInt16) = zext_int(Int32, x)
Int32(x::UInt32) = bitcast(Int32, check_top_bit(x))
Int32(x::UInt64) = checked_trunc_sint(Int32, check_top_bit(x))
Int32(x::UInt128) = checked_trunc_sint(Int32, check_top_bit(x))
Int32(x::Bool) = and_int(zext_int(Int32, x), Int32(1))
Int64(x::Int8) = sext_int(Int64, x)
Int64(x::Int16) = sext_int(Int64, x)
Int64(x::Int32) = sext_int(Int64, x)
Int64(x::Int64) = x
Int64(x::Int128) = checked_trunc_sint(Int64, x)
Int64(x::UInt8) = zext_int(Int64, x)
Int64(x::UInt16) = zext_int(Int64, x)
Int64(x::UInt32) = zext_int(Int64, x)
Int64(x::UInt64) = bitcast(Int64, check_top_bit(x))
Int64(x::UInt128) = checked_trunc_sint(Int64, check_top_bit(x))
Int64(x::Bool) = and_int(zext_int(Int64, x), Int64(1))
Int128(x::Int8) = sext_int(Int128, x)
Int128(x::Int16) = sext_int(Int128, x)
Int128(x::Int32) = sext_int(Int128, x)
Int128(x::Int64) = sext_int(Int128, x)
Int128(x::Int128) = x
Int128(x::UInt8) = zext_int(Int128, x)
Int128(x::UInt16) = zext_int(Int128, x)
Int128(x::UInt32) = zext_int(Int128, x)
Int128(x::UInt64) = zext_int(Int128, x)
Int128(x::UInt128) = bitcast(Int128, check_top_bit(x))
Int128(x::Bool) = and_int(zext_int(Int128, x), Int128(1))
UInt8(x::Int8) = bitcast(UInt8, check_top_bit(x))
UInt8(x::Int16) = checked_trunc_uint(UInt8, x)
UInt8(x::Int32) = checked_trunc_uint(UInt8, x)
UInt8(x::Int64) = checked_trunc_uint(UInt8, x)
UInt8(x::Int128) = checked_trunc_uint(UInt8, x)
UInt8(x::UInt8) = x
UInt8(x::UInt16) = checked_trunc_uint(UInt8, x)
UInt8(x::UInt32) = checked_trunc_uint(UInt8, x)
UInt8(x::UInt64) = checked_trunc_uint(UInt8, x)
UInt8(x::UInt128) = checked_trunc_uint(UInt8, x)
UInt8(x::Bool) = and_int(zext_int(UInt8, x), UInt8(1))
UInt16(x::Int8) = sext_int(UInt16, check_top_bit(x))
UInt16(x::Int16) = bitcast(UInt16, check_top_bit(x))
UInt16(x::Int32) = checked_trunc_uint(UInt16, x)
UInt16(x::Int64) = checked_trunc_uint(UInt16, x)
UInt16(x::Int128) = checked_trunc_uint(UInt16, x)
UInt16(x::UInt8) = zext_int(UInt16, x)
UInt16(x::UInt16) = x
UInt16(x::UInt32) = checked_trunc_uint(UInt16, x)
UInt16(x::UInt64) = checked_trunc_uint(UInt16, x)
UInt16(x::UInt128) = checked_trunc_uint(UInt16, x)
UInt16(x::Bool) = and_int(zext_int(UInt16, x), UInt16(1))
UInt32(x::Int8) = sext_int(UInt32, check_top_bit(x))
UInt32(x::Int16) = sext_int(UInt32, check_top_bit(x))
UInt32(x::Int32) = bitcast(UInt32, check_top_bit(x))
UInt32(x::Int64) = checked_trunc_uint(UInt32, x)
UInt32(x::Int128) = checked_trunc_uint(UInt32, x)
UInt32(x::UInt8) = zext_int(UInt32, x)
UInt32(x::UInt16) = zext_int(UInt32, x)
UInt32(x::UInt32) = x
UInt32(x::UInt64) = checked_trunc_uint(UInt32, x)
UInt32(x::UInt128) = checked_trunc_uint(UInt32, x)
UInt32(x::Bool) = and_int(zext_int(UInt32, x), UInt32(1))
UInt64(x::Int8) = sext_int(UInt64, check_top_bit(x))
UInt64(x::Int16) = sext_int(UInt64, check_top_bit(x))
UInt64(x::Int32) = sext_int(UInt64, check_top_bit(x))
UInt64(x::Int64) = bitcast(UInt64, check_top_bit(x))
UInt64(x::Int128) = checked_trunc_uint(UInt64, x)
UInt64(x::UInt8) = zext_int(UInt64, x)
UInt64(x::UInt16) = zext_int(UInt64, x)
UInt64(x::UInt32) = zext_int(UInt64, x)
UInt64(x::UInt64) = x
UInt64(x::UInt128) = checked_trunc_uint(UInt64, x)
UInt64(x::Bool) = and_int(zext_int(UInt64, x), UInt64(1))
UInt128(x::Int8) = sext_int(UInt128, check_top_bit(x))
UInt128(x::Int16) = sext_int(UInt128, check_top_bit(x))
UInt128(x::Int32) = sext_int(UInt128, check_top_bit(x))
UInt128(x::Int64) = sext_int(UInt128, check_top_bit(x))
UInt128(x::Int128) = bitcast(UInt128, check_top_bit(x))
UInt128(x::UInt8) = zext_int(UInt128, x)
UInt128(x::UInt16) = zext_int(UInt128, x)
UInt128(x::UInt32) = zext_int(UInt128, x)
UInt128(x::UInt64) = zext_int(UInt128, x)
UInt128(x::UInt128) = x
UInt128(x::Bool) = and_int(zext_int(UInt128, x), UInt128(1))
Bool(x::Bool) = x

Int(x::Ptr) = bitcast(Int, x)
UInt(x::Ptr) = bitcast(UInt, x)
Ptr{T}(x::Int) where {T} = bitcast(Ptr{T}, x)
Ptr{T}(x::UInt) where {T} = bitcast(Ptr{T}, x)
Ptr{T}(x::Ptr) where {T} = bitcast(Ptr{T}, x)

ccall(:jl_set_istopmod, Void, (Any, Bool), Core, true)
3 changes: 0 additions & 3 deletions base/coreimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ eval(m, x) = Core.eval(m, x)
include(x) = Core.include(Inference, x)
include(mod, x) = Core.include(mod, x)

# conditional to allow redefining Core.Inference after base exists
isdefined(Main, :Base) || ((::Type{T})(arg) where {T} = convert(T, arg)::T)

function return_type end

## Load essential files and libraries
Expand Down
60 changes: 2 additions & 58 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ const BitUnsigned64T = Union{Type{UInt8}, Type{UInt16}, Type{UInt32}, Type{UIn

const BitIntegerType = Union{map(T->Type{T}, BitInteger_types)...}

throw_inexacterror(f::Symbol, ::Type{T}, val) where T =
(@_noinline_meta; throw(InexactError(f, T, val)))
# calls constructors defined in boot.jl
convert(T::BitIntegerType, x::Union{BitInteger, Bool}) = T(x)

## integer comparisons ##

Expand Down Expand Up @@ -400,75 +400,19 @@ trailing_ones(x::Integer) = trailing_zeros(~x)
>>>(x::BitInteger, y::Int) =
select_value(0 <= y, x >>> unsigned(y), x << unsigned(-y))

function is_top_bit_set(x::BitInteger)
@_inline_meta
lshr_int(x, (sizeof(x) << 0x03) - 1) == rem(0x01, typeof(x))
end
function check_top_bit(x::BitInteger)
@_inline_meta
is_top_bit_set(x) && throw_inexacterror(:check_top_bit, typeof(x), x)
x
end

## integer conversions ##

function checked_trunc_sint(::Type{To}, x::From) where {To,From}
@_inline_meta
y = trunc_int(To, x)
back = sext_int(From, y)
x == back || throw_inexacterror(:trunc, To, x)
y
end

function checked_trunc_uint(::Type{To}, x::From) where {To,From}
@_inline_meta
y = trunc_int(To, x)
back = zext_int(From, y)
x == back || throw_inexacterror(:trunc, To, x)
y
end

for to in BitInteger_types, from in (BitInteger_types..., Bool)
if !(to === from)
if to.size < from.size
if to <: Signed
if from <: Unsigned
@eval convert(::Type{$to}, x::($from)) =
checked_trunc_sint($to, check_top_bit(x))
else
@eval convert(::Type{$to}, x::($from)) =
checked_trunc_sint($to, x)
end
else
@eval convert(::Type{$to}, x::($from)) =
checked_trunc_uint($to, x)
end
@eval rem(x::($from), ::Type{$to}) = trunc_int($to, x)
elseif from === Bool
# Bools use i8 storage and may have garbage in their 7 high bits
@eval convert(::Type{$to}, x::($from)) = zext_int($to, x) & $to(1)
@eval rem(x::($from), ::Type{$to}) = convert($to, x)
elseif from.size < to.size
if from <: Signed
if to <: Unsigned
@eval convert(::Type{$to}, x::($from)) =
sext_int($to, check_top_bit(x))
else
@eval convert(::Type{$to}, x::($from)) =
sext_int($to, x)
end
@eval rem(x::($from), ::Type{$to}) = sext_int($to, x)
else
@eval convert(::Type{$to}, x::($from)) = zext_int($to, x)
@eval rem(x::($from), ::Type{$to}) = convert($to, x)
end
else
if !((from <: Signed) === (to <: Signed))
# raise InexactError if x's top bit is set
@eval convert(::Type{$to}, x::($from)) = bitcast($to, check_top_bit(x))
else
@eval convert(::Type{$to}, x::($from)) = bitcast($to, x)
end
@eval rem(x::($from), ::Type{$to}) = bitcast($to, x)
end
end
Expand Down

0 comments on commit 3d74919

Please sign in to comment.