summaryrefslogtreecommitdiff
path: root/lib/debugger
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@dashbit.co>2021-12-07 12:34:30 +0100
committerJosé Valim <jose.valim@dashbit.co>2021-12-14 13:25:32 +0100
commit223913f95592cb72f090b892107b8e5e7e4a8f97 (patch)
tree9d94ef43d39350cd3310ed768eb11f8f9aab476b /lib/debugger
parent70b84154f98ecd3c659383de17812ad229169856 (diff)
downloaderlang-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.erl32
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