[m-dev.] diff: update extras/dynamic_linking
Fergus Henderson
fjh at cs.mu.OZ.AU
Tue Nov 21 18:38:38 AEDT 2000
Estimated hours taken: 0.25
extras/dynamic_linking/Mmakefile:
Add the appropriate flags to use shared libraries
(since on Linux this is not the default).
Link in `-ldl'.
extras/dynamic_linking/dl.m:
Apply some bug fixes that were previously applied to browser/mdb.m.
(XXX we really ought to fix this code duplication problem...)
Workspace: /home/pgrad/fjh/ws/hg
Index: extras/dynamic_linking/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/dynamic_linking/Mmakefile,v
retrieving revision 1.1
diff -u -d -r1.1 Mmakefile
--- extras/dynamic_linking/Mmakefile 1998/12/06 06:15:14 1.1
+++ extras/dynamic_linking/Mmakefile 2000/11/21 07:37:25
@@ -1,6 +1,13 @@
+# Use shared libraries, since they're needed for dynamic linking
+MGNUCFLAGS = --pic-reg
+MLFLAGS = --shared
+
+# Link in the `-ldl' library (this may not be needed on some systems)
+#MLLIBS = -ldl
+
# enable C-level debugging
CFLAGS = -g
-MLFLAGS = --no-strip
+MLFLAGS += --no-strip
main_target: libdl
depend: dl.depend dl_test.depend hello.depend
Index: extras/dynamic_linking/dl.m
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/dynamic_linking/dl.m,v
retrieving revision 1.1
diff -u -d -r1.1 dl.m
--- extras/dynamic_linking/dl.m 1998/12/06 06:15:15 1.1
+++ extras/dynamic_linking/dl.m 2000/11/21 07:25:52
@@ -1,5 +1,5 @@
%-----------------------------------------------------------------------------%
-% Copyright (C) 1998 The University of Melbourne.
+% Copyright (C) 1998-2000 The University of Melbourne.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%-----------------------------------------------------------------------------%
@@ -55,8 +55,13 @@
:- implementation.
:- import_module std_util, require, string, list.
-:- pragma c_header_code("#include <stdio.h>").
-:- pragma c_header_code("#include <dlfcn.h>").
+:- pragma c_header_code("
+ #include <stdio.h>
+ #include ""mercury_conf.h""
+#ifdef HAVE_DLFCN_H
+ #include <dlfcn.h>
+#endif
+").
:- type handle ---> handle(c_pointer).
@@ -85,15 +90,36 @@
:- pragma c_code(dlopen(FileName::in, Mode::in, Scope::in, Result::out,
_IO0::di, _IO::uo), [], "
{
+#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN) \
+ && defined(RTLD_NOW) && defined(RTLD_LAZY)
int mode = (Mode ? RTLD_NOW : RTLD_LAZY);
/* not all systems have RTLD_GLOBAL */
#ifdef RTLD_GLOBAL
if (Scope) mode |= RTLD_GLOBAL;
#endif
- Result = (Word) dlopen(FileName, mode);
+ Result = (MR_Word) dlopen(FileName, mode);
+#else
+ Result = (MR_Word) NULL;
+#endif
}").
-:- type closure ---> closure(int, c_pointer).
+:- type closure_layout
+ ---> closure_layout(
+ int,
+ string,
+ string,
+ string,
+ int,
+ int,
+ int
+ ).
+
+:- type closure
+ ---> closure(
+ closure_layout,
+ c_pointer,
+ int
+ ).
mercury_sym(Handle, MercuryProc0, Result) -->
{ check_proc_spec_matches_result_type(Result, _,
@@ -109,7 +135,9 @@
% convert the procedure address to a closure
%
NumCurriedInputArgs = 0,
- Closure = closure(NumCurriedInputArgs, Address),
+ ClosureLayout = closure_layout(0, "unknown", "unknown",
+ "unknown", -1, -1, -1),
+ Closure = closure(ClosureLayout, Address, NumCurriedInputArgs),
private_builtin__unsafe_type_cast(Closure, Value),
Result = ok(Value)
}.
@@ -176,16 +204,28 @@
:- pragma c_code(dlsym(Handle::in, Name::in, Pointer::out,
_IO0::di, _IO::uo), [will_not_call_mercury], "
{
- Pointer = (Word) dlsym((void *) Handle, Name);
+#if defined(HAVE_DLFCN_H) && defined(HAVE_DLSYM)
+ Pointer = (MR_Word) dlsym((void *) Handle, Name);
+#else
+ Pointer = (MR_Word) NULL;
+#endif
}").
:- pred dlerror(string::out, io__state::di, io__state::uo) is det.
:- pragma c_code(dlerror(ErrorMsg::out, _IO0::di, _IO::uo),
[will_not_call_mercury], "
{
- const char *msg = dlerror();
+ const char *msg;
+
+#if defined(HAVE_DLFCN_H) && defined(HAVE_DLERROR)
+ msg = dlerror();
if (msg == NULL) msg = """";
- make_aligned_string_copy(ErrorMsg, msg);
+#else
+ MR_make_aligned_string(msg, ""sorry, not implemented: ""
+ ""dynamic linking not supported on this platform"");
+#endif
+
+ MR_make_aligned_string_copy(ErrorMsg, msg);
}").
close(handle(Handle), Result) -->
@@ -193,6 +233,14 @@
dlerror(ErrorMsg),
{ Result = (if ErrorMsg = "" then ok else error(ErrorMsg)) }.
+/*
+** Note that dlclose() may call finalization code (e.g. destructors for global
+** variables in C++) which may end up calling Mercury, so it's not safe
+** to declare this as `will_not_call_mercury'.
+*/
:- pred dlclose(c_pointer::in, io__state::di, io__state::uo) is det.
-:- pragma c_code(dlclose(Handle::in, _IO0::di, _IO::uo),
- [will_not_call_mercury], "dlclose((void *)Handle)").
+:- pragma c_code(dlclose(Handle::in, _IO0::di, _IO::uo), [], "
+#if defined(HAVE_DLFCN_H) && defined(HAVE_DLCLOSE)
+ dlclose((void *)Handle)
+#endif
+").
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list