diff options
156 files changed, 4566 insertions, 2213 deletions
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index 5ca387ffd8..6bc242c246 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -31,6 +31,331 @@ </header> <p>This document describes the changes made to the ERTS application.</p> +<section><title>Erts 10.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + If you set <c>{linger,{true,0}}</c> on a <c>gen_tcp</c> + listen socket, accept a connection on that socket, and + then close the accepted socket, now the linger zero + setting is transferred to the accepted socket. Before + this correction that information was lost and the close + behaviour on the accepted socket incorrect.</p> + <p> + Own Id: OTP-15370 Aux Id: ERIERL-353 </p> + </item> + <item> + <p> + Sending ancillary data implemented in OTP-15747 + accidentally left behind test code that caused all UDP + sends to fail on Windows. This has now been fixed.</p> + <p> + Own Id: OTP-15422 Aux Id: OTP-15747 </p> + </item> + <item> + <p> + In the socket nif, used invalid flags when if-def'ing for + supported TCP flags: TCP_MAXSEG and TCP_NODELAY (the + support function).</p> + <p> + Own Id: OTP-15827</p> + </item> + <item> + <p> + Fixed memory leaks in experimental socket module.</p> + <p> + Own Id: OTP-15830</p> + </item> + <item> + <p> + <c>re:run()</c> now yields when validating utf8 in a + large subject.</p> + <p> + Own Id: OTP-15836 Aux Id: ERL-876 </p> + </item> + <item> + <p> + Fixed bug in <c>seq_trace:set_token(label,Term)</c> which + could cause VM crash if <c>Term</c> was heap allocated + (not an atom, small integer, local pid or port). Bug + exists since OTP 21.0 when terms other than small + integers were first allowed as labels.</p> + <p> + Own Id: OTP-15849 Aux Id: ERL-700 </p> + </item> + <item> + <p> + Extra <c>-mode</c> flags given to <c>erl</c> are ignored + with a warning.</p> + <p> + Own Id: OTP-15852</p> + </item> + <item> + <p> + Don't loop indefinitely when <c>--enable-pgo</c> is given + to configure, but compiler does not support pgo.</p> + <p> + Own Id: OTP-15853 Aux Id: PR-2254 </p> + </item> + <item> + <p> + Fix <c>seq_trace:print/2</c> not to raise <c>badarg</c> + exception if label is not a small integer. Bug exists + since OTP 21.0.</p> + <p> + Own Id: OTP-15859 Aux Id: ERL-700 </p> + </item> + <item> + <p> + Fixed hipe_flush_icache_range for non-Linux OS on ARM.</p> + <p> + Own Id: OTP-15874 Aux Id: ERL-958, PR-2266 </p> + </item> + <item> + <p>The fix in OTP-15871 was too conservative and disabled + the offending load-time optimization in some cases where + it was safe.</p> + <p> + Own Id: OTP-15881</p> + </item> + <item> + <p> + Upgraded the ERTS internal PCRE library from version 8.42 + to version 8.43. See <url + href="http://pcre.org/original/changelog.txt">http://pcre.org/original/changelog.txt</url> + for information about changes made to PCRE. This library + implements major parts of the <seealso + marker="stdlib:re"><c>re</c></seealso> regular + expressions module.</p> + <p> + Own Id: OTP-15889</p> + </item> + <item> + <p> + Fix race condition when closing a socket while using + <c>{active,N}</c> on Windows.</p> + <p> + Own Id: OTP-15901 Aux Id: ERL-960 PR-2272 </p> + </item> + <item> + <p> + Allow more than one <c>-config</c> command line option to + <c>erl</c> on Windows to conform with other OS.</p> + <p> + Own Id: OTP-15918 Aux Id: ERL-912 </p> + </item> + <item> + <p> + Fix so that ERL_FLAGS environment variable does not + interfere with command line arguments. Before this fix + you could write:</p> + <p> + <c>ERL_FLAGS="10" erl +S</c></p> + <p> + and erlang would start as if <c>+S</c> had been given the + argument <c>10</c>.</p> + <p> + Own Id: OTP-15931</p> + </item> + <item> + <p> + The bug with ID ERL-717 has been fixed. The functions + <c>io:columns()</c> and <c>io:rows()</c> only worked + correctly inside interactive erlang shells before this + fix. These functions returned <c>{error,enotsup}</c> + before this fix even if stdout and stdin were connected + to a terminal when they were invoked from an escript or a + program started with e.g., <c>erl -noshell</c>.</p> + <p> + Own Id: OTP-15959 Aux Id: ERL-717 </p> + </item> + <item> + <p> + Do not use named label in <c>ethread.c</c> inline + assemble. This allows erts to be compiled using gcc 9.1.0 + with LTO enabled.</p> + <p> + Own Id: OTP-15971 Aux Id: PR-2333 </p> + </item> + <item> + <p><c>erlang:fun_to_list/1</c> will now escape the module + and function name when necessary.</p> + <p> + Own Id: OTP-15975 Aux Id: ERL-1009 </p> + </item> + <item> + <p><c>process_info(P,binary)</c> would neglect to look + through heap fragments, potentially missing a few + binaries associated with the process.</p> + <p> + Own Id: OTP-15978 Aux Id: ERIERL-366 </p> + </item> + <item> + <p> + HiPE is now automatically disabled on systems with + non-glibc implementation (for instance musl). This is + because musl does not provide the API's for guaranteeing + that signals are delivered on the correct native stack.</p> + <p> + Own Id: OTP-16037</p> + </item> + <item> + <p> + Fixed bug triggered if a process is killed during call to + <c>persistent_term:put</c> or + <c>persistent_term:erase</c>.</p> + <p> + Own Id: OTP-16041</p> + </item> + <item> + <p> + Add units to all memory slogans in the crash dump + documentation.</p> + <p> + Own Id: OTP-16042</p> + </item> + <item> + <p> + Fix a bug in <c>binary_to_term</c> that would crash the + emulator if a term larger than 16GB was to be decoded.</p> + <p> + Own Id: OTP-16058 Aux Id: PR-2382 </p> + </item> + <item> + <p> + Fixed bug related to an exiting process sending EXIT and + DOWN signals to remote linked/monitored processes. Bugs + exists since OTP 22.0.</p> + <p> + Own Id: OTP-16060</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p><c>erlc</c> can now automatically use a compile server + to avoid starting an Erlang system for each file to be + compiled in a multi-file project. See the documentation + for how to enable it.</p> + <p> + Own Id: OTP-15738 Aux Id: PR-2361 </p> + </item> + <item> + <p> + The possibility to send ancillary data, in particular the + TOS field, has been added to <c>gen_udp:send/4,5</c>.</p> + <p> + Own Id: OTP-15747 Aux Id: ERIERL-294 </p> + </item> + <item> + <p> + The net module has been split into 'net' (kernel) and + prim_net (preloaded).</p> + <p> + Own Id: OTP-15765</p> + </item> + <item> + <p> + Socket counters now works as expected and can also be + extracted with the (new) info function.</p> + <p> + Own Id: OTP-15818</p> + </item> + <item> + <p> + <c>re:run()</c> now avoids validating utf8 in the subject + more than once in the same call. This validation could + previously be performed multiple times when the + <c>global</c> option was passed.</p> + <p> + Own Id: OTP-15831 Aux Id: ERL-876 </p> + </item> + <item> + <p> + The un-documented function <c>erlang:dist_get_stat/1</c> + now returns the real value of what the distribution queue + contains instead of a boolean.</p> + <p> + Own Id: OTP-15905 Aux Id: PR-2270 </p> + </item> + <item> + <p> + ETS <c>ordered_set</c> tables with + <c>write_concurrency</c> enabled has got a performance + issue fixed. There were no limits for the values of + internal statistics counters before this fix. This could + result in that the data structure sometimes reacted + slowly to a change in how many parallel processes were + using it.</p> + <p> + Own Id: OTP-15906</p> + </item> + <item> + <p> + Optimize the reception of large distribution messages.</p> + <p> + Own Id: OTP-15926 Aux Id: PR-2291 </p> + </item> + <item> + <p>Binary matching and functions like + <c>split_binary/2</c> will now create heap binaries when + the results are small enough, reducing the chances of + small sub-binaries keeping large binaries alive.</p> + <p> + Own Id: OTP-15977 Aux Id: ERIERL-366 </p> + </item> + <item> + <p>Fixed rare emulator crash in + <c>instrument:allocations/0-1</c>.</p> + <p> + Own Id: OTP-15983</p> + </item> + <item> + <p> + Ports could pass very small binaries as reference counted + off heap binaries to processes. This could cause an + unnecessary large memory usage and an unnecessary load on + the binary allocator. Small binaries are now always + passed as heap binaries to processes.</p> + <p> + Own Id: OTP-16001 Aux Id: ERIERL-366 </p> + </item> + <item> + <p> + <c>unicode:characters_to_binary()</c> could return very + small binaries as reference counted off heap binaries. + This could cause an unnecessary large memory usage and an + unnecessary load on the binary allocator. Small binaries + are now always returned as heap binaries.</p> + <p> + Own Id: OTP-16002 Aux Id: ERIERL-366 </p> + </item> + <item> + <p> + Improved <c>erl_nif</c> documentation regarding + <c>on_load</c> and Erlang stub/fallback functions.</p> + <p> + Own Id: OTP-16028 Aux Id: PR-2362 </p> + </item> + <item> + <p> + New feature <c>ets:info(_, binary)</c> to get information + about all reference counted binaries kept by a table. + This is the same kind of debug information that + <c>process_info(_, binary)</c> returns for a process.</p> + <p> + Own Id: OTP-16035 Aux Id: ERIERL-366 </p> + </item> + </list> + </section> + +</section> + <section><title>Erts 10.4.4</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -640,6 +965,42 @@ </section> +<section><title>Erts 10.3.5.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p><c>process_info(P,binary)</c> would neglect to look + through heap fragments, potentially missing a few + binaries associated with the process.</p> + <p> + Own Id: OTP-15978 Aux Id: ERIERL-366 </p> + </item> + <item> + <p> + Fixed bug triggered if a process is killed during call to + <c>persistent_term:put</c> or + <c>persistent_term:erase</c>.</p> + <p> + Own Id: OTP-16041</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>Fixed rare emulator crash in + <c>instrument:allocations/0-1</c>.</p> + <p> + Own Id: OTP-15983</p> + </item> + </list> + </section> + +</section> + <section><title>Erts 10.3.5.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/erts/doc/src/socket.xml b/erts/doc/src/socket.xml index 2f7ff2fc07..708f87edf6 100644 --- a/erts/doc/src/socket.xml +++ b/erts/doc/src/socket.xml @@ -327,7 +327,7 @@ </func> <func> - <name name="accept" arity="2" clause_i="1" anchor="accept_async" since="OTP @OTP-15731@"/> + <name name="accept" arity="2" clause_i="1" anchor="accept_async" since="OTP 22.1"/> <fsummary>Accept a connection on a socket.</fsummary> <desc> <p>Accept a connection on a socket.</p> @@ -362,7 +362,7 @@ </func> <func> - <name name="cancel" arity="2" since="OTP @OTP-15731@"/> + <name name="cancel" arity="2" since="OTP 22.1"/> <fsummary>Cancel an asynchronous request.</fsummary> <desc> <p>Cancel an asynchronous request.</p> @@ -403,7 +403,7 @@ </func> <func> - <name name="connect" arity="3" clause_i="1" anchor="connect_async" since="OTP @OTP-15731@"/> + <name name="connect" arity="3" clause_i="1" anchor="connect_async" since="OTP 22.1"/> <fsummary>Initiate a connection on a socket.</fsummary> <desc> <p>This function connects the socket to the address @@ -471,7 +471,7 @@ </func> <func> - <name name="info" arity="1" since="OTP @OTP-15818@"/> + <name name="info" arity="1" since="OTP 22.1"/> <fsummary>Get miscellaneous socket info.</fsummary> <desc> <p>Get miscellaneous info about the socket.</p> @@ -544,8 +544,8 @@ </func> <func> - <name name="recv" arity="3" clause_i="2" anchor="recv_async" since="OTP @OTP-15731@"/> - <name name="recv" arity="4" clause_i="1" since="OTP @OTP-15731@"/> + <name name="recv" arity="3" clause_i="2" anchor="recv_async" since="OTP 22.1"/> + <name name="recv" arity="4" clause_i="1" since="OTP 22.1"/> <fsummary>Receive a message from a socket.</fsummary> <desc> <p>Receive a message from a socket.</p> @@ -596,9 +596,9 @@ </func> <func> - <name name="recvfrom" arity="3" clause_i="1" anchor="recvfrom_async" since="OTP @OTP-15731@"/> - <name name="recvfrom" arity="3" clause_i="4" since="OTP @OTP-15731@"/> - <name name="recvfrom" arity="4" clause_i="1" since="OTP @OTP-15731@"/> + <name name="recvfrom" arity="3" clause_i="1" anchor="recvfrom_async" since="OTP 22.1"/> + <name name="recvfrom" arity="3" clause_i="4" since="OTP 22.1"/> + <name name="recvfrom" arity="4" clause_i="1" since="OTP 22.1"/> <fsummary>Receive a message from a socket.</fsummary> <desc> <p>Receive a message from a socket.</p> @@ -663,9 +663,9 @@ </func> <func> - <name name="recvmsg" arity="2" clause_i="2" anchor="recvmsg_async" since="OTP @OTP-15731@"/> - <name name="recvmsg" arity="3" clause_i="1" since="OTP @OTP-15731@"/> - <name name="recvmsg" arity="5" clause_i="1" since="OTP @OTP-15731@"/> + <name name="recvmsg" arity="2" clause_i="2" anchor="recvmsg_async" since="OTP 22.1"/> + <name name="recvmsg" arity="3" clause_i="1" since="OTP 22.1"/> + <name name="recvmsg" arity="5" clause_i="1" since="OTP 22.1"/> <fsummary>Receive a message from a socket.</fsummary> <desc> <p>Receive a message from a socket.</p> @@ -716,8 +716,8 @@ </func> <func> - <name name="send" arity="3" clause_i="2" anchor="send_async" since="OTP @OTP-15731@"/> - <name name="send" arity="4" clause_i="1" since="OTP @OTP-15731@"/> + <name name="send" arity="3" clause_i="2" anchor="send_async" since="OTP 22.1"/> + <name name="send" arity="4" clause_i="1" since="OTP 22.1"/> <fsummary>Send a message on a socket.</fsummary> <desc> <p>Send a message on a connected socket.</p> @@ -764,8 +764,8 @@ </func> <func> - <name name="sendmsg" arity="3" clause_i="2" anchor="sendmsg_async" since="OTP @OTP-15731@"/> - <name name="sendmsg" arity="4" clause_i="1" since="OTP @OTP-15731@"/> + <name name="sendmsg" arity="3" clause_i="2" anchor="sendmsg_async" since="OTP 22.1"/> + <name name="sendmsg" arity="4" clause_i="1" since="OTP 22.1"/> <fsummary>Send a message on a socket.</fsummary> <desc> <p>Send a message on a socket. The destination, if needed @@ -806,8 +806,8 @@ </func> <func> - <name name="sendto" arity="4" clause_i="2" anchor="sendto_async" since="OTP @OTP-15731@"/> - <name name="sendto" arity="5" clause_i="1" since="OTP @OTP-15731@"/> + <name name="sendto" arity="4" clause_i="2" anchor="sendto_async" since="OTP 22.1"/> + <name name="sendto" arity="5" clause_i="1" since="OTP 22.1"/> <fsummary>Send a message on a socket.</fsummary> <desc> <p>Send a message on a socket, to the specified destination.</p> @@ -953,4 +953,3 @@ server(Addr, Port) -> </code> </section> </erlref> - diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index b2b8acd1b0..70718575e9 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -599,7 +599,6 @@ endif $(TTF_DIR)/erl_bif_table.c \ $(TTF_DIR)/erl_bif_table.h \ -$(TTF_DIR)/erl_bif_wrap.c \ $(TTF_DIR)/erl_bif_list.h \ $(TTF_DIR)/erl_atom_table.c \ $(TTF_DIR)/erl_atom_table.h \ @@ -885,7 +884,6 @@ RUN_OBJS += \ $(OBJDIR)/erl_bif_persistent.o \ $(OBJDIR)/erl_bif_atomics.o $(OBJDIR)/erl_bif_counters.o \ $(OBJDIR)/erl_bif_trace.o $(OBJDIR)/erl_bif_unique.o \ - $(OBJDIR)/erl_bif_wrap.o $(OBJDIR)/erl_nfunc_sched.o \ $(OBJDIR)/erl_guard_bifs.o $(OBJDIR)/erl_dirty_bif_wrap.o \ $(OBJDIR)/erl_trace.o $(OBJDIR)/copy.o \ $(OBJDIR)/utils.o $(OBJDIR)/bif.o \ @@ -920,7 +918,8 @@ RUN_OBJS += \ $(OBJDIR)/erl_ptab.o $(OBJDIR)/erl_map.o \ $(OBJDIR)/erl_msacc.o $(OBJDIR)/erl_lock_flags.o \ $(OBJDIR)/erl_io_queue.o $(OBJDIR)/erl_db_catree.o \ - $(ESOCK_RUN_OBJS) $(OBJDIR)/erl_flxctr.o + $(ESOCK_RUN_OBJS) $(OBJDIR)/erl_flxctr.o \ + $(OBJDIR)/erl_nfunc_sched.o LTTNG_OBJS = $(OBJDIR)/erlang_lttng.o diff --git a/erts/emulator/beam/arith_instrs.tab b/erts/emulator/beam/arith_instrs.tab index f14b376419..29f761286f 100644 --- a/erts/emulator/beam/arith_instrs.tab +++ b/erts/emulator/beam/arith_instrs.tab @@ -447,10 +447,10 @@ shift.execute(Fail, Dst) { reg[1] = Op2; SWAPOUT; if (IsOpCode(I[0], i_bsl_ssjd)) { - I = handle_error(c_p, I, reg, &bif_export[BIF_bsl_2]->info.mfa); + I = handle_error(c_p, I, reg, &bif_trap_export[BIF_bsl_2].info.mfa); } else { ASSERT(IsOpCode(I[0], i_bsr_ssjd)); - I = handle_error(c_p, I, reg, &bif_export[BIF_bsr_2]->info.mfa); + I = handle_error(c_p, I, reg, &bif_trap_export[BIF_bsr_2].info.mfa); } goto post_error_handling; } diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names index 93ba56dccd..4c67c2029f 100644 --- a/erts/emulator/beam/atom.names +++ b/erts/emulator/beam/atom.names @@ -404,6 +404,7 @@ atom min_bin_vheap_size atom minor atom minor_version atom Minus='-' +atom MinusMinus='--' atom module atom module_info atom monitored_by @@ -494,6 +495,7 @@ atom packet atom packet_size atom parallelism atom Plus='+' +atom PlusPlus='++' atom pause atom pending atom pending_driver diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c index 04b2ed64b7..66cc1855e9 100644 --- a/erts/emulator/beam/beam_bif_load.c +++ b/erts/emulator/beam/beam_bif_load.c @@ -166,7 +166,7 @@ BIF_RETTYPE code_make_stub_module_3(BIF_ALIST_3) BIF_ERROR(BIF_P, BADARG); if (!erts_try_seize_code_write_permission(BIF_P)) { - ERTS_BIF_YIELD3(bif_export[BIF_code_make_stub_module_3], + ERTS_BIF_YIELD3(&bif_trap_export[BIF_code_make_stub_module_3], BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3); } @@ -301,7 +301,7 @@ finish_loading_1(BIF_ALIST_1) int do_commit = 0; if (!erts_try_seize_code_write_permission(BIF_P)) { - ERTS_BIF_YIELD1(bif_export[BIF_finish_loading_1], BIF_P, BIF_ARG_1); + ERTS_BIF_YIELD1(&bif_trap_export[BIF_finish_loading_1], BIF_P, BIF_ARG_1); } /* @@ -659,7 +659,7 @@ BIF_RETTYPE delete_module_1(BIF_ALIST_1) } if (!erts_try_seize_code_write_permission(BIF_P)) { - ERTS_BIF_YIELD1(bif_export[BIF_delete_module_1], BIF_P, BIF_ARG_1); + ERTS_BIF_YIELD1(&bif_trap_export[BIF_delete_module_1], BIF_P, BIF_ARG_1); } { @@ -785,7 +785,7 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2) } if (!erts_try_seize_code_write_permission(BIF_P)) { - ERTS_BIF_YIELD2(bif_export[BIF_finish_after_on_load_2], + ERTS_BIF_YIELD2(&bif_trap_export[BIF_finish_after_on_load_2], BIF_P, BIF_ARG_1, BIF_ARG_2); } @@ -835,21 +835,25 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2) */ num_exps = export_list_size(code_ix); for (i = 0; i < num_exps; i++) { - Export *ep = export_list(i,code_ix); - if (ep == NULL || ep->info.mfa.module != BIF_ARG_1) { - continue; - } - if (ep->beam[1] != 0) { - ep->addressv[code_ix] = (void *) ep->beam[1]; - ep->beam[1] = 0; - } else { - if (ep->addressv[code_ix] == ep->beam && - BeamIsOpCode(ep->beam[0], op_apply_bif)) { - continue; - } - ep->addressv[code_ix] = ep->beam; - ep->beam[0] = BeamOpCodeAddr(op_call_error_handler); - } + Export *ep = export_list(i, code_ix); + + if (ep == NULL || ep->info.mfa.module != BIF_ARG_1) { + continue; + } + + DBG_CHECK_EXPORT(ep, code_ix); + + if (ep->trampoline.not_loaded.deferred != 0) { + ep->addressv[code_ix] = (void*)ep->trampoline.not_loaded.deferred; + ep->trampoline.not_loaded.deferred = 0; + } else { + if (ep->bif_number != -1) { + continue; + } + + ep->addressv[code_ix] = ep->trampoline.raw; + ep->trampoline.op = BeamOpCodeAddr(op_call_error_handler); + } } modp->curr.code_hdr->on_load_function_ptr = NULL; @@ -872,10 +876,11 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2) if (ep == NULL || ep->info.mfa.module != BIF_ARG_1) { continue; } - if (BeamIsOpCode(ep->beam[0], op_apply_bif)) { + if (ep->bif_number != -1) { continue; } - ep->beam[1] = 0; + + ep->trampoline.not_loaded.deferred = 0; } } erts_release_code_write_permission(); @@ -1133,7 +1138,7 @@ check_process_code(Process* rp, Module* modp, int *redsp, int fcalls) *redsp += 1; - if (erts_check_nif_export_in_area(rp, mod_start, mod_size)) + if (erts_check_nfunc_in_area(rp, mod_start, mod_size)) return am_true; *redsp += (STACK_START(rp) - rp->stop) / 32; @@ -1672,7 +1677,7 @@ BIF_RETTYPE erts_internal_purge_module_2(BIF_ALIST_2) BIF_ERROR(BIF_P, BADARG); if (!erts_try_seize_code_write_permission(BIF_P)) { - ERTS_BIF_YIELD2(bif_export[BIF_erts_internal_purge_module_2], + ERTS_BIF_YIELD2(&bif_trap_export[BIF_erts_internal_purge_module_2], BIF_P, BIF_ARG_1, BIF_ARG_2); } @@ -1884,25 +1889,28 @@ delete_code(Module* modp) for (i = 0; i < num_exps; i++) { Export *ep = export_list(i, code_ix); if (ep != NULL && (ep->info.mfa.module == module)) { - if (ep->addressv[code_ix] == ep->beam) { - if (BeamIsOpCode(ep->beam[0], op_apply_bif)) { - continue; - } - else if (BeamIsOpCode(ep->beam[0], op_i_generic_breakpoint)) { + if (ep->addressv[code_ix] == ep->trampoline.raw) { + if (BeamIsOpCode(ep->trampoline.op, op_i_generic_breakpoint)) { ERTS_LC_ASSERT(erts_thr_progress_is_blocking()); ASSERT(modp->curr.num_traced_exports > 0); DBG_TRACE_MFA_P(&ep->info.mfa, "export trace cleared, code_ix=%d", code_ix); - erts_clear_export_break(modp, &ep->info); + erts_clear_export_break(modp, ep); } else { - ASSERT(BeamIsOpCode(ep->beam[0], op_call_error_handler) || + ASSERT(BeamIsOpCode(ep->trampoline.op, op_call_error_handler) || !erts_initialized); } } - ep->addressv[code_ix] = ep->beam; - ep->beam[0] = BeamOpCodeAddr(op_call_error_handler); - ep->beam[1] = 0; + + if (ep->bif_number != -1 && ep->is_bif_traced) { + /* Code unloading kills both global and local call tracing. */ + ep->is_bif_traced = 0; + } + + ep->addressv[code_ix] = ep->trampoline.raw; + ep->trampoline.op = BeamOpCodeAddr(op_call_error_handler); + ep->trampoline.not_loaded.deferred = 0; DBG_TRACE_MFA_P(&ep->info.mfa, "export invalidation, code_ix=%d", code_ix); } diff --git a/erts/emulator/beam/beam_bp.c b/erts/emulator/beam/beam_bp.c index 10940072ae..1bb20f6ae3 100644 --- a/erts/emulator/beam/beam_bp.c +++ b/erts/emulator/beam/beam_bp.c @@ -207,9 +207,6 @@ erts_bp_match_functions(BpFunctions* f, ErtsCodeMFA *mfa, int specified) if (erts_is_function_native(ci)) { continue; } - if (is_nil(ci->mfa.module)) { /* Ignore BIF stub */ - continue; - } switch (specified) { case 3: if (ci->mfa.arity != mfa->arity) @@ -244,8 +241,10 @@ erts_bp_match_export(BpFunctions* f, ErtsCodeMFA *mfa, int specified) f->matching = (BpFunction *) Alloc(num_exps*sizeof(BpFunction)); ne = 0; for (i = 0; i < num_exps; i++) { - Export* ep = export_list(i, code_ix); - BeamInstr* pc; + BeamInstr *func; + Export* ep; + + ep = export_list(i, code_ix); switch (specified) { case 3: @@ -263,19 +262,20 @@ erts_bp_match_export(BpFunctions* f, ErtsCodeMFA *mfa, int specified) ASSERT(0); } - pc = ep->beam; - if (ep->addressv[code_ix] == pc) { - if (BeamIsOpCode(*pc, op_apply_bif) || - BeamIsOpCode(*pc, op_call_error_handler)) { - continue; - } - ASSERT(BeamIsOpCode(*pc, op_i_generic_breakpoint)); - } else if (erts_is_function_native(erts_code_to_codeinfo(ep->addressv[code_ix]))) { - continue; - } + func = ep->addressv[code_ix]; + + if (func == ep->trampoline.raw) { + if (BeamIsOpCode(*func, op_call_error_handler)) { + continue; + } + ASSERT(BeamIsOpCode(*func, op_i_generic_breakpoint)); + } else if (erts_is_function_native(erts_code_to_codeinfo(func))) { + continue; + } f->matching[ne].ci = &ep->info; f->matching[ne].mod = erts_get_module(ep->info.mfa.module, code_ix); + ne++; } @@ -305,18 +305,6 @@ erts_consolidate_bp_data(BpFunctions* f, int local) } } -void -erts_consolidate_bif_bp_data(void) -{ - int i; - - ERTS_LC_ASSERT(erts_has_code_write_permission()); - for (i = 0; i < BIF_SIZE; i++) { - Export *ep = bif_export[i]; - consolidate_bp_data(0, &ep->info, 0); - } -} - static void consolidate_bp_data(Module* modp, ErtsCodeInfo *ci, int local) { @@ -495,7 +483,7 @@ erts_set_mtrace_break(BpFunctions* f, Binary *match_spec, ErtsTracer tracer) } void -erts_set_call_trace_bif(ErtsCodeInfo *ci, Binary *match_spec, int local) +erts_set_export_trace(ErtsCodeInfo *ci, Binary *match_spec, int local) { Uint flags = local ? ERTS_BPF_LOCAL_TRACE : ERTS_BPF_GLOBAL_TRACE; @@ -503,25 +491,6 @@ erts_set_call_trace_bif(ErtsCodeInfo *ci, Binary *match_spec, int local) } void -erts_set_mtrace_bif(ErtsCodeInfo *ci, Binary *match_spec, ErtsTracer tracer) -{ - set_function_break(ci, match_spec, ERTS_BPF_META_TRACE, 0, tracer); -} - -void -erts_set_time_trace_bif(ErtsCodeInfo *ci, enum erts_break_op count_op) -{ - set_function_break(ci, NULL, - ERTS_BPF_TIME_TRACE|ERTS_BPF_TIME_TRACE_ACTIVE, - count_op, erts_tracer_nil); -} - -void -erts_clear_time_trace_bif(ErtsCodeInfo *ci) { - clear_function_break(ci, ERTS_BPF_TIME_TRACE|ERTS_BPF_TIME_TRACE_ACTIVE); -} - -void erts_set_debug_break(BpFunctions* f) { set_break(f, NULL, ERTS_BPF_DEBUG, 0, erts_tracer_nil); } @@ -547,7 +516,7 @@ erts_clear_trace_break(BpFunctions* f) } void -erts_clear_call_trace_bif(ErtsCodeInfo *ci, int local) +erts_clear_export_trace(ErtsCodeInfo *ci, int local) { GenericBp* g = ci->u.gen_bp; @@ -566,12 +535,6 @@ erts_clear_mtrace_break(BpFunctions* f) } void -erts_clear_mtrace_bif(ErtsCodeInfo *ci) -{ - clear_function_break(ci, ERTS_BPF_META_TRACE); -} - -void erts_clear_debug_break(BpFunctions* f) { ERTS_LC_ASSERT(erts_thr_progress_is_blocking()); @@ -630,13 +593,22 @@ erts_clear_module_break(Module *modp) { } void -erts_clear_export_break(Module* modp, ErtsCodeInfo *ci) +erts_clear_export_break(Module* modp, Export *ep) { + ErtsCodeInfo *ci; + ERTS_LC_ASSERT(erts_thr_progress_is_blocking()); + ci = &ep->info; + + ASSERT(erts_codeinfo_to_code(ci) == ep->trampoline.raw); + + ASSERT(BeamIsOpCode(ep->trampoline.op, op_i_generic_breakpoint)); + ep->trampoline.op = 0; + clear_function_break(ci, ERTS_BPF_ALL); erts_commit_staged_bp(); - *erts_codeinfo_to_code(ci) = (BeamInstr) 0; + consolidate_bp_data(modp, ci, 0); ASSERT(ci->u.gen_bp == NULL); } @@ -762,229 +734,6 @@ erts_generic_breakpoint(Process* c_p, ErtsCodeInfo *info, Eterm* reg) } } -/* - * Entry point called by the trace wrap functions in erl_bif_wrap.c - * - * The trace wrap functions are themselves called through the export - * entries instead of the original BIF functions. - */ -Eterm -erts_bif_trace(int bif_index, Process* p, Eterm* args, BeamInstr* I) -{ - Eterm result; - Eterm (*func)(Process*, Eterm*, BeamInstr*); - Export* ep = bif_export[bif_index]; - Uint32 flags = 0, flags_meta = 0; - ErtsTracer meta_tracer = erts_tracer_nil; - int applying = (I == ep->beam); /* Yup, the apply code for a bif - * is actually in the - * export entry */ - BeamInstr* cp = (BeamInstr *) p->stop[0]; - GenericBp* g; - GenericBpData* bp = NULL; - Uint bp_flags = 0; - int return_to_trace = 0; - - ERTS_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p); - - g = ep->info.u.gen_bp; - if (g) { - bp = &g->data[erts_active_bp_ix()]; - bp_flags = bp->flags; - } - - /* - * Make continuation pointer OK, it is not during direct BIF calls, - * but it is correct during apply of bif. - */ - if (!applying) { - p->stop[0] = (Eterm) I; - } else { - fixup_cp_before_trace(p, &return_to_trace); - } - if (bp_flags & (ERTS_BPF_LOCAL_TRACE|ERTS_BPF_GLOBAL_TRACE) && - IS_TRACED_FL(p, F_TRACE_CALLS)) { - int local = !!(bp_flags & ERTS_BPF_LOCAL_TRACE); - flags = erts_call_trace(p, &ep->info, bp->local_ms, args, - local, &ERTS_TRACER(p)); - } - if (bp_flags & ERTS_BPF_META_TRACE) { - ErtsTracer old_tracer; - - meta_tracer = erts_atomic_read_nob(&bp->meta_tracer->tracer); - old_tracer = meta_tracer; - flags_meta = erts_call_trace(p, &ep->info, bp->meta_ms, args, - 0, &meta_tracer); - - if (!ERTS_TRACER_COMPARE(old_tracer, meta_tracer)) { - ErtsTracer new_tracer = erts_tracer_nil; - erts_tracer_update(&new_tracer, meta_tracer); - if (old_tracer == erts_atomic_cmpxchg_acqb( - &bp->meta_tracer->tracer, - (erts_aint_t)new_tracer, - (erts_aint_t)old_tracer)) { - ERTS_TRACER_CLEAR(&old_tracer); - } else { - ERTS_TRACER_CLEAR(&new_tracer); - } - } - } - if (bp_flags & ERTS_BPF_TIME_TRACE_ACTIVE && - IS_TRACED_FL(p, F_TRACE_CALLS)) { - erts_trace_time_call(p, &ep->info, bp->time); - } - - /* Restore original continuation pointer (if changed). */ - p->stop[0] = (Eterm) cp; - - func = bif_table[bif_index].f; - - result = func(p, args, I); - - if (erts_nif_export_check_save_trace(p, result, - applying, ep, - flags, - flags_meta, I, - meta_tracer)) { - /* - * erts_bif_trace_epilogue() will be called - * later when appropriate via the NIF export - * scheduling functionality... - */ - return result; - } - - return erts_bif_trace_epilogue(p, result, applying, ep, - flags, flags_meta, I, - meta_tracer); -} - -Eterm -erts_bif_trace_epilogue(Process *p, Eterm result, int applying, - Export* ep, Uint32 flags, - Uint32 flags_meta, BeamInstr* I, - ErtsTracer meta_tracer) -{ - BeamInstr *cp = NULL; - - if (applying && (flags & MATCH_SET_RETURN_TO_TRACE)) { - BeamInstr i_return_trace = beam_return_trace[0]; - BeamInstr i_return_to_trace = beam_return_to_trace[0]; - BeamInstr i_return_time_trace = beam_return_time_trace[0]; - Eterm *cpp; - - /* Maybe advance cp to skip trace stack frames */ - cpp = p->stop; - while (is_not_CP(*cpp)) { - cpp++; - } - for (cp = cp_val(*cpp++); ;) { - if (*cp == i_return_trace) { - /* Skip stack frame variables */ - while (is_not_CP(*cpp)) cpp++; - cpp += 2; /* Skip return_trace parameters */ - } else if (*cp == i_return_time_trace) { - /* Skip stack frame variables */ - while (is_not_CP(*cpp)) cpp++; - cpp += 1; /* Skip return_time_trace parameters */ - } else if (*cp == i_return_to_trace) { - /* A return_to trace message is going to be generated - * by normal means, so we do not have to. - */ - cp = NULL; - break; - } else { - break; - } - cp = cp_val(*cpp++); - } - } - - /* Try to get these in the order - * they usually appear in normal code... */ - if (is_non_value(result)) { - Uint reason = p->freason; - if (reason != TRAP) { - Eterm class; - Eterm value = p->fvalue; - /* Expand error value like in handle_error() */ - if (reason & EXF_ARGLIST) { - Eterm *tp; - ASSERT(is_tuple(value)); - tp = tuple_val(value); - value = tp[1]; - } - if ((reason & EXF_THROWN) && (p->catches <= 0)) { - Eterm *hp = HAlloc(p, 3); - value = TUPLE2(hp, am_nocatch, value); - reason = EXC_ERROR; - } - /* Note: expand_error_value() could theoretically - * allocate on the heap, but not for any error - * returned by a BIF, and it would do no harm, - * just be annoying. - */ - value = expand_error_value(p, reason, value); - class = exception_tag[GET_EXC_CLASS(reason)]; - - if (flags_meta & MATCH_SET_EXCEPTION_TRACE) { - erts_trace_exception(p, &ep->info.mfa, class, value, - &meta_tracer); - } - if (flags & MATCH_SET_EXCEPTION_TRACE) { - erts_trace_exception(p, &ep->info.mfa, class, value, - &ERTS_TRACER(p)); - } - if ((flags & MATCH_SET_RETURN_TO_TRACE) && p->catches > 0) { - /* can only happen if(local)*/ - Eterm *ptr = p->stop; - ASSERT(!applying || is_CP(*ptr)); - ASSERT(ptr <= STACK_START(p)); - /* Search the nearest stack frame for a catch */ - while (++ptr < STACK_START(p)) { - if (is_CP(*ptr)) break; - if (is_catch(*ptr)) { - if (applying) { - /* Apply of BIF, cp is in calling function */ - if (cp) erts_trace_return_to(p, cp); - } else { - /* Direct bif call, I points into - * calling function */ - erts_trace_return_to(p, I); - } - } - } - } - if ((flags_meta|flags) & MATCH_SET_EXCEPTION_TRACE) { - erts_proc_lock(p, ERTS_PROC_LOCKS_ALL_MINOR); - ERTS_TRACE_FLAGS(p) |= F_EXCEPTION_TRACE; - erts_proc_unlock(p, ERTS_PROC_LOCKS_ALL_MINOR); - } - } - } else { - if (flags_meta & MATCH_SET_RX_TRACE) { - erts_trace_return(p, &ep->info.mfa, result, &meta_tracer); - } - /* MATCH_SET_RETURN_TO_TRACE cannot occur if(meta) */ - if (flags & MATCH_SET_RX_TRACE) { - erts_trace_return(p, &ep->info.mfa, result, &ERTS_TRACER(p)); - } - if (flags & MATCH_SET_RETURN_TO_TRACE && - IS_TRACED_FL(p, F_TRACE_RETURN_TO)) { - /* can only happen if(local)*/ - if (applying) { - /* Apply of BIF, cp is in calling function */ - if (cp) erts_trace_return_to(p, cp); - } else { - /* Direct bif call, I points into calling function */ - erts_trace_return_to(p, I); - } - } - } - ERTS_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p); - return result; -} - static ErtsTracer do_call_trace(Process* c_p, ErtsCodeInfo* info, Eterm* reg, int local, Binary* ms, ErtsTracer tracer) diff --git a/erts/emulator/beam/beam_bp.h b/erts/emulator/beam/beam_bp.h index a64765822b..54e84e7e4f 100644 --- a/erts/emulator/beam/beam_bp.h +++ b/erts/emulator/beam/beam_bp.h @@ -119,20 +119,16 @@ void erts_bp_free_matched_functions(BpFunctions* f); void erts_install_breakpoints(BpFunctions* f); void erts_uninstall_breakpoints(BpFunctions* f); void erts_consolidate_bp_data(BpFunctions* f, int local); -void erts_consolidate_bif_bp_data(void); void erts_set_trace_break(BpFunctions *f, Binary *match_spec); void erts_clear_trace_break(BpFunctions *f); -void erts_set_call_trace_bif(ErtsCodeInfo *ci, Binary *match_spec, int local); -void erts_clear_call_trace_bif(ErtsCodeInfo *ci, int local); +void erts_set_export_trace(ErtsCodeInfo *ci, Binary *match_spec, int local); +void erts_clear_export_trace(ErtsCodeInfo *ci, int local); void erts_set_mtrace_break(BpFunctions *f, Binary *match_spec, ErtsTracer tracer); void erts_clear_mtrace_break(BpFunctions *f); -void erts_set_mtrace_bif(ErtsCodeInfo *ci, Binary *match_spec, - ErtsTracer tracer); -void erts_clear_mtrace_bif(ErtsCodeInfo *ci); void erts_set_debug_break(BpFunctions *f); void erts_clear_debug_break(BpFunctions *f); @@ -142,7 +138,7 @@ void erts_clear_count_break(BpFunctions *f); void erts_clear_all_breaks(BpFunctions* f); int erts_clear_module_break(Module *modp); -void erts_clear_export_break(Module *modp, ErtsCodeInfo* ci); +void erts_clear_export_break(Module *modp, Export *ep); BeamInstr erts_generic_breakpoint(Process* c_p, ErtsCodeInfo *ci, Eterm* reg); BeamInstr erts_trace_break(Process *p, ErtsCodeInfo *ci, Eterm *args, @@ -151,8 +147,6 @@ BeamInstr erts_trace_break(Process *p, ErtsCodeInfo *ci, Eterm *args, int erts_is_trace_break(ErtsCodeInfo *ci, Binary **match_spec_ret, int local); int erts_is_mtrace_break(ErtsCodeInfo *ci, Binary **match_spec_ret, ErtsTracer *tracer_ret); -int erts_is_mtrace_bif(ErtsCodeInfo *ci, Binary **match_spec_ret, - ErtsTracer *tracer_ret); int erts_is_native_break(ErtsCodeInfo *ci); int erts_is_count_break(ErtsCodeInfo *ci, Uint *count_ret); int erts_is_time_break(Process *p, ErtsCodeInfo *ci, Eterm *call_time); @@ -163,10 +157,6 @@ void erts_schedule_time_break(Process *p, Uint out); void erts_set_time_break(BpFunctions *f, enum erts_break_op); void erts_clear_time_break(BpFunctions *f); -int erts_is_time_trace_bif(Process *p, ErtsCodeInfo *ci, Eterm *call_time); -void erts_set_time_trace_bif(ErtsCodeInfo *ci, enum erts_break_op); -void erts_clear_time_trace_bif(ErtsCodeInfo *ci); - ErtsCodeInfo *erts_find_local_func(ErtsCodeMFA *mfa); #if ERTS_GLB_INLINE_INCL_FUNC_DEF diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c index 4d52435139..255ce48306 100644 --- a/erts/emulator/beam/beam_debug.c +++ b/erts/emulator/beam/beam_debug.c @@ -158,7 +158,7 @@ erts_debug_breakpoint_2(BIF_ALIST_2) } if (!erts_try_seize_code_write_permission(BIF_P)) { - ERTS_BIF_YIELD2(bif_export[BIF_erts_debug_breakpoint_2], + ERTS_BIF_YIELD2(&bif_trap_export[BIF_erts_debug_breakpoint_2], BIF_P, BIF_ARG_1, BIF_ARG_2); } erts_proc_unlock(p, ERTS_PROC_LOCK_MAIN); @@ -332,7 +332,7 @@ erts_debug_disassemble_1(BIF_ALIST_1) "unknown " HEXF "\n", instr); code_ptr++; } - if (i == op_call_nif) { + if (i == op_call_nif_WWW) { /* * The rest of the code will not be executed. Don't disassemble any * more code in this function. diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 9f8b56a5d5..a7d28f705d 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -111,10 +111,9 @@ do { \ #define CHECK_ALIGNED(Dst) ASSERT((((Uint)&Dst) & (sizeof(Uint)-1)) == 0) -#define GET_BIF_MODULE(p) (p->info.mfa.module) -#define GET_BIF_FUNCTION(p) (p->info.mfa.function) -#define GET_BIF_ARITY(p) (p->info.mfa.arity) -#define GET_BIF_ADDRESS(p) ((BifFunction) (p->beam[1])) +#define GET_EXPORT_MODULE(p) ((p)->info.mfa.module) +#define GET_EXPORT_FUNCTION(p) ((p)->info.mfa.function) +#define GET_EXPORT_ARITY(p) ((p)->info.mfa.arity) #define TermWords(t) (((t) / (sizeof(BeamInstr)/sizeof(Eterm))) + !!((t) % (sizeof(BeamInstr)/sizeof(Eterm)))) @@ -250,72 +249,6 @@ void** beam_ops; #define Q(N) (N*sizeof(Eterm *)) #define l(N) (freg[N].fd) -/* - * Check that we haven't used the reductions and jump to function pointed to by - * the I register. If we are out of reductions, do a context switch. - */ - -#define DispatchMacro() \ - do { \ - BeamInstr dis_next; \ - dis_next = *I; \ - CHECK_ARGS(I); \ - if (FCALLS > 0 || FCALLS > neg_o_reds) { \ - FCALLS--; \ - Goto(dis_next); \ - } else { \ - goto context_switch; \ - } \ - } while (0) \ - -#define DispatchMacroFun() \ - do { \ - BeamInstr dis_next; \ - dis_next = *I; \ - CHECK_ARGS(I); \ - if (FCALLS > 0 || FCALLS > neg_o_reds) { \ - FCALLS--; \ - Goto(dis_next); \ - } else { \ - goto context_switch_fun; \ - } \ - } while (0) - -#define DispatchMacrox() \ - do { \ - if (FCALLS > 0) { \ - BeamInstr dis_next; \ - SET_I(((Export *) Arg(0))->addressv[erts_active_code_ix()]); \ - dis_next = *I; \ - FCALLS--; \ - CHECK_ARGS(I); \ - Goto(dis_next); \ - } else if (ERTS_PROC_GET_SAVED_CALLS_BUF(c_p) \ - && FCALLS > neg_o_reds) { \ - goto save_calls1; \ - } else { \ - SET_I(((Export *) Arg(0))->addressv[erts_active_code_ix()]); \ - CHECK_ARGS(I); \ - goto context_switch; \ - } \ - } while (0) - -#ifdef DEBUG -/* - * To simplify breakpoint setting, put the code in one place only and jump to it. - */ -# define Dispatch() goto do_dispatch -# define Dispatchx() goto do_dispatchx -# define Dispatchfun() goto do_dispatchfun -#else -/* - * Inline for speed. - */ -# define Dispatch() DispatchMacro() -# define Dispatchx() DispatchMacrox() -# define Dispatchfun() DispatchMacroFun() -#endif - #define Arg(N) I[(N)+1] #define GetSource(raw, dst) \ @@ -348,19 +281,6 @@ do { \ } \ } while(0) -#define DispatchReturn \ -do { \ - if (FCALLS > 0 || FCALLS > neg_o_reds) { \ - FCALLS--; \ - Goto(*I); \ - } \ - else { \ - c_p->current = NULL; \ - c_p->arity = 1; \ - goto context_switch3; \ - } \ -} while (0) - #ifdef DEBUG /* Better static type testing by the C compiler */ # define BEAM_IS_TUPLE(Src) is_tuple(Src) @@ -517,10 +437,10 @@ init_emulator(void) } \ } while(0) -#define DTRACE_RETURN_FROM_PC(p) \ +#define DTRACE_RETURN_FROM_PC(p, i) \ do { \ ErtsCodeMFA* cmfa; \ - if (DTRACE_ENABLED(function_return) && (cmfa = find_function_from_pc(cp_val((p)->stop[0])))) { \ + if (DTRACE_ENABLED(function_return) && (cmfa = find_function_from_pc(i))) { \ DTRACE_RETURN((p), cmfa); \ } \ } while(0) @@ -530,7 +450,7 @@ init_emulator(void) #define DTRACE_GLOBAL_CALL(p, mfa) do {} while (0) #define DTRACE_GLOBAL_CALL_FROM_EXPORT(p, e) do {} while (0) #define DTRACE_RETURN(p, mfa) do {} while (0) -#define DTRACE_RETURN_FROM_PC(p) do {} while (0) +#define DTRACE_RETURN_FROM_PC(p, i) do {} while (0) #define DTRACE_BIF_ENTRY(p, mfa) do {} while (0) #define DTRACE_BIF_RETURN(p, mfa) do {} while (0) #define DTRACE_NIF_ENTRY(p, mfa) do {} while (0) @@ -768,27 +688,9 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array) #endif #include "beam_hot.h" - -#ifdef DEBUG - /* - * Set a breakpoint here to get control just after a call instruction. - * I points to the first instruction in the called function. - * - * In gdb, use 'call dis(I-5, 1)' to show the name of the function. - */ - do_dispatch: - DispatchMacro(); - - do_dispatchx: - DispatchMacrox(); - - do_dispatchfun: - DispatchMacroFun(); - -#endif - /* - * Jumped to from the Dispatch() macro when the reductions are used up. + * The labels are jumped to from the $DISPATCH() macros when the reductions + * are used up. * * Since the I register points just beyond the FuncBegin instruction, we * can get the module, function, and arity for the function being @@ -982,18 +884,46 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array) } #endif return; /* Never executed */ +} - save_calls1: - { - BeamInstr dis_next; +/* + * Enter all BIFs into the export table. + * + * Note that they will all call the error_handler until their modules have been + * loaded, which may prevent the system from booting if BIFs from non-preloaded + * modules are apply/3'd while loading code. Ordinary BIF calls will work fine + * however since they won't go through export entries. + */ +static void install_bifs(void) { + int i; + + for (i = 0; i < BIF_SIZE; i++) { + BifEntry *entry; + Export *ep; + int j; + + entry = &bif_table[i]; + + ep = erts_export_put(entry->module, entry->name, entry->arity); - save_calls(c_p, (Export *) Arg(0)); + ep->info.op = BeamOpCodeAddr(op_i_func_info_IaaI); + ep->info.mfa.module = entry->module; + ep->info.mfa.function = entry->name; + ep->info.mfa.arity = entry->arity; + ep->bif_number = i; - SET_I(((Export *) Arg(0))->addressv[erts_active_code_ix()]); + memset(&ep->trampoline, 0, sizeof(ep->trampoline)); + ep->trampoline.op = BeamOpCodeAddr(op_call_error_handler); - dis_next = *I; - FCALLS--; - Goto(dis_next); + for (j = 0; j < ERTS_NUM_CODE_IX; j++) { + ep->addressv[j] = ep->trampoline.raw; + } + + /* Set up a hidden export entry so we can trap to this BIF without + * it being seen when tracing. */ + erts_init_trap_export(&bif_trap_export[i], + entry->module, entry->name, entry->arity, + entry->f); } } @@ -1004,43 +934,30 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array) static void init_emulator_finish(void) { - int i; - Export* ep; - #if defined(ARCH_64) && defined(CODE_MODEL_SMALL) - for (i = 0; i < NUMBER_OF_OPCODES; i++) { - BeamInstr instr = BeamOpCodeAddr(i); - if (instr >= (1ull << 32)) { - erts_exit(ERTS_ERROR_EXIT, - "This run-time was supposed be compiled with all code below 2Gb,\n" - "but the instruction '%s' is located at %016lx.\n", - opc[i].name, instr); - } - } + int i; + + for (i = 0; i < NUMBER_OF_OPCODES; i++) { + BeamInstr instr = BeamOpCodeAddr(i); + if (instr >= (1ull << 32)) { + erts_exit(ERTS_ERROR_EXIT, + "This run-time was supposed be compiled with all code below 2Gb,\n" + "but the instruction '%s' is located at %016lx.\n", + opc[i].name, instr); + } + } #endif - beam_apply[0] = BeamOpCodeAddr(op_i_apply); - beam_apply[1] = BeamOpCodeAddr(op_normal_exit); - beam_exit[0] = BeamOpCodeAddr(op_error_action_code); - beam_continue_exit[0] = BeamOpCodeAddr(op_continue_exit); - beam_return_to_trace[0] = BeamOpCodeAddr(op_i_return_to_trace); - beam_return_trace[0] = BeamOpCodeAddr(op_return_trace); - beam_exception_trace[0] = BeamOpCodeAddr(op_return_trace); /* UGLY */ - beam_return_time_trace[0] = BeamOpCodeAddr(op_i_return_time_trace); + beam_apply[0] = BeamOpCodeAddr(op_i_apply); + beam_apply[1] = BeamOpCodeAddr(op_normal_exit); + beam_exit[0] = BeamOpCodeAddr(op_error_action_code); + beam_continue_exit[0] = BeamOpCodeAddr(op_continue_exit); + beam_return_to_trace[0] = BeamOpCodeAddr(op_i_return_to_trace); + beam_return_trace[0] = BeamOpCodeAddr(op_return_trace); + beam_exception_trace[0] = BeamOpCodeAddr(op_return_trace); /* UGLY */ + beam_return_time_trace[0] = BeamOpCodeAddr(op_i_return_time_trace); - /* - * Enter all BIFs into the export table. - */ - for (i = 0; i < BIF_SIZE; i++) { - ep = erts_export_put(bif_table[i].module, - bif_table[i].name, - bif_table[i].arity); - bif_export[i] = ep; - ep->beam[0] = BeamOpCodeAddr(op_apply_bif); - ep->beam[1] = (BeamInstr) bif_table[i].f; - /* XXX: set func info for bifs */ - ep->info.op = BeamOpCodeAddr(op_i_func_info_IaaI); - } + install_bifs(); } /* @@ -1253,7 +1170,7 @@ void erts_dirty_process_main(ErtsSchedulerData *esdp) * I[2]: Pointer to erl_module_nif * I[3]: Function pointer to dirty NIF * - * This layout is determined by the NifExport struct + * This layout is determined by the ErtsNativeFunc struct */ ERTS_MSACC_SET_STATE_CACHED_M_X(ERTS_MSACC_STATE_NIF); @@ -1267,11 +1184,11 @@ void erts_dirty_process_main(ErtsSchedulerData *esdp) ERTS_UNREQ_PROC_MAIN_LOCK(c_p); ASSERT(!ERTS_PROC_IS_EXITING(c_p)); - if (BeamIsOpCode(*I, op_apply_bif)) { + if (BeamIsOpCode(*I, op_call_bif_W)) { exiting = erts_call_dirty_bif(esdp, c_p, I, reg); } else { - ASSERT(BeamIsOpCode(*I, op_call_nif)); + ASSERT(BeamIsOpCode(*I, op_call_nif_WWW)); exiting = erts_call_dirty_nif(esdp, c_p, I, reg); } @@ -1299,7 +1216,7 @@ ubif2mfa(void* uf) int i; for (i = 0; erts_u_bifs[i].bif; i++) { if (erts_u_bifs[i].bif == uf) - return &bif_export[erts_u_bifs[i].exp_ix]->info.mfa; + return &bif_trap_export[erts_u_bifs[i].exp_ix].info.mfa; } erts_exit(ERTS_ERROR_EXIT, "bad u bif: %p\n", uf); return NULL; @@ -1340,6 +1257,33 @@ Eterm error_atom[NUMBER_EXIT_CODES] = { am_badkey, /* 19 */ }; +/* Returns the return address at E[0] in printable form, skipping tracing in + * the same manner as gather_stacktrace. + * + * This is needed to generate correct stacktraces when throwing errors from + * instructions that return like an ordinary function, such as call_nif. */ +BeamInstr *erts_printable_return_address(Process* p, Eterm *E) { + Eterm *ptr = E; + + ASSERT(is_CP(*ptr)); + + while (ptr < STACK_START(p)) { + BeamInstr *cp = cp_val(*ptr); + + if (cp == beam_exception_trace || cp == beam_return_trace) { + ptr += 3; + } else if (cp == beam_return_time_trace) { + ptr += 2; + } else if (cp == beam_return_to_trace) { + ptr += 1; + } else { + return cp; + } + } + + ERTS_ASSERT(!"No continuation pointer on stack"); +} + /* * To fully understand the error handling, one must keep in mind that * when an exception is thrown, the search for a handler can jump back @@ -1369,14 +1313,14 @@ handle_error(Process* c_p, BeamInstr* pc, Eterm* reg, ErtsCodeMFA *bif_mfa) ASSERT(c_p->freason != TRAP); /* Should have been handled earlier. */ - if (c_p->freason & EXF_RESTORE_NIF) - erts_nif_export_restore_error(c_p, &pc, reg, &bif_mfa); + if (c_p->freason & EXF_RESTORE_NFUNC) + erts_nfunc_restore_error(c_p, &pc, reg, &bif_mfa); #ifdef DEBUG if (bif_mfa) { - /* Verify that bif_mfa does not point into our nif export */ - NifExport *nep = ERTS_PROC_GET_NIF_TRAP_EXPORT(c_p); - ASSERT(!nep || !ErtsInArea(bif_mfa, (char *)nep, sizeof(NifExport))); + /* Verify that bif_mfa does not point into our native function wrapper */ + ErtsNativeFunc *nep = ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(c_p); + ASSERT(!nep || !ErtsInArea(bif_mfa, (char *)nep, sizeof(ErtsNativeFunc))); } #endif @@ -1633,19 +1577,17 @@ expand_error_value(Process* c_p, Uint freason, Eterm Value) { static void -gather_stacktrace(Process* p, Eterm *ptr, struct StackTrace* s, int depth) +gather_stacktrace(Process* p, struct StackTrace* s, int depth) { BeamInstr *prev; - BeamInstr i_return_trace; - BeamInstr i_return_to_trace; + Eterm *ptr; if (depth == 0) { return; } - prev = s->depth ? s->trace[s->depth-1] : s->pc; - i_return_trace = beam_return_trace[0]; - i_return_to_trace = beam_return_to_trace[0]; + prev = s->depth ? s->trace[s->depth - 1] : s->pc; + ptr = p->stop; /* * Traverse the stack backwards and add all unique continuation @@ -1658,16 +1600,15 @@ gather_stacktrace(Process* p, Eterm *ptr, struct StackTrace* s, int depth) while (ptr < STACK_START(p) && depth > 0) { if (is_CP(*ptr)) { - if (*cp_val(*ptr) == i_return_trace) { - /* Skip stack frame variables */ - do ++ptr; while (is_not_CP(*ptr)); - /* Skip return_trace parameters */ + BeamInstr *cp = cp_val(*ptr); + + if (cp == beam_exception_trace || cp == beam_return_trace) { + ptr += 3; + } else if (cp == beam_return_time_trace) { ptr += 2; - } else if (*cp_val(*ptr) == i_return_to_trace) { - /* Skip stack frame variables */ - do ++ptr; while (is_not_CP(*ptr)); + } else if (cp == beam_return_to_trace) { + ptr += 1; } else { - BeamInstr *cp = cp_val(*ptr); if (cp != prev) { /* Record non-duplicates only */ prev = cp; @@ -1720,7 +1661,6 @@ static void save_stacktrace(Process* c_p, BeamInstr* pc, Eterm* reg, ErtsCodeMFA *bif_mfa, Eterm args) { struct StackTrace* s; - Eterm *stack_start; int sz; int depth = erts_backtrace_depth; /* max depth (never negative) */ @@ -1739,33 +1679,6 @@ save_stacktrace(Process* c_p, BeamInstr* pc, Eterm* reg, s->depth = 0; /* - * If we crash on an instruction that returns to a return/exception trace - * instruction, we must set the stacktrace 'pc' to the actual return - * address or we'll lose the top stackframe when gathering the stack - * trace. - */ - stack_start = STACK_TOP(c_p); - if (stack_start < STACK_START(c_p) && is_CP(*stack_start)) { - BeamInstr *cp = cp_val(*stack_start); - - if (cp == pc) { - if (pc == beam_exception_trace || pc == beam_return_trace) { - ASSERT(&stack_start[3] <= STACK_START(c_p)); - /* Fake having failed on the first instruction in the function - * pointed to by the tag. */ - pc = cp_val(stack_start[1]); - stack_start += 3; - } else if (pc == beam_return_to_trace) { - ASSERT(&stack_start[2] <= STACK_START(c_p)); - pc = cp_val(stack_start[1]); - /* Skip both the trace tag and the new 'pc' to avoid - * duplicated entries. */ - stack_start += 2; - } - } - } - - /* * If the failure was in a BIF other than 'error/1', 'error/2', * 'exit/1' or 'throw/1', save BIF-MFA and save the argument * registers by consing up an arglist. @@ -1827,13 +1740,13 @@ save_stacktrace(Process* c_p, BeamInstr* pc, Eterm* reg, } /* Save the actual stack trace */ - gather_stacktrace(c_p, stack_start, s, depth); + gather_stacktrace(c_p, s, depth); } void erts_save_stacktrace(Process* p, struct StackTrace* s, int depth) { - gather_stacktrace(p, STACK_TOP(p), s, depth); + gather_stacktrace(p, s, depth); } /* @@ -2092,83 +2005,66 @@ apply_bif_error_adjustment(Process *p, Export *ep, Eterm *reg, Uint arity, BeamInstr *I, Uint stack_offset) { + int apply_only; + Uint need; + + need = stack_offset /* bytes */ / sizeof(Eterm); + apply_only = stack_offset == 0; + /* * I is only set when the apply is a tail call, i.e., * from the instructions i_apply_only, i_apply_last_P, * and apply_last_IP. */ - if (I - && BeamIsOpCode(ep->beam[0], op_apply_bif) - && (ep == bif_export[BIF_error_1] - || ep == bif_export[BIF_error_2] - || ep == bif_export[BIF_exit_1] - || ep == bif_export[BIF_throw_1])) { - /* - * We are about to tail apply one of the BIFs - * erlang:error/1, erlang:error/2, erlang:exit/1, - * or erlang:throw/1. Error handling of these BIFs is - * special! - * - * We need the topmost continuation pointer to point into the - * calling function when handling the error after the BIF has - * been applied. This in order to get the topmost stackframe - * correct. - * - * Note that these BIFs will unconditionally cause an - * exception to be raised. That is, our modifications of the - * stack will be corrected by the error handling code. - */ - int apply_only = stack_offset == 0; - BeamInstr *cpp; - Eterm *E; + if (!(I && (ep->bif_number == BIF_error_1 || + ep->bif_number == BIF_error_2 || + ep->bif_number == BIF_exit_1 || + ep->bif_number == BIF_throw_1))) { + return; + } - E = p->stop; + /* + * We are about to tail apply one of the BIFs erlang:error/1, + * erlang:error/2, erlang:exit/1, or erlang:throw/1. Error handling of + * these BIFs is special! + * + * We need the topmost continuation pointer to point into the calling + * function when handling the error after the BIF has been applied. This in + * order to get the topmost stackframe correct. + * + * Note that these BIFs will unconditionally cause an exception to be + * raised. That is, our modifications of the stack will be corrected by the + * error handling code. + */ + if (need == 0) { + need = 1; /* i_apply_only */ + } - while (is_not_CP(*E)) { - E++; - } - cpp = cp_val(E[0]); + if (p->stop - p->htop < need) { + erts_garbage_collect(p, (int) need, reg, arity+1); + } + if (apply_only) { /* - * If we find an exception/return-to trace continuation - * pointer as the topmost continuation pointer, we do not - * need to do anything since the information will already - * be available for generation of the stacktrace. + * Called from the i_apply_only instruction. + * + * Push the continuation pointer for the current function to the stack. */ - - if (cpp != beam_exception_trace - && cpp != beam_return_trace - && cpp != beam_return_to_trace) { - Uint need = stack_offset /* bytes */ / sizeof(Eterm); - if (need == 0) - need = 1; /* i_apply_only */ - if (p->stop - p->htop < need) - erts_garbage_collect(p, (int) need, reg, arity+1); - if (apply_only) { - /* - * Called from the i_apply_only instruction. - * - * Push the continuation pointer for the current - * function to the stack. - */ - p->stop -= need; - p->stop[0] = make_cp(I); - } else { - /* - * Called from an i_apply_last_* instruction. - * - * The calling instruction will deallocate a stack - * frame of size 'stack_offset'. - * - * Push the continuation pointer for the current - * function to the stack, and then add a dummy - * stackframe for the i_apply_last* instruction - * to discard. - */ - p->stop[0] = make_cp(I); - p->stop -= need; - } - } + p->stop -= need; + p->stop[0] = make_cp(I); + } else { + /* + * Called from an i_apply_last_* instruction. + * + * The calling instruction will deallocate a stack frame of size + * 'stack_offset'. + * + * Push the continuation pointer for the current function to the stack, + * and then add a dummy stackframe for the i_apply_last* instruction + * to discard. + */ + p->stop[0] = make_cp(I); + p->stop -= need; } } @@ -2412,7 +2308,7 @@ erts_hibernate(Process* c_p, Eterm* reg) ASSERT(!ERTS_PROC_IS_EXITING(c_p)); } erts_proc_unlock(c_p, ERTS_PROC_LOCK_MSGQ|ERTS_PROC_LOCK_STATUS); - c_p->current = &bif_export[BIF_hibernate_3]->info.mfa; + c_p->current = &bif_trap_export[BIF_hibernate_3].info.mfa; c_p->flags |= F_HIBERNATE_SCHED; /* Needed also when woken! */ return 1; } @@ -3220,10 +3116,10 @@ erts_is_builtin(Eterm Mod, Eterm Name, int arity) e.info.mfa.arity = arity; if ((ep = export_get(&e)) == NULL) { - return 0; + return 0; } - return ep->addressv[erts_active_code_ix()] == ep->beam && - BeamIsOpCode(ep->beam[0], op_apply_bif); + + return ep->bif_number != -1; } diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 3d5683f19f..13d366ef8b 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -141,7 +141,7 @@ typedef struct { * eventually patch with a pointer into * the export entry. */ - BifFunction bf; /* Pointer to BIF function if BIF; + Export *bif; /* Pointer to export entry if BIF; * NULL otherwise. */ } ImportEntry; @@ -845,17 +845,23 @@ erts_finish_loading(Binary* magic, Process* c_p, if (ep == NULL || ep->info.mfa.module != module) { continue; } - if (ep->addressv[code_ix] == ep->beam) { - if (BeamIsOpCode(ep->beam[0], op_apply_bif)) { - continue; - } else if (BeamIsOpCode(ep->beam[0], op_i_generic_breakpoint)) { + + DBG_CHECK_EXPORT(ep, code_ix); + + if (ep->addressv[code_ix] == ep->trampoline.raw) { + if (BeamIsOpCode(ep->trampoline.op, op_i_generic_breakpoint)) { ERTS_LC_ASSERT(erts_thr_progress_is_blocking()); ASSERT(mod_tab_p->curr.num_traced_exports > 0); - erts_clear_export_break(mod_tab_p, &ep->info); - ep->addressv[code_ix] = (BeamInstr *) ep->beam[1]; - ep->beam[1] = 0; + + erts_clear_export_break(mod_tab_p, ep); + + ep->addressv[code_ix] = + (BeamInstr*)ep->trampoline.breakpoint.address; + ep->trampoline.breakpoint.address = 0; + + ASSERT(ep->addressv[code_ix] != ep->trampoline.raw); } - ASSERT(ep->beam[1] == 0); + ASSERT(ep->trampoline.breakpoint.address == 0); } } ASSERT(mod_tab_p->curr.num_breakpoints == 0); @@ -1471,15 +1477,14 @@ load_import_table(LoaderState* stp) } stp->import[i].arity = arity; stp->import[i].patches = 0; - stp->import[i].bf = NULL; + stp->import[i].bif = NULL; /* - * If the export entry refers to a BIF, get the pointer to - * the BIF function. + * If the export entry refers to a BIF, save a pointer to the BIF entry. */ if ((e = erts_active_export_entry(mod, func, arity)) != NULL) { - if (BeamIsOpCode(e->beam[0], op_apply_bif)) { - stp->import[i].bf = (BifFunction) e->beam[1]; + if (e->bif_number != -1) { + stp->import[i].bif = e; if (func == am_load_nif && mod == am_erlang && arity == 2) { stp->may_load_nif = 1; } @@ -1530,33 +1535,6 @@ read_export_table(LoaderState* stp) LoadError2(stp, "export table entry %u: label %u not resolved", i, n); } stp->export[i].address = address = stp->codev + value; - - /* - * Find out if there is a BIF with the same name. - */ - - if (!is_bif(stp->module, func, arity)) { - continue; - } - - /* - * This is a stub for a BIF. - * - * It should not be exported, and the information in its - * func_info instruction should be invalidated so that it - * can be filtered out by module_info(functions) and by - * any other functions that walk through all local functions. - */ - - if (stp->labels[n].num_patches > 0) { - LoadError3(stp, "there are local calls to the stub for " - "the BIF %T:%T/%d", - stp->module, func, arity); - } - stp->export[i].address = NULL; - address[-1] = 0; - address[-2] = NIL; - address[-3] = NIL; } return 1; @@ -1564,25 +1542,16 @@ read_export_table(LoaderState* stp) return 0; } - static int is_bif(Eterm mod, Eterm func, unsigned arity) { - Export* e = erts_active_export_entry(mod, func, arity); - if (e == NULL) { - return 0; - } - if (! BeamIsOpCode(e->beam[0], op_apply_bif)) { - return 0; - } - if (mod == am_erlang && func == am_apply && arity == 3) { - /* - * erlang:apply/3 is a special case -- it is implemented - * as an instruction and it is OK to redefine it. - */ - return 0; + Export *e = erts_active_export_entry(mod, func, arity); + + if (e != NULL) { + return e->bif_number != -1; } - return 1; + + return 0; } static int @@ -2534,10 +2503,14 @@ load_code(LoaderState* stp) if (i >= stp->num_imports) { LoadError1(stp, "invalid import table index %d", i); } - if (stp->import[i].bf == NULL) { + if (stp->import[i].bif == NULL) { LoadError1(stp, "not a BIF: import table index %d", i); } - code[ci++] = (BeamInstr) stp->import[i].bf; + { + int bif_index = stp->import[i].bif->bif_number; + BifEntry *bif_entry = &bif_table[bif_index]; + code[ci++] = (BeamInstr) bif_entry->f; + } break; case 'P': /* Byte offset into tuple or stack */ case 'Q': /* Like 'P', but packable */ @@ -2845,18 +2818,43 @@ load_code(LoaderState* stp) switch (stp->specific_op) { case op_i_func_info_IaaI: { + int padding_required; Sint offset; + if (function_number >= stp->num_functions) { LoadError1(stp, "too many functions in module (header said %u)", stp->num_functions); } - if (stp->may_load_nif) { + /* Native function calls may be larger than their stubs, so + * we'll need to make sure any potentially-native function stub + * is padded with enough room. + * + * Note that the padding is applied for the previous function, + * not the current one, so we check whether the old F/A is + * a BIF. */ + padding_required = last_func_start && (stp->may_load_nif || + is_bif(stp->module, stp->function, stp->arity)); + + /* + * Save context for error messages. + */ + stp->function = code[ci-2]; + stp->arity = code[ci-1]; + + /* + * Save current offset of into the line instruction array. + */ + if (stp->func_line) { + stp->func_line[function_number] = stp->current_li; + } + + if (padding_required) { const int finfo_ix = ci - FUNC_INFO_SZ; - if (finfo_ix - last_func_start < BEAM_NIF_MIN_FUNC_SZ && last_func_start) { + if (finfo_ix - last_func_start < BEAM_NATIVE_MIN_FUNC_SZ) { /* Must make room for call_nif op */ - int pad = BEAM_NIF_MIN_FUNC_SZ - (finfo_ix - last_func_start); - ASSERT(pad > 0 && pad < BEAM_NIF_MIN_FUNC_SZ); + int pad = BEAM_NATIVE_MIN_FUNC_SZ - (finfo_ix - last_func_start); + ASSERT(pad > 0 && pad < BEAM_NATIVE_MIN_FUNC_SZ); CodeNeed(pad); sys_memmove(&code[finfo_ix+pad], &code[finfo_ix], FUNC_INFO_SZ*sizeof(BeamInstr)); @@ -2867,20 +2865,6 @@ load_code(LoaderState* stp) } last_func_start = ci; - /* - * Save current offset of into the line instruction array. - */ - - if (stp->func_line) { - stp->func_line[function_number] = stp->current_li; - } - - /* - * Save context for error messages. - */ - stp->function = code[ci-2]; - stp->arity = code[ci-1]; - /* When this assert is triggered, it is normally a sign that the size of the ops.tab i_func_info instruction is not the same as FUNC_INFO_SZ */ @@ -2910,7 +2894,6 @@ load_code(LoaderState* stp) case op_i_bs_match_string_yfWW: new_string_patch(stp, ci-1); break; - case op_catch_yf: /* code[ci-3] &&lb_catch_yf * code[ci-2] y-register offset in E @@ -3184,6 +3167,25 @@ is_killed_by_make_fun(LoaderState* stp, GenOpArg Reg, GenOpArg idx) } } +/* Test whether Bif is "heavy" and should always go through its export entry */ +static int +is_heavy_bif(LoaderState* stp, GenOpArg Bif) +{ + Export *ep; + + if (Bif.type != TAG_u || Bif.val >= stp->num_imports) { + return 0; + } + + ep = stp->import[Bif.val].bif; + + if (ep) { + return bif_table[ep->bif_number].kind == BIF_KIND_HEAVY; + } + + return 0; +} + /* * Generate an instruction for element/2. */ @@ -5211,26 +5213,51 @@ final_touch(LoaderState* stp, struct erl_module_instance* inst_p) */ for (i = 0; i < stp->num_exps; i++) { - Export* ep; - BeamInstr* address = stp->export[i].address; + Export* ep; + BeamInstr* address = stp->export[i].address; - if (address == NULL) { - /* Skip stub for a BIF */ - continue; - } - ep = erts_export_put(stp->module, stp->export[i].function, - stp->export[i].arity); - if (on_load) { - /* - * on_load: Don't make any of the exported functions - * callable yet. Keep any function in the current - * code callable. - */ - ep->beam[1] = (BeamInstr) address; - } - else + ep = erts_export_put(stp->module, + stp->export[i].function, + stp->export[i].arity); + + /* Fill in BIF stubs with a proper call to said BIF. */ + if (ep->bif_number != -1) { + erts_write_bif_wrapper(ep, address); + } + + if (on_load) { + /* + * on_load: Don't make any of the exported functions + * callable yet. Keep any function in the current + * code callable. + */ + ep->trampoline.not_loaded.deferred = (BeamInstr) address; + } else { ep->addressv[erts_staging_code_ix()] = address; + } + } + +#ifdef DEBUG + /* Ensure that we've loaded stubs for all BIFs in this module. */ + for (i = 0; i < BIF_SIZE; i++) { + BifEntry *entry = &bif_table[i]; + + if (stp->module == entry->module) { + Export *ep = erts_export_put(entry->module, + entry->name, + entry->arity); + BeamInstr *addr = ep->addressv[erts_staging_code_ix()]; + + if (!ErtsInArea(addr, stp->codev, stp->ci * sizeof(BeamInstr))) { + erts_exit(ERTS_ABORT_EXIT, + "Module %T doesn't export BIF %T/%i\n", + entry->module, + entry->name, + entry->arity); + } + } } +#endif /* * Import functions and patch all callers. @@ -5403,15 +5430,16 @@ transform_engine(LoaderState* st) i = instr->a[ap].val; ASSERT(i < st->num_imports); - if (i >= st->num_imports || st->import[i].bf == NULL) + if (i >= st->num_imports || st->import[i].bif == NULL) goto restart; - if (bif_number != -1 && - bif_export[bif_number]->beam[1] != (BeamInstr) st->import[i].bf) { - goto restart; - } + if (bif_number != -1) { + Export *bif = st->import[i].bif; + if (bif->bif_number != bif_number) { + goto restart; + } + } } break; - #endif #if defined(TOP_is_not_bif) case TOP_is_not_bif: @@ -5441,7 +5469,7 @@ transform_engine(LoaderState* st) * they are special. */ if (i < st->num_imports) { - if (st->import[i].bf != NULL || + if (st->import[i].bif != NULL || (st->import[i].module == am_erlang && st->import[i].function == am_apply && (st->import[i].arity == 2 || st->import[i].arity == 3))) { @@ -6286,12 +6314,12 @@ exported_from_module(Process* p, /* Process whose heap to use. */ if (ep->info.mfa.module == mod) { Eterm tuple; - - if (ep->addressv[code_ix] == ep->beam && - BeamIsOpCode(ep->beam[0], op_call_error_handler)) { - /* There is a call to the function, but it does not exist. */ - continue; - } + + if (ep->addressv[code_ix] == ep->trampoline.raw && + BeamIsOpCode(ep->trampoline.op, op_call_error_handler)) { + /* There is a call to the function, but it does not exist. */ + continue; + } if (hp == hend) { int need = 10 * 5; diff --git a/erts/emulator/beam/beam_load.h b/erts/emulator/beam/beam_load.h index 156c3c45e2..e7127c5b08 100644 --- a/erts/emulator/beam/beam_load.h +++ b/erts/emulator/beam/beam_load.h @@ -106,7 +106,7 @@ typedef struct beam_code_header { }BeamCodeHeader; -# define BEAM_NIF_MIN_FUNC_SZ 4 +# define BEAM_NATIVE_MIN_FUNC_SZ 4 void erts_release_literal_area(struct ErtsLiteralArea_* literal_area); int erts_is_module_native(BeamCodeHeader* code); diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 7afbbfd894..14f6c44cb8 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -2160,7 +2160,7 @@ BIF_RETTYPE send_3(BIF_ALIST_3) break; case SEND_YIELD: if (suspend) { - ERTS_BIF_PREP_YIELD3(retval, bif_export[BIF_send_3], p, to, msg, opts); + ERTS_BIF_PREP_YIELD3(retval, &bif_trap_export[BIF_send_3], p, to, msg, opts); } else { ERTS_BIF_PREP_RET(retval, am_nosuspend); } @@ -2277,7 +2277,7 @@ Eterm erl_send(Process *p, Eterm to, Eterm msg) ERTS_BIF_PREP_RET(retval, msg); break; case SEND_YIELD: - ERTS_BIF_PREP_YIELD2(retval, bif_export[BIF_send_2], p, to, msg); + ERTS_BIF_PREP_YIELD2(retval, &bif_trap_export[BIF_send_2], p, to, msg); break; case SEND_YIELD_RETURN: yield_return: @@ -2584,7 +2584,7 @@ BIF_RETTYPE iolist_size_1(BIF_ALIST_1) } else { ERTS_BIF_ERROR_TRAPPED1(BIF_P, BADARG, - bif_export[BIF_iolist_size_1], + &bif_trap_export[BIF_iolist_size_1], input_list); } @@ -2604,7 +2604,7 @@ BIF_RETTYPE iolist_size_1(BIF_ALIST_1) ESTACK_SAVE(s, &context->stack); erts_set_gc_state(BIF_P, 0); BUMP_ALL_REDS(BIF_P); - BIF_TRAP1(bif_export[BIF_iolist_size_1], BIF_P, state_mref); + BIF_TRAP1(&bif_trap_export[BIF_iolist_size_1], BIF_P, state_mref); } /**********************************************************************/ @@ -3942,7 +3942,7 @@ BIF_RETTYPE halt_2(BIF_ALIST_2) ("System halted by BIF halt(%T, %T)\n", BIF_ARG_1, BIF_ARG_2)); if (flush) { erts_halt(pos_int_code); - ERTS_BIF_YIELD2(bif_export[BIF_halt_2], BIF_P, am_undefined, am_undefined); + ERTS_BIF_YIELD2(&bif_trap_export[BIF_halt_2], BIF_P, am_undefined, am_undefined); } else { erts_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); @@ -4527,7 +4527,7 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2) BIF_RET(am_enabled); case ERTS_SCHDLR_SSPND_YIELD_RESTART: ERTS_VBUMP_ALL_REDS(BIF_P); - BIF_TRAP2(bif_export[BIF_system_flag_2], + BIF_TRAP2(&bif_trap_export[BIF_system_flag_2], BIF_P, BIF_ARG_1, BIF_ARG_2); case ERTS_SCHDLR_SSPND_YIELD_DONE: ERTS_BIF_YIELD_RETURN_X(BIF_P, am_enabled, @@ -4552,7 +4552,7 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2) BIF_RET(make_small(old_no)); case ERTS_SCHDLR_SSPND_YIELD_RESTART: ERTS_VBUMP_ALL_REDS(BIF_P); - BIF_TRAP2(bif_export[BIF_system_flag_2], + BIF_TRAP2(&bif_trap_export[BIF_system_flag_2], BIF_P, BIF_ARG_1, BIF_ARG_2); case ERTS_SCHDLR_SSPND_YIELD_DONE: ERTS_BIF_YIELD_RETURN_X(BIF_P, make_small(old_no), @@ -4716,7 +4716,7 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2) BIF_RET(make_small(old_no)); case ERTS_SCHDLR_SSPND_YIELD_RESTART: ERTS_VBUMP_ALL_REDS(BIF_P); - BIF_TRAP2(bif_export[BIF_system_flag_2], + BIF_TRAP2(&bif_trap_export[BIF_system_flag_2], BIF_P, BIF_ARG_1, BIF_ARG_2); case ERTS_SCHDLR_SSPND_YIELD_DONE: ERTS_BIF_YIELD_RETURN_X(BIF_P, make_small(old_no), @@ -4871,7 +4871,7 @@ BIF_RETTYPE phash2_1(BIF_ALIST_1) if (trap_state == THE_NON_VALUE) { BIF_RET(make_small(hash & ((1L << 27) - 1))); } else { - BIF_TRAP1(bif_export[BIF_phash2_1], BIF_P, trap_state); + BIF_TRAP1(&bif_trap_export[BIF_phash2_1], BIF_P, trap_state); } } @@ -4894,7 +4894,7 @@ BIF_RETTYPE phash2_2(BIF_ALIST_2) } hash = trapping_make_hash2(BIF_ARG_1, &trap_state, BIF_P); if (trap_state != THE_NON_VALUE) { - BIF_TRAP2(bif_export[BIF_phash2_2], BIF_P, trap_state, BIF_ARG_2); + BIF_TRAP2(&bif_trap_export[BIF_phash2_2], BIF_P, trap_state, BIF_ARG_2); } if (range) { final_hash = hash % range; /* [0..range-1] */ @@ -4971,15 +4971,32 @@ void erts_init_trap_export(Export* ep, Eterm m, Eterm f, Uint a, Eterm (*bif)(BIF_ALIST)) { int i; + sys_memset((void *) ep, 0, sizeof(Export)); + for (i=0; i<ERTS_NUM_CODE_IX; i++) { - ep->addressv[i] = ep->beam; + ep->addressv[i] = ep->trampoline.raw; } + + ep->bif_number = -1; + + ep->info.op = op_i_func_info_IaaI; ep->info.mfa.module = m; ep->info.mfa.function = f; ep->info.mfa.arity = a; - ep->beam[0] = BeamOpCodeAddr(op_apply_bif); - ep->beam[1] = (BeamInstr) bif; + + ep->trampoline.op = BeamOpCodeAddr(op_call_bif_W); + ep->trampoline.raw[1] = (BeamInstr)bif; +} + +/* + * Writes a BIF call wrapper to the given address. + */ +void erts_write_bif_wrapper(Export *export, BeamInstr *address) { + BifEntry *entry = &bif_table[export->bif_number]; + + address[0] = BeamOpCodeAddr(op_call_bif_W); + address[1] = (BeamInstr)entry->f; } void erts_init_bif(void) @@ -5031,7 +5048,7 @@ void erts_init_bif(void) } /* - * Scheduling of BIFs via NifExport... + * Scheduling of BIFs via ErtsNativeFunc... */ #define ERTS_WANT_NFUNC_SCHED_INTERNALS__ #include "erl_nfunc_sched.h" @@ -5046,8 +5063,8 @@ schedule(Process *c_p, Process *dirty_shadow_proc, int argc, Eterm *argv) { ERTS_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(c_p)); - (void) erts_nif_export_schedule(c_p, dirty_shadow_proc, - mfa, pc, BeamOpCodeAddr(op_apply_bif), + (void) erts_nfunc_schedule(c_p, dirty_shadow_proc, + mfa, pc, BeamOpCodeAddr(op_call_bif_W), dfunc, ifunc, module, function, argc, argv); @@ -5056,23 +5073,23 @@ schedule(Process *c_p, Process *dirty_shadow_proc, static BIF_RETTYPE dirty_bif_result(BIF_ALIST_1) { - NifExport *nep = (NifExport *) ERTS_PROC_GET_NIF_TRAP_EXPORT(BIF_P); - erts_nif_export_restore(BIF_P, nep, BIF_ARG_1); + ErtsNativeFunc *nep = (ErtsNativeFunc *) ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(BIF_P); + erts_nfunc_restore(BIF_P, nep, BIF_ARG_1); BIF_RET(BIF_ARG_1); } static BIF_RETTYPE dirty_bif_trap(BIF_ALIST) { - NifExport *nep = (NifExport *) ERTS_PROC_GET_NIF_TRAP_EXPORT(BIF_P); + ErtsNativeFunc *nep = (ErtsNativeFunc *) ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(BIF_P); /* * Arity and argument registers already set * correct by call to dirty_bif_trap()... */ - ASSERT(BIF_P->arity == nep->exp.info.mfa.arity); + ASSERT(BIF_P->arity == nep->trampoline.info.mfa.arity); - erts_nif_export_restore(BIF_P, nep, THE_NON_VALUE); + erts_nfunc_restore(BIF_P, nep, THE_NON_VALUE); BIF_P->i = (BeamInstr *) nep->func; BIF_P->freason = TRAP; @@ -5087,8 +5104,8 @@ static BIF_RETTYPE dirty_bif_exception(BIF_ALIST_2) freason = signed_val(BIF_ARG_1); - /* Restore orig info for error and clear nif export in handle_error() */ - freason |= EXF_RESTORE_NIF; + /* Restore orig info for error and clear nif wrapper in handle_error() */ + freason |= EXF_RESTORE_NFUNC; BIF_P->fvalue = BIF_ARG_2; @@ -5126,6 +5143,7 @@ erts_schedule_bif(Process *proc, if (!ERTS_PROC_IS_EXITING(c_p)) { Export *exp; BifFunction dbif, ibif; + BeamInstr call_instr; BeamInstr *pc; /* @@ -5160,27 +5178,40 @@ erts_schedule_bif(Process *proc, if (i == NULL) { ERTS_INTERNAL_ERROR("Missing instruction pointer"); } + + if (BeamIsOpCode(*i, op_i_generic_breakpoint)) { + ErtsCodeInfo *ci; + GenericBp *bp; + + ci = erts_code_to_codeinfo(i); + bp = ci->u.gen_bp; + + call_instr = bp->orig_instr; + } else { + call_instr = *i; + } + #ifdef HIPE - else if (proc->flags & F_HIPE_MODE) { + if (proc->flags & F_HIPE_MODE) { /* Pointer to bif export in i */ exp = (Export *) i; pc = cp_val(c_p->stop[0]); mfa = &exp->info.mfa; - } + } else /* !! This is part of the if clause below !! */ #endif - else if (BeamIsOpCode(*i, op_call_bif_e)) { - /* Pointer to bif export in i+1 */ - exp = (Export *) i[1]; + if (BeamIsOpCode(call_instr, op_call_light_bif_be)) { + /* Pointer to bif export in i+2 */ + exp = (Export *) i[2]; pc = i; mfa = &exp->info.mfa; } - else if (BeamIsOpCode(*i, op_call_bif_only_e)) { - /* Pointer to bif export in i+1 */ - exp = (Export *) i[1]; + else if (BeamIsOpCode(call_instr, op_call_light_bif_only_be)) { + /* Pointer to bif export in i+2 */ + exp = (Export *) i[2]; pc = i; mfa = &exp->info.mfa; } - else if (BeamIsOpCode(*i, op_apply_bif)) { + else if (BeamIsOpCode(call_instr, op_call_bif_W)) { pc = cp_val(c_p->stop[0]); mfa = erts_code_to_codemfa(i); } @@ -5209,7 +5240,7 @@ erts_schedule_bif(Process *proc, static BIF_RETTYPE call_bif(Process *c_p, Eterm *reg, BeamInstr *I) { - NifExport *nep = ERTS_I_BEAM_OP_TO_NIF_EXPORT(I); + ErtsNativeFunc *nep = ERTS_I_BEAM_OP_TO_NFUNC(I); ErtsBifFunc bif = (ErtsBifFunc) nep->func; BIF_RETTYPE ret; @@ -5222,12 +5253,12 @@ call_bif(Process *c_p, Eterm *reg, BeamInstr *I) ret = (*bif)(c_p, reg, I); if (is_value(ret)) - erts_nif_export_restore(c_p, nep, ret); + erts_nfunc_restore(c_p, nep, ret); else if (c_p->freason != TRAP) - c_p->freason |= EXF_RESTORE_NIF; /* restore in handle_error() */ + c_p->freason |= EXF_RESTORE_NFUNC; /* restore in handle_error() */ else if (nep->func == ERTS_SCHED_BIF_TRAP_MARKER) { /* BIF did an ordinary trap... */ - erts_nif_export_restore(c_p, nep, ret); + erts_nfunc_restore(c_p, nep, ret); } /* else: * BIF rescheduled itself using erts_schedule_bif(). @@ -5244,7 +5275,7 @@ erts_call_dirty_bif(ErtsSchedulerData *esdp, Process *c_p, BeamInstr *I, Eterm * int exiting; Process *dirty_shadow_proc; ErtsBifFunc bf; - NifExport *nep; + ErtsNativeFunc *nep; #ifdef DEBUG Eterm *c_p_htop; erts_aint32_t state; @@ -5257,8 +5288,8 @@ erts_call_dirty_bif(ErtsSchedulerData *esdp, Process *c_p, BeamInstr *I, Eterm * #endif - nep = ERTS_I_BEAM_OP_TO_NIF_EXPORT(I); - ASSERT(nep == ERTS_PROC_GET_NIF_TRAP_EXPORT(c_p)); + nep = ERTS_I_BEAM_OP_TO_NFUNC(I); + ASSERT(nep == ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(c_p)); nep->func = ERTS_SCHED_BIF_TRAP_MARKER; diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index c9f5177bd3..19dabc0514 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -25,13 +25,14 @@ # # <bif-decl> ::= "bif" <bif> <C-name>* | # "ubif" <bif> <C-name>* | -# "gcbif" <bif> <C-name>* +# "hbif" <bif> <C-name>* # <bif> ::= <module> ":" <name> "/" <arity> # -# ubif: Use for operators and guard BIFs that never build anything -# on the heap (such as tuple_size/1) and operators. +# ubif: Use for operators and guard BIFs. # -# gcbif: Use for guard BIFs that may build on the heap (such as abs/1). +# hbif: Use for BIFs that perform garbage collection or need up-to-date +# information on where they were called from. These must be called +# through the export entry. # # bif: Use for all other BIFs. # @@ -60,7 +61,7 @@ bif erlang:display_string/1 bif erlang:display_nl/0 ubif erlang:element/2 bif erlang:erase/0 -bif erlang:erase/1 +hbif erlang:erase/1 bif erlang:exit/1 bif erlang:exit/2 bif erlang:exit_signal/2 @@ -70,7 +71,7 @@ ubif erlang:float/1 bif erlang:float_to_list/1 bif erlang:float_to_list/2 bif erlang:fun_info/2 -bif erts_internal:garbage_collect/1 +hbif erts_internal:garbage_collect/1 bif erlang:get/0 bif erlang:get/1 bif erlang:get_keys/1 @@ -127,10 +128,10 @@ bif erlang:ports/0 bif erlang:pre_loaded/0 bif erlang:process_flag/2 bif erts_internal:process_flag/3 -bif erlang:process_info/1 -bif erlang:process_info/2 +hbif erlang:process_info/1 +hbif erlang:process_info/2 bif erlang:processes/0 -bif erlang:put/2 +hbif erlang:put/2 bif erlang:register/2 bif erlang:registered/0 ubif erlang:round/1 @@ -174,7 +175,7 @@ bif erts_internal:port_connect/2 bif erts_internal:request_system_task/3 bif erts_internal:request_system_task/4 -bif erts_internal:check_process_code/1 +hbif erts_internal:check_process_code/1 bif erts_internal:map_to_tuple_keys/1 bif erts_internal:term_type/1 @@ -466,7 +467,7 @@ bif code:is_module_native/1 # New Bifs in R9C. # -bif erlang:hibernate/3 +hbif erlang:hibernate/3 bif error_logger:warning_map/0 # diff --git a/erts/emulator/beam/bif_instrs.tab b/erts/emulator/beam/bif_instrs.tab index f1877882a1..de5305bde4 100644 --- a/erts/emulator/beam/bif_instrs.tab +++ b/erts/emulator/beam/bif_instrs.tab @@ -212,26 +212,32 @@ i_length.execute(Fail, Live, Dst) { // Call a BIF, store the result in x(0) and transfer control to the // next instruction. // -call_bif(Exp) { +call_light_bif(Bif, Exp) { + Export *export; ErtsBifFunc bf; + Eterm result; ErlHeapFragment *live_hf_end; - Export *export = (Export*) $Exp; + + bf = (ErtsBifFunc) $Bif; + export = (Export*) $Exp; if (!((FCALLS - 1) > 0 || (FCALLS-1) > neg_o_reds)) { /* * If we have run out of reductions, do a context * switch before calling the BIF. */ - c_p->arity = GET_BIF_ARITY(export); + c_p->arity = GET_EXPORT_ARITY(export); c_p->current = &export->info.mfa; goto context_switch3; } - ERTS_MSACC_SET_BIF_STATE_CACHED_X(GET_BIF_MODULE(export), - GET_BIF_ADDRESS(export)); + if (ERTS_UNLIKELY(export->is_bif_traced)) { + $SAVE_CONTINUATION_POINTER($NEXT_INSTRUCTION); + $DISPATCH_EXPORT(export); + } - bf = GET_BIF_ADDRESS(export); + ERTS_MSACC_SET_BIF_STATE_CACHED_X(GET_EXPORT_MODULE(export), bf); PRE_BIF_SWAPOUT(c_p); ERTS_DBG_CHK_REDS(c_p, FCALLS); @@ -243,21 +249,26 @@ call_bif(Exp) { ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p); live_hf_end = c_p->mbuf; ERTS_CHK_MBUF_SZ(c_p); + result = (*bf)(c_p, reg, I); + + /* Only heavy BIFs may GC. */ + ASSERT(E == c_p->stop); + ERTS_CHK_MBUF_SZ(c_p); ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(result)); ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p); ERTS_HOLE_CHECK(c_p); ERTS_REQ_PROC_MAIN_LOCK(c_p); if (ERTS_IS_GC_DESIRED(c_p)) { - Uint arity = GET_BIF_ARITY(export); + Uint arity = GET_EXPORT_ARITY(export); result = erts_gc_after_bif_call_lhf(c_p, live_hf_end, result, reg, arity); E = c_p->stop; } - PROCESS_MAIN_CHK_LOCKS(c_p); HTOP = HEAP_TOP(c_p); FCALLS = c_p->fcalls; + PROCESS_MAIN_CHK_LOCKS(c_p); ERTS_DBG_CHK_REDS(c_p, FCALLS); /* @@ -282,8 +293,7 @@ call_bif(Exp) { */ $SAVE_CONTINUATION_POINTER($NEXT_INSTRUCTION); SET_I(c_p->i); - SWAPIN; - Dispatch(); + $DISPATCH(); } /* @@ -299,27 +309,36 @@ call_bif(Exp) { // Call a BIF tail-recursively, storing the result in x(0) and doing // a return to the continuation poiner. // - -call_bif_only(Exp) { +call_light_bif_only(Bif, Exp) { + ErlHeapFragment *live_hf_end; ErtsBifFunc bf; + Export *export; Eterm result; - ErlHeapFragment *live_hf_end; - Export *export = (Export*) $Exp; + + bf = (ErtsBifFunc) $Bif; + export = (Export*) $Exp; if (!((FCALLS - 1) > 0 || (FCALLS-1) > neg_o_reds)) { /* * If we have run out of reductions, do a context * switch before calling the BIF. */ - c_p->arity = GET_BIF_ARITY(export); + c_p->arity = GET_EXPORT_ARITY(export); c_p->current = &export->info.mfa; goto context_switch3; } - ERTS_MSACC_SET_BIF_STATE_CACHED_X(GET_BIF_MODULE(export), - GET_BIF_ADDRESS(export)); + if (ERTS_UNLIKELY(export->is_bif_traced)) { + /* Set up a dummy stack frame so we can perform a normal call. Loader + * transformations ensure that the next instruction after this is + * 'deallocate_return 0'. */ + $AH(0, 0, GET_EXPORT_ARITY(export)); + + $SAVE_CONTINUATION_POINTER($NEXT_INSTRUCTION); + $DISPATCH_EXPORT(export); + } - bf = GET_BIF_ADDRESS(export); + ERTS_MSACC_SET_BIF_STATE_CACHED_X(GET_EXPORT_MODULE(export), bf); PRE_BIF_SWAPOUT(c_p); ERTS_DBG_CHK_REDS(c_p, FCALLS); @@ -331,21 +350,26 @@ call_bif_only(Exp) { ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p); live_hf_end = c_p->mbuf; ERTS_CHK_MBUF_SZ(c_p); + result = (*bf)(c_p, reg, I); + + /* Only heavy BIFs may GC. */ + ASSERT(E == c_p->stop); + ERTS_CHK_MBUF_SZ(c_p); ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(result)); ERTS_VERIFY_UNUSED_TEMP_ALLOC(c_p); ERTS_HOLE_CHECK(c_p); ERTS_REQ_PROC_MAIN_LOCK(c_p); if (ERTS_IS_GC_DESIRED(c_p)) { - Uint arity = GET_BIF_ARITY(export); + Uint arity = GET_EXPORT_ARITY(export); result = erts_gc_after_bif_call_lhf(c_p, live_hf_end, result, reg, arity); E = c_p->stop; } - PROCESS_MAIN_CHK_LOCKS(c_p); HTOP = HEAP_TOP(c_p); FCALLS = c_p->fcalls; + PROCESS_MAIN_CHK_LOCKS(c_p); ERTS_DBG_CHK_REDS(c_p, FCALLS); /* @@ -370,8 +394,7 @@ call_bif_only(Exp) { * to the continuation pointer on the stack will be done. */ SET_I(c_p->i); - SWAPIN; - Dispatch(); + $DISPATCH(); } /* @@ -416,14 +439,14 @@ send() { $SAVE_CONTINUATION_POINTER($NEXT_INSTRUCTION); SET_I(c_p->i); SWAPIN; - Dispatch(); + $DISPATCH(); } else { goto find_func_info; } } call_nif := nif_bif.call_nif.epilogue; -apply_bif := nif_bif.apply_bif.epilogue; +call_bif := nif_bif.call_bif.epilogue; nif_bif.head() { Eterm nif_bif_result; @@ -433,7 +456,7 @@ nif_bif.head() { ErtsCodeMFA *codemfa; } -nif_bif.call_nif() { +nif_bif.call_nif(Func, NifMod, DirtyFunc) { /* * call_nif is always first instruction in function: * @@ -443,11 +466,14 @@ nif_bif.call_nif() { * I[0]: &&call_nif * I[1]: Function pointer to NIF function * I[2]: Pointer to erl_module_nif - * I[3]: Function pointer to dirty NIF + * I[3]: Function pointer to dirty NIF. This is not used in this + * instruction, but dirty schedulers look at it. * - * This layout is determined by the NifExport struct + * This layout is determined by the ErtsNativeFunc struct */ + (void)$DirtyFunc; + ERTS_MSACC_SET_STATE_CACHED_M_X(ERTS_MSACC_STATE_NIF); codemfa = erts_code_to_codemfa(I); @@ -465,12 +491,12 @@ nif_bif.call_nif() { ASSERT(!ERTS_PROC_IS_EXITING(c_p)); { typedef Eterm NifF(struct enif_environment_t*, int argc, Eterm argv[]); - NifF* fp = vbf = (NifF*) I[1]; + NifF* fp = vbf = (NifF*) $Func; struct enif_environment_t env; ASSERT(c_p->scheduler_data); live_hf_end = c_p->mbuf; ERTS_CHK_MBUF_SZ(c_p); - erts_pre_nif(&env, c_p, (struct erl_module_nif*)I[2], NULL); + erts_pre_nif(&env, c_p, (struct erl_module_nif*)$NifMod, NULL); ASSERT((c_p->scheduler_data)->current_nif == NULL); (c_p->scheduler_data)->current_nif = &env; @@ -495,15 +521,15 @@ nif_bif.call_nif() { DTRACE_NIF_RETURN(c_p, codemfa); } -nif_bif.apply_bif() { +nif_bif.call_bif(Func) { /* - * At this point, I points to the code[0] in the export entry for - * the BIF: + * At this point, I points to the code[0] in the native function wrapper + * for the BIF: * * code[-3]: Module * code[-2]: Function * code[-1]: Arity - * code[0]: &&apply_bif + * code[0]: &&call_bif * code[1]: Function pointer to BIF function */ @@ -515,21 +541,19 @@ nif_bif.apply_bif() { codemfa = erts_code_to_codemfa(I); - ERTS_MSACC_SET_BIF_STATE_CACHED_X(codemfa->module, (BifFunction)Arg(0)); - + ERTS_MSACC_SET_BIF_STATE_CACHED_X(codemfa->module, (BifFunction)$Func); /* In case we apply process_info/1,2 or load_nif/1 */ c_p->current = codemfa; $SET_CP_I_ABS(I); /* In case we apply check_process_code/2. */ c_p->arity = 0; /* To allow garbage collection on ourselves - * (check_process_code/2). - */ + * (check_process_code/2, put/2, etc). */ DTRACE_BIF_ENTRY(c_p, codemfa); SWAPOUT; ERTS_DBG_CHK_REDS(c_p, FCALLS - 1); c_p->fcalls = FCALLS - 1; - vbf = (BifFunction) Arg(0); + vbf = (BifFunction)$Func; PROCESS_MAIN_CHK_LOCKS(c_p); bif_nif_arity = codemfa->arity; ASSERT(bif_nif_arity <= 4); @@ -557,6 +581,7 @@ nif_bif.apply_bif() { } nif_bif.epilogue() { + //| -no_next ERTS_REQ_PROC_MAIN_LOCK(c_p); ERTS_HOLE_CHECK(c_p); if (ERTS_IS_GC_DESIRED(c_p)) { @@ -578,12 +603,42 @@ nif_bif.epilogue() { c_p->flags &= ~F_HIBERNATE_SCHED; goto do_schedule; } - Dispatch(); + $DISPATCH(); } { - BeamInstr *cp = cp_val(*E); + BeamInstr *cp = erts_printable_return_address(c_p, E); ASSERT(VALID_INSTR(*cp)); I = handle_error(c_p, cp, reg, c_p->current); } goto post_error_handling; } + +i_load_nif() { + //| -no_next + if (erts_try_seize_code_write_permission(c_p)) { + Eterm result; + + PRE_BIF_SWAPOUT(c_p); + result = erts_load_nif(c_p, I, r(0), r(1)); + erts_release_code_write_permission(); + ERTS_REQ_PROC_MAIN_LOCK(c_p); + SWAPIN; + + if (ERTS_LIKELY(is_value(result))) { + r(0) = result; + $NEXT0(); + } else { + static ErtsCodeMFA mfa = {am_erlang, am_load_nif, 2}; + c_p->freason = BADARG; + I = handle_error(c_p, I, reg, &mfa); + goto post_error_handling; + } + } else { + /* Yield and try again */ + $SET_CP_I_ABS(I); + SWAPOUT; + c_p->current = NULL; + c_p->arity = 2; + goto do_schedule; + } +} diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c index 4ddf59092a..0ae4bc1e60 100644 --- a/erts/emulator/beam/binary.c +++ b/erts/emulator/beam/binary.c @@ -567,7 +567,7 @@ BIF_RETTYPE binary_to_list_1(BIF_ALIST_1) if (size < L2B_B2L_MIN_EXEC_REDS*ERTS_B2L_BYTES_PER_REDUCTION) { if (reds_left <= L2B_B2L_RESCHED_REDS) { /* Yield and do it with full context reds... */ - ERTS_BIF_YIELD1(bif_export[BIF_binary_to_list_1], + ERTS_BIF_YIELD1(&bif_trap_export[BIF_binary_to_list_1], BIF_P, BIF_ARG_1); } /* Allow a bit more reductions... */ @@ -621,7 +621,7 @@ BIF_RETTYPE binary_to_list_3(BIF_ALIST_3) if (size < L2B_B2L_MIN_EXEC_REDS*ERTS_B2L_BYTES_PER_REDUCTION) { if (reds_left <= L2B_B2L_RESCHED_REDS) { /* Yield and do it with full context reds... */ - ERTS_BIF_YIELD3(bif_export[BIF_binary_to_list_3], + ERTS_BIF_YIELD3(&bif_trap_export[BIF_binary_to_list_3], BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3); } /* Allow a bit more reductions... */ @@ -668,7 +668,7 @@ BIF_RETTYPE bitstring_to_list_1(BIF_ALIST_1) if (size < L2B_B2L_MIN_EXEC_REDS*ERTS_B2L_BYTES_PER_REDUCTION) { if (reds_left <= L2B_B2L_RESCHED_REDS) { /* Yield and do it with full context reds... */ - ERTS_BIF_YIELD1(bif_export[BIF_bitstring_to_list_1], + ERTS_BIF_YIELD1(&bif_trap_export[BIF_bitstring_to_list_1], BIF_P, BIF_ARG_1); } /* Allow a bit more reductions... */ @@ -1041,7 +1041,7 @@ HIPE_WRAPPER_BIF_DISABLE_GC(list_to_binary, 1) BIF_RETTYPE list_to_binary_1(BIF_ALIST_1) { - return erts_list_to_binary_bif(BIF_P, BIF_ARG_1, bif_export[BIF_list_to_binary_1]); + return erts_list_to_binary_bif(BIF_P, BIF_ARG_1, &bif_trap_export[BIF_list_to_binary_1]); } HIPE_WRAPPER_BIF_DISABLE_GC(iolist_to_binary, 1) @@ -1054,7 +1054,7 @@ BIF_RETTYPE iolist_to_binary_1(BIF_ALIST_1) } BIF_ERROR(BIF_P, BADARG); } - return erts_list_to_binary_bif(BIF_P, BIF_ARG_1, bif_export[BIF_iolist_to_binary_1]); + return erts_list_to_binary_bif(BIF_P, BIF_ARG_1, &bif_trap_export[BIF_iolist_to_binary_1]); } static int bitstr_list_len(ErtsIOListState *); @@ -1081,7 +1081,7 @@ BIF_RETTYPE list_to_bitstring_1(BIF_ALIST_1) else { ErtsL2BState state = ERTS_L2B_STATE_INITER(BIF_P, BIF_ARG_1, - bif_export[BIF_list_to_bitstring_1], + &bif_trap_export[BIF_list_to_bitstring_1], bitstr_list_len, list_to_bitstr_buf_yielding); int orig_reds_left = ERTS_BIF_REDS_LEFT(BIF_P); diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index dafe805a6f..3fdd20eecd 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -3437,7 +3437,7 @@ dist_ctrl_get_data_1(BIF_ALIST_1) erts_de_runlock(dep); if (obufsize) erts_atomic_add_nob(&dep->qsize, (erts_aint_t) -obufsize); - ERTS_BIF_YIELD1(bif_export[BIF_dist_ctrl_get_data_1], + ERTS_BIF_YIELD1(&bif_trap_export[BIF_dist_ctrl_get_data_1], BIF_P, BIF_ARG_1); } diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c index b9f0334172..1bbc7d7f1e 100644 --- a/erts/emulator/beam/erl_alloc.c +++ b/erts/emulator/beam/erl_alloc.c @@ -653,8 +653,6 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop) = erts_timer_type_size(ERTS_ALC_T_HL_PTIMER); fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_BIF_TIMER)] = erts_timer_type_size(ERTS_ALC_T_BIF_TIMER); - fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_NIF_EXP_TRACE)] - = sizeof(NifExportTrace); fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_MREF_NSCHED_ENT)] = sizeof(ErtsNSchedMagicRefTableEntry); fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_MINDIRECTION)] @@ -2392,10 +2390,6 @@ erts_memory(fmtfn_t *print_to_p, void *print_to_arg, void *proc, Eterm earg) &size.processes_used, fi, ERTS_ALC_T_BIF_TIMER); - add_fix_values(&size.processes, - &size.processes_used, - fi, - ERTS_ALC_T_NIF_EXP_TRACE); } if (want.atom || want.atom_used) { diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types index 349977ebe7..3e643a6223 100644 --- a/erts/emulator/beam/erl_alloc.types +++ b/erts/emulator/beam/erl_alloc.types @@ -331,8 +331,7 @@ type DB_HEIR_DATA STANDARD ETS db_heir_data type DB_MS_PSDO_PROC LONG_LIVED ETS db_match_pseudo_proc type SCHDLR_DATA LONG_LIVED SYSTEM scheduler_data -type NIF_TRAP_EXPORT STANDARD PROCESSES nif_trap_export_entry -type NIF_EXP_TRACE FIXED_SIZE PROCESSES nif_export_trace +type NFUNC_TRAP_WRAPPER STANDARD PROCESSES nfunc_trap_wrapper type EXPORT LONG_LIVED CODE export_entry type MONITOR FIXED_SIZE PROCESSES monitor type MONITOR_SUSPEND STANDARD PROCESSES monitor_suspend diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c index b8e56390c1..03b8e0e632 100644 --- a/erts/emulator/beam/erl_bif_binary.c +++ b/erts/emulator/beam/erl_bif_binary.c @@ -2413,7 +2413,7 @@ HIPE_WRAPPER_BIF_DISABLE_GC(binary_list_to_bin, 1) BIF_RETTYPE binary_list_to_bin_1(BIF_ALIST_1) { - return erts_list_to_binary_bif(BIF_P, BIF_ARG_1, bif_export[BIF_binary_list_to_bin_1]); + return erts_list_to_binary_bif(BIF_P, BIF_ARG_1, &bif_trap_export[BIF_binary_list_to_bin_1]); } typedef struct { diff --git a/erts/emulator/beam/erl_bif_chksum.c b/erts/emulator/beam/erl_bif_chksum.c index cce8472ccb..4cab9bec1d 100644 --- a/erts/emulator/beam/erl_bif_chksum.c +++ b/erts/emulator/beam/erl_bif_chksum.c @@ -327,7 +327,7 @@ crc32_1(BIF_ALIST_1) res_sum = erts_make_integer(chksum,BIF_P); if (rest != NIL) { BUMP_ALL_REDS(BIF_P); - BIF_TRAP2(bif_export[BIF_crc32_2], BIF_P, res_sum, rest); + BIF_TRAP2(&bif_trap_export[BIF_crc32_2], BIF_P, res_sum, rest); } BIF_RET(res_sum); } @@ -354,7 +354,7 @@ crc32_2(BIF_ALIST_2) res_sum = erts_make_integer(chksum,BIF_P); if (rest != NIL) { BUMP_ALL_REDS(BIF_P); - BIF_TRAP2(bif_export[BIF_crc32_2], BIF_P, res_sum, rest); + BIF_TRAP2(&bif_trap_export[BIF_crc32_2], BIF_P, res_sum, rest); } BIF_RET(res_sum); } @@ -407,7 +407,7 @@ adler32_1(BIF_ALIST_1) res_sum = erts_make_integer(chksum,BIF_P); if (rest != NIL) { BUMP_ALL_REDS(BIF_P); - BIF_TRAP2(bif_export[BIF_adler32_2], BIF_P, res_sum, rest); + BIF_TRAP2(&bif_trap_export[BIF_adler32_2], BIF_P, res_sum, rest); } BIF_RET(res_sum); } @@ -434,7 +434,7 @@ adler32_2(BIF_ALIST_2) res_sum = erts_make_integer(chksum,BIF_P); if (rest != NIL) { BUMP_ALL_REDS(BIF_P); - BIF_TRAP2(bif_export[BIF_adler32_2], BIF_P, res_sum, rest); + BIF_TRAP2(&bif_trap_export[BIF_adler32_2], BIF_P, res_sum, rest); } BIF_RET(res_sum); } @@ -575,7 +575,7 @@ md5_update_2(BIF_ALIST_2) bin = new_binary(BIF_P, (byte *) &context, sizeof(MD5_CTX)); if (rest != NIL) { BUMP_ALL_REDS(BIF_P); - BIF_TRAP2(bif_export[BIF_md5_update_2], BIF_P, bin, rest); + BIF_TRAP2(&bif_trap_export[BIF_md5_update_2], BIF_P, bin, rest); } BUMP_REDS(BIF_P,res); BIF_RET(bin); diff --git a/erts/emulator/beam/erl_bif_guard.c b/erts/emulator/beam/erl_bif_guard.c index 09757e473b..053797bc89 100644 --- a/erts/emulator/beam/erl_bif_guard.c +++ b/erts/emulator/beam/erl_bif_guard.c @@ -239,7 +239,7 @@ static BIF_RETTYPE erlang_length_trap(BIF_ALIST_3) * Signal an error. The original argument was tucked away in BIF_ARG_3. */ ERTS_BIF_ERROR_TRAPPED1(BIF_P, BIF_P->freason, - bif_export[BIF_length_1], BIF_ARG_3); + &bif_trap_export[BIF_length_1], BIF_ARG_3); } } } diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index b51148eb9e..43be78715b 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -158,8 +158,9 @@ static Eterm os_version_tuple; static Eterm current_function(Process* p, ErtsHeapFactory *hfact, Process* rp, int full_info, Uint reserve_size, int flags); -static Eterm current_stacktrace(ErtsHeapFactory *hfact, Process* rp, - Uint reserve_size); +static Eterm +current_stacktrace(Process* p, ErtsHeapFactory *hfact, Process* rp, + Uint reserve_size, int flags); Eterm erts_bld_bin_list(Uint **hpp, Uint *szp, ErlOffHeap* oh, Eterm tail) @@ -1249,9 +1250,9 @@ exited: yield: if (pi2) - ERTS_BIF_PREP_YIELD2(ret, bif_export[BIF_process_info_2], c_p, pid, opt); + ERTS_BIF_PREP_YIELD2(ret, &bif_trap_export[BIF_process_info_2], c_p, pid, opt); else - ERTS_BIF_PREP_YIELD1(ret, bif_export[BIF_process_info_1], c_p, pid); + ERTS_BIF_PREP_YIELD1(ret, &bif_trap_export[BIF_process_info_1], c_p, pid); goto done; send_signal: { @@ -1384,7 +1385,7 @@ process_info_aux(Process *c_p, break; case ERTS_PI_IX_CURRENT_STACKTRACE: - res = current_stacktrace(hfact, rp, reserve_size); + res = current_stacktrace(c_p, hfact, rp, reserve_size, flags); break; case ERTS_PI_IX_INITIAL_CALL: @@ -2022,21 +2023,23 @@ current_function(Process *c_p, ErtsHeapFactory *hfact, Process* rp, } if (c_p == rp && !(flags & ERTS_PI_FLAG_REQUEST_FOR_OTHER)) { - FunctionInfo fi2; - BeamInstr* continuation_ptr; + BeamInstr* return_address; + FunctionInfo caller_fi; - /* - * The current function is erlang:process_info/{1,2}, - * which is not the answer that the application want. - * We will use the continuation pointer stored at the - * top of the stack instead. - */ - continuation_ptr = (BeamInstr *) rp->stop[0]; - erts_lookup_function_info(&fi2, continuation_ptr, full_info); - if (fi2.mfa) { - fi = fi2; - rp->current = fi2.mfa; - } + /* + * The current function is erlang:process_info/{1,2}, and we've + * historically returned the *calling* function in that case. We + * therefore use the continuation pointer stored at the top of the + * stack instead, which is safe since process_info is a "heavy" BIF + * that is only called through its export entry. + */ + return_address = erts_printable_return_address(rp, STACK_TOP(rp)); + + erts_lookup_function_info(&caller_fi, return_address, full_info); + if (caller_fi.mfa) { + fi = caller_fi; + rp->current = caller_fi.mfa; + } } /* @@ -2057,8 +2060,8 @@ current_function(Process *c_p, ErtsHeapFactory *hfact, Process* rp, } static Eterm -current_stacktrace(ErtsHeapFactory *hfact, Process* rp, - Uint reserve_size) +current_stacktrace(Process *p, ErtsHeapFactory *hfact, Process* rp, + Uint reserve_size, int flags) { Uint sz; struct StackTrace* s; @@ -2075,9 +2078,14 @@ current_stacktrace(ErtsHeapFactory *hfact, Process* rp, sz = offsetof(struct StackTrace, trace) + sizeof(BeamInstr *)*depth; s = (struct StackTrace *) erts_alloc(ERTS_ALC_T_TMP, sz); s->depth = 0; - if (depth > 0 && rp->i) { - s->trace[s->depth++] = rp->i; - depth--; + s->pc = NULL; + + /* We skip current pc when requesting our own stack trace since it will + * inevitably point to process_info/1,2 */ + if ((p != rp || (flags & ERTS_PI_FLAG_REQUEST_FOR_OTHER)) && + depth > 0 && rp->i) { + s->trace[s->depth++] = rp->i; + depth--; } erts_save_stacktrace(rp, s, depth); @@ -4588,7 +4596,7 @@ BIF_RETTYPE erts_debug_set_internal_state_2(BIF_ALIST_2) if (!flag && BIF_ARG_2 != am_false) { erts_atomic_set_nob(&hipe_test_reschedule_flag, 1); erts_suspend(BIF_P, ERTS_PROC_LOCK_MAIN, NULL); - ERTS_BIF_YIELD2(bif_export[BIF_erts_debug_set_internal_state_2], + ERTS_BIF_YIELD2(&bif_trap_export[BIF_erts_debug_set_internal_state_2], BIF_P, BIF_ARG_1, BIF_ARG_2); } erts_atomic_set_nob(&hipe_test_reschedule_flag, !flag); diff --git a/erts/emulator/beam/erl_bif_lists.c b/erts/emulator/beam/erl_bif_lists.c index fa2edfef1e..40512a117d 100644 --- a/erts/emulator/beam/erl_bif_lists.c +++ b/erts/emulator/beam/erl_bif_lists.c @@ -32,8 +32,7 @@ #include "bif.h" #include "erl_binary.h" - -static Eterm keyfind(int Bif, Process* p, Eterm Key, Eterm Pos, Eterm List); +static Eterm keyfind(Export* Bif, Process* p, Eterm Key, Eterm Pos, Eterm List); /* erlang:'++'/2 * @@ -308,12 +307,12 @@ static Eterm append(Export *bif_entry, BIF_ALIST_2) { Eterm ebif_plusplus_2(BIF_ALIST_2) { - return append(bif_export[BIF_ebif_plusplus_2], BIF_CALL_ARGS); + return append(&bif_trap_export[BIF_ebif_plusplus_2], BIF_CALL_ARGS); } BIF_RETTYPE append_2(BIF_ALIST_2) { - return append(bif_export[BIF_append_2], BIF_CALL_ARGS); + return append(&bif_trap_export[BIF_append_2], BIF_CALL_ARGS); } /* erlang:'--'/2 @@ -1039,11 +1038,11 @@ static Eterm subtract(Export *bif_entry, BIF_ALIST_2) { } BIF_RETTYPE ebif_minusminus_2(BIF_ALIST_2) { - return subtract(bif_export[BIF_ebif_minusminus_2], BIF_CALL_ARGS); + return subtract(&bif_trap_export[BIF_ebif_minusminus_2], BIF_CALL_ARGS); } BIF_RETTYPE subtract_2(BIF_ALIST_2) { - return subtract(bif_export[BIF_subtract_2], BIF_CALL_ARGS); + return subtract(&bif_trap_export[BIF_subtract_2], BIF_CALL_ARGS); } @@ -1068,7 +1067,7 @@ BIF_RETTYPE lists_member_2(BIF_ALIST_2) while (is_list(list)) { if (--max_iter < 0) { BUMP_ALL_REDS(BIF_P); - BIF_TRAP2(bif_export[BIF_lists_member_2], BIF_P, term, list); + BIF_TRAP2(&bif_trap_export[BIF_lists_member_2], BIF_P, term, list); } item = CAR(list_val(list)); if ((item == term) || (non_immed_key && eq(item, term))) { @@ -1130,7 +1129,7 @@ static BIF_RETTYPE lists_reverse_alloc(Process *c_p, } ASSERT(is_list(tail) && cells_left == 0); - BIF_TRAP2(bif_export[BIF_lists_reverse_2], c_p, list, tail); + BIF_TRAP2(&bif_trap_export[BIF_lists_reverse_2], c_p, list, tail); } static BIF_RETTYPE lists_reverse_onheap(Process *c_p, @@ -1179,7 +1178,7 @@ static BIF_RETTYPE lists_reverse_onheap(Process *c_p, } BUMP_ALL_REDS(c_p); - BIF_TRAP2(bif_export[BIF_lists_reverse_2], c_p, list, tail); + BIF_TRAP2(&bif_trap_export[BIF_lists_reverse_2], c_p, list, tail); } BIF_ERROR(c_p, BADARG); @@ -1209,7 +1208,7 @@ lists_keymember_3(BIF_ALIST_3) { Eterm res; - res = keyfind(BIF_lists_keymember_3, BIF_P, + res = keyfind(&bif_trap_export[BIF_lists_keymember_3], BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3); if (is_value(res) && is_tuple(res)) { return am_true; @@ -1223,7 +1222,7 @@ lists_keysearch_3(BIF_ALIST_3) { Eterm res; - res = keyfind(BIF_lists_keysearch_3, BIF_P, + res = keyfind(&bif_trap_export[BIF_lists_keysearch_3], BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3); if (is_non_value(res) || is_not_tuple(res)) { return res; @@ -1236,12 +1235,12 @@ lists_keysearch_3(BIF_ALIST_3) BIF_RETTYPE lists_keyfind_3(BIF_ALIST_3) { - return keyfind(BIF_lists_keyfind_3, BIF_P, + return keyfind(&bif_trap_export[BIF_lists_keyfind_3], BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3); } static Eterm -keyfind(int Bif, Process* p, Eterm Key, Eterm Pos, Eterm List) +keyfind(Export *Bif, Process* p, Eterm Key, Eterm Pos, Eterm List) { int max_iter = 10 * CONTEXT_REDS; Sint pos; @@ -1257,7 +1256,7 @@ keyfind(int Bif, Process* p, Eterm Key, Eterm Pos, Eterm List) while (is_list(List)) { if (--max_iter < 0) { BUMP_ALL_REDS(p); - BIF_TRAP3(bif_export[Bif], p, Key, Pos, List); + BIF_TRAP3(Bif, p, Key, Pos, List); } term = CAR(list_val(List)); List = CDR(list_val(List)); @@ -1282,7 +1281,7 @@ keyfind(int Bif, Process* p, Eterm Key, Eterm Pos, Eterm List) while (is_list(List)) { if (--max_iter < 0) { BUMP_ALL_REDS(p); - BIF_TRAP3(bif_export[Bif], p, Key, Pos, List); + BIF_TRAP3(Bif, p, Key, Pos, List); } term = CAR(list_val(List)); List = CDR(list_val(List)); @@ -1300,7 +1299,7 @@ keyfind(int Bif, Process* p, Eterm Key, Eterm Pos, Eterm List) while (is_list(List)) { if (--max_iter < 0) { BUMP_ALL_REDS(p); - BIF_TRAP3(bif_export[Bif], p, Key, Pos, List); + BIF_TRAP3(Bif, p, Key, Pos, List); } term = CAR(list_val(List)); List = CDR(list_val(List)); diff --git a/erts/emulator/beam/erl_bif_persistent.c b/erts/emulator/beam/erl_bif_persistent.c index 9dc5c66a0a..d27f35c8ae 100644 --- a/erts/emulator/beam/erl_bif_persistent.c +++ b/erts/emulator/beam/erl_bif_persistent.c @@ -284,7 +284,7 @@ BIF_RETTYPE persistent_term_put_2(BIF_ALIST_2) long iterations_until_trap; long max_iterations; #define PUT_TRAP_CODE \ - BIF_TRAP2(bif_export[BIF_persistent_term_put_2], BIF_P, state_mref, BIF_ARG_2) + BIF_TRAP2(&bif_trap_export[BIF_persistent_term_put_2], BIF_P, state_mref, BIF_ARG_2) #define TRAPPING_COPY_TABLE_PUT(TABLE_DEST, OLD_TABLE, NEW_SIZE, COPY_TYPE, LOC_NAME) \ TRAPPING_COPY_TABLE(TABLE_DEST, OLD_TABLE, NEW_SIZE, COPY_TYPE, LOC_NAME, PUT_TRAP_CODE) @@ -329,7 +329,7 @@ BIF_RETTYPE persistent_term_put_2(BIF_ALIST_2) if (!try_seize_update_permission(BIF_P)) { - ERTS_BIF_YIELD2(bif_export[BIF_persistent_term_put_2], + ERTS_BIF_YIELD2(&bif_trap_export[BIF_persistent_term_put_2], BIF_P, BIF_ARG_1, BIF_ARG_2); } ctx->hash_table = (HashTable *) erts_atomic_read_nob(&the_hash_table); @@ -507,7 +507,7 @@ BIF_RETTYPE persistent_term_erase_1(BIF_ALIST_1) ITERATIONS_PER_RED * ERTS_BIF_REDS_LEFT(BIF_P); #endif #define ERASE_TRAP_CODE \ - BIF_TRAP1(bif_export[BIF_persistent_term_erase_1], BIF_P, state_mref); + BIF_TRAP1(&bif_trap_export[BIF_persistent_term_erase_1], BIF_P, state_mref); #define TRAPPING_COPY_TABLE_ERASE(TABLE_DEST, OLD_TABLE, NEW_SIZE, REHASH, LOC_NAME) \ TRAPPING_COPY_TABLE(TABLE_DEST, OLD_TABLE, NEW_SIZE, REHASH, LOC_NAME, ERASE_TRAP_CODE) if (is_internal_magic_ref(BIF_ARG_1) && @@ -542,7 +542,7 @@ BIF_RETTYPE persistent_term_erase_1(BIF_ALIST_1) ctx->tmp_table = NULL; } if (!try_seize_update_permission(BIF_P)) { - ERTS_BIF_YIELD1(bif_export[BIF_persistent_term_erase_1], + ERTS_BIF_YIELD1(&bif_trap_export[BIF_persistent_term_erase_1], BIF_P, BIF_ARG_1); } @@ -614,7 +614,7 @@ BIF_RETTYPE erts_internal_erase_persistent_terms_0(BIF_ALIST_0) HashTable* new_table; if (!try_seize_update_permission(BIF_P)) { - ERTS_BIF_YIELD0(bif_export[BIF_erts_internal_erase_persistent_terms_0], + ERTS_BIF_YIELD0(&bif_trap_export[BIF_erts_internal_erase_persistent_terms_0], BIF_P); } old_table = (HashTable *) erts_atomic_read_nob(&the_hash_table); diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c index dd1e884705..17e09f835b 100644 --- a/erts/emulator/beam/erl_bif_port.c +++ b/erts/emulator/beam/erl_bif_port.c @@ -211,7 +211,7 @@ BIF_RETTYPE erts_internal_port_command_3(BIF_ALIST_3) ERTS_BIF_PREP_RET(res, am_false); else { erts_suspend(BIF_P, ERTS_PROC_LOCK_MAIN, prt); - ERTS_BIF_PREP_YIELD3(res, bif_export[BIF_erts_internal_port_command_3], + ERTS_BIF_PREP_YIELD3(res, &bif_trap_export[BIF_erts_internal_port_command_3], BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3); } break; diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c index 80ba7d1b3c..46f4ed7ab0 100644 --- a/erts/emulator/beam/erl_bif_trace.c +++ b/erts/emulator/beam/erl_bif_trace.c @@ -80,9 +80,6 @@ static Eterm trace_info_func(Process* p, Eterm pid_spec, Eterm key); static Eterm trace_info_on_load(Process* p, Eterm key); static Eterm trace_info_event(Process* p, Eterm event, Eterm key); - -static void reset_bif_trace(void); -static void setup_bif_trace(void); static void install_exp_breakpoints(BpFunctions* f); static void uninstall_exp_breakpoints(BpFunctions* f); static void clean_export_entries(BpFunctions* f); @@ -133,7 +130,7 @@ trace_pattern(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist) ErtsTracer meta_tracer = erts_tracer_nil; if (!erts_try_seize_code_write_permission(p)) { - ERTS_BIF_YIELD3(bif_export[BIF_erts_internal_trace_pattern_3], p, MFA, Pattern, flaglist); + ERTS_BIF_YIELD3(&bif_trap_export[BIF_erts_internal_trace_pattern_3], p, MFA, Pattern, flaglist); } finish_bp.current = -1; @@ -543,7 +540,7 @@ Eterm erts_internal_trace_3(BIF_ALIST_3) } if (!erts_try_seize_code_write_permission(BIF_P)) { - ERTS_BIF_YIELD3(bif_export[BIF_erts_internal_trace_3], + ERTS_BIF_YIELD3(&bif_trap_export[BIF_erts_internal_trace_3], BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3); } @@ -793,7 +790,7 @@ Eterm trace_info_2(BIF_ALIST_2) Eterm res; if (!erts_try_seize_code_write_permission(p)) { - ERTS_BIF_YIELD2(bif_export[BIF_trace_info_2], p, What, Key); + ERTS_BIF_YIELD2(&bif_trap_export[BIF_trace_info_2], p, What, Key); } if (What == am_on_load) { @@ -1047,14 +1044,13 @@ static int function_is_traced(Process *p, e.info.mfa.function = mfa[1]; e.info.mfa.arity = mfa[2]; if ((ep = export_get(&e)) != NULL) { - pc = ep->beam; + pc = ep->trampoline.raw; if (ep->addressv[erts_active_code_ix()] == pc && ! BeamIsOpCode(*pc, op_call_error_handler)) { int r = 0; - ASSERT(BeamIsOpCode(*pc, op_apply_bif) || - BeamIsOpCode(*pc, op_i_generic_breakpoint)); + ASSERT(BeamIsOpCode(*pc, op_i_generic_breakpoint)); if (erts_is_trace_break(&ep->info, ms, 0)) { return FUNC_TRACE_GLOBAL_TRACE; @@ -1426,18 +1422,21 @@ erts_set_trace_pattern(Process*p, ErtsCodeMFA *mfa, int specified, int n; BpFunction* fp; - /* - * First work on normal functions (not real BIFs). - */ - erts_bp_match_export(&finish_bp.e, mfa, specified); fp = finish_bp.e.matching; n = finish_bp.e.matched; for (i = 0; i < n; i++) { ErtsCodeInfo *ci = fp[i].ci; - BeamInstr* pc = erts_codeinfo_to_code(ci); - Export* ep = ErtsContainerStruct(ci, Export, info); + BeamInstr* pc; + Export* ep; + + pc = erts_codeinfo_to_code(ci); + ep = ErtsContainerStruct(ci, Export, info); + + if (ep->bif_number != -1) { + ep->is_bif_traced = !!on; + } if (on && !flags.breakpoint) { /* Turn on global call tracing */ @@ -1446,12 +1445,12 @@ erts_set_trace_pattern(Process*p, ErtsCodeMFA *mfa, int specified, #ifdef DEBUG ep->info.op = BeamOpCodeAddr(op_i_func_info_IaaI); #endif - ep->beam[0] = BeamOpCodeAddr(op_trace_jump_W); - ep->beam[1] = (BeamInstr) ep->addressv[code_ix]; + ep->trampoline.op = BeamOpCodeAddr(op_trace_jump_W); + ep->trampoline.trace.address = (BeamInstr) ep->addressv[code_ix]; } - erts_set_call_trace_bif(ci, match_prog_set, 0); + erts_set_export_trace(ci, match_prog_set, 0); if (ep->addressv[code_ix] != pc) { - ep->beam[0] = BeamOpCodeAddr(op_i_generic_breakpoint); + ep->trampoline.op = BeamOpCodeAddr(op_i_generic_breakpoint); } } else if (!on && flags.breakpoint) { /* Turn off breakpoint tracing -- nothing to do here. */ @@ -1460,91 +1459,14 @@ erts_set_trace_pattern(Process*p, ErtsCodeMFA *mfa, int specified, * Turn off global tracing, either explicitly or implicitly * before turning on breakpoint tracing. */ - erts_clear_call_trace_bif(ci, 0); - if (BeamIsOpCode(ep->beam[0], op_i_generic_breakpoint)) { - ep->beam[0] = BeamOpCodeAddr(op_trace_jump_W); + erts_clear_export_trace(ci, 0); + if (BeamIsOpCode(ep->trampoline.op, op_i_generic_breakpoint)) { + ep->trampoline.op = BeamOpCodeAddr(op_trace_jump_W); } } } /* - ** OK, now for the bif's - */ - for (i = 0; i < BIF_SIZE; ++i) { - Export *ep = bif_export[i]; - - if (!ExportIsBuiltIn(ep)) { - continue; - } - - if (bif_table[i].f == bif_table[i].traced) { - /* Trace wrapper same as regular function - untraceable */ - continue; - } - - switch (specified) { - case 3: - if (mfa->arity != ep->info.mfa.arity) - continue; - case 2: - if (mfa->function != ep->info.mfa.function) - continue; - case 1: - if (mfa->module != ep->info.mfa.module) - continue; - case 0: - break; - default: - ASSERT(0); - } - - if (! flags.breakpoint) { /* Export entry call trace */ - if (on) { - erts_clear_call_trace_bif(&ep->info, 1); - erts_clear_mtrace_bif(&ep->info); - erts_set_call_trace_bif(&ep->info, match_prog_set, 0); - } else { /* off */ - erts_clear_call_trace_bif(&ep->info, 0); - } - matches++; - } else { /* Breakpoint call trace */ - int m = 0; - - if (on) { - if (flags.local) { - erts_clear_call_trace_bif(&ep->info, 0); - erts_set_call_trace_bif(&ep->info, match_prog_set, 1); - m = 1; - } - if (flags.meta) { - erts_set_mtrace_bif(&ep->info, meta_match_prog_set, - meta_tracer); - m = 1; - } - if (flags.call_time) { - erts_set_time_trace_bif(&ep->info, on); - /* I don't want to remove any other tracers */ - m = 1; - } - } else { /* off */ - if (flags.local) { - erts_clear_call_trace_bif(&ep->info, 1); - m = 1; - } - if (flags.meta) { - erts_clear_mtrace_bif(&ep->info); - m = 1; - } - if (flags.call_time) { - erts_clear_time_trace_bif(&ep->info); - m = 1; - } - } - matches += m; - } - } - - /* ** So, now for breakpoint tracing */ erts_bp_match_functions(&finish_bp.f, mfa, specified); @@ -1670,7 +1592,6 @@ erts_finish_breakpointing(void) install_exp_breakpoints(&finish_bp.e); } } - setup_bif_trace(); return 1; case 1: /* @@ -1699,7 +1620,6 @@ erts_finish_breakpointing(void) uninstall_exp_breakpoints(&finish_bp.e); } } - reset_bif_trace(); return 1; case 3: /* @@ -1710,7 +1630,6 @@ erts_finish_breakpointing(void) * updated). If any breakpoints have been totally disabled, * deallocate the GenericBp structs for them. */ - erts_consolidate_bif_bp_data(); clean_export_entries(&finish_bp.e); erts_consolidate_bp_data(&finish_bp.e, 0); erts_consolidate_bp_data(&finish_bp.f, 1); @@ -1736,7 +1655,7 @@ install_exp_breakpoints(BpFunctions* f) for (i = 0; i < ne; i++) { Export* ep = ErtsContainerStruct(fp[i].ci, Export, info); - ep->addressv[code_ix] = ep->beam; + ep->addressv[code_ix] = ep->trampoline.raw; } } @@ -1751,11 +1670,12 @@ uninstall_exp_breakpoints(BpFunctions* f) for (i = 0; i < ne; i++) { Export* ep = ErtsContainerStruct(fp[i].ci, Export, info); - if (ep->addressv[code_ix] != ep->beam) { - continue; - } - ASSERT(BeamIsOpCode(ep->beam[0], op_trace_jump_W)); - ep->addressv[code_ix] = (BeamInstr *) ep->beam[1]; + if (ep->addressv[code_ix] != ep->trampoline.raw) { + continue; + } + + ASSERT(BeamIsOpCode(ep->trampoline.op, op_trace_jump_W)); + ep->addressv[code_ix] = (BeamInstr *) ep->trampoline.trace.address; } } @@ -1770,48 +1690,14 @@ clean_export_entries(BpFunctions* f) for (i = 0; i < ne; i++) { Export* ep = ErtsContainerStruct(fp[i].ci, Export, info); - if (ep->addressv[code_ix] == ep->beam) { - continue; - } - if (BeamIsOpCode(ep->beam[0], op_trace_jump_W)) { - ep->beam[0] = (BeamInstr) 0; - ep->beam[1] = (BeamInstr) 0; - } - } -} - -static void -setup_bif_trace(void) -{ - int i; - - for (i = 0; i < BIF_SIZE; ++i) { - Export *ep = bif_export[i]; - GenericBp* g = ep->info.u.gen_bp; - if (g) { - if (ExportIsBuiltIn(ep)) { - ASSERT(ep->beam[1]); - ep->beam[1] = (BeamInstr) bif_table[i].traced; - } - } - } -} + if (ep->addressv[code_ix] == ep->trampoline.raw) { + continue; + } -static void -reset_bif_trace(void) -{ - int i; - ErtsBpIndex active = erts_active_bp_ix(); - - for (i = 0; i < BIF_SIZE; ++i) { - Export *ep = bif_export[i]; - GenericBp* g = ep->info.u.gen_bp; - if (g && g->data[active].flags == 0) { - if (ExportIsBuiltIn(ep)) { - ASSERT(ep->beam[1]); - ep->beam[1] = (BeamInstr) bif_table[i].f; - } - } + if (BeamIsOpCode(ep->trampoline.op, op_trace_jump_W)) { + ep->trampoline.op = (BeamInstr) 0; + ep->trampoline.trace.address = (BeamInstr) 0; + } } } diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 285c23ea01..a78e6b53ae 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -75,7 +75,7 @@ static BIF_RETTYPE db_bif_fail(Process* p, Uint freason, { if (freason == TRAP) { if (!bif_exp) - bif_exp = bif_export[bif_ix]; + bif_exp = &bif_trap_export[bif_ix]; p->arity = bif_exp->info.mfa.arity; p->i = (BeamInstr*) bif_exp->addressv[erts_active_code_ix()]; } @@ -2170,7 +2170,7 @@ BIF_RETTYPE ets_internal_delete_all_2(BIF_ALIST_2) tb->common.status |= DB_BUSY; db_unlock(tb, LCK_WRITE); BUMP_ALL_REDS(BIF_P); - BIF_TRAP2(bif_export[BIF_ets_internal_delete_all_2], BIF_P, + BIF_TRAP2(&bif_trap_export[BIF_ets_internal_delete_all_2], BIF_P, BIF_ARG_1, nitems_holder); } else { @@ -3334,7 +3334,7 @@ BIF_RETTYPE ets_info_1(BIF_ALIST_1) BIF_RET(am_undefined); } if (rp == ERTS_PROC_LOCK_BUSY) { - ERTS_BIF_YIELD1(bif_export[BIF_ets_info_1], BIF_P, BIF_ARG_1); + ERTS_BIF_YIELD1(&bif_trap_export[BIF_ets_info_1], BIF_P, BIF_ARG_1); } if ((tb = db_get_table(BIF_P, BIF_ARG_1, DB_INFO, LCK_READ)) == NULL || tb->common.owner != owner) { @@ -3355,10 +3355,10 @@ BIF_RETTYPE ets_info_1(BIF_ALIST_1) db_unlock(tb, LCK_READ); hp = HAlloc(BIF_P, 3); tuple = TUPLE2(hp, res.trap_resume_state, table); - BIF_TRAP1(bif_export[BIF_ets_info_1], BIF_P, tuple); + BIF_TRAP1(&bif_trap_export[BIF_ets_info_1], BIF_P, tuple); } else if (res.type == ERTS_FLXCTR_TRY_AGAIN_AFTER_TRAP) { db_unlock(tb, LCK_READ); - BIF_TRAP1(bif_export[BIF_ets_info_1], BIF_P, table); + BIF_TRAP1(&bif_trap_export[BIF_ets_info_1], BIF_P, table); } else { size = res.result[ERTS_DB_TABLE_NITEMS_COUNTER_ID]; memory = res.result[ERTS_DB_TABLE_MEM_COUNTER_ID]; @@ -3429,10 +3429,10 @@ BIF_RETTYPE ets_info_2(BIF_ALIST_2) erts_flxctr_snapshot(&tb->common.counters, ERTS_ALC_T_DB_TABLE, BIF_P); if (ERTS_FLXCTR_GET_RESULT_AFTER_TRAP == res.type) { db_unlock(tb, LCK_READ); - BIF_TRAP2(bif_export[BIF_ets_info_2], BIF_P, res.trap_resume_state, BIF_ARG_2); + BIF_TRAP2(&bif_trap_export[BIF_ets_info_2], BIF_P, res.trap_resume_state, BIF_ARG_2); } else if (res.type == ERTS_FLXCTR_TRY_AGAIN_AFTER_TRAP) { db_unlock(tb, LCK_READ); - BIF_TRAP2(bif_export[BIF_ets_info_2], BIF_P, BIF_ARG_1, BIF_ARG_2); + BIF_TRAP2(&bif_trap_export[BIF_ets_info_2], BIF_P, BIF_ARG_1, BIF_ARG_2); } else if (BIF_ARG_2 == am_size) { ret = erts_make_integer(res.result[ERTS_DB_TABLE_NITEMS_COUNTER_ID], BIF_P); } else { /* BIF_ARG_2 == am_memory */ @@ -3498,7 +3498,7 @@ BIF_RETTYPE ets_match_spec_run_r_3(BIF_ALIST_3) for (lst = BIF_ARG_1; is_list(lst); lst = CDR(list_val(lst))) { if (++i > CONTEXT_REDS) { BUMP_ALL_REDS(BIF_P); - BIF_TRAP3(bif_export[BIF_ets_match_spec_run_r_3], + BIF_TRAP3(&bif_trap_export[BIF_ets_match_spec_run_r_3], BIF_P,lst,BIF_ARG_2,ret); } res = db_prog_match(BIF_P, BIF_P, diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c index ac1e9beaa5..2bcdb47a54 100644 --- a/erts/emulator/beam/erl_db_hash.c +++ b/erts/emulator/beam/erl_db_hash.c @@ -3328,6 +3328,12 @@ void db_foreach_offheap_hash(DbTable *tbl, int i; int nactive = NACTIVE(tb); + if (nactive > tb->nslots) { + /* Table is being emptied by delete/1 or delete_all_objects/1 */ + ASSERT(!(tb->common.status & (DB_PRIVATE|DB_PROTECTED|DB_PUBLIC))); + nactive = tb->nslots; + } + for (i = 0; i < nactive; i++) { list = BUCKET(tb,i); while(list != 0) { diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index 723b3c5d29..954fe1dcaf 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -1175,7 +1175,7 @@ int db_select_continue_tree_common(Process *p, sc.accum, tptr[7], make_small(sc.got)); - RET_TO_BIF(bif_trap1(bif_export[BIF_ets_select_1], p, continuation), + RET_TO_BIF(bif_trap1(&bif_trap_export[BIF_ets_select_1], p, continuation), DB_ERROR_NONE); #undef RET_TO_BIF @@ -1320,7 +1320,7 @@ int db_select_tree_common(Process *p, DbTable *tb, make_small(sc.got)); /* Don't free mpi.mp, so don't use macro */ - *ret = bif_trap1(bif_export[BIF_ets_select_1], p, continuation); + *ret = bif_trap1(&bif_trap_export[BIF_ets_select_1], p, continuation); return DB_ERROR_NONE; #undef RET_TO_BIF @@ -1728,7 +1728,7 @@ int db_select_chunk_tree_common(Process *p, DbTable *tb, make_small(reverse), make_small(sc.got)); /* Don't let RET_TO_BIF macro free mpi.mp*/ - *ret = bif_trap1(bif_export[BIF_ets_select_1], p, continuation); + *ret = bif_trap1(&bif_trap_export[BIF_ets_select_1], p, continuation); return DB_ERROR_NONE; #undef RET_TO_BIF diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index f387960b08..4a6f204cb5 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -2588,7 +2588,7 @@ setup_rootset(Process *p, Eterm *objv, int nobj, Rootset *rootset) /* * If a NIF or BIF has saved arguments, they need to be added */ - if (erts_setup_nif_export_rootset(p, &roots[n].v, &roots[n].sz)) + if (erts_setup_nfunc_rootset(p, &roots[n].v, &roots[n].sz)) n++; ASSERT(n <= rootset->size); @@ -3236,7 +3236,7 @@ offset_one_rootset(Process *p, Sint offs, char* area, Uint area_size, offset_heap_ptr(objv, nobj, offs, area, area_size); } offset_off_heap(p, offs, area, area_size); - if (erts_setup_nif_export_rootset(p, &v, &sz)) + if (erts_setup_nfunc_rootset(p, &v, &sz)) offset_heap_ptr(v, sz, offs, area, area_size); } diff --git a/erts/emulator/beam/erl_io_queue.c b/erts/emulator/beam/erl_io_queue.c index 2ae5b56b5c..c82d67f893 100644 --- a/erts/emulator/beam/erl_io_queue.c +++ b/erts/emulator/beam/erl_io_queue.c @@ -1078,7 +1078,7 @@ static BIF_RETTYPE iol2v_yield(iol2v_state_t *state) { state = boxed_state; } - ERTS_BIF_YIELD1(bif_export[BIF_iolist_to_iovec_1], + ERTS_BIF_YIELD1(&bif_trap_export[BIF_iolist_to_iovec_1], state->process, state->magic_reference); } diff --git a/erts/emulator/beam/erl_nfunc_sched.c b/erts/emulator/beam/erl_nfunc_sched.c index b2658ef180..8263a6e9b7 100644 --- a/erts/emulator/beam/erl_nfunc_sched.c +++ b/erts/emulator/beam/erl_nfunc_sched.c @@ -30,76 +30,37 @@ #include "erl_nfunc_sched.h" #include "erl_trace.h" -NifExport * -erts_new_proc_nif_export(Process *c_p, int argc) +ErtsNativeFunc * +erts_new_proc_nfunc(Process *c_p, int argc) { + ErtsNativeFunc *nep, *old_nep; size_t size; - int i; - NifExport *nep, *old_nep; - - size = sizeof(NifExport) + (argc-1)*sizeof(Eterm); - nep = erts_alloc(ERTS_ALC_T_NIF_TRAP_EXPORT, size); - for (i = 0; i < ERTS_NUM_CODE_IX; i++) - nep->exp.addressv[i] = &nep->exp.beam[0]; + size = sizeof(ErtsNativeFunc) + (argc-1)*sizeof(Eterm); + nep = erts_alloc(ERTS_ALC_T_NFUNC_TRAP_WRAPPER, size); nep->argc = -1; /* unused marker */ nep->argv_size = argc; - nep->trace = NULL; - old_nep = ERTS_PROC_SET_NIF_TRAP_EXPORT(c_p, nep); + old_nep = ERTS_PROC_SET_NFUNC_TRAP_WRAPPER(c_p, nep); if (old_nep) { - ASSERT(!nep->trace); - erts_free(ERTS_ALC_T_NIF_TRAP_EXPORT, old_nep); + erts_free(ERTS_ALC_T_NFUNC_TRAP_WRAPPER, old_nep); } return nep; } void -erts_destroy_nif_export(Process *p) +erts_destroy_nfunc(Process *p) { - NifExport *nep = ERTS_PROC_SET_NIF_TRAP_EXPORT(p, NULL); + ErtsNativeFunc *nep = ERTS_PROC_SET_NFUNC_TRAP_WRAPPER(p, NULL); if (nep) { if (nep->m) - erts_nif_export_cleanup_nif_mod(nep); - erts_free(ERTS_ALC_T_NIF_TRAP_EXPORT, nep); + erts_nfunc_cleanup_nif_mod(nep); + erts_free(ERTS_ALC_T_NFUNC_TRAP_WRAPPER, nep); } } -void -erts_nif_export_save_trace(Process *c_p, NifExport *nep, int applying, - Export* ep, Uint32 flags, - Uint32 flags_meta, BeamInstr* I, - ErtsTracer meta_tracer) -{ - NifExportTrace *netp; - ASSERT(nep && nep->argc >= 0); - ASSERT(!nep->trace); - netp = erts_alloc(ERTS_ALC_T_NIF_EXP_TRACE, - sizeof(NifExportTrace)); - netp->applying = applying; - netp->ep = ep; - netp->flags = flags; - netp->flags_meta = flags_meta; - netp->I = I; - netp->meta_tracer = NIL; - erts_tracer_update(&netp->meta_tracer, meta_tracer); - nep->trace = netp; -} - -void -erts_nif_export_restore_trace(Process *c_p, Eterm result, NifExport *nep) -{ - NifExportTrace *netp = nep->trace; - nep->trace = NULL; - erts_bif_trace_epilogue(c_p, result, netp->applying, netp->ep, - netp->flags, netp->flags_meta, - netp->I, netp->meta_tracer); - erts_tracer_update(&netp->meta_tracer, NIL); - erts_free(ERTS_ALC_T_NIF_EXP_TRACE, netp); -} - -NifExport * -erts_nif_export_schedule(Process *c_p, Process *dirty_shadow_proc, +ErtsNativeFunc * +erts_nfunc_schedule(Process *c_p, Process *dirty_shadow_proc, ErtsCodeMFA *mfa, BeamInstr *pc, BeamInstr instr, void *dfunc, void *ifunc, @@ -109,7 +70,7 @@ erts_nif_export_schedule(Process *c_p, Process *dirty_shadow_proc, Process *used_proc; ErtsSchedulerData *esdp; Eterm* reg; - NifExport* nep; + ErtsNativeFunc* nep; int i; ERTS_LC_ASSERT(erts_proc_lc_my_proc_locks(c_p) @@ -132,10 +93,10 @@ erts_nif_export_schedule(Process *c_p, Process *dirty_shadow_proc, reg = esdp->x_reg_array; if (mfa) - nep = erts_get_proc_nif_export(c_p, (int) mfa->arity); + nep = erts_get_proc_nfunc(c_p, (int) mfa->arity); else { /* If no mfa, this is not the first schedule... */ - nep = ERTS_PROC_GET_NIF_TRAP_EXPORT(c_p); + nep = ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(c_p); ASSERT(nep && nep->argc >= 0); } @@ -153,9 +114,9 @@ erts_nif_export_schedule(Process *c_p, Process *dirty_shadow_proc, nep->argc = (int) mfa->arity; nep->m = NULL; - ASSERT(!erts_check_nif_export_in_area(c_p, + ASSERT(!erts_check_nfunc_in_area(c_p, (char *) nep, - (sizeof(NifExport) + (sizeof(ErtsNativeFunc) + (sizeof(Eterm) *(nep->argc-1))))); } @@ -165,14 +126,14 @@ erts_nif_export_schedule(Process *c_p, Process *dirty_shadow_proc, reg[i] = argv[i]; } ASSERT(is_atom(mod) && is_atom(func)); - nep->exp.info.mfa.module = mod; - nep->exp.info.mfa.function = func; - nep->exp.info.mfa.arity = (Uint) argc; - nep->exp.beam[0] = (BeamInstr) instr; /* call_nif || apply_bif */ - nep->exp.beam[1] = (BeamInstr) dfunc; + nep->trampoline.info.mfa.module = mod; + nep->trampoline.info.mfa.function = func; + nep->trampoline.info.mfa.arity = (Uint) argc; + nep->trampoline.call_op = (BeamInstr) instr; /* call_bif || call_nif */ + nep->trampoline.dfunc = (BeamInstr) dfunc; nep->func = ifunc; used_proc->arity = argc; used_proc->freason = TRAP; - used_proc->i = (BeamInstr*) nep->exp.addressv[0]; + used_proc->i = (BeamInstr*)&nep->trampoline.call_op; return nep; } diff --git a/erts/emulator/beam/erl_nfunc_sched.h b/erts/emulator/beam/erl_nfunc_sched.h index 5c6486cbb8..4dae242d4f 100644 --- a/erts/emulator/beam/erl_nfunc_sched.h +++ b/erts/emulator/beam/erl_nfunc_sched.h @@ -25,90 +25,78 @@ #include "bif.h" #include "error.h" -typedef struct { - int applying; - Export* ep; - Uint32 flags; - Uint32 flags_meta; - BeamInstr* I; - ErtsTracer meta_tracer; -} NifExportTrace; - /* - * NIF exports need a few more items than the Export struct provides, - * including the erl_module_nif* and a NIF function pointer, so the - * NifExport below adds those. The Export member must be first in the - * struct. A number of values are stored for error handling purposes - * only. + * Native function wrappers are used to schedule native functions on both + * normal and dirty schedulers. + * + * A number of values are only stored for error handling, and the fields + * following `current` can be omitted when a wrapper is statically "scheduled" + * through placement in a function stub. * - * 'argc' is >= 0 when NifExport is in use, and < 0 when not. + * 'argc' is >= 0 when ErtsNativeFunc is in use, and < 0 when not. */ typedef struct { - Export exp; + struct { + ErtsCodeInfo info; + BeamInstr call_op; /* call_bif || call_nif */ + BeamInstr dfunc; + } trampoline; + struct erl_module_nif* m; /* NIF module, or NULL if BIF */ void *func; /* Indirect NIF or BIF to execute (may be unused) */ ErtsCodeMFA *current;/* Current as set when originally called */ - NifExportTrace *trace; /* --- The following is only used on error --- */ BeamInstr *pc; /* Program counter */ ErtsCodeMFA *mfa; /* MFA of original call */ int argc; /* Number of arguments in original call */ int argv_size; /* Allocated size of argv */ Eterm argv[1]; /* Saved arguments from the original call */ -} NifExport; - -NifExport *erts_new_proc_nif_export(Process *c_p, int argc); -void erts_nif_export_save_trace(Process *c_p, NifExport *nep, int applying, - Export* ep, Uint32 flags, - Uint32 flags_meta, BeamInstr* I, - ErtsTracer meta_tracer); -void erts_nif_export_restore_trace(Process *c_p, Eterm result, NifExport *nep); -void erts_destroy_nif_export(Process *p); -NifExport *erts_nif_export_schedule(Process *c_p, Process *dirty_shadow_proc, - ErtsCodeMFA *mfa, BeamInstr *pc, - BeamInstr instr, - void *dfunc, void *ifunc, - Eterm mod, Eterm func, - int argc, const Eterm *argv); -void erts_nif_export_cleanup_nif_mod(NifExport *ep); /* erl_nif.c */ -ERTS_GLB_INLINE NifExport *erts_get_proc_nif_export(Process *c_p, int extra); -ERTS_GLB_INLINE int erts_setup_nif_export_rootset(Process* proc, Eterm** objv, - Uint* nobj); -ERTS_GLB_INLINE int erts_check_nif_export_in_area(Process *p, - char *start, Uint size); -ERTS_GLB_INLINE void erts_nif_export_restore(Process *c_p, NifExport *ep, - Eterm result); -ERTS_GLB_INLINE void erts_nif_export_restore_error(Process* c_p, BeamInstr **pc, - Eterm *reg, ErtsCodeMFA **nif_mfa); -ERTS_GLB_INLINE int erts_nif_export_check_save_trace(Process *c_p, Eterm result, - int applying, Export* ep, - Uint32 flags, - Uint32 flags_meta, BeamInstr* I, - ErtsTracer meta_tracer); +} ErtsNativeFunc; + +ErtsNativeFunc *erts_new_proc_nfunc(Process *c_p, int argc); +void erts_destroy_nfunc(Process *p); +ErtsNativeFunc *erts_nfunc_schedule(Process *c_p, Process *dirty_shadow_proc, + ErtsCodeMFA *mfa, BeamInstr *pc, + BeamInstr instr, + void *dfunc, void *ifunc, + Eterm mod, Eterm func, + int argc, const Eterm *argv); +void erts_nfunc_cleanup_nif_mod(ErtsNativeFunc *ep); /* erl_nif.c */ +ERTS_GLB_INLINE ErtsNativeFunc *erts_get_proc_nfunc(Process *c_p, int extra); +ERTS_GLB_INLINE int erts_setup_nfunc_rootset(Process* proc, Eterm** objv, + Uint* nobj); +ERTS_GLB_INLINE int erts_check_nfunc_in_area(Process *p, + char *start, Uint size); +ERTS_GLB_INLINE void erts_nfunc_restore(Process *c_p, ErtsNativeFunc *ep, + Eterm result); +ERTS_GLB_INLINE void erts_nfunc_restore_error(Process* c_p, + BeamInstr **pc, + Eterm *reg, + ErtsCodeMFA **nif_mfa); ERTS_GLB_INLINE Process *erts_proc_shadow2real(Process *c_p); #if ERTS_GLB_INLINE_INCL_FUNC_DEF -ERTS_GLB_INLINE NifExport * -erts_get_proc_nif_export(Process *c_p, int argc) +ERTS_GLB_INLINE ErtsNativeFunc * +erts_get_proc_nfunc(Process *c_p, int argc) { - NifExport *nep = ERTS_PROC_GET_NIF_TRAP_EXPORT(c_p); + ErtsNativeFunc *nep = ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(c_p); if (!nep || (nep->argc < 0 && nep->argv_size < argc)) - return erts_new_proc_nif_export(c_p, argc); + return erts_new_proc_nfunc(c_p, argc); return nep; } /* * If a process has saved arguments, they need to be part of the GC * rootset. The function below is called from setup_rootset() in - * erl_gc.c. Any exception term saved in the NifExport is also made + * erl_gc.c. Any exception term saved in the ErtsNativeFunc is also made * part of the GC rootset here; it always resides in rootset[0]. */ ERTS_GLB_INLINE int -erts_setup_nif_export_rootset(Process* proc, Eterm** objv, Uint* nobj) +erts_setup_nfunc_rootset(Process* proc, Eterm** objv, Uint* nobj) { - NifExport* ep = (NifExport*) ERTS_PROC_GET_NIF_TRAP_EXPORT(proc); + ErtsNativeFunc* ep = (ErtsNativeFunc*) ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(proc); if (!ep || ep->argc <= 0) return 0; @@ -119,12 +107,12 @@ erts_setup_nif_export_rootset(Process* proc, Eterm** objv, Uint* nobj) } /* - * Check if nif export points into code area... + * Check if native func wrapper points into code area... */ ERTS_GLB_INLINE int -erts_check_nif_export_in_area(Process *p, char *start, Uint size) +erts_check_nfunc_in_area(Process *p, char *start, Uint size) { - NifExport *nep = ERTS_PROC_GET_NIF_TRAP_EXPORT(p); + ErtsNativeFunc *nep = ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(p); if (!nep || nep->argc < 0) return 0; if (ErtsInArea(nep->pc, start, size)) @@ -137,7 +125,7 @@ erts_check_nif_export_in_area(Process *p, char *start, Uint size) } ERTS_GLB_INLINE void -erts_nif_export_restore(Process *c_p, NifExport *ep, Eterm result) +erts_nfunc_restore(Process *c_p, ErtsNativeFunc *ep, Eterm result) { ASSERT(!ERTS_SCHEDULER_IS_DIRTY(erts_get_scheduler_data())); ERTS_LC_ASSERT(!(c_p->static_flags @@ -147,15 +135,13 @@ erts_nif_export_restore(Process *c_p, NifExport *ep, Eterm result) c_p->current = ep->current; ep->argc = -1; /* Unused nif-export marker... */ - if (ep->trace) - erts_nif_export_restore_trace(c_p, result, ep); } ERTS_GLB_INLINE void -erts_nif_export_restore_error(Process* c_p, BeamInstr **pc, +erts_nfunc_restore_error(Process* c_p, BeamInstr **pc, Eterm *reg, ErtsCodeMFA **nif_mfa) { - NifExport *nep = (NifExport *) ERTS_PROC_GET_NIF_TRAP_EXPORT(c_p); + ErtsNativeFunc *nep = (ErtsNativeFunc *) ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(c_p); int ix; ASSERT(nep); @@ -163,26 +149,7 @@ erts_nif_export_restore_error(Process* c_p, BeamInstr **pc, *nif_mfa = nep->mfa; for (ix = 0; ix < nep->argc; ix++) reg[ix] = nep->argv[ix]; - erts_nif_export_restore(c_p, nep, THE_NON_VALUE); -} - -ERTS_GLB_INLINE int -erts_nif_export_check_save_trace(Process *c_p, Eterm result, - int applying, Export* ep, - Uint32 flags, - Uint32 flags_meta, BeamInstr* I, - ErtsTracer meta_tracer) -{ - if (is_non_value(result) && c_p->freason == TRAP) { - NifExport *nep = ERTS_PROC_GET_NIF_TRAP_EXPORT(c_p); - if (nep && nep->argc >= 0) { - erts_nif_export_save_trace(c_p, nep, applying, ep, - flags, flags_meta, - I, meta_tracer); - return 1; - } - } - return 0; + erts_nfunc_restore(c_p, nep, THE_NON_VALUE); } ERTS_GLB_INLINE Process * @@ -205,10 +172,10 @@ erts_proc_shadow2real(Process *c_p) #if defined(ERTS_WANT_NFUNC_SCHED_INTERNALS__) && !defined(ERTS_NFUNC_SCHED_INTERNALS__) #define ERTS_NFUNC_SCHED_INTERNALS__ -#define ERTS_I_BEAM_OP_TO_NIF_EXPORT(I) \ - (ASSERT(BeamIsOpCode(*(I), op_apply_bif) || \ - BeamIsOpCode(*(I), op_call_nif)), \ - ((NifExport *) (((char *) (I)) - offsetof(NifExport, exp.beam[0])))) +#define ERTS_I_BEAM_OP_TO_NFUNC(I) \ + (ASSERT(BeamIsOpCode(*(I), op_call_bif_W) || \ + BeamIsOpCode(*(I), op_call_nif_WWW)), \ + ((ErtsNativeFunc *) (((char *) (I)) - offsetof(ErtsNativeFunc, trampoline.call_op)))) #include "erl_message.h" diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 46f7e864fd..6e27b4b7cb 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -309,10 +309,10 @@ void erts_post_nif(ErlNifEnv* env) /* - * Initialize a NifExport struct. Create it if needed and store it in the + * Initialize a ErtsNativeFunc struct. Create it if needed and store it in the * proc. The direct_fp function is what will be invoked by op_call_nif, and * the indirect_fp function, if not NULL, is what the direct_fp function - * will call. If the allocated NifExport isn't enough to hold all of argv, + * will call. If the allocated ErtsNativeFunc isn't enough to hold all of argv, * allocate a larger one. Save 'current' and registers if first time this * call is scheduled. */ @@ -321,7 +321,7 @@ static ERTS_INLINE ERL_NIF_TERM schedule(ErlNifEnv* env, NativeFunPtr direct_fp, NativeFunPtr indirect_fp, Eterm mod, Eterm func_name, int argc, const ERL_NIF_TERM argv[]) { - NifExport *ep; + ErtsNativeFunc *ep; Process *c_p, *dirty_shadow_proc; execution_state(env, &c_p, NULL); @@ -332,10 +332,10 @@ schedule(ErlNifEnv* env, NativeFunPtr direct_fp, NativeFunPtr indirect_fp, ERTS_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(c_p)); - ep = erts_nif_export_schedule(c_p, dirty_shadow_proc, + ep = erts_nfunc_schedule(c_p, dirty_shadow_proc, c_p->current, cp_val(c_p->stop[0]), - BeamOpCodeAddr(op_call_nif), + BeamOpCodeAddr(op_call_nif_WWW), direct_fp, indirect_fp, mod, func_name, argc, (const Eterm *) argv); @@ -356,7 +356,7 @@ erts_call_dirty_nif(ErtsSchedulerData *esdp, Process *c_p, BeamInstr *I, Eterm * { int exiting; ERL_NIF_TERM *argv = (ERL_NIF_TERM *) reg; - NifExport *nep = ERTS_I_BEAM_OP_TO_NIF_EXPORT(I); + ErtsNativeFunc *nep = ERTS_I_BEAM_OP_TO_NFUNC(I); ErtsCodeMFA *codemfa = erts_code_to_codemfa(I); NativeFunPtr dirty_nif = (NativeFunPtr) I[1]; ErlNifEnv env; @@ -364,7 +364,7 @@ erts_call_dirty_nif(ErtsSchedulerData *esdp, Process *c_p, BeamInstr *I, Eterm * #ifdef DEBUG erts_aint32_t state = erts_atomic32_read_nob(&c_p->state); - ASSERT(nep == ERTS_PROC_GET_NIF_TRAP_EXPORT(c_p)); + ASSERT(nep == ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(c_p)); ASSERT(!c_p->scheduler_data); ASSERT((state & ERTS_PSFLG_DIRTY_RUNNING) @@ -2823,7 +2823,7 @@ int enif_consume_timeslice(ErlNifEnv* env, int percent) } static ERTS_INLINE void -nif_export_cleanup_nif_mod(NifExport *ep) +nfunc_cleanup_nif_mod(ErtsNativeFunc *ep) { if (erts_refc_dectest(&ep->m->rt_dtor_cnt, 0) == 0 && ep->m->mod == NULL) close_lib(ep->m); @@ -2831,17 +2831,17 @@ nif_export_cleanup_nif_mod(NifExport *ep) } void -erts_nif_export_cleanup_nif_mod(NifExport *ep) +erts_nfunc_cleanup_nif_mod(ErtsNativeFunc *ep) { - nif_export_cleanup_nif_mod(ep); + nfunc_cleanup_nif_mod(ep); } static ERTS_INLINE void -nif_export_restore(Process *c_p, NifExport *ep, Eterm res) +nfunc_restore(Process *c_p, ErtsNativeFunc *ep, Eterm res) { - erts_nif_export_restore(c_p, ep, res); + erts_nfunc_restore(c_p, ep, res); ASSERT(ep->m); - nif_export_cleanup_nif_mod(ep); + nfunc_cleanup_nif_mod(ep); } @@ -2858,15 +2858,15 @@ static ERL_NIF_TERM dirty_nif_finalizer(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { Process* proc; - NifExport* ep; + ErtsNativeFunc* ep; execution_state(env, &proc, NULL); ASSERT(argc == 1); ASSERT(!ERTS_SCHEDULER_IS_DIRTY(erts_proc_sched_data(proc))); - ep = (NifExport*) ERTS_PROC_GET_NIF_TRAP_EXPORT(proc); + ep = (ErtsNativeFunc*) ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(proc); ASSERT(ep); - nif_export_restore(proc, ep, argv[0]); + nfunc_restore(proc, ep, argv[0]); return argv[0]; } @@ -2878,21 +2878,22 @@ dirty_nif_exception(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ERL_NIF_TERM ret; Process* proc; - NifExport* ep; + ErtsNativeFunc* ep; Eterm exception; execution_state(env, &proc, NULL); ASSERT(argc == 1); ASSERT(!ERTS_SCHEDULER_IS_DIRTY(erts_proc_sched_data(proc))); - ep = (NifExport*) ERTS_PROC_GET_NIF_TRAP_EXPORT(proc); + ep = (ErtsNativeFunc*) ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(proc); ASSERT(ep); exception = argv[0]; /* argv overwritten by restore below... */ - nif_export_cleanup_nif_mod(ep); + nfunc_cleanup_nif_mod(ep); ret = enif_raise_exception(env, exception); - /* Restore orig info for error and clear nif export in handle_error() */ - proc->freason |= EXF_RESTORE_NIF; + /* Restore orig info for error and clear native func wrapper in + * handle_error() */ + proc->freason |= EXF_RESTORE_NFUNC; return ret; } @@ -2929,7 +2930,7 @@ static_schedule_dirty_nif(ErlNifEnv* env, erts_aint32_t dirty_psflg, int argc, const ERL_NIF_TERM argv[]) { Process *proc; - NifExport *ep; + ErtsNativeFunc *ep; Eterm mod, func; NativeFunPtr fp; @@ -2939,12 +2940,11 @@ static_schedule_dirty_nif(ErlNifEnv* env, erts_aint32_t dirty_psflg, * Called in order to schedule statically determined * dirty NIF calls... * - * Note that 'current' does not point into a NifExport - * structure; only a structure with similar - * parts (located in code). + * Note that 'current' does not point into a ErtsNativeFunc + * structure; only a structure with similar parts (located in code). */ - ep = ErtsContainerStruct(proc->current, NifExport, exp.info.mfa); + ep = ErtsContainerStruct(proc->current, ErtsNativeFunc, trampoline.info.mfa); mod = proc->current->module; func = proc->current->function; fp = (NativeFunPtr) ep->func; @@ -2983,12 +2983,12 @@ execute_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { Process* proc; NativeFunPtr fp; - NifExport* ep; + ErtsNativeFunc* ep; ERL_NIF_TERM result; execution_state(env, &proc, NULL); - ep = ErtsContainerStruct(proc->current, NifExport, exp.info.mfa); + ep = ErtsContainerStruct(proc->current, ErtsNativeFunc, trampoline.info.mfa); fp = ep->func; ASSERT(ep); ASSERT(!env->exception_thrown); @@ -3001,20 +3001,20 @@ execute_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) result = (*fp)(env, argc, argv); - ASSERT(ep == ERTS_PROC_GET_NIF_TRAP_EXPORT(proc)); + ASSERT(ep == ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(proc)); if (is_value(result) || proc->freason != TRAP) { /* Done (not rescheduled)... */ ASSERT(ep->func == ERTS_DBG_NIF_NOT_SCHED_MARKER); if (!env->exception_thrown) - nif_export_restore(proc, ep, result); + nfunc_restore(proc, ep, result); else { - nif_export_cleanup_nif_mod(ep); + nfunc_cleanup_nif_mod(ep); /* * Restore orig info for error and clear nif * export in handle_error() */ - proc->freason |= EXF_RESTORE_NIF; + proc->freason |= EXF_RESTORE_NFUNC; } } @@ -4117,7 +4117,23 @@ static struct erl_module_nif* create_lib(const ErlNifEntry* src) return lib; }; -BIF_RETTYPE load_nif_2(BIF_ALIST_2) +/* load_nif/2 is implemented as an instruction as it needs to know where it + * was called from, and it's a pain to get that information in a BIF. + * + * This is a small stub that rejects apply(erlang, load_nif, [Path, Args]). */ +BIF_RETTYPE load_nif_2(BIF_ALIST_2) { + if (BIF_P->flags & F_HIPE_MODE) { + BIF_RET(load_nif_error(BIF_P, "notsup", + "Calling load_nif from HiPE compiled modules " + "not supported")); + } + + BIF_RET(load_nif_error(BIF_P, "bad_lib", + "load_nif/2 must be explicitly called from the NIF " + "module. It cannot be called through apply/3.")); +} + +Eterm erts_load_nif(Process *c_p, BeamInstr *I, Eterm filename, Eterm args) { static const char bad_lib[] = "bad_lib"; static const char upgrade[] = "upgrade"; @@ -4139,13 +4155,6 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) struct erl_module_nif* lib = NULL; struct erl_module_instance* this_mi; struct erl_module_instance* prev_mi; - BeamInstr* caller_cp; - - if (BIF_P->flags & F_HIPE_MODE) { - ret = load_nif_error(BIF_P, "notsup", "Calling load_nif from HiPE compiled " - "modules not supported"); - BIF_RET(ret); - } encoding = erts_get_native_filename_encoding(); if (encoding == ERL_FILENAME_WIN_WCHAR) { @@ -4153,30 +4162,19 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) /* since lib_name is used in error messages */ encoding = ERL_FILENAME_UTF8; } - lib_name = erts_convert_filename_to_encoding(BIF_ARG_1, NULL, 0, + lib_name = erts_convert_filename_to_encoding(filename, NULL, 0, ERTS_ALC_T_TMP, 1, 0, encoding, NULL, 0); if (!lib_name) { - BIF_ERROR(BIF_P, BADARG); - } - - if (!erts_try_seize_code_write_permission(BIF_P)) { - erts_free(ERTS_ALC_T_TMP, lib_name); - ERTS_BIF_YIELD2(bif_export[BIF_load_nif_2], - BIF_P, BIF_ARG_1, BIF_ARG_2); + return THE_NON_VALUE; } /* Block system (is this the right place to do it?) */ - erts_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); + erts_proc_unlock(c_p, ERTS_PROC_LOCK_MAIN); erts_thr_progress_block(); /* Find calling module */ - ASSERT(BIF_P->current != NULL); - ASSERT(BIF_P->current->module == am_erlang - && BIF_P->current->function == am_load_nif - && BIF_P->current->arity == 2); - caller_cp = cp_val(BIF_P->stop[0]); - caller = find_function_from_pc(caller_cp); + caller = find_function_from_pc(I); ASSERT(caller != NULL); mod_atom = caller->module; ASSERT(is_atom(mod_atom)); @@ -4196,7 +4194,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) this_mi = &module_p->curr; prev_mi = &module_p->old; if (in_area(caller, module_p->old.code_hdr, module_p->old.code_length)) { - ret = load_nif_error(BIF_P, "old_code", "Calling load_nif from old " + ret = load_nif_error(c_p, "old_code", "Calling load_nif from old " "module '%T' not allowed", mod_atom); goto error; } else if (module_p->on_load) { @@ -4210,52 +4208,52 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) } if (this_mi->nif != NULL) { - ret = load_nif_error(BIF_P,"reload","NIF library already loaded" + ret = load_nif_error(c_p,"reload","NIF library already loaded" " (reload disallowed since OTP 20)."); } else if (init_func == NULL && (err=erts_sys_ddll_open(lib_name, &handle, &errdesc)) != ERL_DE_NO_ERROR) { const char slogan[] = "Failed to load NIF library"; if (strstr(errdesc.str, lib_name) != NULL) { - ret = load_nif_error(BIF_P, "load_failed", "%s: '%s'", slogan, errdesc.str); + ret = load_nif_error(c_p, "load_failed", "%s: '%s'", slogan, errdesc.str); } else { - ret = load_nif_error(BIF_P, "load_failed", "%s %s: '%s'", slogan, lib_name, errdesc.str); + ret = load_nif_error(c_p, "load_failed", "%s %s: '%s'", slogan, lib_name, errdesc.str); } } else if (init_func == NULL && erts_sys_ddll_load_nif_init(handle, &init_func, &errdesc) != ERL_DE_NO_ERROR) { - ret = load_nif_error(BIF_P, bad_lib, "Failed to find library init" + ret = load_nif_error(c_p, bad_lib, "Failed to find library init" " function: '%s'", errdesc.str); } else if ((taint ? erts_add_taint(mod_atom) : 0, (entry = erts_sys_ddll_call_nif_init(init_func)) == NULL)) { - ret = load_nif_error(BIF_P, bad_lib, "Library init-call unsuccessful"); + ret = load_nif_error(c_p, bad_lib, "Library init-call unsuccessful"); } else if (entry->major > ERL_NIF_MAJOR_VERSION || (entry->major == ERL_NIF_MAJOR_VERSION && entry->minor > ERL_NIF_MINOR_VERSION)) { char* fmt = "That '%T' NIF library needs %s or newer. Either try to" " recompile the NIF lib or use a newer erts runtime."; - ret = load_nif_error(BIF_P, bad_lib, fmt, mod_atom, entry->min_erts); + ret = load_nif_error(c_p, bad_lib, fmt, mod_atom, entry->min_erts); } else if (entry->major < ERL_NIF_MIN_REQUIRED_MAJOR_VERSION_ON_LOAD || (entry->major==2 && entry->minor == 5)) { /* experimental maps */ char* fmt = "That old NIF library (%d.%d) is not compatible with this " "erts runtime (%d.%d). Try recompile the NIF lib."; - ret = load_nif_error(BIF_P, bad_lib, fmt, entry->major, entry->minor, + ret = load_nif_error(c_p, bad_lib, fmt, entry->major, entry->minor, ERL_NIF_MAJOR_VERSION, ERL_NIF_MINOR_VERSION); } else if (AT_LEAST_VERSION(entry, 2, 1) && sys_strcmp(entry->vm_variant, ERL_NIF_VM_VARIANT) != 0) { - ret = load_nif_error(BIF_P, bad_lib, "Library (%s) not compiled for " + ret = load_nif_error(c_p, bad_lib, "Library (%s) not compiled for " "this vm variant (%s).", entry->vm_variant, ERL_NIF_VM_VARIANT); } else if (!erts_is_atom_str((char*)entry->name, mod_atom, 1)) { - ret = load_nif_error(BIF_P, bad_lib, "Library module name '%s' does not" + ret = load_nif_error(c_p, bad_lib, "Library module name '%s' does not" " match calling module '%T'", entry->name, mod_atom); } else { @@ -4274,7 +4272,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom, ERTS_ATOM_ENC_LATIN1) || (ci_pp = get_func_pp(this_mi->code_hdr, f_atom, f->arity))==NULL) { - ret = load_nif_error(BIF_P,bad_lib,"Function not found %T:%s/%u", + ret = load_nif_error(c_p,bad_lib,"Function not found %T:%s/%u", mod_atom, f->name, f->arity); } else if (f->flags) { @@ -4286,16 +4284,13 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) * a load error. */ if (f->flags != ERL_NIF_DIRTY_JOB_IO_BOUND && f->flags != ERL_NIF_DIRTY_JOB_CPU_BOUND) - ret = load_nif_error(BIF_P, bad_lib, "Illegal flags field value %d for NIF %T:%s/%u", + ret = load_nif_error(c_p, bad_lib, "Illegal flags field value %d for NIF %T:%s/%u", f->flags, mod_atom, f->name, f->arity); } - else if (erts_codeinfo_to_code(ci_pp[1]) - erts_codeinfo_to_code(ci_pp[0]) - < BEAM_NIF_MIN_FUNC_SZ) - { - ret = load_nif_error(BIF_P,bad_lib,"No explicit call to load_nif" - " in module (%T:%s/%u too small)", - mod_atom, f->name, f->arity); - } + + ASSERT(erts_codeinfo_to_code(ci_pp[1]) - erts_codeinfo_to_code(ci_pp[0]) + >= BEAM_NATIVE_MIN_FUNC_SZ); + /*erts_fprintf(stderr, "Found NIF %T:%s/%u\r\n", mod_atom, f->name, f->arity);*/ } @@ -4314,23 +4309,23 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) if (prev_mi->nif != NULL) { /**************** Upgrade ***************/ void* prev_old_data = prev_mi->nif->priv_data; if (entry->upgrade == NULL) { - ret = load_nif_error(BIF_P, upgrade, "Upgrade not supported by this NIF library."); + ret = load_nif_error(c_p, upgrade, "Upgrade not supported by this NIF library."); goto error; } - erts_pre_nif(&env, BIF_P, lib, NULL); - veto = entry->upgrade(&env, &lib->priv_data, &prev_mi->nif->priv_data, BIF_ARG_2); + erts_pre_nif(&env, c_p, lib, NULL); + veto = entry->upgrade(&env, &lib->priv_data, &prev_mi->nif->priv_data, args); erts_post_nif(&env); if (veto) { prev_mi->nif->priv_data = prev_old_data; - ret = load_nif_error(BIF_P, upgrade, "Library upgrade-call unsuccessful (%d).", veto); + ret = load_nif_error(c_p, upgrade, "Library upgrade-call unsuccessful (%d).", veto); } } else if (entry->load != NULL) { /********* Initial load ***********/ - erts_pre_nif(&env, BIF_P, lib, NULL); - veto = entry->load(&env, &lib->priv_data, BIF_ARG_2); + erts_pre_nif(&env, c_p, lib, NULL); + veto = entry->load(&env, &lib->priv_data, args); erts_post_nif(&env); if (veto) { - ret = load_nif_error(BIF_P, "load", "Library load-call unsuccessful (%d).", veto); + ret = load_nif_error(c_p, "load", "Library load-call unsuccessful (%d).", veto); } } if (ret == am_ok) { @@ -4352,12 +4347,12 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) code_ptr = erts_codeinfo_to_code(ci); if (ci->u.gen_bp == NULL) { - code_ptr[0] = BeamOpCodeAddr(op_call_nif); + code_ptr[0] = BeamOpCodeAddr(op_call_nif_WWW); } else { /* Function traced, patch the original instruction word */ GenericBp* g = ci->u.gen_bp; ASSERT(BeamIsOpCode(code_ptr[0], op_i_generic_breakpoint)); - g->orig_instr = BeamOpCodeAddr(op_call_nif); + g->orig_instr = BeamOpCodeAddr(op_call_nif_WWW); } if (f->flags) { code_ptr[3] = (BeamInstr) f->fptr; @@ -4384,8 +4379,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) } erts_thr_progress_unblock(); - erts_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); - erts_release_code_write_permission(); + erts_proc_lock(c_p, ERTS_PROC_LOCK_MAIN); erts_free(ERTS_ALC_T_TMP, lib_name); BIF_RET(ret); diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index a247258eff..479a4c6f9a 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -708,10 +708,10 @@ erts_pre_init_process(void) erts_psd_required_locks[ERTS_PSD_DELAYED_GC_TASK_QS].set_locks = ERTS_PSD_DELAYED_GC_TASK_QS_SET_LOCKS; - erts_psd_required_locks[ERTS_PSD_NIF_TRAP_EXPORT].get_locks - = ERTS_PSD_NIF_TRAP_EXPORT_GET_LOCKS; - erts_psd_required_locks[ERTS_PSD_NIF_TRAP_EXPORT].set_locks - = ERTS_PSD_NIF_TRAP_EXPORT_SET_LOCKS; + erts_psd_required_locks[ERTS_PSD_NFUNC_TRAP_WRAPPER].get_locks + = ERTS_PSD_NFUNC_TRAP_WRAPPER_GET_LOCKS; + erts_psd_required_locks[ERTS_PSD_NFUNC_TRAP_WRAPPER].set_locks + = ERTS_PSD_NFUNC_TRAP_WRAPPER_SET_LOCKS; erts_psd_required_locks[ERTS_PSD_ETS_OWNED_TABLES].get_locks = ERTS_PSD_ETS_OWNED_TABLES_GET_LOCKS; @@ -6478,8 +6478,8 @@ schedule_out_process(ErtsRunQueue *c_rq, erts_aint32_t state, Process *p, ASSERT(!(state & (ERTS_PSFLG_DIRTY_IO_PROC |ERTS_PSFLG_DIRTY_CPU_PROC)) - || (BeamIsOpCode(*p->i, op_call_nif) - || BeamIsOpCode(*p->i, op_apply_bif))); + || (BeamIsOpCode(*p->i, op_call_nif_WWW) + || BeamIsOpCode(*p->i, op_call_bif_W))); a = state; @@ -11976,7 +11976,7 @@ delete_process(Process* p) if (pbt) erts_free(ERTS_ALC_T_BPD, (void *) pbt); - erts_destroy_nif_export(p); + erts_destroy_nfunc(p); /* Cleanup psd */ @@ -12118,6 +12118,7 @@ erts_proc_exit_handle_dist_monitor(ErtsMonitor *mon, void *vctxt, Sint reds) ASSERT(c_p->flags & F_DISABLE_GC); ASSERT(erts_monitor_is_target(mon) && mon->type == ERTS_MON_TYPE_DIST_PROC); ASSERT(ctxt->dist_state == NIL); + ASSERT(!ctxt->yield); mdp = erts_monitor_to_data(mon); @@ -12164,10 +12165,12 @@ erts_proc_exit_handle_dist_monitor(ErtsMonitor *mon, void *vctxt, Sint reds) switch (code) { case ERTS_DSIG_SEND_YIELD: reds_consumed = reds; /* force yield */ + ctxt->yield = 1; break; case ERTS_DSIG_SEND_CONTINUE: ctxt->dist_state = erts_dsend_export_trap_context(c_p, &ctx); reds_consumed = reds; /* force yield */ + ctxt->yield = 1; break; case ERTS_DSIG_SEND_OK: break; @@ -12379,6 +12382,7 @@ erts_proc_exit_handle_dist_link(ErtsLink *lnk, void *vctxt, Sint reds) ASSERT(c_p->flags & F_DISABLE_GC); ASSERT(lnk->type == ERTS_LNK_TYPE_DIST_PROC); ASSERT(ctxt->dist_state == NIL); + ASSERT(!ctxt->yield); dlnk = erts_link_to_other(lnk, &ldp); dist = ((ErtsLinkDataExtended *) ldp)->dist; @@ -12418,10 +12422,12 @@ erts_proc_exit_handle_dist_link(ErtsLink *lnk, void *vctxt, Sint reds) switch (code) { case ERTS_DSIG_SEND_YIELD: reds_consumed = reds; /* force yield */ + ctxt->yield = 1; break; case ERTS_DSIG_SEND_CONTINUE: ctxt->dist_state = erts_dsend_export_trap_context(c_p, &ctx); reds_consumed = reds; /* force yield */ + ctxt->yield = 1; break; case ERTS_DSIG_SEND_OK: break; @@ -12844,6 +12850,7 @@ restart: trap_state->pectxt.dist_links = NULL; trap_state->pectxt.dist_monitors = NULL; trap_state->pectxt.dist_state = NIL; + trap_state->pectxt.yield = 0; erts_proc_lock(p, ERTS_PROC_LOCK_MSGQ); @@ -12946,7 +12953,7 @@ restart: (void *) &trap_state->pectxt, &trap_state->yield_state, reds); - if (reds <= 0 || is_not_nil(trap_state->pectxt.dist_state)) + if (reds <= 0 || trap_state->pectxt.yield) goto yield; trap_state->phase = ERTS_CONTINUE_EXIT_DIST_MONITORS; } @@ -12961,7 +12968,7 @@ restart: (void *) &trap_state->pectxt, &trap_state->yield_state, reds); - if (reds <= 0 || is_not_nil(trap_state->pectxt.dist_state)) + if (reds <= 0 || trap_state->pectxt.yield) goto yield; trap_state->phase = ERTS_CONTINUE_EXIT_DONE; @@ -13046,6 +13053,7 @@ restart: sys_memcpy(trap_state, &static_state, sizeof(*trap_state)); p->u.terminate = trap_state; } + trap_state->pectxt.yield = 0; ASSERT(p->scheduler_data); ASSERT(p->scheduler_data->current_process == p); @@ -13461,7 +13469,7 @@ static void print_current_process_info(fmtfn_t to, void *to_arg, * * A BIF that calls this should make sure to schedule out to never come back: * erts_halt(code); - * ERTS_BIF_YIELD1(bif_export[BIF_erlang_halt_1], BIF_P, NIL); + * ERTS_BIF_YIELD1(&bif_trap_export[BIF_erlang_halt_1], BIF_P, NIL); */ void erts_halt(int code) { diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index a50d9efb89..09a6c0e961 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -812,7 +812,7 @@ erts_reset_max_len(ErtsRunQueue *rq, ErtsRunQueueInfo *rqi) #define ERTS_PSD_SCHED_ID 2 #define ERTS_PSD_CALL_TIME_BP 3 #define ERTS_PSD_DELAYED_GC_TASK_QS 4 -#define ERTS_PSD_NIF_TRAP_EXPORT 5 +#define ERTS_PSD_NFUNC_TRAP_WRAPPER 5 #define ERTS_PSD_ETS_OWNED_TABLES 6 #define ERTS_PSD_ETS_FIXED_TABLES 7 #define ERTS_PSD_DIST_ENTRY 8 @@ -849,8 +849,8 @@ typedef struct { #define ERTS_PSD_DELAYED_GC_TASK_QS_GET_LOCKS ERTS_PROC_LOCK_MAIN #define ERTS_PSD_DELAYED_GC_TASK_QS_SET_LOCKS ERTS_PROC_LOCK_MAIN -#define ERTS_PSD_NIF_TRAP_EXPORT_GET_LOCKS ERTS_PROC_LOCK_MAIN -#define ERTS_PSD_NIF_TRAP_EXPORT_SET_LOCKS ERTS_PROC_LOCK_MAIN +#define ERTS_PSD_NFUNC_TRAP_WRAPPER_GET_LOCKS ERTS_PROC_LOCK_MAIN +#define ERTS_PSD_NFUNC_TRAP_WRAPPER_SET_LOCKS ERTS_PROC_LOCK_MAIN #define ERTS_PSD_ETS_OWNED_TABLES_GET_LOCKS ERTS_PROC_LOCK_STATUS #define ERTS_PSD_ETS_OWNED_TABLES_SET_LOCKS ERTS_PROC_LOCK_STATUS @@ -1832,6 +1832,7 @@ typedef struct { ErtsLink *dist_links; ErtsMonitor *dist_monitors; Eterm dist_state; + int yield; } ErtsProcExitContext; int erts_proc_exit_handle_monitor(ErtsMonitor *mon, void *vctxt, Sint reds); int erts_proc_exit_handle_link(ErtsLink *lnk, void *vctxt, Sint reds); @@ -2037,10 +2038,10 @@ erts_psd_set(Process *p, int ix, void *data) #define ERTS_PROC_SET_DELAYED_GC_TASK_QS(P, PBT) \ ((ErtsProcSysTaskQs *) erts_psd_set((P), ERTS_PSD_DELAYED_GC_TASK_QS, (void *) (PBT))) -#define ERTS_PROC_GET_NIF_TRAP_EXPORT(P) \ - erts_psd_get((P), ERTS_PSD_NIF_TRAP_EXPORT) -#define ERTS_PROC_SET_NIF_TRAP_EXPORT(P, NTE) \ - erts_psd_set((P), ERTS_PSD_NIF_TRAP_EXPORT, (void *) (NTE)) +#define ERTS_PROC_GET_NFUNC_TRAP_WRAPPER(P) \ + erts_psd_get((P), ERTS_PSD_NFUNC_TRAP_WRAPPER) +#define ERTS_PROC_SET_NFUNC_TRAP_WRAPPER(P, NTE) \ + erts_psd_set((P), ERTS_PSD_NFUNC_TRAP_WRAPPER, (void *) (NTE)) #define ERTS_PROC_GET_DIST_ENTRY(P) \ ((DistEntry *) erts_psd_get((P), ERTS_PSD_DIST_ENTRY)) diff --git a/erts/emulator/beam/erl_trace.h b/erts/emulator/beam/erl_trace.h index f564549ab9..c0f31e0cb6 100644 --- a/erts/emulator/beam/erl_trace.h +++ b/erts/emulator/beam/erl_trace.h @@ -142,12 +142,6 @@ void monitor_generic(Process *p, Eterm type, Eterm spec); Uint erts_trace_flag2bit(Eterm flag); int erts_trace_flags(Eterm List, Uint *pMask, ErtsTracer *pTracer, int *pCpuTimestamp); -Eterm erts_bif_trace(int bif_index, Process* p, Eterm* args, BeamInstr *I); -Eterm -erts_bif_trace_epilogue(Process *p, Eterm result, int applying, - Export* ep, Uint32 flags, - Uint32 flags_meta, BeamInstr* I, - ErtsTracer meta_tracer); void erts_send_pending_trace_msgs(ErtsSchedulerData *esdp); #define ERTS_CHK_PEND_TRACE_MSGS(ESDP) \ diff --git a/erts/emulator/beam/erlang_dtrace.d b/erts/emulator/beam/erlang_dtrace.d index 8792138d53..8864a8ec84 100644 --- a/erts/emulator/beam/erlang_dtrace.d +++ b/erts/emulator/beam/erlang_dtrace.d @@ -176,7 +176,7 @@ provider erlang { * Fired whenever a user function returns. * * @param p the PID (string form) of the process - * @param mfa the m:f/a of the function + * @param mfa the m:f/a of the function being returned from * @param depth the stack depth */ probe function__return(char *p, char *mfa, int depth); @@ -193,7 +193,7 @@ provider erlang { * Fired whenever a Built In Function returns. * * @param p the PID (string form) of the process - * @param mfa the m:f/a of the function + * @param mfa the m:f/a of the function being returned from */ probe bif__return(char *p, char *mfa); @@ -209,7 +209,7 @@ provider erlang { * Fired whenever a Native Function returns. * * @param p the PID (string form) of the process - * @param mfa the m:f/a of the function + * @param mfa the m:f/a of the function being returned from */ probe nif__return(char *p, char *mfa); diff --git a/erts/emulator/beam/error.h b/erts/emulator/beam/error.h index 64c08b1570..44a9809a18 100644 --- a/erts/emulator/beam/error.h +++ b/erts/emulator/beam/error.h @@ -66,13 +66,13 @@ #define EXF_OFFSET EXTAG_BITS #define EXF_BITS 7 -#define EXF_PANIC (1<<(0+EXF_OFFSET)) /* ignore catches */ -#define EXF_THROWN (1<<(1+EXF_OFFSET)) /* nonlocal return */ -#define EXF_LOG (1<<(2+EXF_OFFSET)) /* write to logger on termination */ -#define EXF_NATIVE (1<<(3+EXF_OFFSET)) /* occurred in native code */ -#define EXF_SAVETRACE (1<<(4+EXF_OFFSET)) /* save stack trace in internal form */ -#define EXF_ARGLIST (1<<(5+EXF_OFFSET)) /* has arglist for top of trace */ -#define EXF_RESTORE_NIF (1<<(6+EXF_OFFSET)) /* restore original bif/nif */ +#define EXF_PANIC (1<<(0+EXF_OFFSET)) /* ignore catches */ +#define EXF_THROWN (1<<(1+EXF_OFFSET)) /* nonlocal return */ +#define EXF_LOG (1<<(2+EXF_OFFSET)) /* write to logger on termination */ +#define EXF_NATIVE (1<<(3+EXF_OFFSET)) /* occurred in native code */ +#define EXF_SAVETRACE (1<<(4+EXF_OFFSET)) /* save stack trace in internal form */ +#define EXF_ARGLIST (1<<(5+EXF_OFFSET)) /* has arglist for top of trace */ +#define EXF_RESTORE_NFUNC (1<<(6+EXF_OFFSET)) /* restore original bif/nif */ #define EXC_FLAGBITS (((1<<(EXF_BITS+EXF_OFFSET))-1) \ & ~((1<<(EXF_OFFSET))-1)) diff --git a/erts/emulator/beam/export.c b/erts/emulator/beam/export.c index b928f03b2f..af1b1c2892 100644 --- a/erts/emulator/beam/export.c +++ b/erts/emulator/beam/export.c @@ -129,14 +129,17 @@ export_alloc(struct export_entry* tmpl_e) obj->info.mfa.module = tmpl->info.mfa.module; obj->info.mfa.function = tmpl->info.mfa.function; obj->info.mfa.arity = tmpl->info.mfa.arity; - obj->beam[0] = 0; + obj->bif_number = -1; + obj->is_bif_traced = 0; + + memset(&obj->trampoline, 0, sizeof(obj->trampoline)); + if (BeamOpsAreInitialized()) { - obj->beam[0] = BeamOpCodeAddr(op_call_error_handler); + obj->trampoline.op = BeamOpCodeAddr(op_call_error_handler); } - obj->beam[1] = 0; for (ix=0; ix<ERTS_NUM_CODE_IX; ix++) { - obj->addressv[ix] = obj->beam; + obj->addressv[ix] = obj->trampoline.raw; blob->entryv[ix].slot.index = -1; blob->entryv[ix].ep = &blob->exp; @@ -204,6 +207,8 @@ static struct export_entry* init_template(struct export_templ* templ, templ->exp.info.mfa.module = m; templ->exp.info.mfa.function = f; templ->exp.info.mfa.arity = a; + templ->exp.bif_number = -1; + templ->exp.is_bif_traced = 0; return &templ->entry; } @@ -253,8 +258,8 @@ erts_find_function(Eterm m, Eterm f, unsigned int a, ErtsCodeIndex code_ix) ee = hash_get(&export_tables[code_ix].htable, init_template(&templ, m, f, a)); if (ee == NULL || - (ee->ep->addressv[code_ix] == ee->ep->beam && - ! BeamIsOpCode(ee->ep->beam[0], op_i_generic_breakpoint))) { + (ee->ep->addressv[code_ix] == ee->ep->trampoline.raw && + ! BeamIsOpCode(ee->ep->trampoline.op, op_i_generic_breakpoint))) { return NULL; } return ee->ep; diff --git a/erts/emulator/beam/export.h b/erts/emulator/beam/export.h index ae8dfa4cf8..91c4844d20 100644 --- a/erts/emulator/beam/export.h +++ b/erts/emulator/beam/export.h @@ -31,24 +31,72 @@ typedef struct export { - void* addressv[ERTS_NUM_CODE_IX]; /* Pointer to code for function. */ - - ErtsCodeInfo info; /* MUST be just before beam[] */ - - /* - * beam[0]: This entry is 0 unless the 'addressv' field points to it. - * Threaded code instruction to load function - * (em_call_error_handler), execute BIF (em_apply_bif), - * or a breakpoint instruction (op_i_generic_breakpoint). - * beam[1]: Function pointer to BIF function (for BIFs only), - * or pointer to threaded code if the module has an - * on_load function that has not been run yet, or pointer - * to code if function beam[0] is a breakpoint instruction. - * Otherwise: 0. - */ - BeamInstr beam[2]; + /* Pointer to code for function. */ + void* addressv[ERTS_NUM_CODE_IX]; + + /* Index into bif_table[], or -1 if not a BIF. */ + int bif_number; + /* Non-zero if this is a BIF that's traced. */ + int is_bif_traced; + + /* This is a small trampoline function that can be used for lazy code + * loading, global call tracing, and so on. It's only valid when + * addressv points to it and should otherwise be left zeroed. + * + * Needless to say, the order of the fields below is significant. */ + ErtsCodeInfo info; + union { + BeamInstr op; /* Union discriminant. */ + + struct { + BeamInstr op; /* op_i_generic_breakpoint */ + BeamInstr address; /* Address of the original function */ + } breakpoint; + + /* This is used when a module refers to (imports) a function that + * hasn't been loaded yet. Upon loading we create an export entry which + * redirects to the error_handler so that the appropriate module will + * be loaded when called (or crash). + * + * This is also used when a module has an on_load callback as we need + * to defer all calls until the callback returns. `deferred` contains + * the address of the original function in this case, and there's an + * awkward condiditon where `deferred` may be set while op is zero. See + * erlang:finish_after_on_load/2 for details. */ + struct { + BeamInstr op; /* op_call_error_handler, or 0 during the last + * phase of code loading when on_load is + * present. See above. */ + BeamInstr deferred; + } not_loaded; + + struct { + BeamInstr op; /* op_trace_jump_W */ + BeamInstr address; /* Address of the traced function */ + } trace; + + BeamInstr raw[2]; /* For use in address comparisons, should not + * be tampered directly. */ + } trampoline; } Export; +#ifdef DEBUG +#define DBG_CHECK_EXPORT(EP, CX) \ + do { \ + if((EP)->addressv[CX] == (EP)->trampoline.raw) { \ + /* The entry currently points at the trampoline, so the + * instructions must be valid. */ \ + ASSERT(((BeamIsOpCode((EP)->trampoline.op, op_i_generic_breakpoint)) && \ + (EP)->trampoline.breakpoint.address != 0) || \ + ((BeamIsOpCode((EP)->trampoline.op, op_trace_jump_W)) && \ + (EP)->trampoline.trace.address != 0) || \ + /* (EP)->trampoline.not_loaded.deferred may be zero. */ \ + (BeamIsOpCode((EP)->trampoline.op, op_call_error_handler))); \ + } \ + } while(0) +#else +#define DBG_CHECK_EXPORT(EP, CX) ((void)(EP), (void)(CX)) +#endif void init_export_table(void); void export_info(fmtfn_t, void *); @@ -71,9 +119,6 @@ extern erts_mtx_t export_staging_lock; #define export_staging_unlock() erts_mtx_unlock(&export_staging_lock) #include "beam_load.h" /* For em_* extern declarations */ -#define ExportIsBuiltIn(EntryPtr) \ -(((EntryPtr)->addressv[erts_active_code_ix()] == (EntryPtr)->beam) && \ - (BeamIsOpCode((EntryPtr)->beam[0], op_apply_bif))) #if ERTS_GLB_INLINE_INCL_FUNC_DEF diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 5cea253ebe..7f24876773 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -1294,10 +1294,10 @@ static BIF_RETTYPE term_to_binary_trap_1(BIF_ALIST_1) } if (Opts == am_undefined) ERTS_BIF_ERROR_TRAPPED1(BIF_P, SYSTEM_LIMIT, - bif_export[BIF_term_to_binary_1], Term); + &bif_trap_export[BIF_term_to_binary_1], Term); else ERTS_BIF_ERROR_TRAPPED2(BIF_P, SYSTEM_LIMIT, - bif_export[BIF_term_to_binary_2], Term, Opts); + &bif_trap_export[BIF_term_to_binary_2], Term, Opts); } if (is_tuple(res)) { ASSERT(BIF_P->flags & F_DISABLE_GC); @@ -1413,7 +1413,7 @@ enum B2TState { /* order is somewhat significant */ }; typedef struct { - int heap_size; + Sint heap_size; int terms; byte* ep; int atom_extra_skip; @@ -1803,8 +1803,8 @@ static BIF_RETTYPE binary_to_term_int(Process* p, Eterm bin, B2TContext *ctx) case B2TBadArg: BUMP_REDS(p, (initial_reds - ctx->reds) / B2T_BYTES_PER_REDUCTION); - ASSERT(ctx->bif == bif_export[BIF_binary_to_term_1] - || ctx->bif == bif_export[BIF_binary_to_term_2]); + ASSERT(ctx->bif == &bif_trap_export[BIF_binary_to_term_1] + || ctx->bif == &bif_trap_export[BIF_binary_to_term_2]); if (is_first_call) ERTS_BIF_PREP_ERROR(ret_val, p, BADARG); @@ -1885,7 +1885,7 @@ BIF_RETTYPE binary_to_term_1(BIF_ALIST_1) ctx.flags = 0; ctx.used_bytes = 0; ctx.trap_bin = THE_NON_VALUE; - ctx.bif = bif_export[BIF_binary_to_term_1]; + ctx.bif = &bif_trap_export[BIF_binary_to_term_1]; ctx.arg[0] = BIF_ARG_1; ctx.arg[1] = THE_NON_VALUE; return binary_to_term_int(BIF_P, BIF_ARG_1, &ctx); @@ -1920,7 +1920,7 @@ BIF_RETTYPE binary_to_term_2(BIF_ALIST_2) goto error; ctx.trap_bin = THE_NON_VALUE; - ctx.bif = bif_export[BIF_binary_to_term_2]; + ctx.bif = &bif_trap_export[BIF_binary_to_term_2]; ctx.arg[0] = BIF_ARG_1; ctx.arg[1] = BIF_ARG_2; return binary_to_term_int(BIF_P, BIF_ARG_1, &ctx); @@ -4536,7 +4536,7 @@ encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, static Sint decoded_size(byte *ep, byte* endp, int internal_tags, B2TContext* ctx) { - int heap_size; + Sint heap_size; int terms; int atom_extra_skip; Uint n; diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 40c65461bc..dd114a98fa 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -122,6 +122,10 @@ void erts_nif_demonitored(ErtsResource* resource); extern void erts_add_taint(Eterm mod_atom); extern Eterm erts_nif_taints(Process* p); extern void erts_print_nif_taints(fmtfn_t to, void* to_arg); + +/* Loads the specified NIF. The caller must have code write permission. */ +Eterm erts_load_nif(Process *c_p, BeamInstr *I, Eterm filename, Eterm args); + void erts_unload_nif(struct erl_module_nif* nif); extern void erl_nif_init(void); extern int erts_nif_get_funcs(struct erl_module_nif*, @@ -885,6 +889,8 @@ void erts_bif_info_init(void); /* bif.c */ +void erts_write_bif_wrapper(Export *export, BeamInstr *address); + void erts_queue_monitor_message(Process *, ErtsProcLocks*, Eterm, @@ -1147,6 +1153,7 @@ void erts_dirty_process_main(ErtsSchedulerData *); Eterm build_stacktrace(Process* c_p, Eterm exc); Eterm expand_error_value(Process* c_p, Uint freason, Eterm Value); void erts_save_stacktrace(Process* p, struct StackTrace* s, int depth); +BeamInstr *erts_printable_return_address(Process* p, Eterm *E) ERTS_NOINLINE; /* erl_init.c */ diff --git a/erts/emulator/beam/instrs.tab b/erts/emulator/beam/instrs.tab index 38b1e5909b..c9291c8cc4 100644 --- a/erts/emulator/beam/instrs.tab +++ b/erts/emulator/beam/instrs.tab @@ -120,7 +120,7 @@ dealloc_ret.execute() { E = ADD_BYTE_OFFSET(E, num_bytes); $RETURN(); CHECK_TERM(x(0)); - DispatchReturn; + $DISPATCH_RETURN(); } move_deallocate_return(Src, Deallocate) { @@ -135,33 +135,22 @@ move_deallocate_return(Src, Deallocate) { Eterm src = $Src; E = ADD_BYTE_OFFSET(E, bytes_to_pop); x(0) = src; + DTRACE_RETURN_FROM_PC(c_p, I); $RETURN(); CHECK_TERM(x(0)); - DispatchReturn; + $DISPATCH_RETURN(); } // Call instructions -DISPATCH_REL(CallDest) { - //| -no_next - $SET_I_REL($CallDest); - DTRACE_LOCAL_CALL(c_p, erts_code_to_codemfa(I)); - Dispatch(); -} - -DISPATCH_ABS(CallDest) { - //| -no_next - SET_I((BeamInstr *) $CallDest); - DTRACE_LOCAL_CALL(c_p, erts_code_to_codemfa(I)); - Dispatch(); -} - i_call(CallDest) { + //| -no_next $SAVE_CONTINUATION_POINTER($NEXT_INSTRUCTION); $DISPATCH_REL($CallDest); } move_call(Src, CallDest) { + //| -no_next Eterm call_dest = $CallDest; Eterm src = $Src; $SAVE_CONTINUATION_POINTER($NEXT_INSTRUCTION); @@ -170,11 +159,13 @@ move_call(Src, CallDest) { } i_call_last(CallDest, Deallocate) { + //| -no_next $deallocate($Deallocate); $DISPATCH_REL($CallDest); } move_call_last(Src, CallDest, Deallocate) { + //| -no_next Eterm call_dest = $CallDest; Eterm src = $Src; $deallocate($Deallocate); @@ -183,59 +174,59 @@ move_call_last(Src, CallDest, Deallocate) { } i_call_only(CallDest) { + //| -no_next $DISPATCH_REL($CallDest); } move_call_only(Src, CallDest) { + //| -no_next Eterm call_dest = $CallDest; Eterm src = $Src; x(0) = src; $DISPATCH_REL(call_dest); } -DISPATCHX(Dest) { - //| -no_next - DTRACE_GLOBAL_CALL_FROM_EXPORT(c_p, $Dest); - // Dispatchx assumes the Export* is in Arg(0) - I = (&$Dest) - 1; - Dispatchx(); -} - i_call_ext(Dest) { + //| -no_next $SAVE_CONTINUATION_POINTER($NEXT_INSTRUCTION); - $DISPATCHX($Dest); + $DISPATCH_EXPORT($Dest); } i_move_call_ext(Src, CallDest) { + //| -no_next Eterm call_dest = $CallDest; Eterm src = $Src; $SAVE_CONTINUATION_POINTER($NEXT_INSTRUCTION); x(0) = src; - $DISPATCHX(call_dest); + $DISPATCH_EXPORT(call_dest); } i_call_ext_only(Dest) { - $DISPATCHX($Dest); + //| -no_next + $DISPATCH_EXPORT($Dest); } i_move_call_ext_only(CallDest, Src) { + //| -no_next Eterm call_dest = $CallDest; Eterm src = $Src; x(0) = src; - $DISPATCHX(call_dest); + $DISPATCH_EXPORT(call_dest); } i_call_ext_last(Dest, Deallocate) { + //| -no_next $deallocate($Deallocate); - $DISPATCHX($Dest); + $DISPATCH_EXPORT($Dest); } i_move_call_ext_last(CallDest, Deallocate, Src) { + //| -no_next Eterm call_dest = $CallDest; Eterm src = $Src; $deallocate($Deallocate); x(0) = src; - $DISPATCHX(call_dest); + $DISPATCH_EXPORT(call_dest); } APPLY(I, Deallocate, Next) { @@ -246,11 +237,12 @@ APPLY(I, Deallocate, Next) { } HANDLE_APPLY_ERROR() { - I = handle_error(c_p, I, reg, &bif_export[BIF_apply_3]->info.mfa); + I = handle_error(c_p, I, reg, &bif_trap_export[BIF_apply_3].info.mfa); goto post_error_handling; } i_apply() { + //| -no_next BeamInstr *next; $APPLY(NULL, 0, next); if (ERTS_LIKELY(next != NULL)) { @@ -261,6 +253,7 @@ i_apply() { } i_apply_last(Deallocate) { + //| -no_next BeamInstr *next; $APPLY(I, $Deallocate, next); if (ERTS_LIKELY(next != NULL)) { @@ -271,6 +264,7 @@ i_apply_last(Deallocate) { } i_apply_only() { + //| -no_next BeamInstr *next; $APPLY(I, 0, next); if (ERTS_LIKELY(next != NULL)) { @@ -287,6 +281,7 @@ FIXED_APPLY(Arity, I, Deallocate, Next) { } apply(Arity) { + //| -no_next BeamInstr *next; $FIXED_APPLY($Arity, NULL, 0, next); if (ERTS_LIKELY(next != NULL)) { @@ -297,6 +292,7 @@ apply(Arity) { } apply_last(Arity, Deallocate) { + //| -no_next BeamInstr *next; $FIXED_APPLY($Arity, I, $Deallocate, next); if (ERTS_LIKELY(next != NULL)) { @@ -316,13 +312,8 @@ HANDLE_APPLY_FUN_ERROR() { goto find_func_info; } -DISPATCH_FUN(I) { - //| -no_next - SET_I($I); - Dispatchfun(); -} - i_apply_fun() { + //| -no_next BeamInstr *next; $APPLY_FUN(next); if (ERTS_LIKELY(next != NULL)) { @@ -333,6 +324,7 @@ i_apply_fun() { } i_apply_fun_last(Deallocate) { + //| -no_next BeamInstr *next; $APPLY_FUN(next); if (ERTS_LIKELY(next != NULL)) { @@ -343,6 +335,7 @@ i_apply_fun_last(Deallocate) { } i_apply_fun_only() { + //| -no_next BeamInstr *next; $APPLY_FUN(next); if (ERTS_LIKELY(next != NULL)) { @@ -359,6 +352,7 @@ CALL_FUN(Fun, Next) { } i_call_fun(Fun) { + //| -no_next BeamInstr *next; $CALL_FUN($Fun, next); if (ERTS_LIKELY(next != NULL)) { @@ -369,6 +363,7 @@ i_call_fun(Fun) { } i_call_fun_last(Fun, Deallocate) { + //| -no_next BeamInstr *next; $CALL_FUN($Fun, next); if (ERTS_LIKELY(next != NULL)) { @@ -380,11 +375,12 @@ i_call_fun_last(Fun, Deallocate) { return() { //| -no_next + DTRACE_RETURN_FROM_PC(c_p, I); $RETURN(); - DTRACE_RETURN_FROM_PC(c_p); CHECK_TERM(r(0)); HEAP_SPACE_VERIFIED(0); - DispatchReturn; + + $DISPATCH_RETURN(); } get_list(Src, Hd, Tl) { @@ -676,8 +672,9 @@ move_window5(S1, S2, S3, S4, S5, D) { move_return(Src) { //| -no_next x(0) = $Src; + DTRACE_RETURN_FROM_PC(c_p, I); $RETURN(); - DispatchReturn; + $DISPATCH_RETURN(); } move_x1(Src) { diff --git a/erts/emulator/beam/macros.tab b/erts/emulator/beam/macros.tab index 9d183e1f41..802c8aec9a 100644 --- a/erts/emulator/beam/macros.tab +++ b/erts/emulator/beam/macros.tab @@ -136,6 +136,90 @@ AH(NeedStack, NeedHeap, Live) { *E = NIL; } + +// +// Helpers for call instructions +// + +DISPATCH() { + BeamInstr dis_next; + + dis_next = *I; + CHECK_ARGS(I); + + if (FCALLS > 0 || FCALLS > neg_o_reds) { + FCALLS--; + Goto(dis_next); + } else { + goto context_switch; + } +} + +DISPATCH_ABS(CallDest) { + SET_I((BeamInstr *) $CallDest); + DTRACE_LOCAL_CALL(c_p, erts_code_to_codemfa(I)); + + $DISPATCH(); +} + +DISPATCH_EXPORT(Export) { + BeamInstr dis_next; + Export *ep; + + ep = (Export*)($Export); + + DTRACE_GLOBAL_CALL_FROM_EXPORT(c_p, ep); + + SET_I(ep->addressv[erts_active_code_ix()]); + CHECK_ARGS(I); + dis_next = *I; + + if (ERTS_UNLIKELY(FCALLS <= 0)) { + if (ERTS_PROC_GET_SAVED_CALLS_BUF(c_p) && FCALLS > neg_o_reds) { + save_calls(c_p, ep); + } else { + goto context_switch; + } + } + + FCALLS--; + Goto(dis_next); +} + +DISPATCH_FUN(I) { + BeamInstr dis_next; + + SET_I($I); + + dis_next = *I; + CHECK_ARGS(I); + + if (FCALLS > 0 || FCALLS > neg_o_reds) { + FCALLS--; + Goto(dis_next); + } else { + goto context_switch_fun; + } +} + +DISPATCH_REL(CallDest) { + $SET_I_REL($CallDest); + DTRACE_LOCAL_CALL(c_p, erts_code_to_codemfa(I)); + + $DISPATCH(); +} + +DISPATCH_RETURN() { + if (FCALLS > 0 || FCALLS > neg_o_reds) { + FCALLS--; + Goto(*I); + } else { + c_p->current = NULL; + c_p->arity = 1; + goto context_switch3; + } +} + // Save the continuation pointer in the reserved slot at the // top of the stack as preparation for doing a function call. @@ -205,7 +289,7 @@ BIF_ERROR_ARITY_1(Fail, BIF, Op1) { } reg[0] = $Op1; SWAPOUT; - I = handle_error(c_p, I, reg, &bif_export[$BIF]->info.mfa); + I = handle_error(c_p, I, reg, &bif_trap_export[$BIF].info.mfa); goto post_error_handling; } @@ -217,6 +301,6 @@ BIF_ERROR_ARITY_2(Fail, BIF, Op1, Op2) { reg[0] = $Op1; reg[1] = $Op2; SWAPOUT; - I = handle_error(c_p, I, reg, &bif_export[$BIF]->info.mfa); + I = handle_error(c_p, I, reg, &bif_trap_export[$BIF].info.mfa); goto post_error_handling; } diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab index c0ca9260a0..1d336e4b7b 100644 --- a/erts/emulator/beam/ops.tab +++ b/erts/emulator/beam/ops.tab @@ -77,19 +77,32 @@ return # To ensure that a "move Src x(0)" instruction can be combined with # the following call instruction, we need to make sure that there is # no line/1 instruction between the move and the call. -# -# A tail-recursive call to an external function (BIF or non-BIF) will -# never be saved on the stack, so there is no reason to keep the line -# instruction. + +move S X0=x==0 | line Loc | call Ar Func => \ + line Loc | move S X0 | call Ar Func move S X0=x==0 | line Loc | call_ext Ar Func => \ line Loc | move S X0 | call_ext Ar Func + +# +# A tail call will not refer to the current function on error unless it's a +# BIF, so we can omit the line instruction for non-BIFs. +# + +move S X0=x==0 | line Loc | call_ext_last Ar Func=u$is_bif D => \ + line Loc | move S X0 | call_ext_last Ar Func D +move S X0=x==0 | line Loc | call_ext_only Ar Func=u$is_bif => \ + line Loc | move S X0 | call_ext_only Ar Func + move S X0=x==0 | line Loc | call_ext_last Ar Func D => \ move S X0 | call_ext_last Ar Func D move S X0=x==0 | line Loc | call_ext_only Ar Func => \ move S X0 | call_ext_only Ar Func -move S X0=x==0 | line Loc | call Ar Func => \ - line Loc | move S X0 | call Ar Func + +move S X0=x==0 | line Loc | call_last Ar Func D => \ + move S X0 | call_last Ar Func D +move S X0=x==0 | line Loc | call_only Ar Func => \ + move S X0 | call_only Ar Func line Loc | func_info M F A => func_info M F A | line Loc @@ -574,8 +587,8 @@ put_list s s d %cold normal_exit continue_exit -apply_bif -call_nif +call_bif W +call_nif W W W call_error_handler error_action_code return_trace @@ -787,62 +800,22 @@ allocate_init t t? y # External function and bif calls. ################################################################# -# -# The BIFs erts_internal:check_process_code/1 must be called like a function, -# to ensure that c_p->i (program counter) is set correctly (an ordinary -# BIF call doesn't set it). -# - -call_ext u==1 Bif=u$bif:erts_internal:check_process_code/1 => i_call_ext Bif -call_ext_last u==1 Bif=u$bif:erts_internal:check_process_code/1 D => i_call_ext_last Bif D -call_ext_only u==1 Bif=u$bif:erts_internal:check_process_code/1 => i_call_ext_only Bif - -# -# The BIFs erts_internal:garbage_collect/1 must be called like a function, -# to allow them to invoke the garbage collector. (The stack pointer must -# be saved and p->arity must be zeroed, which is not done on ordinary BIF calls.) -# -call_ext u==1 Bif=u$bif:erts_internal:garbage_collect/1 => i_call_ext Bif -call_ext_last u==1 Bif=u$bif:erts_internal:garbage_collect/1 D => i_call_ext_last Bif D -call_ext_only u==1 Bif=u$bif:erts_internal:garbage_collect/1 => i_call_ext_only Bif +# Expands into call_light_bif(_only)/2 +call_light_bif/1 +call_light_bif_only/1 +call_light_bif_last/2 # -# put/2 and erase/1 must be able to do garbage collection, so we must call -# them like functions. +# The load_nif/2 BIF is an instruction. # -call_ext u==2 Bif=u$bif:erlang:put/2 => i_call_ext Bif -call_ext_last u==2 Bif=u$bif:erlang:put/2 D => i_call_ext_last Bif D -call_ext_only u==2 Bif=u$bif:erlang:put/2 => i_call_ext_only Bif - -call_ext u==1 Bif=u$bif:erlang:erase/1 => i_call_ext Bif -call_ext_last u==1 Bif=u$bif:erlang:erase/1 D => i_call_ext_last Bif D -call_ext_only u==1 Bif=u$bif:erlang:erase/1 => i_call_ext_only Bif - -# -# The process_info/1,2 BIF should be called like a function, to force -# the emulator to set c_p->current before calling it (a BIF call doesn't -# set it). -# -# In addition, we force the use of a non-tail-recursive call. This will ensure -# that c_p->cp points into the function making the call. -# - -call_ext u==1 Bif=u$bif:erlang:process_info/1 => i_call_ext Bif -call_ext_last u==1 Bif=u$bif:erlang:process_info/1 D => i_call_ext Bif | deallocate_return D -call_ext_only Ar=u==1 Bif=u$bif:erlang:process_info/1 => allocate u Ar | i_call_ext Bif | deallocate_return u - -call_ext u==2 Bif=u$bif:erlang:process_info/2 => i_call_ext Bif -call_ext_last u==2 Bif=u$bif:erlang:process_info/2 D => i_call_ext Bif | deallocate_return D -call_ext_only Ar=u==2 Bif=u$bif:erlang:process_info/2 => allocate u Ar | i_call_ext Bif | deallocate_return u - -# -# load_nif/2 also needs to know calling function like process_info -# -call_ext u==2 Bif=u$bif:erlang:load_nif/2 => i_call_ext Bif -call_ext_last u==2 Bif=u$bif:erlang:load_nif/2 D => i_call_ext Bif | deallocate_return D -call_ext_only Ar=u==2 Bif=u$bif:erlang:load_nif/2 => allocate u Ar | i_call_ext Bif | deallocate_return u +call_ext u==2 u$func:erlang:load_nif/2 => i_load_nif +call_ext_last u==2 u$func:erlang:load_nif/2 D => i_load_nif | deallocate_return D +call_ext_only u==2 u$func:erlang:load_nif/2 => i_load_nif | return +%cold +i_load_nif +%hot # # apply/2 is an instruction, not a BIF. @@ -861,33 +834,6 @@ call_ext_last u==3 u$bif:erlang:apply/3 D => i_apply_last D call_ext_only u==3 u$bif:erlang:apply/3 => i_apply_only # -# The exit/1 and throw/1 BIFs never execute the instruction following them; -# thus there is no need to generate any return instruction. -# - -call_ext_last u==1 Bif=u$bif:erlang:exit/1 D => call_bif Bif -call_ext_last u==1 Bif=u$bif:erlang:throw/1 D => call_bif Bif - -call_ext_only u==1 Bif=u$bif:erlang:exit/1 => call_bif Bif -call_ext_only u==1 Bif=u$bif:erlang:throw/1 => call_bif Bif - -# -# The error/1 and error/2 BIFs never execute the instruction following them; -# thus there is no need to generate any return instruction. -# However, they generate stack backtraces, so if the call instruction -# is call_ext_only/2 instruction, we explicitly do an allocate/2 to store -# the continuation pointer on the stack. -# - -call_ext_last u==1 Bif=u$bif:erlang:error/1 D => call_bif Bif -call_ext_last u==2 Bif=u$bif:erlang:error/2 D => call_bif Bif - -call_ext_only Ar=u==1 Bif=u$bif:erlang:error/1 => \ - allocate u Ar | call_bif Bif -call_ext_only Ar=u==2 Bif=u$bif:erlang:error/2 => \ - allocate u Ar | call_bif Bif - -# # The yield/0 BIF is an instruction # @@ -999,17 +945,24 @@ call_ext_only u==0 u$func:os:perf_counter/0 => \ i_perf_counter | return # -# The general case for BIFs that have no special instructions. -# A BIF used in the tail must be followed by a return instruction. +# BIFs like process_info/1,2 require up-to-date information about the current +# emulator state, which the ordinary call_light_bif instruction doesn't save. # -# To make trapping and stack backtraces work correctly, we make sure that -# the continuation pointer is always stored on the stack. -call_ext u Bif=u$is_bif => call_bif Bif +call_ext u Bif=u$is_bif | is_heavy_bif(Bif) => \ + i_call_ext Bif +call_ext_last u Bif=u$is_bif D | is_heavy_bif(Bif) => \ + i_call_ext Bif | deallocate_return D +call_ext_only Ar=u Bif=u$is_bif | is_heavy_bif(Bif) => \ + allocate u Ar | i_call_ext Bif | deallocate_return u -call_ext_last u Bif=u$is_bif D => deallocate D | call_bif_only Bif +# +# The general case for BIFs that have no special requirements. +# -call_ext_only Ar=u Bif=u$is_bif => call_bif_only Bif +call_ext u Bif=u$is_bif => call_light_bif Bif +call_ext_last u Bif=u$is_bif D => call_light_bif_last Bif D +call_ext_only Ar=u Bif=u$is_bif => call_light_bif_only Bif # # Any remaining calls are calls to Erlang functions, not BIFs. @@ -1034,14 +987,32 @@ i_apply_fun i_apply_fun_last Q i_apply_fun_only +# +# When a BIF is traced, these instructions make a body call through the export +# entry instead of calling the BIF directly (setting up a temporary stack frame +# if needed). We therefore retain the stack frame in call_light_bif_last, and +# add a deallocate_return after call_light_bif_only to remove the temporary +# stack frame before returning. +# + +call_light_bif Bif=u$is_bif => \ + call_light_bif Bif Bif + +call_light_bif_last Bif=u$is_bif D => \ + call_light_bif Bif Bif | deallocate_return D + +call_light_bif_only Bif=u$is_bif => \ + call_light_bif_only Bif Bif | deallocate_return u + +call_light_bif b e +call_light_bif_only b e + %cold -i_hibernate +i_hibernate i_perf_counter -%hot -call_bif e -call_bif_only e +%hot # # Calls to non-building and guard BIFs. diff --git a/erts/emulator/beam/trace_instrs.tab b/erts/emulator/beam/trace_instrs.tab index 9f22587f96..18e48804f7 100644 --- a/erts/emulator/beam/trace_instrs.tab +++ b/erts/emulator/beam/trace_instrs.tab @@ -107,7 +107,7 @@ i_hibernate() { goto do_schedule; } else { HEAVY_SWAPIN; - I = handle_error(c_p, I, reg, &bif_export[BIF_hibernate_3]->info.mfa); + I = handle_error(c_p, I, reg, &bif_trap_export[BIF_hibernate_3].info.mfa); goto post_error_handling; } //| -no_next diff --git a/erts/emulator/hipe/hipe_instrs.tab b/erts/emulator/hipe/hipe_instrs.tab index 62162fcb9c..8aa8544b2a 100644 --- a/erts/emulator/hipe/hipe_instrs.tab +++ b/erts/emulator/hipe/hipe_instrs.tab @@ -93,7 +93,7 @@ hipe_trap.post() { /*fall through*/ case HIPE_MODE_SWITCH_RES_CALL_BEAM: SET_I(c_p->i); - Dispatch(); + $DISPATCH(); case HIPE_MODE_SWITCH_RES_CALL_CLOSURE: /* This can be used to call any function value, but currently it's only used to call closures referring to unloaded @@ -104,8 +104,7 @@ hipe_trap.post() { next = call_fun(c_p, c_p->arity - 1, reg, THE_NON_VALUE); HEAVY_SWAPIN; if (next != NULL) { - SET_I(next); - Dispatchfun(); + $DISPATCH_FUN(next); } goto find_func_info; } diff --git a/erts/emulator/internal_doc/beam_makeops.md b/erts/emulator/internal_doc/beam_makeops.md index 2880099b70..267af78412 100644 --- a/erts/emulator/internal_doc/beam_makeops.md +++ b/erts/emulator/internal_doc/beam_makeops.md @@ -1457,26 +1457,26 @@ all instructions. It expands to the address of the next instruction. Here is an example: i_call(CallDest) { - SET_CP(c_p, $NEXT_INSTRUCTION); + //| -no_next + $SAVE_CONTINUATION_POINTER($NEXT_INSTRUCTION); $DISPATCH_REL($CallDest); } -When calling a function, the return address is first stored in `c_p->cp` -(using the `SET_CP()` macro defined in `beam_emu.c`), and then control is +When calling a function, the return address is first stored in `E[0]` +(using the `$SAVE_CONTINUATION_POINTER()` macro), and then control is transferred to the callee. Here is the generated code: OpCase(i_call_f): { - SET_CP(c_p, I+1); - ASSERT(VALID_INSTR(*(I + (fb(BeamExtraData(I[0]))) + 0))); - I += fb(BeamExtraData(I[0])) + 0;; - DTRACE_LOCAL_CALL(c_p, erts_code_to_codemfa(I)); - Dispatch();; + ASSERT(VALID_INSTR(*(I+2))); + *E = (BeamInstr) (I+2);; + + /* ... dispatch code intentionally left out ... */ } -We can see that that `$NEXT_INSTRUCTION` has been expanded to `I+1`. +We can see that that `$NEXT_INSTRUCTION` has been expanded to `I+2`. That makes sense since the size of the `i_call_f/1` instruction is -one word. +two words. ##### The IP_ADJUSTMENT pre-bound variable ##### diff --git a/erts/emulator/nifs/unix/unix_prim_file.c b/erts/emulator/nifs/unix/unix_prim_file.c index 176a9318b2..e5099dd921 100644 --- a/erts/emulator/nifs/unix/unix_prim_file.c +++ b/erts/emulator/nifs/unix/unix_prim_file.c @@ -566,18 +566,54 @@ int efile_allocate(efile_data_t *d, Sint64 offset, Sint64 length) { } while(ret < 0 && errno == EINTR); #elif defined(F_PREALLOCATE) /* Mac-specific */ + off_t original_position, eof_offset; fstore_t fs = {}; + if(offset < 0 || length < 0 || (offset > ERTS_SINT64_MAX - length)) { + u->common.posix_errno = EINVAL; + return 0; + } + + original_position = lseek(u->fd, 0, SEEK_CUR); + + if(original_position < 0) { + u->common.posix_errno = errno; + return 0; + } + + eof_offset = lseek(u->fd, 0, SEEK_END); + + if(eof_offset < 0 || lseek(u->fd, original_position, SEEK_SET) < 0) { + u->common.posix_errno = errno; + return 0; + } + + if(offset + length <= eof_offset) { + /* File is already large enough. */ + return 1; + } + fs.fst_flags = F_ALLOCATECONTIG; - fs.fst_posmode = F_VOLPOSMODE; - fs.fst_offset = offset; - fs.fst_length = length; + fs.fst_posmode = F_PEOFPOSMODE; + fs.fst_offset = 0; + fs.fst_length = (offset + length) - eof_offset; ret = fcntl(u->fd, F_PREALLOCATE, &fs); if(ret < 0) { fs.fst_flags = F_ALLOCATEALL; ret = fcntl(u->fd, F_PREALLOCATE, &fs); } + + if(ret >= 0) { + /* We MUST truncate since F_PREALLOCATE works relative to end-of-file, + * otherwise we will expand the file on repeated calls to + * file:allocate/3 with the same arguments. */ + ret = ftruncate(u->fd, offset + length); + if(ret < 0) { + u->common.posix_errno = errno; + return 0; + } + } #elif !defined(HAVE_POSIX_FALLOCATE) u->common.posix_errno = ENOTSUP; return 0; diff --git a/erts/emulator/test/call_trace_SUITE.erl b/erts/emulator/test/call_trace_SUITE.erl index 742592f88e..477b0f5bb3 100644 --- a/erts/emulator/test/call_trace_SUITE.erl +++ b/erts/emulator/test/call_trace_SUITE.erl @@ -832,21 +832,27 @@ deep_exception() -> R1 -> ct:fail({returned,abbr(R1)}) catch error:badarg -> ok end, - expect(fun ({trace,S,call,{lists,reverse,[L1,L2]}}) + expect(fun ({trace,S,call,{lists,reverse,[L1,L2]}}, Traps) when is_list(L1), is_list(L2), S == Self -> - next; + %% Each trapping call to reverse/2 must have a corresponding + %% exception_from + {next, Traps + 1}; ({trace,S,exception_from, - {lists,reverse,2},{error,badarg}}) + {lists,reverse,2},{error,badarg}}, Traps) + when S == Self, Traps > 1 -> + {next, Traps - 1}; + ({trace,S,exception_from, + {lists,reverse,2},{error,badarg}}, 1) when S == Self -> expected; - ('_') -> + ('_', _Traps) -> {trace,Self,exception_from, {lists,reverse,2},{error,badarg}}; - (_) -> + (_, _Traps) -> {unexpected, {trace,Self,exception_from, {lists,reverse,2},{error,badarg}}} - end), + end, 0), deep_exception(?LINE, deep_5, [1,2], 7, [{trace,Self,call,{erlang,error,[undef]}}, {trace,Self,exception_from,{erlang,error,1}, @@ -896,21 +902,27 @@ deep_exception() -> R2 -> ct:fail({returned,abbr(R2)}) catch error:badarg -> ok end, - expect(fun ({trace,S,call,{lists,reverse,[L1,L2]}}) + expect(fun ({trace,S,call,{lists,reverse,[L1,L2]}}, Traps) when is_list(L1), is_list(L2), S == Self -> - next; + %% Each trapping call to reverse/2 must have a corresponding + %% exception_from + {next, Traps + 1}; + ({trace,S,exception_from, + {lists,reverse,2},{error,badarg}}, Traps) + when S == Self, Traps > 1 -> + {next, Traps - 1}; ({trace,S,exception_from, - {lists,reverse,2},{error,badarg}}) + {lists,reverse,2},{error,badarg}}, 1) when S == Self -> expected; - ('_') -> + ('_', _Traps) -> {trace,Self,exception_from, {lists,reverse,2},{error,badarg}}; - (_) -> + (_, _Traps) -> {unexpected, {trace,Self,exception_from, {lists,reverse,2},{error,badarg}}} - end), + end, 0), deep_exception(?LINE, apply, [?MODULE,deep_5,[1,2]], 7, [{trace,Self,call,{erlang,error,[undef]}}, {trace,Self,exception_from,{erlang,error,1}, @@ -975,21 +987,27 @@ deep_exception() -> R3 -> ct:fail({returned,abbr(R3)}) catch error:badarg -> ok end, - expect(fun ({trace,S,call,{lists,reverse,[L1,L2]}}) + expect(fun ({trace,S,call,{lists,reverse,[L1,L2]}}, Traps) when is_list(L1), is_list(L2), S == Self -> - next; + %% Each trapping call to reverse/2 must have a corresponding + %% exception_from + {next, Traps + 1}; + ({trace,S,exception_from, + {lists,reverse,2},{error,badarg}}, Traps) + when S == Self, Traps > 1 -> + {next, Traps - 1}; ({trace,S,exception_from, - {lists,reverse,2},{error,badarg}}) + {lists,reverse,2},{error,badarg}}, 1) when S == Self -> expected; - ('_') -> + ('_', _Traps) -> {trace,Self,exception_from, {lists,reverse,2},{error,badarg}}; - (_) -> + (_, _Traps) -> {unexpected, {trace,Self,exception_from, {lists,reverse,2},{error,badarg}}} - end), + end, 0), deep_exception(?LINE, apply, [fun () -> ?MODULE:deep_5(1,2) end, []], 7, [{trace,Self,call,{erlang,error,[undef]}}, @@ -1249,6 +1267,24 @@ expect(Message) -> ct:fail(no_trace_message) end. +expect(Validator, State0) when is_function(Validator) -> + receive + M -> + case Validator(M, State0) of + expected -> + ok = io:format("Expected and got ~p", [abbr(M)]); + {next, State} -> + ok = io:format("Expected and got ~p", [abbr(M)]), + expect(Validator, State); + {unexpected,Message} -> + io:format("Expected ~p; got ~p", [abbr(Message),abbr(M)]), + ct:fail({unexpected,abbr([M|flush()])}) + end + after 5000 -> + io:format("Expected ~p; got nothing", [abbr(Validator('_'))]), + ct:fail(no_trace_message) + end. + trace_info(What, Key) -> get(tracer) ! {apply,self(),{erlang,trace_info,[What,Key]}}, Res = receive diff --git a/erts/emulator/test/dirty_bif_SUITE.erl b/erts/emulator/test/dirty_bif_SUITE.erl index 4f5ad0295a..2ded862b8a 100644 --- a/erts/emulator/test/dirty_bif_SUITE.erl +++ b/erts/emulator/test/dirty_bif_SUITE.erl @@ -397,7 +397,9 @@ dirty_process_trace(Config) when is_list(Config) -> access_dirty_process( Config, fun() -> - erlang:trace_pattern({erts_debug,dirty_io,2}, + %% BIFs can only be traced when their modules are loaded. + code:ensure_loaded(erts_debug), + 1 = erlang:trace_pattern({erts_debug,dirty_io,2}, [{'_',[],[{return_trace}]}], [local,meta]), ok diff --git a/erts/emulator/test/lcnt_SUITE.erl b/erts/emulator/test/lcnt_SUITE.erl index 2dbaec9942..7bee7cf1d4 100644 --- a/erts/emulator/test/lcnt_SUITE.erl +++ b/erts/emulator/test/lcnt_SUITE.erl @@ -24,8 +24,7 @@ -export( [all/0, suite/0, - init_per_suite/1, end_per_suite/1, - init_per_testcase/2, end_per_testcase/2]). + init_per_suite/1, end_per_suite/1]). -export( [toggle_lock_counting/1, error_on_invalid_category/1, preserve_locks/1, @@ -63,13 +62,6 @@ end_per_suite(Config) -> erts_debug:lcnt_clear(), ok. -init_per_testcase(_Case, Config) -> - disable_lock_counting(), - Config. - -end_per_testcase(_Case, _Config) -> - ok. - disable_lock_counting() -> ok = erts_debug:lcnt_control(copy_save, false), ok = erts_debug:lcnt_control(mask, []), @@ -96,7 +88,10 @@ wait_for_empty_lock_list(Tries) when Tries > 0 -> wait_for_empty_lock_list(Tries - 1) end; wait_for_empty_lock_list(0) -> - ct:fail("Lock list failed to clear after disabling lock counting."). + [{duration, _}, {locks, Locks0}] = erts_debug:lcnt_collect(), + Locks = remove_untoggleable_locks(Locks0), + ct:fail("Lock list failed to clear after disabling lock counting.~n\t~p", + [Locks]). %% Queue up a lot of thread progress cleanup ops in a vain attempt to %% flush the lock list. @@ -109,6 +104,8 @@ try_flush_cleanup_ops() -> %% toggle_lock_counting(Config) when is_list(Config) -> + ok = disable_lock_counting(), + Categories = [allocator, db, debug, distribution, generic, io, process, scheduler], lists:foreach( @@ -131,6 +128,8 @@ get_lock_info_for(Category) when is_atom(Category) -> get_lock_info_for([Category]). preserve_locks(Config) when is_list(Config) -> + ok = disable_lock_counting(), + erts_debug:lcnt_control(mask, [process]), erts_debug:lcnt_control(copy_save, true), @@ -155,10 +154,14 @@ preserve_locks(Config) when is_list(Config) -> end. error_on_invalid_category(Config) when is_list(Config) -> + ok = disable_lock_counting(), + {error, badarg, q_invalid} = erts_debug:lcnt_control(mask, [q_invalid]), ok. registered_processes(Config) when is_list(Config) -> + ok = disable_lock_counting(), + %% There ought to be at least one registered process (init/code_server) erts_debug:lcnt_control(mask, [process]), [_, {locks, ProcLocks}] = erts_debug:lcnt_collect(), @@ -170,6 +173,8 @@ registered_processes(Config) when is_list(Config) -> ok. registered_db_tables(Config) when is_list(Config) -> + ok = disable_lock_counting(), + %% There ought to be at least one registered table (code) erts_debug:lcnt_control(mask, [db]), [_, {locks, DbLocks}] = erts_debug:lcnt_collect(), @@ -187,7 +192,7 @@ remove_untoggleable_locks([]) -> []; remove_untoggleable_locks([{resource_monitors, _, _, _} | T]) -> remove_untoggleable_locks(T); -remove_untoggleable_locks([{'socket[gcnt]', _, _, _} | T]) -> +remove_untoggleable_locks([{'esock[gcnt]', _, _, _} | T]) -> %% Global lock used by socket NIF remove_untoggleable_locks(T); remove_untoggleable_locks([H | T]) -> diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl index 21de6b1002..686b431876 100644 --- a/erts/emulator/test/match_spec_SUITE.erl +++ b/erts/emulator/test/match_spec_SUITE.erl @@ -198,7 +198,8 @@ caller_and_return_to(Config) -> {trace,Tracee,call,{?MODULE,do_the_put,[test]},{?MODULE,do_put,1}}, {trace,Tracee,call,{erlang,integer_to_list,[1]},{?MODULE,do_the_put,1}}, {trace,Tracee,return_to,{?MODULE,do_the_put,1}}, - {trace,Tracee,call,{erlang,put,[test,"1"]},{?MODULE,do_put,1}}, + {trace,Tracee,call,{erlang,put,[test,"1"]},{?MODULE,do_the_put,1}}, + {trace,Tracee,return_to,{?MODULE,do_the_put,1}}, {trace,Tracee,return_to,{?MODULE,do_put,1}}, %% These last trace messages are a bit strange... diff --git a/erts/emulator/test/trace_call_time_SUITE.erl b/erts/emulator/test/trace_call_time_SUITE.erl index 26f96a1766..9bab4cbbd8 100644 --- a/erts/emulator/test/trace_call_time_SUITE.erl +++ b/erts/emulator/test/trace_call_time_SUITE.erl @@ -254,8 +254,7 @@ combo(Config) when is_list(Config) -> 2 = erlang:trace_pattern({erlang, term_to_binary, '_'}, [], [local]), 2 = erlang:trace_pattern({erlang, term_to_binary, '_'}, true, [call_time]), 2 = erlang:trace_pattern({erlang, term_to_binary, '_'}, MetaMs, [{meta,MetaTracer}]), - %% not implemented - %2 = erlang:trace_pattern({erlang, term_to_binary, '_'}, true, [call_count]), + 2 = erlang:trace_pattern({erlang, term_to_binary, '_'}, true, [call_count]), 1 = erlang:trace(Self, true, [{tracer,LocalTracer} | Flags]), %% @@ -284,9 +283,7 @@ combo(Config) when is_list(Config) -> {value,{match_spec,[]}} = lists:keysearch(match_spec, 1, TraceInfoBif), {value,{meta, MetaTracer}} = lists:keysearch(meta, 1, TraceInfoBif), {value,{meta_match_spec,MetaMs}} = lists:keysearch(meta_match_spec, 1, TraceInfoBif), - %% not implemented - {value,{call_count,false}} = lists:keysearch(call_count, 1, TraceInfoBif), - %{value,{call_count,0}} = lists:keysearch(call_count, 1, TraceInfoBif), + {value,{call_count,0}} = lists:keysearch(call_count, 1, TraceInfoBif), {value,{call_time,[]}} = lists:keysearch(call_time, 1, TraceInfoBif), %% @@ -429,6 +426,8 @@ called_function(Config) when is_list(Config) -> %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% dead_tracer(Config) when is_list(Config) -> + TracedMFAs = dead_tracer_mfas(), + Self = self(), FirstTracer = tracer(), StartTracing = fun() -> turn_on_tracing(Self) end, @@ -443,14 +442,14 @@ dead_tracer(Config) when is_list(Config) -> erlang:yield(), %% Collect and check that we only get call_time info for the current process. - Info1 = collect_all_info(), + Info1 = collect_all_info(TracedMFAs), [] = other_than_self(Info1), io:format("~p\n", [Info1]), %% Note that we have not turned off tracing for the current process, %% but that the tracer has terminated. No more call_time information should be recorded. [1,2,3] = seq(1, 3, fun(I) -> I + 1 end), - [] = collect_all_info(), + [] = collect_all_info(TracedMFAs), %% When we start a second tracer process, that tracer process must %% not inherit the tracing flags and the dead tracer (even though @@ -459,7 +458,7 @@ dead_tracer(Config) when is_list(Config) -> tell_tracer(SecondTracer, StartTracing), Seq20 = lists:seq(1, 20), Seq20 = seq(1, 20, fun(I) -> I + 1 end), - Info2 = collect_all_info(), + Info2 = collect_all_info(TracedMFAs), io:format("~p\n", [Info2]), [] = other_than_self(Info2), SecondTracer ! quit, @@ -495,9 +494,21 @@ turn_on_tracing(Pid) -> _ = now(), ok. -collect_all_info() -> - collect_all_info([{?MODULE,F,A} || {F,A} <- module_info(functions)] ++ - erlang:system_info(snifs)). +%% We want to trace functions local to this module as well as all BIFs, and for +%% the latter we need to ensure that their modules are loaded. +dead_tracer_mfas() -> + Modules = [M || {M,_F,_A} <- erlang:system_info(snifs)], + Whitelist0 = gb_sets:from_list(Modules), + Whitelist = case code:ensure_modules_loaded(Modules) of + {error, Reasons} -> + Blacklist = gb_sets:from_list([M || {M, _} <- Reasons]), + gb_sets:subtract(Whitelist0, Blacklist); + ok -> + Whitelist0 + end, + EligibleSNIFs = [MFA || {M,_F,_A}=MFA <- erlang:system_info(snifs), + gb_sets:is_element(M, Whitelist)], + [{?MODULE,F,A} || {F,A} <- module_info(functions)] ++ EligibleSNIFs. collect_all_info([MFA|T]) -> CallTime = erlang:trace_info(MFA, call_time), @@ -567,21 +578,29 @@ seq_r(Start, Stop, Succ, R) -> seq_r(Succ(Start), Stop, Succ, [Start | R]). % Check call time tracing data and print mismatches -check_trace_info(Mfa, [{Pid, C,_,_}] = Expect, Time) -> - case erlang:trace_info(Mfa, call_time) of - % Time tests are somewhat problematic. We want to know if Time (EXPECTED_TIME) and S*1000000 + Us (ACTUAL_TIME) - % is the same. - % If the ratio EXPECTED_TIME/ACTUAL_TIME is ~ 1 or if EXPECTED_TIME - ACTUAL_TIME is near zero, the test is ok. - {call_time,[{Pid,C,S,Us}]} when S >= 0, Us >= 0, abs(1 - Time/(S*1000000 + Us)) < ?R_ERROR; abs(Time - S*1000000 - Us) < ?US_ERROR -> +check_trace_info(Mfa, [{Pid, ExpectedC,_,_}] = Expect, Time) -> + {call_time,[{Pid,C,S,Us}]} = erlang:trace_info(Mfa, call_time), + {Mod, Name, Arity} = Mfa, + IsBuiltin = erlang:is_builtin(Mod, Name, Arity), + if + %% Call count on BIFs may exceed number of calls as they often trap to + %% themselves. + IsBuiltin, C >= ExpectedC, S >= 0, Us >= 0, + abs(1 - Time/(S*1000000 + Us)) < ?R_ERROR; + abs(Time - S*1000000 - Us) < ?US_ERROR -> ok; - {call_time,[{Pid,C,S,Us}]} -> + not IsBuiltin, C =:= ExpectedC, S >= 0, Us >= 0, + abs(1 - Time/(S*1000000 + Us)) < ?R_ERROR; + abs(Time - S*1000000 - Us) < ?US_ERROR -> + ok; + true -> Sum = S*1000000 + Us, - io:format("Expected ~p -> {call_time, ~p (Time ~p us)}~n - got ~w s. ~w us. = ~w us. - ~w -> delta ~w (ratio ~.2f, should be 1.0)~n", - [Mfa, Expect, Time, S, Us, Sum, Time, Sum - Time, Time/Sum]), - time_error; - Other -> - io:format("Expected ~p -> {call_time, ~p (Time ~p us)}~n - got ~p~n", [ Mfa, Expect, Time, Other]), - time_count_error + io:format("Expected ~p -> {call_time, ~p (Time ~p us)}~n - got ~w " + "s. ~w us. = ~w us. - ~w -> delta ~w (ratio ~.2f, " + "should be 1.0)~n", + [Mfa, Expect, Time, + S, Us, Sum, Time, Sum - Time, Time/Sum]), + time_error end; check_trace_info(Mfa, Expect, _) -> case erlang:trace_info(Mfa, call_time) of @@ -670,9 +689,12 @@ loop() -> quit -> ok; {Pid, execute, Fun } when is_function(Fun) -> + %% Make sure we always run with the same amount of reductions. + erlang:yield(), Pid ! {self(), answer, erlang:apply(Fun, [])}, loop(); {Pid, execute, {M, F, A}} -> + erlang:yield(), Pid ! {self(), answer, erlang:apply(M, F, A)}, loop() end. diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops index 605a402f2a..cc21f9b5b4 100755 --- a/erts/emulator/utils/beam_makeops +++ b/erts/emulator/utils/beam_makeops @@ -1315,7 +1315,7 @@ sub combine_instruction_group { my $inc = 0; unless ($i == $#slots) { - $flags = "-no_next"; + $flags = "-micro_instruction"; my $next_offset = $label_to_offset{$next}; $inc = ($offset + $size) - $next_offset; $transfer_to_next = "I += $inc;\n" if $inc; @@ -1553,8 +1553,10 @@ sub code_gen { my $dispatch_next; my $instr_offset = $group_size + $offset + 1; - if ($flags =~ /-no_next/) { + if ($flags =~ /-micro_instruction/) { $dispatch_next = ""; + } elsif ($flags =~ /-no_next/) { + $dispatch_next = "ASSERT(!\"Fell through '$name' (-no_next)\");"; } elsif ($flags =~ /-no_prefetch/) { $dispatch_next = "\nI += $instr_offset;\n" . "ASSERT(VALID_INSTR(*I));\n" . diff --git a/erts/emulator/utils/make_tables b/erts/emulator/utils/make_tables index deee5c2344..f87472111f 100755 --- a/erts/emulator/utils/make_tables +++ b/erts/emulator/utils/make_tables @@ -35,7 +35,6 @@ use File::Basename; # Output: # <-src>/erl_am.c # <-src>/erl_bif_table.c -# <-src>/erl_bif_wrap.c # <-src>/erl_dirty_bif_wrap.c # <-src>/erl_guard_bifs.c # <-src>/hipe_nbif_impl.c @@ -92,7 +91,7 @@ while (<>) { my($type, @args) = split; if ($type eq 'atom') { save_atoms(@args); - } elsif ($type eq 'bif' or $type eq 'ubif' or $type eq 'gcbif') { + } elsif ($type eq 'bif' or $type eq 'ubif' or $type eq 'hbif') { if (@args > 2) { error("$type only allows two arguments"); } @@ -124,14 +123,22 @@ while (<>) { error("invalid sched_type: $sched_type"); } - my $wrapper; - if ($type eq 'bif') { - $wrapper = "wrap_$alias"; - } else { - $wrapper = $alias; - } + my $kind; + if ($type eq 'bif') { + $kind = 'BIF_KIND_REGULAR'; + } + elsif ($type eq 'hbif') { + $kind = 'BIF_KIND_HEAVY'; + } + elsif ($type eq 'ubif') { + $kind = 'BIF_KIND_GUARD'; + } + else { + error("invalid bif_type: $type"); + } + push(@bif, ["am_$atom_alias{$mod}","am_$atom_alias{$name}",$arity, - $alias3,$wrapper,$alias]); + $alias3,$alias,$kind]); push(@bif_info, [$type, $sched_type, $alias3, $alias]); } elsif ($type eq 'dirty-cpu' or $type eq 'dirty-io' or $type eq 'dirty-cpu-test' or $type eq 'dirty-io-test') { @@ -196,7 +203,7 @@ open_file("$include/erl_bif_list.h"); my $i; for ($i = 0; $i < @bif; $i++) { # module atom, function atom, arity, C function, table index - print "BIF_LIST($bif[$i]->[0],$bif[$i]->[1],$bif[$i]->[2],$bif[$i]->[3],$bif[$i]->[5],$i)\n"; + print "BIF_LIST($bif[$i]->[0],$bif[$i]->[1],$bif[$i]->[2],$bif[$i]->[3],$bif[$i]->[4],$i)\n"; } # @@ -208,15 +215,24 @@ my $bif_size = @bif; print <<EOF; #ifndef __ERL_BIF_TABLE_H__ #define __ERL_BIF_TABLE_H__ + +#include "sys.h" + typedef void *BifFunction; +typedef enum { + BIF_KIND_REGULAR, + BIF_KIND_HEAVY, + BIF_KIND_GUARD +} BifKind; + typedef struct bif_entry { Eterm module; Eterm name; int arity; BifFunction f; - BifFunction traced; BifFunction impl; + BifKind kind; } BifEntry; typedef struct erts_gc_bif { @@ -231,8 +247,7 @@ typedef struct erts_u_bif { } ErtsUBif; extern BifEntry bif_table[]; -extern Export* bif_export[]; -extern const ErtsGcBif erts_gc_bifs[]; +extern Export bif_trap_export[]; extern const ErtsUBif erts_u_bifs[]; #define BIF_SIZE $bif_size @@ -250,7 +265,6 @@ for ($i = 0; $i < @bif; $i++) { my $args = join(', ', 'Process*', 'Eterm*', 'UWord*'); my $name = $bif_info[$i]->[3]; print "Eterm $name($args);\n"; - print "Eterm wrap_$name($args);\n"; print "Eterm erts_gc_$name(Process* p, Eterm* reg, Uint live);\n" if $bif_info[$i]->[0] eq 'gcbif'; print "Eterm $bif_info[$i]->[2]($args);\n" @@ -273,7 +287,7 @@ my $i; includes("export.h", "sys.h", "erl_vm.h", "erl_process.h", "bif.h", "erl_bif_table.h", "erl_atom_table.h"); -print "\nExport* bif_export[BIF_SIZE];\n"; +print "\nExport bif_trap_export[BIF_SIZE];\n"; print "BifEntry bif_table[] = {\n"; for ($i = 0; $i < @bif; $i++) { @@ -283,25 +297,6 @@ for ($i = 0; $i < @bif; $i++) { print "};\n\n"; # -# Generate the bif wrappers file. -# - -open_file("$src/erl_bif_wrap.c"); -my $i; -includes("export.h", "sys.h", "erl_vm.h", "global.h", "erl_process.h", "bif.h", - "erl_bif_table.h", "erl_atom_table.h"); -for ($i = 0; $i < @bif; $i++) { - next if $bif[$i]->[3] eq $bif[$i]->[4]; # Skip unwrapped bifs - my $arity = $bif[$i]->[2]; - my $func = $bif_info[$i]->[3]; - print "Eterm\n"; - print "wrap_$func(Process* p, Eterm* args, UWord* I)\n"; - print "{\n"; - print " return erts_bif_trace($i, p, args, I);\n"; - print "}\n\n"; -} - -# # Generate erl_gc_bifs.c. # @@ -309,18 +304,11 @@ open_file("$src/erl_guard_bifs.c"); my $i; includes("export.h", "sys.h", "erl_vm.h", "global.h", "erl_process.h", "bif.h", "erl_bif_table.h"); -print "const ErtsGcBif erts_gc_bifs[] = {\n"; -for ($i = 0; $i < @bif; $i++) { - next unless $bif_info[$i]->[0] eq 'gcbif'; - print " {$bif[$i]->[3], erts_gc_$bif[$i]->[3], BIF_$bif[$i]->[5]},\n"; -} -print " {NULL, NULL, -1}\n"; -print "};\n"; print "const ErtsUBif erts_u_bifs[] = {\n"; for ($i = 0; $i < @bif; $i++) { next unless $bif_info[$i]->[0] eq 'ubif'; - print " {$bif[$i]->[3], BIF_$bif[$i]->[5]},\n"; + print " {$bif[$i]->[3], BIF_$bif[$i]->[4]},\n"; } print " {NULL, -1}\n"; print "};\n"; @@ -368,7 +356,7 @@ EOF my $i; for ($i = 0; $i < @bif; $i++) { print <<EOF; -Eterm nbif_impl_$bif[$i]->[5](Process *c_p, Eterm *regs); +Eterm nbif_impl_$bif[$i]->[4](Process *c_p, Eterm *regs); EOF } @@ -388,9 +376,9 @@ EOF for ($i = 0; $i < @bif; $i++) { print <<EOF; -Eterm nbif_impl_$bif[$i]->[5](Process *c_p, Eterm *regs) +Eterm nbif_impl_$bif[$i]->[4](Process *c_p, Eterm *regs) { - return $bif[$i]->[3](c_p, regs, (UWord *) bif_export\[BIF_$bif[$i]->[5]\]); + return $bif[$i]->[3](c_p, regs, (UWord *)&bif_trap_export\[BIF_$bif[$i]->[4]\]); } EOF diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src index 59de9bdec8..d85a36acd4 100644 --- a/erts/etc/unix/cerl.src +++ b/erts/etc/unix/cerl.src @@ -315,8 +315,13 @@ if [ "x$GDB" = "x" ]; then ncpu=`cat /proc/cpuinfo | grep -w processor | wc -l` # Choose a random core in order to not collide with any other valgrind # run on the same machine. - taskset1=$((1 << (`shuf -i 1-$ncpu -n 1` - 1) )) - taskset1="taskset $taskset1" + cpu=`shuf -i 1-$ncpu -n 1` + mask=1 + while [ $cpu -gt 1 ]; do + mask=`expr $mask \* 2` + cpu=`expr $cpu - 1` + done + taskset1="taskset $mask" sched_arg="-S$ncpu:$ncpu" else taskset1= diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam Binary files differindex 78a9a4eef2..1530982393 100644 --- a/erts/preloaded/ebin/erlang.beam +++ b/erts/preloaded/ebin/erlang.beam diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index f1a1de4ab2..94595ab78f 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -189,6 +189,27 @@ -export([dt_get_tag/0, dt_get_tag_data/0, dt_prepend_vm_tag_data/1, dt_append_vm_tag_data/1, dt_put_tag/1, dt_restore_tag/1, dt_spread_tag/1]). +%% Operators + +-export(['=='/2, '=:='/2, + '/='/2, '=/='/2, + '=<'/2, '>='/2, + '<'/2, '>'/2]). + +-export(['-'/1, '+'/1, + '-'/2, '+'/2, + '/'/2, '*'/2, + 'div'/2, 'rem'/2, + 'bsl'/2, 'bsr'/2, + 'bor'/2, 'band'/2, + 'bxor'/2, 'bnot'/1]). + +-export(['and'/2, 'or'/2, + 'xor'/2, 'not'/1]). + +-export(['--'/2, '++'/2]). + +-export(['!'/2]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Simple native code BIFs @@ -3932,3 +3953,98 @@ gc_info(Ref, N, {OrigColls,OrigRecl}) -> {Ref, {_,Colls, Recl}} -> gc_info(Ref, N-1, {Colls+OrigColls,Recl+OrigRecl}) end. + +%% Operators + +-spec erlang:'=='(term(), term()) -> boolean(). +'=='(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'=:='(term(), term()) -> boolean(). +'=:='(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'/='(term(), term()) -> boolean(). +'/='(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'=/='(term(), term()) -> boolean(). +'=/='(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'=<'(term(), term()) -> boolean(). +'=<'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'>='(term(), term()) -> boolean(). +'>='(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'<'(term(), term()) -> boolean(). +'<'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'>'(term(), term()) -> boolean(). +'>'(_A, _B) -> + erlang:nif_error(undefined). + +-spec erlang:'-'(number()) -> number(). +'-'(_A) -> + erlang:nif_error(undefined). +-spec erlang:'+'(number()) -> number(). +'+'(_A) -> + erlang:nif_error(undefined). +-spec erlang:'-'(number(), number()) -> number(). +'-'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'+'(number(), number()) -> number(). +'+'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'/'(number(), number()) -> float(). +'/'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'*'(number(), number()) -> number(). +'*'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'div'(integer(), integer()) -> integer(). +'div'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'rem'(integer(), integer()) -> integer(). +'rem'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'bsl'(integer(), integer()) -> integer(). +'bsl'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'bsr'(integer(), integer()) -> integer(). +'bsr'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'bor'(integer(), integer()) -> integer(). +'bor'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'band'(integer(), integer()) -> integer(). +'band'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'bxor'(integer(), integer()) -> integer(). +'bxor'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'bnot'(integer()) -> integer(). +'bnot'(_A) -> + erlang:nif_error(undefined). + +-spec erlang:'--'(list(), list()) -> list(). +'--'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'++'(list(), term()) -> term(). +'++'(_A, _B) -> + erlang:nif_error(undefined). + +-spec erlang:'and'(boolean(), boolean()) -> boolean(). +'and'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'or'(boolean(), boolean()) -> boolean(). +'or'(_A, _B) -> + erlang:nif_error(undefined). + +-spec erlang:'xor'(boolean(), boolean()) -> boolean(). +'xor'(_A, _B) -> + erlang:nif_error(undefined). +-spec erlang:'not'(boolean()) -> boolean(). +'not'(_A) -> + erlang:nif_error(undefined). + +-spec erlang:'!'(dst(), term()) -> term(). +'!'(_Dst, _Msg) -> + erlang:nif_error(undefined). diff --git a/erts/vsn.mk b/erts/vsn.mk index f06fd08540..d1db2ceceb 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% # -VSN = 10.4.4 +VSN = 10.5 # Port number 4365 in 4.2 # Port number 4366 in 4.3 diff --git a/lib/common_test/doc/src/ct_netconfc.xml b/lib/common_test/doc/src/ct_netconfc.xml index ab56ea5587..f4d98b611b 100644 --- a/lib/common_test/doc/src/ct_netconfc.xml +++ b/lib/common_test/doc/src/ct_netconfc.xml @@ -435,8 +435,8 @@ </func> <func> - <name name="create_subscription" arity="2" clause_i="1"/> - <name name="create_subscription" arity="3" clause_i="1"/> + <name name="create_subscription" arity="2" clause_i="1" since="OTP 22.1"/> + <name name="create_subscription" arity="3" clause_i="1" since="OTP 22.1"/> <fsummary>Creates a subscription for event notifications.</fsummary> <desc> <p>Creates a subscription for event notifications by sending @@ -483,6 +483,13 @@ <c>StopTime</c> must only be used with <c>StartTime</c> is not enforced, to allow an invalid request to be sent to the server.</p> + + <p>Prior to OTP 22.1, this function was documented as having + 15 variants in 6 arities. These are still exported for + backwards compatibility, but no longer documented. + The map-based variants documented above provide the same + functionality with simpler arguments.</p> + </desc> </func> diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml index c454608bbe..39388fd5ed 100644 --- a/lib/common_test/doc/src/notes.xml +++ b/lib/common_test/doc/src/notes.xml @@ -33,6 +33,64 @@ <file>notes.xml</file> </header> +<section><title>Common_Test 1.18</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + If a ct hook is installed in the <c>suite/0</c> function + in a test suite, then the hook's <c>terminate/1</c> + function would be called several times without it's + <c>init/2</c> function being called first. This is now + corrected.</p> + <p> + Own Id: OTP-15863 Aux Id: ERIERL-370 </p> + </item> + <item> + <p> + If <c>init_per_testcase</c> fails, the test itself is + skipped. According to the documentation, it should be + possible to change the result to failed in a hook + function. The only available hook function in this case + is <c>post_init_per_testcase</c>, but changing the return + value there did not affect the test case result. This is + now corrected.</p> + <p> + Own Id: OTP-15869 Aux Id: ERIERL-350 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Add ct_netconfc support for NETCONF 1.1 (RFC 6241). The + 1.1 base capability can be sent in hello, and RFC 6242 + chunk framing is applied when both client and server + advertise 1.1 support.</p> + <p> + Own Id: OTP-15789</p> + </item> + <item> + <p> + Correct lib_dir paths in common_tests opaque data + structure that is passed to ct_release_test callback + modules in functions upgrade_init/2, upgrade_upgraded/2 + and upgrade_downgraded/2. The incorrect paths may cause + confusion when debugging although it will not cause any + incorrect behavior on the part of common_test as it is + currently not used.</p> + <p> + Own Id: OTP-15934</p> + </item> + </list> + </section> + +</section> + <section><title>Common_Test 1.17.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk index 8dcb69c1c6..ddc518f474 100644 --- a/lib/common_test/vsn.mk +++ b/lib/common_test/vsn.mk @@ -1 +1 @@ -COMMON_TEST_VSN = 1.17.3 +COMMON_TEST_VSN = 1.18 diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml index f11444137d..4db09e8059 100644 --- a/lib/compiler/doc/src/notes.xml +++ b/lib/compiler/doc/src/notes.xml @@ -32,6 +32,84 @@ <p>This document describes the changes made to the Compiler application.</p> +<section><title>Compiler 7.4.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Code such as the following would crash the compiler in + OTP 22: <c>[some_atom = fun some_function/1]</c></p> + <p> + Own Id: OTP-15833</p> + </item> + <item> + <p>Compilation could get really slow (in the order of + minutes instead of seconds) when compiling huge + functions. (Thanks to Kostis Sagonas for reporting this + bug.)</p> + <p> + Own Id: OTP-15923</p> + </item> + <item> + <p>Fixed a bug in the validator that could reject valid + code.</p> + <p> + Own Id: OTP-15954 Aux Id: ERL-995 </p> + </item> + <item> + <p>In rare circumstances, when two clauses had identical + bodies and guard tests that tested a single boolean + variable, the guard test for the second clause could be + discarded, executing the second clause unconditionally if + the first clause was not executed.</p> + <p> + Own Id: OTP-15963</p> + </item> + <item> + <p>Fixed extremely slow compilation for huge functions + doing predominantly pattern matching.</p> + <p> + Own Id: OTP-15966 Aux Id: ERL-1014 </p> + </item> + <item> + <p>The compiler could generate unsafe code (that would + crash the runtime system) for map pattern matching. The + code could be unsafe if the matched key was not present + in the map at runtime. </p> + <p> + Own Id: OTP-15968 Aux Id: ERL-1017 </p> + </item> + <item> + <p>Correct code using try/after could fail to compile + when using the option '<c>no_type_opt</c>'.</p> + <p> + Own Id: OTP-15969 Aux Id: ERL-997 </p> + </item> + <item> + <p>The compiler could crash when compiling code that + called '<c>length/1</c>' on a binary extracted using the + binary syntax.</p> + <p> + Own Id: OTP-15970 Aux Id: ERL-1013 </p> + </item> + <item> + <p>Fixed a bug where the compiler could fail with an + internal consistency failure error when compiling receive + statements.</p> + <p> + Own Id: OTP-15982 Aux Id: ERL-1022 </p> + </item> + <item> + <p>Fixed a problem where the compiler would crash when + compiling binary matching in a function head.</p> + <p> + Own Id: OTP-15985 Aux Id: ERL-1026 </p> + </item> + </list> + </section> + +</section> + <section><title>Compiler 7.4.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl index 74f80ca70e..85fd89bbe8 100644 --- a/lib/compiler/src/beam_jump.erl +++ b/lib/compiler/src/beam_jump.erl @@ -580,8 +580,6 @@ is_unreachable_after(I) -> is_exit_instruction(I). -spec is_exit_instruction(instruction()) -> boolean(). -is_exit_instruction({call_ext,_,{extfunc,M,F,A}}) -> - erl_bifs:is_exit_bif(M, F, A); is_exit_instruction(if_end) -> true; is_exit_instruction({case_end,_}) -> true; is_exit_instruction({try_case_end,_}) -> true; diff --git a/lib/compiler/src/beam_ssa_pre_codegen.erl b/lib/compiler/src/beam_ssa_pre_codegen.erl index 61c42fdb6d..bf2503a2a5 100644 --- a/lib/compiler/src/beam_ssa_pre_codegen.erl +++ b/lib/compiler/src/beam_ssa_pre_codegen.erl @@ -707,20 +707,30 @@ legacy_bs_is([], _Last, _IsYreg, Count, Copies, Acc) -> exception_trampolines(#st{ssa=Blocks0}=St) -> RPO = reverse(beam_ssa:rpo(Blocks0)), - Blocks = et_1(RPO, #{}, Blocks0), + Blocks = et_1(RPO, #{}, #{}, Blocks0), St#st{ssa=Blocks}. -et_1([L | Ls], Trampolines, Blocks) -> +et_1([L | Ls], Trampolines, Exceptions, Blocks) -> #{ L := #b_blk{is=Is,last=Last0}=Block0 } = Blocks, case {Is, Last0} of - {[#b_set{op=exception_trampoline}], #b_br{succ=Succ}} -> - et_1(Ls, Trampolines#{ L => Succ }, maps:remove(L, Blocks)); + {[#b_set{op=exception_trampoline,args=[Arg]}], #b_br{succ=Succ}} -> + et_1(Ls, + Trampolines#{ L => Succ }, + Exceptions#{ L => Arg }, + maps:remove(L, Blocks)); {_, #b_br{succ=Same,fail=Same}} when Same =:= ?EXCEPTION_BLOCK -> %% The exception block is just a marker saying that we should raise %% an exception (= {f,0}) instead of jumping to a particular fail %% block. Since it's not a reachable block we can't allow %% unconditional jumps to it except through a trampoline. error({illegal_jump_to_exception_block, L}); + {_, #b_br{succ=Same,fail=Same}} + when map_get(Same, Trampolines) =:= ?EXCEPTION_BLOCK -> + %% This block always fails at runtime (and we are not in a + %% try/catch); rewrite the terminator to a return. + Last = #b_ret{arg=map_get(Same, Exceptions)}, + Block = Block0#b_blk{last=Last}, + et_1(Ls, Trampolines, Exceptions, Blocks#{ L := Block }); {_, #b_br{succ=Succ0,fail=Fail0}} -> Succ = maps:get(Succ0, Trampolines, Succ0), Fail = maps:get(Fail0, Trampolines, Fail0), @@ -728,14 +738,14 @@ et_1([L | Ls], Trampolines, Blocks) -> Succ =/= Succ0; Fail =/= Fail0 -> Last = Last0#b_br{succ=Succ,fail=Fail}, Block = Block0#b_blk{last=Last}, - et_1(Ls, Trampolines, Blocks#{ L := Block }); + et_1(Ls, Trampolines, Exceptions, Blocks#{ L := Block }); Succ =:= Succ0, Fail =:= Fail0 -> - et_1(Ls, Trampolines, Blocks) + et_1(Ls, Trampolines, Exceptions, Blocks) end; {_, _} -> - et_1(Ls, Trampolines, Blocks) + et_1(Ls, Trampolines, Exceptions, Blocks) end; -et_1([], _Trampolines, Blocks) -> +et_1([], _Trampolines, _Exceptions, Blocks) -> Blocks. %% sanitize(St0) -> St. @@ -1331,14 +1341,9 @@ need_frame_1([#b_set{op=call,args=[Func|_]}|Is], Context) -> #b_remote{mod=#b_literal{val=Mod}, name=#b_literal{val=Name}, arity=Arity} when is_atom(Mod), is_atom(Name) -> - case erl_bifs:is_exit_bif(Mod, Name, Arity) of - true -> - false; - false -> - Context =:= body orelse - Is =/= [] orelse - is_trap_bif(Mod, Name, Arity) - end; + Context =:= body orelse + Is =/= [] orelse + is_trap_bif(Mod, Name, Arity); #b_remote{} -> %% This is an apply(), which always needs a frame. true; diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 911b5eb777..d55aeed9a9 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -395,28 +395,33 @@ valfun_1({init,Reg}, Vst) -> create_tag(initialized, init, [], Reg, Vst); valfun_1({test_heap,Heap,Live}, Vst) -> test_heap(Heap, Live, Vst); -valfun_1({bif,Op,{f,0},Ss,Dst}=I, Vst) -> - case will_bif_succeed(Op, Ss, Vst) of +valfun_1({bif,Op,{f,0},Ss,Dst}=I, Vst0) -> + case will_bif_succeed(Op, Ss, Vst0) of yes -> %% This BIF cannot fail, handle it here without updating catch %% state. - validate_bif(Op, cannot_fail, Ss, Dst, Vst); + validate_bif(Op, cannot_fail, Ss, Dst, Vst0); no -> %% The stack will be scanned, so Y registers must be initialized. + Vst = branch_exception(Vst0), verify_y_init(Vst), kill_state(Vst); maybe -> %% The BIF can fail, make sure that any catch state is updated. + Vst = branch_exception(Vst0), valfun_2(I, Vst) end; -valfun_1({gc_bif,Op,{f,0},Live,Ss,Dst}=I, Vst) -> - case will_bif_succeed(Op, Ss, Vst) of +valfun_1({gc_bif,Op,{f,0},Live,Ss,Dst}=I, Vst0) -> + case will_bif_succeed(Op, Ss, Vst0) of yes -> - validate_gc_bif(Op, cannot_fail, Ss, Dst, Live, Vst); + validate_gc_bif(Op, cannot_fail, Ss, Dst, Live, Vst0); no -> + Vst = branch_exception(Vst0), verify_y_init(Vst), kill_state(Vst); maybe -> + Vst = branch_exception(Vst0), + assert_float_checked(Vst), valfun_2(I, Vst) end; %% Put instructions. @@ -510,26 +515,42 @@ valfun_1({'%',_}, Vst) -> Vst; valfun_1({line,_}, Vst) -> Vst; -%% Exception generating calls -valfun_1({call_ext,Live,Func}=I, Vst) -> - case will_call_succeed(Func, Vst) of - yes -> - %% This call cannot fail, handle it here without updating catch - %% state. - call(Func, Live, Vst); - no -> - %% The stack will be scanned, so Y registers must be initialized. - verify_live(Live, Vst), - verify_y_init(Vst), - kill_state(Vst); - maybe -> - %% The call can fail, make sure that any catch state is updated. - valfun_2(I, Vst) - end; +%% +%% Calls; these may be okay when the try/catch state or stack is undecided, +%% depending on whether they always succeed or always fail. +%% +valfun_1({apply,Live}, Vst) -> + validate_body_call(apply, Live+2, Vst); +valfun_1({apply_last,Live,N}, Vst) -> + validate_tail_call(N, apply, Live+2, Vst); +valfun_1({call_fun,Live}, Vst) -> + Fun = {x,Live}, + assert_term(Fun, Vst), + + %% An exception is raised on error, hence branching to 0. + branch(0, Vst, + fun(SuccVst0) -> + SuccVst = update_type(fun meet/2, #t_fun{arity=Live}, + Fun, SuccVst0), + validate_body_call('fun', Live+1, SuccVst) + end); +valfun_1({call,Live,Func}, Vst) -> + validate_body_call(Func, Live, Vst); +valfun_1({call_ext,Live,Func}, Vst) -> + validate_body_call(Func, Live, Vst); +valfun_1({call_only,Live,Func}, Vst) -> + validate_tail_call(none, Func, Live, Vst); +valfun_1({call_ext_only,Live,Func}, Vst) -> + validate_tail_call(none, Func, Live, Vst); +valfun_1({call_last,Live,Func,N}, Vst) -> + validate_tail_call(N, Func, Live, Vst); +valfun_1({call_ext_last,Live,Func,N}, Vst) -> + validate_tail_call(N, Func, Live, Vst); valfun_1(_I, #vst{current=#st{ct=undecided}}) -> error(unknown_catch_try_state); %% %% Allocate and deallocate, et.al +%% valfun_1({allocate,Stk,Live}, Vst) -> allocate(uninitialized, Stk, 0, Live, Vst); valfun_1({allocate_heap,Stk,Heap,Live}, Vst) -> @@ -612,9 +633,58 @@ valfun_1({jump,{f,Lbl}}, Vst) -> %% The next instruction is never executed. kill_state(SuccVst) end); -valfun_1(I, Vst) -> +valfun_1(I, Vst0) -> + Vst = branch_exception(Vst0), valfun_2(I, Vst). +validate_tail_call(Deallocate, Func, Live, #vst{current=#st{numy=NumY}}=Vst0) -> + assert_float_checked(Vst0), + case will_call_succeed(Func, Vst0) of + yes when Deallocate =:= NumY -> + %% This call cannot fail, handle it without updating catch state. + tail_call(Func, Live, Vst0); + maybe when Deallocate =:= NumY -> + %% The call can fail, make sure that any catch state is updated. + Vst = branch_exception(Vst0), + tail_call(Func, Live, Vst); + no -> + %% The stack will be scanned, so Y registers must be initialized. + %% + %% Note that the compiler is allowed to emit garbage values for + %% "Deallocate" as we know that it will not be used in this case. + Vst = branch_exception(Vst0), + verify_live(Live, Vst), + verify_y_init(Vst), + kill_state(Vst); + _ when Deallocate =/= NumY -> + error({allocated, NumY}) + end. + +validate_body_call(Func, Live, + #vst{current=#st{numy=NumY}}=Vst0) when is_integer(NumY)-> + assert_float_checked(Vst0), + case will_call_succeed(Func, Vst0) of + yes -> + call(Func, Live, Vst0); + maybe -> + Vst = branch_exception(Vst0), + call(Func, Live, Vst); + no -> + Vst = branch_exception(Vst0), + verify_live(Live, Vst), + verify_y_init(Vst), + kill_state(Vst) + end; +validate_body_call(_, _, #vst{current=#st{numy=NumY}}) -> + error({allocated, NumY}). + +assert_float_checked(Vst) -> + case get_fls(Vst) of + undefined -> ok; + checked -> ok; + Fls -> error({unsafe_instruction,{float_error_state,Fls}}) + end. + init_try_catch_branch(Kind, Dst, Fail, Vst0) -> Tag = {Kind, [Fail]}, Vst = create_tag(Tag, 'try_catch', [], Dst, Vst0), @@ -633,10 +703,10 @@ init_try_catch_branch(Kind, Dst, Fail, Vst0) -> #vst{current=#st{ct=Tags}=St0} = SuccVst0, St = St0#st{ct=[Tag|Tags]}, SuccVst = SuccVst0#vst{current=St}, - + %% All potentially-throwing instructions after this one will %% implicitly branch to the current try/catch handler; see - %% valfun_2/2 + %% the base case of valfun_1/2 SuccVst end). @@ -649,19 +719,20 @@ init_catch_handler_1(Reg, uninitialized, Vst) -> init_catch_handler_1(_, _, Vst) -> Vst. -valfun_2(I, #vst{current=#st{ct=[{_,[Fail]}|_]}}=Vst) when is_integer(Fail) -> +branch_exception(#vst{current=#st{ct=[{_,[Fail]}|_]}}=Vst) + when is_integer(Fail) -> %% We have an active try/catch tag and we can jump there from this %% instruction, so we need to update the branched state of the try/catch %% handler. - valfun_3(I, fork_state(Fail, Vst)); -valfun_2(I, #vst{current=#st{ct=[]}}=Vst) -> - valfun_3(I, Vst); -valfun_2(_, _) -> + fork_state(Fail, Vst); +branch_exception(#vst{current=#st{ct=[]}}=Vst) -> + Vst; +branch_exception(_) -> error(ambiguous_catch_try_state). %% Handle the remaining floating point instructions here. %% Floating point. -valfun_3({fconv,Src,{fr,_}=Dst}, Vst) -> +valfun_2({fconv,Src,{fr,_}=Dst}, Vst) -> assert_term(Src, Vst), %% An exception is raised on error, hence branching to 0. @@ -670,72 +741,32 @@ valfun_3({fconv,Src,{fr,_}=Dst}, Vst) -> SuccVst = update_type(fun meet/2, number, Src, SuccVst0), set_freg(Dst, SuccVst) end); -valfun_3({bif,fadd,_,[_,_]=Ss,Dst}, Vst) -> +valfun_2({bif,fadd,_,[_,_]=Ss,Dst}, Vst) -> float_op(Ss, Dst, Vst); -valfun_3({bif,fdiv,_,[_,_]=Ss,Dst}, Vst) -> +valfun_2({bif,fdiv,_,[_,_]=Ss,Dst}, Vst) -> float_op(Ss, Dst, Vst); -valfun_3({bif,fmul,_,[_,_]=Ss,Dst}, Vst) -> +valfun_2({bif,fmul,_,[_,_]=Ss,Dst}, Vst) -> float_op(Ss, Dst, Vst); -valfun_3({bif,fnegate,_,[_]=Ss,Dst}, Vst) -> +valfun_2({bif,fnegate,_,[_]=Ss,Dst}, Vst) -> float_op(Ss, Dst, Vst); -valfun_3({bif,fsub,_,[_,_]=Ss,Dst}, Vst) -> +valfun_2({bif,fsub,_,[_,_]=Ss,Dst}, Vst) -> float_op(Ss, Dst, Vst); -valfun_3(fclearerror, Vst) -> +valfun_2(fclearerror, Vst) -> case get_fls(Vst) of - undefined -> ok; - checked -> ok; - Fls -> error({bad_floating_point_state,Fls}) + undefined -> ok; + checked -> ok; + Fls -> error({bad_floating_point_state,Fls}) end, set_fls(cleared, Vst); -valfun_3({fcheckerror,_}, Vst) -> +valfun_2({fcheckerror,_}, Vst) -> assert_fls(cleared, Vst), set_fls(checked, Vst); -valfun_3(I, Vst) -> - %% The instruction is not a float instruction. - case get_fls(Vst) of - undefined -> - valfun_4(I, Vst); - checked -> - valfun_4(I, Vst); - Fls -> - error({unsafe_instruction,{float_error_state,Fls}}) - end. +valfun_2(I, Vst) -> + assert_float_checked(Vst), + valfun_3(I, Vst). %% Instructions that can cause exceptions. -valfun_4({apply,Live}, Vst) -> - call(apply, Live+2, Vst); -valfun_4({apply_last,Live,_}, Vst) -> - tail_call(apply, Live+2, Vst); -valfun_4({call_fun,Live}, Vst) -> - Fun = {x,Live}, - assert_term(Fun, Vst), - - %% An exception is raised on error, hence branching to 0. - branch(0, Vst, - fun(SuccVst0) -> - SuccVst = update_type(fun meet/2, #t_fun{arity=Live}, - Fun, SuccVst0), - call('fun', Live+1, SuccVst) - end); -valfun_4({call,Live,Func}, Vst) -> - call(Func, Live, Vst); -valfun_4({call_ext,Live,Func}, Vst) -> - %% Exception BIFs has already been taken care of above. - call(Func, Live, Vst); -valfun_4({call_only,Live,Func}, Vst) -> - tail_call(Func, Live, Vst); -valfun_4({call_ext_only,Live,Func}, Vst) -> - tail_call(Func, Live, Vst); -valfun_4({call_last,Live,Func,StkSize}, #vst{current=#st{numy=StkSize}}=Vst) -> - tail_call(Func, Live, Vst); -valfun_4({call_last,_,_,_}, #vst{current=#st{numy=NumY}}) -> - error({allocated,NumY}); -valfun_4({call_ext_last,Live,Func,StkSize}, - #vst{current=#st{numy=StkSize}}=Vst) -> - tail_call(Func, Live, Vst); -valfun_4({call_ext_last,_,_,_}, #vst{current=#st{numy=NumY}}) -> - error({allocated,NumY}); -valfun_4({make_fun2,{f,Lbl},_,_,NumFree}, #vst{ft=Ft}=Vst0) -> +valfun_3({make_fun2,{f,Lbl},_,_,NumFree}, #vst{ft=Ft}=Vst0) -> #{ arity := Arity0 } = gb_trees:get(Lbl, Ft), Arity = Arity0 - NumFree, @@ -747,22 +778,22 @@ valfun_4({make_fun2,{f,Lbl},_,_,NumFree}, #vst{ft=Ft}=Vst0) -> create_term(#t_fun{arity=Arity}, make_fun, [], {x,0}, Vst); %% Other BIFs -valfun_4({bif,raise,{f,0},Src,_Dst}, Vst) -> +valfun_3({bif,raise,{f,0},Src,_Dst}, Vst) -> validate_src(Src, Vst), kill_state(Vst); -valfun_4(raw_raise=I, Vst) -> +valfun_3(raw_raise=I, Vst) -> call(I, 3, Vst); -valfun_4({bif,Op,{f,Fail},Ss,Dst}, Vst) -> +valfun_3({bif,Op,{f,Fail},Ss,Dst}, Vst) -> validate_src(Ss, Vst), validate_bif(Op, Fail, Ss, Dst, Vst); -valfun_4({gc_bif,Op,{f,Fail},Live,Ss,Dst}, Vst) -> +valfun_3({gc_bif,Op,{f,Fail},Live,Ss,Dst}, Vst) -> validate_gc_bif(Op, Fail, Ss, Dst, Live, Vst); -valfun_4(return, #vst{current=#st{numy=none}}=Vst) -> +valfun_3(return, #vst{current=#st{numy=none}}=Vst) -> assert_durable_term({x,0}, Vst), kill_state(Vst); -valfun_4(return, #vst{current=#st{numy=NumY}}) -> +valfun_3(return, #vst{current=#st{numy=NumY}}) -> error({stack_frame,NumY}); -valfun_4({loop_rec,{f,Fail},Dst}, Vst) -> +valfun_3({loop_rec,{f,Fail},Dst}, Vst) -> %% This term may not be part of the root set until remove_message/0 is %% executed. If control transfers to the loop_rec_end/1 instruction, no %% part of this term must be stored in a Y register. @@ -771,55 +802,55 @@ valfun_4({loop_rec,{f,Fail},Dst}, Vst) -> {Ref, SuccVst} = new_value(any, loop_rec, [], SuccVst0), mark_fragile(Dst, set_reg_vref(Ref, Dst, SuccVst)) end); -valfun_4({wait,_}, Vst) -> +valfun_3({wait,_}, Vst) -> verify_y_init(Vst), kill_state(Vst); -valfun_4({wait_timeout,_,Src}, Vst) -> +valfun_3({wait_timeout,_,Src}, Vst) -> assert_term(Src, Vst), verify_y_init(Vst), prune_x_regs(0, Vst); -valfun_4({loop_rec_end,_}, Vst) -> +valfun_3({loop_rec_end,_}, Vst) -> verify_y_init(Vst), kill_state(Vst); -valfun_4(timeout, Vst) -> +valfun_3(timeout, Vst) -> prune_x_regs(0, Vst); -valfun_4(send, Vst) -> +valfun_3(send, Vst) -> call(send, 2, Vst); %% Match instructions. -valfun_4({select_val,Src,{f,Fail},{list,Choices}}, Vst) -> +valfun_3({select_val,Src,{f,Fail},{list,Choices}}, Vst) -> assert_term(Src, Vst), assert_choices(Choices), validate_select_val(Fail, Choices, Src, Vst); -valfun_4({select_tuple_arity,Tuple,{f,Fail},{list,Choices}}, Vst) -> +valfun_3({select_tuple_arity,Tuple,{f,Fail},{list,Choices}}, Vst) -> assert_type(#t_tuple{}, Tuple, Vst), assert_arities(Choices), validate_select_tuple_arity(Fail, Choices, Tuple, Vst); %% New bit syntax matching instructions. -valfun_4({test,bs_start_match3,{f,Fail},Live,[Src],Dst}, Vst) -> +valfun_3({test,bs_start_match3,{f,Fail},Live,[Src],Dst}, Vst) -> validate_bs_start_match(Fail, Live, bsm_match_state(), Src, Dst, Vst); -valfun_4({test,bs_start_match2,{f,Fail},Live,[Src,Slots],Dst}, Vst) -> +valfun_3({test,bs_start_match2,{f,Fail},Live,[Src,Slots],Dst}, Vst) -> validate_bs_start_match(Fail, Live, bsm_match_state(Slots), Src, Dst, Vst); -valfun_4({test,bs_match_string,{f,Fail},[Ctx,_,_]}, Vst) -> +valfun_3({test,bs_match_string,{f,Fail},[Ctx,_,_]}, Vst) -> assert_type(#t_bs_context{}, Ctx, Vst), branch(Fail, Vst, fun(V) -> V end); -valfun_4({test,bs_skip_bits2,{f,Fail},[Ctx,Src,_,_]}, Vst) -> +valfun_3({test,bs_skip_bits2,{f,Fail},[Ctx,Src,_,_]}, Vst) -> assert_type(#t_bs_context{}, Ctx, Vst), assert_term(Src, Vst), branch(Fail, Vst, fun(V) -> V end); -valfun_4({test,bs_test_tail2,{f,Fail},[Ctx,_]}, Vst) -> +valfun_3({test,bs_test_tail2,{f,Fail},[Ctx,_]}, Vst) -> assert_type(#t_bs_context{}, Ctx, Vst), branch(Fail, Vst, fun(V) -> V end); -valfun_4({test,bs_test_unit,{f,Fail},[Ctx,_]}, Vst) -> +valfun_3({test,bs_test_unit,{f,Fail},[Ctx,_]}, Vst) -> assert_type(#t_bs_context{}, Ctx, Vst), branch(Fail, Vst, fun(V) -> V end); -valfun_4({test,bs_skip_utf8,{f,Fail},[Ctx,Live,_]}, Vst) -> +valfun_3({test,bs_skip_utf8,{f,Fail},[Ctx,Live,_]}, Vst) -> validate_bs_skip_utf(Fail, Ctx, Live, Vst); -valfun_4({test,bs_skip_utf16,{f,Fail},[Ctx,Live,_]}, Vst) -> +valfun_3({test,bs_skip_utf16,{f,Fail},[Ctx,Live,_]}, Vst) -> validate_bs_skip_utf(Fail, Ctx, Live, Vst); -valfun_4({test,bs_skip_utf32,{f,Fail},[Ctx,Live,_]}, Vst) -> +valfun_3({test,bs_skip_utf32,{f,Fail},[Ctx,Live,_]}, Vst) -> validate_bs_skip_utf(Fail, Ctx, Live, Vst); -valfun_4({test,bs_get_integer2=Op,{f,Fail},Live, +valfun_3({test,bs_get_integer2=Op,{f,Fail},Live, [Ctx,{integer,Size},Unit,{field_flags,Flags}],Dst},Vst) when Size * Unit =< 64 -> Type = case member(unsigned, Flags) of @@ -831,66 +862,66 @@ valfun_4({test,bs_get_integer2=Op,{f,Fail},Live, #t_integer{} end, validate_bs_get(Op, Fail, Ctx, Live, Type, Dst, Vst); -valfun_4({test,bs_get_integer2=Op,{f,Fail},Live, +valfun_3({test,bs_get_integer2=Op,{f,Fail},Live, [Ctx,_Size,_Unit,_Flags],Dst},Vst) -> validate_bs_get(Op, Fail, Ctx, Live, #t_integer{}, Dst, Vst); -valfun_4({test,bs_get_float2=Op,{f,Fail},Live,[Ctx,_,_,_],Dst}, Vst) -> +valfun_3({test,bs_get_float2=Op,{f,Fail},Live,[Ctx,_,_,_],Dst}, Vst) -> validate_bs_get(Op, Fail, Ctx, Live, float, Dst, Vst); -valfun_4({test,bs_get_binary2=Op,{f,Fail},Live,[Ctx,_,Unit,_],Dst}, Vst) -> +valfun_3({test,bs_get_binary2=Op,{f,Fail},Live,[Ctx,_,Unit,_],Dst}, Vst) -> validate_bs_get(Op, Fail, Ctx, Live, #t_bitstring{unit=Unit}, Dst, Vst); -valfun_4({test,bs_get_utf8=Op,{f,Fail},Live,[Ctx,_],Dst}, Vst) -> +valfun_3({test,bs_get_utf8=Op,{f,Fail},Live,[Ctx,_],Dst}, Vst) -> Type = beam_types:make_integer(0, ?UNICODE_MAX), validate_bs_get(Op, Fail, Ctx, Live, Type, Dst, Vst); -valfun_4({test,bs_get_utf16=Op,{f,Fail},Live,[Ctx,_],Dst}, Vst) -> +valfun_3({test,bs_get_utf16=Op,{f,Fail},Live,[Ctx,_],Dst}, Vst) -> Type = beam_types:make_integer(0, ?UNICODE_MAX), validate_bs_get(Op, Fail, Ctx, Live, Type, Dst, Vst); -valfun_4({test,bs_get_utf32=Op,{f,Fail},Live,[Ctx,_],Dst}, Vst) -> +valfun_3({test,bs_get_utf32=Op,{f,Fail},Live,[Ctx,_],Dst}, Vst) -> Type = beam_types:make_integer(0, ?UNICODE_MAX), validate_bs_get(Op, Fail, Ctx, Live, Type, Dst, Vst); -valfun_4({bs_save2,Ctx,SavePoint}, Vst) -> +valfun_3({bs_save2,Ctx,SavePoint}, Vst) -> bsm_save(Ctx, SavePoint, Vst); -valfun_4({bs_restore2,Ctx,SavePoint}, Vst) -> +valfun_3({bs_restore2,Ctx,SavePoint}, Vst) -> bsm_restore(Ctx, SavePoint, Vst); -valfun_4({bs_get_position, Ctx, Dst, Live}, Vst0) -> +valfun_3({bs_get_position, Ctx, Dst, Live}, Vst0) -> assert_type(#t_bs_context{}, Ctx, Vst0), verify_live(Live, Vst0), verify_y_init(Vst0), Vst = prune_x_regs(Live, Vst0), create_term(#t_abstract{kind=ms_position}, bs_get_position, [Ctx], Dst, Vst, Vst0); -valfun_4({bs_set_position, Ctx, Pos}, Vst) -> +valfun_3({bs_set_position, Ctx, Pos}, Vst) -> assert_type(#t_bs_context{}, Ctx, Vst), assert_type(#t_abstract{kind=ms_position}, Pos, Vst), Vst; %% Other test instructions. -valfun_4({test,has_map_fields,{f,Lbl},Src,{list,List}}, Vst) -> +valfun_3({test,has_map_fields,{f,Lbl},Src,{list,List}}, Vst) -> assert_type(#t_map{}, Src, Vst), assert_unique_map_keys(List), branch(Lbl, Vst, fun(V) -> V end); -valfun_4({test,is_atom,{f,Lbl},[Src]}, Vst) -> +valfun_3({test,is_atom,{f,Lbl},[Src]}, Vst) -> type_test(Lbl, #t_atom{}, Src, Vst); -valfun_4({test,is_binary,{f,Lbl},[Src]}, Vst) -> +valfun_3({test,is_binary,{f,Lbl},[Src]}, Vst) -> type_test(Lbl, #t_bitstring{unit=8}, Src, Vst); -valfun_4({test,is_bitstr,{f,Lbl},[Src]}, Vst) -> +valfun_3({test,is_bitstr,{f,Lbl},[Src]}, Vst) -> type_test(Lbl, #t_bitstring{}, Src, Vst); -valfun_4({test,is_boolean,{f,Lbl},[Src]}, Vst) -> +valfun_3({test,is_boolean,{f,Lbl},[Src]}, Vst) -> type_test(Lbl, beam_types:make_boolean(), Src, Vst); -valfun_4({test,is_float,{f,Lbl},[Src]}, Vst) -> +valfun_3({test,is_float,{f,Lbl},[Src]}, Vst) -> type_test(Lbl, float, Src, Vst); -valfun_4({test,is_tuple,{f,Lbl},[Src]}, Vst) -> +valfun_3({test,is_tuple,{f,Lbl},[Src]}, Vst) -> type_test(Lbl, #t_tuple{}, Src, Vst); -valfun_4({test,is_integer,{f,Lbl},[Src]}, Vst) -> +valfun_3({test,is_integer,{f,Lbl},[Src]}, Vst) -> type_test(Lbl, #t_integer{}, Src, Vst); -valfun_4({test,is_nonempty_list,{f,Lbl},[Src]}, Vst) -> +valfun_3({test,is_nonempty_list,{f,Lbl},[Src]}, Vst) -> type_test(Lbl, cons, Src, Vst); -valfun_4({test,is_number,{f,Lbl},[Src]}, Vst) -> +valfun_3({test,is_number,{f,Lbl},[Src]}, Vst) -> type_test(Lbl, number, Src, Vst); -valfun_4({test,is_list,{f,Lbl},[Src]}, Vst) -> +valfun_3({test,is_list,{f,Lbl},[Src]}, Vst) -> type_test(Lbl, list, Src, Vst); -valfun_4({test,is_map,{f,Lbl},[Src]}, Vst) -> +valfun_3({test,is_map,{f,Lbl},[Src]}, Vst) -> type_test(Lbl, #t_map{}, Src, Vst); -valfun_4({test,is_nil,{f,Lbl},[Src]}, Vst) -> +valfun_3({test,is_nil,{f,Lbl},[Src]}, Vst) -> %% is_nil is an exact check against the 'nil' value, and should not be %% treated as a simple type test. assert_term(Src, Vst), @@ -901,16 +932,16 @@ valfun_4({test,is_nil,{f,Lbl},[Src]}, Vst) -> fun(SuccVst) -> update_eq_types(Src, nil, SuccVst) end); -valfun_4({test,test_arity,{f,Lbl},[Tuple,Sz]}, Vst) when is_integer(Sz) -> +valfun_3({test,test_arity,{f,Lbl},[Tuple,Sz]}, Vst) when is_integer(Sz) -> assert_type(#t_tuple{}, Tuple, Vst), Type = #t_tuple{exact=true,size=Sz}, type_test(Lbl, Type, Tuple, Vst); -valfun_4({test,is_tagged_tuple,{f,Lbl},[Src,Sz,Atom]}, Vst) -> +valfun_3({test,is_tagged_tuple,{f,Lbl},[Src,Sz,Atom]}, Vst) -> assert_term(Src, Vst), Es = #{ 1 => get_literal_type(Atom) }, Type = #t_tuple{exact=true,size=Sz,elements=Es}, type_test(Lbl, Type, Src, Vst); -valfun_4({test,is_eq_exact,{f,Lbl},[Src,Val]=Ss}, Vst) -> +valfun_3({test,is_eq_exact,{f,Lbl},[Src,Val]=Ss}, Vst) -> validate_src(Ss, Vst), branch(Lbl, Vst, fun(FailVst) -> @@ -919,7 +950,7 @@ valfun_4({test,is_eq_exact,{f,Lbl},[Src,Val]=Ss}, Vst) -> fun(SuccVst) -> update_eq_types(Src, Val, SuccVst) end); -valfun_4({test,is_ne_exact,{f,Lbl},[Src,Val]=Ss}, Vst) -> +valfun_3({test,is_ne_exact,{f,Lbl},[Src,Val]=Ss}, Vst) -> validate_src(Ss, Vst), branch(Lbl, Vst, fun(FailVst) -> @@ -928,30 +959,30 @@ valfun_4({test,is_ne_exact,{f,Lbl},[Src,Val]=Ss}, Vst) -> fun(SuccVst) -> update_ne_types(Src, Val, SuccVst) end); -valfun_4({test,_Op,{f,Lbl},Src}, Vst) -> +valfun_3({test,_Op,{f,Lbl},Src}, Vst) -> %% is_pid, is_reference, et cetera. validate_src(Src, Vst), branch(Lbl, Vst, fun(V) -> V end); -valfun_4({bs_add,{f,Fail},[A,B,_],Dst}, Vst) -> +valfun_3({bs_add,{f,Fail},[A,B,_],Dst}, Vst) -> assert_term(A, Vst), assert_term(B, Vst), branch(Fail, Vst, fun(SuccVst) -> create_term(#t_integer{}, bs_add, [A, B], Dst, SuccVst) end); -valfun_4({bs_utf8_size,{f,Fail},A,Dst}, Vst) -> +valfun_3({bs_utf8_size,{f,Fail},A,Dst}, Vst) -> assert_term(A, Vst), branch(Fail, Vst, fun(SuccVst) -> create_term(#t_integer{}, bs_utf8_size, [A], Dst, SuccVst) end); -valfun_4({bs_utf16_size,{f,Fail},A,Dst}, Vst) -> +valfun_3({bs_utf16_size,{f,Fail},A,Dst}, Vst) -> assert_term(A, Vst), branch(Fail, Vst, fun(SuccVst) -> create_term(#t_integer{}, bs_utf16_size, [A], Dst, SuccVst) end); -valfun_4({bs_init2,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) -> +valfun_3({bs_init2,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) -> verify_live(Live, Vst0), verify_y_init(Vst0), if @@ -967,7 +998,7 @@ valfun_4({bs_init2,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) -> create_term(#t_bitstring{unit=8}, bs_init2, [], Dst, SuccVst, SuccVst0) end); -valfun_4({bs_init_bits,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) -> +valfun_3({bs_init_bits,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) -> verify_live(Live, Vst0), verify_y_init(Vst0), if @@ -982,7 +1013,7 @@ valfun_4({bs_init_bits,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) -> SuccVst = prune_x_regs(Live, SuccVst0), create_term(#t_bitstring{}, bs_init_bits, [], Dst, SuccVst) end); -valfun_4({bs_append,{f,Fail},Bits,Heap,Live,Unit,Bin,_Flags,Dst}, Vst0) -> +valfun_3({bs_append,{f,Fail},Bits,Heap,Live,Unit,Bin,_Flags,Dst}, Vst0) -> verify_live(Live, Vst0), verify_y_init(Vst0), assert_term(Bits, Vst0), @@ -994,7 +1025,7 @@ valfun_4({bs_append,{f,Fail},Bits,Heap,Live,Unit,Bin,_Flags,Dst}, Vst0) -> create_term(#t_bitstring{unit=Unit}, bs_append, [Bin], Dst, SuccVst, SuccVst0) end); -valfun_4({bs_private_append,{f,Fail},Bits,Unit,Bin,_Flags,Dst}, Vst) -> +valfun_3({bs_private_append,{f,Fail},Bits,Unit,Bin,_Flags,Dst}, Vst) -> assert_term(Bits, Vst), assert_term(Bin, Vst), branch(Fail, Vst, @@ -1002,55 +1033,55 @@ valfun_4({bs_private_append,{f,Fail},Bits,Unit,Bin,_Flags,Dst}, Vst) -> create_term(#t_bitstring{unit=Unit}, bs_private_append, [Bin], Dst, SuccVst) end); -valfun_4({bs_put_string,Sz,_}, Vst) when is_integer(Sz) -> +valfun_3({bs_put_string,Sz,_}, Vst) when is_integer(Sz) -> Vst; -valfun_4({bs_put_binary,{f,Fail},Sz,_,_,Src}, Vst) -> +valfun_3({bs_put_binary,{f,Fail},Sz,_,_,Src}, Vst) -> assert_term(Sz, Vst), assert_term(Src, Vst), branch(Fail, Vst, fun(SuccVst) -> update_type(fun meet/2, #t_bitstring{}, Src, SuccVst) end); -valfun_4({bs_put_float,{f,Fail},Sz,_,_,Src}, Vst) -> +valfun_3({bs_put_float,{f,Fail},Sz,_,_,Src}, Vst) -> assert_term(Sz, Vst), assert_term(Src, Vst), branch(Fail, Vst, fun(SuccVst) -> update_type(fun meet/2, float, Src, SuccVst) end); -valfun_4({bs_put_integer,{f,Fail},Sz,_,_,Src}, Vst) -> +valfun_3({bs_put_integer,{f,Fail},Sz,_,_,Src}, Vst) -> assert_term(Sz, Vst), assert_term(Src, Vst), branch(Fail, Vst, fun(SuccVst) -> update_type(fun meet/2, #t_integer{}, Src, SuccVst) end); -valfun_4({bs_put_utf8,{f,Fail},_,Src}, Vst) -> +valfun_3({bs_put_utf8,{f,Fail},_,Src}, Vst) -> assert_term(Src, Vst), branch(Fail, Vst, fun(SuccVst) -> update_type(fun meet/2, #t_integer{}, Src, SuccVst) end); -valfun_4({bs_put_utf16,{f,Fail},_,Src}, Vst) -> +valfun_3({bs_put_utf16,{f,Fail},_,Src}, Vst) -> assert_term(Src, Vst), branch(Fail, Vst, fun(SuccVst) -> update_type(fun meet/2, #t_integer{}, Src, SuccVst) end); -valfun_4({bs_put_utf32,{f,Fail},_,Src}, Vst) -> +valfun_3({bs_put_utf32,{f,Fail},_,Src}, Vst) -> assert_term(Src, Vst), branch(Fail, Vst, fun(SuccVst) -> update_type(fun meet/2, #t_integer{}, Src, SuccVst) end); %% Map instructions. -valfun_4({put_map_assoc=Op,{f,Fail},Src,Dst,Live,{list,List}}, Vst) -> +valfun_3({put_map_assoc=Op,{f,Fail},Src,Dst,Live,{list,List}}, Vst) -> verify_put_map(Op, Fail, Src, Dst, Live, List, Vst); -valfun_4({put_map_exact=Op,{f,Fail},Src,Dst,Live,{list,List}}, Vst) -> +valfun_3({put_map_exact=Op,{f,Fail},Src,Dst,Live,{list,List}}, Vst) -> verify_put_map(Op, Fail, Src, Dst, Live, List, Vst); -valfun_4({get_map_elements,{f,Fail},Src,{list,List}}, Vst) -> +valfun_3({get_map_elements,{f,Fail},Src,{list,List}}, Vst) -> verify_get_map(Fail, Src, List, Vst); -valfun_4(_, _) -> +valfun_3(_, _) -> error(unknown_instruction). verify_get_map(Fail, Src, List, Vst0) -> diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl index 68b665fbc3..e4e34ec0d2 100644 --- a/lib/compiler/test/beam_validator_SUITE.erl +++ b/lib/compiler/test/beam_validator_SUITE.erl @@ -36,7 +36,7 @@ val_dsetel/1,bad_tuples/1,bad_try_catch_nesting/1, receive_stacked/1,aliased_types/1,type_conflict/1, infer_on_eq/1,infer_dead_value/1,infer_on_ne/1, - branch_to_try_handler/1]). + branch_to_try_handler/1,call_without_stack/1]). -include_lib("common_test/include/ct.hrl"). @@ -67,7 +67,7 @@ groups() -> bad_tuples,bad_try_catch_nesting, receive_stacked,aliased_types,type_conflict, infer_on_eq,infer_dead_value,infer_on_ne, - branch_to_try_handler]}]. + branch_to_try_handler,call_without_stack]}]. init_per_suite(Config) -> test_lib:recompile(?MODULE), @@ -150,19 +150,34 @@ stack(Config) when is_list(Config) -> call_last(Config) when is_list(Config) -> Errors = do_val(call_last, Config), - [{{t,a,1},{{call_last,1,{f,8},2},9,{allocated,1}}}, + [{{t,a,1}, + {{call_last,1,{f,8},2},9,{allocated,1}}}, {{t,b,1}, - {{call_ext_last,2,{extfunc,lists,seq,2},2}, - 10, - {allocated,1}}}] = Errors, + {{call_ext_last,2,{extfunc,lists,seq,2},2},10,{allocated,1}}}, + {{t,baz,2}, + {{call_ext_only,2,{extfunc,erlang,put,2}},5,{allocated,0}}}, + {{t,biz,2}, + {{call_only,2,{f,10}},5,{allocated,0}}}] = Errors, + ok. + +call_without_stack(Config) when is_list(Config) -> + Errors = do_val(call_without_stack, Config), + [{{t,local,2}, + {{call,2,{f,2}},4,{allocated,none}}}, + {{t,remote,2}, + {{call_ext,2,{extfunc,lists,seq,2}},4,{allocated,none}}}] = Errors, ok. merge_undefined(Config) when is_list(Config) -> Errors = do_val(merge_undefined, Config), - [{{t,handle_call,2}, + [{{t,undecided,2}, {{call_ext,2,{extfunc,debug,filter,2}}, 22, - {uninitialized_reg,{y,_}}}}] = Errors, + {allocated,undecided}}}, + {{t,uninitialized,2}, + {{call_ext,2,{extfunc,io,format,2}}, + 17, + {uninitialized_reg,{y,1}}}}] = Errors, ok. uninit(Config) when is_list(Config) -> @@ -265,7 +280,7 @@ freg_uninit(Config) when is_list(Config) -> {uninitialized_reg,{fr,1}}}}, {{t,sum_2,2}, {{bif,fadd,{f,0},[{fr,0},{fr,1}],{fr,0}}, - 9, + 10, {uninitialized_reg,{fr,0}}}}] = Errors, ok. diff --git a/lib/compiler/test/beam_validator_SUITE_data/call_last.S b/lib/compiler/test/beam_validator_SUITE_data/call_last.S index 827b6c0ae6..ff81da1b57 100644 --- a/lib/compiler/test/beam_validator_SUITE_data/call_last.S +++ b/lib/compiler/test/beam_validator_SUITE_data/call_last.S @@ -1,6 +1,6 @@ {module, call_last}. %% version = 0 -{exports, [{a,1},{b,1},{bar,1},{foo,1},{module_info,0},{module_info,1}]}. +{exports, [{a,1},{b,1},{bar,1},{foo,1},{baz,2},{biz,2}]}. {attributes, []}. @@ -53,19 +53,16 @@ {'%live',1}. return. - -{function, module_info, 0, 10}. +{function, baz, 2, 10}. {label,9}. - {func_info,{atom,t},{atom,module_info},0}. + {func_info,{atom,t},{atom,baz},2}. {label,10}. - {move,{atom,t},{x,0}}. - {call_ext_only,1,{extfunc,erlang,get_module_info,1}}. - + {allocate,0,2}. + {call_ext_only,2,{extfunc,erlang,put,2}}. -{function, module_info, 1, 12}. +{function, biz, 2, 12}. {label,11}. - {func_info,{atom,t},{atom,module_info},1}. + {func_info,{atom,t},{atom,biz},2}. {label,12}. - {move,{x,0},{x,1}}. - {move,{atom,t},{x,0}}. - {call_ext_only,2,{extfunc,erlang,get_module_info,2}}. + {allocate,0,2}. + {call_only,2,{f,10}}. diff --git a/lib/compiler/test/beam_validator_SUITE_data/call_without_stack.S b/lib/compiler/test/beam_validator_SUITE_data/call_without_stack.S new file mode 100644 index 0000000000..9ccbc163e3 --- /dev/null +++ b/lib/compiler/test/beam_validator_SUITE_data/call_without_stack.S @@ -0,0 +1,21 @@ +{module, call_without_stack}. %% version = 0 + +{exports, [{remote,2},{local,2}]}. + +{attributes, []}. + +{labels, 9}. + +{function, remote, 2, 2}. + {label,1}. + {func_info,{atom,t},{atom,remote},2}. + {label,2}. + {call_ext,2,{extfunc,lists,seq,2}}. + if_end. + +{function, local, 2, 4}. + {label,3}. + {func_info,{atom,t},{atom,local},2}. + {label,4}. + {call,2,{f,2}}. + if_end. diff --git a/lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S b/lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S index 71e833446a..2d4cbc9388 100644 --- a/lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S +++ b/lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S @@ -21,12 +21,14 @@ {label,3}. {func_info,{atom,t},{atom,sum_2},2}. {label,4}. + {allocate,0,2}. {fconv,{x,0},{fr,0}}. {fconv,{x,1},{fr,1}}. fclearerror. {fcheckerror,{f,0}}. {call,2,{f,6}}. {bif,fadd,{f,0},[{fr,0},{fr,1}],{fr,0}}. + {deallocate,0}. return. {function, foo, 2, 6}. diff --git a/lib/compiler/test/beam_validator_SUITE_data/merge_undefined.S b/lib/compiler/test/beam_validator_SUITE_data/merge_undefined.S index aa344807e4..3035471f04 100644 --- a/lib/compiler/test/beam_validator_SUITE_data/merge_undefined.S +++ b/lib/compiler/test/beam_validator_SUITE_data/merge_undefined.S @@ -1,15 +1,14 @@ {module, merge_undefined}. %% version = 0 -{exports, [{bar,2},{foo,1},{handle_call,2},{module_info,0},{module_info,1}]}. +{exports, [{uninitialized,2},{undecided,2}]}. {attributes, []}. {labels, 15}. - -{function, handle_call, 2, 2}. +{function, uninitialized, 2, 2}. {label,1}. - {func_info,{atom,t},{atom,handle_call},2}. + {func_info,{atom,t},{atom,uninitialized},2}. {label,2}. {test,is_atom,{f,1},[{x,0}]}. {select_val,{x,0},{f,1},{list,[{atom,gurka},{f,3},{atom,delete},{f,4}]}}. @@ -21,7 +20,7 @@ {move,{atom,nisse},{x,0}}. {call_ext,1,{extfunc,erlang,exit,1}}. {label,4}. - {allocate_heap,1,6,2}. + {allocate_heap,2,6,2}. {move,{x,1},{y,0}}. {put_list,{integer,112},nil,{x,0}}. {put_list,{integer,126},{x,0},{x,0}}. @@ -51,37 +50,57 @@ {call_ext,1,{extfunc,erlang,exit,1}}. {label,6}. {move,{y,0},{x,0}}. - {call_last,1,{f,8},1}. + {call_last,1,{f,14},1}. - -{function, foo, 1, 8}. +{function, undecided, 2, 8}. {label,7}. - {func_info,{atom,t},{atom,foo},1}. + {func_info,{atom,t},{atom,undecided},2}. {label,8}. - {move,{atom,ok},{x,0}}. - return. - - -{function, bar, 2, 10}. + {test,is_atom,{f,7},[{x,0}]}. + {select_val,{x,0},{f,1},{list,[{atom,gurka},{f,9},{atom,delete},{f,10}]}}. {label,9}. - {func_info,{atom,t},{atom,bar},2}. + {allocate_heap,2,6,2}. + {test,is_eq_exact,{f,11},[{x,0},{atom,ok}]}. + %% This is unreachable since {x,0} is known not to be 'ok'. We should not + %% fail with "uninitialized y registers" on erlang:exit/1 + {move,{atom,nisse},{x,0}}. + {call_ext,1,{extfunc,erlang,exit,1}}. {label,10}. - {move,{atom,ok},{x,0}}. - return. - - -{function, module_info, 0, 12}. + {allocate_heap,1,6,2}. + {move,{x,1},{y,0}}. + {put_list,{integer,112},nil,{x,0}}. + {put_list,{integer,126},{x,0},{x,0}}. + {put_list,{y,0},nil,{x,1}}. + {'%live',2}. + {call_ext,2,{extfunc,io,format,2}}. + {test,is_ne_exact,{f,12},[{x,0},{atom,ok}]}. {label,11}. - {func_info,{atom,t},{atom,module_info},0}. + %% The number of allocated Y registers are in conflict here. + {move,{atom,logReader},{x,1}}. + {move,{atom,console},{x,0}}. + {call_ext,2,{extfunc,debug,filter,2}}. + {test_heap,14,1}. + {put_list,{atom,logReader},nil,{x,1}}. + {put_list,{atom,console},{x,1},{x,1}}. + {put_tuple,3,{x,2}}. + {put,{atom,debug}}. + {put,{atom,filter}}. + {put,{x,1}}. + {put_tuple,2,{x,1}}. + {put,{x,2}}. + {put,{x,0}}. + {put_tuple,2,{x,0}}. + {put,{atom,badmatch}}. + {put,{x,1}}. + {'%live',1}. + {call_ext,1,{extfunc,erlang,exit,1}}. {label,12}. - {move,{atom,t},{x,0}}. - {call_ext_only,1,{extfunc,erlang,get_module_info,1}}. - + {move,{y,0},{x,0}}. + {call_last,1,{f,8},1}. -{function, module_info, 1, 14}. +{function, foo, 1, 14}. {label,13}. - {func_info,{atom,t},{atom,module_info},1}. + {func_info,{atom,t},{atom,foo},1}. {label,14}. - {move,{x,0},{x,1}}. - {move,{atom,t},{x,0}}. - {call_ext_only,2,{extfunc,erlang,get_module_info,2}}. + {move,{atom,ok},{x,0}}. + return. diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk index 7192ddca15..5434fdf90a 100644 --- a/lib/compiler/vsn.mk +++ b/lib/compiler/vsn.mk @@ -1 +1 @@ -COMPILER_VSN = 7.4.4 +COMPILER_VSN = 7.4.5 diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 3973cf3f9f..5c1f6af016 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -796,7 +796,7 @@ </func> <func> - <name name="mac" arity="3" since="OTP @OTP-13872@"/> + <name name="mac" arity="3" since="OTP 22.1"/> <fsummary></fsummary> <desc> <p>Short for <seealso marker="#mac-4">mac(Type, undefined, Key, Data)</seealso>. @@ -805,7 +805,7 @@ </func> <func> - <name name="mac" arity="4" since="OTP @OTP-13872@"/> + <name name="mac" arity="4" since="OTP 22.1"/> <fsummary></fsummary> <desc> <p>Computes a MAC (Message Authentication Code) of type <c>Type</c> from <c>Data</c>. @@ -846,7 +846,7 @@ </func> <func> - <name name="macN" arity="4" since="OTP @OTP-13872@"/> + <name name="macN" arity="4" since="OTP 22.1"/> <fsummary></fsummary> <desc> <p>Short for <seealso marker="#macN-5">macN(Type, undefined, Key, Data, MacLength)</seealso>. @@ -855,7 +855,7 @@ </func> <func> - <name name="macN" arity="5" since="OTP @OTP-13872@"/> + <name name="macN" arity="5" since="OTP 22.1"/> <fsummary></fsummary> <desc> <p>Computes a MAC (Message Authentication Code) @@ -874,7 +874,7 @@ </func> <func> - <name name="mac_init" arity="2" since="OTP @OTP-13872@"/> + <name name="mac_init" arity="2" since="OTP 22.1"/> <fsummary></fsummary> <desc> <p>Short for <seealso marker="#mac_init-3">mac_init(Type, undefined, Key)</seealso>. @@ -883,7 +883,7 @@ </func> <func> - <name name="mac_init" arity="3" since="OTP @OTP-13872@"/> + <name name="mac_init" arity="3" since="OTP 22.1"/> <fsummary></fsummary> <desc> <p>Initializes the context for streaming MAC operations. @@ -929,7 +929,7 @@ </func> <func> - <name name="mac_update" arity="2" since="OTP @OTP-13872@"/> + <name name="mac_update" arity="2" since="OTP 22.1"/> <fsummary></fsummary> <desc> <p>Updates the MAC represented by <c>State0</c> using the given <c>Data</c> which @@ -945,7 +945,7 @@ </func> <func> - <name name="mac_final" arity="1" since="OTP @OTP-13872@"/> + <name name="mac_final" arity="1" since="OTP 22.1"/> <fsummary></fsummary> <desc> <p>Finalizes the MAC operation referenced by <c>State</c>. The <c>Mac</c> result will have @@ -960,7 +960,7 @@ </func> <func> - <name name="mac_finalN" arity="2" since="OTP @OTP-13872@"/> + <name name="mac_finalN" arity="2" since="OTP 22.1"/> <fsummary></fsummary> <desc> <p>Finalizes the MAC operation referenced by <c>State</c>. diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml index 5f47981855..b35dddf4ff 100644 --- a/lib/crypto/doc/src/notes.xml +++ b/lib/crypto/doc/src/notes.xml @@ -31,6 +31,64 @@ </header> <p>This document describes the changes made to the Crypto application.</p> +<section><title>Crypto 4.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The implementation of <c>crypto_one_time/4</c> is + adjusted to match the type specification. The spec and + the black-box behaviour of the function are unchanged.</p> + <p> + Some details: Both the spec and the implementation were + correct seen separately. But with both of them combined + simultaneously with <c>crypto_one_time/5</c> which was + called by the implementation of <c>crypto_one_time/4</c>, + an (obvious) error was detected by a Dialyzer with more + thorough checking than usual.</p> + <p> + Own Id: OTP-15884 Aux Id: ERL-974 </p> + </item> + <item> + <p> + When using crypto with FIPS mode enabled, the digests + were not correctly handled.</p> + <p> + Own Id: OTP-15911</p> + </item> + <item> + <p> + A memory leak in error handling code in + <c>ng_crypto_init_nif</c> is fixed.</p> + <p> + Own Id: OTP-15924</p> + </item> + <item> + <p> + Fixed the broken static build of the crypto nifs</p> + <p> + Own Id: OTP-15928 Aux Id: PR-2296 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The Message Authentication Codes (MAC) CMAC, HMAC and + Poly1305 are unified into common functions in the New + Crypto API. See the manual for CRYPTO.</p> + <p> + Own Id: OTP-13872</p> + </item> + </list> + </section> + +</section> + <section><title>Crypto 4.5.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk index 2315cb3c48..9a5b9397f7 100644 --- a/lib/crypto/vsn.mk +++ b/lib/crypto/vsn.mk @@ -1 +1 @@ -CRYPTO_VSN = 4.5.1 +CRYPTO_VSN = 4.6 diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml index dad9fd18c7..f6cd2ec585 100644 --- a/lib/dialyzer/doc/src/notes.xml +++ b/lib/dialyzer/doc/src/notes.xml @@ -32,6 +32,23 @@ <p>This document describes the changes made to the Dialyzer application.</p> +<section><title>Dialyzer 4.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> Allow native compilation when using Dialyzer from + Erlang. The options <c>native</c> (defaults to + <c>false</c>) and <c>native_cache</c> have been added. + </p> + <p> + Own Id: OTP-15880 Aux Id: PR-2283 </p> + </item> + </list> + </section> + +</section> + <section><title>Dialyzer 4.0.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk index a77c74c717..03155e2d24 100644 --- a/lib/dialyzer/vsn.mk +++ b/lib/dialyzer/vsn.mk @@ -1 +1 @@ -DIALYZER_VSN = 4.0.3 +DIALYZER_VSN = 4.1 diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml index f25361a202..f51cd26a7f 100644 --- a/lib/erl_docgen/doc/src/notes.xml +++ b/lib/erl_docgen/doc/src/notes.xml @@ -31,7 +31,22 @@ </header> <p>This document describes the changes made to the <em>erl_docgen</em> application.</p> - <section><title>Erl_Docgen 0.9.1</title> + <section><title>Erl_Docgen 0.10</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> Update the documentation build support to handle FOP + 2.1 . </p> + <p> + Own Id: OTP-16051</p> + </item> + </list> + </section> + +</section> + +<section><title>Erl_Docgen 0.9.1</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/erl_docgen/vsn.mk b/lib/erl_docgen/vsn.mk index fece2456c1..2ac4acaf09 100644 --- a/lib/erl_docgen/vsn.mk +++ b/lib/erl_docgen/vsn.mk @@ -1 +1 @@ -ERL_DOCGEN_VSN = 0.9.1 +ERL_DOCGEN_VSN = 0.10 diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml index c47f0d2bd1..08f5a40687 100644 --- a/lib/erl_interface/doc/src/notes.xml +++ b/lib/erl_interface/doc/src/notes.xml @@ -31,6 +31,41 @@ </header> <p>This document describes the changes made to the Erl_interface application.</p> +<section><title>Erl_Interface 3.13</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix bugs in <c>ei_print_term</c> for binaries and bit + strings causing incorrect output.</p> + <p> + Own Id: OTP-15917</p> + </item> + <item> + <p> + Fixed bug in <c>ei_decode_fun</c> for very old fun + encoding format. Bug exist since OTP 22.0.</p> + <p> + Own Id: OTP-15996</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p><c>ei_print_term()</c> now supports printing of maps + and funs.</p> + <p> + Own Id: OTP-15814</p> + </item> + </list> + </section> + +</section> + <section><title>Erl_Interface 3.12</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk index cc72ed639a..2bf84bf18f 100644 --- a/lib/erl_interface/vsn.mk +++ b/lib/erl_interface/vsn.mk @@ -1,2 +1,2 @@ -EI_VSN = 3.12 +EI_VSN = 3.13 ERL_INTERFACE_VSN = $(EI_VSN) diff --git a/lib/eunit/doc/src/notes.xml b/lib/eunit/doc/src/notes.xml index 67a9ae5fcb..397a4657d3 100644 --- a/lib/eunit/doc/src/notes.xml +++ b/lib/eunit/doc/src/notes.xml @@ -33,6 +33,21 @@ </header> <p>This document describes the changes made to the EUnit application.</p> +<section><title>Eunit 2.3.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> Handle <c>get_until</c> request with explicit + encoding in the implementation of the I/O protocol. </p> + <p> + Own Id: OTP-16000</p> + </item> + </list> + </section> + +</section> + <section><title>Eunit 2.3.7</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/eunit/vsn.mk b/lib/eunit/vsn.mk index 46ef5eea3c..52d23698fa 100644 --- a/lib/eunit/vsn.mk +++ b/lib/eunit/vsn.mk @@ -1 +1 @@ -EUNIT_VSN = 2.3.7 +EUNIT_VSN = 2.3.8 diff --git a/lib/ftp/doc/src/notes.xml b/lib/ftp/doc/src/notes.xml index 61da079900..d71f795c09 100644 --- a/lib/ftp/doc/src/notes.xml +++ b/lib/ftp/doc/src/notes.xml @@ -33,7 +33,23 @@ <file>notes.xml</file> </header> - <section><title>Ftp 1.0.2</title> + <section><title>Ftp 1.0.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + A possibly infinite loop when receiving messages divided + in parts is removed.</p> + <p> + Own Id: OTP-16056</p> + </item> + </list> + </section> + +</section> + +<section><title>Ftp 1.0.2</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/ftp/vsn.mk b/lib/ftp/vsn.mk index 9f14658099..397328ce27 100644 --- a/lib/ftp/vsn.mk +++ b/lib/ftp/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = ftp -FTP_VSN = 1.0.2 +FTP_VSN = 1.0.3 PRE_VSN = APP_VSN = "$(APPLICATION)-$(FTP_VSN)$(PRE_VSN)" diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 45533c4f4b..da670bb1c9 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -33,7 +33,30 @@ <file>notes.xml</file> </header> - <section><title>Inets 7.0.9</title> + <section><title>Inets 7.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + httpd - Accept singel LF as line terminator</p> + <p> + Own Id: OTP-15893 Aux Id: PR-2206 </p> + </item> + <item> + <p> + mod_esi will now always propagate the actual HTTP status + code that it answered with, to later mod-modules, and not + in some cases hardcode 200.</p> + <p> + Own Id: OTP-16049 Aux Id: ERIERL-395 </p> + </item> + </list> + </section> + +</section> + +<section><title>Inets 7.0.9</title> <section><title>Fixed Bugs and Malfunctions</title> <list> @@ -66,6 +89,23 @@ </section> + <section><title>Inets 7.0.7.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + mod_esi will now always propagate the actual HTTP status + code that it anwsered with, to later mod-modules, and not + in some cases hardcode 200.</p> + <p> + Own Id: OTP-16049 Aux Id: ERIERL-395 </p> + </item> + </list> + </section> + +</section> + <section><title>Inets 7.0.7</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -3346,5 +3386,3 @@ --> </chapter> - - diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index d948204618..afc02f2038 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 7.0.9 +INETS_VSN = 7.1 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml index e79ada47f1..433534207a 100644 --- a/lib/jinterface/doc/src/notes.xml +++ b/lib/jinterface/doc/src/notes.xml @@ -31,6 +31,22 @@ </header> <p>This document describes the changes made to the Jinterface application.</p> +<section><title>Jinterface 1.10.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Replaced deprecated <tt> with <code> in + documentation.</p> + <p> + Own Id: OTP-16050</p> + </item> + </list> + </section> + +</section> + <section><title>Jinterface 1.10</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk index 95c7c95726..f15a3f323b 100644 --- a/lib/jinterface/vsn.mk +++ b/lib/jinterface/vsn.mk @@ -1 +1 @@ -JINTERFACE_VSN = 1.10 +JINTERFACE_VSN = 1.10.1 diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml index 6c0d072fed..9ecadc5498 100644 --- a/lib/kernel/doc/src/gen_udp.xml +++ b/lib/kernel/doc/src/gen_udp.xml @@ -213,7 +213,7 @@ </func> <func> - <name name="send" arity="3" since="OTP @OTP-15747@"/> + <name name="send" arity="3" since="OTP 22.1"/> <fsummary>Send a packet.</fsummary> <desc> <p> @@ -242,7 +242,7 @@ </func> <func> - <name name="send" arity="4" clause_i="2" anchor="send-4-AncData" since="OTP @OTP-15747@"/> + <name name="send" arity="4" clause_i="2" anchor="send-4-AncData" since="OTP 22.1"/> <fsummary>Send a packet.</fsummary> <desc> <p> @@ -265,7 +265,7 @@ </func> <func> - <name name="send" arity="4" clause_i="3" since="OTP @OTP-15747@"/> + <name name="send" arity="4" clause_i="3" since="OTP 22.1"/> <fsummary>Send a packet.</fsummary> <desc> <p> @@ -284,7 +284,7 @@ </func> <func> - <name name="send" arity="5" since="OTP @OTP-15747@"/> + <name name="send" arity="5" since="OTP 22.1"/> <fsummary>Send a packet.</fsummary> <desc> <p> @@ -305,4 +305,3 @@ </func> </funcs> </erlref> - diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index 3f03104734..e1a8ae567a 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -118,7 +118,7 @@ fe80::204:acff:fe17:bf38 <name name="port_number"/> </datatype> <datatype> - <name name="family_address" since="OTP @OTP-15747@"/> + <name name="family_address" since="OTP 22.1"/> <desc> <p> A general address format on the form <c>{Family, Destination}</c> @@ -130,7 +130,7 @@ fe80::204:acff:fe17:bf38 </desc> </datatype> <datatype> - <name name="inet_address" since="OTP @OTP-15747@"/> + <name name="inet_address" since="OTP 22.1"/> <desc> <warning> <p> @@ -142,7 +142,7 @@ fe80::204:acff:fe17:bf38 </desc> </datatype> <datatype> - <name name="inet6_address" since="OTP @OTP-15747@"/> + <name name="inet6_address" since="OTP 22.1"/> <desc> <warning> <p> diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml index 4d31eeea3d..aea3787115 100644 --- a/lib/kernel/doc/src/notes.xml +++ b/lib/kernel/doc/src/notes.xml @@ -31,6 +31,101 @@ </header> <p>This document describes the changes made to the Kernel application.</p> +<section><title>Kernel 6.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The type specification for <c>gen_sctp:connect/4,5</c> + has been corrected.</p> + <p> + Own Id: OTP-15344 Aux Id: ERL-947 </p> + </item> + <item> + <p> + Extra <c>-mode</c> flags given to <c>erl</c> are ignored + with a warning.</p> + <p> + Own Id: OTP-15852</p> + </item> + <item> + <p> + Fix type spec for <c>seq_trace:set_token/2</c>.</p> + <p> + Own Id: OTP-15858 Aux Id: ERL-700 </p> + </item> + <item> + <p> + <c>logger:compare_levels/2</c> would fail with a + <c>badarg</c> exception if given the values <c>all</c> or + <c>none</c> as any of the parameters. This is now + corrected.</p> + <p> + Own Id: OTP-15942 Aux Id: PR-2301 </p> + </item> + <item> + <p> + Fix bug where the log file in <c>logger_std_h</c> would + not be closed when the inode of the file changed. This + would in turn cause a file descriptor leak when tools + like logrotate are used.</p> + <p> + Own Id: OTP-15997 Aux Id: PR-2331 </p> + </item> + <item> + <p> + Fix a race condition in the debugging function + <c>net_kernel:nodes_info/0</c>.</p> + <p> + Own Id: OTP-16022</p> + </item> + <item> + <p> + Fix race condition when closing a file opened in + <c>compressed</c> or <c>delayed_write</c> mode.</p> + <p> + Own Id: OTP-16023</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The possibility to send ancillary data, in particular the + TOS field, has been added to <c>gen_udp:send/4,5</c>.</p> + <p> + Own Id: OTP-15747 Aux Id: ERIERL-294 </p> + </item> + <item> + <p> + If the log file was given with relative path, the + standard logger handler (<c>logger_std_h</c>) would store + the file name with relative path. If the current + directory of the node was later changed, a new file would + be created relative the new current directory, + potentially failing with an <c>enoent</c> if the new + directory did not exist. This is now corrected and + <c>logger_std_h</c> always stores the log file name as an + absolute path, calculated from the current directory at + the time of the handler startup.</p> + <p> + Own Id: OTP-15850</p> + </item> + <item> + <p> + Support local sockets with inet:i/0.</p> + <p> + Own Id: OTP-15935 Aux Id: PR-2299 </p> + </item> + </list> + </section> + +</section> + <section><title>Kernel 6.4.1</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -147,6 +242,24 @@ </section> +<section><title>Kernel 6.3.1.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix bug where the log file in <c>logger_std_h</c> would + not be closed when the inode of the file changed. This + would in turn cause a file descriptor leak when tools + like logrotate are used.</p> + <p> + Own Id: OTP-15997 Aux Id: PR-2331 </p> + </item> + </list> + </section> + +</section> + <section><title>Kernel 6.3.1.2</title> <section><title>Improvements and New Features</title> diff --git a/lib/kernel/src/group_history.erl b/lib/kernel/src/group_history.erl index e69fa85492..1fab2ba14e 100644 --- a/lib/kernel/src/group_history.erl +++ b/lib/kernel/src/group_history.erl @@ -131,11 +131,15 @@ repair_log(Name) -> %% Return whether the shell history is enabled or not -spec history_status() -> enabled | disabled. history_status() -> - case is_user() orelse init_running() orelse application:get_env(kernel, shell_history) of - true -> disabled; % don't run for user proc - {ok, enabled} -> enabled; - undefined -> ?DEFAULT_STATUS; - _ -> disabled + %% Don't run for user proc or if the emulator's tearing down + Skip = is_user() orelse not init_running(), + case application:get_env(kernel, shell_history) of + {ok, enabled} when not Skip -> + enabled; + undefined when not Skip -> + ?DEFAULT_STATUS; + _ -> + disabled end. %% Return whether the user process is running this diff --git a/lib/kernel/src/kernel.appup.src b/lib/kernel/src/kernel.appup.src index 95853a7a8f..d862b5491f 100644 --- a/lib/kernel/src/kernel.appup.src +++ b/lib/kernel/src/kernel.appup.src @@ -40,7 +40,8 @@ {<<"^6\\.3\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, {<<"^6\\.3\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, {<<"^6\\.4$">>,[restart_new_emulator]}, - {<<"^6\\.4\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}], + {<<"^6\\.4\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, + {<<"^6\\.4\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}], [{<<"^6\\.0$">>,[restart_new_emulator]}, {<<"^6\\.0\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, {<<"^6\\.0\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, @@ -54,4 +55,5 @@ {<<"^6\\.3\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, {<<"^6\\.3\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, {<<"^6\\.4$">>,[restart_new_emulator]}, - {<<"^6\\.4\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}]}. + {<<"^6\\.4\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, + {<<"^6\\.4\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}]}. diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl index 747f1d9e1b..e4299cd346 100644 --- a/lib/kernel/test/file_SUITE.erl +++ b/lib/kernel/test/file_SUITE.erl @@ -96,6 +96,8 @@ -export([allocate/1]). +-export([allocate_file_size/1]). + -export([standard_io/1,mini_server/1]). -export([old_io_protocol/1]). @@ -147,7 +149,7 @@ groups() -> {files, [], [{group, open}, {group, pos}, {group, file_info}, {group, consult}, {group, eval}, {group, script}, - truncate, sync, datasync, advise, allocate]}, + truncate, sync, datasync, advise, allocate, allocate_file_size]}, {open, [], [open1, old_modes, new_modes, path_open, close, access, read_write, pread_write, append, open_errors, @@ -2227,6 +2229,28 @@ allocate_and_assert(Fd, Offset, Length) -> _ = Result end. +%% Tests that asserts that file:allocate/3 changes file size +allocate_file_size(Config) when is_list(Config) -> + case os:type() of + {unix, darwin} -> + PrivDir = proplists:get_value(priv_dir, Config), + Allocate = filename:join(PrivDir, atom_to_list(?MODULE)++"_allocate_file"), + + {ok, Fd} = ?FILE_MODULE:open(Allocate, [write]), + ok = ?FILE_MODULE:allocate(Fd, 0, 1024), + {ok, 1024} = ?FILE_MODULE:position(Fd, eof), + ok = ?FILE_MODULE:close(Fd), + + [] = flush(), + ok; + {unix, linux} -> + {skip, "file:allocate/3 on Linux does not change file size"}; + {win32, _} -> + {skip, "Windows does not support file:allocate/3"}; + _ -> + {skip, "Support for allocate/3 is spotty in our test platform at the moment."} + end. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% delete(Config) when is_list(Config) -> diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index e5188aa9b5..508e54237b 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -1 +1 @@ -KERNEL_VSN = 6.4.1 +KERNEL_VSN = 6.5 diff --git a/lib/megaco/doc/src/notes.xml b/lib/megaco/doc/src/notes.xml index 6f33ae390c..62d0aad77d 100644 --- a/lib/megaco/doc/src/notes.xml +++ b/lib/megaco/doc/src/notes.xml @@ -37,7 +37,24 @@ section is the version number of Megaco.</p> - <section><title>Megaco 3.18.5</title> + <section><title>Megaco 3.18.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix various minor issues related to Dialyzer. Mostly + these are dialyzer warnings, but there was also some + minor bugs detected by Dialyzer.</p> + <p> + Own Id: OTP-15882</p> + </item> + </list> + </section> + +</section> + +<section><title>Megaco 3.18.5</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk index 843a3dccc5..381def97d7 100644 --- a/lib/megaco/vsn.mk +++ b/lib/megaco/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = megaco -MEGACO_VSN = 3.18.5 +MEGACO_VSN = 3.18.6 PRE_VSN = APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)" diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml index 2d38e4d01c..e918338c8a 100644 --- a/lib/mnesia/doc/src/notes.xml +++ b/lib/mnesia/doc/src/notes.xml @@ -39,7 +39,36 @@ thus constitutes one section in this document. The title of each section is the version number of Mnesia.</p> - <section><title>Mnesia 4.16</title> + <section><title>Mnesia 4.16.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + <c>mnesia:add_table_copy/3</c> could cause a deadlock if + called when a new node was starting.</p> + <p> + Own Id: OTP-15933 Aux Id: ERL-872 </p> + </item> + <item> + <p>Transactions with sticky locks could with async_asym + transactions be committed in the wrong order, since asym + transaction are spawned on the remote nodes.</p> <p>To + fix this bug the communication protocol between mnesia + nodes had to be updated, thus mnesia will no longer be + able to connect to nodes earlier than mnesia-4.14 , + OTP-19.0.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-15979 Aux Id: ERL-768 </p> + </item> + </list> + </section> + +</section> + +<section><title>Mnesia 4.16</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/mnesia/src/mnesia.erl b/lib/mnesia/src/mnesia.erl index 02bc884e36..9d462f0a63 100644 --- a/lib/mnesia/src/mnesia.erl +++ b/lib/mnesia/src/mnesia.erl @@ -2731,7 +2731,7 @@ create_table(Arg) -> create_table(Name, Arg) when is_list(Arg) -> mnesia_schema:create_table([{name, Name}| Arg]); create_table(Name, Arg) -> - {aborted, badarg, Name, Arg}. + {aborted, {badarg, Name, Arg}}. -spec delete_table(Tab::table()) -> t_result('ok'). delete_table(Tab) -> diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk index aa5d9adb6d..f1a6333c18 100644 --- a/lib/mnesia/vsn.mk +++ b/lib/mnesia/vsn.mk @@ -1 +1 @@ -MNESIA_VSN = 4.16 +MNESIA_VSN = 4.16.1 diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml index f05e58dc21..f66ab95893 100644 --- a/lib/observer/doc/src/notes.xml +++ b/lib/observer/doc/src/notes.xml @@ -32,6 +32,34 @@ <p>This document describes the changes made to the Observer application.</p> +<section><title>Observer 2.9.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix bug after a user followed link on a pid from an + expanded term window.</p> + <p> + Own Id: OTP-15980 Aux Id: PR-2201 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Improved dark mode colors on Linux.</p> + <p> + Own Id: OTP-15916 Aux Id: ERL-921 </p> + </item> + </list> + </section> + +</section> + <section><title>Observer 2.9.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk index c16c43f942..3bb316a5e2 100644 --- a/lib/observer/vsn.mk +++ b/lib/observer/vsn.mk @@ -1 +1 @@ -OBSERVER_VSN = 2.9.1 +OBSERVER_VSN = 2.9.2 diff --git a/lib/os_mon/doc/src/notes.xml b/lib/os_mon/doc/src/notes.xml index 1f169263e9..63efa96e2f 100644 --- a/lib/os_mon/doc/src/notes.xml +++ b/lib/os_mon/doc/src/notes.xml @@ -31,6 +31,29 @@ </header> <p>This document describes the changes made to the OS_Mon application.</p> +<section><title>Os_Mon 2.5.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix <c>disk_sup</c> to ignore squashfs on Linux when + determining if a mounted filesystem is full or not.</p> + <p> + Own Id: OTP-15778</p> + </item> + <item> + <p> + Fix bug where <c>cpu_sup:util()</c> always returned 100% + on systems not using gnu libc, for example Alpine OS.</p> + <p> + Own Id: OTP-15974 Aux Id: ERL-1012 </p> + </item> + </list> + </section> + +</section> + <section><title>Os_Mon 2.5</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/os_mon/vsn.mk b/lib/os_mon/vsn.mk index 845443d329..6081e181ff 100644 --- a/lib/os_mon/vsn.mk +++ b/lib/os_mon/vsn.mk @@ -1 +1 @@ -OS_MON_VSN = 2.5 +OS_MON_VSN = 2.5.1 diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml index 57d9898661..f47988d6d8 100644 --- a/lib/public_key/doc/src/notes.xml +++ b/lib/public_key/doc/src/notes.xml @@ -35,6 +35,33 @@ <file>notes.xml</file> </header> +<section><title>Public_Key 1.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Support Password based encryption with AES</p> + <p> + Own Id: OTP-15870 Aux Id: ERL-952 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Change dialyzer spec to avoid confusion</p> + <p> + Own Id: OTP-15843 Aux Id: ERL-915 </p> + </item> + </list> + </section> + +</section> + <section><title>Public_Key 1.6.7</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk index a5e4ec8d5a..1982218574 100644 --- a/lib/public_key/vsn.mk +++ b/lib/public_key/vsn.mk @@ -1 +1 @@ -PUBLIC_KEY_VSN = 1.6.7 +PUBLIC_KEY_VSN = 1.7 diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml index 1b94c3e6d9..210d63687c 100644 --- a/lib/runtime_tools/doc/src/notes.xml +++ b/lib/runtime_tools/doc/src/notes.xml @@ -32,6 +32,22 @@ <p>This document describes the changes made to the Runtime_Tools application.</p> +<section><title>Runtime_Tools 1.14</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Fix <c>dbg:stop_clear/0</c> to also clear trace events + (<c>send</c> and <c>'receive'</c>).</p> + <p> + Own Id: OTP-16044</p> + </item> + </list> + </section> + +</section> + <section><title>Runtime_Tools 1.13.3</title> <section><title>Improvements and New Features</title> diff --git a/lib/runtime_tools/examples/function-calls.d b/lib/runtime_tools/examples/function-calls.d index f8ca388228..a51ff51253 100644 --- a/lib/runtime_tools/examples/function-calls.d +++ b/lib/runtime_tools/examples/function-calls.d @@ -19,39 +19,85 @@ * %CopyrightEnd% */ +/** + * Triggered on local function entry + * + * @param arg0 pid + * @param arg1 MFA of the function + * @param arg2 depth + */ erlang*:::local-function-entry { printf("pid %s enter (local) %s depth %d\n", copyinstr(arg0), copyinstr(arg1), arg2); } +/** + * Triggered on global function entry + * + * @param arg0 pid + * @param arg1 MFA of the function + * @param arg2 depth + */ erlang*:::global-function-entry { printf("pid %s enter (global) %s depth %d\n", copyinstr(arg0), copyinstr(arg1), arg2); } +/** + * Triggered upon function return, either global or + * local + * + * @param arg0 pid + * @param arg1 MFA of the returned from function + * @param arg2 depth + */ erlang*:::function-return { printf("pid %s return %s depth %d\n", copyinstr(arg0), copyinstr(arg1), arg2); } +/** + * Triggered on built-in function entry + * + * @param arg0 pid + * @param arg1 MFA of the function + */ erlang*:::bif-entry { printf("pid %s BIF entry mfa %s\n", copyinstr(arg0), copyinstr(arg1)); } +/** + * Triggered on built-in function return + * + * @param arg0 pid + * @param arg1 MFA of the returned from function + */ erlang*:::bif-return { printf("pid %s BIF return mfa %s\n", copyinstr(arg0), copyinstr(arg1)); } +/** + * Triggered on native function entry + * + * @param arg0 pid + * @param arg1 MFA of the function + */ erlang*:::nif-entry { printf("pid %s NIF entry mfa %s\n", copyinstr(arg0), copyinstr(arg1)); } +/** + * Triggered upon native function return + * + * @param arg0 pid + * @param arg1 MFA of the returned from function + */ erlang*:::nif-return { printf("pid %s NIF return mfa %s\n", copyinstr(arg0), copyinstr(arg1)); diff --git a/lib/runtime_tools/examples/function-calls.systemtap b/lib/runtime_tools/examples/function-calls.systemtap index 6bb173b3ec..8f748ce0d1 100644 --- a/lib/runtime_tools/examples/function-calls.systemtap +++ b/lib/runtime_tools/examples/function-calls.systemtap @@ -29,39 +29,85 @@ * to your environment. */ +/** + * Triggered on local function entry + * + * @param arg0 pid + * @param arg1 MFA of the function + * @param arg2 depth + */ probe process("beam.smp").mark("local-function-entry") { printf("pid %s enter (local) %s depth %d\n", user_string($arg1), user_string($arg2), $arg3); } +/** + * Triggered on global function entry + * + * @param arg0 pid + * @param arg1 MFA of the function + * @param arg2 depth + */ probe process("beam.smp").mark("global-function-entry") { printf("pid %s enter (global) %s depth %d\n", user_string($arg1), user_string($arg2), $arg3); } +/** + * Triggered upon function return, either global or + * local + * + * @param arg0 pid + * @param arg1 MFA of the returned from function + * @param arg2 depth + */ probe process("beam.smp").mark("function-return") { printf("pid %s return %s depth %d\n", user_string($arg1), user_string($arg2), $arg3); } +/** + * Triggered on built-in function entry + * + * @param arg0 pid + * @param arg1 MFA of the function + */ probe process("beam.smp").mark("bif-entry") { printf("pid %s BIF entry mfa %s\n", user_string($arg1), user_string($arg2)); } +/** + * Triggered on built-in function return + * + * @param arg0 pid + * @param arg1 MFA of the returned from function + */ probe process("beam.smp").mark("bif-return") { printf("pid %s BIF return mfa %s\n", user_string($arg1), user_string($arg2)); } +/** + * Triggered on native function entry + * + * @param arg0 pid + * @param arg1 MFA of the function + */ probe process("beam.smp").mark("nif-entry") { printf("pid %s NIF entry mfa %s\n", user_string($arg1), user_string($arg2)); } +/** + * Triggered upon native function return + * + * @param arg0 pid + * @param arg1 MFA of the returned from function + */ probe process("beam.smp").mark("nif-return") { printf("pid %s NIF return mfa %s\n", user_string($arg1), user_string($arg2)); diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk index 3f38574be4..c01dd60009 100644 --- a/lib/runtime_tools/vsn.mk +++ b/lib/runtime_tools/vsn.mk @@ -1 +1 @@ -RUNTIME_TOOLS_VSN = 1.13.3 +RUNTIME_TOOLS_VSN = 1.14 diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml index a1ae404776..245542242b 100644 --- a/lib/sasl/doc/src/notes.xml +++ b/lib/sasl/doc/src/notes.xml @@ -31,6 +31,22 @@ </header> <p>This document describes the changes made to the SASL application.</p> +<section><title>SASL 3.4.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The net module has been split into 'net' (kernel) and + prim_net (preloaded).</p> + <p> + Own Id: OTP-15765</p> + </item> + </list> + </section> + +</section> + <section><title>SASL 3.4</title> <section><title>Improvements and New Features</title> diff --git a/lib/sasl/src/sasl.appup.src b/lib/sasl/src/sasl.appup.src index 22a9027b7c..aabe1a904b 100644 --- a/lib/sasl/src/sasl.appup.src +++ b/lib/sasl/src/sasl.appup.src @@ -31,9 +31,13 @@ {<<"^3\\.2\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, {<<"^3\\.2\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, {<<"^3\\.3$">>,[restart_new_emulator]}, - {<<"^3\\.3\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}], + {<<"^3\\.3\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, + {<<"^3\\.4$">>,[restart_new_emulator]}, + {<<"^3\\.4\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}], [{<<"^3\\.2$">>,[restart_new_emulator]}, {<<"^3\\.2\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, {<<"^3\\.2\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, {<<"^3\\.3$">>,[restart_new_emulator]}, - {<<"^3\\.3\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}]}. + {<<"^3\\.3\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, + {<<"^3\\.4$">>,[restart_new_emulator]}, + {<<"^3\\.4\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}]}. diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk index 8838b514da..b13d03dc76 100644 --- a/lib/sasl/vsn.mk +++ b/lib/sasl/vsn.mk @@ -1 +1 @@ -SASL_VSN = 3.4 +SASL_VSN = 3.4.1 diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index 780e0cae76..dd499d1069 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -34,7 +34,62 @@ </header> - <section><title>SNMP 5.3</title> + <section><title>SNMP 5.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix various minor issues related to Dialyzer. Mostly + these are dialyzer warnings, but there was also some + minor bugs detected by Dialyzer.</p> + <p> + Own Id: OTP-15932</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Fixed a dets usage problem detected by dialyzer.</p> + <p> + Own Id: OTP-10400 Aux Id: kunagi-253 [164] </p> + </item> + <item> + <p> + The function snmp:print_version_info() prints various + version info. For each module a number of items are + printed, such as app vsn and md5 digest. And an attempt + was also made to print "compile time". This used to be + available in the module_info for each module, but has now + been removed.</p> + <p> + Own Id: OTP-15330</p> + </item> + <item> + <p> + The use of the deprecated random module has been replaced + the with rand module.</p> + <p> + Own Id: OTP-15331</p> + </item> + <item> + <p> + Removed use of the deprecated function + erlang:get_stacktrace(). Instead make use of the 'catch + Class:Error:Stacktrace' feature.</p> + <p> + Own Id: OTP-15332</p> + </item> + </list> + </section> + +</section> + +<section><title>SNMP 5.3</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index f305497cd3..2450b771f7 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = snmp -SNMP_VSN = 5.3 +SNMP_VSN = 5.4 PRE_VSN = APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)" diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml index 60f20c7c3f..b9cb80806e 100644 --- a/lib/ssh/doc/src/notes.xml +++ b/lib/ssh/doc/src/notes.xml @@ -30,6 +30,86 @@ <file>notes.xml</file> </header> +<section><title>Ssh 4.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed wrong type definition for the daemon option + <c>subsystems</c>.</p> + <p> + Own Id: OTP-15820</p> + </item> + <item> + <p> + Fixed a possible SSH logging crash if there was a problem + in an early stage of session setup.</p> + <p> + Own Id: OTP-15962 Aux Id: ERL-990 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The documentation for the modules ssh_connection, + ssh_sftp and ssh_sftpd are now generated from the + -spec:s.</p> + <p> + Own Id: OTP-15395</p> + </item> + <item> + <p> + Internal cleanup including removal of the internal file + <c>ssh_userauth.hrl</c>.</p> + <p> + Own Id: OTP-15876 Aux Id: PR-2255, PR-2256 </p> + </item> + <item> + <p> + Removed unused definitions in <c>ssh.hrl</c>.</p> + <p> + Own Id: OTP-15929 Aux Id: PR-2297 </p> + </item> + <item> + <p> + Removed unused fields in the internal + <c>#connection{}</c> record.</p> + <p> + Own Id: OTP-15984</p> + </item> + <item> + <p> + To get information of a <c>connection_ref()</c> from for + example <c>ssh:connect/3</c>, there was previously one + function available namely <c>ssh:connection_info/2</c>. + This ticket adds <c>ssh:connection_info/1</c> which + returns all information.</p> + <p> + For daemons (servers) started with for example + <c>ssh:daemon/2</c> the function <c>ssh:daemon_info/1</c> + returning all information was available. This ticket adds + <c>ssh:daemon_info/2</c> which returns only the + information specified in the second argument.</p> + <p> + The info of connections and of daemons now also includes + the item '<c>options</c>'. Only those options that does + not have their default values are returned.</p> + <p> + For a connection also the items '<c>algorithms</c>' and + '<c>channels</c>' are added.</p> + <p> + Own Id: OTP-16040</p> + </item> + </list> + </section> + +</section> + <section><title>Ssh 4.7.7</title> <section><title>Improvements and New Features</title> @@ -45,6 +125,22 @@ </section> +<section><title>Ssh 4.7.6.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed a possible SSH logging crash if there was a problem + in an early stage of session setup.</p> + <p> + Own Id: OTP-15962 Aux Id: ERL-990 </p> + </item> + </list> + </section> + +</section> + <section><title>Ssh 4.7.6</title> <section><title>Improvements and New Features</title> diff --git a/lib/ssh/src/ssh_info.erl b/lib/ssh/src/ssh_info.erl index 11f4bc51e6..91365205aa 100644 --- a/lib/ssh/src/ssh_info.erl +++ b/lib/ssh/src/ssh_info.erl @@ -79,8 +79,8 @@ print_clients() -> lists:map(fun print_client/1, supervisor:which_children(sshc_sup)) catch - C:E -> - io_lib:format('***print_clients FAILED: ~p:~p~n',[C,E]) + C:E:S -> + io_lib:format('***print_clients FAILED: ~p:~p,~n ~p~n',[C,E,S]) end. print_client({undefined,Pid,supervisor,[ssh_connection_handler]}) -> @@ -94,9 +94,9 @@ print_client({undefined,Pid,supervisor,[ssh_connection_handler]}) -> io_lib:format(?INDENT?INDENT?INDENT"No channels~n",[]) end]; -print_client(Other) -> - io_lib:format(" [[Other 1: ~p]]~n",[Other]). - +print_client({{client,ssh_system_sup,_,_,_},Pid,supervisor,[ssh_system_sup]}) when is_pid(Pid) -> + lists:map(fun print_system_sup/1, + supervisor:which_children(Pid)). %%%================================================================ print_servers() -> @@ -104,8 +104,8 @@ print_servers() -> lists:map(fun print_server/1, supervisor:which_children(sshd_sup)) catch - C:E -> - io_lib:format('***print_servers FAILED: ~p:~p~n',[C,E]) + C:E:S -> + io_lib:format('***print_servers FAILED: ~p:~p,~n ~p~n',[C,E,S]) end. @@ -140,22 +140,33 @@ print_system_sup({{ssh_acceptor_sup,_LocalHost,_LocalPort,_Profile}, Pid, superv -print_channels({{server,ssh_channel_sup,_,_},Pid,supervisor,[ssh_channel_sup]}) when is_pid(Pid) -> +print_channels({{Role,ssh_channel_sup,_,_},Pid,supervisor,[ssh_channel_sup]}) when is_pid(Pid) -> + ChanBehaviour = + case Role of + server -> ssh_server_channel; + client -> ssh_client_channel + end, Children = supervisor:which_children(Pid), - ChannelPids = [P || {R,P,worker,[ssh_server_channel]} <- Children, + ChannelPids = [P || {R,P,worker,[Mod]} <- Children, + ChanBehaviour == Mod, is_pid(P), is_reference(R)], case ChannelPids of [] -> io_lib:format(?INDENT?INDENT"No channels~n",[]); [Ch1Pid|_] -> - {{ConnManager,_}, _Str} = ssh_server_channel:get_print_info(Ch1Pid), + {{ConnManager,_}, _Str} = ChanBehaviour:get_print_info(Ch1Pid), {{_,Remote},_} = ssh_connection_handler:get_print_info(ConnManager), [io_lib:format(?INDENT?INDENT"Remote: ~s ConnectionRef = ~p~n",[fmt_host_port(Remote),ConnManager]), lists:map(fun print_ch/1, ChannelPids) ] end; -print_channels({{server,ssh_connection_sup,_,_},Pid,supervisor,[ssh_connection_sup]}) when is_pid(Pid) -> - []. % The supervisor of the connections socket owning process +print_channels({{_Role,ssh_connection_sup,_,_},Pid,supervisor,[ssh_connection_sup]}) when is_pid(Pid) -> + []; % The supervisor of the connections socket owning process + +print_channels({Ref,Pid,supervisor,[ssh_tcpip_forward_acceptor_sup]}) when is_pid(Pid), + is_reference(Ref) -> + []. % The supervisor of the forward_acceptor process + print_ch(Pid) -> try diff --git a/lib/ssh/test/ssh_sup_SUITE.erl b/lib/ssh/test/ssh_sup_SUITE.erl index 3b5e858c53..0bf4d87f0a 100644 --- a/lib/ssh/test/ssh_sup_SUITE.erl +++ b/lib/ssh/test/ssh_sup_SUITE.erl @@ -116,8 +116,11 @@ sshc_subtree(Config) when is_list(Config) -> {user_interaction, false}, {user, ?USER}, {password, ?PASSWD},{user_dir, UserDir}]), - ?wait_match([{_, _,supervisor,[ssh_system_sup]}], - supervisor:which_children(sshc_sup)), + ?wait_match([{{client,ssh_system_sup, LocalIP, LocalPort, ?DEFAULT_PROFILE}, + SysSup, supervisor,[ssh_system_sup]}], + supervisor:which_children(sshc_sup), + [SysSup, LocalIP, LocalPort]), + check_sshc_system_tree(SysSup, Pid1, LocalIP, LocalPort, Config), {ok, Pid2} = ssh:connect(Host, Port, [{silently_accept_hosts, true}, {user_interaction, false}, @@ -389,12 +392,55 @@ check_sshd_system_tree(Daemon, Config) -> ?wait_match([], supervisor:which_children(ChannelSup)), - ssh_sftp:start_channel(Client), + {ok,PidC} = ssh_sftp:start_channel(Client), + + ?wait_match([{_, PidS,worker,[ssh_server_channel]}], + supervisor:which_children(ChannelSup), + [PidS]), + true = (PidS =/= PidC), - ?wait_match([{_, _,worker,[ssh_server_channel]}], - supervisor:which_children(ChannelSup)), ssh:close(Client). + +check_sshc_system_tree(SysSup, Connection, LocalIP, LocalPort, _Config) -> + ?wait_match([{_,SubSysSup,supervisor,[ssh_subsystem_sup]}], + supervisor:which_children(SysSup), + [SubSysSup]), + ?wait_match([{{client,ssh_connection_sup, LocalIP, LocalPort}, + ConnectionSup, supervisor, + [ssh_connection_sup]}, + {{client,ssh_channel_sup, LocalIP, LocalPort}, + ChannelSup,supervisor, + [ssh_channel_sup]}], + supervisor:which_children(SubSysSup), + [ConnectionSup,ChannelSup]), + ?wait_match([{_, Connection, worker,[ssh_connection_handler]}], + supervisor:which_children(ConnectionSup)), + ?wait_match([], supervisor:which_children(ChannelSup)), + + {ok,ChPid1} = ssh_sftp:start_channel(Connection), + ?wait_match([{_,ChPid1,worker,[ssh_client_channel]}], + supervisor:which_children(ChannelSup)), + + {ok,ChPid2} = ssh_sftp:start_channel(Connection), + ?wait_match([{_,ChPidA,worker,[ssh_client_channel]}, + {_,ChPidB,worker,[ssh_client_channel]}], + supervisor:which_children(ChannelSup), + [ChPidA, ChPidB]), + lists:sort([ChPidA, ChPidB]) == lists:sort([ChPid1, ChPid2]), + + ct:pal("Expect a SUPERVISOR REPORT with offender {pid,~p}....~n", [ChPid1]), + exit(ChPid1, kill), + ?wait_match([{_,ChPid2,worker,[ssh_client_channel]}], + supervisor:which_children(ChannelSup)), + + ct:pal("Expect a SUPERVISOR REPORT with offender {pid,~p}....~n", [ChPid2]), + exit(ChPid2, kill), + ?wait_match([], supervisor:which_children(ChannelSup)), + ct:pal("... now there should not be any SUPERVISOR REPORT.~n", []). + + + acceptor_pid(DaemonPid) -> Parent = self(), Pid = spawn(fun() -> diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index bb87dd388c..fcf97177d8 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -1,4 +1,4 @@ #-*-makefile-*- ; force emacs to enter makefile-mode -SSH_VSN = 4.7.7 +SSH_VSN = 4.8 APP_VSN = "ssh-$(SSH_VSN)" diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml index 335896c60a..2f675560d6 100644 --- a/lib/ssl/doc/src/notes.xml +++ b/lib/ssl/doc/src/notes.xml @@ -27,6 +27,75 @@ </header> <p>This document describes the changes made to the SSL application.</p> +<section><title>SSL 9.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Handling of zero size fragments in TLS could cause an + infinite loop. This has now been corrected.</p> + <p> + Own Id: OTP-15328 Aux Id: ERIERL-379 </p> + </item> + <item> + <p> + DTLS record check needs to consider that a resent hello + message can have a different version than the negotiated.</p> + <p> + Own Id: OTP-15807 Aux Id: ERL-920 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Basic support for TLS 1.3 Client for experimental use. + For more information see the Standards Compliance chapter + of the User's Guide.</p> + <p> + Own Id: OTP-15431</p> + </item> + <item> + <p> + Correct solution for retaining tcp flow control OTP-15802 + (ERL-934) as to not break ssl:recv as reported in + (ERL-938)</p> + <p> + Own Id: OTP-15823 Aux Id: ERL-934, ERL-938 </p> + </item> + <item> + <p> + Enhance dialyzer specs to reflect implementation better + and avoid dialyzer warnings for the user that wants to + use TLS with unix domain sockets.</p> + <p> + Own Id: OTP-15851 Aux Id: PR-2235 </p> + </item> + <item> + <p> + Add support for ECDSA signature algorithms in TLS 1.3.</p> + <p> + Own Id: OTP-15854</p> + </item> + <item> + <p> + Correct error handling of TLS downgrade, possible return + values form ssl:close/2 when downgrading is {ok, Port} or + {error, Reason}, it could happen that only ok was + returned instead of {error, closed} when downgrade failed + due to that the peer closed the TCP connection.</p> + <p> + Own Id: OTP-16027</p> + </item> + </list> + </section> + +</section> + <section><title>SSL 9.3.5</title> <section><title>Improvements and New Features</title> diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index c6c94ee853..0d6501b5ee 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -1609,7 +1609,9 @@ handle_options(Opts0, Role, Host) -> proplists:delete(Key, PropList) end, Opts, ?SSL_OPTIONS ++ [ssl_imp, %% TODO: remove ssl_imp - client_preferred_next_protocols]), %% next_protocol_selector + client_preferred_next_protocols, %% next_protocol_selector + log_alert, + cb_info]), {Sock, Emulated} = emulated_options(Protocol, SockOpts), ConnetionCb = connection_cb(Opts), diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk index c9547cae36..c7404c0169 100644 --- a/lib/ssl/vsn.mk +++ b/lib/ssl/vsn.mk @@ -1 +1 @@ -SSL_VSN = 9.3.5 +SSL_VSN = 9.4 diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index 0e35bd3db3..dabce02b3d 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -33,28 +33,40 @@ <description> <p> <c>gen_statem</c> provides a generic state machine behaviour - and replaces its predecessor + that for new code replaces its predecessor <seealso marker="gen_fsm"><c>gen_fsm</c></seealso> - since Erlang/OTP 20.0. + since Erlang/OTP 20.0. The <c>gen_fsm</c> behaviour remains + in OTP "as is". </p> + <note> + <p> + If you are new to <c>gen_statem</c> and want an overview + of concepts and operation the section + <seealso marker="doc/design_principles:statem"> + <c>gen_statem</c> Behaviour + </seealso> + located in the User's Guide + <seealso marker="doc/design_principles:users_guide"> + OTP Design Principles + </seealso> + is recommended to read before this reference manual, + possibly after the Description section you are reading here. + </p> + </note> <p> - This reference manual describes types generated from the types - in the <c>gen_statem</c> source code, so they are correct. + This reference manual contains type descriptions generated from + types in the <c>gen_statem</c> source code, so they are correct. However, the generated descriptions also reflect the type hierarchy, - which makes them kind of hard to read. - </p> - <p> - To get an overview of the concepts and operation of <c>gen_statem</c>, - do read the + which sometimes makes it hard to get a good overview. + If so, see the section <seealso marker="doc/design_principles:statem"> <c>gen_statem</c> Behaviour </seealso> - in + in the <seealso marker="doc/design_principles:users_guide"> OTP Design Principles </seealso> - which frequently links back to this reference manual to avoid - containing detailed facts that may rot by age. + User's Guide. </p> <note> <list type="bulleted"> @@ -1260,7 +1272,7 @@ handle_event(_, _, State, Data) -> </desc> </datatype> <datatype> - <name name="timeout_cancel_action" since="OTP @OTP-15510@"/> + <name name="timeout_cancel_action" since="OTP 22.1"/> <desc> <p> This is a shorter and clearer form of @@ -1272,7 +1284,7 @@ handle_event(_, _, State, Data) -> </desc> </datatype> <datatype> - <name name="timeout_update_action" since="OTP @OTP-15510@"/> + <name name="timeout_update_action" since="OTP 22.1"/> <desc> <p> Updates a time-out with a new <c>EventContent</c>. diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml index 66624c43be..e2badecffa 100644 --- a/lib/stdlib/doc/src/notes.xml +++ b/lib/stdlib/doc/src/notes.xml @@ -31,6 +31,148 @@ </header> <p>This document describes the changes made to the STDLIB application.</p> +<section><title>STDLIB 3.10</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + <c>re:run()</c> now yields when validating utf8 in a + large subject.</p> + <p> + Own Id: OTP-15836 Aux Id: ERL-876 </p> + </item> + <item> + <p> + Upgraded the ERTS internal PCRE library from version 8.42 + to version 8.43. See <url + href="http://pcre.org/original/changelog.txt">http://pcre.org/original/changelog.txt</url> + for information about changes made to PCRE. This library + implements major parts of the <seealso + marker="stdlib:re"><c>re</c></seealso> regular + expressions module.</p> + <p> + Own Id: OTP-15889</p> + </item> + <item> + <p> + The bug with ID ERL-717 has been fixed. The functions + <c>io:columns()</c> and <c>io:rows()</c> only worked + correctly inside interactive erlang shells before this + fix. These functions returned <c>{error,enotsup}</c> + before this fix even if stdout and stdin were connected + to a terminal when they were invoked from an escript or a + program started with e.g., <c>erl -noshell</c>.</p> + <p> + Own Id: OTP-15959 Aux Id: ERL-717 </p> + </item> + <item> + <p>Fixed handling of ".." and "@" in wildcards. ".." + would only work when preceded by a literal pattern such + as in "a/..", not when preceded by wildcard characters + such as in "*/..". The combination "@/.." was also + broken, and in addition "@" in a pattern could degrade + performance of the wildcard matching.</p> + <p> + Own Id: OTP-15987 Aux Id: ERL-1029 </p> + </item> + <item> + <p> Make sure <c>ets:fun2ms()</c> can handle <c>++/2</c> + in the head of functions when called from the shell. </p> + <p> + Own Id: OTP-15992 Aux Id: PR-2322 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>Debugging of time-outs in <c>gen_statem</c> has been + improved. Starting a time-out is now logged in + <c>sys:log</c> and <c>sys:trace</c>. Running time-outs + are visible in server crash logs, and with + <c>sys:get_status</c>. Due to this system events + <c>{start_timer, Action, State}</c> and + <c>{insert_timout, Event, State}</c> have been added, + which may surprise tools that rely on the format of these + events. </p> <p>New features: The <c>EventContent</c> of + a running time-out can be updated with <c>{TimeoutType, + update, NewEventContent}</c>. Running time-outs can be + cancelled with <c>{TimeoutType, cancel}</c> which is more + readable than using <c>Time = infinity</c>. </p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-15510</p> + </item> + <item> + <p> + <c>re:run()</c> now avoids validating utf8 in the subject + more than once in the same call. This validation could + previously be performed multiple times when the + <c>global</c> option was passed.</p> + <p> + Own Id: OTP-15831 Aux Id: ERL-876 </p> + </item> + <item> + <p> + ETS <c>ordered_set</c> tables with + <c>write_concurrency</c> enabled has got a performance + issue fixed. There were no limits for the values of + internal statistics counters before this fix. This could + result in that the data structure sometimes reacted + slowly to a change in how many parallel processes were + using it.</p> + <p> + Own Id: OTP-15906</p> + </item> + <item> + <p>The <c>ordsets:union/1</c> is now faster when passed a + long list of ordsets.</p> + <p> + Own Id: OTP-15927</p> + </item> + <item> + <p> + <c>unicode:characters_to_binary()</c> could return very + small binaries as reference counted off heap binaries. + This could cause an unnecessary large memory usage and an + unnecessary load on the binary allocator. Small binaries + are now always returned as heap binaries.</p> + <p> + Own Id: OTP-16002 Aux Id: ERIERL-366 </p> + </item> + <item> + <p> Display a more meaningful error message when a bad + I/O server is used in a script written in Erlang + (<c>escript</c>). </p> + <p> + Own Id: OTP-16006 Aux Id: ERL-992 </p> + </item> + <item> + <p> + New feature <c>ets:info(_, binary)</c> to get information + about all reference counted binaries kept by a table. + This is the same kind of debug information that + <c>process_info(_, binary)</c> returns for a process.</p> + <p> + Own Id: OTP-16035 Aux Id: ERIERL-366 </p> + </item> + <item> + <p> + Corrected ETS documentation about the behavior of + compiled match specifications when serialized through + external format.</p> + <p> + Own Id: OTP-16038 Aux Id: PR-2366 </p> + </item> + </list> + </section> + +</section> + <section><title>STDLIB 3.9.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index 0cd0aef124..d6cb57e392 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -3371,9 +3371,11 @@ handle_comprehension(E, Qs, Vt0, St0) -> Vt3 = vtmerge(vtsubtract(Vt2, Uvt), Uvt), %% Don't export local variables. Vt4 = vtold(Vt3, Vt0), - %% Forget about old variables which were not used. - Vt5 = vt_no_unused(Vt4), - {Vt5,St}. + %% Forget about old variables which were not used as well as unsafe + %% variables, preventing them from being marked as used and bound by + %% icrt_export/4. + Vt = vt_no_unsafe(vt_no_unused(Vt4)), + {Vt, St}. %% lc_quals(Qualifiers, ImportVarTable, State) -> %% {VarTable,ShadowedVarTable,State} diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src index 22d2c65cf6..4c4fb4349e 100644 --- a/lib/stdlib/src/stdlib.app.src +++ b/lib/stdlib/src/stdlib.app.src @@ -108,7 +108,6 @@ dets]}, {applications, [kernel]}, {env, []}, - {runtime_dependencies, ["sasl-3.0","kernel-6.0","erts-@OTP-15831:OTP-15836:OTP-15889:OTP-16002@","crypto-3.3", + {runtime_dependencies, ["sasl-3.0","kernel-6.0","erts-10.5","crypto-3.3", "compiler-5.0"]} ]}. - diff --git a/lib/stdlib/src/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src index 0c270e9dd5..0f87d1e52a 100644 --- a/lib/stdlib/src/stdlib.appup.src +++ b/lib/stdlib/src/stdlib.appup.src @@ -41,7 +41,8 @@ {<<"^3\\.8\\.2(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, {<<"^3\\.9$">>,[restart_new_emulator]}, {<<"^3\\.9\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, - {<<"^3\\.9\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}], + {<<"^3\\.9\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, + {<<"^3\\.9\\.2(?:\\.[0-9]+)*$">>,[restart_new_emulator]}], [{<<"^3\\.5$">>,[restart_new_emulator]}, {<<"^3\\.5\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, {<<"^3\\.5\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, @@ -56,4 +57,5 @@ {<<"^3\\.8\\.2(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, {<<"^3\\.9$">>,[restart_new_emulator]}, {<<"^3\\.9\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]}, - {<<"^3\\.9\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}]}. + {<<"^3\\.9\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]}, + {<<"^3\\.9\\.2(?:\\.[0-9]+)*$">>,[restart_new_emulator]}]}. diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl index e7882e0daf..a8ed4b19db 100644 --- a/lib/stdlib/test/erl_lint_SUITE.erl +++ b/lib/stdlib/test/erl_lint_SUITE.erl @@ -1018,7 +1018,27 @@ unsafe_vars(Config) when is_list(Config) -> {errors,[{24,erl_lint,{unsafe_var,'A',{'catch',4}}}, {24,erl_lint,{unsafe_var,'B',{'case',2}}}, {24,erl_lint,{unsafe_var,'D',{'case',2}}}], - []}} + []}}, + {unsafe_comprehension, + <<"foo() -> + case node() of + P when is_tuple(P) -> + P; + _ -> + ok + end, + Y = try + ok + catch _C:_R -> + [1 || _ <- []] + end, + case Y of + P -> + P + end. + ">>, + [], + {errors,[{14,erl_lint,{unsafe_var,'P',{'case',2}}}],[]}} ], [] = run(Config, Ts), ok. diff --git a/lib/stdlib/test/unicode_util_SUITE_data/GraphemeBreakTest.txt b/lib/stdlib/test/unicode_util_SUITE_data/GraphemeBreakTest.txt index 6847953c23..fb4fec9fff 100644 --- a/lib/stdlib/test/unicode_util_SUITE_data/GraphemeBreakTest.txt +++ b/lib/stdlib/test/unicode_util_SUITE_data/GraphemeBreakTest.txt @@ -1,6 +1,6 @@ -# GraphemeBreakTest-11.0.0.txt -# Date: 2018-03-18, 13:30:33 GMT -# ยฉ 2018 Unicodeยฎ, Inc. +# GraphemeBreakTest-12.1.0.txt +# Date: 2019-03-10, 10:53:12 GMT +# ยฉ 2019 Unicodeยฎ, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # @@ -56,8 +56,6 @@ รท 0020 ร 0308 ร 200D รท # รท [0.2] SPACE (Other) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 0020 รท 0378 รท # รท [0.2] SPACE (Other) รท [999.0] <reserved-0378> (Other) รท [0.3] รท 0020 ร 0308 รท 0378 รท # รท [0.2] SPACE (Other) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 0020 รท D800 รท # รท [0.2] SPACE (Other) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท 0020 ร 0308 รท D800 รท # รท [0.2] SPACE (Other) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 000D รท 0020 รท # รท [0.2] <CARRIAGE RETURN (CR)> (CR) รท [4.0] SPACE (Other) รท [0.3] รท 000D รท 0308 รท 0020 รท # รท [0.2] <CARRIAGE RETURN (CR)> (CR) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 000D รท 000D รท # รท [0.2] <CARRIAGE RETURN (CR)> (CR) รท [4.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -92,8 +90,6 @@ รท 000D รท 0308 ร 200D รท # รท [0.2] <CARRIAGE RETURN (CR)> (CR) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 000D รท 0378 รท # รท [0.2] <CARRIAGE RETURN (CR)> (CR) รท [4.0] <reserved-0378> (Other) รท [0.3] รท 000D รท 0308 รท 0378 รท # รท [0.2] <CARRIAGE RETURN (CR)> (CR) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 000D รท D800 รท # รท [0.2] <CARRIAGE RETURN (CR)> (CR) รท [4.0] <surrogate-D800> (Control) รท [0.3] -รท 000D รท 0308 รท D800 รท # รท [0.2] <CARRIAGE RETURN (CR)> (CR) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 000A รท 0020 รท # รท [0.2] <LINE FEED (LF)> (LF) รท [4.0] SPACE (Other) รท [0.3] รท 000A รท 0308 รท 0020 รท # รท [0.2] <LINE FEED (LF)> (LF) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 000A รท 000D รท # รท [0.2] <LINE FEED (LF)> (LF) รท [4.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -128,8 +124,6 @@ รท 000A รท 0308 ร 200D รท # รท [0.2] <LINE FEED (LF)> (LF) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 000A รท 0378 รท # รท [0.2] <LINE FEED (LF)> (LF) รท [4.0] <reserved-0378> (Other) รท [0.3] รท 000A รท 0308 รท 0378 รท # รท [0.2] <LINE FEED (LF)> (LF) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 000A รท D800 รท # รท [0.2] <LINE FEED (LF)> (LF) รท [4.0] <surrogate-D800> (Control) รท [0.3] -รท 000A รท 0308 รท D800 รท # รท [0.2] <LINE FEED (LF)> (LF) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 0001 รท 0020 รท # รท [0.2] <START OF HEADING> (Control) รท [4.0] SPACE (Other) รท [0.3] รท 0001 รท 0308 รท 0020 รท # รท [0.2] <START OF HEADING> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 0001 รท 000D รท # รท [0.2] <START OF HEADING> (Control) รท [4.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -164,8 +158,6 @@ รท 0001 รท 0308 ร 200D รท # รท [0.2] <START OF HEADING> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 0001 รท 0378 รท # รท [0.2] <START OF HEADING> (Control) รท [4.0] <reserved-0378> (Other) รท [0.3] รท 0001 รท 0308 รท 0378 รท # รท [0.2] <START OF HEADING> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 0001 รท D800 รท # รท [0.2] <START OF HEADING> (Control) รท [4.0] <surrogate-D800> (Control) รท [0.3] -รท 0001 รท 0308 รท D800 รท # รท [0.2] <START OF HEADING> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 034F รท 0020 รท # รท [0.2] COMBINING GRAPHEME JOINER (Extend) รท [999.0] SPACE (Other) รท [0.3] รท 034F ร 0308 รท 0020 รท # รท [0.2] COMBINING GRAPHEME JOINER (Extend) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 034F รท 000D รท # รท [0.2] COMBINING GRAPHEME JOINER (Extend) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -200,8 +192,6 @@ รท 034F ร 0308 ร 200D รท # รท [0.2] COMBINING GRAPHEME JOINER (Extend) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 034F รท 0378 รท # รท [0.2] COMBINING GRAPHEME JOINER (Extend) รท [999.0] <reserved-0378> (Other) รท [0.3] รท 034F ร 0308 รท 0378 รท # รท [0.2] COMBINING GRAPHEME JOINER (Extend) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 034F รท D800 รท # รท [0.2] COMBINING GRAPHEME JOINER (Extend) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท 034F ร 0308 รท D800 รท # รท [0.2] COMBINING GRAPHEME JOINER (Extend) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 1F1E6 รท 0020 รท # รท [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) รท [999.0] SPACE (Other) รท [0.3] รท 1F1E6 ร 0308 รท 0020 รท # รท [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 1F1E6 รท 000D รท # รท [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -236,8 +226,6 @@ รท 1F1E6 ร 0308 ร 200D รท # รท [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 1F1E6 รท 0378 รท # รท [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) รท [999.0] <reserved-0378> (Other) รท [0.3] รท 1F1E6 ร 0308 รท 0378 รท # รท [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 1F1E6 รท D800 รท # รท [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท 1F1E6 ร 0308 รท D800 รท # รท [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 0600 ร 0020 รท # รท [0.2] ARABIC NUMBER SIGN (Prepend) ร [9.2] SPACE (Other) รท [0.3] รท 0600 ร 0308 รท 0020 รท # รท [0.2] ARABIC NUMBER SIGN (Prepend) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 0600 รท 000D รท # รท [0.2] ARABIC NUMBER SIGN (Prepend) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -272,8 +260,6 @@ รท 0600 ร 0308 ร 200D รท # รท [0.2] ARABIC NUMBER SIGN (Prepend) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 0600 ร 0378 รท # รท [0.2] ARABIC NUMBER SIGN (Prepend) ร [9.2] <reserved-0378> (Other) รท [0.3] รท 0600 ร 0308 รท 0378 รท # รท [0.2] ARABIC NUMBER SIGN (Prepend) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 0600 รท D800 รท # รท [0.2] ARABIC NUMBER SIGN (Prepend) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท 0600 ร 0308 รท D800 รท # รท [0.2] ARABIC NUMBER SIGN (Prepend) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 0903 รท 0020 รท # รท [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) รท [999.0] SPACE (Other) รท [0.3] รท 0903 ร 0308 รท 0020 รท # รท [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 0903 รท 000D รท # รท [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -308,8 +294,6 @@ รท 0903 ร 0308 ร 200D รท # รท [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 0903 รท 0378 รท # รท [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) รท [999.0] <reserved-0378> (Other) รท [0.3] รท 0903 ร 0308 รท 0378 รท # รท [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 0903 รท D800 รท # รท [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท 0903 ร 0308 รท D800 รท # รท [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 1100 รท 0020 รท # รท [0.2] HANGUL CHOSEONG KIYEOK (L) รท [999.0] SPACE (Other) รท [0.3] รท 1100 ร 0308 รท 0020 รท # รท [0.2] HANGUL CHOSEONG KIYEOK (L) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 1100 รท 000D รท # รท [0.2] HANGUL CHOSEONG KIYEOK (L) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -344,8 +328,6 @@ รท 1100 ร 0308 ร 200D รท # รท [0.2] HANGUL CHOSEONG KIYEOK (L) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 1100 รท 0378 รท # รท [0.2] HANGUL CHOSEONG KIYEOK (L) รท [999.0] <reserved-0378> (Other) รท [0.3] รท 1100 ร 0308 รท 0378 รท # รท [0.2] HANGUL CHOSEONG KIYEOK (L) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 1100 รท D800 รท # รท [0.2] HANGUL CHOSEONG KIYEOK (L) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท 1100 ร 0308 รท D800 รท # รท [0.2] HANGUL CHOSEONG KIYEOK (L) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 1160 รท 0020 รท # รท [0.2] HANGUL JUNGSEONG FILLER (V) รท [999.0] SPACE (Other) รท [0.3] รท 1160 ร 0308 รท 0020 รท # รท [0.2] HANGUL JUNGSEONG FILLER (V) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 1160 รท 000D รท # รท [0.2] HANGUL JUNGSEONG FILLER (V) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -380,8 +362,6 @@ รท 1160 ร 0308 ร 200D รท # รท [0.2] HANGUL JUNGSEONG FILLER (V) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 1160 รท 0378 รท # รท [0.2] HANGUL JUNGSEONG FILLER (V) รท [999.0] <reserved-0378> (Other) รท [0.3] รท 1160 ร 0308 รท 0378 รท # รท [0.2] HANGUL JUNGSEONG FILLER (V) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 1160 รท D800 รท # รท [0.2] HANGUL JUNGSEONG FILLER (V) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท 1160 ร 0308 รท D800 รท # รท [0.2] HANGUL JUNGSEONG FILLER (V) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 11A8 รท 0020 รท # รท [0.2] HANGUL JONGSEONG KIYEOK (T) รท [999.0] SPACE (Other) รท [0.3] รท 11A8 ร 0308 รท 0020 รท # รท [0.2] HANGUL JONGSEONG KIYEOK (T) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 11A8 รท 000D รท # รท [0.2] HANGUL JONGSEONG KIYEOK (T) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -416,8 +396,6 @@ รท 11A8 ร 0308 ร 200D รท # รท [0.2] HANGUL JONGSEONG KIYEOK (T) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 11A8 รท 0378 รท # รท [0.2] HANGUL JONGSEONG KIYEOK (T) รท [999.0] <reserved-0378> (Other) รท [0.3] รท 11A8 ร 0308 รท 0378 รท # รท [0.2] HANGUL JONGSEONG KIYEOK (T) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 11A8 รท D800 รท # รท [0.2] HANGUL JONGSEONG KIYEOK (T) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท 11A8 ร 0308 รท D800 รท # รท [0.2] HANGUL JONGSEONG KIYEOK (T) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท AC00 รท 0020 รท # รท [0.2] HANGUL SYLLABLE GA (LV) รท [999.0] SPACE (Other) รท [0.3] รท AC00 ร 0308 รท 0020 รท # รท [0.2] HANGUL SYLLABLE GA (LV) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท AC00 รท 000D รท # รท [0.2] HANGUL SYLLABLE GA (LV) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -452,8 +430,6 @@ รท AC00 ร 0308 ร 200D รท # รท [0.2] HANGUL SYLLABLE GA (LV) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท AC00 รท 0378 รท # รท [0.2] HANGUL SYLLABLE GA (LV) รท [999.0] <reserved-0378> (Other) รท [0.3] รท AC00 ร 0308 รท 0378 รท # รท [0.2] HANGUL SYLLABLE GA (LV) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท AC00 รท D800 รท # รท [0.2] HANGUL SYLLABLE GA (LV) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท AC00 ร 0308 รท D800 รท # รท [0.2] HANGUL SYLLABLE GA (LV) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท AC01 รท 0020 รท # รท [0.2] HANGUL SYLLABLE GAG (LVT) รท [999.0] SPACE (Other) รท [0.3] รท AC01 ร 0308 รท 0020 รท # รท [0.2] HANGUL SYLLABLE GAG (LVT) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท AC01 รท 000D รท # รท [0.2] HANGUL SYLLABLE GAG (LVT) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -488,8 +464,6 @@ รท AC01 ร 0308 ร 200D รท # รท [0.2] HANGUL SYLLABLE GAG (LVT) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท AC01 รท 0378 รท # รท [0.2] HANGUL SYLLABLE GAG (LVT) รท [999.0] <reserved-0378> (Other) รท [0.3] รท AC01 ร 0308 รท 0378 รท # รท [0.2] HANGUL SYLLABLE GAG (LVT) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท AC01 รท D800 รท # รท [0.2] HANGUL SYLLABLE GAG (LVT) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท AC01 ร 0308 รท D800 รท # รท [0.2] HANGUL SYLLABLE GAG (LVT) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 231A รท 0020 รท # รท [0.2] WATCH (ExtPict) รท [999.0] SPACE (Other) รท [0.3] รท 231A ร 0308 รท 0020 รท # รท [0.2] WATCH (ExtPict) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 231A รท 000D รท # รท [0.2] WATCH (ExtPict) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -524,8 +498,6 @@ รท 231A ร 0308 ร 200D รท # รท [0.2] WATCH (ExtPict) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 231A รท 0378 รท # รท [0.2] WATCH (ExtPict) รท [999.0] <reserved-0378> (Other) รท [0.3] รท 231A ร 0308 รท 0378 รท # รท [0.2] WATCH (ExtPict) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 231A รท D800 รท # รท [0.2] WATCH (ExtPict) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท 231A ร 0308 รท D800 รท # รท [0.2] WATCH (ExtPict) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 0300 รท 0020 รท # รท [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 0300 ร 0308 รท 0020 รท # รท [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 0300 รท 000D รท # รท [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -560,8 +532,6 @@ รท 0300 ร 0308 ร 200D รท # รท [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 0300 รท 0378 รท # รท [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] รท 0300 ร 0308 รท 0378 รท # รท [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 0300 รท D800 รท # รท [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท 0300 ร 0308 รท D800 รท # รท [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 200D รท 0020 รท # รท [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 200D ร 0308 รท 0020 รท # รท [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 200D รท 000D รท # รท [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -596,8 +566,6 @@ รท 200D ร 0308 ร 200D รท # รท [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 200D รท 0378 รท # รท [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] รท 200D ร 0308 รท 0378 รท # รท [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 200D รท D800 รท # รท [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท 200D ร 0308 รท D800 รท # รท [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 0378 รท 0020 รท # รท [0.2] <reserved-0378> (Other) รท [999.0] SPACE (Other) รท [0.3] รท 0378 ร 0308 รท 0020 รท # รท [0.2] <reserved-0378> (Other) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] รท 0378 รท 000D รท # รท [0.2] <reserved-0378> (Other) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] @@ -632,44 +600,6 @@ รท 0378 ร 0308 ร 200D รท # รท [0.2] <reserved-0378> (Other) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] รท 0378 รท 0378 รท # รท [0.2] <reserved-0378> (Other) รท [999.0] <reserved-0378> (Other) รท [0.3] รท 0378 ร 0308 รท 0378 รท # รท [0.2] <reserved-0378> (Other) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท 0378 รท D800 รท # รท [0.2] <reserved-0378> (Other) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท 0378 ร 0308 รท D800 รท # รท [0.2] <reserved-0378> (Other) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] -รท D800 รท 0020 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] SPACE (Other) รท [0.3] -รท D800 รท 0308 รท 0020 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] SPACE (Other) รท [0.3] -รท D800 รท 000D รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] -รท D800 รท 0308 รท 000D รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <CARRIAGE RETURN (CR)> (CR) รท [0.3] -รท D800 รท 000A รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] <LINE FEED (LF)> (LF) รท [0.3] -รท D800 รท 0308 รท 000A รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <LINE FEED (LF)> (LF) รท [0.3] -รท D800 รท 0001 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] <START OF HEADING> (Control) รท [0.3] -รท D800 รท 0308 รท 0001 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <START OF HEADING> (Control) รท [0.3] -รท D800 รท 034F รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING GRAPHEME JOINER (Extend) รท [0.3] -รท D800 รท 0308 ร 034F รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] COMBINING GRAPHEME JOINER (Extend) รท [0.3] -รท D800 รท 1F1E6 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) รท [0.3] -รท D800 รท 0308 รท 1F1E6 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) รท [0.3] -รท D800 รท 0600 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] ARABIC NUMBER SIGN (Prepend) รท [0.3] -รท D800 รท 0308 รท 0600 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] ARABIC NUMBER SIGN (Prepend) รท [0.3] -รท D800 รท 0903 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) รท [0.3] -รท D800 รท 0308 ร 0903 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) รท [0.3] -รท D800 รท 1100 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] HANGUL CHOSEONG KIYEOK (L) รท [0.3] -รท D800 รท 0308 รท 1100 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] HANGUL CHOSEONG KIYEOK (L) รท [0.3] -รท D800 รท 1160 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] HANGUL JUNGSEONG FILLER (V) รท [0.3] -รท D800 รท 0308 รท 1160 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] HANGUL JUNGSEONG FILLER (V) รท [0.3] -รท D800 รท 11A8 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] HANGUL JONGSEONG KIYEOK (T) รท [0.3] -รท D800 รท 0308 รท 11A8 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] HANGUL JONGSEONG KIYEOK (T) รท [0.3] -รท D800 รท AC00 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] HANGUL SYLLABLE GA (LV) รท [0.3] -รท D800 รท 0308 รท AC00 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] HANGUL SYLLABLE GA (LV) รท [0.3] -รท D800 รท AC01 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] HANGUL SYLLABLE GAG (LVT) รท [0.3] -รท D800 รท 0308 รท AC01 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] HANGUL SYLLABLE GAG (LVT) รท [0.3] -รท D800 รท 231A รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] WATCH (ExtPict) รท [0.3] -รท D800 รท 0308 รท 231A รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] WATCH (ExtPict) รท [0.3] -รท D800 รท 0300 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) รท [0.3] -รท D800 รท 0308 ร 0300 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) รท [0.3] -รท D800 รท 200D รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] -รท D800 รท 0308 ร 200D รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [0.3] -รท D800 รท 0378 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] <reserved-0378> (Other) รท [0.3] -รท D800 รท 0308 รท 0378 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [999.0] <reserved-0378> (Other) รท [0.3] -รท D800 รท D800 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] <surrogate-D800> (Control) รท [0.3] -รท D800 รท 0308 รท D800 รท # รท [0.2] <surrogate-D800> (Control) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [5.0] <surrogate-D800> (Control) รท [0.3] รท 000D ร 000A รท 0061 รท 000A รท 0308 รท # รท [0.2] <CARRIAGE RETURN (CR)> (CR) ร [3.0] <LINE FEED (LF)> (LF) รท [4.0] LATIN SMALL LETTER A (Other) รท [5.0] <LINE FEED (LF)> (LF) รท [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [0.3] รท 0061 ร 0308 รท # รท [0.2] LATIN SMALL LETTER A (Other) ร [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) รท [0.3] รท 0020 ร 200D รท 0646 รท # รท [0.2] SPACE (Other) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [999.0] ARABIC LETTER NOON (Other) รท [0.3] @@ -695,6 +625,6 @@ รท 2701 ร 200D ร 2701 รท # รท [0.2] UPPER BLADE SCISSORS (Other) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ร [11.0] UPPER BLADE SCISSORS (Other) รท [0.3] รท 0061 ร 200D รท 2701 รท # รท [0.2] LATIN SMALL LETTER A (Other) ร [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) รท [999.0] UPPER BLADE SCISSORS (Other) รท [0.3] # -# Lines: 672 +# Lines: 602 # # EOF diff --git a/lib/stdlib/test/unicode_util_SUITE_data/LineBreakTest.txt b/lib/stdlib/test/unicode_util_SUITE_data/LineBreakTest.txt index 0e9e678a85..eb056990a0 100644 --- a/lib/stdlib/test/unicode_util_SUITE_data/LineBreakTest.txt +++ b/lib/stdlib/test/unicode_util_SUITE_data/LineBreakTest.txt @@ -1,6 +1,6 @@ -# LineBreakTest-11.0.0.txt -# Date: 2018-05-20, 09:03:09 GMT -# ยฉ 2018 Unicodeยฎ, Inc. +# LineBreakTest-12.1.0.txt +# Date: 2019-03-10, 10:53:14 GMT +# ยฉ 2019 Unicodeยฎ, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # diff --git a/lib/stdlib/test/unicode_util_SUITE_data/NormalizationTest.txt b/lib/stdlib/test/unicode_util_SUITE_data/NormalizationTest.txt index 72a31bcdf1..54f43bdf4d 100644 --- a/lib/stdlib/test/unicode_util_SUITE_data/NormalizationTest.txt +++ b/lib/stdlib/test/unicode_util_SUITE_data/NormalizationTest.txt @@ -1,6 +1,6 @@ -# NormalizationTest-11.0.0.txt -# Date: 2018-02-19, 18:33:08 GMT -# ยฉ 2018 Unicodeยฎ, Inc. +# NormalizationTest-12.1.0.txt +# Date: 2019-04-01, 09:10:28 GMT +# ยฉ 2019 Unicodeยฎ, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # @@ -2149,6 +2149,7 @@ 32FC;32FC;32FC;30F0;30F0; # (ใผ; ใผ; ใผ; ใฐ; ใฐ; ) CIRCLED KATAKANA WI 32FD;32FD;32FD;30F1;30F1; # (ใฝ; ใฝ; ใฝ; ใฑ; ใฑ; ) CIRCLED KATAKANA WE 32FE;32FE;32FE;30F2;30F2; # (ใพ; ใพ; ใพ; ใฒ; ใฒ; ) CIRCLED KATAKANA WO +32FF;32FF;32FF;4EE4 548C;4EE4 548C; # (ใฟ; ใฟ; ใฟ; ไปคๅ; ไปคๅ; ) SQUARE ERA NAME REIWA 3300;3300;3300;30A2 30D1 30FC 30C8;30A2 30CF 309A 30FC 30C8; # (ใ; ใ; ใ; ใขใใผใ; ใขใโใใผใ; ) SQUARE APAATO 3301;3301;3301;30A2 30EB 30D5 30A1;30A2 30EB 30D5 30A1; # (ใ; ใ; ใ; ใขใซใใก; ใขใซใใก; ) SQUARE ARUHUA 3302;3302;3302;30A2 30F3 30DA 30A2;30A2 30F3 30D8 309A 30A2; # (ใ; ใ; ใ; ใขใณใใข; ใขใณใโใใข; ) SQUARE ANPEA @@ -16363,6 +16364,7 @@ FFEE;FFEE;FFEE;25CB;25CB; # (๏ฟฎ; ๏ฟฎ; ๏ฟฎ; โ; โ; ) HALFWIDTH WHITE CIRCLE 1F14F;1F14F;1F14F;0057 0043;0057 0043; # (๐
; ๐
; ๐
; WC; WC; ) SQUARED WC 1F16A;1F16A;1F16A;004D 0043;004D 0043; # (๐
ช; ๐
ช; ๐
ช; MC; MC; ) RAISED MC SIGN 1F16B;1F16B;1F16B;004D 0044;004D 0044; # (๐
ซ; ๐
ซ; ๐
ซ; MD; MD; ) RAISED MD SIGN +1F16C;1F16C;1F16C;004D 0052;004D 0052; # (๐
ฌ; ๐
ฌ; ๐
ฌ; MR; MR; ) RAISED MR SIGN 1F190;1F190;1F190;0044 004A;0044 004A; # (๐; ๐; ๐; DJ; DJ; ) SQUARE DJ 1F200;1F200;1F200;307B 304B;307B 304B; # (๐; ๐; ๐; ใปใ; ใปใ; ) SQUARE HIRAGANA HOKA 1F201;1F201;1F201;30B3 30B3;30B3 30B3; # (๐; ๐; ๐; ใณใณ; ใณใณ; ) SQUARED KATAKANA KOKO @@ -17685,6 +17687,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (๏ฟฎ; ๏ฟฎ; ๏ฟฎ; โ; โ; ) HALFWIDTH WHITE CIRCLE 0061 0EB8 0EC8 0EB8 0E48 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062;0061 0E48 0EB8 0EB8 0EC8 0062; # (aโเบธโเปโเบธโเนb; aโเนโเบธโเบธโเปb; aโเนโเบธโเบธโเปb; aโเนโเบธโเบธโเปb; aโเนโเบธโเบธโเปb; ) LATIN SMALL LETTER A, LAO VOWEL SIGN U, LAO TONE MAI EK, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, LATIN SMALL LETTER B 0061 0EC8 0EB8 0E48 0EB9 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062;0061 0E48 0EB8 0EB9 0EC8 0062; # (aโเปโเบธโเนโเบนb; aโเนโเบธโเบนโเปb; aโเนโเบธโเบนโเปb; aโเนโเบธโเบนโเปb; aโเนโเบธโเบนโเปb; ) LATIN SMALL LETTER A, LAO TONE MAI EK, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, LAO VOWEL SIGN UU, LATIN SMALL LETTER B 0061 0EB9 0EC8 0EB8 0E48 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062;0061 0E48 0EB9 0EB8 0EC8 0062; # (aโเบนโเปโเบธโเนb; aโเนโเบนโเบธโเปb; aโเนโเบนโเบธโเปb; aโเนโเบนโเบธโเปb; aโเนโเบนโเบธโเปb; ) LATIN SMALL LETTER A, LAO VOWEL SIGN UU, LAO TONE MAI EK, LAO VOWEL SIGN U, THAI CHARACTER MAI EK, LATIN SMALL LETTER B +0061 05B0 094D 3099 0EBA 0062;0061 3099 094D 0EBA 05B0 0062;0061 3099 094D 0EBA 05B0 0062;0061 3099 094D 0EBA 05B0 0062;0061 3099 094D 0EBA 05B0 0062; # (aโึฐโเฅโใโเบบb; aโใโเฅโเบบโึฐb; aโใโเฅโเบบโึฐb; aโใโเฅโเบบโึฐb; aโใโเฅโเบบโึฐb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LAO SIGN PALI VIRAMA, LATIN SMALL LETTER B +0061 0EBA 05B0 094D 3099 0062;0061 3099 0EBA 094D 05B0 0062;0061 3099 0EBA 094D 05B0 0062;0061 3099 0EBA 094D 05B0 0062;0061 3099 0EBA 094D 05B0 0062; # (aโเบบโึฐโเฅโใb; aโใโเบบโเฅโึฐb; aโใโเบบโเฅโึฐb; aโใโเบบโเฅโึฐb; aโใโเบบโเฅโึฐb; ) LATIN SMALL LETTER A, LAO SIGN PALI VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B 0061 0F71 0EC8 0EB8 0EC8 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062; # (aโเฝฑโเปโเบธโเปb; aโเบธโเปโเปโเฝฑb; aโเบธโเปโเปโเฝฑb; aโเบธโเปโเปโเฝฑb; aโเบธโเปโเปโเฝฑb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LAO TONE MAI EK, LATIN SMALL LETTER B 0061 0EC8 0F71 0EC8 0EB8 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062;0061 0EB8 0EC8 0EC8 0F71 0062; # (aโเปโเฝฑโเปโเบธb; aโเบธโเปโเปโเฝฑb; aโเบธโเปโเปโเฝฑb; aโเบธโเปโเปโเฝฑb; aโเบธโเปโเปโเฝฑb; ) LATIN SMALL LETTER A, LAO TONE MAI EK, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LATIN SMALL LETTER B 0061 0F71 0EC8 0EB8 0EC9 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062;0061 0EB8 0EC8 0EC9 0F71 0062; # (aโเฝฑโเปโเบธโเปb; aโเบธโเปโเปโเฝฑb; aโเบธโเปโเปโเฝฑb; aโเบธโเปโเปโเฝฑb; aโเบธโเปโเปโเฝฑb; ) LATIN SMALL LETTER A, TIBETAN VOWEL SIGN AA, LAO TONE MAI EK, LAO VOWEL SIGN U, LAO TONE MAI THO, LATIN SMALL LETTER B @@ -18453,6 +18457,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (๏ฟฎ; ๏ฟฎ; ๏ฟฎ; โ; โ; ) HALFWIDTH WHITE CIRCLE 0061 11839 05B0 094D 3099 0062;0061 3099 11839 094D 05B0 0062;0061 3099 11839 094D 05B0 0062;0061 3099 11839 094D 05B0 0062;0061 3099 11839 094D 05B0 0062; # (aโ๐ นโึฐโเฅโใb; aโใโ๐ นโเฅโึฐb; aโใโ๐ นโเฅโึฐb; aโใโ๐ นโเฅโึฐb; aโใโ๐ นโเฅโึฐb; ) LATIN SMALL LETTER A, DOGRA SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B 0061 3099 093C 0334 1183A 0062;0061 0334 093C 1183A 3099 0062;0061 0334 093C 1183A 3099 0062;0061 0334 093C 1183A 3099 0062;0061 0334 093C 1183A 3099 0062; # (aโใโเคผโฬดโ๐ บb; aโฬดโเคผโ๐ บโใb; aโฬดโเคผโ๐ บโใb; aโฬดโเคผโ๐ บโใb; aโฬดโเคผโ๐ บโใb; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, DOGRA SIGN NUKTA, LATIN SMALL LETTER B 0061 1183A 3099 093C 0334 0062;0061 0334 1183A 093C 3099 0062;0061 0334 1183A 093C 3099 0062;0061 0334 1183A 093C 3099 0062;0061 0334 1183A 093C 3099 0062; # (aโ๐ บโใโเคผโฬดb; aโฬดโ๐ บโเคผโใb; aโฬดโ๐ บโเคผโใb; aโฬดโ๐ บโเคผโใb; aโฬดโ๐ บโเคผโใb; ) LATIN SMALL LETTER A, DOGRA SIGN NUKTA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B +0061 05B0 094D 3099 119E0 0062;0061 3099 094D 119E0 05B0 0062;0061 3099 094D 119E0 05B0 0062;0061 3099 094D 119E0 05B0 0062;0061 3099 094D 119E0 05B0 0062; # (aโึฐโเฅโใโ๐ง b; aโใโเฅโ๐ง โึฐb; aโใโเฅโ๐ง โึฐb; aโใโเฅโ๐ง โึฐb; aโใโเฅโ๐ง โึฐb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, NANDINAGARI SIGN VIRAMA, LATIN SMALL LETTER B +0061 119E0 05B0 094D 3099 0062;0061 3099 119E0 094D 05B0 0062;0061 3099 119E0 094D 05B0 0062;0061 3099 119E0 094D 05B0 0062;0061 3099 119E0 094D 05B0 0062; # (aโ๐ง โึฐโเฅโใb; aโใโ๐ง โเฅโึฐb; aโใโ๐ง โเฅโึฐb; aโใโ๐ง โเฅโึฐb; aโใโ๐ง โเฅโึฐb; ) LATIN SMALL LETTER A, NANDINAGARI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B 0061 05B0 094D 3099 11A34 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062;0061 3099 094D 11A34 05B0 0062; # (aโึฐโเฅโใโ๐จดb; aโใโเฅโ๐จดโึฐb; aโใโเฅโ๐จดโึฐb; aโใโเฅโ๐จดโึฐb; aโใโเฅโ๐จดโึฐb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, ZANABAZAR SQUARE SIGN VIRAMA, LATIN SMALL LETTER B 0061 11A34 05B0 094D 3099 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062;0061 3099 11A34 094D 05B0 0062; # (aโ๐จดโึฐโเฅโใb; aโใโ๐จดโเฅโึฐb; aโใโ๐จดโเฅโึฐb; aโใโ๐จดโเฅโึฐb; aโใโ๐จดโเฅโึฐb; ) LATIN SMALL LETTER A, ZANABAZAR SQUARE SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B 0061 05B0 094D 3099 11A47 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062;0061 3099 094D 11A47 05B0 0062; # (aโึฐโเฅโใโ๐ฉb; aโใโเฅโ๐ฉโึฐb; aโใโเฅโ๐ฉโึฐb; aโใโเฅโ๐ฉโึฐb; aโใโเฅโ๐ฉโึฐb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, ZANABAZAR SQUARE SUBJOINER, LATIN SMALL LETTER B @@ -18637,6 +18643,28 @@ FFEE;FFEE;FFEE;25CB;25CB; # (๏ฟฎ; ๏ฟฎ; ๏ฟฎ; โ; โ; ) HALFWIDTH WHITE CIRCLE 0061 1E029 0315 0300 05AE 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062; # (aโ๐ฉโฬโฬโึฎb; aโึฎโ๐ฉโฬโฬb; aโึฎโ๐ฉโฬโฬb; aโึฎโ๐ฉโฬโฬb; aโึฎโ๐ฉโฬโฬb; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER IOTATED BIG YUS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B 0061 0315 0300 05AE 1E02A 0062;00E0 05AE 1E02A 0315 0062;0061 05AE 0300 1E02A 0315 0062;00E0 05AE 1E02A 0315 0062;0061 05AE 0300 1E02A 0315 0062; # (aโฬโฬโึฎโ๐ชb; ร โึฎโ๐ชโฬb; aโึฎโฬโ๐ชโฬb; ร โึฎโ๐ชโฬb; aโึฎโฬโ๐ชโฬb; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER FITA, LATIN SMALL LETTER B 0061 1E02A 0315 0300 05AE 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062; # (aโ๐ชโฬโฬโึฎb; aโึฎโ๐ชโฬโฬb; aโึฎโ๐ชโฬโฬb; aโึฎโ๐ชโฬโฬb; aโึฎโ๐ชโฬโฬb; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER FITA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 1E130 0062;00E0 05AE 1E130 0315 0062;0061 05AE 0300 1E130 0315 0062;00E0 05AE 1E130 0315 0062;0061 05AE 0300 1E130 0315 0062; # (aโฬโฬโึฎโ๐ฐb; ร โึฎโ๐ฐโฬb; aโึฎโฬโ๐ฐโฬb; ร โึฎโ๐ฐโฬb; aโึฎโฬโ๐ฐโฬb; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NYIAKENG PUACHUE HMONG TONE-B, LATIN SMALL LETTER B +0061 1E130 0315 0300 05AE 0062;0061 05AE 1E130 0300 0315 0062;0061 05AE 1E130 0300 0315 0062;0061 05AE 1E130 0300 0315 0062;0061 05AE 1E130 0300 0315 0062; # (aโ๐ฐโฬโฬโึฎb; aโึฎโ๐ฐโฬโฬb; aโึฎโ๐ฐโฬโฬb; aโึฎโ๐ฐโฬโฬb; aโึฎโ๐ฐโฬโฬb; ) LATIN SMALL LETTER A, NYIAKENG PUACHUE HMONG TONE-B, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 1E131 0062;00E0 05AE 1E131 0315 0062;0061 05AE 0300 1E131 0315 0062;00E0 05AE 1E131 0315 0062;0061 05AE 0300 1E131 0315 0062; # (aโฬโฬโึฎโ๐ฑb; ร โึฎโ๐ฑโฬb; aโึฎโฬโ๐ฑโฬb; ร โึฎโ๐ฑโฬb; aโึฎโฬโ๐ฑโฬb; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NYIAKENG PUACHUE HMONG TONE-M, LATIN SMALL LETTER B +0061 1E131 0315 0300 05AE 0062;0061 05AE 1E131 0300 0315 0062;0061 05AE 1E131 0300 0315 0062;0061 05AE 1E131 0300 0315 0062;0061 05AE 1E131 0300 0315 0062; # (aโ๐ฑโฬโฬโึฎb; aโึฎโ๐ฑโฬโฬb; aโึฎโ๐ฑโฬโฬb; aโึฎโ๐ฑโฬโฬb; aโึฎโ๐ฑโฬโฬb; ) LATIN SMALL LETTER A, NYIAKENG PUACHUE HMONG TONE-M, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 1E132 0062;00E0 05AE 1E132 0315 0062;0061 05AE 0300 1E132 0315 0062;00E0 05AE 1E132 0315 0062;0061 05AE 0300 1E132 0315 0062; # (aโฬโฬโึฎโ๐ฒb; ร โึฎโ๐ฒโฬb; aโึฎโฬโ๐ฒโฬb; ร โึฎโ๐ฒโฬb; aโึฎโฬโ๐ฒโฬb; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NYIAKENG PUACHUE HMONG TONE-J, LATIN SMALL LETTER B +0061 1E132 0315 0300 05AE 0062;0061 05AE 1E132 0300 0315 0062;0061 05AE 1E132 0300 0315 0062;0061 05AE 1E132 0300 0315 0062;0061 05AE 1E132 0300 0315 0062; # (aโ๐ฒโฬโฬโึฎb; aโึฎโ๐ฒโฬโฬb; aโึฎโ๐ฒโฬโฬb; aโึฎโ๐ฒโฬโฬb; aโึฎโ๐ฒโฬโฬb; ) LATIN SMALL LETTER A, NYIAKENG PUACHUE HMONG TONE-J, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 1E133 0062;00E0 05AE 1E133 0315 0062;0061 05AE 0300 1E133 0315 0062;00E0 05AE 1E133 0315 0062;0061 05AE 0300 1E133 0315 0062; # (aโฬโฬโึฎโ๐ณb; ร โึฎโ๐ณโฬb; aโึฎโฬโ๐ณโฬb; ร โึฎโ๐ณโฬb; aโึฎโฬโ๐ณโฬb; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NYIAKENG PUACHUE HMONG TONE-V, LATIN SMALL LETTER B +0061 1E133 0315 0300 05AE 0062;0061 05AE 1E133 0300 0315 0062;0061 05AE 1E133 0300 0315 0062;0061 05AE 1E133 0300 0315 0062;0061 05AE 1E133 0300 0315 0062; # (aโ๐ณโฬโฬโึฎb; aโึฎโ๐ณโฬโฬb; aโึฎโ๐ณโฬโฬb; aโึฎโ๐ณโฬโฬb; aโึฎโ๐ณโฬโฬb; ) LATIN SMALL LETTER A, NYIAKENG PUACHUE HMONG TONE-V, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 1E134 0062;00E0 05AE 1E134 0315 0062;0061 05AE 0300 1E134 0315 0062;00E0 05AE 1E134 0315 0062;0061 05AE 0300 1E134 0315 0062; # (aโฬโฬโึฎโ๐ดb; ร โึฎโ๐ดโฬb; aโึฎโฬโ๐ดโฬb; ร โึฎโ๐ดโฬb; aโึฎโฬโ๐ดโฬb; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NYIAKENG PUACHUE HMONG TONE-S, LATIN SMALL LETTER B +0061 1E134 0315 0300 05AE 0062;0061 05AE 1E134 0300 0315 0062;0061 05AE 1E134 0300 0315 0062;0061 05AE 1E134 0300 0315 0062;0061 05AE 1E134 0300 0315 0062; # (aโ๐ดโฬโฬโึฎb; aโึฎโ๐ดโฬโฬb; aโึฎโ๐ดโฬโฬb; aโึฎโ๐ดโฬโฬb; aโึฎโ๐ดโฬโฬb; ) LATIN SMALL LETTER A, NYIAKENG PUACHUE HMONG TONE-S, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 1E135 0062;00E0 05AE 1E135 0315 0062;0061 05AE 0300 1E135 0315 0062;00E0 05AE 1E135 0315 0062;0061 05AE 0300 1E135 0315 0062; # (aโฬโฬโึฎโ๐ตb; ร โึฎโ๐ตโฬb; aโึฎโฬโ๐ตโฬb; ร โึฎโ๐ตโฬb; aโึฎโฬโ๐ตโฬb; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NYIAKENG PUACHUE HMONG TONE-G, LATIN SMALL LETTER B +0061 1E135 0315 0300 05AE 0062;0061 05AE 1E135 0300 0315 0062;0061 05AE 1E135 0300 0315 0062;0061 05AE 1E135 0300 0315 0062;0061 05AE 1E135 0300 0315 0062; # (aโ๐ตโฬโฬโึฎb; aโึฎโ๐ตโฬโฬb; aโึฎโ๐ตโฬโฬb; aโึฎโ๐ตโฬโฬb; aโึฎโ๐ตโฬโฬb; ) LATIN SMALL LETTER A, NYIAKENG PUACHUE HMONG TONE-G, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 1E136 0062;00E0 05AE 1E136 0315 0062;0061 05AE 0300 1E136 0315 0062;00E0 05AE 1E136 0315 0062;0061 05AE 0300 1E136 0315 0062; # (aโฬโฬโึฎโ๐ถb; ร โึฎโ๐ถโฬb; aโึฎโฬโ๐ถโฬb; ร โึฎโ๐ถโฬb; aโึฎโฬโ๐ถโฬb; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NYIAKENG PUACHUE HMONG TONE-D, LATIN SMALL LETTER B +0061 1E136 0315 0300 05AE 0062;0061 05AE 1E136 0300 0315 0062;0061 05AE 1E136 0300 0315 0062;0061 05AE 1E136 0300 0315 0062;0061 05AE 1E136 0300 0315 0062; # (aโ๐ถโฬโฬโึฎb; aโึฎโ๐ถโฬโฬb; aโึฎโ๐ถโฬโฬb; aโึฎโ๐ถโฬโฬb; aโึฎโ๐ถโฬโฬb; ) LATIN SMALL LETTER A, NYIAKENG PUACHUE HMONG TONE-D, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 1E2EC 0062;00E0 05AE 1E2EC 0315 0062;0061 05AE 0300 1E2EC 0315 0062;00E0 05AE 1E2EC 0315 0062;0061 05AE 0300 1E2EC 0315 0062; # (aโฬโฬโึฎโ๐ฌb; ร โึฎโ๐ฌโฬb; aโึฎโฬโ๐ฌโฬb; ร โึฎโ๐ฌโฬb; aโึฎโฬโ๐ฌโฬb; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, WANCHO TONE TUP, LATIN SMALL LETTER B +0061 1E2EC 0315 0300 05AE 0062;0061 05AE 1E2EC 0300 0315 0062;0061 05AE 1E2EC 0300 0315 0062;0061 05AE 1E2EC 0300 0315 0062;0061 05AE 1E2EC 0300 0315 0062; # (aโ๐ฌโฬโฬโึฎb; aโึฎโ๐ฌโฬโฬb; aโึฎโ๐ฌโฬโฬb; aโึฎโ๐ฌโฬโฬb; aโึฎโ๐ฌโฬโฬb; ) LATIN SMALL LETTER A, WANCHO TONE TUP, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 1E2ED 0062;00E0 05AE 1E2ED 0315 0062;0061 05AE 0300 1E2ED 0315 0062;00E0 05AE 1E2ED 0315 0062;0061 05AE 0300 1E2ED 0315 0062; # (aโฬโฬโึฎโ๐ญb; ร โึฎโ๐ญโฬb; aโึฎโฬโ๐ญโฬb; ร โึฎโ๐ญโฬb; aโึฎโฬโ๐ญโฬb; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, WANCHO TONE TUPNI, LATIN SMALL LETTER B +0061 1E2ED 0315 0300 05AE 0062;0061 05AE 1E2ED 0300 0315 0062;0061 05AE 1E2ED 0300 0315 0062;0061 05AE 1E2ED 0300 0315 0062;0061 05AE 1E2ED 0300 0315 0062; # (aโ๐ญโฬโฬโึฎb; aโึฎโ๐ญโฬโฬb; aโึฎโ๐ญโฬโฬb; aโึฎโ๐ญโฬโฬb; aโึฎโ๐ญโฬโฬb; ) LATIN SMALL LETTER A, WANCHO TONE TUPNI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 1E2EE 0062;00E0 05AE 1E2EE 0315 0062;0061 05AE 0300 1E2EE 0315 0062;00E0 05AE 1E2EE 0315 0062;0061 05AE 0300 1E2EE 0315 0062; # (aโฬโฬโึฎโ๐ฎb; ร โึฎโ๐ฎโฬb; aโึฎโฬโ๐ฎโฬb; ร โึฎโ๐ฎโฬb; aโึฎโฬโ๐ฎโฬb; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, WANCHO TONE KOI, LATIN SMALL LETTER B +0061 1E2EE 0315 0300 05AE 0062;0061 05AE 1E2EE 0300 0315 0062;0061 05AE 1E2EE 0300 0315 0062;0061 05AE 1E2EE 0300 0315 0062;0061 05AE 1E2EE 0300 0315 0062; # (aโ๐ฎโฬโฬโึฎb; aโึฎโ๐ฎโฬโฬb; aโึฎโ๐ฎโฬโฬb; aโึฎโ๐ฎโฬโฬb; aโึฎโ๐ฎโฬโฬb; ) LATIN SMALL LETTER A, WANCHO TONE KOI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 1E2EF 0062;00E0 05AE 1E2EF 0315 0062;0061 05AE 0300 1E2EF 0315 0062;00E0 05AE 1E2EF 0315 0062;0061 05AE 0300 1E2EF 0315 0062; # (aโฬโฬโึฎโ๐ฏb; ร โึฎโ๐ฏโฬb; aโึฎโฬโ๐ฏโฬb; ร โึฎโ๐ฏโฬb; aโึฎโฬโ๐ฏโฬb; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, WANCHO TONE KOINI, LATIN SMALL LETTER B +0061 1E2EF 0315 0300 05AE 0062;0061 05AE 1E2EF 0300 0315 0062;0061 05AE 1E2EF 0300 0315 0062;0061 05AE 1E2EF 0300 0315 0062;0061 05AE 1E2EF 0300 0315 0062; # (aโ๐ฏโฬโฬโึฎb; aโึฎโ๐ฏโฬโฬb; aโึฎโ๐ฏโฬโฬb; aโึฎโ๐ฏโฬโฬb; aโึฎโ๐ฏโฬโฬb; ) LATIN SMALL LETTER A, WANCHO TONE KOINI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B 0061 059A 0316 302A 1E8D0 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062;0061 302A 0316 1E8D0 059A 0062; # (aโึโฬโใชโ๐ฃb; aโใชโฬโ๐ฃโึb; aโใชโฬโ๐ฃโึb; aโใชโฬโ๐ฃโึb; aโใชโฬโ๐ฃโึb; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER TEENS, LATIN SMALL LETTER B 0061 1E8D0 059A 0316 302A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062;0061 302A 1E8D0 0316 059A 0062; # (aโ๐ฃโึโฬโใชb; aโใชโ๐ฃโฬโึb; aโใชโ๐ฃโฬโึb; aโใชโ๐ฃโฬโึb; aโใชโ๐ฃโฬโึb; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER TEENS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, LATIN SMALL LETTER B 0061 059A 0316 302A 1E8D1 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062;0061 302A 0316 1E8D1 059A 0062; # (aโึโฬโใชโ๐ฃb; aโใชโฬโ๐ฃโึb; aโใชโฬโ๐ฃโึb; aโใชโฬโ๐ฃโึb; aโใชโฬโ๐ฃโึb; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, IDEOGRAPHIC LEVEL TONE MARK, MENDE KIKAKUI COMBINING NUMBER TENS, LATIN SMALL LETTER B diff --git a/lib/stdlib/uc_spec/CaseFolding.txt b/lib/stdlib/uc_spec/CaseFolding.txt index cce350f49c..7eeb915abf 100644 --- a/lib/stdlib/uc_spec/CaseFolding.txt +++ b/lib/stdlib/uc_spec/CaseFolding.txt @@ -1,6 +1,6 @@ -# CaseFolding-11.0.0.txt -# Date: 2018-01-31, 08:20:09 GMT -# ยฉ 2018 Unicodeยฎ, Inc. +# CaseFolding-12.1.0.txt +# Date: 2019-03-10, 10:53:00 GMT +# ยฉ 2019 Unicodeยฎ, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # @@ -1227,6 +1227,13 @@ A7B3; C; AB53; # LATIN CAPITAL LETTER CHI A7B4; C; A7B5; # LATIN CAPITAL LETTER BETA A7B6; C; A7B7; # LATIN CAPITAL LETTER OMEGA A7B8; C; A7B9; # LATIN CAPITAL LETTER U WITH STROKE +A7BA; C; A7BB; # LATIN CAPITAL LETTER GLOTTAL A +A7BC; C; A7BD; # LATIN CAPITAL LETTER GLOTTAL I +A7BE; C; A7BF; # LATIN CAPITAL LETTER GLOTTAL U +A7C2; C; A7C3; # LATIN CAPITAL LETTER ANGLICANA W +A7C4; C; A794; # LATIN CAPITAL LETTER C WITH PALATAL HOOK +A7C5; C; 0282; # LATIN CAPITAL LETTER S WITH HOOK +A7C6; C; 1D8E; # LATIN CAPITAL LETTER Z WITH PALATAL HOOK AB70; C; 13A0; # CHEROKEE SMALL LETTER A AB71; C; 13A1; # CHEROKEE SMALL LETTER E AB72; C; 13A2; # CHEROKEE SMALL LETTER I diff --git a/lib/stdlib/uc_spec/CompositionExclusions.txt b/lib/stdlib/uc_spec/CompositionExclusions.txt index ea63595bd3..aa654974be 100644 --- a/lib/stdlib/uc_spec/CompositionExclusions.txt +++ b/lib/stdlib/uc_spec/CompositionExclusions.txt @@ -1,6 +1,6 @@ -# CompositionExclusions-11.0.0.txt -# Date: 2017-12-06, 00:00:00 GMT [KW, LI] -# ยฉ 2017 Unicodeยฎ, Inc. +# CompositionExclusions-12.1.0.txt +# Date: 2019-03-08, 23:59:00 GMT [KW, LI] +# ยฉ 2019 Unicodeยฎ, Inc. # For terms of use, see http://www.unicode.org/terms_of_use.html # # Unicode Character Database diff --git a/lib/stdlib/uc_spec/GraphemeBreakProperty.txt b/lib/stdlib/uc_spec/GraphemeBreakProperty.txt index 52052e6e33..b75b201f97 100644 --- a/lib/stdlib/uc_spec/GraphemeBreakProperty.txt +++ b/lib/stdlib/uc_spec/GraphemeBreakProperty.txt @@ -1,6 +1,6 @@ -# GraphemeBreakProperty-11.0.0.txt -# Date: 2018-03-16, 20:34:02 GMT -# ยฉ 2018 Unicodeยฎ, Inc. +# GraphemeBreakProperty-12.1.0.txt +# Date: 2019-03-10, 10:53:12 GMT +# ยฉ 2019 Unicodeยฎ, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # @@ -27,10 +27,10 @@ 110CD ; Prepend # Cf KAITHI NUMBER SIGN ABOVE 111C2..111C3 ; Prepend # Lo [2] SHARADA SIGN JIHVAMULIYA..SHARADA SIGN UPADHMANIYA 11A3A ; Prepend # Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA -11A86..11A89 ; Prepend # Lo [4] SOYOMBO CLUSTER-INITIAL LETTER RA..SOYOMBO CLUSTER-INITIAL LETTER SA +11A84..11A89 ; Prepend # Lo [6] SOYOMBO SIGN JIHVAMULIYA..SOYOMBO CLUSTER-INITIAL LETTER SA 11D46 ; Prepend # Lo MASARAM GONDI REPHA -# Total code points: 20 +# Total code points: 22 # ================================================ @@ -61,10 +61,10 @@ 2060..2064 ; Control # Cf [5] WORD JOINER..INVISIBLE PLUS 2065 ; Control # Cn <reserved-2065> 2066..206F ; Control # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES -D800..DFFF ; Control # Cs [2048] <surrogate-D800>..<surrogate-DFFF> FEFF ; Control # Cf ZERO WIDTH NO-BREAK SPACE FFF0..FFF8 ; Control # Cn [9] <reserved-FFF0>..<reserved-FFF8> FFF9..FFFB ; Control # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR +13430..13438 ; Control # Cf [9] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END SEGMENT 1BCA0..1BCA3 ; Control # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP 1D173..1D17A ; Control # Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE E0000 ; Control # Cn <reserved-E0000> @@ -73,7 +73,7 @@ E0002..E001F ; Control # Cn [30] <reserved-E0002>..<reserved-E001F> E0080..E00FF ; Control # Cn [128] <reserved-E0080>..<reserved-E00FF> E01F0..E0FFF ; Control # Cn [3600] <reserved-E01F0>..<reserved-E0FFF> -# Total code points: 5925 +# Total code points: 3886 # ================================================ @@ -178,8 +178,7 @@ E01F0..E0FFF ; Control # Cn [3600] <reserved-E01F0>..<reserved-E0FFF> 0E34..0E3A ; Extend # Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU 0E47..0E4E ; Extend # Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN 0EB1 ; Extend # Mn LAO VOWEL SIGN MAI KAN -0EB4..0EB9 ; Extend # Mn [6] LAO VOWEL SIGN I..LAO VOWEL SIGN UU -0EBB..0EBC ; Extend # Mn [2] LAO VOWEL SIGN MAI KON..LAO SEMIVOWEL SIGN LO +0EB4..0EBC ; Extend # Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO 0EC8..0ECD ; Extend # Mn [6] LAO TONE MAI EK..LAO NIGGAHITA 0F18..0F19 ; Extend # Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS 0F35 ; Extend # Mn TIBETAN MARK NGAS BZUNG NYI ZLA @@ -232,6 +231,7 @@ E01F0..E0FFF ; Control # Cn [3600] <reserved-E01F0>..<reserved-E0FFF> 1ABE ; Extend # Me COMBINING PARENTHESES OVERLAY 1B00..1B03 ; Extend # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG 1B34 ; Extend # Mn BALINESE SIGN REREKAN +1B35 ; Extend # Mc BALINESE VOWEL SIGN TEDUNG 1B36..1B3A ; Extend # Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA 1B3C ; Extend # Mn BALINESE VOWEL SIGN LA LENGA 1B42 ; Extend # Mn BALINESE VOWEL SIGN PEPET @@ -283,7 +283,7 @@ A947..A951 ; Extend # Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R A980..A982 ; Extend # Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR A9B3 ; Extend # Mn JAVANESE SIGN CECAK TELU A9B6..A9B9 ; Extend # Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT -A9BC ; Extend # Mn JAVANESE VOWEL SIGN PEPET +A9BC..A9BD ; Extend # Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET A9E5 ; Extend # Mn MYANMAR SIGN SHAN SAW AA29..AA2E ; Extend # Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE AA31..AA32 ; Extend # Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE @@ -368,6 +368,9 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT 11727..1172B ; Extend # Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER 1182F..11837 ; Extend # Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA 11839..1183A ; Extend # Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA +119D4..119D7 ; Extend # Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR +119DA..119DB ; Extend # Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI +119E0 ; Extend # Mn NANDINAGARI SIGN VIRAMA 11A01..11A0A ; Extend # Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK 11A33..11A38 ; Extend # Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA 11A3B..11A3E ; Extend # Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA @@ -394,6 +397,7 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT 11EF3..11EF4 ; Extend # Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U 16AF0..16AF4 ; Extend # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE 16B30..16B36 ; Extend # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM +16F4F ; Extend # Mn MIAO SIGN CONSONANT MODIFIER BAR 16F8F..16F92 ; Extend # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW 1BC9D..1BC9E ; Extend # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK 1D165 ; Extend # Mc MUSICAL SYMBOL COMBINING STEM @@ -414,13 +418,15 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT 1E01B..1E021 ; Extend # Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI 1E023..1E024 ; Extend # Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS 1E026..1E02A ; Extend # Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA +1E130..1E136 ; Extend # Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D +1E2EC..1E2EF ; Extend # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI 1E8D0..1E8D6 ; Extend # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS 1E944..1E94A ; Extend # Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA 1F3FB..1F3FF ; Extend # Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 E0020..E007F ; Extend # Cf [96] TAG SPACE..CANCEL TAG E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 -# Total code points: 1948 +# Total code points: 1970 # ================================================ @@ -489,7 +495,6 @@ E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 1A57 ; SpacingMark # Mc TAI THAM CONSONANT SIGN LA TANG LAI 1A6D..1A72 ; SpacingMark # Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI 1B04 ; SpacingMark # Mc BALINESE SIGN BISAH -1B35 ; SpacingMark # Mc BALINESE VOWEL SIGN TEDUNG 1B3B ; SpacingMark # Mc BALINESE VOWEL SIGN RA REPA TEDUNG 1B3D..1B41 ; SpacingMark # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG 1B43..1B44 ; SpacingMark # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG @@ -504,7 +509,6 @@ E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 1C24..1C2B ; SpacingMark # Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU 1C34..1C35 ; SpacingMark # Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG 1CE1 ; SpacingMark # Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA -1CF2..1CF3 ; SpacingMark # Mc [2] VEDIC SIGN ARDHAVISARGA..VEDIC SIGN ROTATED ARDHAVISARGA 1CF7 ; SpacingMark # Mc VEDIC SIGN ATIKRAMA A823..A824 ; SpacingMark # Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I A827 ; SpacingMark # Mc SYLOTI NAGRI VOWEL SIGN OO @@ -514,7 +518,7 @@ A952..A953 ; SpacingMark # Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA A983 ; SpacingMark # Mc JAVANESE SIGN WIGNYAN A9B4..A9B5 ; SpacingMark # Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG A9BA..A9BB ; SpacingMark # Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE -A9BD..A9C0 ; SpacingMark # Mc [4] JAVANESE CONSONANT SIGN KERET..JAVANESE PANGKON +A9BE..A9C0 ; SpacingMark # Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON AA2F..AA30 ; SpacingMark # Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI AA33..AA34 ; SpacingMark # Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA AA4D ; SpacingMark # Mc CHAM CONSONANT SIGN FINAL H @@ -566,6 +570,9 @@ ABEC ; SpacingMark # Mc MEETEI MAYEK LUM IYEK 11726 ; SpacingMark # Mc AHOM VOWEL SIGN E 1182C..1182E ; SpacingMark # Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II 11838 ; SpacingMark # Mc DOGRA SIGN VISARGA +119D1..119D3 ; SpacingMark # Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II +119DC..119DF ; SpacingMark # Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA +119E4 ; SpacingMark # Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E 11A39 ; SpacingMark # Mc ZANABAZAR SQUARE SIGN VISARGA 11A57..11A58 ; SpacingMark # Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU 11A97 ; SpacingMark # Mc SOYOMBO SIGN VISARGA @@ -578,11 +585,11 @@ ABEC ; SpacingMark # Mc MEETEI MAYEK LUM IYEK 11D93..11D94 ; SpacingMark # Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU 11D96 ; SpacingMark # Mc GUNJALA GONDI SIGN VISARGA 11EF5..11EF6 ; SpacingMark # Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O -16F51..16F7E ; SpacingMark # Mc [46] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN NG +16F51..16F87 ; SpacingMark # Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI 1D166 ; SpacingMark # Mc MUSICAL SYMBOL COMBINING SPRECHGESANG STEM 1D16D ; SpacingMark # Mc MUSICAL SYMBOL COMBINING AUGMENTATION DOT -# Total code points: 362 +# Total code points: 375 # ================================================ diff --git a/lib/stdlib/uc_spec/PropList.txt b/lib/stdlib/uc_spec/PropList.txt index ef86795abe..4394602fea 100644 --- a/lib/stdlib/uc_spec/PropList.txt +++ b/lib/stdlib/uc_spec/PropList.txt @@ -1,6 +1,6 @@ -# PropList-11.0.0.txt -# Date: 2018-03-15, 04:28:35 GMT -# ยฉ 2018 Unicodeยฎ, Inc. +# PropList-12.1.0.txt +# Date: 2019-03-10, 10:53:16 GMT +# ยฉ 2019 Unicodeยฎ, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # @@ -138,7 +138,7 @@ FF63 ; Quotation_Mark # Pe HALFWIDTH RIGHT CORNER BRACKET 0F0D..0F12 ; Terminal_Punctuation # Po [6] TIBETAN MARK SHAD..TIBETAN MARK RGYA GRAM SHAD 104A..104B ; Terminal_Punctuation # Po [2] MYANMAR SIGN LITTLE SECTION..MYANMAR SIGN SECTION 1361..1368 ; Terminal_Punctuation # Po [8] ETHIOPIC WORDSPACE..ETHIOPIC PARAGRAPH SEPARATOR -166D..166E ; Terminal_Punctuation # Po [2] CANADIAN SYLLABICS CHI SIGN..CANADIAN SYLLABICS FULL STOP +166E ; Terminal_Punctuation # Po CANADIAN SYLLABICS FULL STOP 16EB..16ED ; Terminal_Punctuation # Po [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION 1735..1736 ; Terminal_Punctuation # Po [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION 17D4..17D6 ; Terminal_Punctuation # Po [3] KHMER SIGN KHAN..KHMER SIGN CAMNUC PII KUUH @@ -157,7 +157,7 @@ FF63 ; Quotation_Mark # Pe HALFWIDTH RIGHT CORNER BRACKET 2E3C ; Terminal_Punctuation # Po STENOGRAPHIC FULL STOP 2E41 ; Terminal_Punctuation # Po REVERSED COMMA 2E4C ; Terminal_Punctuation # Po MEDIEVAL COMMA -2E4E ; Terminal_Punctuation # Po PUNCTUS ELEVATUS MARK +2E4E..2E4F ; Terminal_Punctuation # Po [2] PUNCTUS ELEVATUS MARK..CORNISH VERSE DIVIDER 3001..3002 ; Terminal_Punctuation # Po [2] IDEOGRAPHIC COMMA..IDEOGRAPHIC FULL STOP A4FE..A4FF ; Terminal_Punctuation # Po [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP A60D..A60F ; Terminal_Punctuation # Po [3] VAI COMMA..VAI QUESTION MARK @@ -553,15 +553,17 @@ FF41..FF46 ; Hex_Digit # L& [6] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH L 1056..1057 ; Other_Alphabetic # Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR 1058..1059 ; Other_Alphabetic # Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL 105E..1060 ; Other_Alphabetic # Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA -1062 ; Other_Alphabetic # Mc MYANMAR VOWEL SIGN SGAW KAREN EU -1067..1068 ; Other_Alphabetic # Mc [2] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR VOWEL SIGN WESTERN PWO KAREN UE +1062..1064 ; Other_Alphabetic # Mc [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO +1067..106D ; Other_Alphabetic # Mc [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5 1071..1074 ; Other_Alphabetic # Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE 1082 ; Other_Alphabetic # Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA 1083..1084 ; Other_Alphabetic # Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E 1085..1086 ; Other_Alphabetic # Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y -109C ; Other_Alphabetic # Mc MYANMAR VOWEL SIGN AITON A +1087..108C ; Other_Alphabetic # Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3 +108D ; Other_Alphabetic # Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE +108F ; Other_Alphabetic # Mc MYANMAR SIGN RUMAI PALAUNG TONE-5 +109A..109C ; Other_Alphabetic # Mc [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A 109D ; Other_Alphabetic # Mn MYANMAR VOWEL SIGN AITON AI -135F ; Other_Alphabetic # Mn ETHIOPIC COMBINING GEMINATION MARK 1712..1713 ; Other_Alphabetic # Mn [2] TAGALOG VOWEL SIGN I..TAGALOG VOWEL SIGN U 1732..1733 ; Other_Alphabetic # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U 1752..1753 ; Other_Alphabetic # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U @@ -618,18 +620,21 @@ FF41..FF46 ; Hex_Digit # L& [6] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH L 1C24..1C2B ; Other_Alphabetic # Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU 1C2C..1C33 ; Other_Alphabetic # Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T 1C34..1C35 ; Other_Alphabetic # Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG -1CF2..1CF3 ; Other_Alphabetic # Mc [2] VEDIC SIGN ARDHAVISARGA..VEDIC SIGN ROTATED ARDHAVISARGA +1C36 ; Other_Alphabetic # Mn LEPCHA SIGN RAN 1DE7..1DF4 ; Other_Alphabetic # Mn [14] COMBINING LATIN SMALL LETTER ALPHA..COMBINING LATIN SMALL LETTER U WITH DIAERESIS 24B6..24E9 ; Other_Alphabetic # So [52] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN SMALL LETTER Z 2DE0..2DFF ; Other_Alphabetic # Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS A674..A67B ; Other_Alphabetic # Mn [8] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC LETTER OMEGA A69E..A69F ; Other_Alphabetic # Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E +A802 ; Other_Alphabetic # Mn SYLOTI NAGRI SIGN DVISVARA +A80B ; Other_Alphabetic # Mn SYLOTI NAGRI SIGN ANUSVARA A823..A824 ; Other_Alphabetic # Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I A825..A826 ; Other_Alphabetic # Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E A827 ; Other_Alphabetic # Mc SYLOTI NAGRI VOWEL SIGN OO A880..A881 ; Other_Alphabetic # Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA A8B4..A8C3 ; Other_Alphabetic # Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU A8C5 ; Other_Alphabetic # Mn SAURASHTRA SIGN CANDRABINDU +A8FF ; Other_Alphabetic # Mn DEVANAGARI VOWEL SIGN AY A926..A92A ; Other_Alphabetic # Mn [5] KAYAH LI VOWEL UE..KAYAH LI VOWEL O A947..A951 ; Other_Alphabetic # Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R A952 ; Other_Alphabetic # Mc REJANG CONSONANT SIGN H @@ -638,8 +643,9 @@ A983 ; Other_Alphabetic # Mc JAVANESE SIGN WIGNYAN A9B4..A9B5 ; Other_Alphabetic # Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG A9B6..A9B9 ; Other_Alphabetic # Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT A9BA..A9BB ; Other_Alphabetic # Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE -A9BC ; Other_Alphabetic # Mn JAVANESE VOWEL SIGN PEPET -A9BD..A9BF ; Other_Alphabetic # Mc [3] JAVANESE CONSONANT SIGN KERET..JAVANESE CONSONANT SIGN CAKRA +A9BC..A9BD ; Other_Alphabetic # Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET +A9BE..A9BF ; Other_Alphabetic # Mc [2] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE CONSONANT SIGN CAKRA +A9E5 ; Other_Alphabetic # Mn MYANMAR SIGN SHAN SAW AA29..AA2E ; Other_Alphabetic # Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE AA2F..AA30 ; Other_Alphabetic # Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI AA31..AA32 ; Other_Alphabetic # Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE @@ -648,6 +654,9 @@ AA35..AA36 ; Other_Alphabetic # Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONA AA43 ; Other_Alphabetic # Mn CHAM CONSONANT SIGN FINAL NG AA4C ; Other_Alphabetic # Mn CHAM CONSONANT SIGN FINAL M AA4D ; Other_Alphabetic # Mc CHAM CONSONANT SIGN FINAL H +AA7B ; Other_Alphabetic # Mc MYANMAR SIGN PAO KAREN TONE +AA7C ; Other_Alphabetic # Mn MYANMAR SIGN TAI LAING TONE-2 +AA7D ; Other_Alphabetic # Mc MYANMAR SIGN TAI LAING TONE-5 AAB0 ; Other_Alphabetic # Mn TAI VIET MAI KANG AAB2..AAB4 ; Other_Alphabetic # Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U AAB7..AAB8 ; Other_Alphabetic # Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA @@ -740,6 +749,11 @@ FB1E ; Other_Alphabetic # Mn HEBREW POINT JUDEO-SPANISH VARIKA 1182C..1182E ; Other_Alphabetic # Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II 1182F..11837 ; Other_Alphabetic # Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA 11838 ; Other_Alphabetic # Mc DOGRA SIGN VISARGA +119D1..119D3 ; Other_Alphabetic # Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II +119D4..119D7 ; Other_Alphabetic # Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR +119DA..119DB ; Other_Alphabetic # Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI +119DC..119DF ; Other_Alphabetic # Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA +119E4 ; Other_Alphabetic # Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E 11A01..11A0A ; Other_Alphabetic # Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK 11A35..11A38 ; Other_Alphabetic # Mn [4] ZANABAZAR SQUARE SIGN CANDRABINDU..ZANABAZAR SQUARE SIGN ANUSVARA 11A39 ; Other_Alphabetic # Mc ZANABAZAR SQUARE SIGN VISARGA @@ -773,8 +787,9 @@ FB1E ; Other_Alphabetic # Mn HEBREW POINT JUDEO-SPANISH VARIKA 11D96 ; Other_Alphabetic # Mc GUNJALA GONDI SIGN VISARGA 11EF3..11EF4 ; Other_Alphabetic # Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U 11EF5..11EF6 ; Other_Alphabetic # Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O -16B30..16B36 ; Other_Alphabetic # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM -16F51..16F7E ; Other_Alphabetic # Mc [46] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN NG +16F4F ; Other_Alphabetic # Mn MIAO SIGN CONSONANT MODIFIER BAR +16F51..16F87 ; Other_Alphabetic # Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI +16F8F..16F92 ; Other_Alphabetic # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW 1BC9E ; Other_Alphabetic # Mn DUPLOYAN DOUBLE MARK 1E000..1E006 ; Other_Alphabetic # Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE 1E008..1E018 ; Other_Alphabetic # Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU @@ -786,7 +801,7 @@ FB1E ; Other_Alphabetic # Mn HEBREW POINT JUDEO-SPANISH VARIKA 1F150..1F169 ; Other_Alphabetic # So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z 1F170..1F189 ; Other_Alphabetic # So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z -# Total code points: 1334 +# Total code points: 1377 # ================================================ @@ -798,7 +813,7 @@ FB1E ; Other_Alphabetic # Mn HEBREW POINT JUDEO-SPANISH VARIKA 4E00..9FEF ; Ideographic # Lo [20976] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FEF F900..FA6D ; Ideographic # Lo [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D FA70..FAD9 ; Ideographic # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 -17000..187F1 ; Ideographic # Lo [6130] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F1 +17000..187F7 ; Ideographic # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18AF2 ; Ideographic # Lo [755] TANGUT COMPONENT-001..TANGUT COMPONENT-755 1B170..1B2FB ; Ideographic # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB 20000..2A6D6 ; Ideographic # Lo [42711] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6D6 @@ -808,7 +823,7 @@ FA70..FAD9 ; Ideographic # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COM 2CEB0..2EBE0 ; Ideographic # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0 2F800..2FA1D ; Ideographic # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D -# Total code points: 96184 +# Total code points: 96190 # ================================================ @@ -876,6 +891,7 @@ FA70..FAD9 ; Ideographic # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COM 0DCA ; Diacritic # Mn SINHALA SIGN AL-LAKUNA 0E47..0E4C ; Diacritic # Mn [6] THAI CHARACTER MAITAIKHU..THAI CHARACTER THANTHAKHAT 0E4E ; Diacritic # Mn THAI CHARACTER YAMAKKAN +0EBA ; Diacritic # Mn LAO SIGN PALI VIRAMA 0EC8..0ECC ; Diacritic # Mn [5] LAO TONE MAI EK..LAO CANCELLATION MARK 0F18..0F19 ; Diacritic # Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS 0F35 ; Diacritic # Mn TIBETAN MARK NGAS BZUNG NYI ZLA @@ -887,10 +903,13 @@ FA70..FAD9 ; Ideographic # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COM 0FC6 ; Diacritic # Mn TIBETAN SYMBOL PADMA GDAN 1037 ; Diacritic # Mn MYANMAR SIGN DOT BELOW 1039..103A ; Diacritic # Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT +1063..1064 ; Diacritic # Mc [2] MYANMAR TONE MARK SGAW KAREN HATHI..MYANMAR TONE MARK SGAW KAREN KE PHO +1069..106D ; Diacritic # Mc [5] MYANMAR SIGN WESTERN PWO KAREN TONE-1..MYANMAR SIGN WESTERN PWO KAREN TONE-5 1087..108C ; Diacritic # Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3 108D ; Diacritic # Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE 108F ; Diacritic # Mc MYANMAR SIGN RUMAI PALAUNG TONE-5 109A..109B ; Diacritic # Mc [2] MYANMAR SIGN KHAMTI TONE-1..MYANMAR SIGN KHAMTI TONE-3 +135D..135F ; Diacritic # Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK 17C9..17D3 ; Diacritic # Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT 17DD ; Diacritic # Mn KHMER SIGN ATTHACAN 1939..193B ; Diacritic # Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I @@ -935,9 +954,11 @@ A67C..A67D ; Diacritic # Mn [2] COMBINING CYRILLIC KAVYKA..COMBINING CYRILL A67F ; Diacritic # Lm CYRILLIC PAYEROK A69C..A69D ; Diacritic # Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN A6F0..A6F1 ; Diacritic # Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS +A700..A716 ; Diacritic # Sk [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR A717..A71F ; Diacritic # Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK A720..A721 ; Diacritic # Sk [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE A788 ; Diacritic # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT +A789..A78A ; Diacritic # Sk [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN A7F8..A7F9 ; Diacritic # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE A8C4 ; Diacritic # Mn SAURASHTRA SIGN VIRAMA A8E0..A8F1 ; Diacritic # Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA @@ -992,6 +1013,7 @@ FFE3 ; Diacritic # Sk FULLWIDTH MACRON 116B7 ; Diacritic # Mn TAKRI SIGN NUKTA 1172B ; Diacritic # Mn AHOM SIGN KILLER 11839..1183A ; Diacritic # Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA +119E0 ; Diacritic # Mn NANDINAGARI SIGN VIRAMA 11A34 ; Diacritic # Mn ZANABAZAR SQUARE SIGN VIRAMA 11A47 ; Diacritic # Mn ZANABAZAR SQUARE SUBJOINER 11A99 ; Diacritic # Mn SOYOMBO SUBJOINER @@ -1000,6 +1022,7 @@ FFE3 ; Diacritic # Sk FULLWIDTH MACRON 11D44..11D45 ; Diacritic # Mn [2] MASARAM GONDI SIGN HALANTA..MASARAM GONDI VIRAMA 11D97 ; Diacritic # Mn GUNJALA GONDI VIRAMA 16AF0..16AF4 ; Diacritic # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE +16B30..16B36 ; Diacritic # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM 16F8F..16F92 ; Diacritic # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW 16F93..16F9F ; Diacritic # Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 1D167..1D169 ; Diacritic # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 @@ -1007,11 +1030,13 @@ FFE3 ; Diacritic # Sk FULLWIDTH MACRON 1D17B..1D182 ; Diacritic # Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE 1D185..1D18B ; Diacritic # Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE 1D1AA..1D1AD ; Diacritic # Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO +1E130..1E136 ; Diacritic # Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D +1E2EC..1E2EF ; Diacritic # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI 1E8D0..1E8D6 ; Diacritic # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS 1E944..1E946 ; Diacritic # Mn [3] ADLAM ALIF LENGTHENER..ADLAM GEMINATION MARK 1E948..1E94A ; Diacritic # Mn [3] ADLAM CONSONANT MODIFIER..ADLAM NUKTA -# Total code points: 818 +# Total code points: 873 # ================================================ @@ -1043,9 +1068,11 @@ FF70 ; Extender # Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND 11A98 ; Extender # Mn SOYOMBO GEMINATION MARK 16B42..16B43 ; Extender # Lm [2] PAHAWH HMONG SIGN VOS NRUA..PAHAWH HMONG SIGN IB YAM 16FE0..16FE1 ; Extender # Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK +16FE3 ; Extender # Lm OLD CHINESE ITERATION MARK +1E13C..1E13D ; Extender # Lm [2] NYIAKENG PUACHUE HMONG SIGN XW XW..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER 1E944..1E946 ; Extender # Mn [3] ADLAM ALIF LENGTHENER..ADLAM GEMINATION MARK -# Total code points: 44 +# Total code points: 47 # ================================================ @@ -1119,6 +1146,7 @@ FFFFE..FFFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-FFFFE>..<noncha 0D57 ; Other_Grapheme_Extend # Mc MALAYALAM AU LENGTH MARK 0DCF ; Other_Grapheme_Extend # Mc SINHALA VOWEL SIGN AELA-PILLA 0DDF ; Other_Grapheme_Extend # Mc SINHALA VOWEL SIGN GAYANUKITTA +1B35 ; Other_Grapheme_Extend # Mc BALINESE VOWEL SIGN TEDUNG 200C ; Other_Grapheme_Extend # Cf ZERO WIDTH NON-JOINER 302E..302F ; Other_Grapheme_Extend # Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK FF9E..FF9F ; Other_Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK @@ -1131,7 +1159,7 @@ FF9E..FF9F ; Other_Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND 1D16E..1D172 ; Other_Grapheme_Extend # Mc [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5 E0020..E007F ; Other_Grapheme_Extend # Cf [96] TAG SPACE..CANCEL TAG -# Total code points: 125 +# Total code points: 126 # ================================================ @@ -1547,10 +1575,7 @@ E0100..E01EF ; Variation_Selector # Mn [240] VARIATION SELECTOR-17..VARIATION S 2B74..2B75 ; Pattern_Syntax # Cn [2] <reserved-2B74>..<reserved-2B75> 2B76..2B95 ; Pattern_Syntax # So [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW 2B96..2B97 ; Pattern_Syntax # Cn [2] <reserved-2B96>..<reserved-2B97> -2B98..2BC8 ; Pattern_Syntax # So [49] THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD..BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED -2BC9 ; Pattern_Syntax # Cn <reserved-2BC9> -2BCA..2BFE ; Pattern_Syntax # So [53] TOP HALF BLACK CIRCLE..REVERSED RIGHT ANGLE -2BFF ; Pattern_Syntax # Cn <reserved-2BFF> +2B98..2BFF ; Pattern_Syntax # So [104] THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD..HELLSCHREIBER PAUSE SYMBOL 2E00..2E01 ; Pattern_Syntax # Po [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER 2E02 ; Pattern_Syntax # Pi LEFT SUBSTITUTION BRACKET 2E03 ; Pattern_Syntax # Pf RIGHT SUBSTITUTION BRACKET @@ -1588,8 +1613,8 @@ E0100..E01EF ; Variation_Selector # Mn [240] VARIATION SELECTOR-17..VARIATION S 2E40 ; Pattern_Syntax # Pd DOUBLE HYPHEN 2E41 ; Pattern_Syntax # Po REVERSED COMMA 2E42 ; Pattern_Syntax # Ps DOUBLE LOW-REVERSED-9 QUOTATION MARK -2E43..2E4E ; Pattern_Syntax # Po [12] DASH WITH LEFT UPTURN..PUNCTUS ELEVATUS MARK -2E4F..2E7F ; Pattern_Syntax # Cn [49] <reserved-2E4F>..<reserved-2E7F> +2E43..2E4F ; Pattern_Syntax # Po [13] DASH WITH LEFT UPTURN..CORNISH VERSE DIVIDER +2E50..2E7F ; Pattern_Syntax # Cn [48] <reserved-2E50>..<reserved-2E7F> 3001..3003 ; Pattern_Syntax # Po [3] IDEOGRAPHIC COMMA..DITTO MARK 3008 ; Pattern_Syntax # Ps LEFT ANGLE BRACKET 3009 ; Pattern_Syntax # Pe RIGHT ANGLE BRACKET diff --git a/lib/stdlib/uc_spec/README-UPDATE.txt b/lib/stdlib/uc_spec/README-UPDATE.txt index e1f5c8fcd0..73274e512a 100644 --- a/lib/stdlib/uc_spec/README-UPDATE.txt +++ b/lib/stdlib/uc_spec/README-UPDATE.txt @@ -2,12 +2,10 @@ When updating the unicode version copy the necessary files to this directory. And update the test files in stdlib/test/unicode_util_SUITE_data/* -Unicode 11 was updated from: -https://www.unicode.org/Public/11.0.0/ucd/ -https://www.unicode.org/Public/11.0.0/ucd/auxiliary/ -https://www.unicode.org/Public/emoji/11.0/ +Unicode 12.1 was updated from: +https://www.unicode.org/Public/12.1.0/ucd/ +https://www.unicode.org/Public/12.1.0/ucd/auxiliary/ +https://www.unicode.org/Public/emoji/12.0/ Update the spec_version(..) function in the generator, gen_unicode_mod.escript - - diff --git a/lib/stdlib/uc_spec/SpecialCasing.txt b/lib/stdlib/uc_spec/SpecialCasing.txt index c90d09acb3..1c04aacf97 100644 --- a/lib/stdlib/uc_spec/SpecialCasing.txt +++ b/lib/stdlib/uc_spec/SpecialCasing.txt @@ -1,6 +1,6 @@ -# SpecialCasing-11.0.0.txt -# Date: 2018-02-22, 06:16:47 GMT -# ยฉ 2018 Unicodeยฎ, Inc. +# SpecialCasing-12.1.0.txt +# Date: 2019-03-10, 10:53:28 GMT +# ยฉ 2019 Unicodeยฎ, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # diff --git a/lib/stdlib/uc_spec/UnicodeData.txt b/lib/stdlib/uc_spec/UnicodeData.txt index ec32fafbce..e65aec52f7 100644 --- a/lib/stdlib/uc_spec/UnicodeData.txt +++ b/lib/stdlib/uc_spec/UnicodeData.txt @@ -640,7 +640,7 @@ 027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;; 0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;;01A6;;01A6 0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;; -0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;;; +0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;A7C5;;A7C5 0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9 0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;; 0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;; @@ -2809,6 +2809,7 @@ 0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0C77;TELUGU SIGN SIDDHAM;Po;0;L;;;;;N;;;;; 0C78;TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR;No;0;ON;;;;0;N;;;;; 0C79;TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR;No;0;ON;;;;1;N;;;;; 0C7A;TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR;No;0;ON;;;;2;N;;;;; @@ -3203,14 +3204,24 @@ 0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;; 0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;; 0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;; +0E86;LAO LETTER PALI GHA;Lo;0;L;;;;;N;;;;; 0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;; 0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;; +0E89;LAO LETTER PALI CHA;Lo;0;L;;;;;N;;;;; 0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;; +0E8C;LAO LETTER PALI JHA;Lo;0;L;;;;;N;;;;; 0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;; +0E8E;LAO LETTER PALI NYA;Lo;0;L;;;;;N;;;;; +0E8F;LAO LETTER PALI TTA;Lo;0;L;;;;;N;;;;; +0E90;LAO LETTER PALI TTHA;Lo;0;L;;;;;N;;;;; +0E91;LAO LETTER PALI DDA;Lo;0;L;;;;;N;;;;; +0E92;LAO LETTER PALI DDHA;Lo;0;L;;;;;N;;;;; +0E93;LAO LETTER PALI NNA;Lo;0;L;;;;;N;;;;; 0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;; 0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;; 0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;; 0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;; +0E98;LAO LETTER PALI DHA;Lo;0;L;;;;;N;;;;; 0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;; 0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;; 0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;; @@ -3218,13 +3229,17 @@ 0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;; 0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;; 0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;; +0EA0;LAO LETTER PALI BHA;Lo;0;L;;;;;N;;;;; 0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;; 0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;; 0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;; 0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;; 0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;; +0EA8;LAO LETTER SANSKRIT SHA;Lo;0;L;;;;;N;;;;; +0EA9;LAO LETTER SANSKRIT SSA;Lo;0;L;;;;;N;;;;; 0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;; 0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;; +0EAC;LAO LETTER PALI LLA;Lo;0;L;;;;;N;;;;; 0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;; 0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;; 0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;; @@ -3238,6 +3253,7 @@ 0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;; 0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;; 0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;; +0EBA;LAO SIGN PALI VIRAMA;Mn;9;NSM;;;;;N;;;;; 0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;; 0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;; 0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;; @@ -5079,7 +5095,7 @@ 166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;; 166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;; 166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;; -166D;CANADIAN SYLLABICS CHI SIGN;Po;0;L;;;;;N;;;;; +166D;CANADIAN SYLLABICS CHI SIGN;So;0;L;;;;;N;;;;; 166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;; 166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;; 1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;; @@ -6488,14 +6504,15 @@ 1CEF;VEDIC SIGN LONG ANUSVARA;Lo;0;L;;;;;N;;;;; 1CF0;VEDIC SIGN RTHANG LONG ANUSVARA;Lo;0;L;;;;;N;;;;; 1CF1;VEDIC SIGN ANUSVARA UBHAYATO MUKHA;Lo;0;L;;;;;N;;;;; -1CF2;VEDIC SIGN ARDHAVISARGA;Mc;0;L;;;;;N;;;;; -1CF3;VEDIC SIGN ROTATED ARDHAVISARGA;Mc;0;L;;;;;N;;;;; +1CF2;VEDIC SIGN ARDHAVISARGA;Lo;0;L;;;;;N;;;;; +1CF3;VEDIC SIGN ROTATED ARDHAVISARGA;Lo;0;L;;;;;N;;;;; 1CF4;VEDIC TONE CANDRA ABOVE;Mn;230;NSM;;;;;N;;;;; 1CF5;VEDIC SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; 1CF6;VEDIC SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;; 1CF7;VEDIC SIGN ATIKRAMA;Mc;0;L;;;;;N;;;;; 1CF8;VEDIC TONE RING ABOVE;Mn;230;NSM;;;;;N;;;;; 1CF9;VEDIC TONE DOUBLE RING ABOVE;Mn;230;NSM;;;;;N;;;;; +1CFA;VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA;Lo;0;L;;;;;N;;;;; 1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;; 1D01;LATIN LETTER SMALL CAPITAL AE;Ll;0;L;;;;;N;;;;; 1D02;LATIN SMALL LETTER TURNED AE;Ll;0;L;;;;;N;;;;; @@ -6638,7 +6655,7 @@ 1D8B;LATIN SMALL LETTER ESH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; 1D8C;LATIN SMALL LETTER V WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; 1D8D;LATIN SMALL LETTER X WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; -1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;A7C6;;A7C6 1D8F;LATIN SMALL LETTER A WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; 1D90;LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; 1D91;LATIN SMALL LETTER D WITH HOOK AND TAIL;Ll;0;L;;;;;N;;;;; @@ -10165,6 +10182,7 @@ 2BC6;BLACK MEDIUM DOWN-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;; 2BC7;BLACK MEDIUM LEFT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;; 2BC8;BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;; +2BC9;NEPTUNE FORM TWO;So;0;ON;;;;;N;;;;; 2BCA;TOP HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; 2BCB;BOTTOM HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; 2BCC;LIGHT FOUR POINTED BLACK CUSP;So;0;ON;;;;;N;;;;; @@ -10218,6 +10236,7 @@ 2BFC;DOUBLED SYMBOL;So;0;ON;;;;;N;;;;; 2BFD;PASSED SYMBOL;So;0;ON;;;;;N;;;;; 2BFE;REVERSED RIGHT ANGLE;So;0;ON;;;;;Y;;;;; +2BFF;HELLSCHREIBER PAUSE SYMBOL;So;0;ON;;;;;N;;;;; 2C00;GLAGOLITIC CAPITAL LETTER AZU;Lu;0;L;;;;;N;;;;2C30; 2C01;GLAGOLITIC CAPITAL LETTER BUKY;Lu;0;L;;;;;N;;;;2C31; 2C02;GLAGOLITIC CAPITAL LETTER VEDE;Lu;0;L;;;;;N;;;;2C32; @@ -10756,6 +10775,7 @@ 2E4C;MEDIEVAL COMMA;Po;0;ON;;;;;N;;;;; 2E4D;PARAGRAPHUS MARK;Po;0;ON;;;;;N;;;;; 2E4E;PUNCTUS ELEVATUS MARK;Po;0;ON;;;;;N;;;;; +2E4F;CORNISH VERSE DIVIDER;Po;0;ON;;;;;N;;;;; 2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;; 2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;; 2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;; @@ -11836,6 +11856,7 @@ 32FC;CIRCLED KATAKANA WI;So;0;L;<circle> 30F0;;;;N;;;;; 32FD;CIRCLED KATAKANA WE;So;0;L;<circle> 30F1;;;;N;;;;; 32FE;CIRCLED KATAKANA WO;So;0;L;<circle> 30F2;;;;N;;;;; +32FF;SQUARE ERA NAME REIWA;So;0;L;<square> 4EE4 548C;;;;N;;;;; 3300;SQUARE APAATO;So;0;L;<square> 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;; 3301;SQUARE ARUHUA;So;0;L;<square> 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;; 3302;SQUARE ANPEA;So;0;L;<square> 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;; @@ -14060,7 +14081,7 @@ A790;LATIN CAPITAL LETTER N WITH DESCENDER;Lu;0;L;;;;;N;;;;A791; A791;LATIN SMALL LETTER N WITH DESCENDER;Ll;0;L;;;;;N;;;A790;;A790 A792;LATIN CAPITAL LETTER C WITH BAR;Lu;0;L;;;;;N;;;;A793; A793;LATIN SMALL LETTER C WITH BAR;Ll;0;L;;;;;N;;;A792;;A792 -A794;LATIN SMALL LETTER C WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +A794;LATIN SMALL LETTER C WITH PALATAL HOOK;Ll;0;L;;;;;N;;;A7C4;;A7C4 A795;LATIN SMALL LETTER H WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; A796;LATIN CAPITAL LETTER B WITH FLOURISH;Lu;0;L;;;;;N;;;;A797; A797;LATIN SMALL LETTER B WITH FLOURISH;Ll;0;L;;;;;N;;;A796;;A796 @@ -14098,6 +14119,17 @@ A7B6;LATIN CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;A7B7; A7B7;LATIN SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;A7B6;;A7B6 A7B8;LATIN CAPITAL LETTER U WITH STROKE;Lu;0;L;;;;;N;;;;A7B9; A7B9;LATIN SMALL LETTER U WITH STROKE;Ll;0;L;;;;;N;;;A7B8;;A7B8 +A7BA;LATIN CAPITAL LETTER GLOTTAL A;Lu;0;L;;;;;N;;;;A7BB; +A7BB;LATIN SMALL LETTER GLOTTAL A;Ll;0;L;;;;;N;;;A7BA;;A7BA +A7BC;LATIN CAPITAL LETTER GLOTTAL I;Lu;0;L;;;;;N;;;;A7BD; +A7BD;LATIN SMALL LETTER GLOTTAL I;Ll;0;L;;;;;N;;;A7BC;;A7BC +A7BE;LATIN CAPITAL LETTER GLOTTAL U;Lu;0;L;;;;;N;;;;A7BF; +A7BF;LATIN SMALL LETTER GLOTTAL U;Ll;0;L;;;;;N;;;A7BE;;A7BE +A7C2;LATIN CAPITAL LETTER ANGLICANA W;Lu;0;L;;;;;N;;;;A7C3; +A7C3;LATIN SMALL LETTER ANGLICANA W;Ll;0;L;;;;;N;;;A7C2;;A7C2 +A7C4;LATIN CAPITAL LETTER C WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;A794; +A7C5;LATIN CAPITAL LETTER S WITH HOOK;Lu;0;L;;;;;N;;;;0282; +A7C6;LATIN CAPITAL LETTER Z WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;1D8E; A7F7;LATIN EPIGRAPHIC LETTER SIDEWAYS I;Lo;0;L;;;;;N;;;;; A7F8;MODIFIER LETTER CAPITAL H WITH STROKE;Lm;0;L;<super> 0126;;;;N;;;;; A7F9;MODIFIER LETTER SMALL LIGATURE OE;Lm;0;L;<super> 0153;;;;N;;;;; @@ -14506,7 +14538,7 @@ A9B9;JAVANESE VOWEL SIGN SUKU MENDUT;Mn;0;NSM;;;;;N;;;;; A9BA;JAVANESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;; A9BB;JAVANESE VOWEL SIGN DIRGA MURE;Mc;0;L;;;;;N;;;;; A9BC;JAVANESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;; -A9BD;JAVANESE CONSONANT SIGN KERET;Mc;0;L;;;;;N;;;;; +A9BD;JAVANESE CONSONANT SIGN KERET;Mn;0;NSM;;;;;N;;;;; A9BE;JAVANESE CONSONANT SIGN PENGKAL;Mc;0;L;;;;;N;;;;; A9BF;JAVANESE CONSONANT SIGN CAKRA;Mc;0;L;;;;;N;;;;; A9C0;JAVANESE PANGKON;Mc;9;L;;;;;N;;;;; @@ -14863,6 +14895,8 @@ AB62;LATIN SMALL LETTER OPEN OE;Ll;0;L;;;;;N;;;;; AB63;LATIN SMALL LETTER UO;Ll;0;L;;;;;N;;;;; AB64;LATIN SMALL LETTER INVERTED ALPHA;Ll;0;L;;;;;N;;;;; AB65;GREEK LETTER SMALL CAPITAL OMEGA;Ll;0;L;;;;;N;;;;; +AB66;LATIN SMALL LETTER DZ DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +AB67;LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; AB70;CHEROKEE SMALL LETTER A;Ll;0;L;;;;;N;;;13A0;;13A0 AB71;CHEROKEE SMALL LETTER E;Ll;0;L;;;;;N;;;13A1;;13A1 AB72;CHEROKEE SMALL LETTER I;Ll;0;L;;;;;N;;;13A2;;13A2 @@ -19105,6 +19139,29 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10F57;SOGDIAN PUNCTUATION CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;; 10F58;SOGDIAN PUNCTUATION TWO CIRCLES WITH DOTS;Po;0;AL;;;;;N;;;;; 10F59;SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;; +10FE0;ELYMAIC LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10FE1;ELYMAIC LETTER BETH;Lo;0;R;;;;;N;;;;; +10FE2;ELYMAIC LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10FE3;ELYMAIC LETTER DALETH;Lo;0;R;;;;;N;;;;; +10FE4;ELYMAIC LETTER HE;Lo;0;R;;;;;N;;;;; +10FE5;ELYMAIC LETTER WAW;Lo;0;R;;;;;N;;;;; +10FE6;ELYMAIC LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10FE7;ELYMAIC LETTER HETH;Lo;0;R;;;;;N;;;;; +10FE8;ELYMAIC LETTER TETH;Lo;0;R;;;;;N;;;;; +10FE9;ELYMAIC LETTER YODH;Lo;0;R;;;;;N;;;;; +10FEA;ELYMAIC LETTER KAPH;Lo;0;R;;;;;N;;;;; +10FEB;ELYMAIC LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10FEC;ELYMAIC LETTER MEM;Lo;0;R;;;;;N;;;;; +10FED;ELYMAIC LETTER NUN;Lo;0;R;;;;;N;;;;; +10FEE;ELYMAIC LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10FEF;ELYMAIC LETTER AYIN;Lo;0;R;;;;;N;;;;; +10FF0;ELYMAIC LETTER PE;Lo;0;R;;;;;N;;;;; +10FF1;ELYMAIC LETTER SADHE;Lo;0;R;;;;;N;;;;; +10FF2;ELYMAIC LETTER QOPH;Lo;0;R;;;;;N;;;;; +10FF3;ELYMAIC LETTER RESH;Lo;0;R;;;;;N;;;;; +10FF4;ELYMAIC LETTER SHIN;Lo;0;R;;;;;N;;;;; +10FF5;ELYMAIC LETTER TAW;Lo;0;R;;;;;N;;;;; +10FF6;ELYMAIC LIGATURE ZAYIN-YODH;Lo;0;R;;;;;N;;;;; 11000;BRAHMI SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;; 11001;BRAHMI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; 11002;BRAHMI SIGN VISARGA;Mc;0;L;;;;;N;;;;; @@ -19887,6 +19944,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1145B;NEWA PLACEHOLDER MARK;Po;0;L;;;;;N;;;;; 1145D;NEWA INSERTION SIGN;Po;0;L;;;;;N;;;;; 1145E;NEWA SANDHI MARK;Mn;230;NSM;;;;;N;;;;; +1145F;NEWA LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;; 11480;TIRHUTA ANJI;Lo;0;L;;;;;N;;;;; 11481;TIRHUTA LETTER A;Lo;0;L;;;;;N;;;;; 11482;TIRHUTA LETTER AA;Lo;0;L;;;;;N;;;;; @@ -20209,6 +20267,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 116B5;TAKRI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; 116B6;TAKRI SIGN VIRAMA;Mc;9;L;;;;;N;;;;; 116B7;TAKRI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +116B8;TAKRI LETTER ARCHAIC KHA;Lo;0;L;;;;;N;;;;; 116C0;TAKRI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 116C1;TAKRI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 116C2;TAKRI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; @@ -20421,6 +20480,71 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 118F1;WARANG CITI NUMBER EIGHTY;No;0;L;;;;80;N;;;;; 118F2;WARANG CITI NUMBER NINETY;No;0;L;;;;90;N;;;;; 118FF;WARANG CITI OM;Lo;0;L;;;;;N;;;;; +119A0;NANDINAGARI LETTER A;Lo;0;L;;;;;N;;;;; +119A1;NANDINAGARI LETTER AA;Lo;0;L;;;;;N;;;;; +119A2;NANDINAGARI LETTER I;Lo;0;L;;;;;N;;;;; +119A3;NANDINAGARI LETTER II;Lo;0;L;;;;;N;;;;; +119A4;NANDINAGARI LETTER U;Lo;0;L;;;;;N;;;;; +119A5;NANDINAGARI LETTER UU;Lo;0;L;;;;;N;;;;; +119A6;NANDINAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +119A7;NANDINAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +119AA;NANDINAGARI LETTER E;Lo;0;L;;;;;N;;;;; +119AB;NANDINAGARI LETTER AI;Lo;0;L;;;;;N;;;;; +119AC;NANDINAGARI LETTER O;Lo;0;L;;;;;N;;;;; +119AD;NANDINAGARI LETTER AU;Lo;0;L;;;;;N;;;;; +119AE;NANDINAGARI LETTER KA;Lo;0;L;;;;;N;;;;; +119AF;NANDINAGARI LETTER KHA;Lo;0;L;;;;;N;;;;; +119B0;NANDINAGARI LETTER GA;Lo;0;L;;;;;N;;;;; +119B1;NANDINAGARI LETTER GHA;Lo;0;L;;;;;N;;;;; +119B2;NANDINAGARI LETTER NGA;Lo;0;L;;;;;N;;;;; +119B3;NANDINAGARI LETTER CA;Lo;0;L;;;;;N;;;;; +119B4;NANDINAGARI LETTER CHA;Lo;0;L;;;;;N;;;;; +119B5;NANDINAGARI LETTER JA;Lo;0;L;;;;;N;;;;; +119B6;NANDINAGARI LETTER JHA;Lo;0;L;;;;;N;;;;; +119B7;NANDINAGARI LETTER NYA;Lo;0;L;;;;;N;;;;; +119B8;NANDINAGARI LETTER TTA;Lo;0;L;;;;;N;;;;; +119B9;NANDINAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;; +119BA;NANDINAGARI LETTER DDA;Lo;0;L;;;;;N;;;;; +119BB;NANDINAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;; +119BC;NANDINAGARI LETTER NNA;Lo;0;L;;;;;N;;;;; +119BD;NANDINAGARI LETTER TA;Lo;0;L;;;;;N;;;;; +119BE;NANDINAGARI LETTER THA;Lo;0;L;;;;;N;;;;; +119BF;NANDINAGARI LETTER DA;Lo;0;L;;;;;N;;;;; +119C0;NANDINAGARI LETTER DHA;Lo;0;L;;;;;N;;;;; +119C1;NANDINAGARI LETTER NA;Lo;0;L;;;;;N;;;;; +119C2;NANDINAGARI LETTER PA;Lo;0;L;;;;;N;;;;; +119C3;NANDINAGARI LETTER PHA;Lo;0;L;;;;;N;;;;; +119C4;NANDINAGARI LETTER BA;Lo;0;L;;;;;N;;;;; +119C5;NANDINAGARI LETTER BHA;Lo;0;L;;;;;N;;;;; +119C6;NANDINAGARI LETTER MA;Lo;0;L;;;;;N;;;;; +119C7;NANDINAGARI LETTER YA;Lo;0;L;;;;;N;;;;; +119C8;NANDINAGARI LETTER RA;Lo;0;L;;;;;N;;;;; +119C9;NANDINAGARI LETTER LA;Lo;0;L;;;;;N;;;;; +119CA;NANDINAGARI LETTER VA;Lo;0;L;;;;;N;;;;; +119CB;NANDINAGARI LETTER SHA;Lo;0;L;;;;;N;;;;; +119CC;NANDINAGARI LETTER SSA;Lo;0;L;;;;;N;;;;; +119CD;NANDINAGARI LETTER SA;Lo;0;L;;;;;N;;;;; +119CE;NANDINAGARI LETTER HA;Lo;0;L;;;;;N;;;;; +119CF;NANDINAGARI LETTER LLA;Lo;0;L;;;;;N;;;;; +119D0;NANDINAGARI LETTER RRA;Lo;0;L;;;;;N;;;;; +119D1;NANDINAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +119D2;NANDINAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +119D3;NANDINAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +119D4;NANDINAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +119D5;NANDINAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +119D6;NANDINAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +119D7;NANDINAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +119DA;NANDINAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +119DB;NANDINAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +119DC;NANDINAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +119DD;NANDINAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +119DE;NANDINAGARI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +119DF;NANDINAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +119E0;NANDINAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +119E1;NANDINAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +119E2;NANDINAGARI SIGN SIDDHAM;Po;0;L;;;;;N;;;;; +119E3;NANDINAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;; +119E4;NANDINAGARI VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;; 11A00;ZANABAZAR SQUARE LETTER A;Lo;0;L;;;;;N;;;;; 11A01;ZANABAZAR SQUARE VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 11A02;ZANABAZAR SQUARE VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;; @@ -20545,6 +20669,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11A81;SOYOMBO LETTER SA;Lo;0;L;;;;;N;;;;; 11A82;SOYOMBO LETTER HA;Lo;0;L;;;;;N;;;;; 11A83;SOYOMBO LETTER KSSA;Lo;0;L;;;;;N;;;;; +11A84;SOYOMBO SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; +11A85;SOYOMBO SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;; 11A86;SOYOMBO CLUSTER-INITIAL LETTER RA;Lo;0;L;;;;;N;;;;; 11A87;SOYOMBO CLUSTER-INITIAL LETTER LA;Lo;0;L;;;;;N;;;;; 11A88;SOYOMBO CLUSTER-INITIAL LETTER SHA;Lo;0;L;;;;;N;;;;; @@ -20959,6 +21085,57 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11EF6;MAKASAR VOWEL SIGN O;Mc;0;L;;;;;N;;;;; 11EF7;MAKASAR PASSIMBANG;Po;0;L;;;;;N;;;;; 11EF8;MAKASAR END OF SECTION;Po;0;L;;;;;N;;;;; +11FC0;TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH;No;0;L;;;;1/320;N;;;;; +11FC1;TAMIL FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;; +11FC2;TAMIL FRACTION ONE EIGHTIETH;No;0;L;;;;1/80;N;;;;; +11FC3;TAMIL FRACTION ONE SIXTY-FOURTH;No;0;L;;;;1/64;N;;;;; +11FC4;TAMIL FRACTION ONE FORTIETH;No;0;L;;;;1/40;N;;;;; +11FC5;TAMIL FRACTION ONE THIRTY-SECOND;No;0;L;;;;1/32;N;;;;; +11FC6;TAMIL FRACTION THREE EIGHTIETHS;No;0;L;;;;3/80;N;;;;; +11FC7;TAMIL FRACTION THREE SIXTY-FOURTHS;No;0;L;;;;3/64;N;;;;; +11FC8;TAMIL FRACTION ONE TWENTIETH;No;0;L;;;;1/20;N;;;;; +11FC9;TAMIL FRACTION ONE SIXTEENTH-1;No;0;L;;;;1/16;N;;;;; +11FCA;TAMIL FRACTION ONE SIXTEENTH-2;No;0;L;;;;1/16;N;;;;; +11FCB;TAMIL FRACTION ONE TENTH;No;0;L;;;;1/10;N;;;;; +11FCC;TAMIL FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;; +11FCD;TAMIL FRACTION THREE TWENTIETHS;No;0;L;;;;3/20;N;;;;; +11FCE;TAMIL FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;; +11FCF;TAMIL FRACTION ONE FIFTH;No;0;L;;;;1/5;N;;;;; +11FD0;TAMIL FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;; +11FD1;TAMIL FRACTION ONE HALF-1;No;0;L;;;;1/2;N;;;;; +11FD2;TAMIL FRACTION ONE HALF-2;No;0;L;;;;1/2;N;;;;; +11FD3;TAMIL FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;; +11FD4;TAMIL FRACTION DOWNSCALING FACTOR KIIZH;No;0;L;;;;1/320;N;;;;; +11FD5;TAMIL SIGN NEL;So;0;ON;;;;;N;;;;; +11FD6;TAMIL SIGN CEVITU;So;0;ON;;;;;N;;;;; +11FD7;TAMIL SIGN AAZHAAKKU;So;0;ON;;;;;N;;;;; +11FD8;TAMIL SIGN UZHAKKU;So;0;ON;;;;;N;;;;; +11FD9;TAMIL SIGN MUUVUZHAKKU;So;0;ON;;;;;N;;;;; +11FDA;TAMIL SIGN KURUNI;So;0;ON;;;;;N;;;;; +11FDB;TAMIL SIGN PATHAKKU;So;0;ON;;;;;N;;;;; +11FDC;TAMIL SIGN MUKKURUNI;So;0;ON;;;;;N;;;;; +11FDD;TAMIL SIGN KAACU;Sc;0;ET;;;;;N;;;;; +11FDE;TAMIL SIGN PANAM;Sc;0;ET;;;;;N;;;;; +11FDF;TAMIL SIGN PON;Sc;0;ET;;;;;N;;;;; +11FE0;TAMIL SIGN VARAAKAN;Sc;0;ET;;;;;N;;;;; +11FE1;TAMIL SIGN PAARAM;So;0;ON;;;;;N;;;;; +11FE2;TAMIL SIGN KUZHI;So;0;ON;;;;;N;;;;; +11FE3;TAMIL SIGN VELI;So;0;ON;;;;;N;;;;; +11FE4;TAMIL WET CULTIVATION SIGN;So;0;ON;;;;;N;;;;; +11FE5;TAMIL DRY CULTIVATION SIGN;So;0;ON;;;;;N;;;;; +11FE6;TAMIL LAND SIGN;So;0;ON;;;;;N;;;;; +11FE7;TAMIL SALT PAN SIGN;So;0;ON;;;;;N;;;;; +11FE8;TAMIL TRADITIONAL CREDIT SIGN;So;0;ON;;;;;N;;;;; +11FE9;TAMIL TRADITIONAL NUMBER SIGN;So;0;ON;;;;;N;;;;; +11FEA;TAMIL CURRENT SIGN;So;0;ON;;;;;N;;;;; +11FEB;TAMIL AND ODD SIGN;So;0;ON;;;;;N;;;;; +11FEC;TAMIL SPENT SIGN;So;0;ON;;;;;N;;;;; +11FED;TAMIL TOTAL SIGN;So;0;ON;;;;;N;;;;; +11FEE;TAMIL IN POSSESSION SIGN;So;0;ON;;;;;N;;;;; +11FEF;TAMIL STARTING FROM SIGN;So;0;ON;;;;;N;;;;; +11FF0;TAMIL SIGN MUTHALIYA;So;0;ON;;;;;N;;;;; +11FF1;TAMIL SIGN VAKAIYARAA;So;0;ON;;;;;N;;;;; +11FFF;TAMIL PUNCTUATION END OF TEXT;Po;0;L;;;;;N;;;;; 12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;; 12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;; 12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;; @@ -23264,6 +23441,15 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;; 1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;; 1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;; +13430;EGYPTIAN HIEROGLYPH VERTICAL JOINER;Cf;0;L;;;;;N;;;;; +13431;EGYPTIAN HIEROGLYPH HORIZONTAL JOINER;Cf;0;L;;;;;N;;;;; +13432;EGYPTIAN HIEROGLYPH INSERT AT TOP START;Cf;0;L;;;;;N;;;;; +13433;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM START;Cf;0;L;;;;;N;;;;; +13434;EGYPTIAN HIEROGLYPH INSERT AT TOP END;Cf;0;L;;;;;N;;;;; +13435;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM END;Cf;0;L;;;;;N;;;;; +13436;EGYPTIAN HIEROGLYPH OVERLAY MIDDLE;Cf;0;L;;;;;N;;;;; +13437;EGYPTIAN HIEROGLYPH BEGIN SEGMENT;Cf;0;L;;;;;N;;;;; +13438;EGYPTIAN HIEROGLYPH END SEGMENT;Cf;0;L;;;;;N;;;;; 14400;ANATOLIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;; 14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;; 14402;ANATOLIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;; @@ -24782,6 +24968,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 16F42;MIAO LETTER WA;Lo;0;L;;;;;N;;;;; 16F43;MIAO LETTER AH;Lo;0;L;;;;;N;;;;; 16F44;MIAO LETTER HHA;Lo;0;L;;;;;N;;;;; +16F45;MIAO LETTER BRI;Lo;0;L;;;;;N;;;;; +16F46;MIAO LETTER SYI;Lo;0;L;;;;;N;;;;; +16F47;MIAO LETTER DZYI;Lo;0;L;;;;;N;;;;; +16F48;MIAO LETTER TE;Lo;0;L;;;;;N;;;;; +16F49;MIAO LETTER TSE;Lo;0;L;;;;;N;;;;; +16F4A;MIAO LETTER RTE;Lo;0;L;;;;;N;;;;; +16F4F;MIAO SIGN CONSONANT MODIFIER BAR;Mn;0;NSM;;;;;N;;;;; 16F50;MIAO LETTER NASALIZATION;Lo;0;L;;;;;N;;;;; 16F51;MIAO SIGN ASPIRATION;Mc;0;L;;;;;N;;;;; 16F52;MIAO SIGN REFORMED VOICING;Mc;0;L;;;;;N;;;;; @@ -24829,6 +25022,15 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 16F7C;MIAO VOWEL SIGN OU;Mc;0;L;;;;;N;;;;; 16F7D;MIAO VOWEL SIGN N;Mc;0;L;;;;;N;;;;; 16F7E;MIAO VOWEL SIGN NG;Mc;0;L;;;;;N;;;;; +16F7F;MIAO VOWEL SIGN UOG;Mc;0;L;;;;;N;;;;; +16F80;MIAO VOWEL SIGN YUI;Mc;0;L;;;;;N;;;;; +16F81;MIAO VOWEL SIGN OG;Mc;0;L;;;;;N;;;;; +16F82;MIAO VOWEL SIGN OER;Mc;0;L;;;;;N;;;;; +16F83;MIAO VOWEL SIGN VW;Mc;0;L;;;;;N;;;;; +16F84;MIAO VOWEL SIGN IG;Mc;0;L;;;;;N;;;;; +16F85;MIAO VOWEL SIGN EA;Mc;0;L;;;;;N;;;;; +16F86;MIAO VOWEL SIGN IONG;Mc;0;L;;;;;N;;;;; +16F87;MIAO VOWEL SIGN UI;Mc;0;L;;;;;N;;;;; 16F8F;MIAO TONE RIGHT;Mn;0;NSM;;;;;N;;;;; 16F90;MIAO TONE TOP RIGHT;Mn;0;NSM;;;;;N;;;;; 16F91;MIAO TONE ABOVE;Mn;0;NSM;;;;;N;;;;; @@ -24848,8 +25050,10 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 16F9F;MIAO LETTER REFORMED TONE-8;Lm;0;L;;;;;N;;;;; 16FE0;TANGUT ITERATION MARK;Lm;0;L;;;;;N;;;;; 16FE1;NUSHU ITERATION MARK;Lm;0;L;;;;;N;;;;; +16FE2;OLD CHINESE HOOK MARK;Po;0;ON;;;;;N;;;;; +16FE3;OLD CHINESE ITERATION MARK;Lm;0;L;;;;;N;;;;; 17000;<Tangut Ideograph, First>;Lo;0;L;;;;;N;;;;; -187F1;<Tangut Ideograph, Last>;Lo;0;L;;;;;N;;;;; +187F7;<Tangut Ideograph, Last>;Lo;0;L;;;;;N;;;;; 18800;TANGUT COMPONENT-001;Lo;0;L;;;;;N;;;;; 18801;TANGUT COMPONENT-002;Lo;0;L;;;;;N;;;;; 18802;TANGUT COMPONENT-003;Lo;0;L;;;;;N;;;;; @@ -25892,6 +26096,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1B11C;HENTAIGANA LETTER WO-7;Lo;0;L;;;;;N;;;;; 1B11D;HENTAIGANA LETTER N-MU-MO-1;Lo;0;L;;;;;N;;;;; 1B11E;HENTAIGANA LETTER N-MU-MO-2;Lo;0;L;;;;;N;;;;; +1B150;HIRAGANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;; +1B151;HIRAGANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;; +1B152;HIRAGANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;; +1B164;KATAKANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;; +1B165;KATAKANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;; +1B166;KATAKANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;; +1B167;KATAKANA LETTER SMALL N;Lo;0;L;;;;;N;;;;; 1B170;NUSHU CHARACTER-1B170;Lo;0;L;;;;;N;;;;; 1B171;NUSHU CHARACTER-1B171;Lo;0;L;;;;;N;;;;; 1B172;NUSHU CHARACTER-1B172;Lo;0;L;;;;;N;;;;; @@ -28820,6 +29031,136 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1E028;COMBINING GLAGOLITIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;; 1E029;COMBINING GLAGOLITIC LETTER IOTATED BIG YUS;Mn;230;NSM;;;;;N;;;;; 1E02A;COMBINING GLAGOLITIC LETTER FITA;Mn;230;NSM;;;;;N;;;;; +1E100;NYIAKENG PUACHUE HMONG LETTER MA;Lo;0;L;;;;;N;;;;; +1E101;NYIAKENG PUACHUE HMONG LETTER TSA;Lo;0;L;;;;;N;;;;; +1E102;NYIAKENG PUACHUE HMONG LETTER NTA;Lo;0;L;;;;;N;;;;; +1E103;NYIAKENG PUACHUE HMONG LETTER TA;Lo;0;L;;;;;N;;;;; +1E104;NYIAKENG PUACHUE HMONG LETTER HA;Lo;0;L;;;;;N;;;;; +1E105;NYIAKENG PUACHUE HMONG LETTER NA;Lo;0;L;;;;;N;;;;; +1E106;NYIAKENG PUACHUE HMONG LETTER XA;Lo;0;L;;;;;N;;;;; +1E107;NYIAKENG PUACHUE HMONG LETTER NKA;Lo;0;L;;;;;N;;;;; +1E108;NYIAKENG PUACHUE HMONG LETTER CA;Lo;0;L;;;;;N;;;;; +1E109;NYIAKENG PUACHUE HMONG LETTER LA;Lo;0;L;;;;;N;;;;; +1E10A;NYIAKENG PUACHUE HMONG LETTER SA;Lo;0;L;;;;;N;;;;; +1E10B;NYIAKENG PUACHUE HMONG LETTER ZA;Lo;0;L;;;;;N;;;;; +1E10C;NYIAKENG PUACHUE HMONG LETTER NCA;Lo;0;L;;;;;N;;;;; +1E10D;NYIAKENG PUACHUE HMONG LETTER NTSA;Lo;0;L;;;;;N;;;;; +1E10E;NYIAKENG PUACHUE HMONG LETTER KA;Lo;0;L;;;;;N;;;;; +1E10F;NYIAKENG PUACHUE HMONG LETTER DA;Lo;0;L;;;;;N;;;;; +1E110;NYIAKENG PUACHUE HMONG LETTER NYA;Lo;0;L;;;;;N;;;;; +1E111;NYIAKENG PUACHUE HMONG LETTER NRA;Lo;0;L;;;;;N;;;;; +1E112;NYIAKENG PUACHUE HMONG LETTER VA;Lo;0;L;;;;;N;;;;; +1E113;NYIAKENG PUACHUE HMONG LETTER NTXA;Lo;0;L;;;;;N;;;;; +1E114;NYIAKENG PUACHUE HMONG LETTER TXA;Lo;0;L;;;;;N;;;;; +1E115;NYIAKENG PUACHUE HMONG LETTER FA;Lo;0;L;;;;;N;;;;; +1E116;NYIAKENG PUACHUE HMONG LETTER RA;Lo;0;L;;;;;N;;;;; +1E117;NYIAKENG PUACHUE HMONG LETTER QA;Lo;0;L;;;;;N;;;;; +1E118;NYIAKENG PUACHUE HMONG LETTER YA;Lo;0;L;;;;;N;;;;; +1E119;NYIAKENG PUACHUE HMONG LETTER NQA;Lo;0;L;;;;;N;;;;; +1E11A;NYIAKENG PUACHUE HMONG LETTER PA;Lo;0;L;;;;;N;;;;; +1E11B;NYIAKENG PUACHUE HMONG LETTER XYA;Lo;0;L;;;;;N;;;;; +1E11C;NYIAKENG PUACHUE HMONG LETTER NPA;Lo;0;L;;;;;N;;;;; +1E11D;NYIAKENG PUACHUE HMONG LETTER DLA;Lo;0;L;;;;;N;;;;; +1E11E;NYIAKENG PUACHUE HMONG LETTER NPLA;Lo;0;L;;;;;N;;;;; +1E11F;NYIAKENG PUACHUE HMONG LETTER HAH;Lo;0;L;;;;;N;;;;; +1E120;NYIAKENG PUACHUE HMONG LETTER MLA;Lo;0;L;;;;;N;;;;; +1E121;NYIAKENG PUACHUE HMONG LETTER PLA;Lo;0;L;;;;;N;;;;; +1E122;NYIAKENG PUACHUE HMONG LETTER GA;Lo;0;L;;;;;N;;;;; +1E123;NYIAKENG PUACHUE HMONG LETTER RRA;Lo;0;L;;;;;N;;;;; +1E124;NYIAKENG PUACHUE HMONG LETTER A;Lo;0;L;;;;;N;;;;; +1E125;NYIAKENG PUACHUE HMONG LETTER AA;Lo;0;L;;;;;N;;;;; +1E126;NYIAKENG PUACHUE HMONG LETTER I;Lo;0;L;;;;;N;;;;; +1E127;NYIAKENG PUACHUE HMONG LETTER U;Lo;0;L;;;;;N;;;;; +1E128;NYIAKENG PUACHUE HMONG LETTER O;Lo;0;L;;;;;N;;;;; +1E129;NYIAKENG PUACHUE HMONG LETTER OO;Lo;0;L;;;;;N;;;;; +1E12A;NYIAKENG PUACHUE HMONG LETTER E;Lo;0;L;;;;;N;;;;; +1E12B;NYIAKENG PUACHUE HMONG LETTER EE;Lo;0;L;;;;;N;;;;; +1E12C;NYIAKENG PUACHUE HMONG LETTER W;Lo;0;L;;;;;N;;;;; +1E130;NYIAKENG PUACHUE HMONG TONE-B;Mn;230;NSM;;;;;N;;;;; +1E131;NYIAKENG PUACHUE HMONG TONE-M;Mn;230;NSM;;;;;N;;;;; +1E132;NYIAKENG PUACHUE HMONG TONE-J;Mn;230;NSM;;;;;N;;;;; +1E133;NYIAKENG PUACHUE HMONG TONE-V;Mn;230;NSM;;;;;N;;;;; +1E134;NYIAKENG PUACHUE HMONG TONE-S;Mn;230;NSM;;;;;N;;;;; +1E135;NYIAKENG PUACHUE HMONG TONE-G;Mn;230;NSM;;;;;N;;;;; +1E136;NYIAKENG PUACHUE HMONG TONE-D;Mn;230;NSM;;;;;N;;;;; +1E137;NYIAKENG PUACHUE HMONG SIGN FOR PERSON;Lm;0;L;;;;;N;;;;; +1E138;NYIAKENG PUACHUE HMONG SIGN FOR THING;Lm;0;L;;;;;N;;;;; +1E139;NYIAKENG PUACHUE HMONG SIGN FOR LOCATION;Lm;0;L;;;;;N;;;;; +1E13A;NYIAKENG PUACHUE HMONG SIGN FOR ANIMAL;Lm;0;L;;;;;N;;;;; +1E13B;NYIAKENG PUACHUE HMONG SIGN FOR INVERTEBRATE;Lm;0;L;;;;;N;;;;; +1E13C;NYIAKENG PUACHUE HMONG SIGN XW XW;Lm;0;L;;;;;N;;;;; +1E13D;NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER;Lm;0;L;;;;;N;;;;; +1E140;NYIAKENG PUACHUE HMONG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1E141;NYIAKENG PUACHUE HMONG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1E142;NYIAKENG PUACHUE HMONG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1E143;NYIAKENG PUACHUE HMONG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1E144;NYIAKENG PUACHUE HMONG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1E145;NYIAKENG PUACHUE HMONG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1E146;NYIAKENG PUACHUE HMONG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1E147;NYIAKENG PUACHUE HMONG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1E148;NYIAKENG PUACHUE HMONG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1E149;NYIAKENG PUACHUE HMONG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1E14E;NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ;Lo;0;L;;;;;N;;;;; +1E14F;NYIAKENG PUACHUE HMONG CIRCLED CA;So;0;L;;;;;N;;;;; +1E2C0;WANCHO LETTER AA;Lo;0;L;;;;;N;;;;; +1E2C1;WANCHO LETTER A;Lo;0;L;;;;;N;;;;; +1E2C2;WANCHO LETTER BA;Lo;0;L;;;;;N;;;;; +1E2C3;WANCHO LETTER CA;Lo;0;L;;;;;N;;;;; +1E2C4;WANCHO LETTER DA;Lo;0;L;;;;;N;;;;; +1E2C5;WANCHO LETTER GA;Lo;0;L;;;;;N;;;;; +1E2C6;WANCHO LETTER YA;Lo;0;L;;;;;N;;;;; +1E2C7;WANCHO LETTER PHA;Lo;0;L;;;;;N;;;;; +1E2C8;WANCHO LETTER LA;Lo;0;L;;;;;N;;;;; +1E2C9;WANCHO LETTER NA;Lo;0;L;;;;;N;;;;; +1E2CA;WANCHO LETTER PA;Lo;0;L;;;;;N;;;;; +1E2CB;WANCHO LETTER TA;Lo;0;L;;;;;N;;;;; +1E2CC;WANCHO LETTER THA;Lo;0;L;;;;;N;;;;; +1E2CD;WANCHO LETTER FA;Lo;0;L;;;;;N;;;;; +1E2CE;WANCHO LETTER SA;Lo;0;L;;;;;N;;;;; +1E2CF;WANCHO LETTER SHA;Lo;0;L;;;;;N;;;;; +1E2D0;WANCHO LETTER JA;Lo;0;L;;;;;N;;;;; +1E2D1;WANCHO LETTER ZA;Lo;0;L;;;;;N;;;;; +1E2D2;WANCHO LETTER WA;Lo;0;L;;;;;N;;;;; +1E2D3;WANCHO LETTER VA;Lo;0;L;;;;;N;;;;; +1E2D4;WANCHO LETTER KA;Lo;0;L;;;;;N;;;;; +1E2D5;WANCHO LETTER O;Lo;0;L;;;;;N;;;;; +1E2D6;WANCHO LETTER AU;Lo;0;L;;;;;N;;;;; +1E2D7;WANCHO LETTER RA;Lo;0;L;;;;;N;;;;; +1E2D8;WANCHO LETTER MA;Lo;0;L;;;;;N;;;;; +1E2D9;WANCHO LETTER KHA;Lo;0;L;;;;;N;;;;; +1E2DA;WANCHO LETTER HA;Lo;0;L;;;;;N;;;;; +1E2DB;WANCHO LETTER E;Lo;0;L;;;;;N;;;;; +1E2DC;WANCHO LETTER I;Lo;0;L;;;;;N;;;;; +1E2DD;WANCHO LETTER NGA;Lo;0;L;;;;;N;;;;; +1E2DE;WANCHO LETTER U;Lo;0;L;;;;;N;;;;; +1E2DF;WANCHO LETTER LLHA;Lo;0;L;;;;;N;;;;; +1E2E0;WANCHO LETTER TSA;Lo;0;L;;;;;N;;;;; +1E2E1;WANCHO LETTER TRA;Lo;0;L;;;;;N;;;;; +1E2E2;WANCHO LETTER ONG;Lo;0;L;;;;;N;;;;; +1E2E3;WANCHO LETTER AANG;Lo;0;L;;;;;N;;;;; +1E2E4;WANCHO LETTER ANG;Lo;0;L;;;;;N;;;;; +1E2E5;WANCHO LETTER ING;Lo;0;L;;;;;N;;;;; +1E2E6;WANCHO LETTER ON;Lo;0;L;;;;;N;;;;; +1E2E7;WANCHO LETTER EN;Lo;0;L;;;;;N;;;;; +1E2E8;WANCHO LETTER AAN;Lo;0;L;;;;;N;;;;; +1E2E9;WANCHO LETTER NYA;Lo;0;L;;;;;N;;;;; +1E2EA;WANCHO LETTER UEN;Lo;0;L;;;;;N;;;;; +1E2EB;WANCHO LETTER YIH;Lo;0;L;;;;;N;;;;; +1E2EC;WANCHO TONE TUP;Mn;230;NSM;;;;;N;;;;; +1E2ED;WANCHO TONE TUPNI;Mn;230;NSM;;;;;N;;;;; +1E2EE;WANCHO TONE KOI;Mn;230;NSM;;;;;N;;;;; +1E2EF;WANCHO TONE KOINI;Mn;230;NSM;;;;;N;;;;; +1E2F0;WANCHO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1E2F1;WANCHO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1E2F2;WANCHO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1E2F3;WANCHO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1E2F4;WANCHO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1E2F5;WANCHO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1E2F6;WANCHO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1E2F7;WANCHO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1E2F8;WANCHO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1E2F9;WANCHO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1E2FF;WANCHO NGUN SIGN;Sc;0;ET;;;;;N;;;;; 1E800;MENDE KIKAKUI SYLLABLE M001 KI;Lo;0;R;;;;;N;;;;; 1E801;MENDE KIKAKUI SYLLABLE M002 KA;Lo;0;R;;;;;N;;;;; 1E802;MENDE KIKAKUI SYLLABLE M003 KU;Lo;0;R;;;;;N;;;;; @@ -29108,6 +29449,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1E948;ADLAM CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;; 1E949;ADLAM GEMINATE CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;; 1E94A;ADLAM NUKTA;Mn;7;NSM;;;;;N;;;;; +1E94B;ADLAM NASALIZATION MARK;Lm;0;R;;;;;N;;;;; 1E950;ADLAM DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;; 1E951;ADLAM DIGIT ONE;Nd;0;R;;1;1;1;N;;;;; 1E952;ADLAM DIGIT TWO;Nd;0;R;;2;2;2;N;;;;; @@ -29188,6 +29530,67 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1ECB2;INDIC SIYAQ NUMBER ALTERNATE TWO;No;0;AL;;;;2;N;;;;; 1ECB3;INDIC SIYAQ NUMBER ALTERNATE TEN THOUSAND;No;0;AL;;;;10000;N;;;;; 1ECB4;INDIC SIYAQ ALTERNATE LAKH MARK;No;0;AL;;;;100000;N;;;;; +1ED01;OTTOMAN SIYAQ NUMBER ONE;No;0;AL;;;;1;N;;;;; +1ED02;OTTOMAN SIYAQ NUMBER TWO;No;0;AL;;;;2;N;;;;; +1ED03;OTTOMAN SIYAQ NUMBER THREE;No;0;AL;;;;3;N;;;;; +1ED04;OTTOMAN SIYAQ NUMBER FOUR;No;0;AL;;;;4;N;;;;; +1ED05;OTTOMAN SIYAQ NUMBER FIVE;No;0;AL;;;;5;N;;;;; +1ED06;OTTOMAN SIYAQ NUMBER SIX;No;0;AL;;;;6;N;;;;; +1ED07;OTTOMAN SIYAQ NUMBER SEVEN;No;0;AL;;;;7;N;;;;; +1ED08;OTTOMAN SIYAQ NUMBER EIGHT;No;0;AL;;;;8;N;;;;; +1ED09;OTTOMAN SIYAQ NUMBER NINE;No;0;AL;;;;9;N;;;;; +1ED0A;OTTOMAN SIYAQ NUMBER TEN;No;0;AL;;;;10;N;;;;; +1ED0B;OTTOMAN SIYAQ NUMBER TWENTY;No;0;AL;;;;20;N;;;;; +1ED0C;OTTOMAN SIYAQ NUMBER THIRTY;No;0;AL;;;;30;N;;;;; +1ED0D;OTTOMAN SIYAQ NUMBER FORTY;No;0;AL;;;;40;N;;;;; +1ED0E;OTTOMAN SIYAQ NUMBER FIFTY;No;0;AL;;;;50;N;;;;; +1ED0F;OTTOMAN SIYAQ NUMBER SIXTY;No;0;AL;;;;60;N;;;;; +1ED10;OTTOMAN SIYAQ NUMBER SEVENTY;No;0;AL;;;;70;N;;;;; +1ED11;OTTOMAN SIYAQ NUMBER EIGHTY;No;0;AL;;;;80;N;;;;; +1ED12;OTTOMAN SIYAQ NUMBER NINETY;No;0;AL;;;;90;N;;;;; +1ED13;OTTOMAN SIYAQ NUMBER ONE HUNDRED;No;0;AL;;;;100;N;;;;; +1ED14;OTTOMAN SIYAQ NUMBER TWO HUNDRED;No;0;AL;;;;200;N;;;;; +1ED15;OTTOMAN SIYAQ NUMBER THREE HUNDRED;No;0;AL;;;;300;N;;;;; +1ED16;OTTOMAN SIYAQ NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;; +1ED17;OTTOMAN SIYAQ NUMBER FIVE HUNDRED;No;0;AL;;;;500;N;;;;; +1ED18;OTTOMAN SIYAQ NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;; +1ED19;OTTOMAN SIYAQ NUMBER SEVEN HUNDRED;No;0;AL;;;;700;N;;;;; +1ED1A;OTTOMAN SIYAQ NUMBER EIGHT HUNDRED;No;0;AL;;;;800;N;;;;; +1ED1B;OTTOMAN SIYAQ NUMBER NINE HUNDRED;No;0;AL;;;;900;N;;;;; +1ED1C;OTTOMAN SIYAQ NUMBER ONE THOUSAND;No;0;AL;;;;1000;N;;;;; +1ED1D;OTTOMAN SIYAQ NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;; +1ED1E;OTTOMAN SIYAQ NUMBER THREE THOUSAND;No;0;AL;;;;3000;N;;;;; +1ED1F;OTTOMAN SIYAQ NUMBER FOUR THOUSAND;No;0;AL;;;;4000;N;;;;; +1ED20;OTTOMAN SIYAQ NUMBER FIVE THOUSAND;No;0;AL;;;;5000;N;;;;; +1ED21;OTTOMAN SIYAQ NUMBER SIX THOUSAND;No;0;AL;;;;6000;N;;;;; +1ED22;OTTOMAN SIYAQ NUMBER SEVEN THOUSAND;No;0;AL;;;;7000;N;;;;; +1ED23;OTTOMAN SIYAQ NUMBER EIGHT THOUSAND;No;0;AL;;;;8000;N;;;;; +1ED24;OTTOMAN SIYAQ NUMBER NINE THOUSAND;No;0;AL;;;;9000;N;;;;; +1ED25;OTTOMAN SIYAQ NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;; +1ED26;OTTOMAN SIYAQ NUMBER TWENTY THOUSAND;No;0;AL;;;;20000;N;;;;; +1ED27;OTTOMAN SIYAQ NUMBER THIRTY THOUSAND;No;0;AL;;;;30000;N;;;;; +1ED28;OTTOMAN SIYAQ NUMBER FORTY THOUSAND;No;0;AL;;;;40000;N;;;;; +1ED29;OTTOMAN SIYAQ NUMBER FIFTY THOUSAND;No;0;AL;;;;50000;N;;;;; +1ED2A;OTTOMAN SIYAQ NUMBER SIXTY THOUSAND;No;0;AL;;;;60000;N;;;;; +1ED2B;OTTOMAN SIYAQ NUMBER SEVENTY THOUSAND;No;0;AL;;;;70000;N;;;;; +1ED2C;OTTOMAN SIYAQ NUMBER EIGHTY THOUSAND;No;0;AL;;;;80000;N;;;;; +1ED2D;OTTOMAN SIYAQ NUMBER NINETY THOUSAND;No;0;AL;;;;90000;N;;;;; +1ED2E;OTTOMAN SIYAQ MARRATAN;So;0;AL;;;;;N;;;;; +1ED2F;OTTOMAN SIYAQ ALTERNATE NUMBER TWO;No;0;AL;;;;2;N;;;;; +1ED30;OTTOMAN SIYAQ ALTERNATE NUMBER THREE;No;0;AL;;;;3;N;;;;; +1ED31;OTTOMAN SIYAQ ALTERNATE NUMBER FOUR;No;0;AL;;;;4;N;;;;; +1ED32;OTTOMAN SIYAQ ALTERNATE NUMBER FIVE;No;0;AL;;;;5;N;;;;; +1ED33;OTTOMAN SIYAQ ALTERNATE NUMBER SIX;No;0;AL;;;;6;N;;;;; +1ED34;OTTOMAN SIYAQ ALTERNATE NUMBER SEVEN;No;0;AL;;;;7;N;;;;; +1ED35;OTTOMAN SIYAQ ALTERNATE NUMBER EIGHT;No;0;AL;;;;8;N;;;;; +1ED36;OTTOMAN SIYAQ ALTERNATE NUMBER NINE;No;0;AL;;;;9;N;;;;; +1ED37;OTTOMAN SIYAQ ALTERNATE NUMBER TEN;No;0;AL;;;;10;N;;;;; +1ED38;OTTOMAN SIYAQ ALTERNATE NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;; +1ED39;OTTOMAN SIYAQ ALTERNATE NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;; +1ED3A;OTTOMAN SIYAQ ALTERNATE NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;; +1ED3B;OTTOMAN SIYAQ ALTERNATE NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;; +1ED3C;OTTOMAN SIYAQ FRACTION ONE HALF;No;0;AL;;;;1/2;N;;;;; +1ED3D;OTTOMAN SIYAQ FRACTION ONE SIXTH;No;0;AL;;;;1/6;N;;;;; 1EE00;ARABIC MATHEMATICAL ALEF;Lo;0;AL;<font> 0627;;;;N;;;;; 1EE01;ARABIC MATHEMATICAL BEH;Lo;0;AL;<font> 0628;;;;N;;;;; 1EE02;ARABIC MATHEMATICAL JEEM;Lo;0;AL;<font> 062C;;;;N;;;;; @@ -29662,6 +30065,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F169;NEGATIVE CIRCLED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;; 1F16A;RAISED MC SIGN;So;0;ON;<super> 004D 0043;;;;N;;;;; 1F16B;RAISED MD SIGN;So;0;ON;<super> 004D 0044;;;;N;;;;; +1F16C;RAISED MR SIGN;So;0;ON;<super> 004D 0052;;;;N;;;;; 1F170;NEGATIVE SQUARED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;; 1F171;NEGATIVE SQUARED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;; 1F172;NEGATIVE SQUARED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;; @@ -30794,6 +31198,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F6D2;SHOPPING TROLLEY;So;0;ON;;;;;N;;;;; 1F6D3;STUPA;So;0;ON;;;;;N;;;;; 1F6D4;PAGODA;So;0;ON;;;;;N;;;;; +1F6D5;HINDU TEMPLE;So;0;ON;;;;;N;;;;; 1F6E0;HAMMER AND WRENCH;So;0;ON;;;;;N;;;;; 1F6E1;SHIELD;So;0;ON;;;;;N;;;;; 1F6E2;OIL DRUM;So;0;ON;;;;;N;;;;; @@ -30817,6 +31222,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F6F7;SLED;So;0;ON;;;;;N;;;;; 1F6F8;FLYING SAUCER;So;0;ON;;;;;N;;;;; 1F6F9;SKATEBOARD;So;0;ON;;;;;N;;;;; +1F6FA;AUTO RICKSHAW;So;0;ON;;;;;N;;;;; 1F700;ALCHEMICAL SYMBOL FOR QUINTESSENCE;So;0;ON;;;;;N;;;;; 1F701;ALCHEMICAL SYMBOL FOR AIR;So;0;ON;;;;;N;;;;; 1F702;ALCHEMICAL SYMBOL FOR FIRE;So;0;ON;;;;;N;;;;; @@ -31022,6 +31428,18 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F7D6;NEGATIVE CIRCLED TRIANGLE;So;0;ON;;;;;N;;;;; 1F7D7;CIRCLED SQUARE;So;0;ON;;;;;N;;;;; 1F7D8;NEGATIVE CIRCLED SQUARE;So;0;ON;;;;;N;;;;; +1F7E0;LARGE ORANGE CIRCLE;So;0;ON;;;;;N;;;;; +1F7E1;LARGE YELLOW CIRCLE;So;0;ON;;;;;N;;;;; +1F7E2;LARGE GREEN CIRCLE;So;0;ON;;;;;N;;;;; +1F7E3;LARGE PURPLE CIRCLE;So;0;ON;;;;;N;;;;; +1F7E4;LARGE BROWN CIRCLE;So;0;ON;;;;;N;;;;; +1F7E5;LARGE RED SQUARE;So;0;ON;;;;;N;;;;; +1F7E6;LARGE BLUE SQUARE;So;0;ON;;;;;N;;;;; +1F7E7;LARGE ORANGE SQUARE;So;0;ON;;;;;N;;;;; +1F7E8;LARGE YELLOW SQUARE;So;0;ON;;;;;N;;;;; +1F7E9;LARGE GREEN SQUARE;So;0;ON;;;;;N;;;;; +1F7EA;LARGE PURPLE SQUARE;So;0;ON;;;;;N;;;;; +1F7EB;LARGE BROWN SQUARE;So;0;ON;;;;;N;;;;; 1F800;LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; 1F801;UPWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; 1F802;RIGHTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; @@ -31182,6 +31600,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F909;DOWNWARD FACING NOTCHED HOOK;So;0;ON;;;;;N;;;;; 1F90A;DOWNWARD FACING HOOK WITH DOT;So;0;ON;;;;;N;;;;; 1F90B;DOWNWARD FACING NOTCHED HOOK WITH DOT;So;0;ON;;;;;N;;;;; +1F90D;WHITE HEART;So;0;ON;;;;;N;;;;; +1F90E;BROWN HEART;So;0;ON;;;;;N;;;;; +1F90F;PINCHING HAND;So;0;ON;;;;;N;;;;; 1F910;ZIPPER-MOUTH FACE;So;0;ON;;;;;N;;;;; 1F911;MONEY-MOUTH FACE;So;0;ON;;;;;N;;;;; 1F912;FACE WITH THERMOMETER;So;0;ON;;;;;N;;;;; @@ -31229,6 +31650,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F93C;WRESTLERS;So;0;ON;;;;;N;;;;; 1F93D;WATER POLO;So;0;ON;;;;;N;;;;; 1F93E;HANDBALL;So;0;ON;;;;;N;;;;; +1F93F;DIVING MASK;So;0;ON;;;;;N;;;;; 1F940;WILTED FLOWER;So;0;ON;;;;;N;;;;; 1F941;DRUM WITH DRUMSTICKS;So;0;ON;;;;;N;;;;; 1F942;CLINKING GLASSES;So;0;ON;;;;;N;;;;; @@ -31278,11 +31700,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F96E;MOON CAKE;So;0;ON;;;;;N;;;;; 1F96F;BAGEL;So;0;ON;;;;;N;;;;; 1F970;SMILING FACE WITH SMILING EYES AND THREE HEARTS;So;0;ON;;;;;N;;;;; +1F971;YAWNING FACE;So;0;ON;;;;;N;;;;; 1F973;FACE WITH PARTY HORN AND PARTY HAT;So;0;ON;;;;;N;;;;; 1F974;FACE WITH UNEVEN EYES AND WAVY MOUTH;So;0;ON;;;;;N;;;;; 1F975;OVERHEATED FACE;So;0;ON;;;;;N;;;;; 1F976;FREEZING FACE;So;0;ON;;;;;N;;;;; 1F97A;FACE WITH PLEADING EYES;So;0;ON;;;;;N;;;;; +1F97B;SARI;So;0;ON;;;;;N;;;;; 1F97C;LAB COAT;So;0;ON;;;;;N;;;;; 1F97D;GOGGLES;So;0;ON;;;;;N;;;;; 1F97E;HIKING BOOT;So;0;ON;;;;;N;;;;; @@ -31322,6 +31746,14 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F9A0;MICROBE;So;0;ON;;;;;N;;;;; 1F9A1;BADGER;So;0;ON;;;;;N;;;;; 1F9A2;SWAN;So;0;ON;;;;;N;;;;; +1F9A5;SLOTH;So;0;ON;;;;;N;;;;; +1F9A6;OTTER;So;0;ON;;;;;N;;;;; +1F9A7;ORANGUTAN;So;0;ON;;;;;N;;;;; +1F9A8;SKUNK;So;0;ON;;;;;N;;;;; +1F9A9;FLAMINGO;So;0;ON;;;;;N;;;;; +1F9AA;OYSTER;So;0;ON;;;;;N;;;;; +1F9AE;GUIDE DOG;So;0;ON;;;;;N;;;;; +1F9AF;PROBING CANE;So;0;ON;;;;;N;;;;; 1F9B0;EMOJI COMPONENT RED HAIR;So;0;ON;;;;;N;;;;; 1F9B1;EMOJI COMPONENT CURLY HAIR;So;0;ON;;;;;N;;;;; 1F9B2;EMOJI COMPONENT BALD;So;0;ON;;;;;N;;;;; @@ -31332,9 +31764,26 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F9B7;TOOTH;So;0;ON;;;;;N;;;;; 1F9B8;SUPERHERO;So;0;ON;;;;;N;;;;; 1F9B9;SUPERVILLAIN;So;0;ON;;;;;N;;;;; +1F9BA;SAFETY VEST;So;0;ON;;;;;N;;;;; +1F9BB;EAR WITH HEARING AID;So;0;ON;;;;;N;;;;; +1F9BC;MOTORIZED WHEELCHAIR;So;0;ON;;;;;N;;;;; +1F9BD;MANUAL WHEELCHAIR;So;0;ON;;;;;N;;;;; +1F9BE;MECHANICAL ARM;So;0;ON;;;;;N;;;;; +1F9BF;MECHANICAL LEG;So;0;ON;;;;;N;;;;; 1F9C0;CHEESE WEDGE;So;0;ON;;;;;N;;;;; 1F9C1;CUPCAKE;So;0;ON;;;;;N;;;;; 1F9C2;SALT SHAKER;So;0;ON;;;;;N;;;;; +1F9C3;BEVERAGE BOX;So;0;ON;;;;;N;;;;; +1F9C4;GARLIC;So;0;ON;;;;;N;;;;; +1F9C5;ONION;So;0;ON;;;;;N;;;;; +1F9C6;FALAFEL;So;0;ON;;;;;N;;;;; +1F9C7;WAFFLE;So;0;ON;;;;;N;;;;; +1F9C8;BUTTER;So;0;ON;;;;;N;;;;; +1F9C9;MATE DRINK;So;0;ON;;;;;N;;;;; +1F9CA;ICE CUBE;So;0;ON;;;;;N;;;;; +1F9CD;STANDING PERSON;So;0;ON;;;;;N;;;;; +1F9CE;KNEELING PERSON;So;0;ON;;;;;N;;;;; +1F9CF;DEAF PERSON;So;0;ON;;;;;N;;;;; 1F9D0;FACE WITH MONOCLE;So;0;ON;;;;;N;;;;; 1F9D1;ADULT;So;0;ON;;;;;N;;;;; 1F9D2;CHILD;So;0;ON;;;;;N;;;;; @@ -31383,6 +31832,90 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F9FD;SPONGE;So;0;ON;;;;;N;;;;; 1F9FE;RECEIPT;So;0;ON;;;;;N;;;;; 1F9FF;NAZAR AMULET;So;0;ON;;;;;N;;;;; +1FA00;NEUTRAL CHESS KING;So;0;ON;;;;;N;;;;; +1FA01;NEUTRAL CHESS QUEEN;So;0;ON;;;;;N;;;;; +1FA02;NEUTRAL CHESS ROOK;So;0;ON;;;;;N;;;;; +1FA03;NEUTRAL CHESS BISHOP;So;0;ON;;;;;N;;;;; +1FA04;NEUTRAL CHESS KNIGHT;So;0;ON;;;;;N;;;;; +1FA05;NEUTRAL CHESS PAWN;So;0;ON;;;;;N;;;;; +1FA06;WHITE CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA07;BLACK CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA08;NEUTRAL CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA09;WHITE CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0A;WHITE CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0B;WHITE CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0C;WHITE CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0D;WHITE CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0E;WHITE CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0F;BLACK CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA10;BLACK CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA11;BLACK CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA12;BLACK CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA13;BLACK CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA14;BLACK CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA15;NEUTRAL CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA16;NEUTRAL CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA17;NEUTRAL CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA18;NEUTRAL CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA19;NEUTRAL CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA1A;NEUTRAL CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA1B;WHITE CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA1C;BLACK CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA1D;NEUTRAL CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA1E;WHITE CHESS TURNED KING;So;0;ON;;;;;N;;;;; +1FA1F;WHITE CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;; +1FA20;WHITE CHESS TURNED ROOK;So;0;ON;;;;;N;;;;; +1FA21;WHITE CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;; +1FA22;WHITE CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;; +1FA23;WHITE CHESS TURNED PAWN;So;0;ON;;;;;N;;;;; +1FA24;BLACK CHESS TURNED KING;So;0;ON;;;;;N;;;;; +1FA25;BLACK CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;; +1FA26;BLACK CHESS TURNED ROOK;So;0;ON;;;;;N;;;;; +1FA27;BLACK CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;; +1FA28;BLACK CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;; +1FA29;BLACK CHESS TURNED PAWN;So;0;ON;;;;;N;;;;; +1FA2A;NEUTRAL CHESS TURNED KING;So;0;ON;;;;;N;;;;; +1FA2B;NEUTRAL CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;; +1FA2C;NEUTRAL CHESS TURNED ROOK;So;0;ON;;;;;N;;;;; +1FA2D;NEUTRAL CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;; +1FA2E;NEUTRAL CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;; +1FA2F;NEUTRAL CHESS TURNED PAWN;So;0;ON;;;;;N;;;;; +1FA30;WHITE CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA31;BLACK CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA32;NEUTRAL CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA33;WHITE CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA34;WHITE CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA35;WHITE CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA36;WHITE CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA37;WHITE CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA38;WHITE CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA39;BLACK CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3A;BLACK CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3B;BLACK CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3C;BLACK CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3D;BLACK CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3E;BLACK CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3F;NEUTRAL CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA40;NEUTRAL CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA41;NEUTRAL CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA42;NEUTRAL CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA43;NEUTRAL CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA44;NEUTRAL CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA45;WHITE CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;; +1FA46;BLACK CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;; +1FA47;NEUTRAL CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;; +1FA48;WHITE CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;; +1FA49;BLACK CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;; +1FA4A;NEUTRAL CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;; +1FA4B;WHITE CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA4C;BLACK CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA4D;NEUTRAL CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA4E;WHITE CHESS KNIGHT-QUEEN;So;0;ON;;;;;N;;;;; +1FA4F;WHITE CHESS KNIGHT-ROOK;So;0;ON;;;;;N;;;;; +1FA50;WHITE CHESS KNIGHT-BISHOP;So;0;ON;;;;;N;;;;; +1FA51;BLACK CHESS KNIGHT-QUEEN;So;0;ON;;;;;N;;;;; +1FA52;BLACK CHESS KNIGHT-ROOK;So;0;ON;;;;;N;;;;; +1FA53;BLACK CHESS KNIGHT-BISHOP;So;0;ON;;;;;N;;;;; 1FA60;XIANGQI RED GENERAL;So;0;ON;;;;;N;;;;; 1FA61;XIANGQI RED MANDARIN;So;0;ON;;;;;N;;;;; 1FA62;XIANGQI RED ELEPHANT;So;0;ON;;;;;N;;;;; @@ -31397,6 +31930,22 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FA6B;XIANGQI BLACK CHARIOT;So;0;ON;;;;;N;;;;; 1FA6C;XIANGQI BLACK CANNON;So;0;ON;;;;;N;;;;; 1FA6D;XIANGQI BLACK SOLDIER;So;0;ON;;;;;N;;;;; +1FA70;BALLET SHOES;So;0;ON;;;;;N;;;;; +1FA71;ONE-PIECE SWIMSUIT;So;0;ON;;;;;N;;;;; +1FA72;BRIEFS;So;0;ON;;;;;N;;;;; +1FA73;SHORTS;So;0;ON;;;;;N;;;;; +1FA78;DROP OF BLOOD;So;0;ON;;;;;N;;;;; +1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;; +1FA7A;STETHOSCOPE;So;0;ON;;;;;N;;;;; +1FA80;YO-YO;So;0;ON;;;;;N;;;;; +1FA81;KITE;So;0;ON;;;;;N;;;;; +1FA82;PARACHUTE;So;0;ON;;;;;N;;;;; +1FA90;RINGED PLANET;So;0;ON;;;;;N;;;;; +1FA91;CHAIR;So;0;ON;;;;;N;;;;; +1FA92;RAZOR;So;0;ON;;;;;N;;;;; +1FA93;AXE;So;0;ON;;;;;N;;;;; +1FA94;DIYA LAMP;So;0;ON;;;;;N;;;;; +1FA95;BANJO;So;0;ON;;;;;N;;;;; 20000;<CJK Ideograph Extension B, First>;Lo;0;L;;;;;N;;;;; 2A6D6;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;; 2A700;<CJK Ideograph Extension C, First>;Lo;0;L;;;;;N;;;;; diff --git a/lib/stdlib/uc_spec/emoji-data.txt b/lib/stdlib/uc_spec/emoji-data.txt index 6e66455252..2fb5c3ff68 100644 --- a/lib/stdlib/uc_spec/emoji-data.txt +++ b/lib/stdlib/uc_spec/emoji-data.txt @@ -1,11 +1,11 @@ # emoji-data.txt -# Date: 2018-02-07, 07:55:18 GMT -# ยฉ 2018 Unicodeยฎ, Inc. +# Date: 2019-01-15, 12:10:05 GMT +# ยฉ 2019 Unicodeยฎ, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # # Emoji Data for UTS #51 -# Version: 11.0 +# Version: 12.0 # # For documentation and usage, see http://www.unicode.org/reports/tr51 # @@ -45,7 +45,7 @@ 25FB..25FE ; Emoji # 3.2 [4] (โป๏ธ..โพ) white medium square..black medium-small square 2600..2604 ; Emoji # 1.1 [5] (โ๏ธ..โ๏ธ) sun..comet 260E ; Emoji # 1.1 [1] (โ๏ธ) telephone -2611 ; Emoji # 1.1 [1] (โ๏ธ) ballot box with check +2611 ; Emoji # 1.1 [1] (โ๏ธ) check box with check 2614..2615 ; Emoji # 4.0 [2] (โ..โ) umbrella with rain drops..hot beverage 2618 ; Emoji # 4.1 [1] (โ๏ธ) shamrock 261D ; Emoji # 1.1 [1] (โ๏ธ) index pointing up @@ -82,14 +82,14 @@ 26F7..26FA ; Emoji # 5.2 [4] (โท๏ธ..โบ) skier..tent 26FD ; Emoji # 5.2 [1] (โฝ) fuel pump 2702 ; Emoji # 1.1 [1] (โ๏ธ) scissors -2705 ; Emoji # 6.0 [1] (โ
) white heavy check mark +2705 ; Emoji # 6.0 [1] (โ
) check mark button 2708..2709 ; Emoji # 1.1 [2] (โ๏ธ..โ๏ธ) airplane..envelope 270A..270B ; Emoji # 6.0 [2] (โ..โ) raised fist..raised hand 270C..270D ; Emoji # 1.1 [2] (โ๏ธ..โ๏ธ) victory hand..writing hand 270F ; Emoji # 1.1 [1] (โ๏ธ) pencil 2712 ; Emoji # 1.1 [1] (โ๏ธ) black nib -2714 ; Emoji # 1.1 [1] (โ๏ธ) heavy check mark -2716 ; Emoji # 1.1 [1] (โ๏ธ) heavy multiplication x +2714 ; Emoji # 1.1 [1] (โ๏ธ) check mark +2716 ; Emoji # 1.1 [1] (โ๏ธ) multiplication sign 271D ; Emoji # 1.1 [1] (โ๏ธ) latin cross 2721 ; Emoji # 1.1 [1] (โก๏ธ) star of David 2728 ; Emoji # 6.0 [1] (โจ) sparkles @@ -100,8 +100,8 @@ 274E ; Emoji # 6.0 [1] (โ) cross mark button 2753..2755 ; Emoji # 6.0 [3] (โ..โ) question mark..white exclamation mark 2757 ; Emoji # 5.2 [1] (โ) exclamation mark -2763..2764 ; Emoji # 1.1 [2] (โฃ๏ธ..โค๏ธ) heavy heart exclamation..red heart -2795..2797 ; Emoji # 6.0 [3] (โ..โ) heavy plus sign..heavy division sign +2763..2764 ; Emoji # 1.1 [2] (โฃ๏ธ..โค๏ธ) heart exclamation..red heart +2795..2797 ; Emoji # 6.0 [3] (โ..โ) plus sign..division sign 27A1 ; Emoji # 1.1 [1] (โก๏ธ) right arrow 27B0 ; Emoji # 6.0 [1] (โฐ) curly loop 27BF ; Emoji # 6.0 [1] (โฟ) double curly loop @@ -109,7 +109,7 @@ 2B05..2B07 ; Emoji # 4.0 [3] (โฌ
๏ธ..โฌ๏ธ) left arrow..down arrow 2B1B..2B1C ; Emoji # 5.1 [2] (โฌ..โฌ) black large square..white large square 2B50 ; Emoji # 5.1 [1] (โญ) star -2B55 ; Emoji # 5.2 [1] (โญ) heavy large circle +2B55 ; Emoji # 5.2 [1] (โญ) hollow red circle 3030 ; Emoji # 1.1 [1] (ใฐ๏ธ) wavy dash 303D ; Emoji # 3.2 [1] (ใฝ๏ธ) part alternation mark 3297 ; Emoji # 1.1 [1] (ใ๏ธ) Japanese โcongratulationsโ button @@ -206,7 +206,7 @@ 1F62E..1F62F ; Emoji # 6.1 [2] (๐ฎ..๐ฏ) face with open mouth..hushed face 1F630..1F633 ; Emoji # 6.0 [4] (๐ฐ..๐ณ) anxious face with sweat..flushed face 1F634 ; Emoji # 6.1 [1] (๐ด) sleeping face -1F635..1F640 ; Emoji # 6.0 [12] (๐ต..๐) dizzy face..weary cat face +1F635..1F640 ; Emoji # 6.0 [12] (๐ต..๐) dizzy face..weary cat 1F641..1F642 ; Emoji # 7.0 [2] (๐..๐) slightly frowning face..slightly smiling face 1F643..1F644 ; Emoji # 8.0 [2] (๐..๐) upside-down face..face with rolling eyes 1F645..1F64F ; Emoji # 6.0 [11] (๐
..๐) person gesturing NO..folded hands @@ -214,6 +214,7 @@ 1F6CB..1F6CF ; Emoji # 7.0 [5] (๐๏ธ..๐๏ธ) couch and lamp..bed 1F6D0 ; Emoji # 8.0 [1] (๐) place of worship 1F6D1..1F6D2 ; Emoji # 9.0 [2] (๐..๐) stop sign..shopping cart +1F6D5 ; Emoji # 12.0 [1] (๐) hindu temple 1F6E0..1F6E5 ; Emoji # 7.0 [6] (๐ ๏ธ..๐ฅ๏ธ) hammer and wrench..motor boat 1F6E9 ; Emoji # 7.0 [1] (๐ฉ๏ธ) small airplane 1F6EB..1F6EC ; Emoji # 7.0 [2] (๐ซ..๐ฌ) airplane departure..airplane arrival @@ -222,6 +223,9 @@ 1F6F4..1F6F6 ; Emoji # 9.0 [3] (๐ด..๐ถ) kick scooter..canoe 1F6F7..1F6F8 ; Emoji # 10.0 [2] (๐ท..๐ธ) sled..flying saucer 1F6F9 ; Emoji # 11.0 [1] (๐น) skateboard +1F6FA ; Emoji # 12.0 [1] (๐บ) auto rickshaw +1F7E0..1F7EB ; Emoji # 12.0 [12] (๐ ..๐ซ) orange circle..brown square +1F90D..1F90F ; Emoji # 12.0 [3] (๐ค..๐ค) white heart..pinching hand 1F910..1F918 ; Emoji # 8.0 [9] (๐ค..๐ค) zipper-mouth face..sign of the horns 1F919..1F91E ; Emoji # 9.0 [6] (๐ค..๐ค) call me hand..crossed fingers 1F91F ; Emoji # 10.0 [1] (๐ค) love-you gesture @@ -231,27 +235,39 @@ 1F931..1F932 ; Emoji # 10.0 [2] (๐คฑ..๐คฒ) breast-feeding..palms up together 1F933..1F93A ; Emoji # 9.0 [8] (๐คณ..๐คบ) selfie..person fencing 1F93C..1F93E ; Emoji # 9.0 [3] (๐คผ..๐คพ) people wrestling..person playing handball +1F93F ; Emoji # 12.0 [1] (๐คฟ) diving mask 1F940..1F945 ; Emoji # 9.0 [6] (๐ฅ..๐ฅ
) wilted flower..goal net 1F947..1F94B ; Emoji # 9.0 [5] (๐ฅ..๐ฅ) 1st place medal..martial arts uniform 1F94C ; Emoji # 10.0 [1] (๐ฅ) curling stone 1F94D..1F94F ; Emoji # 11.0 [3] (๐ฅ..๐ฅ) lacrosse..flying disc 1F950..1F95E ; Emoji # 9.0 [15] (๐ฅ..๐ฅ) croissant..pancakes 1F95F..1F96B ; Emoji # 10.0 [13] (๐ฅ..๐ฅซ) dumpling..canned food -1F96C..1F970 ; Emoji # 11.0 [5] (๐ฅฌ..๐ฅฐ) leafy green..smiling face with 3 hearts +1F96C..1F970 ; Emoji # 11.0 [5] (๐ฅฌ..๐ฅฐ) leafy green..smiling face with hearts +1F971 ; Emoji # 12.0 [1] (๐ฅฑ) yawning face 1F973..1F976 ; Emoji # 11.0 [4] (๐ฅณ..๐ฅถ) partying face..cold face 1F97A ; Emoji # 11.0 [1] (๐ฅบ) pleading face -1F97C..1F97F ; Emoji # 11.0 [4] (๐ฅผ..๐ฅฟ) lab coat..womanโs flat shoe -1F980..1F984 ; Emoji # 8.0 [5] (๐ฆ..๐ฆ) crab..unicorn face +1F97B ; Emoji # 12.0 [1] (๐ฅป) sari +1F97C..1F97F ; Emoji # 11.0 [4] (๐ฅผ..๐ฅฟ) lab coat..flat shoe +1F980..1F984 ; Emoji # 8.0 [5] (๐ฆ..๐ฆ) crab..unicorn 1F985..1F991 ; Emoji # 9.0 [13] (๐ฆ
..๐ฆ) eagle..squid 1F992..1F997 ; Emoji # 10.0 [6] (๐ฆ..๐ฆ) giraffe..cricket 1F998..1F9A2 ; Emoji # 11.0 [11] (๐ฆ..๐ฆข) kangaroo..swan -1F9B0..1F9B9 ; Emoji # 11.0 [10] (๐ฆฐ..๐ฆน) red-haired..supervillain +1F9A5..1F9AA ; Emoji # 12.0 [6] (๐ฆฅ..๐ฆช) sloth..oyster +1F9AE..1F9AF ; Emoji # 12.0 [2] (๐ฆฎ..๐ฆฏ) guide dog..probing cane +1F9B0..1F9B9 ; Emoji # 11.0 [10] (๐ฆฐ..๐ฆน) red hair..supervillain +1F9BA..1F9BF ; Emoji # 12.0 [6] (๐ฆบ..๐ฆฟ) safety vest..mechanical leg 1F9C0 ; Emoji # 8.0 [1] (๐ง) cheese wedge 1F9C1..1F9C2 ; Emoji # 11.0 [2] (๐ง..๐ง) cupcake..salt +1F9C3..1F9CA ; Emoji # 12.0 [8] (๐ง..๐ง) beverage box..ice cube +1F9CD..1F9CF ; Emoji # 12.0 [3] (๐ง..๐ง) person standing..deaf person 1F9D0..1F9E6 ; Emoji # 10.0 [23] (๐ง..๐งฆ) face with monocle..socks 1F9E7..1F9FF ; Emoji # 11.0 [25] (๐งง..๐งฟ) red envelope..nazar amulet +1FA70..1FA73 ; Emoji # 12.0 [4] (๐ฉฐ..๐ฉณ) ballet shoes..shorts +1FA78..1FA7A ; Emoji # 12.0 [3] (๐ฉธ..๐ฉบ) drop of blood..stethoscope +1FA80..1FA82 ; Emoji # 12.0 [3] (๐ช..๐ช) yo-yo..parachute +1FA90..1FA95 ; Emoji # 12.0 [6] (๐ช..๐ช) ringed planet..banjo -# Total elements: 1250 +# Total elements: 1311 # ================================================ @@ -278,19 +294,19 @@ 26F5 ; Emoji_Presentation # 5.2 [1] (โต) sailboat 26FA ; Emoji_Presentation # 5.2 [1] (โบ) tent 26FD ; Emoji_Presentation # 5.2 [1] (โฝ) fuel pump -2705 ; Emoji_Presentation # 6.0 [1] (โ
) white heavy check mark +2705 ; Emoji_Presentation # 6.0 [1] (โ
) check mark button 270A..270B ; Emoji_Presentation # 6.0 [2] (โ..โ) raised fist..raised hand 2728 ; Emoji_Presentation # 6.0 [1] (โจ) sparkles 274C ; Emoji_Presentation # 6.0 [1] (โ) cross mark 274E ; Emoji_Presentation # 6.0 [1] (โ) cross mark button 2753..2755 ; Emoji_Presentation # 6.0 [3] (โ..โ) question mark..white exclamation mark 2757 ; Emoji_Presentation # 5.2 [1] (โ) exclamation mark -2795..2797 ; Emoji_Presentation # 6.0 [3] (โ..โ) heavy plus sign..heavy division sign +2795..2797 ; Emoji_Presentation # 6.0 [3] (โ..โ) plus sign..division sign 27B0 ; Emoji_Presentation # 6.0 [1] (โฐ) curly loop 27BF ; Emoji_Presentation # 6.0 [1] (โฟ) double curly loop 2B1B..2B1C ; Emoji_Presentation # 5.1 [2] (โฌ..โฌ) black large square..white large square 2B50 ; Emoji_Presentation # 5.1 [1] (โญ) star -2B55 ; Emoji_Presentation # 5.2 [1] (โญ) heavy large circle +2B55 ; Emoji_Presentation # 5.2 [1] (โญ) hollow red circle 1F004 ; Emoji_Presentation # 5.1 [1] (๐) mahjong red dragon 1F0CF ; Emoji_Presentation # 6.0 [1] (๐) joker 1F18E ; Emoji_Presentation # 6.0 [1] (๐) AB button (blood type) @@ -349,7 +365,7 @@ 1F62E..1F62F ; Emoji_Presentation # 6.1 [2] (๐ฎ..๐ฏ) face with open mouth..hushed face 1F630..1F633 ; Emoji_Presentation # 6.0 [4] (๐ฐ..๐ณ) anxious face with sweat..flushed face 1F634 ; Emoji_Presentation # 6.1 [1] (๐ด) sleeping face -1F635..1F640 ; Emoji_Presentation # 6.0 [12] (๐ต..๐) dizzy face..weary cat face +1F635..1F640 ; Emoji_Presentation # 6.0 [12] (๐ต..๐) dizzy face..weary cat 1F641..1F642 ; Emoji_Presentation # 7.0 [2] (๐..๐) slightly frowning face..slightly smiling face 1F643..1F644 ; Emoji_Presentation # 8.0 [2] (๐..๐) upside-down face..face with rolling eyes 1F645..1F64F ; Emoji_Presentation # 6.0 [11] (๐
..๐) person gesturing NO..folded hands @@ -357,10 +373,14 @@ 1F6CC ; Emoji_Presentation # 7.0 [1] (๐) person in bed 1F6D0 ; Emoji_Presentation # 8.0 [1] (๐) place of worship 1F6D1..1F6D2 ; Emoji_Presentation # 9.0 [2] (๐..๐) stop sign..shopping cart +1F6D5 ; Emoji_Presentation # 12.0 [1] (๐) hindu temple 1F6EB..1F6EC ; Emoji_Presentation # 7.0 [2] (๐ซ..๐ฌ) airplane departure..airplane arrival 1F6F4..1F6F6 ; Emoji_Presentation # 9.0 [3] (๐ด..๐ถ) kick scooter..canoe 1F6F7..1F6F8 ; Emoji_Presentation # 10.0 [2] (๐ท..๐ธ) sled..flying saucer 1F6F9 ; Emoji_Presentation # 11.0 [1] (๐น) skateboard +1F6FA ; Emoji_Presentation # 12.0 [1] (๐บ) auto rickshaw +1F7E0..1F7EB ; Emoji_Presentation # 12.0 [12] (๐ ..๐ซ) orange circle..brown square +1F90D..1F90F ; Emoji_Presentation # 12.0 [3] (๐ค..๐ค) white heart..pinching hand 1F910..1F918 ; Emoji_Presentation # 8.0 [9] (๐ค..๐ค) zipper-mouth face..sign of the horns 1F919..1F91E ; Emoji_Presentation # 9.0 [6] (๐ค..๐ค) call me hand..crossed fingers 1F91F ; Emoji_Presentation # 10.0 [1] (๐ค) love-you gesture @@ -370,27 +390,39 @@ 1F931..1F932 ; Emoji_Presentation # 10.0 [2] (๐คฑ..๐คฒ) breast-feeding..palms up together 1F933..1F93A ; Emoji_Presentation # 9.0 [8] (๐คณ..๐คบ) selfie..person fencing 1F93C..1F93E ; Emoji_Presentation # 9.0 [3] (๐คผ..๐คพ) people wrestling..person playing handball +1F93F ; Emoji_Presentation # 12.0 [1] (๐คฟ) diving mask 1F940..1F945 ; Emoji_Presentation # 9.0 [6] (๐ฅ..๐ฅ
) wilted flower..goal net 1F947..1F94B ; Emoji_Presentation # 9.0 [5] (๐ฅ..๐ฅ) 1st place medal..martial arts uniform 1F94C ; Emoji_Presentation # 10.0 [1] (๐ฅ) curling stone 1F94D..1F94F ; Emoji_Presentation # 11.0 [3] (๐ฅ..๐ฅ) lacrosse..flying disc 1F950..1F95E ; Emoji_Presentation # 9.0 [15] (๐ฅ..๐ฅ) croissant..pancakes 1F95F..1F96B ; Emoji_Presentation # 10.0 [13] (๐ฅ..๐ฅซ) dumpling..canned food -1F96C..1F970 ; Emoji_Presentation # 11.0 [5] (๐ฅฌ..๐ฅฐ) leafy green..smiling face with 3 hearts +1F96C..1F970 ; Emoji_Presentation # 11.0 [5] (๐ฅฌ..๐ฅฐ) leafy green..smiling face with hearts +1F971 ; Emoji_Presentation # 12.0 [1] (๐ฅฑ) yawning face 1F973..1F976 ; Emoji_Presentation # 11.0 [4] (๐ฅณ..๐ฅถ) partying face..cold face 1F97A ; Emoji_Presentation # 11.0 [1] (๐ฅบ) pleading face -1F97C..1F97F ; Emoji_Presentation # 11.0 [4] (๐ฅผ..๐ฅฟ) lab coat..womanโs flat shoe -1F980..1F984 ; Emoji_Presentation # 8.0 [5] (๐ฆ..๐ฆ) crab..unicorn face +1F97B ; Emoji_Presentation # 12.0 [1] (๐ฅป) sari +1F97C..1F97F ; Emoji_Presentation # 11.0 [4] (๐ฅผ..๐ฅฟ) lab coat..flat shoe +1F980..1F984 ; Emoji_Presentation # 8.0 [5] (๐ฆ..๐ฆ) crab..unicorn 1F985..1F991 ; Emoji_Presentation # 9.0 [13] (๐ฆ
..๐ฆ) eagle..squid 1F992..1F997 ; Emoji_Presentation # 10.0 [6] (๐ฆ..๐ฆ) giraffe..cricket 1F998..1F9A2 ; Emoji_Presentation # 11.0 [11] (๐ฆ..๐ฆข) kangaroo..swan -1F9B0..1F9B9 ; Emoji_Presentation # 11.0 [10] (๐ฆฐ..๐ฆน) red-haired..supervillain +1F9A5..1F9AA ; Emoji_Presentation # 12.0 [6] (๐ฆฅ..๐ฆช) sloth..oyster +1F9AE..1F9AF ; Emoji_Presentation # 12.0 [2] (๐ฆฎ..๐ฆฏ) guide dog..probing cane +1F9B0..1F9B9 ; Emoji_Presentation # 11.0 [10] (๐ฆฐ..๐ฆน) red hair..supervillain +1F9BA..1F9BF ; Emoji_Presentation # 12.0 [6] (๐ฆบ..๐ฆฟ) safety vest..mechanical leg 1F9C0 ; Emoji_Presentation # 8.0 [1] (๐ง) cheese wedge 1F9C1..1F9C2 ; Emoji_Presentation # 11.0 [2] (๐ง..๐ง) cupcake..salt +1F9C3..1F9CA ; Emoji_Presentation # 12.0 [8] (๐ง..๐ง) beverage box..ice cube +1F9CD..1F9CF ; Emoji_Presentation # 12.0 [3] (๐ง..๐ง) person standing..deaf person 1F9D0..1F9E6 ; Emoji_Presentation # 10.0 [23] (๐ง..๐งฆ) face with monocle..socks 1F9E7..1F9FF ; Emoji_Presentation # 11.0 [25] (๐งง..๐งฟ) red envelope..nazar amulet +1FA70..1FA73 ; Emoji_Presentation # 12.0 [4] (๐ฉฐ..๐ฉณ) ballet shoes..shorts +1FA78..1FA7A ; Emoji_Presentation # 12.0 [3] (๐ฉธ..๐ฉบ) drop of blood..stethoscope +1FA80..1FA82 ; Emoji_Presentation # 12.0 [3] (๐ช..๐ช) yo-yo..parachute +1FA90..1FA95 ; Emoji_Presentation # 12.0 [6] (๐ช..๐ช) ringed planet..banjo -# Total elements: 1032 +# Total elements: 1093 # ================================================ @@ -417,12 +449,12 @@ 1F3CB..1F3CC ; Emoji_Modifier_Base # 7.0 [2] (๐๏ธ..๐๏ธ) person lifting weights..person golfing 1F442..1F443 ; Emoji_Modifier_Base # 6.0 [2] (๐..๐) ear..nose 1F446..1F450 ; Emoji_Modifier_Base # 6.0 [11] (๐..๐) backhand index pointing up..open hands -1F466..1F469 ; Emoji_Modifier_Base # 6.0 [4] (๐ฆ..๐ฉ) boy..woman -1F46E ; Emoji_Modifier_Base # 6.0 [1] (๐ฎ) police officer -1F470..1F478 ; Emoji_Modifier_Base # 6.0 [9] (๐ฐ..๐ธ) bride with veil..princess +1F466..1F478 ; Emoji_Modifier_Base # 6.0 [19] (๐ฆ..๐ธ) boy..princess 1F47C ; Emoji_Modifier_Base # 6.0 [1] (๐ผ) baby angel 1F481..1F483 ; Emoji_Modifier_Base # 6.0 [3] (๐..๐) person tipping hand..woman dancing 1F485..1F487 ; Emoji_Modifier_Base # 6.0 [3] (๐
..๐) nail polish..person getting haircut +1F48F ; Emoji_Modifier_Base # 6.0 [1] (๐) kiss +1F491 ; Emoji_Modifier_Base # 6.0 [1] (๐) couple with heart 1F4AA ; Emoji_Modifier_Base # 6.0 [1] (๐ช) flexed biceps 1F574..1F575 ; Emoji_Modifier_Base # 7.0 [2] (๐ด๏ธ..๐ต๏ธ) man in suit levitating..detective 1F57A ; Emoji_Modifier_Base # 9.0 [1] (๐บ) man dancing @@ -434,20 +466,22 @@ 1F6B4..1F6B6 ; Emoji_Modifier_Base # 6.0 [3] (๐ด..๐ถ) person biking..person walking 1F6C0 ; Emoji_Modifier_Base # 6.0 [1] (๐) person taking bath 1F6CC ; Emoji_Modifier_Base # 7.0 [1] (๐) person in bed +1F90F ; Emoji_Modifier_Base # 12.0 [1] (๐ค) pinching hand 1F918 ; Emoji_Modifier_Base # 8.0 [1] (๐ค) sign of the horns -1F919..1F91C ; Emoji_Modifier_Base # 9.0 [4] (๐ค..๐ค) call me hand..right-facing fist -1F91E ; Emoji_Modifier_Base # 9.0 [1] (๐ค) crossed fingers +1F919..1F91E ; Emoji_Modifier_Base # 9.0 [6] (๐ค..๐ค) call me hand..crossed fingers 1F91F ; Emoji_Modifier_Base # 10.0 [1] (๐ค) love-you gesture 1F926 ; Emoji_Modifier_Base # 9.0 [1] (๐คฆ) person facepalming 1F930 ; Emoji_Modifier_Base # 9.0 [1] (๐คฐ) pregnant woman 1F931..1F932 ; Emoji_Modifier_Base # 10.0 [2] (๐คฑ..๐คฒ) breast-feeding..palms up together 1F933..1F939 ; Emoji_Modifier_Base # 9.0 [7] (๐คณ..๐คน) selfie..person juggling -1F93D..1F93E ; Emoji_Modifier_Base # 9.0 [2] (๐คฝ..๐คพ) person playing water polo..person playing handball +1F93C..1F93E ; Emoji_Modifier_Base # 9.0 [3] (๐คผ..๐คพ) people wrestling..person playing handball 1F9B5..1F9B6 ; Emoji_Modifier_Base # 11.0 [2] (๐ฆต..๐ฆถ) leg..foot 1F9B8..1F9B9 ; Emoji_Modifier_Base # 11.0 [2] (๐ฆธ..๐ฆน) superhero..supervillain -1F9D1..1F9DD ; Emoji_Modifier_Base # 10.0 [13] (๐ง..๐ง) adult..elf +1F9BB ; Emoji_Modifier_Base # 12.0 [1] (๐ฆป) ear with hearing aid +1F9CD..1F9CF ; Emoji_Modifier_Base # 12.0 [3] (๐ง..๐ง) person standing..deaf person +1F9D1..1F9DD ; Emoji_Modifier_Base # 10.0 [13] (๐ง..๐ง) person..elf -# Total elements: 106 +# Total elements: 120 # ================================================ @@ -462,7 +496,7 @@ FE0F ; Emoji_Component # 3.2 [1] () VARIATION SELECTOR-16 1F1E6..1F1FF ; Emoji_Component # 6.0 [26] (๐ฆ..๐ฟ) regional indicator symbol letter a..regional indicator symbol letter z 1F3FB..1F3FF ; Emoji_Component # 8.0 [5] (๐ป..๐ฟ) light skin tone..dark skin tone -1F9B0..1F9B3 ; Emoji_Component # 11.0 [4] (๐ฆฐ..๐ฆณ) red-haired..white-haired +1F9B0..1F9B3 ; Emoji_Component # 11.0 [4] (๐ฆฐ..๐ฆณ) red hair..white hair E0020..E007F ; Emoji_Component # 3.1 [96] (๓ ..๓ ฟ) tag space..cancel tag # Total elements: 146 @@ -482,7 +516,7 @@ E0020..E007F ; Emoji_Component # 3.1 [96] (๓ ..๓ ฟ) tag space..ca 21A9..21AA ; Extended_Pictographic# 1.1 [2] (โฉ๏ธ..โช๏ธ) right arrow curving left..left arrow curving right 231A..231B ; Extended_Pictographic# 1.1 [2] (โ..โ) watch..hourglass done 2328 ; Extended_Pictographic# 1.1 [1] (โจ๏ธ) keyboard -2388 ; Extended_Pictographic# 3.0 [1] (โ๏ธ) HELM SYMBOL +2388 ; Extended_Pictographic# 3.0 [1] (โ) HELM SYMBOL 23CF ; Extended_Pictographic# 4.0 [1] (โ๏ธ) eject button 23E9..23F3 ; Extended_Pictographic# 6.0 [11] (โฉ..โณ) fast-forward button..hourglass not done 23F8..23FA ; Extended_Pictographic# 7.0 [3] (โธ๏ธ..โบ๏ธ) pause button..record button @@ -491,42 +525,42 @@ E0020..E007F ; Emoji_Component # 3.1 [96] (๓ ..๓ ฟ) tag space..ca 25B6 ; Extended_Pictographic# 1.1 [1] (โถ๏ธ) play button 25C0 ; Extended_Pictographic# 1.1 [1] (โ๏ธ) reverse button 25FB..25FE ; Extended_Pictographic# 3.2 [4] (โป๏ธ..โพ) white medium square..black medium-small square -2600..2605 ; Extended_Pictographic# 1.1 [6] (โ๏ธ..โ
๏ธ) sun..BLACK STAR -2607..2612 ; Extended_Pictographic# 1.1 [12] (โ๏ธ..โ๏ธ) LIGHTNING..BALLOT BOX WITH X +2600..2605 ; Extended_Pictographic# 1.1 [6] (โ๏ธ..โ
) sun..BLACK STAR +2607..2612 ; Extended_Pictographic# 1.1 [12] (โ..โ) LIGHTNING..BALLOT BOX WITH X 2614..2615 ; Extended_Pictographic# 4.0 [2] (โ..โ) umbrella with rain drops..hot beverage -2616..2617 ; Extended_Pictographic# 3.2 [2] (โ๏ธ..โ๏ธ) WHITE SHOGI PIECE..BLACK SHOGI PIECE +2616..2617 ; Extended_Pictographic# 3.2 [2] (โ..โ) WHITE SHOGI PIECE..BLACK SHOGI PIECE 2618 ; Extended_Pictographic# 4.1 [1] (โ๏ธ) shamrock -2619 ; Extended_Pictographic# 3.0 [1] (โ๏ธ) REVERSED ROTATED FLORAL HEART BULLET -261A..266F ; Extended_Pictographic# 1.1 [86] (โ๏ธ..โฏ๏ธ) BLACK LEFT POINTING INDEX..MUSIC SHARP SIGN -2670..2671 ; Extended_Pictographic# 3.0 [2] (โฐ๏ธ..โฑ๏ธ) WEST SYRIAC CROSS..EAST SYRIAC CROSS -2672..267D ; Extended_Pictographic# 3.2 [12] (โฒ๏ธ..โฝ๏ธ) UNIVERSAL RECYCLING SYMBOL..PARTIALLY-RECYCLED PAPER SYMBOL +2619 ; Extended_Pictographic# 3.0 [1] (โ) REVERSED ROTATED FLORAL HEART BULLET +261A..266F ; Extended_Pictographic# 1.1 [86] (โ..โฏ) BLACK LEFT POINTING INDEX..MUSIC SHARP SIGN +2670..2671 ; Extended_Pictographic# 3.0 [2] (โฐ..โฑ) WEST SYRIAC CROSS..EAST SYRIAC CROSS +2672..267D ; Extended_Pictographic# 3.2 [12] (โฒ..โฝ) UNIVERSAL RECYCLING SYMBOL..PARTIALLY-RECYCLED PAPER SYMBOL 267E..267F ; Extended_Pictographic# 4.1 [2] (โพ๏ธ..โฟ) infinity..wheelchair symbol -2680..2685 ; Extended_Pictographic# 3.2 [6] (โ๏ธ..โ
๏ธ) DIE FACE-1..DIE FACE-6 -2690..2691 ; Extended_Pictographic# 4.0 [2] (โ๏ธ..โ๏ธ) WHITE FLAG..BLACK FLAG +2680..2685 ; Extended_Pictographic# 3.2 [6] (โ..โ
) DIE FACE-1..DIE FACE-6 +2690..2691 ; Extended_Pictographic# 4.0 [2] (โ..โ) WHITE FLAG..BLACK FLAG 2692..269C ; Extended_Pictographic# 4.1 [11] (โ๏ธ..โ๏ธ) hammer and pick..fleur-de-lis -269D ; Extended_Pictographic# 5.1 [1] (โ๏ธ) OUTLINED WHITE STAR -269E..269F ; Extended_Pictographic# 5.2 [2] (โ๏ธ..โ๏ธ) THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT +269D ; Extended_Pictographic# 5.1 [1] (โ) OUTLINED WHITE STAR +269E..269F ; Extended_Pictographic# 5.2 [2] (โ..โ) THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT 26A0..26A1 ; Extended_Pictographic# 4.0 [2] (โ ๏ธ..โก) warning..high voltage -26A2..26B1 ; Extended_Pictographic# 4.1 [16] (โข๏ธ..โฑ๏ธ) DOUBLED FEMALE SIGN..funeral urn -26B2 ; Extended_Pictographic# 5.0 [1] (โฒ๏ธ) NEUTER -26B3..26BC ; Extended_Pictographic# 5.1 [10] (โณ๏ธ..โผ๏ธ) CERES..SESQUIQUADRATE -26BD..26BF ; Extended_Pictographic# 5.2 [3] (โฝ..โฟ๏ธ) soccer ball..SQUARED KEY -26C0..26C3 ; Extended_Pictographic# 5.1 [4] (โ๏ธ..โ๏ธ) WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING -26C4..26CD ; Extended_Pictographic# 5.2 [10] (โ..โ๏ธ) snowman without snow..DISABLED CAR +26A2..26B1 ; Extended_Pictographic# 4.1 [16] (โข..โฑ๏ธ) DOUBLED FEMALE SIGN..funeral urn +26B2 ; Extended_Pictographic# 5.0 [1] (โฒ) NEUTER +26B3..26BC ; Extended_Pictographic# 5.1 [10] (โณ..โผ) CERES..SESQUIQUADRATE +26BD..26BF ; Extended_Pictographic# 5.2 [3] (โฝ..โฟ) soccer ball..SQUARED KEY +26C0..26C3 ; Extended_Pictographic# 5.1 [4] (โ..โ) WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING +26C4..26CD ; Extended_Pictographic# 5.2 [10] (โ..โ) snowman without snow..DISABLED CAR 26CE ; Extended_Pictographic# 6.0 [1] (โ) Ophiuchus -26CF..26E1 ; Extended_Pictographic# 5.2 [19] (โ๏ธ..โก๏ธ) pick..RESTRICTED LEFT ENTRY-2 -26E2 ; Extended_Pictographic# 6.0 [1] (โข๏ธ) ASTRONOMICAL SYMBOL FOR URANUS -26E3 ; Extended_Pictographic# 5.2 [1] (โฃ๏ธ) HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE -26E4..26E7 ; Extended_Pictographic# 6.0 [4] (โค๏ธ..โง๏ธ) PENTAGRAM..INVERTED PENTAGRAM -26E8..26FF ; Extended_Pictographic# 5.2 [24] (โจ๏ธ..โฟ๏ธ) BLACK CROSS ON SHIELD..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE -2700 ; Extended_Pictographic# 7.0 [1] (โ๏ธ) BLACK SAFETY SCISSORS -2701..2704 ; Extended_Pictographic# 1.1 [4] (โ๏ธ..โ๏ธ) UPPER BLADE SCISSORS..WHITE SCISSORS -2705 ; Extended_Pictographic# 6.0 [1] (โ
) white heavy check mark +26CF..26E1 ; Extended_Pictographic# 5.2 [19] (โ๏ธ..โก) pick..RESTRICTED LEFT ENTRY-2 +26E2 ; Extended_Pictographic# 6.0 [1] (โข) ASTRONOMICAL SYMBOL FOR URANUS +26E3 ; Extended_Pictographic# 5.2 [1] (โฃ) HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE +26E4..26E7 ; Extended_Pictographic# 6.0 [4] (โค..โง) PENTAGRAM..INVERTED PENTAGRAM +26E8..26FF ; Extended_Pictographic# 5.2 [24] (โจ..โฟ) BLACK CROSS ON SHIELD..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE +2700 ; Extended_Pictographic# 7.0 [1] (โ) BLACK SAFETY SCISSORS +2701..2704 ; Extended_Pictographic# 1.1 [4] (โ..โ) UPPER BLADE SCISSORS..WHITE SCISSORS +2705 ; Extended_Pictographic# 6.0 [1] (โ
) check mark button 2708..2709 ; Extended_Pictographic# 1.1 [2] (โ๏ธ..โ๏ธ) airplane..envelope 270A..270B ; Extended_Pictographic# 6.0 [2] (โ..โ) raised fist..raised hand 270C..2712 ; Extended_Pictographic# 1.1 [7] (โ๏ธ..โ๏ธ) victory hand..black nib -2714 ; Extended_Pictographic# 1.1 [1] (โ๏ธ) heavy check mark -2716 ; Extended_Pictographic# 1.1 [1] (โ๏ธ) heavy multiplication x +2714 ; Extended_Pictographic# 1.1 [1] (โ๏ธ) check mark +2716 ; Extended_Pictographic# 1.1 [1] (โ๏ธ) multiplication sign 271D ; Extended_Pictographic# 1.1 [1] (โ๏ธ) latin cross 2721 ; Extended_Pictographic# 1.1 [1] (โก๏ธ) star of David 2728 ; Extended_Pictographic# 6.0 [1] (โจ) sparkles @@ -537,8 +571,8 @@ E0020..E007F ; Emoji_Component # 3.1 [96] (๓ ..๓ ฟ) tag space..ca 274E ; Extended_Pictographic# 6.0 [1] (โ) cross mark button 2753..2755 ; Extended_Pictographic# 6.0 [3] (โ..โ) question mark..white exclamation mark 2757 ; Extended_Pictographic# 5.2 [1] (โ) exclamation mark -2763..2767 ; Extended_Pictographic# 1.1 [5] (โฃ๏ธ..โง๏ธ) heavy heart exclamation..ROTATED FLORAL HEART BULLET -2795..2797 ; Extended_Pictographic# 6.0 [3] (โ..โ) heavy plus sign..heavy division sign +2763..2767 ; Extended_Pictographic# 1.1 [5] (โฃ๏ธ..โง) heart exclamation..ROTATED FLORAL HEART BULLET +2795..2797 ; Extended_Pictographic# 6.0 [3] (โ..โ) plus sign..division sign 27A1 ; Extended_Pictographic# 1.1 [1] (โก๏ธ) right arrow 27B0 ; Extended_Pictographic# 6.0 [1] (โฐ) curly loop 27BF ; Extended_Pictographic# 6.0 [1] (โฟ) double curly loop @@ -546,45 +580,46 @@ E0020..E007F ; Emoji_Component # 3.1 [96] (๓ ..๓ ฟ) tag space..ca 2B05..2B07 ; Extended_Pictographic# 4.0 [3] (โฌ
๏ธ..โฌ๏ธ) left arrow..down arrow 2B1B..2B1C ; Extended_Pictographic# 5.1 [2] (โฌ..โฌ) black large square..white large square 2B50 ; Extended_Pictographic# 5.1 [1] (โญ) star -2B55 ; Extended_Pictographic# 5.2 [1] (โญ) heavy large circle +2B55 ; Extended_Pictographic# 5.2 [1] (โญ) hollow red circle 3030 ; Extended_Pictographic# 1.1 [1] (ใฐ๏ธ) wavy dash 303D ; Extended_Pictographic# 3.2 [1] (ใฝ๏ธ) part alternation mark 3297 ; Extended_Pictographic# 1.1 [1] (ใ๏ธ) Japanese โcongratulationsโ button 3299 ; Extended_Pictographic# 1.1 [1] (ใ๏ธ) Japanese โsecretโ button -1F000..1F02B ; Extended_Pictographic# 5.1 [44] (๐๏ธ..๐ซ๏ธ) MAHJONG TILE EAST WIND..MAHJONG TILE BACK -1F02C..1F02F ; Extended_Pictographic# NA [4] (๐ฌ๏ธ..๐ฏ๏ธ) <reserved-1F02C>..<reserved-1F02F> -1F030..1F093 ; Extended_Pictographic# 5.1[100] (๐ฐ๏ธ..๐๏ธ) DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06 -1F094..1F09F ; Extended_Pictographic# NA [12] (๐๏ธ..๐๏ธ) <reserved-1F094>..<reserved-1F09F> -1F0A0..1F0AE ; Extended_Pictographic# 6.0 [15] (๐ ๏ธ..๐ฎ๏ธ) PLAYING CARD BACK..PLAYING CARD KING OF SPADES -1F0AF..1F0B0 ; Extended_Pictographic# NA [2] (๐ฏ๏ธ..๐ฐ๏ธ) <reserved-1F0AF>..<reserved-1F0B0> -1F0B1..1F0BE ; Extended_Pictographic# 6.0 [14] (๐ฑ๏ธ..๐พ๏ธ) PLAYING CARD ACE OF HEARTS..PLAYING CARD KING OF HEARTS -1F0BF ; Extended_Pictographic# 7.0 [1] (๐ฟ๏ธ) PLAYING CARD RED JOKER -1F0C0 ; Extended_Pictographic# NA [1] (๐๏ธ) <reserved-1F0C0> -1F0C1..1F0CF ; Extended_Pictographic# 6.0 [15] (๐๏ธ..๐) PLAYING CARD ACE OF DIAMONDS..joker -1F0D0 ; Extended_Pictographic# NA [1] (๐๏ธ) <reserved-1F0D0> -1F0D1..1F0DF ; Extended_Pictographic# 6.0 [15] (๐๏ธ..๐๏ธ) PLAYING CARD ACE OF CLUBS..PLAYING CARD WHITE JOKER -1F0E0..1F0F5 ; Extended_Pictographic# 7.0 [22] (๐ ๏ธ..๐ต๏ธ) PLAYING CARD FOOL..PLAYING CARD TRUMP-21 -1F0F6..1F0FF ; Extended_Pictographic# NA [10] (๐ถ๏ธ..๐ฟ๏ธ) <reserved-1F0F6>..<reserved-1F0FF> -1F10D..1F10F ; Extended_Pictographic# NA [3] (๐๏ธ..๐๏ธ) <reserved-1F10D>..<reserved-1F10F> -1F12F ; Extended_Pictographic# 11.0 [1] (๐ฏ๏ธ) COPYLEFT SYMBOL -1F16C..1F16F ; Extended_Pictographic# NA [4] (๐
ฌ๏ธ..๐
ฏ๏ธ) <reserved-1F16C>..<reserved-1F16F> +1F000..1F02B ; Extended_Pictographic# 5.1 [44] (๐..๐ซ) MAHJONG TILE EAST WIND..MAHJONG TILE BACK +1F02C..1F02F ; Extended_Pictographic# NA [4] (๐ฌ..๐ฏ) <reserved-1F02C>..<reserved-1F02F> +1F030..1F093 ; Extended_Pictographic# 5.1[100] (๐ฐ..๐) DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06 +1F094..1F09F ; Extended_Pictographic# NA [12] (๐..๐) <reserved-1F094>..<reserved-1F09F> +1F0A0..1F0AE ; Extended_Pictographic# 6.0 [15] (๐ ..๐ฎ) PLAYING CARD BACK..PLAYING CARD KING OF SPADES +1F0AF..1F0B0 ; Extended_Pictographic# NA [2] (๐ฏ..๐ฐ) <reserved-1F0AF>..<reserved-1F0B0> +1F0B1..1F0BE ; Extended_Pictographic# 6.0 [14] (๐ฑ..๐พ) PLAYING CARD ACE OF HEARTS..PLAYING CARD KING OF HEARTS +1F0BF ; Extended_Pictographic# 7.0 [1] (๐ฟ) PLAYING CARD RED JOKER +1F0C0 ; Extended_Pictographic# NA [1] (๐) <reserved-1F0C0> +1F0C1..1F0CF ; Extended_Pictographic# 6.0 [15] (๐..๐) PLAYING CARD ACE OF DIAMONDS..joker +1F0D0 ; Extended_Pictographic# NA [1] (๐) <reserved-1F0D0> +1F0D1..1F0DF ; Extended_Pictographic# 6.0 [15] (๐..๐) PLAYING CARD ACE OF CLUBS..PLAYING CARD WHITE JOKER +1F0E0..1F0F5 ; Extended_Pictographic# 7.0 [22] (๐ ..๐ต) PLAYING CARD FOOL..PLAYING CARD TRUMP-21 +1F0F6..1F0FF ; Extended_Pictographic# NA [10] (๐ถ..๐ฟ) <reserved-1F0F6>..<reserved-1F0FF> +1F10D..1F10F ; Extended_Pictographic# NA [3] (๐..๐) <reserved-1F10D>..<reserved-1F10F> +1F12F ; Extended_Pictographic# 11.0 [1] (๐ฏ) COPYLEFT SYMBOL +1F16C ; Extended_Pictographic# 12.0 [1] (๐
ฌ) RAISED MR SIGN +1F16D..1F16F ; Extended_Pictographic# NA [3] (๐
ญ..๐
ฏ) <reserved-1F16D>..<reserved-1F16F> 1F170..1F171 ; Extended_Pictographic# 6.0 [2] (๐
ฐ๏ธ..๐
ฑ๏ธ) A button (blood type)..B button (blood type) 1F17E ; Extended_Pictographic# 6.0 [1] (๐
พ๏ธ) O button (blood type) 1F17F ; Extended_Pictographic# 5.2 [1] (๐
ฟ๏ธ) P button 1F18E ; Extended_Pictographic# 6.0 [1] (๐) AB button (blood type) 1F191..1F19A ; Extended_Pictographic# 6.0 [10] (๐..๐) CL button..VS button -1F1AD..1F1E5 ; Extended_Pictographic# NA [57] (๐ญ๏ธ..๐ฅ๏ธ) <reserved-1F1AD>..<reserved-1F1E5> +1F1AD..1F1E5 ; Extended_Pictographic# NA [57] (๐ญ..๐ฅ) <reserved-1F1AD>..<reserved-1F1E5> 1F201..1F202 ; Extended_Pictographic# 6.0 [2] (๐..๐๏ธ) Japanese โhereโ button..Japanese โservice chargeโ button -1F203..1F20F ; Extended_Pictographic# NA [13] (๐๏ธ..๐๏ธ) <reserved-1F203>..<reserved-1F20F> +1F203..1F20F ; Extended_Pictographic# NA [13] (๐..๐) <reserved-1F203>..<reserved-1F20F> 1F21A ; Extended_Pictographic# 5.2 [1] (๐) Japanese โfree of chargeโ button 1F22F ; Extended_Pictographic# 5.2 [1] (๐ฏ) Japanese โreservedโ button 1F232..1F23A ; Extended_Pictographic# 6.0 [9] (๐ฒ..๐บ) Japanese โprohibitedโ button..Japanese โopen for businessโ button -1F23C..1F23F ; Extended_Pictographic# NA [4] (๐ผ๏ธ..๐ฟ๏ธ) <reserved-1F23C>..<reserved-1F23F> -1F249..1F24F ; Extended_Pictographic# NA [7] (๐๏ธ..๐๏ธ) <reserved-1F249>..<reserved-1F24F> +1F23C..1F23F ; Extended_Pictographic# NA [4] (๐ผ..๐ฟ) <reserved-1F23C>..<reserved-1F23F> +1F249..1F24F ; Extended_Pictographic# NA [7] (๐..๐) <reserved-1F249>..<reserved-1F24F> 1F250..1F251 ; Extended_Pictographic# 6.0 [2] (๐..๐) Japanese โbargainโ button..Japanese โacceptableโ button -1F252..1F25F ; Extended_Pictographic# NA [14] (๐๏ธ..๐๏ธ) <reserved-1F252>..<reserved-1F25F> -1F260..1F265 ; Extended_Pictographic# 10.0 [6] (๐ ๏ธ..๐ฅ๏ธ) ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI -1F266..1F2FF ; Extended_Pictographic# NA[154] (๐ฆ๏ธ..๐ฟ๏ธ) <reserved-1F266>..<reserved-1F2FF> +1F252..1F25F ; Extended_Pictographic# NA [14] (๐..๐) <reserved-1F252>..<reserved-1F25F> +1F260..1F265 ; Extended_Pictographic# 10.0 [6] (๐ ..๐ฅ) ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI +1F266..1F2FF ; Extended_Pictographic# NA[154] (๐ฆ..๐ฟ) <reserved-1F266>..<reserved-1F2FF> 1F300..1F320 ; Extended_Pictographic# 6.0 [33] (๐..๐ ) cyclone..shooting star 1F321..1F32C ; Extended_Pictographic# 7.0 [12] (๐ก๏ธ..๐ฌ๏ธ) thermometer..wind face 1F32D..1F32F ; Extended_Pictographic# 8.0 [3] (๐ญ..๐ฏ) hot dog..burrito @@ -594,7 +629,7 @@ E0020..E007F ; Emoji_Component # 3.1 [96] (๓ ..๓ ฟ) tag space..ca 1F37D ; Extended_Pictographic# 7.0 [1] (๐ฝ๏ธ) fork and knife with plate 1F37E..1F37F ; Extended_Pictographic# 8.0 [2] (๐พ..๐ฟ) bottle with popping cork..popcorn 1F380..1F393 ; Extended_Pictographic# 6.0 [20] (๐..๐) ribbon..graduation cap -1F394..1F39F ; Extended_Pictographic# 7.0 [12] (๐๏ธ..๐๏ธ) HEART WITH TIP ON THE LEFT..admission tickets +1F394..1F39F ; Extended_Pictographic# 7.0 [12] (๐..๐๏ธ) HEART WITH TIP ON THE LEFT..admission tickets 1F3A0..1F3C4 ; Extended_Pictographic# 6.0 [37] (๐ ..๐) carousel horse..person surfing 1F3C5 ; Extended_Pictographic# 7.0 [1] (๐
) sports medal 1F3C6..1F3CA ; Extended_Pictographic# 6.0 [5] (๐..๐) trophy..person swimming @@ -602,7 +637,7 @@ E0020..E007F ; Emoji_Component # 3.1 [96] (๓ ..๓ ฟ) tag space..ca 1F3CF..1F3D3 ; Extended_Pictographic# 8.0 [5] (๐..๐) cricket game..ping pong 1F3D4..1F3DF ; Extended_Pictographic# 7.0 [12] (๐๏ธ..๐๏ธ) snow-capped mountain..stadium 1F3E0..1F3F0 ; Extended_Pictographic# 6.0 [17] (๐ ..๐ฐ) house..castle -1F3F1..1F3F7 ; Extended_Pictographic# 7.0 [7] (๐ฑ๏ธ..๐ท๏ธ) WHITE PENNANT..label +1F3F1..1F3F7 ; Extended_Pictographic# 7.0 [7] (๐ฑ..๐ท๏ธ) WHITE PENNANT..label 1F3F8..1F3FA ; Extended_Pictographic# 8.0 [3] (๐ธ..๐บ) badminton..amphora 1F400..1F43E ; Extended_Pictographic# 6.0 [63] (๐..๐พ) rat..paw prints 1F43F ; Extended_Pictographic# 7.0 [1] (๐ฟ๏ธ) chipmunk @@ -611,15 +646,15 @@ E0020..E007F ; Emoji_Component # 3.1 [96] (๓ ..๓ ฟ) tag space..ca 1F442..1F4F7 ; Extended_Pictographic# 6.0[182] (๐..๐ท) ear..camera 1F4F8 ; Extended_Pictographic# 7.0 [1] (๐ธ) camera with flash 1F4F9..1F4FC ; Extended_Pictographic# 6.0 [4] (๐น..๐ผ) video camera..videocassette -1F4FD..1F4FE ; Extended_Pictographic# 7.0 [2] (๐ฝ๏ธ..๐พ๏ธ) film projector..PORTABLE STEREO +1F4FD..1F4FE ; Extended_Pictographic# 7.0 [2] (๐ฝ๏ธ..๐พ) film projector..PORTABLE STEREO 1F4FF ; Extended_Pictographic# 8.0 [1] (๐ฟ) prayer beads 1F500..1F53D ; Extended_Pictographic# 6.0 [62] (๐..๐ฝ) shuffle tracks button..downwards button -1F546..1F54A ; Extended_Pictographic# 7.0 [5] (๐๏ธ..๐๏ธ) WHITE LATIN CROSS..dove -1F54B..1F54F ; Extended_Pictographic# 8.0 [5] (๐..๐๏ธ) kaaba..BOWL OF HYGIEIA +1F546..1F54A ; Extended_Pictographic# 7.0 [5] (๐..๐๏ธ) WHITE LATIN CROSS..dove +1F54B..1F54F ; Extended_Pictographic# 8.0 [5] (๐..๐) kaaba..BOWL OF HYGIEIA 1F550..1F567 ; Extended_Pictographic# 6.0 [24] (๐..๐ง) one oโclock..twelve-thirty -1F568..1F579 ; Extended_Pictographic# 7.0 [18] (๐จ๏ธ..๐น๏ธ) RIGHT SPEAKER..joystick +1F568..1F579 ; Extended_Pictographic# 7.0 [18] (๐จ..๐น๏ธ) RIGHT SPEAKER..joystick 1F57A ; Extended_Pictographic# 9.0 [1] (๐บ) man dancing -1F57B..1F5A3 ; Extended_Pictographic# 7.0 [41] (๐ป๏ธ..๐ฃ๏ธ) LEFT HAND TELEPHONE RECEIVER..BLACK DOWN POINTING BACKHAND INDEX +1F57B..1F5A3 ; Extended_Pictographic# 7.0 [41] (๐ป..๐ฃ) LEFT HAND TELEPHONE RECEIVER..BLACK DOWN POINTING BACKHAND INDEX 1F5A4 ; Extended_Pictographic# 9.0 [1] (๐ค) black heart 1F5A5..1F5FA ; Extended_Pictographic# 7.0 [86] (๐ฅ๏ธ..๐บ๏ธ) desktop computer..world map 1F5FB..1F5FF ; Extended_Pictographic# 6.0 [5] (๐ป..๐ฟ) mount fuji..moai @@ -644,32 +679,37 @@ E0020..E007F ; Emoji_Component # 3.1 [96] (๓ ..๓ ฟ) tag space..ca 1F62E..1F62F ; Extended_Pictographic# 6.1 [2] (๐ฎ..๐ฏ) face with open mouth..hushed face 1F630..1F633 ; Extended_Pictographic# 6.0 [4] (๐ฐ..๐ณ) anxious face with sweat..flushed face 1F634 ; Extended_Pictographic# 6.1 [1] (๐ด) sleeping face -1F635..1F640 ; Extended_Pictographic# 6.0 [12] (๐ต..๐) dizzy face..weary cat face +1F635..1F640 ; Extended_Pictographic# 6.0 [12] (๐ต..๐) dizzy face..weary cat 1F641..1F642 ; Extended_Pictographic# 7.0 [2] (๐..๐) slightly frowning face..slightly smiling face 1F643..1F644 ; Extended_Pictographic# 8.0 [2] (๐..๐) upside-down face..face with rolling eyes 1F645..1F64F ; Extended_Pictographic# 6.0 [11] (๐
..๐) person gesturing NO..folded hands 1F680..1F6C5 ; Extended_Pictographic# 6.0 [70] (๐..๐
) rocket..left luggage -1F6C6..1F6CF ; Extended_Pictographic# 7.0 [10] (๐๏ธ..๐๏ธ) TRIANGLE WITH ROUNDED CORNERS..bed +1F6C6..1F6CF ; Extended_Pictographic# 7.0 [10] (๐..๐๏ธ) TRIANGLE WITH ROUNDED CORNERS..bed 1F6D0 ; Extended_Pictographic# 8.0 [1] (๐) place of worship 1F6D1..1F6D2 ; Extended_Pictographic# 9.0 [2] (๐..๐) stop sign..shopping cart -1F6D3..1F6D4 ; Extended_Pictographic# 10.0 [2] (๐๏ธ..๐๏ธ) STUPA..PAGODA -1F6D5..1F6DF ; Extended_Pictographic# NA [11] (๐๏ธ..๐๏ธ) <reserved-1F6D5>..<reserved-1F6DF> +1F6D3..1F6D4 ; Extended_Pictographic# 10.0 [2] (๐..๐) STUPA..PAGODA +1F6D5 ; Extended_Pictographic# 12.0 [1] (๐) hindu temple +1F6D6..1F6DF ; Extended_Pictographic# NA [10] (๐..๐) <reserved-1F6D6>..<reserved-1F6DF> 1F6E0..1F6EC ; Extended_Pictographic# 7.0 [13] (๐ ๏ธ..๐ฌ) hammer and wrench..airplane arrival -1F6ED..1F6EF ; Extended_Pictographic# NA [3] (๐ญ๏ธ..๐ฏ๏ธ) <reserved-1F6ED>..<reserved-1F6EF> +1F6ED..1F6EF ; Extended_Pictographic# NA [3] (๐ญ..๐ฏ) <reserved-1F6ED>..<reserved-1F6EF> 1F6F0..1F6F3 ; Extended_Pictographic# 7.0 [4] (๐ฐ๏ธ..๐ณ๏ธ) satellite..passenger ship 1F6F4..1F6F6 ; Extended_Pictographic# 9.0 [3] (๐ด..๐ถ) kick scooter..canoe 1F6F7..1F6F8 ; Extended_Pictographic# 10.0 [2] (๐ท..๐ธ) sled..flying saucer 1F6F9 ; Extended_Pictographic# 11.0 [1] (๐น) skateboard -1F6FA..1F6FF ; Extended_Pictographic# NA [6] (๐บ๏ธ..๐ฟ๏ธ) <reserved-1F6FA>..<reserved-1F6FF> -1F774..1F77F ; Extended_Pictographic# NA [12] (๐ด๏ธ..๐ฟ๏ธ) <reserved-1F774>..<reserved-1F77F> -1F7D5..1F7D8 ; Extended_Pictographic# 11.0 [4] (๐๏ธ..๐๏ธ) CIRCLED TRIANGLE..NEGATIVE CIRCLED SQUARE -1F7D9..1F7FF ; Extended_Pictographic# NA [39] (๐๏ธ..๐ฟ๏ธ) <reserved-1F7D9>..<reserved-1F7FF> -1F80C..1F80F ; Extended_Pictographic# NA [4] (๐ ๏ธ..๐ ๏ธ) <reserved-1F80C>..<reserved-1F80F> -1F848..1F84F ; Extended_Pictographic# NA [8] (๐ก๏ธ..๐ก๏ธ) <reserved-1F848>..<reserved-1F84F> -1F85A..1F85F ; Extended_Pictographic# NA [6] (๐ก๏ธ..๐ก๏ธ) <reserved-1F85A>..<reserved-1F85F> -1F888..1F88F ; Extended_Pictographic# NA [8] (๐ข๏ธ..๐ข๏ธ) <reserved-1F888>..<reserved-1F88F> -1F8AE..1F8FF ; Extended_Pictographic# NA [82] (๐ขฎ๏ธ..๐ฃฟ๏ธ) <reserved-1F8AE>..<reserved-1F8FF> -1F90C..1F90F ; Extended_Pictographic# NA [4] (๐ค๏ธ..๐ค๏ธ) <reserved-1F90C>..<reserved-1F90F> +1F6FA ; Extended_Pictographic# 12.0 [1] (๐บ) auto rickshaw +1F6FB..1F6FF ; Extended_Pictographic# NA [5] (๐ป..๐ฟ) <reserved-1F6FB>..<reserved-1F6FF> +1F774..1F77F ; Extended_Pictographic# NA [12] (๐ด..๐ฟ) <reserved-1F774>..<reserved-1F77F> +1F7D5..1F7D8 ; Extended_Pictographic# 11.0 [4] (๐..๐) CIRCLED TRIANGLE..NEGATIVE CIRCLED SQUARE +1F7D9..1F7DF ; Extended_Pictographic# NA [7] (๐..๐) <reserved-1F7D9>..<reserved-1F7DF> +1F7E0..1F7EB ; Extended_Pictographic# 12.0 [12] (๐ ..๐ซ) orange circle..brown square +1F7EC..1F7FF ; Extended_Pictographic# NA [20] (๐ฌ..๐ฟ) <reserved-1F7EC>..<reserved-1F7FF> +1F80C..1F80F ; Extended_Pictographic# NA [4] (๐ ..๐ ) <reserved-1F80C>..<reserved-1F80F> +1F848..1F84F ; Extended_Pictographic# NA [8] (๐ก..๐ก) <reserved-1F848>..<reserved-1F84F> +1F85A..1F85F ; Extended_Pictographic# NA [6] (๐ก..๐ก) <reserved-1F85A>..<reserved-1F85F> +1F888..1F88F ; Extended_Pictographic# NA [8] (๐ข..๐ข) <reserved-1F888>..<reserved-1F88F> +1F8AE..1F8FF ; Extended_Pictographic# NA [82] (๐ขฎ..๐ฃฟ) <reserved-1F8AE>..<reserved-1F8FF> +1F90C ; Extended_Pictographic# NA [1] (๐ค) <reserved-1F90C> +1F90D..1F90F ; Extended_Pictographic# 12.0 [3] (๐ค..๐ค) white heart..pinching hand 1F910..1F918 ; Extended_Pictographic# 8.0 [9] (๐ค..๐ค) zipper-mouth face..sign of the horns 1F919..1F91E ; Extended_Pictographic# 9.0 [6] (๐ค..๐ค) call me hand..crossed fingers 1F91F ; Extended_Pictographic# 10.0 [1] (๐ค) love-you gesture @@ -679,35 +719,50 @@ E0020..E007F ; Emoji_Component # 3.1 [96] (๓ ..๓ ฟ) tag space..ca 1F931..1F932 ; Extended_Pictographic# 10.0 [2] (๐คฑ..๐คฒ) breast-feeding..palms up together 1F933..1F93A ; Extended_Pictographic# 9.0 [8] (๐คณ..๐คบ) selfie..person fencing 1F93C..1F93E ; Extended_Pictographic# 9.0 [3] (๐คผ..๐คพ) people wrestling..person playing handball -1F93F ; Extended_Pictographic# NA [1] (๐คฟ๏ธ) <reserved-1F93F> +1F93F ; Extended_Pictographic# 12.0 [1] (๐คฟ) diving mask 1F940..1F945 ; Extended_Pictographic# 9.0 [6] (๐ฅ..๐ฅ
) wilted flower..goal net 1F947..1F94B ; Extended_Pictographic# 9.0 [5] (๐ฅ..๐ฅ) 1st place medal..martial arts uniform 1F94C ; Extended_Pictographic# 10.0 [1] (๐ฅ) curling stone 1F94D..1F94F ; Extended_Pictographic# 11.0 [3] (๐ฅ..๐ฅ) lacrosse..flying disc 1F950..1F95E ; Extended_Pictographic# 9.0 [15] (๐ฅ..๐ฅ) croissant..pancakes 1F95F..1F96B ; Extended_Pictographic# 10.0 [13] (๐ฅ..๐ฅซ) dumpling..canned food -1F96C..1F970 ; Extended_Pictographic# 11.0 [5] (๐ฅฌ..๐ฅฐ) leafy green..smiling face with 3 hearts -1F971..1F972 ; Extended_Pictographic# NA [2] (๐ฅฑ๏ธ..๐ฅฒ๏ธ) <reserved-1F971>..<reserved-1F972> +1F96C..1F970 ; Extended_Pictographic# 11.0 [5] (๐ฅฌ..๐ฅฐ) leafy green..smiling face with hearts +1F971 ; Extended_Pictographic# 12.0 [1] (๐ฅฑ) yawning face +1F972 ; Extended_Pictographic# NA [1] (๐ฅฒ) <reserved-1F972> 1F973..1F976 ; Extended_Pictographic# 11.0 [4] (๐ฅณ..๐ฅถ) partying face..cold face -1F977..1F979 ; Extended_Pictographic# NA [3] (๐ฅท๏ธ..๐ฅน๏ธ) <reserved-1F977>..<reserved-1F979> +1F977..1F979 ; Extended_Pictographic# NA [3] (๐ฅท..๐ฅน) <reserved-1F977>..<reserved-1F979> 1F97A ; Extended_Pictographic# 11.0 [1] (๐ฅบ) pleading face -1F97B ; Extended_Pictographic# NA [1] (๐ฅป๏ธ) <reserved-1F97B> -1F97C..1F97F ; Extended_Pictographic# 11.0 [4] (๐ฅผ..๐ฅฟ) lab coat..womanโs flat shoe -1F980..1F984 ; Extended_Pictographic# 8.0 [5] (๐ฆ..๐ฆ) crab..unicorn face +1F97B ; Extended_Pictographic# 12.0 [1] (๐ฅป) sari +1F97C..1F97F ; Extended_Pictographic# 11.0 [4] (๐ฅผ..๐ฅฟ) lab coat..flat shoe +1F980..1F984 ; Extended_Pictographic# 8.0 [5] (๐ฆ..๐ฆ) crab..unicorn 1F985..1F991 ; Extended_Pictographic# 9.0 [13] (๐ฆ
..๐ฆ) eagle..squid 1F992..1F997 ; Extended_Pictographic# 10.0 [6] (๐ฆ..๐ฆ) giraffe..cricket 1F998..1F9A2 ; Extended_Pictographic# 11.0 [11] (๐ฆ..๐ฆข) kangaroo..swan -1F9A3..1F9AF ; Extended_Pictographic# NA [13] (๐ฆฃ๏ธ..๐ฆฏ๏ธ) <reserved-1F9A3>..<reserved-1F9AF> -1F9B0..1F9B9 ; Extended_Pictographic# 11.0 [10] (๐ฆฐ..๐ฆน) red-haired..supervillain -1F9BA..1F9BF ; Extended_Pictographic# NA [6] (๐ฆบ๏ธ..๐ฆฟ๏ธ) <reserved-1F9BA>..<reserved-1F9BF> +1F9A3..1F9A4 ; Extended_Pictographic# NA [2] (๐ฆฃ..๐ฆค) <reserved-1F9A3>..<reserved-1F9A4> +1F9A5..1F9AA ; Extended_Pictographic# 12.0 [6] (๐ฆฅ..๐ฆช) sloth..oyster +1F9AB..1F9AD ; Extended_Pictographic# NA [3] (๐ฆซ..๐ฆญ) <reserved-1F9AB>..<reserved-1F9AD> +1F9AE..1F9AF ; Extended_Pictographic# 12.0 [2] (๐ฆฎ..๐ฆฏ) guide dog..probing cane +1F9B0..1F9B9 ; Extended_Pictographic# 11.0 [10] (๐ฆฐ..๐ฆน) red hair..supervillain +1F9BA..1F9BF ; Extended_Pictographic# 12.0 [6] (๐ฆบ..๐ฆฟ) safety vest..mechanical leg 1F9C0 ; Extended_Pictographic# 8.0 [1] (๐ง) cheese wedge 1F9C1..1F9C2 ; Extended_Pictographic# 11.0 [2] (๐ง..๐ง) cupcake..salt -1F9C3..1F9CF ; Extended_Pictographic# NA [13] (๐ง๏ธ..๐ง๏ธ) <reserved-1F9C3>..<reserved-1F9CF> +1F9C3..1F9CA ; Extended_Pictographic# 12.0 [8] (๐ง..๐ง) beverage box..ice cube +1F9CB..1F9CC ; Extended_Pictographic# NA [2] (๐ง..๐ง) <reserved-1F9CB>..<reserved-1F9CC> +1F9CD..1F9CF ; Extended_Pictographic# 12.0 [3] (๐ง..๐ง) person standing..deaf person 1F9D0..1F9E6 ; Extended_Pictographic# 10.0 [23] (๐ง..๐งฆ) face with monocle..socks 1F9E7..1F9FF ; Extended_Pictographic# 11.0 [25] (๐งง..๐งฟ) red envelope..nazar amulet -1FA00..1FA5F ; Extended_Pictographic# NA [96] (๐จ๏ธ..๐ฉ๏ธ) <reserved-1FA00>..<reserved-1FA5F> -1FA60..1FA6D ; Extended_Pictographic# 11.0 [14] (๐ฉ ๏ธ..๐ฉญ๏ธ) XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER -1FA6E..1FFFD ; Extended_Pictographic# NA[1424] (๐ฉฎ๏ธ..๐ฟฝ๏ธ) <reserved-1FA6E>..<reserved-1FFFD> +1FA00..1FA53 ; Extended_Pictographic# 12.0 [84] (๐จ..๐ฉ) NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP +1FA54..1FA5F ; Extended_Pictographic# NA [12] (๐ฉ..๐ฉ) <reserved-1FA54>..<reserved-1FA5F> +1FA60..1FA6D ; Extended_Pictographic# 11.0 [14] (๐ฉ ..๐ฉญ) XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER +1FA6E..1FA6F ; Extended_Pictographic# NA [2] (๐ฉฎ..๐ฉฏ) <reserved-1FA6E>..<reserved-1FA6F> +1FA70..1FA73 ; Extended_Pictographic# 12.0 [4] (๐ฉฐ..๐ฉณ) ballet shoes..shorts +1FA74..1FA77 ; Extended_Pictographic# NA [4] (๐ฉด..๐ฉท) <reserved-1FA74>..<reserved-1FA77> +1FA78..1FA7A ; Extended_Pictographic# 12.0 [3] (๐ฉธ..๐ฉบ) drop of blood..stethoscope +1FA7B..1FA7F ; Extended_Pictographic# NA [5] (๐ฉป..๐ฉฟ) <reserved-1FA7B>..<reserved-1FA7F> +1FA80..1FA82 ; Extended_Pictographic# 12.0 [3] (๐ช..๐ช) yo-yo..parachute +1FA83..1FA8F ; Extended_Pictographic# NA [13] (๐ช..๐ช) <reserved-1FA83>..<reserved-1FA8F> +1FA90..1FA95 ; Extended_Pictographic# 12.0 [6] (๐ช..๐ช) ringed planet..banjo +1FA96..1FFFD ; Extended_Pictographic# NA[1384] (๐ช..๐ฟฝ) <reserved-1FA96>..<reserved-1FFFD> # Total elements: 3793 diff --git a/lib/stdlib/uc_spec/gen_unicode_mod.escript b/lib/stdlib/uc_spec/gen_unicode_mod.escript index de67b18afc..d820b9ed8e 100644 --- a/lib/stdlib/uc_spec/gen_unicode_mod.escript +++ b/lib/stdlib/uc_spec/gen_unicode_mod.escript @@ -191,7 +191,7 @@ gen_static(Fd) -> " {U,L} -> #{upper=>U,lower=>L,title=>U,fold=>L};\n" " {U,L,T,F} -> #{upper=>U,lower=>L,title=>T,fold=>F}\n" " end.\n\n"), - io:put_chars(Fd, "spec_version() -> {11,0}.\n\n\n"), + io:put_chars(Fd, "spec_version() -> {12,1}.\n\n\n"), io:put_chars(Fd, "class(Codepoint) -> {CCC,_,_} = unicode_table(Codepoint),\n CCC.\n\n"), io:put_chars(Fd, "-spec uppercase(unicode:chardata()) -> " "maybe_improper_list(gc(),unicode:chardata()).\n"), diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk index c2f586fef5..e2ed11a3d2 100644 --- a/lib/stdlib/vsn.mk +++ b/lib/stdlib/vsn.mk @@ -1 +1 @@ -STDLIB_VSN = 3.9.2 +STDLIB_VSN = 3.10 diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml index a2dd78f280..31b3e45016 100644 --- a/lib/syntax_tools/doc/src/notes.xml +++ b/lib/syntax_tools/doc/src/notes.xml @@ -32,6 +32,22 @@ <p>This document describes the changes made to the Syntax_Tools application.</p> +<section><title>Syntax_Tools 2.2.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> Add missing calls to <c>erl_syntax:unwrap/1</c>. The + nodes concerned represent names and values of maps and + map types. </p> + <p> + Own Id: OTP-16012 Aux Id: PR-2348 </p> + </item> + </list> + </section> + +</section> + <section><title>Syntax_Tools 2.2</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -60,6 +76,22 @@ </section> +<section><title>Syntax_Tools 2.1.7.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> Add missing calls to <c>erl_syntax:unwrap/1</c>. The + nodes concerned represent names and values of maps and + map types. </p> + <p> + Own Id: OTP-16012 Aux Id: PR-2348 </p> + </item> + </list> + </section> + +</section> + <section><title>Syntax_Tools 2.1.7</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -786,4 +818,3 @@ <p>Miscellaneous changes.</p> </section> </chapter> - diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk index 0ace11772d..9e6967d45d 100644 --- a/lib/syntax_tools/vsn.mk +++ b/lib/syntax_tools/vsn.mk @@ -1 +1 @@ -SYNTAX_TOOLS_VSN = 2.2 +SYNTAX_TOOLS_VSN = 2.2.1 diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml index 09ae5ef04a..c1e664b10f 100644 --- a/lib/tools/doc/src/notes.xml +++ b/lib/tools/doc/src/notes.xml @@ -31,6 +31,21 @@ </header> <p>This document describes the changes made to the Tools application.</p> +<section><title>Tools 3.2.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p><c>cover</c> would fail to start if two processes + tried to start it at the exact same time.</p> + <p> + Own Id: OTP-15813 Aux Id: ERL-943 </p> + </item> + </list> + </section> + +</section> + <section><title>Tools 3.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk index 191a458c62..022332e840 100644 --- a/lib/tools/vsn.mk +++ b/lib/tools/vsn.mk @@ -1 +1 @@ -TOOLS_VSN = 3.2 +TOOLS_VSN = 3.2.1 diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml index 0c3374091d..4de771d209 100644 --- a/lib/wx/doc/src/notes.xml +++ b/lib/wx/doc/src/notes.xml @@ -32,6 +32,22 @@ <p>This document describes the changes made to the wxErlang application.</p> +<section><title>Wx 1.8.9</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix a driver bug that could crashes when allocating + memory.</p> + <p> + Own Id: OTP-15883 Aux Id: PR-2261 </p> + </item> + </list> + </section> + +</section> + <section><title>Wx 1.8.8</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk index 91d15de3a9..ec07f7b691 100644 --- a/lib/wx/vsn.mk +++ b/lib/wx/vsn.mk @@ -1 +1 @@ -WX_VSN = 1.8.8 +WX_VSN = 1.8.9 diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml index 9fb4a430e5..4355b7114a 100644 --- a/lib/xmerl/doc/src/notes.xml +++ b/lib/xmerl/doc/src/notes.xml @@ -32,6 +32,23 @@ <p>This document describes the changes made to the Xmerl application.</p> +<section><title>Xmerl 1.3.22</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + <c>xmerl_sax_parser</c> crashed during charset detection + when the xml declarations attribute values was missing + the closing quotation (' or ").</p> + <p> + Own Id: OTP-15826</p> + </item> + </list> + </section> + +</section> + <section><title>Xmerl 1.3.21</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk index 08696606e6..fc73964773 100644 --- a/lib/xmerl/vsn.mk +++ b/lib/xmerl/vsn.mk @@ -1 +1 @@ -XMERL_VSN = 1.3.21 +XMERL_VSN = 1.3.22 diff --git a/make/otp_patch_solve_forward_merge_version b/make/otp_patch_solve_forward_merge_version index b4de394767..48082f72f0 100644 --- a/make/otp_patch_solve_forward_merge_version +++ b/make/otp_patch_solve_forward_merge_version @@ -1 +1 @@ -11 +12 diff --git a/make/otp_version_tickets_in_merge b/make/otp_version_tickets_in_merge index e69de29bb2..a8bd952e0e 100644 --- a/make/otp_version_tickets_in_merge +++ b/make/otp_version_tickets_in_merge @@ -0,0 +1,125 @@ +OTP-10400 +OTP-13872 +OTP-15328 +OTP-15330 +OTP-15331 +OTP-15332 +OTP-15344 +OTP-15370 +OTP-15395 +OTP-15422 +OTP-15431 +OTP-15510 +OTP-15566 +OTP-15731 +OTP-15738 +OTP-15747 +OTP-15764 +OTP-15765 +OTP-15778 +OTP-15789 +OTP-15807 +OTP-15813 +OTP-15814 +OTP-15817 +OTP-15818 +OTP-15820 +OTP-15822 +OTP-15823 +OTP-15826 +OTP-15827 +OTP-15830 +OTP-15831 +OTP-15833 +OTP-15836 +OTP-15843 +OTP-15849 +OTP-15850 +OTP-15851 +OTP-15852 +OTP-15853 +OTP-15854 +OTP-15858 +OTP-15859 +OTP-15863 +OTP-15869 +OTP-15870 +OTP-15874 +OTP-15876 +OTP-15880 +OTP-15881 +OTP-15882 +OTP-15883 +OTP-15884 +OTP-15889 +OTP-15893 +OTP-15897 +OTP-15901 +OTP-15904 +OTP-15905 +OTP-15906 +OTP-15911 +OTP-15916 +OTP-15917 +OTP-15918 +OTP-15923 +OTP-15924 +OTP-15926 +OTP-15927 +OTP-15928 +OTP-15929 +OTP-15931 +OTP-15932 +OTP-15933 +OTP-15934 +OTP-15935 +OTP-15942 +OTP-15954 +OTP-15955 +OTP-15958 +OTP-15959 +OTP-15962 +OTP-15963 +OTP-15966 +OTP-15968 +OTP-15969 +OTP-15970 +OTP-15971 +OTP-15974 +OTP-15975 +OTP-15977 +OTP-15978 +OTP-15979 +OTP-15980 +OTP-15982 +OTP-15983 +OTP-15984 +OTP-15985 +OTP-15987 +OTP-15992 +OTP-15996 +OTP-15997 +OTP-16000 +OTP-16001 +OTP-16002 +OTP-16006 +OTP-16012 +OTP-16022 +OTP-16023 +OTP-16027 +OTP-16028 +OTP-16032 +OTP-16035 +OTP-16036 +OTP-16037 +OTP-16038 +OTP-16040 +OTP-16041 +OTP-16042 +OTP-16044 +OTP-16049 +OTP-16050 +OTP-16051 +OTP-16056 +OTP-16058 +OTP-16060 diff --git a/otp_versions.table b/otp_versions.table index 47b95b7ee1..d55b21470d 100644 --- a/otp_versions.table +++ b/otp_versions.table @@ -1,3 +1,4 @@ +OTP-22.1 : common_test-1.18 compiler-7.4.5 crypto-4.6 dialyzer-4.1 erl_docgen-0.10 erl_interface-3.13 erts-10.5 eunit-2.3.8 ftp-1.0.3 inets-7.1 jinterface-1.10.1 kernel-6.5 megaco-3.18.6 mnesia-4.16.1 observer-2.9.2 os_mon-2.5.1 public_key-1.7 runtime_tools-1.14 sasl-3.4.1 snmp-5.4 ssh-4.8 ssl-9.4 stdlib-3.10 syntax_tools-2.2.1 tools-3.2.1 wx-1.8.9 xmerl-1.3.22 # asn1-5.0.9 debugger-4.2.7 diameter-2.2.1 edoc-0.11 eldap-1.2.8 et-1.6.4 hipe-3.19.1 odbc-2.12.4 parsetools-2.1.8 reltool-0.8 tftp-1.0.1 : OTP-22.0.7 : compiler-7.4.4 # asn1-5.0.9 common_test-1.17.3 crypto-4.5.1 debugger-4.2.7 dialyzer-4.0.3 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 erts-10.4.4 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.19.1 inets-7.0.9 jinterface-1.10 kernel-6.4.1 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 ssl-9.3.5 stdlib-3.9.2 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 : OTP-22.0.6 : compiler-7.4.3 dialyzer-4.0.3 hipe-3.19.1 ssl-9.3.5 # asn1-5.0.9 common_test-1.17.3 crypto-4.5.1 debugger-4.2.7 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 erts-10.4.4 et-1.6.4 eunit-2.3.7 ftp-1.0.2 inets-7.0.9 jinterface-1.10 kernel-6.4.1 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 stdlib-3.9.2 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 : OTP-22.0.5 : dialyzer-4.0.2 erts-10.4.4 inets-7.0.9 ssl-9.3.4 # asn1-5.0.9 common_test-1.17.3 compiler-7.4.2 crypto-4.5.1 debugger-4.2.7 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.19 jinterface-1.10 kernel-6.4.1 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 stdlib-3.9.2 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 : @@ -6,6 +7,7 @@ OTP-22.0.3 : compiler-7.4.2 dialyzer-4.0.1 erts-10.4.2 ssl-9.3.2 stdlib-3.9.2 # OTP-22.0.2 : compiler-7.4.1 crypto-4.5.1 erts-10.4.1 stdlib-3.9.1 # asn1-5.0.9 common_test-1.17.3 debugger-4.2.7 dialyzer-4.0 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.19 inets-7.0.8 jinterface-1.10 kernel-6.4 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 ssl-9.3.1 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 : OTP-22.0.1 : ssl-9.3.1 # asn1-5.0.9 common_test-1.17.3 compiler-7.4 crypto-4.5 debugger-4.2.7 dialyzer-4.0 diameter-2.2.1 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 erts-10.4 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.19 inets-7.0.8 jinterface-1.10 kernel-6.4 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 parsetools-2.1.8 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 stdlib-3.9 syntax_tools-2.2 tftp-1.0.1 tools-3.2 wx-1.8.8 xmerl-1.3.21 : OTP-22.0 : asn1-5.0.9 common_test-1.17.3 compiler-7.4 crypto-4.5 debugger-4.2.7 dialyzer-4.0 edoc-0.11 eldap-1.2.8 erl_docgen-0.9.1 erl_interface-3.12 erts-10.4 hipe-3.19 inets-7.0.8 jinterface-1.10 kernel-6.4 megaco-3.18.5 mnesia-4.16 observer-2.9.1 odbc-2.12.4 os_mon-2.5 public_key-1.6.7 reltool-0.8 runtime_tools-1.13.3 sasl-3.4 snmp-5.3 ssh-4.7.7 ssl-9.3 stdlib-3.9 syntax_tools-2.2 tools-3.2 wx-1.8.8 xmerl-1.3.21 # diameter-2.2.1 et-1.6.4 eunit-2.3.7 ftp-1.0.2 parsetools-2.1.8 tftp-1.0.1 : +OTP-21.3.8.7 : erts-10.3.5.5 inets-7.0.7.1 kernel-6.3.1.3 ssh-4.7.6.1 syntax_tools-2.1.7.1 # asn1-5.0.8 common_test-1.17.2.1 compiler-7.3.2 crypto-4.4.2 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.18.3 jinterface-1.9.1 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.6.1 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssl-9.2.3.5 stdlib-3.8.2.2 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 xmerl-1.3.20.1 : OTP-21.3.8.6 : ssl-9.2.3.5 # asn1-5.0.8 common_test-1.17.2.1 compiler-7.3.2 crypto-4.4.2 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 erts-10.3.5.4 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.18.3 inets-7.0.7 jinterface-1.9.1 kernel-6.3.1.2 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.6.1 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssh-4.7.6 stdlib-3.8.2.2 syntax_tools-2.1.7 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 xmerl-1.3.20.1 : OTP-21.3.8.5 : erts-10.3.5.4 ssl-9.2.3.4 # asn1-5.0.8 common_test-1.17.2.1 compiler-7.3.2 crypto-4.4.2 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.18.3 inets-7.0.7 jinterface-1.9.1 kernel-6.3.1.2 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 public_key-1.6.6.1 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssh-4.7.6 stdlib-3.8.2.2 syntax_tools-2.1.7 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 xmerl-1.3.20.1 : OTP-21.3.8.4 : common_test-1.17.2.1 erts-10.3.5.3 kernel-6.3.1.2 public_key-1.6.6.1 ssl-9.2.3.3 stdlib-3.8.2.2 # asn1-5.0.8 compiler-7.3.2 crypto-4.4.2 debugger-4.2.6 dialyzer-3.3.2 diameter-2.2.1 edoc-0.10 eldap-1.2.7 erl_docgen-0.9 erl_interface-3.11.3 et-1.6.4 eunit-2.3.7 ftp-1.0.2 hipe-3.18.3 inets-7.0.7 jinterface-1.9.1 megaco-3.18.4 mnesia-4.15.6 observer-2.9 odbc-2.12.3 os_mon-2.4.7 otp_mibs-1.2.1 parsetools-2.1.8 reltool-0.7.8 runtime_tools-1.13.2 sasl-3.3 snmp-5.2.12 ssh-4.7.6 syntax_tools-2.1.7 tftp-1.0.1 tools-3.1.0.1 wx-1.8.7 xmerl-1.3.20.1 : |