Skip to content

Commit 10f87db

Browse files
Add deinitializeDMD function to deinitialize the front end
This is a start of being able to restore the global state initialized by `initDMD` to its original state. It only deinitializes state initialized by `initDMD`, state store directly inside functions are not restored. This is useful to invoke the compiler multiple times within the same application. This allows to write more fine grained tests for the compiler, more of a unit test style compared to the current end to end tests.
1 parent 703cd95 commit 10f87db

17 files changed

Lines changed: 880 additions & 79 deletions

File tree

.circleci/run.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ check_clean_git()
173173
check_run_individual()
174174
{
175175
local build_path=generated/linux/release/$MODEL
176-
"${build_path}/dmd" -i -run ./test/run.d test/runnable/template2962.d ./test/compilable/test14275.d
176+
"${build_path}/dmd" -I./test -i -run ./test/run.d test/runnable/template2962.d ./test/compilable/test14275.d
177177
}
178178
179179
# Checks the D build.d script

dub.sdl

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,14 @@ subPackage {
3333
preGenerateCommands `
3434
"$${DUB_EXE}" \
3535
--arch=$${DUB_ARCH} \
36+
--compiler=$${DC} \
3637
--single "$${DUB_PACKAGE_DIR}config.d" \
3738
-- "$${DUB_PACKAGE_DIR}generated/dub" \
3839
"$${DUB_PACKAGE_DIR}VERSION" \
3940
/etc
4041
` platform="posix"
4142

42-
preGenerateCommands `
43-
"%DUB_EXE%" ^
44-
--arch=%DUB_ARCH% ^
45-
--single "%DUB_PACKAGE_DIR%config.d" ^
46-
-- "%DUB_PACKAGE_DIR%generated/dub" ^
47-
"%DUB_PACKAGE_DIR%VERSION"
48-
` platform="windows"
43+
preGenerateCommands `"%DUB_EXE%" --arch=%DUB_ARCH% --compiler="%DC%" --single "%DUB_PACKAGE_DIR%config.d" -- "%DUB_PACKAGE_DIR%generated/dub" "%DUB_PACKAGE_DIR%VERSION"` platform="windows"
4944

5045
stringImportPaths "generated/dub"
5146

src/dmd/builtin.d

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,17 @@ public extern (C++) void builtin_init()
425425
add_builtin("_D4core5bitop7_popcntFNaNbNiNfmZi", &eval_popcnt);
426426
}
427427

428+
/**
429+
* Deinitializes the global state of the compiler.
430+
*
431+
* This can be used to restore the state set by `builtin_init` to its original
432+
* state.
433+
*/
434+
public void builtinDeinitialize()
435+
{
436+
builtins = builtins.init;
437+
}
438+
428439
/**********************************
429440
* Determine if function is a builtin one that we can
430441
* evaluate at compile time.

src/dmd/dmodule.d

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,17 @@ extern (C++) final class Module : Package
299299
modules = new DsymbolTable();
300300
}
301301

302+
/**
303+
* Deinitializes the global state of the compiler.
304+
*
305+
* This can be used to restore the state set by `_init` to its original
306+
* state.
307+
*/
308+
static void deinitialize()
309+
{
310+
modules = modules.init;
311+
}
312+
302313
extern (C++) __gshared AggregateDeclaration moduleinfo;
303314

304315
const(char)* arg; // original argument name

src/dmd/expression.d

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,22 @@ extern (C++) abstract class Expression : RootObject
640640
CTFEExp.showcontext = new CTFEExp(TOK.showCtfeContext);
641641
}
642642

643+
/**
644+
* Deinitializes the global state of the compiler.
645+
*
646+
* This can be used to restore the state set by `_init` to its original
647+
* state.
648+
*/
649+
static void deinitialize()
650+
{
651+
CTFEExp.cantexp = CTFEExp.cantexp.init;
652+
CTFEExp.voidexp = CTFEExp.voidexp.init;
653+
CTFEExp.breakexp = CTFEExp.breakexp.init;
654+
CTFEExp.continueexp = CTFEExp.continueexp.init;
655+
CTFEExp.gotoexp = CTFEExp.gotoexp.init;
656+
CTFEExp.showcontext = CTFEExp.showcontext.init;
657+
}
658+
643659
/*********************************
644660
* Does *not* do a deep copy.
645661
*/

src/dmd/frontend.d

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,35 @@ void initDMD()
7676
FileCache._init();
7777
}
7878

79+
/**
80+
Deinitializes the global variables of the DMD compiler.
81+
82+
This can be used to restore the state set by `initDMD` to its original state.
83+
Useful if there's a need for multiple sessions of the DMD compiler in the same
84+
application.
85+
*/
86+
void deinitializeDMD()
87+
{
88+
import dmd.builtin : builtinDeinitialize;
89+
import dmd.dmodule : Module;
90+
import dmd.expression : Expression;
91+
import dmd.globals : global;
92+
import dmd.id : Id;
93+
import dmd.mtype : Type;
94+
import dmd.objc : Objc;
95+
import dmd.target : target;
96+
97+
global.deinitialize();
98+
99+
Type.deinitialize();
100+
Id.deinitialize();
101+
Module.deinitialize();
102+
target.deinitialize();
103+
Expression.deinitialize();
104+
Objc.deinitialize();
105+
builtinDeinitialize();
106+
}
107+
79108
/**
80109
Add import path to the `global.path`.
81110
Params:

src/dmd/globals.d

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,17 @@ struct Global
401401
params.color = Console.detectTerminal();
402402
}
403403

404+
/**
405+
* Deinitializes the global state of the compiler.
406+
*
407+
* This can be used to restore the state set by `_init` to its original
408+
* state.
409+
*/
410+
void deinitialize()
411+
{
412+
this = this.init;
413+
}
414+
404415
/**
405416
Returns: the version as the number that would be returned for __VERSION__
406417
*/

src/dmd/id.d

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ struct Id
3939
{
4040
mixin(msgtable.generate(&initializer));
4141
}
42+
43+
/**
44+
* Deinitializes the global state of the compiler.
45+
*
46+
* This can be used to restore the state set by `initialize` to its original
47+
* state.
48+
*/
49+
void deinitialize()
50+
{
51+
mixin(msgtable.generate(&deinitializer));
52+
}
4253
}
4354

4455
private:
@@ -487,3 +498,9 @@ string initializer(Msgtable m)
487498
{
488499
return m.ident ~ ` = Identifier.idPool("` ~ m.name ~ `");`;
489500
}
501+
502+
// Used to generate the code for each deinitializer.
503+
string deinitializer(Msgtable m)
504+
{
505+
return m.ident ~ " = Identifier.init;";
506+
}

src/dmd/mtype.d

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,17 @@ extern (C++) abstract class Type : RootObject
905905
thash_t = tsize_t;
906906
}
907907

908+
/**
909+
* Deinitializes the global state of the compiler.
910+
*
911+
* This can be used to restore the state set by `_init` to its original
912+
* state.
913+
*/
914+
static void deinitialize()
915+
{
916+
stringtable = stringtable.init;
917+
}
918+
908919
final d_uns64 size()
909920
{
910921
return size(Loc.initial);

src/dmd/objc.d

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,17 @@ extern(C++) abstract class Objc
188188
_objc = new Unsupported;
189189
}
190190

191+
/**
192+
* Deinitializes the global state of the compiler.
193+
*
194+
* This can be used to restore the state set by `_init` to its original
195+
* state.
196+
*/
197+
static void deinitialize()
198+
{
199+
_objc = _objc.init;
200+
}
201+
191202
abstract void setObjc(ClassDeclaration cd);
192203
abstract void setObjc(InterfaceDeclaration);
193204

0 commit comments

Comments
 (0)