[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