Skip to content

Commit

Permalink
add builtin sizeof(). fixes #5406
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Aug 29, 2014
1 parent a0459b1 commit 411ec9f
Show file tree
Hide file tree
Showing 13 changed files with 49 additions and 30 deletions.
2 changes: 0 additions & 2 deletions base/bool.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ promote_rule{T<:Number}(::Type{Bool}, ::Type{T}) = T
bool(x::Bool) = x
bool(x::Number) = convert(Bool, x)

sizeof(::Type{Bool}) = 1

typemin(::Type{Bool}) = false
typemax(::Type{Bool}) = true

Expand Down
1 change: 1 addition & 0 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export
apply, fieldtype, getfield, setfield!, yieldto, throw, tuple, is, ===, isdefined,
# arraylen, arrayref, arrayset, arraysize, tuplelen, tupleref, convert_default,
# kwcall,
# sizeof # not exported, to avoid conflicting with Base.sizeof
# type reflection
issubtype, typeof, isa,
# typeassert, apply_type,
Expand Down
4 changes: 0 additions & 4 deletions base/char.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ bswap(x::Char) = char(bswap(uint32(x)))
< (x::Char, y::Char) = uint32(x) < uint32(y)
<=(x::Char, y::Char) = uint32(x) <= uint32(y)

## traits ##

sizeof(::Type{Char}) = 4

## printing & showing characters ##

print(io::IO, c::Char) = (write(io,c); nothing)
Expand Down
2 changes: 0 additions & 2 deletions base/complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ typealias Complex128 Complex{Float64}
typealias Complex64 Complex{Float32}
typealias Complex32 Complex{Float16}

sizeof{T<:Real}(::Type{Complex{T}}) = 2*sizeof(T)

convert{T<:Real}(::Type{Complex{T}}, x::Real) = Complex{T}(x,0)
convert{T<:Real}(::Type{Complex{T}}, z::Complex) = Complex{T}(real(z),imag(z))
convert{T<:Real}(::Type{T}, z::Complex) =
Expand Down
4 changes: 0 additions & 4 deletions base/float.jl
Original file line number Diff line number Diff line change
Expand Up @@ -290,10 +290,6 @@ prevfloat(x::FloatingPoint) = nextfloat(x,-1)
eps() = eps(Float64)
end

sizeof(::Type{Float16}) = 2
sizeof(::Type{Float32}) = 4
sizeof(::Type{Float64}) = 8

## byte order swaps for arbitrary-endianness serialization/deserialization ##
bswap(x::Float32) = box(Float32,bswap_int(unbox(Float32,x)))
bswap(x::Float64) = box(Float64,bswap_int(unbox(Float64,x)))
1 change: 1 addition & 0 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ t_func[is] = (2, 2, cmp_tfunc)
t_func[issubtype] = (2, 2, cmp_tfunc)
t_func[isa] = (2, 2, cmp_tfunc)
t_func[isdefined] = (1, Inf, (args...)->Bool)
t_func[Core.sizeof] = (1, 1, x->Int)
t_func[Union] = (0, Inf,
(args...)->(if all(isType,args)
Type{Union(map(t->t.parameters[1],args)...)}
Expand Down
11 changes: 0 additions & 11 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -479,17 +479,6 @@ typemax(::Type{Uint64}) = 0xffffffffffffffff
typemax(::Type{Int128} ) = $(int128((uint128(-1))>>int32(1)))
end

sizeof(::Type{Int8}) = 1
sizeof(::Type{Uint8}) = 1
sizeof(::Type{Int16}) = 2
sizeof(::Type{Uint16}) = 2
sizeof(::Type{Int32}) = 4
sizeof(::Type{Uint32}) = 4
sizeof(::Type{Int64}) = 8
sizeof(::Type{Uint64}) = 8
sizeof(::Type{Int128}) = 16
sizeof(::Type{Uint128}) = 16

widen(::Type{Int8}) = Int
widen(::Type{Int16}) = Int
widen(::Type{Int32}) = Int64
Expand Down
6 changes: 1 addition & 5 deletions base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,7 @@ oftype{T}(x::T,c) = convert(T,c)

widen{T<:Number}(x::T) = convert(widen(T), x)

sizeof(T::Type) = error(string("size of type ",T," unknown"))
sizeof(T::DataType) = if isleaftype(T) T.size else error("type does not have a native size") end
sizeof(::Type{Symbol}) = error("type does not have a native size")
sizeof{T<:Array}(::Type{T}) = error("type $(T) does not have a native size")
sizeof(x) = sizeof(typeof(x))
sizeof(x) = Core.sizeof(x)

# copying immutable things
copy(x::Union(Symbol,Number,String,Function,Tuple,LambdaStaticData,
Expand Down
1 change: 0 additions & 1 deletion base/pointer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ pointer_from_objref(x::Any) = ccall(:jl_value_ptr, Ptr{Void}, (Any,), x)
integer(x::Ptr) = convert(Uint, x)
unsigned(x::Ptr) = convert(Uint, x)

@eval sizeof{T<:Ptr}(::Type{T}) = $(div(WORD_SIZE,8))
eltype{T}(::Ptr{T}) = T

## limited pointer arithmetic & comparison ##
Expand Down
1 change: 1 addition & 0 deletions src/builtin_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ JL_CALLABLE(jl_f_new_module);
JL_CALLABLE(jl_f_throw);
JL_CALLABLE(jl_f_is);
JL_CALLABLE(jl_f_typeof);
JL_CALLABLE(jl_f_sizeof);
JL_CALLABLE(jl_f_subtype);
JL_CALLABLE(jl_f_isa);
JL_CALLABLE(jl_f_typeassert);
Expand Down
30 changes: 30 additions & 0 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,35 @@ JL_CALLABLE(jl_f_typeof)
return jl_full_type(args[0]);
}

JL_CALLABLE(jl_f_sizeof)
{
JL_NARGS(sizeof, 1, 1);
jl_value_t *x = args[0];
if (jl_is_datatype(x)) {
jl_datatype_t *dx = (jl_datatype_t*)x;
if (dx->name == jl_array_typename || dx == jl_symbol_type)
jl_error("type does not have a canonical binary representation");
if (!(dx->names == jl_null && dx->size > 0)) {
// names===() and size > 0 => bitstype, size always known
if (dx->abstract || !jl_is_leaf_type(x))
jl_error("argument is an abstract type; size is indeterminate");
}
return jl_box_long(jl_datatype_size(x));
}
if (jl_is_array(x)) {
return jl_box_long(jl_array_len(x) * ((jl_array_t*)x)->elsize);
}
if (jl_is_tuple(x)) {
jl_error("tuples do not yet have a canonical binary representation");
}
jl_datatype_t *dt = (jl_datatype_t*)jl_typeof(x);
assert(jl_is_datatype(dt));
assert(!dt->abstract);
if (dt == jl_symbol_type)
jl_error("value does not have a canonical binary representation");
return jl_box_long(jl_datatype_size(dt));
}

JL_CALLABLE(jl_f_subtype)
{
JL_NARGS(subtype, 2, 2);
Expand Down Expand Up @@ -996,6 +1025,7 @@ void jl_init_primitives(void)
{
add_builtin_func("is", jl_f_is);
add_builtin_func("typeof", jl_f_typeof);
add_builtin_func("sizeof", jl_f_sizeof);
add_builtin_func("issubtype", jl_f_subtype);
add_builtin_func("isa", jl_f_isa);
add_builtin_func("typeassert", jl_f_typeassert);
Expand Down
14 changes: 14 additions & 0 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2200,6 +2200,20 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs,
}
}
}
else if (f->fptr == &jl_f_sizeof && nargs == 1) {
jl_datatype_t *sty = (jl_datatype_t*)expr_type(args[1], ctx);
rt1 = (jl_value_t*)sty;
if (jl_is_type_type((jl_value_t*)sty) && !jl_is_typevar(jl_tparam0(sty))) {
sty = (jl_datatype_t*)jl_tparam0(sty);
}
if (jl_is_datatype(sty) && sty != jl_symbol_type && sty->name != jl_array_typename) {
if (jl_is_leaf_type((jl_value_t*)sty) ||
(sty->names == jl_null && sty->size > 0)) {
JL_GC_POP();
return ConstantInt::get(T_size, sty->size);
}
}
}
// TODO: other known builtins
JL_GC_POP();
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,7 @@ void jl_init_serializer(void)
jl_f_invoke, jl_apply_generic,
jl_unprotect_stack, jl_f_task,
jl_f_yieldto, jl_f_ctor_trampoline,
jl_f_new_module,
jl_f_new_module, jl_f_sizeof,
NULL };
i=2;
while (fptrs[i-2] != NULL) {
Expand Down

0 comments on commit 411ec9f

Please sign in to comment.