/usr/share/julia/base/reflection.jl is in julia 0.2.1+dfsg-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | # name and module reflection
module_name(m::Module) = ccall(:jl_module_name, Any, (Any,), m)::Symbol
module_parent(m::Module) = ccall(:jl_module_parent, Any, (Any,), m)::Module
current_module() = ccall(:jl_get_current_module, Any, ())::Module
fullname(m::Module) = m===Main ? () : tuple(fullname(module_parent(m))...,
module_name(m))
names(m::Module, all::Bool, imported::Bool) = ccall(:jl_module_names, Array{Symbol,1}, (Any,Int32,Int32), m, all, imported)
names(m::Module, all::Bool) = names(m, all, false)
names(m::Module) = names(m, false, false)
names(t::DataType) = collect(t.names)
function names(v)
t = typeof(v)
if isa(t,DataType)
return names(t)
else
error("cannot call names() on a non-composite type")
end
end
isconst(s::Symbol) =
ccall(:jl_is_const, Int32, (Ptr{Void}, Any), C_NULL, s) != 0
isconst(m::Module, s::Symbol) =
ccall(:jl_is_const, Int32, (Any, Any), m, s) != 0
# return an integer such that object_id(x)==object_id(y) if is(x,y)
object_id(x::ANY) = ccall(:jl_object_id, Uint, (Any,), x)
# type predicates
const isimmutable = x->(isa(x,Tuple) || !typeof(x).mutable)
isstructtype(t::DataType) = t.names!=() || (t.size==0 && !t.abstract)
isstructtype(x) = false
isbits(t::DataType) = !t.mutable & t.pointerfree & isleaftype(t)
isbits(t::Type) = false
isbits(x) = isbits(typeof(x))
isleaftype(t::ANY) = ccall(:jl_is_leaf_type, Int32, (Any,), t) != 0
typeintersect(a::ANY,b::ANY) = ccall(:jl_type_intersection, Any, (Any,Any), a, b)
typeseq(a::ANY,b::ANY) = a<:b && b<:a
function fieldoffsets(x::DataType)
offsets = Array(Int, length(x.names))
ccall(:jl_field_offsets, Void, (Any, Ptr{Int}), x, offsets)
offsets
end
# subtypes
function _subtypes(m::Module, x::DataType, sts=Set(), visited=Set())
push!(visited, m)
for s in names(m,true)
if isdefined(m,s)
t = eval(m,s)
if isa(t, DataType) && super(t).name == x.name
push!(sts, t)
elseif isa(t, Module) && !in(t, visited)
_subtypes(t, x, sts, visited)
end
end
end
sts
end
subtypes(m::Module, x::DataType) = sort(collect(_subtypes(m, x)), by=string)
subtypes(x::DataType) = subtypes(Main, x)
subtypetree(x::DataType, level=-1) = (level == 0 ? (x, {}) : (x, {subtypetree(y, level-1) for y in subtypes(x)}))
# function reflection
isgeneric(f::ANY) = (isa(f,Function)||isa(f,DataType)) && isa(f.env,MethodTable)
function_name(f::Function) = isgeneric(f) ? f.env.name : (:anonymous)
code_lowered(f::Function,t::Tuple) = map(m->uncompressed_ast(m.func.code), methods(f,t))
methods(f::ANY,t::ANY) = map(m->m[3], _methods(f,t,-1))::Array{Any,1}
_methods(f::ANY,t::ANY,lim) = _methods(f,{(t::Tuple)...},length(t::Tuple),lim,{})
function _methods(f::ANY,t::Array,i,lim::Integer,matching::Array{Any,1})
if i == 0
new = ccall(:jl_matching_methods, Any, (Any,Any,Int32), f, tuple(t...), lim)
if new === false
return false
end
append!(matching, new::Array{Any,1})
else
ti = t[i]
if isa(ti, UnionType)
for ty in (ti::UnionType).types
t[i] = ty
if _methods(f,t,i-1,lim,matching) === false
t[i] = ty
return false
end
end
t[i] = ti
else
return _methods(f,t,i-1,lim,matching)
end
end
matching
end
function methods(f::Function)
if !isgeneric(f)
error("methods: not a generic function")
end
f.env
end
methods(t::DataType) = (_methods(t,Tuple,0); # force constructor creation
t.env)
function length(mt::MethodTable)
n = 0
d = mt.defs
while !is(d,())
n += 1
d = d.next
end
n
end
start(mt::MethodTable) = mt.defs
next(mt::MethodTable, m::Method) = (m,m.next)
done(mt::MethodTable, m::Method) = false
done(mt::MethodTable, i::()) = true
uncompressed_ast(l::LambdaStaticData) =
isa(l.ast,Expr) ? l.ast : ccall(:jl_uncompress_ast, Any, (Any,Any), l, l.ast)
function _dump_function(f, t::ANY, native)
str = ccall(:jl_dump_function, Any, (Any,Any,Bool), f, t, native)::ByteString
if str == ""
error("no method found for the specified argument types")
end
str
end
code_llvm (f::Callable, types::Tuple) = print(_dump_function(f, types, false))
code_native(f::Callable, types::Tuple) = print(_dump_function(f, types, true))
function functionlocs(f::Function, types=(Any...))
locs = Any[]
for m in methods(f, types)
lsd = m.func.code::LambdaStaticData
ln = lsd.line
if ln > 0
push!(locs, (find_source_file(string(lsd.file)), ln))
end
end
if length(locs) == 0
error("could not find function definition")
end
locs
end
functionloc(f::Function, types=(Any...)) = functionlocs(f, types)[1]
function function_module(f::Function, types=(Any...))
m = methods(f, types)
if isempty(m)
error("no matching methods")
end
m[1].func.code.module
end
|