diff options
-rw-r--r-- | erts/emulator/beam/beam_bp.c | 21 | ||||
-rw-r--r-- | erts/emulator/beam/beam_emu.c | 2 | ||||
-rw-r--r-- | erts/emulator/beam/beam_load.c | 21 | ||||
-rw-r--r-- | erts/emulator/beam/beam_load.h | 1 | ||||
-rw-r--r-- | erts/emulator/test/hipe_SUITE.erl | 68 | ||||
-rw-r--r-- | erts/emulator/test/hipe_SUITE_data/trycatch_1.erl | 14 | ||||
-rw-r--r-- | erts/emulator/test/hipe_SUITE_data/trycatch_2.erl | 10 | ||||
-rw-r--r-- | erts/emulator/test/hipe_SUITE_data/trycatch_3.erl | 9 | ||||
-rw-r--r-- | erts/emulator/test/trace_local_SUITE.erl | 1 | ||||
-rw-r--r-- | lib/compiler/src/beam_asm.erl | 2 | ||||
-rw-r--r-- | lib/compiler/src/v3_kernel_pp.erl | 2 | ||||
-rw-r--r-- | lib/compiler/test/compile_SUITE.erl | 21 | ||||
-rw-r--r-- | lib/inets/src/http_server/httpd_util.erl | 4 | ||||
-rw-r--r-- | lib/inets/test/httpd_basic_SUITE.erl | 13 | ||||
-rw-r--r-- | lib/kernel/src/kernel.erl | 2 | ||||
-rw-r--r-- | system/doc/top/templates/index.html.src | 7 |
16 files changed, 167 insertions, 31 deletions
diff --git a/erts/emulator/beam/beam_bp.c b/erts/emulator/beam/beam_bp.c index 92ede09102..b9453c1d9a 100644 --- a/erts/emulator/beam/beam_bp.c +++ b/erts/emulator/beam/beam_bp.c @@ -211,7 +211,7 @@ erts_bp_match_functions(BpFunctions* f, ErtsCodeMFA *mfa, int specified) ci = code_hdr->functions[fi]; ASSERT(ci->op == (BeamInstr) BeamOp(op_i_func_info_IaaI)); - if (erts_is_native_break(ci)) { + if (erts_is_function_native(ci)) { continue; } if (is_nil(ci->mfa.module)) { /* Ignore BIF stub */ @@ -277,7 +277,7 @@ erts_bp_match_export(BpFunctions* f, ErtsCodeMFA *mfa, int specified) continue; } ASSERT(*pc == (BeamInstr) BeamOp(op_i_generic_breakpoint)); - } else if (erts_is_native_break(erts_code_to_codeinfo(ep->addressv[code_ix]))) { + } else if (erts_is_function_native(erts_code_to_codeinfo(ep->addressv[code_ix]))) { continue; } @@ -611,7 +611,7 @@ erts_clear_module_break(Module *modp) { n = (Uint)(UWord) code_hdr->num_functions; for (i = 0; i < n; ++i) { ErtsCodeInfo *ci = code_hdr->functions[i]; - if (erts_is_native_break(ci)) + if (erts_is_function_native(ci)) continue; clear_function_break(ci, ERTS_BPF_ALL); } @@ -620,7 +620,7 @@ erts_clear_module_break(Module *modp) { for (i = 0; i < n; ++i) { ErtsCodeInfo *ci = code_hdr->functions[i]; - if (erts_is_native_break(ci)) + if (erts_is_function_native(ci)) continue; uninstall_breakpoint(ci); consolidate_bp_data(modp, ci, 1); @@ -1212,17 +1212,6 @@ erts_is_mtrace_break(ErtsCodeInfo *ci, Binary **match_spec_ret, return 0; } -int -erts_is_native_break(ErtsCodeInfo *ci) { -#ifdef HIPE - ASSERT(ci->op == (BeamInstr) BeamOp(op_i_func_info_IaaI)); - return erts_codeinfo_to_code(ci)[0] == (BeamInstr) BeamOp(op_hipe_trap_call) - || erts_codeinfo_to_code(ci)[0] == (BeamInstr) BeamOp(op_hipe_trap_call_closure); -#else - return 0; -#endif -} - int erts_is_count_break(ErtsCodeInfo *ci, Uint *count_ret) { @@ -1731,7 +1720,7 @@ check_break(ErtsCodeInfo *ci, Uint break_flags) GenericBp* g = ci->u.gen_bp; ASSERT(ci->op == (BeamInstr) BeamOp(op_i_func_info_IaaI)); - if (erts_is_native_break(ci)) { + if (erts_is_function_native(ci)) { return 0; } if (g) { diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 311bb94242..a90e6a0ba8 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -1814,6 +1814,7 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array) c_p->catches--; make_blank(yb(Arg(0))); if (is_non_value(r(0))) { + c_p->fvalue = NIL; if (x(1) == am_throw) { r(0) = x(2); } else { @@ -1843,6 +1844,7 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array) c_p->catches--; make_blank(yb(Arg(0))); if (is_non_value(r(0))) { + c_p->fvalue = NIL; r(0) = x(1); x(1) = x(2); x(2) = x(3); diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index a0351746b9..23258dbe9c 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -5685,17 +5685,28 @@ erts_is_module_native(BeamCodeHeader* code_hdr) if (code_hdr != NULL) { num_functions = code_hdr->num_functions; for (i=0; i<num_functions; i++) { - BeamInstr* func_info = (BeamInstr *) code_hdr->functions[i]; - Eterm name = (Eterm) func_info[3]; - if (is_atom(name)) { - return func_info[1] != 0; + ErtsCodeInfo* ci = code_hdr->functions[i]; + if (is_atom(ci->mfa.function)) { + return erts_is_function_native(ci); } - else ASSERT(is_nil(name)); /* ignore BIF stubs */ + else ASSERT(is_nil(ci->mfa.function)); /* ignore BIF stubs */ } } return 0; } +int +erts_is_function_native(ErtsCodeInfo *ci) +{ +#ifdef HIPE + ASSERT(ci->op == (BeamInstr) BeamOp(op_i_func_info_IaaI)); + return erts_codeinfo_to_code(ci)[0] == (BeamInstr) BeamOp(op_hipe_trap_call) + || erts_codeinfo_to_code(ci)[0] == (BeamInstr) BeamOp(op_hipe_trap_call_closure); +#else + return 0; +#endif +} + /* * Builds a list of all functions including native addresses. * [{Name,Arity,NativeAddress},...] diff --git a/erts/emulator/beam/beam_load.h b/erts/emulator/beam/beam_load.h index 659b9c303f..b8d8634e28 100644 --- a/erts/emulator/beam/beam_load.h +++ b/erts/emulator/beam/beam_load.h @@ -119,6 +119,7 @@ typedef struct beam_code_header { void erts_release_literal_area(struct ErtsLiteralArea_* literal_area); int erts_is_module_native(BeamCodeHeader* code); +int erts_is_function_native(ErtsCodeInfo*); void erts_beam_bif_load_init(void); struct erl_fun_entry; void erts_purge_state_add_fun(struct erl_fun_entry *fe); diff --git a/erts/emulator/test/hipe_SUITE.erl b/erts/emulator/test/hipe_SUITE.erl index 0b44dd7fb7..5083f01f34 100644 --- a/erts/emulator/test/hipe_SUITE.erl +++ b/erts/emulator/test/hipe_SUITE.erl @@ -22,6 +22,7 @@ -export([all/0 ,t_copy_literals/1 ,t_purge/1 + ,t_trycatch/1 ]). all() -> @@ -29,6 +30,7 @@ all() -> undefined -> {skip, "HiPE is disabled"}; _ -> [t_copy_literals ,t_purge + ,t_trycatch ] end. @@ -118,3 +120,69 @@ t_purge(Config) when is_list(Config) -> call(Pid, Call) -> Pid ! {Call, self()}, receive {Pid, Res} -> Res end. + +t_trycatch(Config) -> + DataDir = proplists:get_value(data_dir, Config), + Files = ["trycatch_1.erl","trycatch_2.erl","trycatch_3.erl"], + Sources0 = [filename:join(DataDir, Src) || Src <- Files], + Sources = trycatch_combine(Sources0), + t_trycatch_1(Sources). + +t_trycatch_1([S|Ss]) -> + io:format("~p", [S]), + compile_and_load(S), + call_trycatch(try_catch), + call_trycatch(plain_catch), + io:nl(), + t_trycatch_1(Ss); +t_trycatch_1([]) -> + ok. + +trycatch_combine([N|Ns]) -> + Combined = trycatch_combine(Ns), + lists:append([[[{N,[]}|C],[{N,[native]},C]] || C <- Combined]); +trycatch_combine([]) -> + [[]]. + +call_trycatch(Func) -> + case do_call_trycatch(error, Func, {error,whatever}) of + {error,whatever,[{trycatch_3,three,1,_}|_]} -> + ok + end, + case do_call_trycatch(error, Func, fc) of + {error,function_clause,[{trycatch_3,three,[fc],_}|_]} -> + ok; + {error,function_clause,[{trycatch_3,three,1,_}|_]} -> + ok + end, + case do_call_trycatch(throw, Func, {throw,{a,b}}) of + {throw,{a,b},[{trycatch_3,three,1,_}|_]} -> + ok + end, + case do_call_trycatch(exit, Func, {exit,{a,b,c}}) of + {exit,{a,b,c},[{trycatch_3,three,1,_}|_]} -> + ok + end, + ok. + +do_call_trycatch(_Class, try_catch, Argument) -> + trycatch_1:one_try_catch(Argument); +do_call_trycatch(error, plain_catch, Argument) -> + {{'EXIT',{Reason,Stk}},Stk} = trycatch_1:one_plain_catch(Argument), + {error,Reason,Stk}; +do_call_trycatch(throw, plain_catch, Argument) -> + {Reason,Stk} = trycatch_1:one_plain_catch(Argument), + {throw,Reason,Stk}; +do_call_trycatch(exit, plain_catch, Argument) -> + {{'EXIT',Reason},Stk} = trycatch_1:one_plain_catch(Argument), + {exit,Reason,Stk}. + +compile_and_load(Sources) -> + _ = [begin + {ok,Mod,Bin} = compile:file(Src, [binary,report|Opts]), + code:purge(Mod), + code:delete(Mod), + code:purge(Mod), + {module,Mod} = code:load_binary(Mod, atom_to_list(Mod), Bin) + end || {Src,Opts} <- Sources], + ok. diff --git a/erts/emulator/test/hipe_SUITE_data/trycatch_1.erl b/erts/emulator/test/hipe_SUITE_data/trycatch_1.erl new file mode 100644 index 0000000000..702b14b5b9 --- /dev/null +++ b/erts/emulator/test/hipe_SUITE_data/trycatch_1.erl @@ -0,0 +1,14 @@ +-module(trycatch_1). +-export([one_try_catch/1,one_plain_catch/1]). + +one_try_catch(Term) -> + try + trycatch_2:two(Term) + catch + C:R -> + Stk = erlang:get_stacktrace(), + {C,R,Stk} + end. + +one_plain_catch(Term) -> + {catch trycatch_2:two(Term),erlang:get_stacktrace()}. diff --git a/erts/emulator/test/hipe_SUITE_data/trycatch_2.erl b/erts/emulator/test/hipe_SUITE_data/trycatch_2.erl new file mode 100644 index 0000000000..ffac420197 --- /dev/null +++ b/erts/emulator/test/hipe_SUITE_data/trycatch_2.erl @@ -0,0 +1,10 @@ +-module(trycatch_2). +-export([two/1]). + +two(Term) -> + Res = trycatch_3:three(Term), + foo(), + Res. + +foo() -> + ok. diff --git a/erts/emulator/test/hipe_SUITE_data/trycatch_3.erl b/erts/emulator/test/hipe_SUITE_data/trycatch_3.erl new file mode 100644 index 0000000000..578fa0e87e --- /dev/null +++ b/erts/emulator/test/hipe_SUITE_data/trycatch_3.erl @@ -0,0 +1,9 @@ +-module(trycatch_3). +-export([three/1]). + +three({error,Term}) -> + error(Term); +three({throw,Term}) -> + throw(Term); +three({exit,Term}) -> + exit(Term). diff --git a/erts/emulator/test/trace_local_SUITE.erl b/erts/emulator/test/trace_local_SUITE.erl index 5b65889f4a..1cbe6201c3 100644 --- a/erts/emulator/test/trace_local_SUITE.erl +++ b/erts/emulator/test/trace_local_SUITE.erl @@ -298,6 +298,7 @@ basic_test() -> setup([call]), NumMatches = erlang:trace_pattern({?MODULE,'_','_'},[],[local]), NumMatches = erlang:trace_pattern({?MODULE,'_','_'},[],[local]), + false = code:is_module_native(?MODULE), % got fooled by local trace erlang:trace_pattern({?MODULE,slave,'_'},false,[local]), [1,1,1,997] = apply_slave(?MODULE,exported_wrap,[1]), ?CT(?MODULE,exported_wrap,[1]), diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl index 6d5071271c..c35efdfc9d 100644 --- a/lib/compiler/src/beam_asm.erl +++ b/lib/compiler/src/beam_asm.erl @@ -194,7 +194,7 @@ build_file(Code, Attr, Dict, NumLabels, NumFuncs, ExtraChunks, SourceFile, Opts, Chunks = case member(slim, Opts) of true -> - [Essentials,AttrChunk,CheckedChunks]; + [Essentials,AttrChunk]; false -> [Essentials,LocChunk,AttrChunk, CompileChunk,CheckedChunks,LineChunk] diff --git a/lib/compiler/src/v3_kernel_pp.erl b/lib/compiler/src/v3_kernel_pp.erl index 187e69a22c..716280a95c 100644 --- a/lib/compiler/src/v3_kernel_pp.erl +++ b/lib/compiler/src/v3_kernel_pp.erl @@ -145,7 +145,7 @@ format_1(#k_local{name=N,arity=A}, Ctxt) -> "local " ++ format_fa_pair({N,A}, Ctxt); format_1(#k_remote{mod=M,name=N,arity=A}, _Ctxt) -> %% This is for our internal translator. - io_lib:format("remote ~s:~s/~w", [format(M),format(N),A]); + io_lib:format("remote ~ts:~ts/~w", [format(M),format(N),A]); format_1(#k_internal{name=N,arity=A}, Ctxt) -> "internal " ++ format_fa_pair({N,A}, Ctxt); format_1(#k_seq{arg=A,body=B}, Ctxt) -> diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index dbf91400ad..1d9c7c44fa 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.erl @@ -31,7 +31,7 @@ file_1/1, forms_2/1, module_mismatch/1, big_file/1, outdir/1, binary/1, makedep/1, cond_and_ifdef/1, listings/1, listings_big/1, other_output/1, kernel_listing/1, encrypted_abstr/1, - strict_record/1, utf8_atoms/1, extra_chunks/1, + strict_record/1, utf8_atoms/1, utf8_functions/1, extra_chunks/1, cover/1, env/1, core/1, core_roundtrip/1, asm/1, optimized_guards/1, sys_pre_attributes/1, dialyzer/1, @@ -49,7 +49,7 @@ all() -> [app_test, appup_test, file_1, forms_2, module_mismatch, big_file, outdir, binary, makedep, cond_and_ifdef, listings, listings_big, other_output, kernel_listing, encrypted_abstr, - strict_record, utf8_atoms, extra_chunks, + strict_record, utf8_atoms, utf8_functions, extra_chunks, cover, env, core, core_roundtrip, asm, optimized_guards, sys_pre_attributes, dialyzer, warnings, pre_load_check, env_compiler_options, custom_debug_info]. @@ -727,6 +727,23 @@ utf8_atoms(Config) when is_list(Config) -> NoUtf8AtomForms = [{attribute,Anno,module,no_utf8_atom}|Forms], error = compile:forms(NoUtf8AtomForms, [binary, r19]). +utf8_functions(Config) when is_list(Config) -> + Anno = erl_anno:new(1), + Atom = binary_to_atom(<<"こんにちは"/utf8>>, utf8), + Forms = [{attribute,Anno,compile,[export_all]}, + {function,Anno,Atom,0,[{clause,Anno,[],[],[{atom,Anno,world}]}]}], + + Utf8FunctionForms = [{attribute,Anno,module,utf8_function}|Forms], + {ok,utf8_function,Utf8FunctionBin} = + compile:forms(Utf8FunctionForms, [binary]), + {ok,{utf8_function,[{atoms,_}]}} = + beam_lib:chunks(Utf8FunctionBin, [atoms]), + code:load_binary(utf8_function, "compile_SUITE", Utf8FunctionBin), + world = utf8_function:Atom(), + + NoUtf8FunctionForms = [{attribute,Anno,module,no_utf8_function}|Forms], + error = compile:forms(NoUtf8FunctionForms, [binary, r19]). + extra_chunks(Config) when is_list(Config) -> Anno = erl_anno:new(1), Forms = [{attribute,Anno,module,extra_chunks}], diff --git a/lib/inets/src/http_server/httpd_util.erl b/lib/inets/src/http_server/httpd_util.erl index a647f04ddc..4f771015a6 100644 --- a/lib/inets/src/http_server/httpd_util.erl +++ b/lib/inets/src/http_server/httpd_util.erl @@ -333,7 +333,9 @@ rfc1123_date(LocalTime) -> {{YYYY,MM,DD},{Hour,Min,Sec}} = case calendar:local_time_to_universal_time_dst(LocalTime) of [Gmt] -> Gmt; - [_,Gmt] -> Gmt + [_,Gmt] -> Gmt; + % Should not happen, but handle the empty list to prevent an error. + [] -> LocalTime end, DayNumber = calendar:day_of_the_week({YYYY,MM,DD}), lists:flatten( diff --git a/lib/inets/test/httpd_basic_SUITE.erl b/lib/inets/test/httpd_basic_SUITE.erl index f413248092..a0a38ca103 100644 --- a/lib/inets/test/httpd_basic_SUITE.erl +++ b/lib/inets/test/httpd_basic_SUITE.erl @@ -42,7 +42,8 @@ all() -> escaped_url_in_error_body, script_timeout, slowdose, - keep_alive_timeout + keep_alive_timeout, + invalid_rfc1123_date ]. groups() -> @@ -383,6 +384,16 @@ slowdose(Config) when is_list(Config) -> end. %%------------------------------------------------------------------------- + +invalid_rfc1123_date() -> + [{doc, "Test that a non-DST date is handled correcly"}]. +invalid_rfc1123_date(Config) when is_list(Config) -> + Rfc1123FormattedDate = "Sun, 26 Mar 2017 01:00:00 GMT", + NonDSTDateTime = {{2017, 03, 26},{1, 0, 0}}, + Rfc1123FormattedDate =:= httpd_util:rfc1123_date(NonDSTDateTime). + + +%%------------------------------------------------------------------------- %% Internal functions %%------------------------------------------------------------------------- diff --git a/lib/kernel/src/kernel.erl b/lib/kernel/src/kernel.erl index 6e5022a405..cba57088ec 100644 --- a/lib/kernel/src/kernel.erl +++ b/lib/kernel/src/kernel.erl @@ -123,7 +123,7 @@ init([]) -> restart => permanent, shutdown => 2000, type => worker, - modeules => [file, file_server, file_io_server, prim_file]}, + modules => [file, file_server, file_io_server, prim_file]}, StdError = #{id => standard_error, start => {standard_error, start_link, []}, diff --git a/system/doc/top/templates/index.html.src b/system/doc/top/templates/index.html.src index b7fff0993d..b987fb4722 100644 --- a/system/doc/top/templates/index.html.src +++ b/system/doc/top/templates/index.html.src @@ -141,10 +141,11 @@ verification, comment support including paragraph filling, skeletons, tags support and more. See the <a href="#tools#/index.html"> Tools</a> application for details. <p> -There are also Erlang plugins for +There are also Erlang plugins for other code editors +<a href="http://github.com/vim-erlang">Vim (vim-erlang)</a> , +<a href="http://atom.io/packages/language-erlang"> Atom </a> , <a href="http://erlide.org/index.html">Eclipse (ErlIDE)</a> and -<a href="http://ignatov.github.io/intellij-erlang/">IntelliJ IDEA</a> -if you prefer a more graphical environment, which are both under active development. +<a href="http://ignatov.github.io/intellij-erlang/">IntelliJ IDEA</a>. <li>When developing with Erlang/OTP you usually test your programs from the interactive shell (see <a href="getting_started/users_guide.html"> Getting Started With Erlang</a>) where you can call individual |