JuliaTokyo / julia-wakalang

Juliaのわからないことへの質問を雑にする場所
MIT License
25 stars 3 forks source link

Core.Box in v0.5 #19

Open oyamad opened 8 years ago

oyamad commented 8 years ago

Version 0.5 で Core.Box というのが出るのですが,これは何なのでしょう.

function f(a::Array)
    length(a) == 0 && throw(ArgumentError())
    sz = size(a)
    [sz for i in 1:1]
end
julia> @code_warntype f(ones(1, 2, 3))
Variables:
  #self#::#f
  a::Array{Float64,3}
  sz::Core.Box
  #1::##1#2

Body:
  begin 
      sz::Core.Box = $(Expr(:new, :(Core.Box)))
      NewvarNode(:(#1::##1#2))
      unless ((Base.arraylen)(a::Array{Float64,3})::Int64 === 0)::Bool goto 5
      (Main.throw)((Main.ArgumentError)()::Any)::Union{}
      5:  # line 3:
      # meta: location array.jl size 20
      # meta: location array.jl _size 24
      SSAValue(9) = (Base.arraysize)(a::Array{Float64,3},(Base.box)(Int64,(Base.add_int)(0,1)))::Int64
      # meta: location array.jl _size 24
      SSAValue(7) = SSAValue(9)
      SSAValue(8) = (Base.arraysize)(a::Array{Float64,3},(Base.box)(Int64,(Base.add_int)(1,1)))::Int64
      # meta: location array.jl _size 24
      SSAValue(6) = (Core.tuple)(SSAValue(7),SSAValue(8),(Base.arraysize)(a::Array{Float64,3},(Base.box)(Int64,(Base.add_int)(2,1)))::Int64)::Tuple{Int64,Int64,Int64}
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      SSAValue(0) = SSAValue(6)
      (Core.setfield!)(sz::Core.Box,:contents,SSAValue(0))::Tuple{Int64,Int64,Int64} # line 4:
      #1::##1#2 = $(Expr(:new, :(Main.##1#2), :(sz)))
      SSAValue(1) = #1::##1#2
      SSAValue(2) = $(Expr(:new, UnitRange{Int64}, 1, :((Base.select_value)((Base.sle_int)(1,1)::Bool,1,(Base.box)(Int64,(Base.sub_int)(1,1)))::Int64)))
      SSAValue(3) = $(Expr(:new, Base.Generator{UnitRange{Int64},##1#2}, SSAValue(1), SSAValue(2)))
      return $(Expr(:invoke, LambdaInfo for collect(::Base.Generator{UnitRange{Int64},##1#2}), :(Base.collect), SSAValue(3)))
  end::AbstractArray{T,N}

順番を変えるとなぜかでなくなります.

function g(a::Array)
    sz = size(a)
    length(a) == 0 && throw(ArgumentError())
    [sz for i in 1:1]
end
julia> @code_warntype g(ones(1, 2, 3))
Variables:
  #self#::#g
  a::Array{Float64,3}
  sz::Tuple{Int64,Int64,Int64}
  #3::##3#4{Tuple{Int64,Int64,Int64}}

Body:
  begin 
      NewvarNode(:(#3::##3#4{Tuple{Int64,Int64,Int64}}))
      # meta: location array.jl size 20
      # meta: location array.jl _size 24
      SSAValue(8) = (Base.arraysize)(a::Array{Float64,3},(Base.box)(Int64,(Base.add_int)(0,1)))::Int64
      # meta: location array.jl _size 24
      SSAValue(6) = SSAValue(8)
      SSAValue(7) = (Base.arraysize)(a::Array{Float64,3},(Base.box)(Int64,(Base.add_int)(1,1)))::Int64
      # meta: location array.jl _size 24
      SSAValue(5) = (Core.tuple)(SSAValue(6),SSAValue(7),(Base.arraysize)(a::Array{Float64,3},(Base.box)(Int64,(Base.add_int)(2,1)))::Int64)::Tuple{Int64,Int64,Int64}
      # meta: pop location
      # meta: pop location
      # meta: pop location
      # meta: pop location
      sz::Tuple{Int64,Int64,Int64} = SSAValue(5) # line 3:
      unless ((Base.arraylen)(a::Array{Float64,3})::Int64 === 0)::Bool goto 18
      (Main.throw)((Main.ArgumentError)()::Any)::Union{}
      18:  # line 4:
      #3::##3#4{Tuple{Int64,Int64,Int64}} = $(Expr(:new, ##3#4{Tuple{Int64,Int64,Int64}}, :(sz)))
      SSAValue(0) = #3::##3#4{Tuple{Int64,Int64,Int64}}
      SSAValue(1) = $(Expr(:new, UnitRange{Int64}, 1, :((Base.select_value)((Base.sle_int)(1,1)::Bool,1,(Base.box)(Int64,(Base.sub_int)(1,1)))::Int64)))
      SSAValue(2) = $(Expr(:new, Base.Generator{UnitRange{Int64},##3#4{Tuple{Int64,Int64,Int64}}}, SSAValue(0), SSAValue(1)))
      return $(Expr(:invoke, LambdaInfo for collect(::Base.Generator{UnitRange{Int64},##3#4{Tuple{Int64,Int64,Int64}}}), :(Base.collect), SSAValue(2)))
  end::Array{Tuple{Int64,Int64,Int64},1}
bicycle1885 commented 8 years ago

オブジェクトがgarbage collectionで回収されるJuliaのheapにallocateされることを表すものだと思います (http://julia.readthedocs.io/en/latest/manual/embedding/#converting-types)。動作が違うのは私にはバグにしか見えないので、未報告でしたらJuliaのGitHubでissueとして報告するのが良いと思います