aboutsummaryrefslogtreecommitdiffstats
path: root/lib/debugger/src/dbg_ieval.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2011-03-31 08:33:56 +0200
committerBjörn Gustavsson <[email protected]>2011-08-16 08:58:48 +0200
commite21b58ac5a016d62bba8117ec09105bcac8b94e8 (patch)
tree410f197a7b524d321d738aac2fd46f912fd44efc /lib/debugger/src/dbg_ieval.erl
parentbbb379003d071f19595bb36d3ead79ba0c8474d3 (diff)
downloadotp-e21b58ac5a016d62bba8117ec09105bcac8b94e8.tar.gz
otp-e21b58ac5a016d62bba8117ec09105bcac8b94e8.tar.bz2
otp-e21b58ac5a016d62bba8117ec09105bcac8b94e8.zip
Fix the no_tail option
The 'no_tail' option was broken and would work almost as the 'all' option, because it would use #ieval.top (formerly known as #ieval.last_call) as the basis for its decision to push or not. Fix it by including a boolean in each call/apply instruction indicating whether the call is tail-recursive and pass that boolean to the dbg_istk:push() function.
Diffstat (limited to 'lib/debugger/src/dbg_ieval.erl')
-rw-r--r--lib/debugger/src/dbg_ieval.erl30
1 files changed, 15 insertions, 15 deletions
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl
index d4009cea4d..251c11fdb9 100644
--- a/lib/debugger/src/dbg_ieval.erl
+++ b/lib/debugger/src/dbg_ieval.erl
@@ -413,8 +413,8 @@ eval_mfa(Debugged, M, F, As, #ieval{level=Le}=Ieval0) ->
{exception, {Class, Reason, get_stacktrace()}}
end.
-eval_function(Mod, Name, As, Bs, Called, Ieval0) ->
- Ieval = dbg_istk:push(Bs, Ieval0),
+eval_function(Mod, Name, As, Bs, Called, Ieval0, Lc) ->
+ Ieval = dbg_istk:push(Bs, Ieval0, Lc),
Res = do_eval_function(Mod, Name, As, Bs, Called, Ieval),
dbg_istk:pop(),
Res.
@@ -773,21 +773,21 @@ expr({make_fun,Line,Name,Cs}, Bs, #ieval{module=Module}=Ieval) ->
{value,Fun,Bs};
%% Common test adaptation
-expr({call_remote,0,ct_line,line,As0}, Bs0, Ieval0) ->
+expr({call_remote,0,ct_line,line,As0,Lc}, Bs0, Ieval0) ->
{As,_Bs} = eval_list(As0, Bs0, Ieval0),
- eval_function(ct_line, line, As, Bs0, extern, Ieval0);
+ eval_function(ct_line, line, As, Bs0, extern, Ieval0, Lc);
%% Local function call
-expr({local_call,Line,F,As0}, Bs0, #ieval{module=M} = Ieval0) ->
+expr({local_call,Line,F,As0,Lc}, Bs0, #ieval{module=M} = Ieval0) ->
Ieval = Ieval0#ieval{line=Line},
{As,Bs} = eval_list(As0, Bs0, Ieval),
- eval_function(M, F, As, Bs, local, Ieval);
+ eval_function(M, F, As, Bs, local, Ieval, Lc);
%% Remote function call
-expr({call_remote,Line,M,F,As0}, Bs0, Ieval0) ->
+expr({call_remote,Line,M,F,As0,Lc}, Bs0, Ieval0) ->
Ieval = Ieval0#ieval{line=Line},
{As,Bs} = eval_list(As0, Bs0, Ieval),
- eval_function(M, F, As, Bs, extern, Ieval);
+ eval_function(M, F, As, Bs, extern, Ieval, Lc);
%% Emulated semantics of some BIFs
expr({dbg,Line,self,[]}, Bs, #ieval{level=Le}) ->
@@ -840,7 +840,7 @@ expr({safe_bif,Line,M,F,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
Ieval1 = Ieval0#ieval{line=Line},
{As,Bs} = eval_list(As0, Bs0, Ieval1),
trace(bif, {Le,Line,M,F,As}),
- Ieval2 = dbg_istk:push(Bs0, Ieval1),
+ Ieval2 = dbg_istk:push(Bs0, Ieval1, false),
Ieval = Ieval2#ieval{module=M,function=F,arguments=As},
{_,Value,_} = Res = safe_bif(M, F, As, Bs, Ieval),
trace(return, {Le,Value}),
@@ -852,7 +852,7 @@ expr({bif,Line,M,F,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
Ieval1 = Ieval0#ieval{line=Line},
{As,Bs} = eval_list(As0, Bs0, Ieval1),
trace(bif, {Le,Line,M,F,As}),
- Ieval2 = dbg_istk:push(Bs0, Ieval1),
+ Ieval2 = dbg_istk:push(Bs0, Ieval1, false),
Ieval = Ieval2#ieval{module=M,function=F,arguments=As},
{_,Value,_} = Res = debugged_cmd({apply,M,F,As}, Bs, Ieval),
trace(return, {Le,Value}),
@@ -872,7 +872,7 @@ expr({op,Line,Op,As0}, Bs0, Ieval0) ->
end;
%% apply/2 (fun)
-expr({apply_fun,Line,Fun0,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
+expr({apply_fun,Line,Fun0,As0,Lc}, Bs0, #ieval{level=Le}=Ieval0) ->
Ieval = Ieval0#ieval{line=Line},
FunValue = case expr(Fun0, Bs0, Ieval) of
{value,{dbg_apply,Mx,Fx,Asx},Bsx} ->
@@ -884,19 +884,19 @@ expr({apply_fun,Line,Fun0,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
case FunValue of
{value,Fun,Bs1} when is_function(Fun) ->
{As,Bs} = eval_list(As0, Bs1, Ieval),
- eval_function(undefined, Fun, As, Bs, extern, Ieval);
+ eval_function(undefined, Fun, As, Bs, extern, Ieval, Lc);
{value,{M,F},Bs1} when is_atom(M), is_atom(F) ->
{As,Bs} = eval_list(As0, Bs1, Ieval),
- eval_function(M, F, As, Bs, extern, Ieval);
+ eval_function(M, F, As, Bs, extern, Ieval, Lc);
{value,BadFun,Bs1} ->
exception(error, {badfun,BadFun}, Bs1, Ieval)
end;
%% apply/3
-expr({apply,Line,As0}, Bs0, Ieval0) ->
+expr({apply,Line,As0,Lc}, Bs0, Ieval0) ->
Ieval = Ieval0#ieval{line=Line},
{[M,F,As],Bs} = eval_list(As0, Bs0, Ieval),
- eval_function(M, F, As, Bs, extern, Ieval);
+ eval_function(M, F, As, Bs, extern, Ieval, Lc);
%% Receive statement
expr({'receive',Line,Cs}, Bs0, #ieval{level=Le}=Ieval) ->