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