This repository was archived by the owner on Oct 12, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 419
Support merging of EH tables across Win64 DLLs #2874
Closed
Closed
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
deb84f2
Support merging of EH tables across DLLs
adamdruppe dcf637b
gh
adamdruppe ddfe0a1
test dynamic cast of class accross dll boundary
John-Colvin c6aceec
fix dynamic casts of classes passed across dll boundaries
John-Colvin a0c51af
fix catching derived exceptions across dll boundaries
John-Colvin 9ee8387
fixes missed from auto tester
John-Colvin 814b402
optlink hates empty file
adamdruppe File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,15 @@ | |
*/ | ||
module rt.cast_; | ||
|
||
// because using == does a dynamic cast, but we | ||
// are trying to implement dynamic cast. | ||
bool compareClassInfo(ClassInfo a, ClassInfo b) | ||
{ | ||
if (a is b) | ||
return true; | ||
return (a && b) && a.info.name == b.info.name; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When would the ClassInfo ever be null? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I vaguely recall seeing it happen in December when working on this originally but I don't remember where. Possible I was just being defensive too. |
||
} | ||
|
||
extern (C): | ||
|
||
/****************************************** | ||
|
@@ -76,19 +85,19 @@ void* _d_dynamic_cast(Object o, ClassInfo c) | |
|
||
int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset) | ||
{ | ||
if (oc is c) | ||
if (oc.compareClassInfo(c)) | ||
return true; | ||
|
||
do | ||
{ | ||
if (oc.base is c) | ||
if (oc.base.compareClassInfo(c)) | ||
return true; | ||
|
||
// Bugzilla 2013: Use depth-first search to calculate offset | ||
// from the derived (oc) to the base (c). | ||
foreach (iface; oc.interfaces) | ||
{ | ||
if (iface.classinfo is c || _d_isbaseof2(iface.classinfo, c, offset)) | ||
if (iface.classinfo.compareClassInfo(c) || _d_isbaseof2(iface.classinfo, c, offset)) | ||
{ | ||
offset += iface.offset; | ||
return true; | ||
|
@@ -103,17 +112,17 @@ int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset) | |
|
||
int _d_isbaseof(ClassInfo oc, ClassInfo c) | ||
{ | ||
if (oc is c) | ||
if (oc.compareClassInfo(c)) | ||
return true; | ||
|
||
do | ||
{ | ||
if (oc.base is c) | ||
if (oc.base.compareClassInfo(c)) | ||
return true; | ||
|
||
foreach (iface; oc.interfaces) | ||
{ | ||
if (iface.classinfo is c || _d_isbaseof(iface.classinfo, c)) | ||
if (iface.classinfo.compareClassInfo(c) || _d_isbaseof(iface.classinfo, c)) | ||
return true; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
class C : Exception | ||
{ | ||
this() { super(""); } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
version (DLL) | ||
{ | ||
version (Windows) | ||
{ | ||
import core.sys.windows.dll; | ||
mixin SimpleDllMain; | ||
} | ||
|
||
pragma(mangle, "foo") | ||
export Object foo(Object o) | ||
{ | ||
import classdef : C; | ||
|
||
assert(cast(C) o); | ||
return new C; | ||
} | ||
|
||
pragma(mangle, "bar") | ||
export void bar(void function() f) | ||
{ | ||
import core.stdc.stdio : fopen, fclose; | ||
import classdef : C; | ||
bool caught; | ||
try | ||
f(); | ||
catch (C e) | ||
caught = true; | ||
assert(caught); | ||
|
||
// verify we've actually got to the end, because for some reason we can | ||
// end up exiting with code 0 when throwing an exception | ||
fclose(fopen("dynamiccast_endbar", "w")); | ||
throw new C; | ||
} | ||
} | ||
else | ||
{ | ||
T getFunc(T)(const(char)* sym, string thisExePath) | ||
{ | ||
import core.runtime : Runtime; | ||
|
||
version (Windows) | ||
{ | ||
import core.sys.windows.winbase : GetProcAddress; | ||
return cast(T) Runtime.loadLibrary("dynamiccast.dll") | ||
.GetProcAddress(sym); | ||
} | ||
else version (Posix) | ||
{ | ||
import core.sys.posix.dlfcn : dlsym; | ||
import core.stdc.string : strrchr; | ||
|
||
auto name = thisExePath ~ '\0'; | ||
const pathlen = strrchr(name.ptr, '/') - name.ptr + 1; | ||
name = name[0 .. pathlen] ~ "dynamiccast.so"; | ||
return cast(T) Runtime.loadLibrary(name) | ||
.dlsym(sym); | ||
} | ||
else static assert(0); | ||
} | ||
|
||
void main(string[] args) | ||
{ | ||
import classdef : C; | ||
import core.stdc.stdio : fopen, fclose, remove; | ||
|
||
remove("dynamiccast_endmain"); | ||
remove("dynamiccast_endbar"); | ||
|
||
C c = new C; | ||
|
||
auto o = getFunc!(Object function(Object))("foo", args[0])(c); | ||
assert(cast(C) o); | ||
|
||
bool caught; | ||
try | ||
getFunc!(void function(void function()))("bar", args[0])( | ||
{ throw new C; }); | ||
catch (C e) | ||
caught = true; | ||
assert(caught); | ||
|
||
// verify we've actually got to the end, because for some reason we can | ||
// end up exiting with code 0 when throwing an exception | ||
fclose(fopen("dynamiccast_endmain", "w")); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
EXETYPE NT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
EXETYPE NT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
LIBRARY l | ||
EXPORTS | ||
_d_innerEhTable = _d_innerEhTable | ||
_d_setEhTablePointer = _d_setEhTablePointer |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is comparing for equality, the name for it should be something like "equals".