diff --git a/Project.toml b/Project.toml index 440063f6..797a91ef 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "JuliaInterpreter" uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" -version = "0.8.7" +version = "0.8.8" [deps] CodeTracking = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" diff --git a/src/builtins.jl b/src/builtins.jl index 7956b8b6..ff85eb8e 100644 --- a/src/builtins.jl +++ b/src/builtins.jl @@ -168,11 +168,11 @@ function maybe_evaluate_builtin(frame, call_expr, expand::Bool) return Some{Any}(applicable(getargs(args, frame)...)) elseif f === fieldtype if nargs == 2 - return Some{Any}(fieldtype(@lookup(frame, args[2]), @lookup(frame, args[3]))) + return Some{Any}(fieldtype(@lookup(frame, args[2]), @lookup(frame, args[3]))::Type) elseif nargs == 3 - return Some{Any}(fieldtype(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]))) + return Some{Any}(fieldtype(@lookup(frame, args[2]), @lookup(frame, args[3]), @lookup(frame, args[4]))::Type) else - return Some{Any}(fieldtype(getargs(args, frame)...)) + return Some{Any}(fieldtype(getargs(args, frame)...)::Type) end elseif f === getfield if nargs == 2 diff --git a/src/optimize.jl b/src/optimize.jl index 2216abac..0890e6fe 100644 --- a/src/optimize.jl +++ b/src/optimize.jl @@ -25,7 +25,7 @@ function extract_inner_call!(stmt::Expr, idx, once::Bool=false) return nothing end -function replace_ssa!(stmt, ssalookup) +function replace_ssa!(@nospecialize(stmt), ssalookup) isa(stmt, Expr) || return nothing for (i, a) in enumerate(stmt.args) if isa(a, SSAValue) @@ -59,7 +59,7 @@ function renumber_ssa!(stmts::Vector{Any}, ssalookup) stmt.args[end] = jumplookup(ssalookup, stmt.args[end]) end elseif is_GotoIfNot(stmt) - cond = stmt.cond + cond = (stmt::Core.GotoIfNot).cond if isa(cond, SSAValue) cond = SSAValue(ssalookup[cond.id]) end @@ -245,7 +245,7 @@ function optimize!(code::CodeInfo, scope) return code, methodtables end -function parametric_type_to_expr(t::Type) +function parametric_type_to_expr(@nospecialize(t::Type)) t isa Core.TypeofBottom && return t t isa UnionAll && (t = t.body) t = t::DataType @@ -253,7 +253,7 @@ function parametric_type_to_expr(t::Type) return Expr(:(...), t.parameters[1]) end if t.hasfreetypevars - params = map(t.parameters) do p + params = map(t.parameters) do @nospecialize(p) isa(p, TypeVar) ? p.name : isa(p, DataType) && p.hasfreetypevars ? parametric_type_to_expr(p) : p end @@ -403,10 +403,18 @@ end function replace_coretypes_list!(list::AbstractVector; rev::Bool) function rep(@nospecialize(x), rev::Bool) - if isa(x, rev ? SSAValue : Core.SSAValue) - return rev ? Core.SSAValue(x.id) : SSAValue(x.id) - elseif isa(x, rev ? SlotNumber : Core.SlotNumber) - return rev ? Core.SlotNumber(x.id) : SlotNumber(x.id) + if rev + if isa(x, SSAValue) + return Core.SSAValue(x.id) + elseif isa(x, SlotNumber) + return Core.SlotNumber(x.id) + end + return x + end + if isa(x, Core.SSAValue) + return SSAValue(x.id) + elseif isa(x, Core.SlotNumber) + return SlotNumber(x.id) end return x end diff --git a/src/precompile.jl b/src/precompile.jl index 671abcc3..9beff6d9 100644 --- a/src/precompile.jl +++ b/src/precompile.jl @@ -17,6 +17,7 @@ function _precompile_() @assert precompile(Tuple{typeof(eval_rhs), Any, Frame, Expr}) @assert precompile(Tuple{typeof(step_expr!), Any, Frame, Any, Bool}) for f in (finish!, finish_and_return!, finish_stack!, next_call!, maybe_next_call!, next_line!) + @assert precompile(Tuple{typeof(f), Any, Frame}) @assert precompile(Tuple{typeof(f), Any, Frame, Bool}) end @assert precompile(Tuple{typeof(through_methoddef_or_done!), Any, Frame}) @@ -51,4 +52,5 @@ function _precompile_() @assert precompile(Tuple{typeof(append_any), Any}) @assert precompile(Tuple{typeof(append_any), Any, Vararg{Any, 100}}) end + @assert precompile(Tuple{typeof(whichtt), Any}) end diff --git a/src/utils.jl b/src/utils.jl index 04a188f2..aa04f381 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -123,11 +123,15 @@ end function scopename(tn::TypeName) modpath = Base.fullname(tn.module) - return Expr(:., _scopename(modpath...), QuoteNode(tn.name)) + if isa(modpath, Tuple{Symbol}) + return Expr(:., modpath[1], QuoteNode(tn.name)) + end + ex = Expr(:., modpath[end-1], QuoteNode(modpath[end])) + for i = length(modpath)-2:-1:1 + ex = Expr(:., modpath[i], ex) + end + return Expr(:., ex, QuoteNode(tn.name)) end -_scopename(sym) = sym -_scopename(parent, child) = Expr(:., parent, QuoteNode(child)) -_scopename(parent, child, rest...) = Expr(:., parent, _scopename(child, rest...)) ## Predicates @@ -146,9 +150,11 @@ end if isdefined(Core, :ReturnNode) is_ReturnNode(@nospecialize(node)) = isa(node, Core.ReturnNode) is_return(@nospecialize(node)) = is_ReturnNode(node) + get_return_node(@nospecialize(node)) = (node::Core.ReturnNode).val else is_ReturnNode(@nospecialize(node)) = false is_return(@nospecialize(node)) = isexpr(node, :return) + get_return_node(@nospecialize(node)) = node.args[1] end is_loc_meta(@nospecialize(expr), @nospecialize(kind)) = isexpr(expr, :meta) && length(expr.args) >= 1 && expr.args[1] === kind diff --git a/test/core.jl b/test/core.jl index a3292a55..a8905690 100644 --- a/test/core.jl +++ b/test/core.jl @@ -23,4 +23,11 @@ using Test if isdefined(Base.IRShow, :show_ir_stmt) # only works on Julia 1.6 and higher @test any(str->occursin(":copyast", str) && occursin("println", str), lines) end + + thunk = Meta.lower(Main, :(return 1+2)) + stmt = thunk.args[1].code[end] # the return + @test JuliaInterpreter.get_return_node(stmt) isa Core.SSAValue + + @test string(JuliaInterpreter.parametric_type_to_expr(Base.Iterators.Stateful{String})) ∈ + ("Base.Iterators.Stateful{String, VS}", "(Base.Iterators).Stateful{String, VS}") end