From 97c5a0bec6d8e09e2b8fe8d71052de835305ec58 Mon Sep 17 00:00:00 2001 From: hatf0 Date: Mon, 18 Oct 2021 00:21:07 -0400 Subject: [PATCH] Rip out FileCache and replace with FileManager --- dub.sdl | 4 +- src/build.d | 2 +- src/dmd/README.md | 16 +-- src/dmd/dmodule.d | 127 +++-------------- src/dmd/errors.d | 42 +++--- src/dmd/expressionsem.d | 27 +++- src/dmd/file_manager.d | 301 ++++++++++++++++++++++++++++++++++++++++ src/dmd/file_manager.h | 19 +++ src/dmd/filecache.d | 137 ------------------ src/dmd/frontend.d | 9 +- src/dmd/frontend.h | 54 ++++++- src/dmd/mars.d | 4 +- 12 files changed, 448 insertions(+), 294 deletions(-) create mode 100644 src/dmd/file_manager.d create mode 100644 src/dmd/file_manager.h delete mode 100644 src/dmd/filecache.d diff --git a/dub.sdl b/dub.sdl index 50634f40c2f0..400ba522d84d 100644 --- a/dub.sdl +++ b/dub.sdl @@ -22,7 +22,7 @@ subPackage { "src/dmd/console.d" \ "src/dmd/entity.d" \ "src/dmd/errors.d" \ - "src/dmd/filecache.d" \ + "src/dmd/file_manager.d" \ "src/dmd/globals.d" \ "src/dmd/id.d" \ "src/dmd/identifier.d" \ @@ -92,7 +92,7 @@ subPackage { console,\ entity,\ errors,\ - filecache,\ + file_manager,\ globals,\ id,\ identifier,\ diff --git a/src/build.d b/src/build.d index fbb4ba6849ce..cd327c7ddb7a 100755 --- a/src/build.d +++ b/src/build.d @@ -1406,7 +1406,7 @@ auto sourceFiles() statement.h staticassert.h target.h template.h tokens.h version.h visitor.h "), lexer: fileArray(env["D"], " - console.d entity.d errors.d filecache.d globals.d id.d identifier.d lexer.d tokens.d utf.d + console.d entity.d errors.d file_manager.d globals.d id.d identifier.d lexer.d tokens.d utf.d ") ~ fileArray(env["ROOT"], " array.d bitarray.d ctfloat.d file.d filename.d hash.d port.d region.d rmem.d rootobject.d stringtable.d diff --git a/src/dmd/README.md b/src/dmd/README.md index 734005ec0e6b..3cb7e127bb6c 100644 --- a/src/dmd/README.md +++ b/src/dmd/README.md @@ -245,14 +245,14 @@ Note that these groups have no strict meaning, the category assignments are a bi Note: many other utilities are in [dmd/root](https://github.com/dlang/dmd/tree/master/src/dmd/root). -| File | Purpose | -|-----------------------------------------------------------------------------|---------------------------------------------------| -| [env.d](https://github.com/dlang/dmd/blob/master/src/dmd/env.d) | Modify environment variables | -| [console.d](https://github.com/dlang/dmd/blob/master/src/dmd/console.d) | Print error messages in color | -| [utf.d](https://github.com/dlang/dmd/blob/master/src/dmd/utf.d) | Encoding/decoding Unicode text | -| [filecache.d](https://github.com/dlang/dmd/blob/master/src/dmd/filecache.d) | Keep file contents in memory | -| [utils.d](https://github.com/dlang/dmd/blob/master/src/dmd/utils.d) | Utility functions related to files and file paths | -| [complex.d](https://github.com/dlang/dmd/blob/master/src/dmd/complex.d) | A complex number type | +| File | Purpose | +|-----------------------------------------------------------------------------------|---------------------------------------------------| +| [env.d](https://github.com/dlang/dmd/blob/master/src/dmd/env.d) | Modify environment variables | +| [console.d](https://github.com/dlang/dmd/blob/master/src/dmd/console.d) | Print error messages in color | +| [utf.d](https://github.com/dlang/dmd/blob/master/src/dmd/utf.d) | Encoding/decoding Unicode text | +| [file_manager.d](https://github.com/dlang/dmd/blob/master/src/dmd/file_manager.d) | Keep file contents in memory | +| [utils.d](https://github.com/dlang/dmd/blob/master/src/dmd/utils.d) | Utility functions related to files and file paths | +| [complex.d](https://github.com/dlang/dmd/blob/master/src/dmd/complex.d) | A complex number type | | File | Purpose | |---------------------------------------------------------------------------------|---------------------------------------------------------------| diff --git a/src/dmd/dmodule.d b/src/dmd/dmodule.d index e2e4e9b08cb8..4e0071304e4d 100644 --- a/src/dmd/dmodule.d +++ b/src/dmd/dmodule.d @@ -31,6 +31,7 @@ import dmd.dsymbolsem; import dmd.errors; import dmd.expression; import dmd.expressionsem; +import dmd.file_manager; import dmd.globals; import dmd.id; import dmd.identifier; @@ -50,113 +51,6 @@ import dmd.target; import dmd.utils; import dmd.visitor; -enum package_d = "package." ~ mars_ext; -enum package_di = "package." ~ hdr_ext; - -/******************************************** - * Look for the source file if it's different from filename. - * Look for .di, .d, directory, and along global.path. - * Does not open the file. - * Params: - * filename = as supplied by the user - * path = path to look for filename - * Returns: - * the found file name or - * `null` if it is not different from filename. - */ -private const(char)[] lookForSourceFile(const char[] filename, const char*[] path) -{ - //printf("lookForSourceFile(`%.*s`)\n", cast(int)filename.length, filename.ptr); - /* Search along path[] for .di file, then .d file, then .i file, then .c file. - */ - const sdi = FileName.forceExt(filename, hdr_ext); - if (FileName.exists(sdi) == 1) - return sdi; - scope(exit) FileName.free(sdi.ptr); - - const sd = FileName.forceExt(filename, mars_ext); - if (FileName.exists(sd) == 1) - return sd; - scope(exit) FileName.free(sd.ptr); - - const si = FileName.forceExt(filename, i_ext); - if (FileName.exists(si) == 1) - return si; - scope(exit) FileName.free(si.ptr); - - const sc = FileName.forceExt(filename, c_ext); - if (FileName.exists(sc) == 1) - return sc; - scope(exit) FileName.free(sc.ptr); - - if (FileName.exists(filename) == 2) - { - /* The filename exists and it's a directory. - * Therefore, the result should be: filename/package.d - * iff filename/package.d is a file - */ - const ni = FileName.combine(filename, package_di); - if (FileName.exists(ni) == 1) - return ni; - FileName.free(ni.ptr); - - const n = FileName.combine(filename, package_d); - if (FileName.exists(n) == 1) - return n; - FileName.free(n.ptr); - } - if (FileName.absolute(filename)) - return null; - if (!path.length) - return null; - foreach (entry; path) - { - const p = entry.toDString(); - - const(char)[] n = FileName.combine(p, sdi); - if (FileName.exists(n) == 1) { - return n; - } - FileName.free(n.ptr); - - n = FileName.combine(p, sd); - if (FileName.exists(n) == 1) { - return n; - } - FileName.free(n.ptr); - - n = FileName.combine(p, si); - if (FileName.exists(n) == 1) { - return n; - } - FileName.free(n.ptr); - - n = FileName.combine(p, sc); - if (FileName.exists(n) == 1) { - return n; - } - FileName.free(n.ptr); - - const b = FileName.removeExt(filename); - n = FileName.combine(p, b); - FileName.free(b.ptr); - if (FileName.exists(n) == 2) - { - const n2i = FileName.combine(n, package_di); - if (FileName.exists(n2i) == 1) - return n2i; - FileName.free(n2i.ptr); - const n2 = FileName.combine(n, package_d); - if (FileName.exists(n2) == 1) { - return n2; - } - FileName.free(n2.ptr); - } - FileName.free(n.ptr); - } - return null; -} - // function used to call semantic3 on a module's dependencies void semantic3OnDependencies(Module m) { @@ -414,7 +308,7 @@ extern (C++) class Package : ScopeDsymbol packages ~= s.ident; reverse(packages); - if (lookForSourceFile(getFilename(packages, ident), global.path ? (*global.path)[] : null)) + if (FileManager.lookForSourceFile(getFilename(packages, ident), global.path ? (*global.path)[] : null)) Module.load(Loc.initial, packages, this.ident); else isPkgMod = PKG.package_; @@ -612,7 +506,7 @@ extern (C++) final class Module : Package // foo\bar\baz const(char)[] filename = getFilename(packages, ident); // Look for the source file - if (const result = lookForSourceFile(filename, global.path ? (*global.path)[] : null)) + if (const result = FileManager.lookForSourceFile(filename, global.path ? (*global.path)[] : null)) filename = result; // leaks auto m = new Module(loc, filename, ident, 0, 0); @@ -781,14 +675,25 @@ extern (C++) final class Module : Package return true; // already read //printf("Module::read('%s') file '%s'\n", toChars(), srcfile.toChars()); - auto readResult = File.read(srcfile.toChars()); if (global.params.emitMakeDeps) { global.params.makeDeps.push(srcfile.toChars()); } - return loadSourceBuffer(loc, readResult); + if (auto readResult = FileManager.fileManager.lookup(srcfile)) + { + srcBuffer = readResult; + return true; + } + + auto readResult = File.read(srcfile.toChars()); + if (loadSourceBuffer(loc, readResult)) + { + FileManager.fileManager.add(srcfile, srcBuffer); + return true; + } + return false; } /// syntactic parse diff --git a/src/dmd/errors.d b/src/dmd/errors.d index f8f258dd9038..d035d2194e1d 100644 --- a/src/dmd/errors.d +++ b/src/dmd/errors.d @@ -387,29 +387,33 @@ private void verrorPrint(const ref Loc loc, Color headerColor, const(char)* head !loc.filename.strstr(".d-mixin-") && !global.params.mixinOut) { - import dmd.filecache : FileCache; - auto fllines = FileCache.fileCache.addOrGetFile(loc.filename.toDString()); - - if (loc.linnum - 1 < fllines.lines.length) + import dmd.file_manager : FileManager; + import dmd.root.filename : FileName; + const fileName = FileName(loc.filename.toDString); + if (auto file = FileManager.fileManager.lookup(fileName)) { - auto line = fllines.lines[loc.linnum - 1]; - if (loc.charnum < line.length) + const(char)[][] lines = FileManager.fileManager.getLines(fileName); + if (loc.linnum - 1 < lines.length) { - fprintf(stderr, "%.*s\n", cast(int)line.length, line.ptr); - // The number of column bytes and the number of display columns - // occupied by a character are not the same for non-ASCII charaters. - // https://issues.dlang.org/show_bug.cgi?id=21849 - size_t c = 0; - while (c < loc.charnum - 1) + auto line = lines[loc.linnum - 1]; + if (loc.charnum < line.length) { - import dmd.utf : utf_decodeChar; - dchar u; - const msg = utf_decodeChar(line, c, u); - assert(msg is null, msg); - fputc(' ', stderr); + fprintf(stderr, "%.*s\n", cast(int)line.length, line.ptr); + // The number of column bytes and the number of display columns + // occupied by a character are not the same for non-ASCII charaters. + // https://issues.dlang.org/show_bug.cgi?id=21849 + size_t c = 0; + while (c < loc.charnum - 1) + { + import dmd.utf : utf_decodeChar; + dchar u; + const msg = utf_decodeChar(line, c, u); + assert(msg is null, msg); + fputc(' ', stderr); + } + fputc('^', stderr); + fputc('\n', stderr); } - fputc('^', stderr); - fputc('\n', stderr); } } } diff --git a/src/dmd/expressionsem.d b/src/dmd/expressionsem.d index fcec71bed60b..a9e1487d3aa8 100644 --- a/src/dmd/expressionsem.d +++ b/src/dmd/expressionsem.d @@ -43,6 +43,7 @@ import dmd.dtemplate; import dmd.errors; import dmd.escape; import dmd.expression; +import dmd.file_manager; import dmd.func; import dmd.globals; import dmd.hdrgen; @@ -6051,17 +6052,29 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor } { - auto readResult = File.read(name); - if (!readResult.success) + auto fileName = FileName(name.toDString); + if (auto fmResult = FileManager.fileManager.lookup(fileName)) { - e.error("cannot read file `%s`", name); - return setError(); + se = new StringExp(e.loc, fmResult.data); } else { - // take ownership of buffer (probably leaking) - auto data = readResult.extractSlice(); - se = new StringExp(e.loc, data); + auto readResult = File.read(name); + if (!readResult.success) + { + e.error("cannot read file `%s`", name); + return setError(); + } + else + { + // take ownership of buffer (probably leaking) + auto data = readResult.extractSlice(); + se = new StringExp(e.loc, data); + + FileBuffer* fileBuffer = FileBuffer.create(); + fileBuffer.data = data; + FileManager.fileManager.add(fileName, fileBuffer); + } } } result = se.expressionSemantic(sc); diff --git a/src/dmd/file_manager.d b/src/dmd/file_manager.d new file mode 100644 index 000000000000..05aeb7df5dc9 --- /dev/null +++ b/src/dmd/file_manager.d @@ -0,0 +1,301 @@ +/** + * Read a file from disk and store it in memory. + * + * Copyright: Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) + * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/file_manager.d, _file_manager.d) + * Documentation: https://dlang.org/phobos/dmd_file_manager.html + * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/file_manager.d + */ + +module dmd.file_manager; + +import dmd.root.stringtable : StringTable; +import dmd.root.file : File, FileBuffer; +import dmd.root.filename : FileName; +import dmd.root.string : toDString; +import dmd.globals; +import dmd.identifier; + +enum package_d = "package." ~ mars_ext; +enum package_di = "package." ~ hdr_ext; + +extern(C++) struct FileManager +{ + private StringTable!(FileBuffer*) files; + private __gshared bool initialized = false; + +nothrow: + extern(D) private FileBuffer* readToFileBuffer(const(char)[] filename) + { + if (!initialized) + FileManager._init(); + + auto readResult = File.read(filename); + if (readResult.success) + { + FileBuffer* fb; + if (auto val = files.lookup(filename)) + fb = val.value; + + if (!fb) + fb = FileBuffer.create(); + + fb.data = readResult.extractSlice(); + + return files.insert(filename, fb) == null ? null : fb; + } + else + { + return null; + } + + } + + /******************************************** + * Look for the source file if it's different from filename. + * Look for .di, .d, directory, and along global.path. + * Does not open the file. + * Params: + * filename = as supplied by the user + * path = path to look for filename + * Returns: + * the found file name or + * `null` if it is not different from filename. + */ + extern(D) static const(char)[] lookForSourceFile(const char[] filename, const char*[] path) + { + //printf("lookForSourceFile(`%.*s`)\n", cast(int)filename.length, filename.ptr); + /* Search along path[] for .di file, then .d file, then .i file, then .c file. + */ + const sdi = FileName.forceExt(filename, hdr_ext); + if (FileName.exists(sdi) == 1) + return sdi; + scope(exit) FileName.free(sdi.ptr); + + const sd = FileName.forceExt(filename, mars_ext); + if (FileName.exists(sd) == 1) + return sd; + scope(exit) FileName.free(sd.ptr); + + const si = FileName.forceExt(filename, i_ext); + if (FileName.exists(si) == 1) + return si; + scope(exit) FileName.free(si.ptr); + + const sc = FileName.forceExt(filename, c_ext); + if (FileName.exists(sc) == 1) + return sc; + scope(exit) FileName.free(sc.ptr); + + if (FileName.exists(filename) == 2) + { + /* The filename exists and it's a directory. + * Therefore, the result should be: filename/package.d + * iff filename/package.d is a file + */ + const ni = FileName.combine(filename, package_di); + if (FileName.exists(ni) == 1) + return ni; + FileName.free(ni.ptr); + + const n = FileName.combine(filename, package_d); + if (FileName.exists(n) == 1) + return n; + FileName.free(n.ptr); + } + if (FileName.absolute(filename)) + return null; + if (!path.length) + return null; + foreach (entry; path) + { + const p = entry.toDString(); + + const(char)[] n = FileName.combine(p, sdi); + if (FileName.exists(n) == 1) { + return n; + } + FileName.free(n.ptr); + + n = FileName.combine(p, sd); + if (FileName.exists(n) == 1) { + return n; + } + FileName.free(n.ptr); + + n = FileName.combine(p, si); + if (FileName.exists(n) == 1) { + return n; + } + FileName.free(n.ptr); + + n = FileName.combine(p, sc); + if (FileName.exists(n) == 1) { + return n; + } + FileName.free(n.ptr); + + const b = FileName.removeExt(filename); + n = FileName.combine(p, b); + FileName.free(b.ptr); + if (FileName.exists(n) == 2) + { + const n2i = FileName.combine(n, package_di); + if (FileName.exists(n2i) == 1) + return n2i; + FileName.free(n2i.ptr); + const n2 = FileName.combine(n, package_d); + if (FileName.exists(n2) == 1) { + return n2; + } + FileName.free(n2.ptr); + } + FileName.free(n.ptr); + } + return null; + } + + /** + * Looks up the given filename from the internal file buffer table. + * If the file does not already exist within the table, it will be read from the filesystem. + * If it has been read before, + * + * Returns: the loaded source file if it was found in memory, + * otherwise `null` + */ + extern(D) FileBuffer* lookup(FileName filename) + { + if (!initialized) + FileManager._init(); + + if (auto val = files.lookup(filename.toString)) + { + // There is a chance that the buffer could've been + // stolen by a reader with extractSlice, so we should + // try and do our reading logic if that happens. + if (val !is null && val.value.data !is null) + { + return val.value; + } + } + + const name = filename.toString; + auto res = FileName.exists(name); + if (res == 1) + return readToFileBuffer(name); + + const fullName = lookForSourceFile(name, global.path ? (*global.path)[] : null); + if (!fullName) + return null; + + return readToFileBuffer(fullName); + } + + extern(C++) FileBuffer* lookup(const(char)* filename) + { + return lookup(FileName(filename.toDString)); + } + + /** + * Looks up the given filename from the internal file buffer table, and returns the lines within the file. + * If the file does not already exist within the table, it will be read from the filesystem. + * If it has been read before, + * + * Returns: the loaded source file if it was found in memory, + * otherwise `null` + */ + extern(D) const(char)[][] getLines(FileName file) + { + if (!initialized) + FileManager._init(); + + const(char)[][] lines; + if (FileBuffer* buffer = lookup(file)) + { + ubyte[] slice = buffer.data[0 .. buffer.data.length]; + size_t start, end; + ubyte c; + for (auto i = 0; i < slice.length; i++) + { + c = slice[i]; + if (c == '\n' || c == '\r') + { + if (i != 0) + { + end = i; + lines ~= cast(const(char)[])slice[start .. end]; + } + // Check for Windows-style CRLF newlines + if (c == '\r') + { + if (slice.length > i + 1 && slice[i + 1] == '\n') + { + // This is a CRLF sequence, skip over two characters + start = i + 2; + i++; + } + else + { + // Just a CR sequence + start = i + 1; + } + } + else + { + // The next line should start after the LF sequence + start = i + 1; + } + } + } + + if (slice[$ - 1] != '\r' && slice[$ - 1] != '\n') + { + end = slice.length; + lines ~= cast(const(char)[])slice[start .. end]; + } + } + + return lines; + } + + /** + * Adds a FileBuffer to the table. + * + * Returns: The FileBuffer added, or null + */ + extern(D) FileBuffer* add(FileName filename, FileBuffer* filebuffer) + { + if (!initialized) + FileManager._init(); + + auto val = files.insert(filename.toString, filebuffer); + return val == null ? null : val.value; + } + + extern(C++) FileBuffer* add(const(char)* filename, FileBuffer* filebuffer) + { + if (!initialized) + FileManager._init(); + + auto val = files.insert(filename.toDString, filebuffer); + return val == null ? null : val.value; + } + + __gshared fileManager = FileManager(); + + // Initialize the global FileManager singleton + extern(C++) static __gshared void _init() + { + if (!initialized) + { + fileManager.initialize(); + initialized = true; + } + } + + void initialize() + { + files._init(); + } +} diff --git a/src/dmd/file_manager.h b/src/dmd/file_manager.h new file mode 100644 index 000000000000..7488fab17fc2 --- /dev/null +++ b/src/dmd/file_manager.h @@ -0,0 +1,19 @@ + +/* Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved + * written by Walter Bright + * http://www.digitalmars.com + * Distributed under the Boost Software License, Version 1.0. + * http://www.boost.org/LICENSE_1_0.txt + * https://github.com/dlang/dmd/blob/master/src/dmd/file_manager.h + */ + +#pragma once + +#include "root/file.h" + +struct FileManager +{ + static void _init(); + FileBuffer* lookup(const char* filename); + FileBuffer* add(const char* filename, FileBuffer* filebuffer); +}; diff --git a/src/dmd/filecache.d b/src/dmd/filecache.d deleted file mode 100644 index 23c45cba0993..000000000000 --- a/src/dmd/filecache.d +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Cache the contents from files read from disk into memory. - * - * Copyright: Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved - * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) - * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) - * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/filecache.d, filecache.d) - * Documentation: https://dlang.org/phobos/dmd_filecache.html - * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/filecache.d - */ - -module dmd.filecache; - -import dmd.root.stringtable; -import dmd.root.array; -import dmd.root.file; -import dmd.root.filename; - -import core.stdc.stdio; - -/** -A line-by-line representation of a $(REF File, dmd,root,file). -*/ -class FileAndLines -{ - FileName* file; - FileBuffer* buffer; - const(char[])[] lines; - - nothrow: - - /** - File to read and split into its lines. - */ - this(const(char)[] filename) - { - file = new FileName(filename); - readAndSplit(); - } - - // Read a file and split the file buffer linewise - private void readAndSplit() - { - auto readResult = File.read(file.toChars()); - // FIXME: check success - // take ownership of buffer - buffer = new FileBuffer(readResult.extractSlice()); - ubyte* buf = buffer.data.ptr; - // slice into lines - while (*buf) - { - auto prevBuf = buf; - for (; *buf != '\n' && *buf != '\r'; buf++) - { - if (!*buf) - break; - } - // handle Windows line endings - if (*buf == '\r' && *(buf + 1) == '\n') - buf++; - lines ~= cast(const(char)[]) prevBuf[0 .. buf - prevBuf]; - buf++; - } - } - - void destroy() - { - if (file) - { - file.destroy(); - file = null; - buffer.destroy(); - buffer = null; - lines.destroy(); - lines = null; - } - } - - ~this() - { - destroy(); - } -} - -/** -A simple file cache that can be used to avoid reading the same file multiple times. -It stores its cached files as $(LREF FileAndLines) -*/ -struct FileCache -{ - private StringTable!(FileAndLines) files; - - nothrow: - - /** - Add or get a file from the file cache. - If the file isn't part of the cache, it will be read from the filesystem. - If the file has been read before, the cached file object will be returned - - Params: - file = file to load in (or get from) the cache - - Returns: a $(LREF FileAndLines) object containing a line-by-line representation of the requested file - */ - FileAndLines addOrGetFile(const(char)[] file) - { - if (auto payload = files.lookup(file)) - { - if (payload !is null) - return payload.value; - } - - auto lines = new FileAndLines(file); - files.insert(file, lines); - return lines; - } - - __gshared fileCache = FileCache(); - - // Initializes the global FileCache singleton - static __gshared void _init() - { - fileCache.initialize(); - } - - void initialize() - { - files._init(); - } - - void deinitialize() - { - foreach (sv; files) - sv.destroy(); - files.reset(); - } -} diff --git a/src/dmd/frontend.d b/src/dmd/frontend.d index 4a98b0c017dc..c63fe0a6f467 100644 --- a/src/dmd/frontend.d +++ b/src/dmd/frontend.d @@ -116,7 +116,6 @@ void initDMD( import dmd.cond : VersionCondition; import dmd.dmodule : Module; import dmd.expression : Expression; - import dmd.filecache : FileCache; import dmd.globals : CHECKENABLE, global; import dmd.id : Id; import dmd.identifier : Identifier; @@ -148,7 +147,6 @@ void initDMD( Module._init(); Expression._init(); Objc._init(); - FileCache._init(); addDefaultVersionIdentifiers(global.params, target); @@ -401,7 +399,12 @@ Tuple!(Module, "module_", Diagnostics, "diagnostics") parseModule(AST = ASTCodeg buffer: FileBuffer(cast(ubyte[]) code.dup ~ '\0') }; - m.loadSourceBuffer(Loc.initial, readResult); + if (m.loadSourceBuffer(Loc.initial, readResult)) + { + import dmd.file_manager : FileManager; + import dmd.root.filename : FileName; + FileManager.fileManager.add(FileName(fileName), m.srcBuffer); + } } m.parseModule!AST(); diff --git a/src/dmd/frontend.h b/src/dmd/frontend.h index e5f5e972eacd..ed53c9246a71 100644 --- a/src/dmd/frontend.h +++ b/src/dmd/frontend.h @@ -2488,10 +2488,6 @@ struct MatchAccumulator final {} }; -static const char* const package_d = "package.d"; - -static const char* const package_di = "package.di"; - enum class StructFlags { none = 0, @@ -4987,6 +4983,40 @@ enum class CPU native = 12, }; +struct StringEntry final +{ + uint32_t hash; + uint32_t vptr; + StringEntry() : + hash(), + vptr() + { + } + StringEntry(uint32_t hash, uint32_t vptr = 0u) : + hash(hash), + vptr(vptr) + {} +}; + +template +struct StringTable final +{ + // Ignoring var table alignment 0 + _d_dynamicArray< StringEntry > table; + // Ignoring var pools alignment 0 + _d_dynamicArray< uint8_t* > pools; + // Ignoring var nfill alignment 0 + size_t nfill; + // Ignoring var count alignment 0 + size_t count; + // Ignoring var countTrigger alignment 0 + size_t countTrigger; + ~StringTable(); + StringTable() + { + } +}; + typedef _d_real longdouble; class AggregateDeclaration : public ScopeDsymbol @@ -7883,6 +7913,22 @@ extern void fatal(); extern void halt(); +struct FileManager final +{ +private: + StringTable files; + static bool initialized; +public: + FileBuffer* lookup(const char* filename); + FileBuffer* add(const char* filename, FileBuffer* filebuffer); + static FileManager fileManager; + static void _init(); + void initialize(); + FileManager() + { + } +}; + struct Id final { static Identifier* IUnknown; diff --git a/src/dmd/mars.d b/src/dmd/mars.d index fbf8a9664772..1c199cf0c141 100644 --- a/src/dmd/mars.d +++ b/src/dmd/mars.d @@ -38,6 +38,7 @@ import dmd.dtemplate; import dmd.dtoh; import dmd.errors; import dmd.expression; +import dmd.file_manager; import dmd.globals; import dmd.hdrgen; import dmd.id; @@ -300,8 +301,6 @@ private int tryMain(size_t argc, const(char)** argv, ref Param params) Module._init(); Expression._init(); Objc._init(); - import dmd.filecache : FileCache; - FileCache._init(); reconcileLinkRunLib(params, files.dim); version(CRuntime_Microsoft) @@ -362,6 +361,7 @@ private int tryMain(size_t argc, const(char)** argv, ref Param params) { auto buffer = readFromStdin(); m.srcBuffer = new FileBuffer(buffer.extractSlice()); + FileManager.fileManager.add(m.srcfile, m.srcBuffer); } }