@@ -89,6 +89,9 @@ version (CRuntime_Microsoft)
89
89
extern (C ) void init_msvc();
90
90
}
91
91
92
+ version (Win64 )
93
+ import rt.deh_win64_posix;
94
+
92
95
/* **********************************
93
96
* These are a temporary means of providing a GC hook for DLL use. They may be
94
97
* replaced with some other similar functionality later.
@@ -102,6 +105,10 @@ extern (C)
102
105
alias void * function () gcGetFn;
103
106
alias void function (void * ) gcSetFn;
104
107
alias void function () gcClrFn;
108
+
109
+ // for exception handling, at least until druntime.dll actually works.
110
+ alias void function (const (FuncTable)[]* ) ehSetFn;
111
+ alias const (FuncTable)[] function () ehGetFn;
105
112
}
106
113
107
114
version (Windows )
@@ -112,12 +119,12 @@ version (Windows)
112
119
* opaque handle to the DLL if successfully loaded
113
120
* null if failure
114
121
*/
115
- extern (C ) void * rt_loadLibrary(const char * name)
122
+ export extern (C) void * rt_loadLibrary(const char * name)
116
123
{
117
124
return initLibrary (.LoadLibraryA(name));
118
125
}
119
126
120
- extern (C ) void * rt_loadLibraryW(const WCHAR * name)
127
+ export extern (C) void * rt_loadLibraryW(const WCHAR * name)
121
128
{
122
129
return initLibrary (.LoadLibraryW(name));
123
130
}
@@ -126,13 +133,58 @@ version (Windows)
126
133
{
127
134
// BUG: LoadLibrary() call calls rt_init(), which fails if proxy is not set!
128
135
// (What? LoadLibrary() is a Windows API call, it shouldn't call rt_init().)
136
+ // FYI LoadLibrary calls DllMain. DllMain calls rt_init.
129
137
if (mod is null )
130
138
return mod;
131
139
gcSetFn gcSet = cast (gcSetFn) GetProcAddress(mod, " gc_setProxy" );
132
140
if (gcSet ! is null )
133
141
{ // BUG: Set proxy, but too late
134
142
gcSet(gc_getProxy());
135
143
}
144
+
145
+ import rt.sections_win64;
146
+
147
+ ehGetFn ehGet = cast (ehGetFn) GetProcAddress(mod, " _d_innerEhTable" );
148
+ ehSetFn ehSet = cast (ehSetFn) GetProcAddress(mod, " _d_setEhTablePointer" );
149
+
150
+ typeof (ehGet()) libraryEh;
151
+ if (ehGet)
152
+ {
153
+ libraryEh = ehGet();
154
+ if (ehTablesGlobal is null )
155
+ {
156
+ // first time: copy the local table into it as well as
157
+ // the new library
158
+ auto local = _d_innerEhTable();
159
+ auto len = libraryEh.length + local.length;
160
+ auto ptr = cast (FuncTable* ) malloc(typeof (ehTablesGlobal[0 ]).sizeof * len);
161
+ ptr[0 .. local.length] = cast (FuncTable[]) local[];
162
+ ptr[local.length .. local.length + libraryEh.length] = cast (FuncTable[]) libraryEh[];
163
+ ehTablesGlobal = ptr[0 .. len];
164
+ }
165
+ else
166
+ {
167
+ // otherwise we need to realloc it to append the library table
168
+ auto ptr = ehTablesGlobal.ptr;
169
+ ptr = cast (FuncTable* ) realloc(cast (void * ) ptr,
170
+ typeof (ehTablesGlobal[0 ]).sizeof * (ehTablesGlobal.length + libraryEh.length));
171
+ if (ptr is null )
172
+ abort();
173
+ auto orig = ehTablesGlobal.length;
174
+ cast (FuncTable[]) ptr[orig .. orig + libraryEh.length] = cast (FuncTable[]) libraryEh[];
175
+ ehTablesGlobal = ptr[0 .. orig + libraryEh.length];
176
+ }
177
+
178
+ // set the local pointer
179
+ _d_setEhTablePointer(&ehTablesGlobal);
180
+
181
+ if (ehSet)
182
+ {
183
+ // and set the remote table too so throwing from the dll also sees the whole thing
184
+ ehSet(&ehTablesGlobal);
185
+ }
186
+ }
187
+
136
188
return mod;
137
189
}
138
190
@@ -144,8 +196,39 @@ version (Windows)
144
196
* 1 succeeded
145
197
* 0 some failure happened
146
198
*/
147
- extern (C ) int rt_unloadLibrary(void * ptr)
199
+ export extern (C) int rt_unloadLibrary(void * ptr)
148
200
{
201
+ // should this logic just be done in the dll's DllMain instead?
202
+
203
+ // need to clear the DLL's table out of the global list, so first that
204
+ // means fetching the dll's table...
205
+ ehGetFn ehGet = cast (ehGetFn) GetProcAddress(ptr, " _d_innerEhTable" );
206
+ if (ehGetFn)
207
+ {
208
+ auto dllTables = ehGetFn();
209
+ import rt.sections_win64;
210
+ // __gshared package(rt) const(FuncTable)[] ehTablesGlobal;
211
+
212
+ loop: foreach (entry; dllTables)
213
+ {
214
+ foreach (idx, ge; ehTablesGlobal)
215
+ {
216
+ if (ge == entry)
217
+ {
218
+ import core.stdc.string ;
219
+ // assumes continuous append! If you ever sort the loading code or something
220
+ // be sure to fix this too.
221
+ memmove(&ehTablesGlobal[idx], &ehTablesGlobal[idx + dllTables.length], typeof (ge).sizeof * (ehTablesGlobal.length - (idx + dllTables.length)));
222
+ ehTablesGlobal = ehTablesGlobal[idx + dllTables.length .. $];
223
+ // could realloc it down to the new size, but I suspect it will be useful
224
+ // again in the future anyway so might as well let the realloc on load reuse
225
+ // space if needed and also simplify this part of the code a little.
226
+ break loop;
227
+ }
228
+ }
229
+ }
230
+ }
231
+
149
232
gcClrFn gcClr = cast (gcClrFn) GetProcAddress(ptr, " gc_clrProxy" );
150
233
if (gcClr ! is null )
151
234
gcClr();
@@ -179,7 +262,7 @@ shared size_t _initCount;
179
262
* If a C program wishes to call D code, and there's no D main(), then it
180
263
* must call rt_init() and rt_term().
181
264
*/
182
- extern (C ) int rt_init()
265
+ export extern (C) int rt_init()
183
266
{
184
267
/* @@BUG 11380 @@ Need to synchronize rt_init/rt_term calls for
185
268
version (Shared) druntime, because multiple C threads might
@@ -191,6 +274,12 @@ extern (C) int rt_init()
191
274
version (CRuntime_Microsoft )
192
275
init_msvc();
193
276
277
+ version (Win64 )
278
+ {{
279
+ import rt.sections_win64;
280
+ loadDefaultEhTables();
281
+ }}
282
+
194
283
_d_monitor_staticctor();
195
284
_d_critical_init();
196
285
@@ -321,7 +410,7 @@ private alias extern(C) int function(char[][] args) MainFunc;
321
410
* runs embedded unittests and then runs the given D main() function,
322
411
* optionally catching and printing any unhandled exceptions.
323
412
*/
324
- extern (C ) int _d_run_main(int argc, char ** argv, MainFunc mainFunc)
413
+ export extern (C) int _d_run_main(int argc, char ** argv, MainFunc mainFunc)
325
414
{
326
415
// Set up _cArgs and array of D char[] slices, then forward to _d_run_main2
327
416
0 commit comments