/
README.CSharp
225 lines (147 loc) · 7.84 KB
/
README.CSharp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
-----------------------------------------------------------------------------
INTRODUCTION
This release of Mercury contains a port to the ECMA Common Language
Infrastructure (CLI), i.e. Microsoft .NET or Mono. The Mercury
compiler will generate C# source code that can be compiled into
bytecode suitable for running on the .NET or Mono runtime systems.
The port is mostly complete, but some parts of the Mercury standard
library are not yet implemented (for a full list see the FAQ below).
The port is currently targeted at C# 2.0 or higher.
NOTE: a previous backend also targetted the .NET runtime, by generating IL
(Intermediate Language), rather than going via C#. That backend is
out-of-date and may be removed in the future.
PREREQUISITES
In order to try this system you will need
- Either Microsoft.NET or Mono 2.8 or above.
WARNING
Please note that the C# backend is still an experimental feature.
-----------------------------------------------------------------------------
THE C# GRADE
The Mercury compiler currently supports the grade `csharp'.
The csharp grade is enabled by using any of the options
`--grade csharp', `--target csharp', or just `--csharp'.
To run a Mercury program using the csharp grade, you need to build the Mercury
library and runtime in the csharp grade, using the Mercury source distribution.
You can now build programs such as hello.m or calculator.m in the samples
directory.
cd samples
mmc --make --csharp hello
-----------------------------------------------------------------------------
RUNNING C# GRADE PROGRAMS ON UNIX WITH MONO
For the example in the previous section on a Unix (or more generally,
non-Windows) system using Mono, the Mercury compiler will generate a process
assembly, e.g. hello.exe, and a wrapper shell script named hello.
The wrapper shell script will set the MONO_PATH environment variable
to point to the location of the Mercury standard library assemblies.
It will then invoke CLI execution environment on the above process assembly,
i.e. you can run the program by simply running the wrapper shell script,
for example
./hello
-----------------------------------------------------------------------------
RUNNING C# GRADE PROGRAMS ON WINDOWS WITH .NET
On Windows, the Mercury compiler will only generate a process assembly, e.g.
hello.exe. (On Windows there is no need to generate a wrapper shell script.)
With .NET, the library assemblies (.dlls) for the Mercury standard
libraries must either (1) reside in (or under) the same directory as the process
assembly (.exe) or (2) be entered into the global assembly cache (GAC).
If neither of these things is done then execution will abort with a message that
begins:
Unhandled Exception: System.IO.FileNotFoundException: Could not load file
or assembly 'mer_std', Version=...
For (1), you will need to copy the library assemblies from the Mercury library
installation into the the same directory as the process assembly.
The files for the library assemblies are located in
<prefix>\lib\mercury\lib\csharp
where <prefix> is the location of the Mercury installation.
Copy all of the dll files in the above directory into that of the process
assembly.
As for (2), in order to enter assemblies into the GAC they must be strongly-
named; unfortunately the Mercury compiler does not currently support creating
strongly-named assemblies in the csharp grade. If you're feeling particularly
fearless, then you can give the standard library assemblies strong-names and
enter them into the GAC manually using the following instructions.
(0) We require the .NET SDK tools, such as gacutil.exe, to be available
from the command line. (You can use the ``Visual Studio Command Prompt''
shortcut to start a command line session with the environment suitably
set up.)
(1) Copy the standard library assemblies out of <prefix>\lib\mercury\lib\csharp
and into a separate directory.
(2) Create a new strong-name key-pair with which to sign the assemblies.
A key-pair can be created by using the sn.exe tool, for example
sn -k mercury.snk
will create a new key-pair and place it in the file mercury.snk.
(You may skip this step if you already have a strong-name key-pair
that you wish to use.)
(3) For each dll file do the following. (We illustrate using mer_std.dll.)
(i) Disassemble the assembly into MSIL.
ildasm mer_std.dll /out:mer_std.il
Note that this may also result in the creation of a resource file
mer_std.res.
(ii) Delete mer_std.dll.
(iii) Reassemble the assembly and sign it using the key-pair.
ilasm mer_std.il /dll /output=mer_std.dll /resource=mer_std.res /key=mercury.snk
Note that the /resource switch is only required if a resource file
is generated during disassembly.
(iv) Enter the assembly in the GAC.
gacutil /i mer_std.dll
(v) Replace Mercury's copy of the assembly with the newly signed one.
copy mer_std.dll <prefix>\lib\mercury\lib\csharp
This last step is important - the C# compiler does not look for
assemblies in the GAC at compile-time. We need to keep the "reference"
copy of the assembly in the Mercury library installation consistent with
the one in the GAC. (If something goes wrong here, the symptom will
typically be an abort from the runtime with a message saying that it
could not find the assembly.)
Assemblies can be removed from the GAC by doing, for example
gacutil /u mer_std.dll
We hope to improve support for signing assemblies in future versions of the
Mercury compiler.
-----------------------------------------------------------------------------
USING C#
The Mercury standard library has not been fully ported to C# yet.
The use of unimplemented procedures will result in a run-time error,
with a message such as "Sorry, not implemented: foreign code for this
function", and a stack trace.
If you find missing functionality, you can interface to C# using Mercury's
foreign language interface.
For example:
:- pred to_string(T::in, string::out) is det.
:- pragma foreign_proc("C#", to_string(T::in, Str::out), [],
"
Str = T.ToString();
").
The implementation will include this C# code in the module's .cs file, and
you can then call the predicate to_string exactly the same as if it were
implemented using pure Mercury code.
For more information about the foreign language interface, see the Mercury
Language Reference Manual, which you can find at:
<http://www.mercury.csse.unimelb.edu.au/information/documentation.html>
-----------------------------------------------------------------------------
FREQUENTLY ASKED QUESTIONS (FAQS)
Q. What are the advantages of using the C# back-end?
A. The main advantage is easy access to the wide range of libraries for the
.NET platform, and the portability you get from using CIL bytecode.
Q. What features are not yet implemented for the C# back-end?
A. The following implementation features are not supported:
Mercury-level debugging (but see next question)
Mercury-level profiling
trailing
tabling
In addition, the following individual procedures are incompletely
implemented:
io.read_binary/{3,4}:
io.write_binary/{3,4}:
io.read_binary is broken.
benchmarking.report_stats/0:
benchmarking.report_full_memory_stats/0:
Memory usage statistics are not yet available, and cpu time
is not the same as in the C backends, as per time.m.
store.arg_ref/5:
store.new_arg_ref/5:
Due to the absence of RTTI, dynamic type checking is missing
for these predicates. They should be used with care.
This list is not complete.
Q. How do I debug Mercury programs on .NET?
A. The only Mercury-level debugger available for C# grades is the
source-to-source debugger; see README.ssdebug.
-----------------------------------------------------------------------------