[m-rev.] diff: fix problems with dynamic linking support in extras

Julien Fischer jfischer at opturion.com
Fri Aug 21 21:11:03 AEST 2015


Fix problems with the dynamic linking support in extras.

Fix a mismatch in the mangling of symbol names between the name mangling
module in the browser / dynamic linking library and the MLDS->C code generator.
The former includes the function return argument in the arity, while the latter
does not.

Make the dynamic linking examples work in low-level C grades on OS X and mostly
work in high-level C grades.  (I say "mostly", since the integer function test
returns an incorrect result on my machine.)

browser/name_mangle.m:
       The arity for symbols corresponding to Mercury functions should not
       include the return argument.

       Add a comment mentioning that this module needs to be kept in sync
       with the name mangling scheme used in compiler/mlds_to_c.m.

       s/XXX/NOTE/ in a spot.

compiler/mlds_to_c.m:
       Add a comment mentioning that the name mangling code here needs to be
       kept in sync with the mlds version of the name mangling code
       in browser/name_mangle.m.

extras/dynamic_linking/Mmakefile:
 	Use the variable EXT_FOR_SHARED_LIBS rather than assuming that the
 	shared library extension is .so.

extras/dynamic_linking/dl_test.m:
extras/dynamic_linking/dl_test2.m:
 	Open 'libhello.dylib' on OS X systems rather than 'libhello.so'.

Julien.

diff --git a/browser/name_mangle.m b/browser/name_mangle.m
index 5447ef0..e15a333 100644
--- a/browser/name_mangle.m
+++ b/browser/name_mangle.m
@@ -73,10 +73,6 @@
  :- import_module list.
  :- import_module string.

-% XXX most of the code below is very similar to the code in
-% compiler/llds_out.m. Any changes there may require changes here
-% and vice versa.
-
  %-----------------------------------------------------------------------------%

  proc_name_mangle(MercuryProc) =
@@ -86,6 +82,12 @@ proc_name_mangle(MercuryProc) =
          llds_proc_name_mangle(MercuryProc)
      ).

+% NOTE:  most of the code below is very similar to the code in
+% compiler/llds_out.m. Any changes there may require changes here and vice
+% versa.
+
+%-----------------------------------------------------------------------------%
+
  :- func llds_proc_name_mangle(mercury_proc) = string.

  llds_proc_name_mangle(MercuryProc) = LabelName :-
@@ -124,6 +126,11 @@ llds_proc_name_mangle(MercuryProc) = LabelName :-
          LabelName = LabelName4
      ).

+%-----------------------------------------------------------------------------%
+
+% NOTE: the following code needs to be kept in sync with the predicates
+% mlds_pred_label_to_string and mlds_output_pred_label in compiler/mlds_to_c.m.
+
  :- func mlds_proc_name_mangle(mercury_proc) = string.

  mlds_proc_name_mangle(MercuryProc) = LabelName :-
@@ -143,19 +150,19 @@ mlds_proc_name_mangle(MercuryProc) = LabelName :-
      name_mangle(LabelName0, LabelName1),
      (
          PredOrFunc = predicate,
-        PredOrFuncString = "p",
-        ArityAsPred = Arity
+        PredOrFuncString = "p"
      ;
          PredOrFunc = function,
-        PredOrFuncString = "f",
-        ArityAsPred = Arity + 1
+        PredOrFuncString = "f"
      ),
-    string.int_to_string(ArityAsPred, ArityString),
+    string.int_to_string(Arity, ArityString),
      string.int_to_string(ModeNum, ModeNumString),
      string.append_list([LabelName1, "_", ArityString, "_",
          PredOrFuncString, "_", ModeNumString],
          LabelName).

+%-----------------------------------------------------------------------------%
+
  :- pred sym_name_mangle(sym_name::in, string::out) is det.

  sym_name_mangle(unqualified(Name), MangledName) :-
@@ -248,6 +255,8 @@ convert_to_valid_c_identifier_2(String, Name) :-
          Name = String
      ).

+%-----------------------------------------------------------------------------%
+
  :- pred use_asm_labels is semidet.

  :- pragma foreign_proc("C",
diff --git a/compiler/mlds_to_c.m b/compiler/mlds_to_c.m
index 653ecaa..367e58f 100644
--- a/compiler/mlds_to_c.m
+++ b/compiler/mlds_to_c.m
@@ -2602,7 +2602,7 @@ mlds_output_name(EntityName, !IO) :-
      ).

      % mlds_output_pred_label should be kept in sync with
-    % mlds_pred_label_to_string.
+    % mlds_pred_label_to_string and browser/name_mangle.m.
      %
  :- pred mlds_output_pred_label(mlds_pred_label::in, io::di, io::uo) is det.

@@ -2652,7 +2652,7 @@ mlds_output_pred_label(PredLabel, !IO) :-
      ).

      % mlds_pred_label_to_string should be kept in sync with
-    % mlds_output_pred_label.
+    % mlds_output_pred_label and browser/name_mangle.m.
      %
  :- func mlds_pred_label_to_string(mlds_pred_label) = string.

diff --git a/extras/dynamic_linking/Mmakefile b/extras/dynamic_linking/Mmakefile
index 6ed7433..da113ab 100644
--- a/extras/dynamic_linking/Mmakefile
+++ b/extras/dynamic_linking/Mmakefile
@@ -39,11 +39,11 @@ ifeq "$(findstring hl,$(GRADE))" ""
  check: dl_test2.res
  endif

-dl_test.res: dl_test dl_test.exp libhello.so
+dl_test.res: dl_test dl_test.exp libhello.$(EXT_FOR_SHARED_LIB)
  	./dl_test > dl_test.out
  	diff -c dl_test.out dl_test.exp

-dl_test2.res: dl_test2 dl_test2.exp libhello.so
+dl_test2.res: dl_test2 dl_test2.exp libhello.$(EXT_FOR_SHARED_LIB)
  	./dl_test2 > dl_test2.out
  	diff -c dl_test2.out dl_test2.exp

diff --git a/extras/dynamic_linking/dl_test.m b/extras/dynamic_linking/dl_test.m
index 8556b04..ffa3a63 100644
--- a/extras/dynamic_linking/dl_test.m
+++ b/extras/dynamic_linking/dl_test.m
@@ -4,8 +4,9 @@
  %
  % Example program using dynamic linking.
  % This module loads in the object code for the module `hello'
-% from the file `libhello.so', looks up the address of the
-% procedure hello/2 in that module, and then calls that procedure.
+% from the file `libhello.so' (or `libhello.dylib' on OS X), looks up the
+% address of the procedure hello/2 in that module, and then calls that
+% procedure.
  %
  % This source file is hereby placed in the public domain.  -fjh (the author).
  %
@@ -32,10 +33,11 @@
  main(!IO) :-
      %
      % Load in the object code for the module `hello' from
-    % the file `libhello.so'.
+    % the file `libhello.so' (`libhello.dylib' on OS X).
      %
-    dl.open("./libhello.so", lazy, local, MaybeHandle, !IO),
-    ( 
+    HelloLib = "./libhello." ++ shared_library_extension,
+    dl.open(HelloLib, lazy, local, MaybeHandle, !IO),
+    (
          MaybeHandle = dl_error(OpenMsg),
          io.format("dlopen failed: %s\n", [s(OpenMsg)], !IO)
      ;
@@ -129,5 +131,24 @@ main(!IO) :-
  ").

  %-----------------------------------------------------------------------------%
+
+:- func shared_library_extension = string.
+
+shared_library_extension =
+   ( if system_is_darwin then "dylib" else "so" ).
+
+:- pred system_is_darwin is semidet.
+:- pragma foreign_proc("C",
+    system_is_darwin,
+    [promise_pure, will_not_call_mercury, thread_safe],
+"
+#if defined(MR_MAC_OSX)
+    SUCCESS_INDICATOR = MR_TRUE;
+#else
+    SUCCESS_INDICATOR = MR_FALSE;
+#endif
+").
+
+%-----------------------------------------------------------------------------%
  :- end_module dl_test.
  %-----------------------------------------------------------------------------%
diff --git a/extras/dynamic_linking/dl_test2.m b/extras/dynamic_linking/dl_test2.m
index 58bef84..74023e7 100644
--- a/extras/dynamic_linking/dl_test2.m
+++ b/extras/dynamic_linking/dl_test2.m
@@ -5,8 +5,8 @@
  % Example program using dynamic linking.
  % This example tests calling functions with floating point arguments.
  %
-% This module loads in the object code for the module `hello'
-% from the file `libhello.so', looks up the address of the
+% This module loads in the object code for the module `hello' from the file
+% `libhello.so' (or `libhello.dylib' on OS X), looks up the address of the
  % function add3/3 in that module, and then calls that procedure.
  %
  % This source file is hereby placed in the public domain.  -fjh (the author).
@@ -34,10 +34,11 @@
  main(!IO) :-
      %
      % Load in the object code for the module `hello' from
-    % the file `libhello.so'.
+    % the file `libhello.so' (`libhello.dylib' on OS X).
      %
-    dl.open("./libhello.so", lazy, local, MaybeHandle, !IO),
-    ( 
+    HelloLib = "./libhello." ++ shared_library_extension,
+    dl.open(HelloLib, lazy, local, MaybeHandle, !IO),
+    (
          MaybeHandle = dl_error(OpenMsg),
          io.format("dlopen failed: %s\n", [s(OpenMsg)], !IO)
      ;
@@ -94,6 +95,25 @@ main(!IO) :-
      Y = X;
  ").

+%-----------------------------------------------------------------------------%
+
+:- func shared_library_extension = string.
+
+shared_library_extension =
+   ( if system_is_darwin then "dylib" else "so" ).
+
+:- pred system_is_darwin is semidet.
+:- pragma foreign_proc("C",
+    system_is_darwin,
+    [promise_pure, will_not_call_mercury, thread_safe],
+"
+#if defined(MR_MAC_OSX)
+    SUCCESS_INDICATOR = MR_TRUE;
+#else
+    SUCCESS_INDICATOR = MR_FALSE;
+#endif
+").
+
  %----------------------------------------------------------------------------%
  :- end_module dl_test2.
  %----------------------------------------------------------------------------%



More information about the reviews mailing list