diff options
author | José Valim <jose.valim@dashbit.co> | 2021-12-07 12:34:30 +0100 |
---|---|---|
committer | José Valim <jose.valim@dashbit.co> | 2021-12-14 13:25:32 +0100 |
commit | 223913f95592cb72f090b892107b8e5e7e4a8f97 (patch) | |
tree | 9d94ef43d39350cd3310ed768eb11f8f9aab476b /lib/debugger | |
parent | 70b84154f98ecd3c659383de17812ad229169856 (diff) | |
download | erlang-223913f95592cb72f090b892107b8e5e7e4a8f97.tar.gz |
Remove undocumented {value, Value, Ann} in erl_eval
The shell relies on an implicit contract
with erl_eval where value triplet is allowed.
Unfortunately, to support this, evaluating
anonymous functions would require a look-ahead
traversal to hide any value triplet from
erl_lint and this affected performance negatively.
This patch removes this undocumented contract
and removes the lookahead. To address this,
we took different approaches:
1. v(N) was expanded to a value before evaluated.
Now, we process and validate the arguments,
but communicate with the shell process to get
the value, similar to how history() works
2. References, Ports, and PIDs were converted to
variables and then replaced to values. Now,
we expand `#PID<0.13.0>` into an expression
such as `erlang:list_to_pid("#PID<0.13.0>").`
3. Finally, the prompt evaluation would use values,
but it only had to pass `[{history,integer()}]`,
which can be manually converted to AST
With this change, evaluating anonymous functions in
a loop gets considerably faster, up to 10% in a
macro benchmark.
Diffstat (limited to 'lib/debugger')
-rw-r--r-- | lib/debugger/src/dbg_icmd.erl | 32 |
1 files changed, 9 insertions, 23 deletions
diff --git a/lib/debugger/src/dbg_icmd.erl b/lib/debugger/src/dbg_icmd.erl index 0eb258567f..8d10fdb2c7 100644 --- a/lib/debugger/src/dbg_icmd.erl +++ b/lib/debugger/src/dbg_icmd.erl @@ -382,19 +382,14 @@ eval_restricted({From,_Mod,Cmd,SP}, Bs) -> case catch parse_cmd(Cmd, 1) of {'EXIT', _Reason} -> From ! {self(), {eval_rsp, 'Parse error'}}; - {[{var,_,Var}], XBs} -> + [{var,_,Var}] -> Bs2 = bindings(Bs, SP), Res = case get_binding(Var, Bs2) of {value, Value} -> Value; - unbound -> - case get_binding(Var, XBs) of - {value, _} -> - 'Only possible to inspect variables'; - unbound -> unbound - end + unbound -> unbound end, From ! {self(), {eval_rsp, Res}}; - {_Forms, _XBs} -> + _Forms -> Rsp = 'Only possible to inspect variables', From ! {self(), {eval_rsp, Rsp}} end. @@ -409,18 +404,17 @@ eval_nonrestricted({From, _Mod, Cmd, _SP}, Bs, {'EXIT', _Reason} -> From ! {self(), {eval_rsp, 'Parse error'}}, Bs; - {Forms, XBs} -> + Forms -> mark_running(Line, Le), - Bs1 = merge_bindings(Bs, XBs), - {Res, Bs2} = + {Res, Bs1} = lists:foldl(fun(Expr, {_Res, Bs0}) -> eval_nonrestricted_1(Expr,Bs0,Ieval) end, - {null, Bs1}, + {null, Bs}, Forms), mark_break(M, Line, Le), From ! {self(), {eval_rsp, Res}}, - remove_binding_structs(Bs2, XBs) + Bs1 end. eval_nonrestricted_1({match,_,{var,_,Var},Expr}, Bs, Ieval) -> @@ -445,14 +439,6 @@ eval_expr(Expr, Bs, Ieval) -> dbg_ieval:eval_expr(Expr, Bs, Ieval#ieval{top=false}), {Res,Bs2}. -%% XBs have unique keys. -merge_bindings(Bs1, XBs) -> - Bs1 ++ erl_eval:bindings(XBs). - -remove_binding_structs(Bs1, XBs) -> - lists:foldl(fun({N, _V}, Bs) -> lists:keydelete(N, 1, Bs) - end, Bs1, erl_eval:bindings(XBs)). - mark_running(LineNo, Le) -> put(next_break, running), put(user_eval, [{LineNo, Le} | get(user_eval)]), @@ -467,8 +453,8 @@ mark_break(Cm, LineNo, Le) -> parse_cmd(Cmd, LineNo) -> {ok,Tokens,_} = erl_scan:string(Cmd, LineNo, [text]), - {ok,Forms,Bs} = erl_eval:extended_parse_exprs(Tokens), - {Forms, Bs}. + {ok,Forms} = erl_eval:extended_parse_exprs(Tokens), + Forms. %%==================================================================== %% Library functions for attached process handling |