Skip to content

Commit

Permalink
Merge pull request #7 from JuliaDebug/teh/varargs
Browse files Browse the repository at this point in the history
 Fix `getproperty` calls and handle Core.Typeof(Vararg)
  • Loading branch information
timholy authored Feb 10, 2019
2 parents 4f68437 + a98f70c commit 4d11b77
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 4 deletions.
13 changes: 10 additions & 3 deletions src/JuliaInterpreter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,12 @@ function determine_method_for_expr(expr; enter_generated = false)
end
f, allargs = prepare_args(f, allargs, kwargs.args)
# Can happen for thunks created by generated functions
if !isa(f, Core.Builtin) && !isa(f, Core.IntrinsicFunction)
return prepare_call(f, allargs; enter_generated=enter_generated)
if isa(f, Core.Builtin) || isa(f, Core.IntrinsicFunction)
return nothing
elseif f === getproperty && allargs[2] <: Vararg
return nothing # https://github.com/JuliaLang/julia/issues/30995
end
nothing
return prepare_call(f, allargs; enter_generated=enter_generated)
end

function get_source(meth)
Expand Down Expand Up @@ -779,6 +781,8 @@ function extract_args(__module__, ex0)
Expr(:call, NamedTuple{names,typeof(values)}, values),
map(x->isexpr(x, :parameters) ? QuoteNode(x) : x,
filter(x->!isexpr(x, :kw),ex0.args))...)
elseif ex0.head == :.
return Expr(:tuple, :getproperty, ex0.args...)
else
return Expr(:tuple,
map(x->isexpr(x,:parameters) ? QuoteNode(x) : x, ex0.args)...)
Expand Down Expand Up @@ -858,6 +862,9 @@ macro interpret(arg)
theargs = $(esc(args))
stack = JuliaStackFrame[]
frame = JuliaInterpreter.enter_call_expr(Expr(:call,theargs...))
if frame === nothing
return eval(Expr(:call, map(QuoteNode, theargs)...))
end
empty!(framedict) # start fresh each time; kind of like bumping the world age at the REPL prompt
empty!(genframedict)
finish_and_return!(stack, frame)
Expand Down
5 changes: 4 additions & 1 deletion src/interpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -454,11 +454,14 @@ end
finish!(stack, frame, istoplevel::Bool) = finish!(stack, frame, frame.pc[], istoplevel)

"""
ret = finish_and_return!(stack, frame, pc=frame.pc[])
ret = finish_and_return!(stack, frame, istoplevel::Bool=false)
ret = finish_and_return!(stack, frame, pc, istoplevel::Bool)
Run `frame` until execution terminates, and pass back the computed return value.
`stack` controls call evaluation; `stack = Compiled()` evaluates :call expressions
by normal dispatch, whereas a vector of `JuliaStackFrame`s will use recursive interpretation.
Optionally supply the starting `pc`, if you don't want to start at the current location in `frame`.
"""
function finish_and_return!(stack, frame, pc::JuliaProgramCounter=frame.pc[], istoplevel::Bool=false)
pc = finish!(stack, frame, pc, istoplevel)
Expand Down
3 changes: 3 additions & 0 deletions src/localmethtable.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ function get_call_framecode(fargs, parentframe::JuliaFrameCode, idx::Int)
# See TODO in optimize!
return f(fargs[2:end]...), nothing # for code that has a direct call to a builtin
end
if f === getproperty && isa(fargs[2], Type) && fargs[2] <: Vararg # https://github.com/JuliaLang/julia/issues/30995
return getproperty(fargs[2:end]...), nothing
end
# HACK: don't recurse into inference. Inference sometimes returns SSAValue objects and this
# seems to confuse lookup_var.
if f === Base._return_type
Expand Down
5 changes: 5 additions & 0 deletions test/interpret.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ fkw(x::Int8; y=0, z="hello") = y
# issue #3
@test @interpret(joinpath("/home/julia/base", "sysimg.jl")) == "/home/julia/base/sysimg.jl"
@test @interpret(10.0^4) == 10.0^4
# issue #6
@test @interpret(Array.body.body.name) === Array.body.body.name
@test @interpret(Vararg.body.body.name) === Vararg.body.body.name
frame = JuliaInterpreter.prepare_toplevel(Main, :(Vararg.body.body.name))
@test JuliaInterpreter.finish_and_return!(JuliaStackFrame[], frame, true) === Vararg.body.body.name

0 comments on commit 4d11b77

Please sign in to comment.