DMD as a library package can now run through all semantic phases

rikki cattermole rikki at cattermole.co.nz
Mon Jan 29 12:53:38 UTC 2018


On 27/01/2018 4:14 AM, rikki cattermole wrote:
> Is it possible to reset the compiler to the point of uninitialized/newly 
> initialized?
> 
> For reuse in a single process.

I have been toying with this idea.
Example:

void main()
{
	import dmd.frontend;
	import std.algorithm : each;
	import std.stdio;
	
	// Sets DMD's global variables. Only required to be called once
	// In the future this might be done automatically (e.g. module 
constructor or initOnce)
	initDMD;

	foreach (_; 0 .. 1) {
		// This doesn't need to be called first time,
		//  however for repeated usage of dmd as a library, it is required 
before each time.
		// It allows for tokens (identifiers mostly) to be reset and not leak 
memory.
		resetDMD();

		// Search for the predefined import paths of your host compiler (DMD 
and LDC are supported)
		findImportPaths.each!addImport;
		
		// Load a module
		// (if no second argument is given, the file will be opened and read)
		auto m = parseModule("test.d", q{
				void foo()
				{
					foreach (i; 0..10) {}
				}
			});
		
		// Run through all semantic phases
		m.fullSemantic;
		m.prettyPrint.writeln;
	}
}

Patch (incomplete, and I probably missed loads):

 From 5f8894ce35ecfccbd1dc48424d262f59bf5dcd6b Mon Sep 17 00:00:00 2001
From: rikki cattermole <alphaglosined at gmail.com>
Date: Tue, 30 Jan 2018 01:49:22 +1300
Subject: [PATCH] Reset of state

---
  src/dmd/builtin.d  |  2 +-
  src/dmd/frontend.d | 31 ++++++++++++++++++++++++++++---
  src/dmd/objc.d     |  2 +-
  3 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/src/dmd/builtin.d b/src/dmd/builtin.d
index 9f1e2163f..b0b0db233 100644
--- a/src/dmd/builtin.d
+++ b/src/dmd/builtin.d
@@ -218,7 +218,7 @@ extern (C++) Expression eval_yl2xp1(Loc loc, 
FuncDeclaration fd, Expressions* ar

  public extern (C++) void builtin_init()
  {
-    builtins._init(47);
+    builtins.reset(47);
      // @safe @nogc pure nothrow real function(real)
      add_builtin("_D4core4math3sinFNaNbNiNfeZe", &eval_sin);
      add_builtin("_D4core4math3cosFNaNbNiNfeZe", &eval_cos);
diff --git a/src/dmd/frontend.d b/src/dmd/frontend.d
index 654516d54..d7ffe0e1a 100644
--- a/src/dmd/frontend.d
+++ b/src/dmd/frontend.d
@@ -18,8 +18,16 @@ import dmd.dmodule : Module;
  import std.range.primitives : isInputRange, ElementType;
  import std.traits : isNarrowString;

-version (Windows) private enum sep = ";", exe = ".exe";
-version (Posix) private enum sep = ":", exe = "";
+version (Windows)
+{
+	private enum sep = ";", exe = ".exe";
+	private enum DMD_CONF_FILE = "sc.ini";
+}
+version (Posix)
+{
+	private enum sep = ":", exe = "";
+	private enum DMD_CONF_FILE = "dmd.conf";
+}

  /*
  Initializes the global variables of the DMD compiler.
@@ -49,6 +57,23 @@ void initDMD()
      builtin_init();
  }

+void resetDMD()
+{
+	import dmd.tokens;
+	import dmd.mtype;
+	import dmd.dmodule;
+	import dmd.target : Target;
+	import dmd.objc : Objc;
+	import dmd.builtin : builtin_init;
+
+	Token.reinitialize();
+	//TODO: Type.* =
+	//TODO: Module.* =
+	Target._init();
+	Objc._init();
+	builtin_init();
+}
+
  /**
  Add import path to the `global.path`.
  Params:
@@ -79,7 +104,7 @@ string findDMDConfig(string dmdFilePath)
      import dmd.dinifile : findConfFile;
      import std.string : fromStringz, toStringz;

-    auto f = findConfFile(dmdFilePath.toStringz, "dmd.conf");
+	auto f = findConfFile(dmdFilePath.toStringz, DMD_CONF_FILE);
      if (f is null)
          return null;

diff --git a/src/dmd/objc.d b/src/dmd/objc.d
index 225c2f108..35d4d2331 100644
--- a/src/dmd/objc.d
+++ b/src/dmd/objc.d
@@ -41,7 +41,7 @@ struct ObjcSelector

      extern (C++) static void _init()
      {
-        stringtable._init();
+        stringtable.reset();
      }

      extern (D) this(const(char)* sv, size_t len, size_t pcount)
-- 
2.12.2.windows.2

 From 6313e30a8bfb32e65c74f700ee3ad5ac6e0d7656 Mon Sep 17 00:00:00 2001
From: rikki cattermole <alphaglosined at gmail.com>
Date: Tue, 30 Jan 2018 00:24:03 +1300
Subject: [PATCH] reset tokens

---
  src/dmd/identifier.d | 2 +-
  src/dmd/tokens.d     | 7 ++++++-
  2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/dmd/identifier.d b/src/dmd/identifier.d
index a6702cdda..6e1cef6bf 100644
--- a/src/dmd/identifier.d
+++ b/src/dmd/identifier.d
@@ -206,6 +206,6 @@ nothrow:

      static void initTable()
      {
-        stringtable._init(28000);
+        stringtable.reset(28000);
      }
  }
diff --git a/src/dmd/tokens.d b/src/dmd/tokens.d
index 1771fe246..057c5900f 100644
--- a/src/dmd/tokens.d
+++ b/src/dmd/tokens.d
@@ -599,7 +599,7 @@ extern (C++) struct Token
          return true;
      }());

-    shared static this()
+    static void reinitialize()
      {
          Identifier.initTable();
          foreach (kw; keywords)
@@ -609,6 +609,11 @@ extern (C++) struct Token
          }
      }

+	shared static this()
+	{
+		reinitialize();
+	}
+
      __gshared Token* freelist = null;

      static Token* alloc()
-- 
2.12.2.windows.2



More information about the Digitalmars-d mailing list