170
168
%% and then raise the exception.
171
169
%%--------------------------------------------------------------------
172
170
exception(Class, Reason, Bs, Ieval) ->
173
exception(Class, Reason, fix_stacktrace(1), Bs, Ieval).
175
exception(Class, Reason, Stacktrace, Bs, #ieval{module=M, line=Line}) ->
176
ExitInfo = {{M,Line}, Bs, term_to_binary(get(stack))},
171
exception(Class, Reason, Bs, Ieval, false).
173
exception(Class, Reason, Bs, Ieval, false) ->
174
do_exception(Class, Reason,
175
dbg_istk:delayed_stacktrace(no_args, Ieval),
177
exception(Class, Reason, Bs, Ieval, true) ->
178
do_exception(Class, Reason,
179
dbg_istk:delayed_stacktrace(include_args, Ieval),
182
do_exception(Class, Reason, Stacktrace, Bs, #ieval{module=M, line=Line}) ->
183
StackFun = dbg_istk:delayed_to_external(),
185
{{M,Line},Bs,StackFun()}
177
187
put(exit_info, ExitInfo),
178
188
put(stacktrace, Stacktrace),
179
189
erlang:Class(Reason).
181
%%--------------------------------------------------------------------
182
%% in_use_p(Mod, Cm) -> boolean()
184
%% Returns true if Mod is found on the stack, otherwise false.
185
%%--------------------------------------------------------------------
186
in_use_p(Mod, Mod) -> true;
187
in_use_p(Mod, _Cm) ->
188
case get(trace_stack) of
191
lists:any(fun({_,{M,_,_,_}}) when M =:= Mod -> true;
197
191
%%====================================================================
198
192
%% Internal functions
199
193
%%====================================================================
313
311
exit_loop(OrigPid, Reason, Bs, Ieval)
316
%%--Stack emulation---------------------------------------------------
318
%% We keep track of a call stack that is used for
319
%% 1) saving stack frames that can be inspected from an Attached
320
%% Process GUI (using dbg_icmd:get(Meta, stack_frame, {Dir, SP})
321
%% 2) generate an approximation of regular stacktrace -- sent to
322
%% Debugged when it should raise an exception or evaluate a
323
%% function (since it might possible raise an exception)
326
%% Entry = {Le, {MFA, Where, Bs}}
327
%% Le = int() % current call level
328
%% MFA = {M,F,Args} % called function (or fun)
330
%% Where = {M,Li} % from where (module+line) function is called
331
%% Bs = bindings() % current variable bindings
333
%% How to push depends on the "Stack Trace" option (value saved in
334
%% process dictionary item 'trace_stack').
335
%% all - everything is pushed
336
%% no_tail - tail recursive push
337
%% false - nothing is pushed
338
%% Whenever a function returns, the corresponding call frame is popped.
340
push(MFA, Bs, #ieval{level=Le,module=Cm,line=Li,last_call=Lc}) ->
341
Entry = {Le, {MFA, {Cm,Li}, Bs}},
342
case get(trace_stack) of
346
[] -> put(stack, [Entry]);
347
[_Entry|Entries] -> put(stack, [Entry|Entries])
349
_ -> % all | no_tail when Lc =:= false
350
put(stack, [Entry|get(stack)])
354
case get(trace_stack) of
366
case get(trace_stack) of
369
put(stack, pop(Le, get(stack)))
372
pop(Level, [{Le, _}|Stack]) when Level=<Le ->
374
pop(_Level, Stack) ->
378
%% stack_level() -> Le
379
%% stack_level(Stack) -> Le
382
stack_level(get(stack)).
384
stack_level([]) -> 1;
385
stack_level([{Le,_}|_]) -> Le.
387
%% fix_stacktrace(Start) -> Stacktrace
389
%% Stacktrace = [{M,F,Args|Arity} | {Fun,Args}]
390
%% Convert internal stack format to imitation of regular stacktrace.
391
%% Max three elements, no repeated (recursive) calls to the same
392
%% function and convert argument lists to arity for all but topmost
394
%% 'Start' indicates where at get(stack) to start. This somewhat ugly
395
%% solution is because fix_stacktrace has two uses: 1) to imitate
396
%% the stacktrace in the case of an exception in the interpreted code,
397
%% in which case the current call (top of the stack = first of the list)
398
%% should be included, and 2) to send a current stacktrace to Debugged
399
%% when evaluation passes into non-interpreted code, in which case
400
%% the current call should NOT be included (as it is Debugged which
401
%% will make the actual function call).
402
fix_stacktrace(Start) ->
403
case fix_stacktrace2(sublist(get(stack), Start, 3)) of
410
sublist([], _Start, _Length) ->
411
[]; % workaround, lists:sublist([],2,3) fails
412
sublist(L, Start, Length) ->
413
lists:sublist(L, Start, Length).
415
fix_stacktrace2([{_,{{M,F,As1},_,_}}, {_,{{M,F,As2},_,_}}|_])
416
when length(As1) =:= length(As2) ->
418
fix_stacktrace2([{_,{{Fun,As1},_,_}}, {_,{{Fun,As2},_,_}}|_])
419
when length(As1) =:= length(As2) ->
421
fix_stacktrace2([{_,{MFA,_,_}}|Entries]) ->
422
[MFA|fix_stacktrace2(Entries)];
423
fix_stacktrace2([]) ->
426
args2arity([{M,F,As}|Entries]) when is_list(As) ->
427
[{M,F,length(As)}|args2arity(Entries)];
428
args2arity([Entry|Entries]) ->
429
[Entry|args2arity(Entries)];
433
%% bindings(SP) -> Bs
434
%% SP = Le % stack pointer
435
%% Return the bindings for the specified call level
437
bindings(SP, get(stack)).
439
bindings(SP, [{SP,{_MFA,_Wh,Bs}}|_]) ->
441
bindings(SP, [_Entry|Entries]) ->
442
bindings(SP, Entries);
444
erl_eval:new_bindings().
446
%% stack_frame(Dir, SP) -> {Le, Where, Bs} | top | bottom
449
%% Cm = Module | undefined % module
450
%% Li = int() | -1 % line number
452
%% Return stack frame info one step up/down from given stack pointer
453
%% up = to lower call levels
454
%% down = to higher call levels
455
stack_frame(up, SP) ->
456
stack_frame(SP, up, get(stack));
457
stack_frame(down, SP) ->
458
stack_frame(SP, down, lists:reverse(get(stack))).
460
stack_frame(SP, up, [{Le, {_MFA,Where,Bs}}|_]) when Le<SP ->
462
stack_frame(SP, down, [{Le, {_MFA,Where,Bs}}|_]) when Le>SP ->
464
stack_frame(SP, Dir, [{SP, _}|Stack]) ->
466
[{Le, {_MFA,Where,Bs}}|_] ->
468
[] when Dir =:= up ->
470
[] when Dir =:= down ->
473
stack_frame(SP, Dir, [_Entry|Stack]) ->
474
stack_frame(SP, Dir, Stack).
476
%% backtrace(HowMany) -> Backtrace
477
%% HowMany = all | int()
478
%% Backtrace = {Le, MFA}
479
%% Return all/the last N called functions, in reversed call order
480
backtrace(HowMany) ->
481
Stack = case HowMany of
483
N -> lists:sublist(get(stack), N)
485
[{Le, MFA} || {Le,{MFA,_Wh,_Bs}} <- Stack].
487
314
%%--Trace function----------------------------------------------------
489
316
%%--------------------------------------------------------------------
582
411
exit:{Int, Reason} ->
585
{exception, {Class, Reason, get(stacktrace)}}
588
eval_function(Mod, Fun, As0, Bs0, _Called, Ieval) when is_function(Fun);
591
#ieval{level=Le, line=Li, last_call=Lc} = Ieval,
414
{exception, {Class, Reason, get_stacktrace()}}
417
eval_function(Mod, Name, As, Bs, Called, Ieval0, Lc) ->
418
Tail = Lc andalso get(trace_stack) =:= no_tail,
421
Ieval = dbg_istk:push(Bs, Ieval0, Lc),
422
{value,Val,_} = do_eval_function(Mod, Name, As, Bs, Called, Ieval),
424
trace(return, {Ieval#ieval.level,Val}),
427
do_eval_function(Mod, Name, As, Bs, Called, Ieval0)
430
do_eval_function(Mod, Fun, As0, Bs0, _, Ieval0) when is_function(Fun);
433
#ieval{level=Le,line=Li,top=Top} = Ieval0,
592
434
case lambda(Fun, As0) of
593
{Cs,Module,Name,As,Bs} ->
594
push({Module,Name,As}, Bs0, Ieval),
435
{[{clause,Fc,_,_,_}|_]=Cs,Module,Name,As,Bs} ->
436
Ieval = Ieval0#ieval{module=Module,function=Name,
437
arguments=As0,line=Fc},
595
438
trace(call_fun, {Le,Li,Name,As}),
597
fnk_clauses(Cs, Module, Name, As, Bs,
598
Ieval#ieval{level=Le+1}),
600
trace(return, {Le,Val}),
439
fnk_clauses(Cs, As, Bs, Ieval);
603
not_interpreted when Lc -> % We are leaving interpreted code
441
not_interpreted when Top -> % We are leaving interpreted code
604
442
trace(call_fun, {Le,Li,Fun,As0}),
605
443
{value, {dbg_apply,erlang,apply,[Fun,As0]}, Bs0};
606
444
not_interpreted ->
607
push({Fun,As0}, Bs0, Ieval),
608
445
trace(call_fun, {Le,Li,Fun,As0}),
610
debugged_cmd({apply,erlang,apply,[Fun,As0]},Bs0,
611
Ieval#ieval{level=Le+1}),
613
trace(return, {Le,Val}),
446
debugged_cmd({apply,erlang,apply,[Fun,As0]}, Bs0, Ieval0);
616
448
{error,Reason} ->
617
449
%% It's ok not to push anything in this case, the error
618
450
%% reason contains information about the culprit
619
451
%% ({badarity,{{Mod,Name},As}})
620
exception(error, Reason, Bs0, Ieval)
452
exception(error, Reason, Bs0, Ieval0)
623
455
%% Common Test adaptation
624
eval_function(ct_line, line, As, Bs, extern, #ieval{level=Le}=Ieval) ->
456
do_eval_function(ct_line, line, As, Bs, extern, #ieval{level=Le}=Ieval) ->
625
457
debugged_cmd({apply,ct_line,line,As}, Bs, Ieval#ieval{level=Le+1}),
626
458
{value, ignore, Bs};
628
eval_function(Mod, Name, As0, Bs0, Called, Ieval) ->
629
#ieval{level=Le, line=Li, last_call=Lc} = Ieval,
631
push({Mod,Name,As0}, Bs0, Ieval),
460
do_eval_function(Mod, Name, As0, Bs0, Called, Ieval0) ->
461
#ieval{level=Le,line=Li,top=Top} = Ieval0,
632
462
trace(call, {Called, {Le,Li,Mod,Name,As0}}),
463
Ieval = Ieval0#ieval{module=Mod,function=Name,arguments=As0},
634
464
case get_function(Mod, Name, As0, Called) of
635
Cs when is_list(Cs) ->
637
fnk_clauses(Cs, Mod, Name, As0, erl_eval:new_bindings(),
638
Ieval#ieval{level=Le+1}),
640
trace(return, {Le,Val}),
465
[{clause,FcLine,_,_,_}|_]=Cs ->
466
fnk_clauses(Cs, As0, erl_eval:new_bindings(),
467
Ieval#ieval{line=FcLine});
643
not_interpreted when Lc -> % We are leaving interpreted code
469
not_interpreted when Top -> % We are leaving interpreted code
644
470
{value, {dbg_apply,Mod,Name,As0}, Bs0};
645
471
not_interpreted ->
647
debugged_cmd({apply,Mod,Name,As0}, Bs0,
648
Ieval#ieval{level=Le+1}),
650
trace(return, {Le,Val}),
472
debugged_cmd({apply,Mod,Name,As0}, Bs0, Ieval);
654
exception(error, undef, Bs0, Ieval)
475
exception(error, undef, Bs0, Ieval, true)
657
478
lambda(eval_fun, [Cs,As,Bs,{Mod,Name}=F]) ->
753
574
%% Try to find a matching function clause
754
575
%% #ieval.level is set, the other fields must be set in this function
755
fnk_clauses([{clause,Line,Pars,Gs,Body}|Cs], M, F, As, Bs0, Ieval) ->
576
fnk_clauses([{clause,Line,Pars,Gs,Body}|Cs], As, Bs0, Ieval) ->
756
577
case head_match(Pars, As, [], Bs0) of
758
579
Bs = add_bindings(Bs1, Bs0),
759
580
case guard(Gs, Bs) of
762
Ieval#ieval{line=Line,
763
module=M,function=F,arguments=As});
582
seq(Body, Bs, Ieval#ieval{line=Line});
765
fnk_clauses(Cs, M, F, As, Bs0, Ieval)
584
fnk_clauses(Cs, As, Bs0, Ieval)
768
fnk_clauses(Cs, M, F, As, Bs0, Ieval)
587
fnk_clauses(Cs, As, Bs0, Ieval)
770
fnk_clauses([], _M, _F, _As, Bs, Ieval) ->
771
exception(error, function_clause, Bs, Ieval).
589
fnk_clauses([], _As, Bs, Ieval) ->
590
exception(error, function_clause, Bs, Ieval, true).
773
592
seq([E], Bs0, Ieval) ->
774
593
case dbg_icmd:cmd(E, Bs0, Ieval) of
875
693
%% Andalso/orelse
876
694
expr({'andalso',Line,E1,E2}, Bs, Ieval) ->
877
case expr(E1, Bs, Ieval#ieval{line=Line, last_call=false}) of
695
case expr(E1, Bs, Ieval#ieval{line=Line, top=false}) of
878
696
{value,false,_}=Res ->
880
698
{value,true,_} ->
881
expr(E2, Bs, Ieval#ieval{line=Line, last_call=false});
699
expr(E2, Bs, Ieval#ieval{line=Line, top=false});
882
700
{value,Val,Bs} ->
883
701
exception(error, {badarg,Val}, Bs, Ieval)
885
703
expr({'orelse',Line,E1,E2}, Bs, Ieval) ->
886
case expr(E1, Bs, Ieval#ieval{line=Line, last_call=false}) of
704
case expr(E1, Bs, Ieval#ieval{line=Line, top=false}) of
887
705
{value,true,_}=Res ->
889
707
{value,false,_} ->
890
expr(E2, Bs, Ieval#ieval{line=Line, last_call=false});
708
expr(E2, Bs, Ieval#ieval{line=Line, top=false});
892
710
exception(error, {badarg,Val}, Bs, Ieval)
771
%% Construct an external fun.
772
expr({make_ext_fun,Line,MFA0}, Bs0, Ieval0) ->
773
{[M,F,A],Bs} = eval_list(MFA0, Bs0, Ieval0),
774
try erlang:make_fun(M, F, A) of
779
Ieval1 = Ieval0#ieval{line=Line},
780
Ieval2 = dbg_istk:push(Bs0, Ieval1, false),
781
Ieval = Ieval2#ieval{module=erlang,function=make_fun,
782
arguments=[M,F,A],line=-1},
783
exception(error, badarg, Bs, Ieval, true)
953
786
%% Common test adaptation
954
expr({call_remote,0,ct_line,line,As0}, Bs0, Ieval0) ->
787
expr({call_remote,0,ct_line,line,As0,Lc}, Bs0, Ieval0) ->
955
788
{As,_Bs} = eval_list(As0, Bs0, Ieval0),
956
eval_function(ct_line, line, As, Bs0, extern, Ieval0);
789
eval_function(ct_line, line, As, Bs0, extern, Ieval0, Lc);
958
791
%% Local function call
959
expr({local_call,Line,F,As0}, Bs0, #ieval{module=M} = Ieval0) ->
792
expr({local_call,Line,F,As0,Lc}, Bs0, #ieval{module=M} = Ieval0) ->
960
793
Ieval = Ieval0#ieval{line=Line},
961
794
{As,Bs} = eval_list(As0, Bs0, Ieval),
962
eval_function(M, F, As, Bs, local, Ieval);
795
eval_function(M, F, As, Bs, local, Ieval, Lc);
964
797
%% Remote function call
965
expr({call_remote,Line,M,F,As0}, Bs0, Ieval0) ->
798
expr({call_remote,Line,M,F,As0,Lc}, Bs0, Ieval0) ->
966
799
Ieval = Ieval0#ieval{line=Line},
967
800
{As,Bs} = eval_list(As0, Bs0, Ieval),
968
eval_function(M, F, As, Bs, extern, Ieval);
801
eval_function(M, F, As, Bs, extern, Ieval, Lc);
970
803
%% Emulated semantics of some BIFs
971
804
expr({dbg,Line,self,[]}, Bs, #ieval{level=Le}) ->
976
809
expr({dbg,Line,get_stacktrace,[]}, Bs, #ieval{level=Le}) ->
977
810
trace(bif, {Le,Line,erlang,get_stacktrace,[]}),
978
Stacktrace = get(stacktrace),
811
Stacktrace = get_stacktrace(),
979
812
trace(return, {Le,Stacktrace}),
980
813
{value,Stacktrace,Bs};
814
expr({dbg,Line,raise,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
815
%% Since erlang:get_stacktrace/0 is emulated, we will
816
%% need to emulate erlang:raise/3 too so that we can
817
%% capture the stacktrace.
818
Ieval = Ieval0#ieval{line=Line},
819
{[Class,Reason,Stk0]=As,Bs} = eval_list(As0, Bs0, Ieval),
820
trace(bif, {Le,Line,erlang,raise,As}),
822
%% Evaluate raise/3 for error checking and
823
%% truncating of the stacktrace to the correct depth.
824
Error = erlang:raise(Class, Reason, Stk0),
825
trace(return, {Le,Error}),
829
Stk = erlang:get_stacktrace(), %Possibly truncated.
830
StkFun = fun(_) -> Stk end,
831
do_exception(Class, Reason, StkFun, Bs, Ieval)
981
833
expr({dbg,Line,throw,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
982
834
Ieval = Ieval0#ieval{line=Line},
983
835
{[Term],Bs} = eval_list(As0, Bs0, Ieval),
988
840
{[Term],Bs} = eval_list(As0, Bs0, Ieval),
989
841
trace(bif, {Le,Line,erlang,error,[Term]}),
990
842
exception(error, Term, Bs, Ieval);
991
expr({dbg,Line,fault,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
992
Ieval = Ieval0#ieval{line=Line},
993
{[Term],Bs} = eval_list(As0, Bs0, Ieval),
994
trace(bif, {Le,Line,erlang,fault,[Term]}),
995
exception(fault, Term, Bs, Ieval);
996
843
expr({dbg,Line,exit,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
997
844
Ieval = Ieval0#ieval{line=Line},
998
845
{[Term],Bs} = eval_list(As0, Bs0, Ieval),
1002
849
%% Call to "safe" BIF, ie a BIF that can be executed in Meta process
1003
850
expr({safe_bif,Line,M,F,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
1004
Ieval = Ieval0#ieval{line=Line},
1005
{As,Bs} = eval_list(As0, Bs0, Ieval),
851
Ieval1 = Ieval0#ieval{line=Line},
852
{As,Bs} = eval_list(As0, Bs0, Ieval1),
1006
853
trace(bif, {Le,Line,M,F,As}),
1007
push({M,F,As}, Bs0, Ieval),
854
Ieval2 = dbg_istk:push(Bs0, Ieval1, false),
855
Ieval = Ieval2#ieval{module=M,function=F,arguments=As,line=-1},
1008
856
{_,Value,_} = Res = safe_bif(M, F, As, Bs, Ieval),
1009
857
trace(return, {Le,Value}),
1013
861
%% Call to a BIF that must be evaluated in the correct process
1014
862
expr({bif,Line,M,F,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
1015
Ieval = Ieval0#ieval{line=Line},
1016
{As,Bs} = eval_list(As0, Bs0, Ieval),
863
Ieval1 = Ieval0#ieval{line=Line},
864
{As,Bs} = eval_list(As0, Bs0, Ieval1),
1017
865
trace(bif, {Le,Line,M,F,As}),
1018
push({M,F,As}, Bs0, Ieval),
1020
Res = debugged_cmd({apply,M,F,As}, Bs, Ieval#ieval{level=Le+1}),
866
Ieval2 = dbg_istk:push(Bs0, Ieval1, false),
867
Ieval = Ieval2#ieval{module=M,function=F,arguments=As,line=-1},
868
{_,Value,_} = Res = debugged_cmd({apply,M,F,As}, Bs, Ieval),
1021
869
trace(return, {Le,Value}),
1025
%% Call to a BIF that spawns a new process
1026
expr({spawn_bif,Line,M,F,As0}, Bs0, #ieval{level=Le}=Ieval0) ->
1027
Ieval = Ieval0#ieval{line=Line},
1028
{As,Bs} = eval_list(As0, Bs0, Ieval),
1029
trace(bif, {Le,Line,M,F,As}),
1030
push({M,F,As}, Bs0, Ieval),
1031
Res = debugged_cmd({apply,M,F,As}, Bs,Ieval#ieval{level=Le+1}),
1032
trace(return, {Le,Res}),
1036
873
%% Call to an operation
1058
895
case FunValue of
1059
896
{value,Fun,Bs1} when is_function(Fun) ->
1060
897
{As,Bs} = eval_list(As0, Bs1, Ieval),
1061
eval_function(undefined, Fun, As, Bs, extern, Ieval);
898
eval_function(undefined, Fun, As, Bs, extern, Ieval, Lc);
1062
899
{value,{M,F},Bs1} when is_atom(M), is_atom(F) ->
1063
900
{As,Bs} = eval_list(As0, Bs1, Ieval),
1064
eval_function(M, F, As, Bs, extern, Ieval);
901
eval_function(M, F, As, Bs, extern, Ieval, Lc);
1065
902
{value,BadFun,Bs1} ->
1066
903
exception(error, {badfun,BadFun}, Bs1, Ieval)
1070
expr({apply,Line,As0}, Bs0, Ieval0) ->
907
expr({apply,Line,As0,Lc}, Bs0, Ieval0) ->
1071
908
Ieval = Ieval0#ieval{line=Line},
1072
909
{[M,F,As],Bs} = eval_list(As0, Bs0, Ieval),
1073
eval_function(M, F, As, Bs, extern, Ieval);
910
eval_function(M, F, As, Bs, extern, Ieval, Lc);
1075
%% Mod:module_info/0,1
1076
expr({module_info_0,_,Mod}, Bs, _Ieval) ->
1077
{value,[{compile,module_info(Mod,compile)},
1078
{attributes,module_info(Mod,attributes)},
1079
{imports,module_info(Mod,imports)},
1080
{exports,module_info(Mod,exports)}],Bs};
1081
expr({module_info_1,Line,Mod,[As0]}, Bs0, Ieval0) ->
1082
Ieval = Ieval0#ieval{line=Line},
1083
{value,What,Bs} = expr(As0, Bs0, Ieval),
1084
{value,module_info(Mod, What),Bs};
1086
912
%% Receive statement
1087
913
expr({'receive',Line,Cs}, Bs0, #ieval{level=Le}=Ieval) ->
1088
914
trace(receivex, {Le,false}),
1139
970
eval_lc1(E, [{generate,Line,P,L0}|Qs], Bs0, Ieval0) ->
1140
971
Ieval = Ieval0#ieval{line=Line},
1141
{value,L1,Bs1} = expr(L0, Bs0, Ieval#ieval{last_call=false}),
972
{value,L1,Bs1} = expr(L0, Bs0, Ieval#ieval{top=false}),
1142
973
CompFun = fun(NewBs) -> eval_lc1(E, Qs, NewBs, Ieval) end,
1143
974
eval_generate(L1, P, Bs1, CompFun, Ieval);
1144
975
eval_lc1(E, [{b_generate,Line,P,L0}|Qs], Bs0, Ieval0) ->
1145
976
Ieval = Ieval0#ieval{line=Line},
1146
{value,Bin,_} = expr(L0, Bs0, Ieval#ieval{last_call=false}),
977
{value,Bin,_} = expr(L0, Bs0, Ieval#ieval{top=false}),
1147
978
CompFun = fun(NewBs) -> eval_lc1(E, Qs, NewBs, Ieval) end,
1148
979
eval_b_generate(Bin, P, Bs0, CompFun, Ieval);
1149
980
eval_lc1(E, [{guard,Q}|Qs], Bs0, Ieval) ->
1172
1003
eval_bc1(E, [{generate,Line,P,L0}|Qs], Bs0, Ieval0) ->
1173
1004
Ieval = Ieval0#ieval{line=Line},
1174
{value,L1,Bs1} = expr(L0, Bs0, Ieval#ieval{last_call=false}),
1005
{value,L1,Bs1} = expr(L0, Bs0, Ieval#ieval{top=false}),
1175
1006
CompFun = fun(NewBs) -> eval_bc1(E, Qs, NewBs, Ieval) end,
1176
1007
eval_generate(L1, P, Bs1, CompFun, Ieval);
1177
1008
eval_bc1(E, [{b_generate,Line,P,L0}|Qs], Bs0, Ieval0) ->
1178
1009
Ieval = Ieval0#ieval{line=Line},
1179
{value,Bin,_} = expr(L0, Bs0, Ieval#ieval{last_call=false}),
1010
{value,Bin,_} = expr(L0, Bs0, Ieval#ieval{top=false}),
1180
1011
CompFun = fun(NewBs) -> eval_bc1(E, Qs, NewBs, Ieval) end,
1181
1012
eval_b_generate(Bin, P, Bs0, CompFun, Ieval);
1182
1013
eval_bc1(E, [{guard,Q}|Qs], Bs0, Ieval) ->
1222
1053
eval_b_generate(Term, _P, Bs, _CompFun, Ieval) ->
1223
1054
exception(error, {bad_generator,Term}, Bs, Ieval).
1225
module_info(Mod, module) -> Mod;
1226
module_info(_Mod, compile) -> [];
1227
module_info(Mod, attributes) ->
1228
{ok, Attr} = dbg_iserver:call(get(int), {lookup, Mod, attributes}),
1230
module_info(_Mod, imports) -> [];
1231
module_info(Mod, exports) ->
1232
{ok, Exp} = dbg_iserver:call(get(int), {lookup, Mod, exports}),
1234
module_info(_Mod, functions) -> [].
1236
1056
safe_bif(M, F, As, Bs, Ieval) ->
1237
1057
try apply(M, F, As) of
1239
1059
{value,Value,Bs}
1241
1061
Class:Reason ->
1242
exception(Class, Reason, Bs, Ieval)
1062
exception(Class, Reason, Bs, Ieval, true)
1245
1065
eval_send(To, Msg, Bs, Ieval) ->
1408
1228
%% eval_list(ExpressionList, Bindings, Ieval)
1409
1229
%% Evaluate a list of expressions "in parallel" at the same level.
1410
1230
eval_list(Es, Bs, Ieval) ->
1411
eval_list(Es, [], Bs, Bs, Ieval).
1231
eval_list_1(Es, [], Bs, Bs, Ieval#ieval{top=false}).
1413
eval_list([E|Es], Vs, BsOrig, Bs0, Ieval) ->
1414
{value,V,Bs1} = expr(E, BsOrig, Ieval#ieval{last_call=false}),
1415
eval_list(Es, [V|Vs], BsOrig, merge_bindings(Bs1,Bs0,Ieval), Ieval);
1416
eval_list([], Vs, _, Bs, _Ieval) ->
1233
eval_list_1([E|Es], Vs, BsOrig, Bs0, Ieval) ->
1234
{value,V,Bs1} = expr(E, BsOrig, Ieval),
1235
eval_list_1(Es, [V|Vs], BsOrig, merge_bindings(Bs1, Bs0, Ieval), Ieval);
1236
eval_list_1([], Vs, _, Bs, _Ieval) ->
1417
1237
{lists:reverse(Vs,[]),Bs}.
1419
1239
%% if_clauses(Clauses, Bindings, Ieval)