Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit c3d1911

Browse files
committed
implement druntime side of DIP1006
1 parent 9cfde10 commit c3d1911

7 files changed

Lines changed: 154 additions & 10 deletions

File tree

mak/SRCS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ SRCS=\
268268
src\rt\deh_win64_posix.d \
269269
src\rt\dmain2.d \
270270
src\rt\dwarfeh.d \
271+
src\rt\ehalloc.d \
271272
src\rt\invariant.d \
272273
src\rt\lifetime.d \
273274
src\rt\llmath.d \

posix.mak

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ ifeq (solaris,$(OS))
5353
endif
5454

5555
# Set DFLAGS
56-
UDFLAGS:=-conf= -Isrc -Iimport -w -dip1000 $(MODEL_FLAG) $(OPTIONAL_PIC) $(OPTIONAL_COVERAGE)
56+
UDFLAGS:=-conf= -Isrc -Iimport -w -dip1000 -dip1006 $(MODEL_FLAG) $(OPTIONAL_PIC) $(OPTIONAL_COVERAGE)
5757
ifeq ($(BUILD),debug)
5858
UDFLAGS += -g -debug
5959
DFLAGS:=$(UDFLAGS)

src/rt/deh_win32.d

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -611,21 +611,33 @@ int _d_exception_filter(EXCEPTION_POINTERS *eptrs,
611611
}
612612

613613
/***********************************
614-
* Throw a D object.
614+
* Throw a D instance of Throwable.
615615
*/
616616

617-
private void throwImpl(Object h)
617+
private void throwImpl(Throwable h)
618618
{
619-
// @@@ TODO @@@ Signature should change: h will always be a Throwable.
620619
//printf("_d_throw(h = %p, &h = %p)\n", h, &h);
621620
//printf("\tvptr = %p\n", *(void **)h);
621+
622+
/* Increment reference count if `h` is a refcounted Throwable
623+
*/
624+
auto refcount = h.refcount();
625+
if (refcount) // non-zero means it's refcounted
626+
h.refcount() = refcount + 1;
627+
622628
_d_createTrace(h, null);
623629
RaiseException(STATUS_DIGITAL_MARS_D_EXCEPTION,
624630
EXCEPTION_NONCONTINUABLE,
625631
1, cast(void *)&h);
626632
}
627633

628-
extern(C) void _d_throwc(Object h)
634+
/***************************************
635+
* The compiler converts:
636+
* throw h;
637+
* into a call to:
638+
* _d_throwc(h);
639+
*/
640+
extern(C) void _d_throwc(Throwable h)
629641
{
630642
// set up a stack frame for trace unwinding
631643
version (AsmX86)

src/rt/deh_win64_posix.d

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ size_t __eh_find_caller(size_t regbp, size_t *pretaddr)
219219
* Throw a D object.
220220
*/
221221

222-
extern (C) void _d_throwc(Object h)
222+
extern (C) void _d_throwc(Throwable h)
223223
{
224224
size_t regebp;
225225

@@ -242,6 +242,12 @@ extern (C) void _d_throwc(Object h)
242242
else
243243
static assert(0);
244244

245+
/* Increment reference count if `h` is a refcounted Throwable
246+
*/
247+
auto refcount = h.refcount();
248+
if (refcount) // non-zero means it's refcounted
249+
h.refcount() = refcount + 1;
250+
245251
_d_createTrace(h, null);
246252

247253
//static uint abc;

src/rt/ehalloc.d

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/**
2+
* Exception allocation, cloning, and release compiler support routines.
3+
*
4+
* Copyright: Copyright (c) 2017 by D Language Foundation
5+
* License: Distributed under the
6+
* $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
7+
* (See accompanying file LICENSE)
8+
* Authors: Walter Bright
9+
* Source: $(DRUNTIMESRC src/rt/_dwarfeh.d)
10+
*/
11+
12+
module rt.ehalloc;
13+
14+
debug = PRINTF;
15+
16+
debug(PRINTF)
17+
{
18+
import core.stdc.stdio;
19+
}
20+
21+
/**********************************************
22+
* Allocate an exception of type `ci` from the exception pool.
23+
* It has the same interface as `rt.lifetime._d_newclass()`.
24+
* The class type must be Throwable or derived from it,
25+
* and cannot be a COM or C++ class. The compiler must enforce
26+
* this.
27+
* Returns:
28+
* default initialized instance of the type
29+
*/
30+
31+
extern (C) Throwable _d_newThrowable(const TypeInfo_Class ci)
32+
{
33+
debug(PRINTF) printf("_d_newThrowable(ci = %p, %s)\n", ci, cast(char *)ci.name);
34+
35+
assert(!(ci.m_flags & TypeInfo_Class.ClassFlags.isCOMclass));
36+
assert(!(ci.m_flags & TypeInfo_Class.ClassFlags.isCPPclass));
37+
38+
import core.stdc.stdlib : malloc;
39+
void* p = malloc(ci.initializer.length);
40+
if (!p)
41+
{
42+
import core.exception : onOutOfMemoryError;
43+
onOutOfMemoryError();
44+
}
45+
46+
debug(PRINTF) printf(" p = %p\n", p);
47+
48+
// initialize it
49+
p[0 .. ci.initializer.length] = ci.initializer[];
50+
51+
if (!(ci.m_flags & TypeInfo_Class.ClassFlags.noPointers))
52+
{
53+
// Inform the GC about the pointers in the object instance
54+
import core.memory : GC;
55+
56+
GC.addRange(p, ci.initializer.length, ci);
57+
}
58+
59+
debug(PRINTF) printf("initialization done\n");
60+
Throwable t = cast(Throwable)p;
61+
t.refcount() = 1;
62+
return t;
63+
}
64+
65+
66+
/********************************************
67+
* Delete exception instance `t` from the exception pool.
68+
* Must have been allocated with `_d_newThrowable()`.
69+
* This is meant to be called at the close of a catch block.
70+
* It's nothrow because otherwise any function with a catch block could
71+
* not be nothrow.
72+
* Input:
73+
* t = Throwable
74+
*/
75+
76+
nothrow extern (C) void _d_delThrowable(Throwable t)
77+
{
78+
if (t)
79+
{
80+
debug(PRINTF) printf("_d_delThrowable(%p)\n", t);
81+
82+
/* If allocated by the GC, don't free it.
83+
* Let the GC handle it.
84+
* Supporting this is necessary while transitioning
85+
* to this new scheme for allocating exceptions.
86+
*/
87+
auto refcount = t.refcount();
88+
if (refcount == 0)
89+
return; // it was allocated by the GC
90+
91+
if (refcount == 1)
92+
assert(0); // no zombie objects
93+
94+
t.refcount() = --refcount;
95+
if (refcount > 1)
96+
return;
97+
98+
TypeInfo_Class **pc = cast(TypeInfo_Class **)t;
99+
if (*pc)
100+
{
101+
TypeInfo_Class ci = **pc;
102+
103+
if (!(ci.m_flags & TypeInfo_Class.ClassFlags.noPointers))
104+
{
105+
// Inform the GC about the pointers in the object instance
106+
import core.memory : GC;
107+
GC.removeRange(cast(void*) t);
108+
}
109+
}
110+
111+
try
112+
{
113+
import rt.lifetime : rt_finalize;
114+
rt_finalize(cast(void*) t);
115+
}
116+
catch (Throwable t)
117+
{
118+
assert(0); // should never happen since Throwable.~this() is nothrow
119+
}
120+
import core.stdc.stdlib : free;
121+
debug(PRINTF) printf("free(%p)\n", t);
122+
free(cast(void*) t);
123+
}
124+
}
125+

win32.mak

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ CC=dmc
99
DOCDIR=doc
1010
IMPDIR=import
1111

12-
DFLAGS=-m$(MODEL) -conf= -O -release -dip1000 -inline -w -Isrc -Iimport
13-
UDFLAGS=-m$(MODEL) -conf= -O -release -dip1000 -w -Isrc -Iimport
12+
DFLAGS=-m$(MODEL) -conf= -O -release -dip1000 -dip1006 -inline -w -Isrc -Iimport
13+
UDFLAGS=-m$(MODEL) -conf= -O -release -dip1000 -dip1006 -w -Isrc -Iimport
1414
DDOCFLAGS=-conf= -c -w -o- -Isrc -Iimport -version=CoreDdoc
1515

1616
CFLAGS=

win64.mak

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ IMPDIR=import
1717

1818
MAKE=make
1919

20-
DFLAGS=-m$(MODEL) -conf= -O -release -dip1000 -inline -w -Isrc -Iimport
21-
UDFLAGS=-m$(MODEL) -conf= -O -release -dip1000 -w -Isrc -Iimport
20+
DFLAGS=-m$(MODEL) -conf= -O -release -dip1000 -dip1006 -inline -w -Isrc -Iimport
21+
UDFLAGS=-m$(MODEL) -conf= -O -release -dip1000 -dip1006 -w -Isrc -Iimport
2222
DDOCFLAGS=-conf= -c -w -o- -Isrc -Iimport -version=CoreDdoc
2323

2424
#CFLAGS=/O2 /I"$(VCDIR)"\INCLUDE /I"$(SDKDIR)"\Include

0 commit comments

Comments
 (0)