diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/doc/src/erl_ext_dist.xml | 29 | ||||
-rw-r--r-- | erts/doc/src/escript.xml | 23 | ||||
-rw-r--r-- | erts/doc/src/time_correction.xml | 4 | ||||
-rw-r--r-- | erts/emulator/Makefile.in | 20 | ||||
-rw-r--r-- | erts/emulator/beam/dist.h | 6 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db_tree.c | 4 | ||||
-rw-r--r-- | erts/emulator/beam/external.c | 55 | ||||
-rw-r--r-- | erts/emulator/beam/ops.tab | 3 | ||||
-rw-r--r-- | erts/emulator/beam/utils.c | 6 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_bif0.c | 39 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_bif0.tab | 3 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_x86_signal.c | 6 | ||||
-rw-r--r-- | erts/emulator/test/map_SUITE.erl | 38 | ||||
-rw-r--r-- | erts/emulator/test/nif_SUITE_data/nif_mod.c | 3 |
14 files changed, 157 insertions, 82 deletions
diff --git a/erts/doc/src/erl_ext_dist.xml b/erts/doc/src/erl_ext_dist.xml index f91ed78122..fa083db4c7 100644 --- a/erts/doc/src/erl_ext_dist.xml +++ b/erts/doc/src/erl_ext_dist.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>2007</year> - <year>2013</year> + <year>2014</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -573,6 +573,33 @@ </section> <section> + <marker id="MAP_EXT"/> + <title>MAP_EXT</title> + + <table align="left"> + <row> + <cell align="center">1</cell> + <cell align="center">4</cell> + <cell align="center">N</cell> + </row> + <row> + <cell align="center">116</cell> + <cell align="center">Arity</cell> + <cell align="center">Pairs</cell> + </row> + <tcaption></tcaption></table> + <p> + <c>MAP_EXT</c> encodes a map. The <c>Arity</c> field is an unsigned + 4 byte integer in big endian format that determines the number of + key-value pairs in the map. Key and value pairs (<c>Ki => Vi</c>) + are encoded in the <c>Pairs</c> section in the following order: + <c>K1, V1, K2, V2,..., Kn, Vn</c>. + Duplicate keys are <em>not allowed</em> within the same map. + </p> + <p><em>Since: </em>OTP 17.0</p> + </section> + + <section> <marker id="NIL_EXT"/> <title>NIL_EXT</title> diff --git a/erts/doc/src/escript.xml b/erts/doc/src/escript.xml index d2b09d4515..1abbdb2180 100644 --- a/erts/doc/src/escript.xml +++ b/erts/doc/src/escript.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>2007</year><year>2013</year> + <year>2007</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -92,6 +92,18 @@ $ <input>escript factorial 5</input> </pre> marker="stdlib:epp#encoding">encoding</seealso> it can be located on the second line.</p> + <note><p> + The encoding specified by the above mentioned comment + applies to the script itself. The encoding of the + I/O-server, however, has to be set explicitly like this: +<code>io:setopts([{encoding, unicode}])</code></p> + <p>The default encoding of the I/O-server for <c>standard_io</c> + is <c>latin1</c> + since the script runs in a non-interactive terminal + (see <seealso marker="stdlib:unicode_usage#unicode_options_summary"> + Using Unicode in Erlang</seealso>). + </p></note> + <p>On the third line (or second line depending on the presence of the Emacs directive), it is possible to give arguments to the emulator, such as </p> @@ -141,8 +153,9 @@ halt(1).</pre> -include_lib("kernel/include/file.hrl").</pre> <p>to include the record definitions for the records used by the <c>file:read_link_info/1</c> function. You can also select - encoding here, but if there is a valid encoding comment on - the second line it takes precedence.</p> + encoding by including a encoding comment here, but if there + is a valid encoding comment on the second line it takes + precedence.</p> <p>The script will be checked for syntactic and semantic correctness before being run. If there are warnings (such as @@ -163,7 +176,7 @@ halt(1).</pre> If much of the execution takes place in interpreted code it may be worthwhile to compile it, even though the compilation itself will take a little while. It is also possible to supply - <c>native</c> instead of compile, this will compile the script + <c>native</c> instead of <c>compile</c>, this will compile the script using the native flag, again depending on the characteristics of the escript this could or could not be worth while.</p> @@ -239,7 +252,7 @@ factorial 5 = 120 can either be returned as a binary or written to file.</p> <p>As an example of how the function can be used, we create an - interpreted escript which uses emu_args to set some emulator + interpreted escript which uses <c>emu_args</c> to set some emulator flag. In this case it happens to disable the smp_support. We do also extract the different sections from the newly created script:</p> diff --git a/erts/doc/src/time_correction.xml b/erts/doc/src/time_correction.xml index d52cc7f3e2..7f7c28fc30 100644 --- a/erts/doc/src/time_correction.xml +++ b/erts/doc/src/time_correction.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="utf8" ?> +<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> - <year>1999</year><year>2013</year> + <year>1999</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 523130d01a..2a9a0a5c2f 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -414,13 +414,6 @@ else UNIX_ONLY_BUILDS = endif -ifeq ($(TARGET), win32) -TMPVAR := $(shell LANG=C $(PERL) utils/make_compiler_flags -o $(TTF_DIR)/erl_compile_flags.h -v CONFIG_H "N/A" -v CFLAGS "$(CFLAGS)" -v LDFLAGS "$(LDFLAGS)") -else -# We force this to be run every time this makefile is executed -TMPVAR := $(shell LANG=C $(PERL) utils/make_compiler_flags -o $(TTF_DIR)/erl_compile_flags.h -f CONFIG_H "$(ERL_TOP)/erts/$(TARGET)/config.h" -v CFLAGS "$(CFLAGS)" -v LDFLAGS "$(LDFLAGS)") -endif - .PHONY: all ifdef VOID_EMULATOR all: @@ -499,6 +492,15 @@ release_docs_spec: _create_dirs := $(shell mkdir -p $(CREATE_DIRS)) + +# has to be run after _create_dirs +ifeq ($(TARGET), win32) +TMPVAR := $(shell LANG=C $(PERL) utils/make_compiler_flags -o $(TTF_DIR)/erl_compile_flags.h -v CONFIG_H "N/A" -v CFLAGS "$(CFLAGS)" -v LDFLAGS "$(LDFLAGS)") +else +# We force this to be run every time this makefile is executed +TMPVAR := $(shell LANG=C $(PERL) utils/make_compiler_flags -o $(TTF_DIR)/erl_compile_flags.h -f CONFIG_H "$(ERL_TOP)/erts/$(TARGET)/config.h" -v CFLAGS "$(CFLAGS)" -v LDFLAGS "$(LDFLAGS)") +endif + GENERATE = HIPE_ASM = @@ -1087,7 +1089,9 @@ BEAM_SRC=$(wildcard beam/*.c) DRV_COMMON_SRC=$(wildcard drivers/common/*.c) DRV_OSTYPE_SRC=$(wildcard drivers/$(ERLANG_OSTYPE)/*.c) ALL_SYS_SRC=$(wildcard sys/$(ERLANG_OSTYPE)/*.c) $(wildcard sys/common/*.c) -TARGET_SRC=$(wildcard $(TARGET)/*.c) $(wildcard $(TTF_DIR)/*.c) +# We use $(shell ls) here instead of wildcard as $(wildcard ) resolved at +# loadtime of the makefile and at that time these files are not generated yet. +TARGET_SRC=$(shell ls $(TARGET)/*.c) $(shell ls $(TTF_DIR)/*.c) # I do not want the -MG flag on windows, it does not work properly for a # windows build. diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h index 0519a9225e..f32b999198 100644 --- a/erts/emulator/beam/dist.h +++ b/erts/emulator/beam/dist.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * Copyright Ericsson AB 1996-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -40,6 +40,7 @@ #define DFLAG_SMALL_ATOM_TAGS 0x4000 #define DFLAG_INTERNAL_TAGS 0x8000 #define DFLAG_UTF8_ATOMS 0x10000 +#define DFLAG_MAP_TAG 0x20000 /* All flags that should be enabled when term_to_binary/1 is used. */ #define TERM_TO_BINARY_DFLAGS (DFLAG_EXTENDED_REFERENCES \ @@ -47,7 +48,8 @@ | DFLAG_NEW_FLOATS \ | DFLAG_EXTENDED_PIDS_PORTS \ | DFLAG_EXPORT_PTR_TAG \ - | DFLAG_BIT_BINARIES) + | DFLAG_BIT_BINARIES \ + | DFLAG_MAP_TAG) /* opcodes used in distribution messages */ #define DOP_LINK 1 diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index 25029ba90f..a62a83a928 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -485,7 +485,7 @@ static int db_first_tree(Process *p, DbTable *tbl, Eterm *ret) *ret = am_EOT; return DB_ERROR_NONE; } - /* Walk down to the tree to the left */ + /* Walk down the tree to the left */ if ((stack = get_static_stack(tb)) != NULL) { stack->pos = stack->slot = 0; } @@ -531,7 +531,7 @@ static int db_last_tree(Process *p, DbTable *tbl, Eterm *ret) *ret = am_EOT; return DB_ERROR_NONE; } - /* Walk down to the tree to the left */ + /* Walk down the tree to the right */ if ((stack = get_static_stack(tb)) != NULL) { stack->pos = stack->slot = 0; } diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 9671cde228..656de7c49a 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -2562,29 +2562,25 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, { map_t *mp = (map_t*)map_val(obj); Uint size = map_get_size(mp); - Eterm *mptr; *ep++ = MAP_EXT; put_int32(size, ep); ep += 4; - /* Push values first */ if (size > 0) { - mptr = map_get_values(mp); + Eterm *kptr = map_get_keys(mp); + Eterm *vptr = map_get_values(mp); + for (i = size-1; i >= 1; i--) { WSTACK_PUSH(s, ENC_TERM); - WSTACK_PUSH(s, (UWord) mptr[i]); + WSTACK_PUSH(s, (UWord) vptr[i]); + WSTACK_PUSH(s, ENC_TERM); + WSTACK_PUSH(s, (UWord) kptr[i]); } WSTACK_PUSH(s, ENC_TERM); - WSTACK_PUSH(s, (UWord) mptr[0]); - - mptr = map_get_keys(mp); - for (i = size-1; i >= 1; i--) { - WSTACK_PUSH(s, ENC_TERM); - WSTACK_PUSH(s, (UWord) mptr[i]); - } + WSTACK_PUSH(s, (UWord) vptr[0]); - obj = mptr[0]; + obj = kptr[0]; goto L_jump_start; } } @@ -3518,16 +3514,16 @@ dec_term_atom_common: keys = make_tuple(hp); *hp++ = make_arityval(size); - kptr = hp; hp += size; + kptr = hp - 1; mp = (map_t*)hp; hp += MAP_HEADER_SIZE; - vptr = hp; hp += size; + vptr = hp - 1; - /* kptr, first word for keys - * vptr, first word for values + /* kptr, last word for keys + * vptr, last word for values */ /* @@ -3542,27 +3538,12 @@ dec_term_atom_common: mp->keys = keys; *objp = make_map(mp); - /* We assume the map is wellformed, meaning: - * - ascending key order - * - unique keys - */ - - objp = vptr + size - 1; - n = size; - - while (n-- > 0) { - *objp = (Eterm) COMPRESS_POINTER(next); - next = objp; - objp--; - } - - objp = kptr + size - 1; - n = size; - - while (n-- > 0) { - *objp = (Eterm) COMPRESS_POINTER(next); - next = objp; - objp--; + for (n = size; n; n--) { + *vptr = (Eterm) COMPRESS_POINTER(next); + *kptr = (Eterm) COMPRESS_POINTER(vptr); + next = kptr; + vptr--; + kptr--; } } break; diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab index 73630fda8e..68fcc177ae 100644 --- a/erts/emulator/beam/ops.tab +++ b/erts/emulator/beam/ops.tab @@ -1484,7 +1484,8 @@ new_map j d I I update_map_assoc j s d I I update_map_exact j s d I I -is_map Fail cq => jump Fail +is_map Fail Literal=q => move Literal x | is_map Fail x +is_map Fail c => jump Fail %macro: is_map IsMap -fail_action is_map f r diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index 5b43d25e3c..738f793020 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -2125,7 +2125,11 @@ tailrecur_ne: if (!is_boxed(b) || *boxed_val_rel(b,b_base) != *aa) goto not_equal; bb = map_val_rel(b,b_base); - if ((sz = map_get_size((map_t*)aa)) == 0) goto pop_next; + sz = map_get_size((map_t*)aa); + + if (sz != map_get_size((map_t*)bb)) goto not_equal; + if (sz == 0) goto pop_next; + aa += 2; bb += 2; sz += 1; /* increment for tuple-keys */ diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c index fa99c817f0..2497d51df1 100644 --- a/erts/emulator/hipe/hipe_bif0.c +++ b/erts/emulator/hipe/hipe_bif0.c @@ -1101,9 +1101,9 @@ BIF_RETTYPE hipe_bifs_make_fun_3(BIF_ALIST_3) #endif /* - * args: Nativecodeaddress, Module, {Uniq, Index, BeamAddress} + * args: Module, {Uniq, Index, BeamAddress} */ -BIF_RETTYPE hipe_bifs_make_fe_3(BIF_ALIST_3) +BIF_RETTYPE hipe_bifs_get_fe_2(BIF_ALIST_2) { Eterm mod; Uint index; @@ -1111,20 +1111,15 @@ BIF_RETTYPE hipe_bifs_make_fe_3(BIF_ALIST_3) void *beam_address; ErlFunEntry *fe; Eterm *tp; - void *native_address; - - native_address = term_to_address(BIF_ARG_1); - if (!native_address) - BIF_ERROR(BIF_P, BADARG); - if (is_not_atom(BIF_ARG_2)) + if (is_not_atom(BIF_ARG_1)) BIF_ERROR(BIF_P, BADARG); - mod = BIF_ARG_2; + mod = BIF_ARG_1; - if (is_not_tuple(BIF_ARG_3) || - (arityval(*tuple_val(BIF_ARG_3)) != 3)) + if (is_not_tuple(BIF_ARG_2) || + (arityval(*tuple_val(BIF_ARG_2)) != 3)) BIF_ERROR(BIF_P, BADARG); - tp = tuple_val(BIF_ARG_3); + tp = tuple_val(BIF_ARG_2); if (term_to_Uint(tp[1], &uniq) == 0) BIF_ERROR(BIF_P, BADARG); if (term_to_Uint(tp[2], &index) == 0) @@ -1144,10 +1139,28 @@ BIF_RETTYPE hipe_bifs_make_fe_3(BIF_ALIST_3) printf("no fun entry for %s %ld:%ld\n", atom_buf, uniq, index); BIF_ERROR(BIF_P, BADARG); } + BIF_RET(address_to_term((void *)fe, BIF_P)); +} + +/* + * args: FE, Nativecodeaddress + */ +BIF_RETTYPE hipe_bifs_set_native_address_in_fe_2(BIF_ALIST_2) +{ + ErlFunEntry *fe; + void *native_address; + + fe = (ErlFunEntry *)term_to_address(BIF_ARG_1); + if (!fe) + BIF_ERROR(BIF_P, BADARG); + native_address = term_to_address(BIF_ARG_2); + if (!native_address) + BIF_ERROR(BIF_P, BADARG); + fe->native_address = native_address; if (erts_refc_dectest(&fe->refc, 0) == 0) erts_erase_fun_entry(fe); - BIF_RET(address_to_term((void *)fe, BIF_P)); + BIF_RET(am_true); } #if 0 /* XXX: unused */ diff --git a/erts/emulator/hipe/hipe_bif0.tab b/erts/emulator/hipe/hipe_bif0.tab index ce641365e9..2514b1c3a5 100644 --- a/erts/emulator/hipe/hipe_bif0.tab +++ b/erts/emulator/hipe/hipe_bif0.tab @@ -69,7 +69,8 @@ bif hipe_bifs:atom_to_word/1 bif hipe_bifs:term_to_word/1 #bif hipe_bifs:make_fun/3 -bif hipe_bifs:make_fe/3 +bif hipe_bifs:get_fe/2 +bif hipe_bifs:set_native_address_in_fe/2 #bif hipe_bifs:make_native_stub/2 bif hipe_bifs:find_na_or_make_stub/2 diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c index 8f997aafab..f5668013e2 100644 --- a/erts/emulator/hipe/hipe_x86_signal.c +++ b/erts/emulator/hipe/hipe_x86_signal.c @@ -2,7 +2,7 @@ * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * Copyright Ericsson AB 2001-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -304,7 +304,9 @@ static void hipe_sigaltstack(void *ss_sp) */ void hipe_thread_signal_init(void) { - hipe_sigaltstack(erts_alloc(ERTS_ALC_T_HIPE, SIGSTKSZ)); + /* Stack don't really need to be cache aligned. + We use it to suppress false leak report from valgrind */ + hipe_sigaltstack(erts_alloc_permanent_cache_aligned(ERTS_ALC_T_HIPE, SIGSTKSZ)); } #endif diff --git a/erts/emulator/test/map_SUITE.erl b/erts/emulator/test/map_SUITE.erl index 8cc5621181..888ed8e272 100644 --- a/erts/emulator/test/map_SUITE.erl +++ b/erts/emulator/test/map_SUITE.erl @@ -29,6 +29,7 @@ t_guard_receive/1, t_guard_fun/1, t_list_comprehension/1, t_map_sort_literals/1, + t_map_equal/1, %t_size/1, t_map_size/1, @@ -74,6 +75,7 @@ all() -> [ t_update_assoc,t_update_exact, t_guard_bifs, t_guard_sequence, t_guard_update, t_guard_receive,t_guard_fun, t_list_comprehension, + t_map_equal, t_map_sort_literals, %% Specific Map BIFs @@ -450,6 +452,23 @@ t_map_sort_literals(Config) when is_list(Config) -> ok. +t_map_equal(Config) when is_list(Config) -> + true = id(#{}) =:= id(#{}), + false = id(#{}) =:= id(#{a=>1}), + false = id(#{a=>1}) =:= id(#{}), + true = id(#{ "a" => "hi", b => 134 }) =:= id(#{ b => 134,"a" => "hi"}), + + false = id(#{ a => 1 }) =:= id(#{ a => 2}), + false = id(#{ a => 2 }) =:= id(#{ a => 1}), + false = id(#{ a => 2, b => 1 }) =:= id(#{ a => 1, b => 3}), + false = id(#{ a => 1, b => 1 }) =:= id(#{ a => 1, b => 3}), + + true = id(#{ a => 1 }) =:= id(#{ a => 1}), + true = id(#{ "a" => 2 }) =:= id(#{ "a" => 2}), + true = id(#{ "a" => 2, b => 3 }) =:= id(#{ "a" => 2, b => 3}), + true = id(#{ a => 1, b => 3, c => <<"wat">> }) =:= id(#{ a => 1, b => 3, c=><<"wat">>}), + ok. + %% BIFs t_bif_map_get(Config) when is_list(Config) -> @@ -794,16 +813,16 @@ t_map_encode_decode(Config) when is_list(Config) -> %% literally #{ b=>2, a=>1 } in the internal order #{ a:=1, b:=2 } = - erlang:binary_to_term(<<131,116,0,0,0,2,100,0,1,98,100,0,1,97,97,2,97,1>>), + erlang:binary_to_term(<<131,116,0,0,0,2,100,0,1,98,97,2,100,0,1,97,97,1>>), %% literally #{ "hi" => "value", a=>33, b=>55 } in the internal order #{ a:=33, b:=55, "hi" := "value"} = erlang:binary_to_term(<<131,116,0,0,0,3, 107,0,2,104,105, % "hi" :: list() - 100,0,1,97, % a :: atom() - 100,0,1,98, % b :: atom() 107,0,5,118,97,108,117,101, % "value" :: list() + 100,0,1,97, % a :: atom() 97,33, % 33 :: integer() + 100,0,1,98, % b :: atom() 97,55 % 55 :: integer() >>), @@ -815,11 +834,17 @@ t_map_encode_decode(Config) when is_list(Config) -> %% uniqueness violation %% literally #{ a=>1, "hi"=>"value", a=>2 } {'EXIT',{badarg,[{_,_,_,_}|_]}} = (catch - erlang:binary_to_term(<<131,116,0,0,0,3,100,0,1,97,107,0,2,104,105,100,0,1,97,97,1,107,0,5,118,97,108,117,101,97,2>>)), + erlang:binary_to_term(<<131,116,0,0,0,3, + 100,0,1,97, + 97,1, + 107,0,2,104,105, + 107,0,5,118,97,108,117,101, + 100,0,1,97, + 97,2>>)), %% bad size (too large) {'EXIT',{badarg,[{_,_,_,_}|_]}} = (catch - erlang:binary_to_term(<<131,116,0,0,0,12,100,0,1,97,100,0,1,98,97,1,97,1>>)), + erlang:binary_to_term(<<131,116,0,0,0,12,100,0,1,97,97,1,100,0,1,98,97,1>>)), %% bad size (too small) .. should fail just truncate it .. weird. %% possibly change external format so truncated will be #{a:=1} @@ -833,7 +858,8 @@ map_encode_decode_and_match([{K,V}|Pairs], EncodedPairs, M0) -> B0 = erlang:term_to_binary(M1), Ls = lists:sort(fun(A,B) -> erts_internal:cmp_term(A,B) < 0 end, [{K, erlang:term_to_binary(K), erlang:term_to_binary(V)}|EncodedPairs]), %% sort Ks and Vs according to term spec, then match it - ok = match_encoded_map(B0, length(Ls), [Kbin||{_,Kbin,_}<-Ls] ++ [Vbin||{_,_,Vbin}<-Ls]), + KVbins = lists:foldr(fun({_,Kbin,Vbin}, Acc) -> [Kbin,Vbin | Acc] end, [], Ls), + ok = match_encoded_map(B0, length(Ls), KVbins), %% decode and match it M1 = erlang:binary_to_term(B0), map_encode_decode_and_match(Pairs,Ls,M1); diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.c b/erts/emulator/test/nif_SUITE_data/nif_mod.c index 55a0d2ac4f..11b5d0cc35 100644 --- a/erts/emulator/test/nif_SUITE_data/nif_mod.c +++ b/erts/emulator/test/nif_SUITE_data/nif_mod.c @@ -217,7 +217,8 @@ static int upgrade(ErlNifEnv* env, void** priv, void** old_priv_data, ERL_NIF_TE *priv = *old_priv_data; do_load_info(env, load_info, &retval); - + if (retval) + NifModPrivData_release(data); return retval; } |