Skip to content

Spurious binding writability failure on nightly #662

@timholy

Description

@timholy
tim@diva:~/.julia/dev/JuliaInterpreter$ ~/src/juliaw/julia --project --startup=no
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.13.0-DEV.208 (2025-03-12)
 _/ |\__'_|_|_|\__'_|  |  Commit 3e7cf64c21* (4 days old master)
|__/                   |

julia> using JuliaInterpreter

julia> bt = Base.include_string(Main, """
       ex = quote
           assignedvar = 33
           return assignedvar + 1
       end
       frame = Frame(Main, ex)
       try
           JuliaInterpreter.finish_and_return!(frame, true)
       catch
           catch_backtrace()
       end
       """);

julia> stacktrace(bt, true)
68-element Vector{Base.StackTraces.StackFrame}:
 ijl_errorf at rtutils.c:77
 ijl_check_binding_currently_writable at module.c:631
 ijl_get_binding_wr at module.c:656
 jl_f_setglobal at builtins.c:1368
 maybe_evaluate_builtin(frame::Frame, call_expr::Expr, expand::Bool) at builtins.jl:358
 evaluate_call_recurse!(recurse::Any, frame::Frame, call_expr::Expr; enter_generated::Bool) at interpret.jl:253
 evaluate_call_recurse!(recurse::Any, frame::Frame, call_expr::Expr) at interpret.jl:249
 eval_rhs(recurse::Any, frame::Frame, node::Expr) at interpret.jl:387
 step_expr!(recurse::Any, frame::Frame, node::Any, istoplevel::Bool) at interpret.jl:552
 step_expr!(recurse::Any, frame::Frame, istoplevel::Bool) at interpret.jl:612

 _start() at client.jl:571
 _start() at sys.so:?
 jl_apply at julia.h:2341 [inlined]
 true_main at jlapi.c:951
 jl_repl_entrypoint at jlapi.c:1111
 main at loader_exe.c:58
 ip:0x7f079c1f4d8f at libc.so.6:?
 __libc_start_main at libc.so.6:?
 _start at julia:?

julia> b = convert(Core.Binding, GlobalRef(Main, :assignedvar))
Binding Main.assignedvar
   40616:∞ - global variable with type Any
   0:40615 - undefined binding - guard entry

That ijl_check_binding_currently_writable points here.

Modifying that assignment to

global assignedvar
assignedvar = 33

doesn't fix the problem.

Any thoughts, @Keno? Here's the framecode:

julia> frame.framecode.src
CodeInfo(
    @ string:2 within `unknown scope`
1$(Expr(:globaldecl, :(Main.assignedvar)))
│       $(Expr(:latestworld))
│         builtin Core.get_binding_type(Main, :assignedvar)
│       _J1 = 33
│       _J1
│         builtin %J5 isa %J3
└──     goto #3 if not %J6
2 ─     goto #4
3 ─     _J1
└──     _J1 = Base.convert(%J3, %J9)
4 ┄     _J1
│         dynamic Base.setglobal!(Main, :assignedvar, %J11)
│   @ string:3 within `unknown scope`
│       Main.:+
│       Main.assignedvar
│         dynamic (%J13)(%J14, 1)
└──     return %J15
)

Is there something we should be doing to prepare for the assignment differently? Is it possibly a world-age issue? We don't seem to do anything with frame.world, xref #653.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions