From 8e5e66b66cf318722e5b128c1b690fa2d080f1db Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Fri, 12 Sep 2014 16:31:24 +0200 Subject: Fix ?MODULE in preprocessed dictionary forms By replacing literal diameter_gen_relay atoms in forms extracted from that module by the name of the module in question. This has been wrong for some time, but only became noticable when the parent commit started using ?MODULE as more than a process dictionary key or tag to match on. In particular, the function dict/1 in diameter_gen.hrl (included by every dictionary module) can now return ?MODULE, which is (not surprisingly) expected to be the name of the dictionary module in question. It wasn't in the case of a module compiled from forms: it was diameter_gen_relay, since that's the module the forms were extracted from. The fix only affects dictionaries compiled from forms, as returned by diameter_make:codec/2. In particular, dictionaries compiled from Erlang source returned by this function, or by diameterc(1), are unaffected. --- lib/diameter/src/compiler/diameter_codegen.erl | 33 ++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/lib/diameter/src/compiler/diameter_codegen.erl b/lib/diameter/src/compiler/diameter_codegen.erl index 5a068c1a25..d91a776321 100644 --- a/lib/diameter/src/compiler/diameter_codegen.erl +++ b/lib/diameter/src/compiler/diameter_codegen.erl @@ -132,7 +132,7 @@ gen(parse, ParseD, _Mod) -> [?VERSION | ParseD]; gen(forms, ParseD, Mod) -> - pp(erl_forms(Mod, ParseD)); + preprocess(Mod, erl_forms(Mod, ParseD)); gen(hrl, ParseD, Mod) -> gen_hrl(Mod, ParseD); @@ -838,19 +838,19 @@ rec_name(Name, Prefix) -> Prefix ++ Name. %% =========================================================================== -%% pp/1 +%% preprocess/2 %% %% Preprocess forms as generated by 'forms' option. In particular, %% replace the include_lib attributes in generated forms by the %% corresponding forms, extracting the latter from an existing %% dictionary (diameter_gen_relay). The resulting forms can be %% compiled to beam using compile:forms/2 (which does no preprocessing -%% or it's own; DiY currently appears to be the only way to preprocess +%% of it's own; DiY currently appears to be the only way to preprocess %% a forms list). -pp(Forms) -> +preprocess(Mod, Forms) -> {_, Beam, _} = code:get_object_code(diameter_gen_relay), - pp(Forms, abstract_code(Beam)). + pp(Forms, remod(Mod, abstract_code(Beam))). pp(Forms, {ok, Code}) -> Files = files(Code, []), @@ -859,6 +859,25 @@ pp(Forms, {ok, Code}) -> pp(Forms, {error, Reason}) -> erlang:error({forms, Reason, Forms}). +%% Replace literal diameter_gen_relay atoms in the extracted forms. +%% ?MODULE for example. + +remod(Mod, L) + when is_list(L) -> + [remod(Mod, T) || T <- L]; + +remod(Mod, {atom, _, diameter_gen_relay} = T) -> + setelement(3, T, Mod); + +remod(Mod, T) + when is_tuple(T) -> + list_to_tuple(remod(Mod, tuple_to_list(T))); + +remod(_, T) -> + T. + +%% Replace include_lib by the corresponding forms. + include({attribute, _, include_lib, Path}, Files) -> Inc = filename:basename(Path), [{Inc, Forms}] = [T || {F, _} = T <- Files, F == Inc], %% expect one @@ -867,6 +886,8 @@ include({attribute, _, include_lib, Path}, Files) -> include(T, _) -> [T]. +%% Extract abstract code. + abstract_code(Beam) -> case beam_lib:chunks(Beam, [abstract_code]) of {ok, {_Mod, [{abstract_code, {_Vsn, Code}}]}} -> @@ -877,6 +898,8 @@ abstract_code(Beam) -> {E, Reason} end. +%% Extract filename/forms pairs for included forms. + files([{attribute, _, file, {Path, _}} | T], Acc) -> {Body, Rest} = lists:splitwith(fun({attribute, _, file, _}) -> false; (_) -> true -- cgit v1.2.3 From 99c1df966b7065345b711086a2286b85d477869b Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Sun, 14 Sep 2014 08:12:37 +0200 Subject: Add recompilation admonition to 17.2 release notes That dictionaries need to be recompiled, which is the case whenever diameter_gen.hrl is modified. --- lib/diameter/doc/src/notes.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/diameter/doc/src/notes.xml b/lib/diameter/doc/src/notes.xml index d89e1dfd26..b3cd53c497 100644 --- a/lib/diameter/doc/src/notes.xml +++ b/lib/diameter/doc/src/notes.xml @@ -113,6 +113,9 @@ first.

answer message as a consequence of other errors (eg. M-bit, resulting in 5001) failed if the AVP contained a complete header.

+

+ Dictionary files must be recompiled for the fix to have + effect.

Own Id: OTP-11946

@@ -151,6 +154,9 @@ first.

fail. Component AVPs are now decoded if possible, otherwise not. AVPs of type Grouped are decoded as much as possible, as deeply as possible.

+

+ Dictionary files must be recompiled for the fix to have + effect.

Own Id: OTP-11936 Aux Id: OTP-11007

-- cgit v1.2.3