├── .gitignore
├── .travis.yml
├── README.md
├── bin
├── dmd
└── rdmd
├── dmd-dscripten.d
├── ldc2.conf
├── rdmd-dscripten.d
├── rt
├── core
│ ├── stdc
│ │ ├── config.d
│ │ ├── errno.d
│ │ ├── fenv.d
│ │ ├── math.d
│ │ ├── stddef.d
│ │ ├── stdio.d
│ │ ├── stdlib.d
│ │ └── time.d
│ └── sys
│ │ └── posix
│ │ ├── stdio.d
│ │ ├── sys
│ │ └── types.d
│ │ └── unistd.d
├── dscripten
│ ├── emscripten.d
│ ├── memory.d
│ ├── standard.d
│ ├── test.d
│ └── typeinfo.d
├── gc
│ ├── config.d
│ ├── gcinterface.d
│ ├── impl
│ │ └── manual
│ │ │ └── gc.d
│ └── proxy.d
├── mainloop.c
├── object.d
├── rt
│ ├── config.d
│ ├── deh.d
│ ├── dmain2.d
│ ├── dwarfeh.d
│ ├── invariant_.d
│ ├── lifetime.d
│ ├── typeinfo
│ │ ├── ti_Acdouble.d
│ │ ├── ti_Acfloat.d
│ │ ├── ti_Acreal.d
│ │ ├── ti_Adouble.d
│ │ ├── ti_Afloat.d
│ │ ├── ti_Ag.d
│ │ ├── ti_Aint.d
│ │ ├── ti_Along.d
│ │ ├── ti_Areal.d
│ │ ├── ti_Ashort.d
│ │ ├── ti_C.d
│ │ ├── ti_byte.d
│ │ ├── ti_cdouble.d
│ │ ├── ti_cent.d
│ │ ├── ti_cfloat.d
│ │ ├── ti_char.d
│ │ ├── ti_creal.d
│ │ ├── ti_dchar.d
│ │ ├── ti_delegate.d
│ │ ├── ti_double.d
│ │ ├── ti_float.d
│ │ ├── ti_idouble.d
│ │ ├── ti_ifloat.d
│ │ ├── ti_int.d
│ │ ├── ti_ireal.d
│ │ ├── ti_long.d
│ │ ├── ti_n.d
│ │ ├── ti_ptr.d
│ │ ├── ti_real.d
│ │ ├── ti_short.d
│ │ ├── ti_ubyte.d
│ │ ├── ti_ucent.d
│ │ ├── ti_uint.d
│ │ ├── ti_ulong.d
│ │ ├── ti_ushort.d
│ │ ├── ti_void.d
│ │ └── ti_wchar.d
│ └── util
│ │ ├── container
│ │ ├── array.d
│ │ ├── common.d
│ │ └── hashtab.d
│ │ ├── hash.d
│ │ └── typeinfo.d
├── runtime.c
├── std
│ ├── ascii.d
│ ├── experimental
│ │ └── allocator
│ │ │ ├── building_blocks
│ │ │ └── free_list.d
│ │ │ ├── mallocator.d
│ │ │ └── package.d
│ ├── math.d
│ ├── stdio.d
│ └── system.d
└── stdx
│ └── allocator
│ ├── mallocator.d
│ └── package.d
└── test
├── .gitignore
├── run-tests.sh
├── t0001-basic
├── output.exp
├── run-test.sh
└── test.d
├── t0002-c
├── output.exp
├── run-test.sh
├── test.c
└── test.d
├── t0003-c-types
├── output.exp
├── run-test.sh
├── test.c
└── test.d
├── t0004-c-includes
├── output.exp
├── run-test.sh
├── test.c
└── test.d
├── t0100-phobos
├── output.exp
├── run-test.sh
└── test.d
├── t0101-d-main
├── output.exp
├── run-test.sh
└── test.d
├── t0102-writeln
├── output.exp
├── run-test.sh
└── test.d
├── t0200-wasm
├── output.exp
├── run-test.sh
└── test.d
└── test-lib.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | /dmd-dscripten
2 | /rdmd-dscripten
3 | *.o
4 | *.bc
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: d
2 | d: dmd-2.076.0
3 |
4 | sudo: false
5 |
6 | install:
7 | # Get the toolchain
8 | # Instead of building it from source, like so:
9 | # - git clone https://github.com/Ace17/dscripten
10 | # - cd dscripten && ./fetch_toolchain
11 | # - cd /tmp && tar Jcvf toolchains.tar.xz --exclude toolchains/emscripten/.git --exclude toolchains/emscripten/tests toolchains
12 | # We get a prebuilt tarball, as building it from source takes VERY long (more than Travis' 60 minutes limit all by itself).
13 | - curl -fsS https://thecybershadow.net/d/toolchains.tar.xz | tar Jxv -C /tmp
14 |
15 | # Initialize and create ~/.emscripten
16 | # Prepend /usr/bin here too, to avoid pyenv bug: https://github.com/pyenv/pyenv/issues/1158
17 | - PATH=/tmp/toolchains/llvm-js/bin:/usr/bin:$PATH /tmp/toolchains/emscripten/emcc --version
18 |
19 | script:
20 | - export DSCRIPTEN_RDMD=$(which rdmd)
21 | - cd test && ./run-tests.sh
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Dscripten Build Tools [](https://travis-ci.org/CyberShadow/dscripten-tools)
2 | =====================
3 |
4 | These allow using [dscripten](https://github.com/Ace17/dscripten) to
5 | compile D code to JavaScript (asm.js) with typical D workflow (dmd and
6 | rdmd).
7 |
8 | Setup
9 | -----
10 |
11 | 1. Run dscripten's `fetch_toolchain` script to download, patch and build LDC and Emscripten.
12 | 2. Build the tools in this directory (e.g. `dmd dmd-dscripten.d && dmd rdmd-dscripten.d`).
13 | 3. (Optional) Set up your environment (see the [Configuration](#configuration) section below).
14 |
15 | Usage
16 | -----
17 |
18 | There are two ways to use this toolchain:
19 |
20 | 1. Invoke the tools directly (e.g. `path/to/rdmd-dscripten --compiler=path/to/dmd-dscripten --build-only worker.d`)
21 | 2. Prepend the `bin` directory to your `PATH`, so that it overrides the standard `dmd` and `rdmd` binaries.
22 |
23 | Because these tools attempt to implement the same command-line interface as dmd/rdmd, the second method can be used with any programs (e.g. build tools, error highlighting in editors) without needing to configure them. For example, Dub can be used to build programs in its `--rdmd` mode.
24 |
25 | In addition to the usual switches and `.d` files, `dmd-dscripten` also understands how to handle `.c`, `.llvm` and `.bc` files on its command line, and will appropriately compile or otherwise include them into the compilation. See the test suite for examples.
26 |
27 | Configuration
28 | -------------
29 |
30 | The tools read a few environment variables:
31 |
32 | - `DSCRIPTEN_RDMD` - path to real `rdmd` binary (default: `/usr/bin/rdmd`)
33 | - `DSCRIPTEN_TOOLCHAINS` - path to toolchains build by `fetch_toolchain` (default: `/tmp/toolchains`)
34 | - `LLVMJS` - path to Dscripten's LDC (default: `$DSCRIPTEN_TOOLCHAINS/llvm-js`)
35 | - `EMSCRIPTEN` - path to Dscripten's Emscripten (default: `$DSCRIPTEN_TOOLCHAINS/emscripten`)
36 | - `DSCRIPTEN_TOOLS` - path to the root of this repository (default: `thisExePath.dirName` - the directory the tool's executable is in)
37 |
38 | Example
39 | -------
40 |
41 | ### `worker.html`
42 |
43 | ```html
44 |
45 |
46 |
Dscripten WebWorker test
47 |
48 |
49 |
58 |
59 |
60 |
61 |
62 |
63 | ```
64 |
65 | ### `worker.d`
66 |
67 | ```d
68 | module worker;
69 |
70 | import core.stdc.stdio;
71 | import core.stdc.string;
72 |
73 | import dscripten.standard;
74 | import dscripten.emscripten;
75 |
76 | import ldc.attributes;
77 |
78 | @assumeUsed
79 | extern(C)
80 | void myFunc(char* data, int size)
81 | {
82 | foreach (i; 0..10)
83 | {
84 | char[32] buf;
85 | sprintf(buf.ptr, "Working... %d", i);
86 | workerRespondProvisionally(buf.ptr[0..strlen(buf.ptr)]);
87 | }
88 | workerRespond("Done!");
89 | }
90 | ```
91 |
92 | Compile with:
93 |
94 | ```shell
95 | $ rdmd-dscripten --compiler=dmd-dscripten --build-only worker.d
96 | ```
97 |
98 | This will create `worker.js`.
99 |
100 | For more examples, see [the testsuite](https://github.com/CyberShadow/dscripten-tools/tree/master/test).
101 |
--------------------------------------------------------------------------------
/bin/dmd:
--------------------------------------------------------------------------------
1 | ../dmd-dscripten
--------------------------------------------------------------------------------
/bin/rdmd:
--------------------------------------------------------------------------------
1 | ../rdmd-dscripten
--------------------------------------------------------------------------------
/dmd-dscripten.d:
--------------------------------------------------------------------------------
1 | /**
2 | Simple DMD driver to build programs targeting the dscripten
3 | toolchain.
4 |
5 | https://github.com/Ace17/dscripten
6 |
7 | Currently geared towards "headless" scripts running from a web
8 | worker (output extension is .js only).
9 | **/
10 |
11 | module dmd_dscripten;
12 |
13 | import core.sys.posix.unistd : isatty;
14 |
15 | import std.algorithm.comparison;
16 | import std.algorithm.iteration;
17 | import std.algorithm.mutation;
18 | import std.algorithm.searching;
19 | import std.array;
20 | import std.digest.digest;
21 | import std.digest.md;
22 | import std.exception;
23 | import std.file;
24 | import std.format;
25 | import std.path;
26 | import std.process;
27 | import std.stdio : stdout, stderr;
28 |
29 | void main(string[] args)
30 | {
31 | bool verbose = args[1..$].canFind("-v") && isatty(stdout.fileno);
32 | if (verbose) stderr.writeln("dmd-dscripten: Args: ", args[1..$]);
33 |
34 | auto toolchainsPath = environment.get("DSCRIPTEN_TOOLCHAINS", "/tmp/toolchains");
35 | auto llvmJSPath = environment.get("LLVMJS", toolchainsPath.buildPath("llvm-js"));
36 | auto emscriptenPath = environment.get("EMSCRIPTEN", toolchainsPath.buildPath("emscripten"));
37 | auto toolsPath = environment.get("DSCRIPTEN_TOOLS", thisExePath.dirName);
38 |
39 | auto compiler = llvmJSPath.buildPath("bin", "ldmd2");
40 | auto compilerOpts = args[1..$];
41 |
42 | void run(string[] args)
43 | {
44 | if (verbose) stderr.writeln("dmd-dscripten: Exec: ", args);
45 | auto result = spawnProcess(args, ["LD_LIBRARY_PATH" : llvmJSPath.buildPath("lib")]).wait();
46 | enforce(result == 0, "%s exited with status %d".format(args[0].baseName, result));
47 | }
48 |
49 | compilerOpts = compilerOpts.map!(
50 | opt => opt.skipOver("@") ? readResponseFile(opt) : [opt]).join;
51 |
52 | // Not only are the produced files not (directly) executable,
53 | // -run changes how the command-line is parsed,
54 | // so detect and forbid it explicitly to avoid any possible weird error messages.
55 | enforce(!compilerOpts.canFind("-run"), "Can't use -run with dscripten!");
56 |
57 | enum objsLink = ".dscripten-objs"; scope(exit) cleanLink(objsLink);
58 | enum rootLink = ".dscripten-root"; scope(exit) cleanLink(rootLink);
59 |
60 | // Include ourselves in the verbose output for rdmd to pick up,
61 | // so that changes in the tools causes a rebuild.
62 | if (compilerOpts.canFind("-v"))
63 | {
64 | stdout.writeln("binary ", toolsPath.buildPath("dmd-dscripten"));
65 | stdout.writeln("binary ", toolsPath.buildPath("rdmd-dscripten"));
66 | }
67 |
68 | // Add runtime to import paths
69 | string objDir, outputFile;
70 | compilerOpts.extract!(opt => opt.startsWith("-of")).each!(opt => outputFile = opt[3..$]);
71 | bool build = compilerOpts.canFind!(arg => !arg.startsWith("-")) && !compilerOpts.canFind("-o-");
72 |
73 | if (build)
74 | {
75 | enforce(outputFile, "Building with no outputFile?");
76 | compilerOpts.extract!(opt => opt.startsWith("-od")).each!(opt => objDir = opt[3..$]);
77 | enforce(objDir, "Building with no objDir?");
78 |
79 | // Ensure the object directory is empty, as we will be globbing it later.
80 | if (objDir.exists && !objDir.dirEntries("*.bc", SpanMode.depth, false).empty)
81 | {
82 | if (objDir.startsWith("/tmp/.rdmd-"))
83 | {
84 | rmdirRecurse(objDir);
85 | mkdir(objDir);
86 | }
87 | else
88 | throw new Exception("Dirty object directory: " ~ objDir);
89 | }
90 |
91 | // rdmd will never add object.d, so add it ourselves
92 | compilerOpts ~= toolsPath.buildPath("rt", "object.d");
93 |
94 | // Ugly work-around for missing -oq
95 | cleanLink(objsLink); symlink(objDir, objsLink);
96 | cleanLink(rootLink); symlink("/" , rootLink);
97 |
98 | foreach (ref arg; compilerOpts)
99 | if (!arg.startsWith("-") && arg.endsWith(".d") && exists(arg))
100 | arg = rootLink ~ absolutePath(arg);
101 |
102 | compilerOpts = ["-output-bc", "-od" ~ objsLink, "-op"] ~ compilerOpts;
103 | }
104 |
105 | // Recognize .c / .llvm / .bc files on the command line, and include them in the compilation accordingly.
106 | auto cFiles = compilerOpts.extract!(arg => !arg.startsWith("-") && arg.endsWith(".c"));
107 | auto llvmFiles = compilerOpts.extract!(arg => !arg.startsWith("-") && arg.endsWith(".llvm"));
108 | auto bcFiles = compilerOpts.extract!(arg => !arg.startsWith("-") && arg.endsWith(".bc"));
109 |
110 | // Extract additional emcc options
111 | string[] emccExtra = compilerOpts.extract!((ref arg) => arg.skipOver("--emcc="));
112 | foreach (opt; compilerOpts.extract!((ref arg) => arg.skipOver("--emcc-s=")))
113 | emccExtra ~= ["-s", opt];
114 |
115 | bool wasm;
116 | if (compilerOpts.extract!(arg => arg == "--wasm"))
117 | wasm = true;
118 |
119 | if (wasm)
120 | compilerOpts ~= [
121 | "-disable-loop-vectorization",
122 | ];
123 |
124 | enum target = "asmjs-unknown-emscripten";
125 | compilerOpts = [
126 | "-mtriple=" ~ target,
127 | "-version=dscripten",
128 | "-conf=" ~ toolsPath.buildPath("ldc2.conf"),
129 | "-I" ~ toolsPath.buildPath("rt"),
130 | "-I" ~ llvmJSPath.buildPath("include", "d"),
131 | ] ~ compilerOpts;
132 |
133 | run([compiler] ~ compilerOpts);
134 |
135 | if (compilerOpts.canFind!(opt => opt.among("-h", "--help")))
136 | {
137 | stderr.writeln();
138 | stderr.writeln("Additional dmd-dscripten options:");
139 | stderr.writeln(" --wasm configure for WebAssembly output");
140 | stderr.writeln(" --emcc=SWITCH pass SWITCH on to emcc's command line");
141 | stderr.writeln(" --emcc-s=OPTION shorthand for --emcc=-s --emcc=OPTION");
142 | stderr.writeln();
143 | stderr.writeln("dmd-dscripten can also accept additional *.c, *.llvm and *.bc files");
144 | stderr.writeln("to include in the build.");
145 | }
146 |
147 | if (build)
148 | {
149 | auto objFiles = dirEntries(objDir, "*.bc", SpanMode.depth, false).map!(de => de.name).array;
150 |
151 | foreach (cFile; cFiles)
152 | {
153 | auto bcFile = objDir.buildPath("c-" ~ toHexString(md5Of(cFile)) ~ ".bc");
154 | run([
155 | emscriptenPath.buildPath("emcc"),
156 | "-c",
157 | cFile,
158 | "-o", bcFile,
159 | // TODO: optimize?
160 | ]);
161 | bcFiles ~= bcFile;
162 | }
163 |
164 | foreach (llvmFile; llvmFiles)
165 | {
166 | auto bcFile = objDir.buildPath("llvm-" ~ toHexString(md5Of(llvmFile)) ~ ".bc");
167 | run([
168 | llvmJSPath.buildPath("bin", "llvm-as"),
169 | llvmFile,
170 | "-o=" ~ bcFile,
171 | ]);
172 | bcFiles ~= bcFile;
173 | }
174 |
175 | objFiles ~= bcFiles;
176 | auto linkedObjFile = objDir.buildPath("_all.bc");
177 |
178 | auto llvmLinker = llvmJSPath.buildPath("bin", "llvm-link");
179 |
180 | run([llvmLinker] ~ objFiles ~ ["-o=" ~ linkedObjFile]);
181 |
182 | // Maybe call 'opt' to optimize (LTO) here?
183 |
184 | auto emccArgs = [
185 | emscriptenPath.buildPath("emcc"),
186 | ];
187 |
188 | // TODO: make this customizable somehow
189 | // It doesn't hurt for any use case, though, just adds some
190 | // WebWorker-specific declarations to the .js output.
191 | if (true)
192 | emccArgs ~= [
193 | "-s", "BUILD_AS_WORKER=1",
194 | ];
195 |
196 | bool optimize;
197 |
198 | if (compilerOpts.canFind("-O"))
199 | optimize = true;
200 |
201 | if (wasm)
202 | {
203 | // Works around error:
204 | // failed to asynchronously prepare wasm: LinkError:
205 | // WebAssembly Instantiation: Import #6 module="env"
206 | // function="core.cpuid.__ModuleInfo" error: global import
207 | // must be a number
208 | optimize = true;
209 | }
210 |
211 | if (optimize)
212 | emccArgs ~= "-O3";
213 |
214 | emccArgs ~= [
215 | "--memory-init-file", "0",
216 | "--target=" ~ target,
217 | "-S",
218 | "-w", linkedObjFile,
219 | "-o", outputFile ~ ".js",
220 | ];
221 |
222 | if (wasm)
223 | emccArgs ~= ["-s", "WASM=1"];
224 |
225 | emccArgs ~= emccExtra;
226 |
227 | run(emccArgs);
228 | if (exists(outputFile ~ ".js"))
229 | rename(outputFile ~ ".js", outputFile);
230 | }
231 | }
232 |
233 | /// Remove and return all elements of `arr` matching `pred`.
234 | string[] extract(alias pred)(ref string[] arr)
235 | {
236 | string[] result;
237 | size_t i = 0;
238 | while (i < arr.length)
239 | {
240 | auto e = arr[i];
241 | if (pred(e))
242 | {
243 | result ~= e;
244 | arr = arr.remove(i);
245 | }
246 | else
247 | i++;
248 | }
249 | return result;
250 | }
251 |
252 | void cleanLink(string link)
253 | {
254 | try
255 | remove(link);
256 | catch (Exception) {}
257 | }
258 |
259 | string[] readResponseFile(string fileName)
260 | {
261 | auto s = fileName.readText;
262 | string[] result;
263 | string arg;
264 | bool inQuote, backslash;
265 | foreach (c; s)
266 | {
267 | if (backslash)
268 | {
269 | arg ~= c;
270 | backslash = false;
271 | }
272 | else
273 | if (c == '\\')
274 | backslash = true;
275 | else
276 | if (c == '"')
277 | inQuote = !inQuote;
278 | else
279 | if ((c == ' ' || c == '\r' || c == '\n') && !inQuote)
280 | {
281 | if (arg.length)
282 | result ~= arg;
283 | arg = null;
284 | }
285 | else
286 | arg ~= c;
287 | }
288 | if (arg.length)
289 | result ~= arg;
290 | return result;
291 | }
292 |
--------------------------------------------------------------------------------
/ldc2.conf:
--------------------------------------------------------------------------------
1 | default:
2 | {
3 | switches = [];
4 | };
5 |
--------------------------------------------------------------------------------
/rdmd-dscripten.d:
--------------------------------------------------------------------------------
1 | /**
2 | Simple rdmd wrapper to build programs targeting the dscripten
3 | toolchain.
4 |
5 | https://github.com/Ace17/dscripten
6 |
7 | Currently geared towards "headless" scripts running from a web
8 | worker (output extension is .js only).
9 | **/
10 |
11 | module rdmd_dscripten;
12 |
13 | import std.algorithm.searching;
14 | import std.path;
15 | import std.process;
16 | import std.range.primitives;
17 | import std.stdio;
18 |
19 | void main(string[] args)
20 | {
21 | bool verbose = args[1..$].canFind("--chatty");
22 | if (verbose) stderr.writeln("rdmd-dscripten: Args: ", args[1..$]);
23 |
24 | auto realRDMD = environment.get("DSCRIPTEN_RDMD", "/usr/bin/rdmd");
25 |
26 | auto rdmdOpts = args[1..$];
27 |
28 | // Force .js file extension.
29 | // rdmd can't figure it out otherwise.
30 | auto nonOptions = args[1..$].find!(arg => !arg.startsWith("-"));
31 | if (!nonOptions.empty)
32 | {
33 | auto mainFile = nonOptions.front;
34 | auto jsFile = mainFile.setExtension(".js");
35 | rdmdOpts = ["-of" ~ jsFile] ~ rdmdOpts;
36 | }
37 |
38 | // Compile code in Druntime/Phobos modules.
39 | // Needed to use non-templated functions/types.
40 | // Normally, they are in libphobos.a or such, but there is no
41 | // equivalent in our case.
42 | // If necessary, this can be canceled out again by using --exclude
43 | // on this rdmd's command line.
44 | rdmdOpts = [
45 | "--include=std",
46 | "--include=etc",
47 | "--include=core",
48 | ] ~ rdmdOpts;
49 |
50 | auto cmdLine = [realRDMD] ~ rdmdOpts;
51 | if (verbose) stderr.writeln("rdmd-dscripten: Exec: ", cmdLine);
52 | execv(cmdLine[0], cmdLine);
53 | throw new Exception("Failed to exec into " ~ realRDMD);
54 | }
55 |
--------------------------------------------------------------------------------
/rt/core/stdc/config.d:
--------------------------------------------------------------------------------
1 | /**
2 | * D header file for C99.
3 | *
4 | * Copyright: Copyright Sean Kelly 2005 - 2009.
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: Sean Kelly
9 | * Source: $(DRUNTIMESRC core/stdc/_config.d)
10 | * Standards: ISO/IEC 9899:1999 (E)
11 | */
12 |
13 | module core.stdc.config;
14 |
15 | version (OSX)
16 | version = Darwin;
17 | else version (iOS)
18 | version = Darwin;
19 | else version (TVOS)
20 | version = Darwin;
21 | else version (WatchOS)
22 | version = Darwin;
23 |
24 | extern (C):
25 | @trusted: // Types only.
26 | nothrow:
27 | @nogc:
28 |
29 | version( Windows )
30 | {
31 | struct __c_long
32 | {
33 | pure nothrow @nogc @safe:
34 | this(int x) { lng = x; }
35 | int lng;
36 | alias lng this;
37 | }
38 |
39 | struct __c_ulong
40 | {
41 | pure nothrow @nogc @safe:
42 | this(uint x) { lng = x; }
43 | uint lng;
44 | alias lng this;
45 | }
46 |
47 | /*
48 | * This is cpp_long instead of c_long because:
49 | * 1. Implicit casting of an int to __c_long doesn't happen, because D doesn't
50 | * allow constructor calls in implicit conversions.
51 | * 2. long lng;
52 | * cast(__c_long)lng;
53 | * does not work because lng has to be implicitly cast to an int in the constructor,
54 | * and since that truncates it is not done.
55 | * Both of these break existing code, so until we find a resolution the types are named
56 | * cpp_xxxx.
57 | */
58 |
59 | alias __c_long cpp_long;
60 | alias __c_ulong cpp_ulong;
61 |
62 | alias int c_long;
63 | alias uint c_ulong;
64 | }
65 | else version( Posix )
66 | {
67 | static if( (void*).sizeof > int.sizeof )
68 | {
69 | alias long c_long;
70 | alias ulong c_ulong;
71 | }
72 | else
73 | {
74 | struct __c_long
75 | {
76 | pure nothrow @nogc @safe:
77 | this(int x) { lng = x; }
78 | int lng;
79 | alias lng this;
80 | }
81 |
82 | struct __c_ulong
83 | {
84 | pure nothrow @nogc @safe:
85 | this(uint x) { lng = x; }
86 | uint lng;
87 | alias lng this;
88 | }
89 |
90 | alias __c_long cpp_long;
91 | alias __c_ulong cpp_ulong;
92 |
93 | alias int c_long;
94 | alias uint c_ulong;
95 | }
96 | }
97 | else version( dscripten )
98 | {
99 | alias int c_long;
100 | alias uint c_ulong;
101 | }
102 |
103 | version( CRuntime_Microsoft )
104 | {
105 | /* long double is 64 bits, not 80 bits, but is mangled differently
106 | * than double. To distinguish double from long double, create a wrapper to represent
107 | * long double, then recognize that wrapper specially in the compiler
108 | * to generate the correct name mangling and correct function call/return
109 | * ABI conformance.
110 | */
111 | struct __c_long_double
112 | {
113 | pure nothrow @nogc @safe:
114 | this(double d) { ld = d; }
115 | double ld;
116 | alias ld this;
117 | }
118 |
119 | alias __c_long_double c_long_double;
120 | }
121 | else version( DigitalMars )
122 | {
123 | version( X86 )
124 | {
125 | alias real c_long_double;
126 | }
127 | else version( X86_64 )
128 | {
129 | version( linux )
130 | alias real c_long_double;
131 | else version( FreeBSD )
132 | alias real c_long_double;
133 | else version( OpenBSD )
134 | alias real c_long_double;
135 | else version( NetBSD )
136 | alias real c_long_double;
137 | else version( Solaris )
138 | alias real c_long_double;
139 | else version( Darwin )
140 | alias real c_long_double;
141 | }
142 | }
143 | else version( GNU )
144 | alias real c_long_double;
145 | else version( LDC )
146 | alias real c_long_double;
147 | else version( SDC )
148 | {
149 | version( X86 )
150 | alias real c_long_double;
151 | else version( X86_64 )
152 | alias real c_long_double;
153 | }
154 |
155 | static assert(is(c_long_double), "c_long_double needs to be declared for this platform/architecture.");
156 |
--------------------------------------------------------------------------------
/rt/core/stdc/stddef.d:
--------------------------------------------------------------------------------
1 | /**
2 | * D header file for C99.
3 | *
4 | * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stddef.h.html, _stddef.h)
5 | *
6 | * Copyright: Copyright Sean Kelly 2005 - 2009.
7 | * License: Distributed under the
8 | * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
9 | * (See accompanying file LICENSE)
10 | * Authors: Sean Kelly
11 | * Source: $(DRUNTIMESRC core/stdc/_stddef.d)
12 | * Standards: ISO/IEC 9899:1999 (E)
13 | */
14 |
15 | module core.stdc.stddef;
16 |
17 | extern (C):
18 | @trusted: // Types only.
19 | nothrow:
20 | @nogc:
21 |
22 | // size_t and ptrdiff_t are defined in the object module.
23 |
24 | version( Windows )
25 | {
26 | ///
27 | alias wchar wchar_t;
28 | }
29 | else version( Posix )
30 | {
31 | ///
32 | alias dchar wchar_t;
33 | }
34 | else version( dscripten )
35 | {
36 | alias dchar wchar_t;
37 | }
38 |
--------------------------------------------------------------------------------
/rt/core/stdc/stdlib.d:
--------------------------------------------------------------------------------
1 | /**
2 | * D header file for C99.
3 | *
4 | * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdlib.h.html, _stdlib.h)
5 | *
6 | * Copyright: Copyright Sean Kelly 2005 - 2014.
7 | * License: Distributed under the
8 | * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
9 | * (See accompanying file LICENSE)
10 | * Authors: Sean Kelly
11 | * Standards: ISO/IEC 9899:1999 (E)
12 | * Source: $(DRUNTIMESRC src/core/stdc/_stdlib.d)
13 | */
14 |
15 | module core.stdc.stdlib;
16 |
17 | private import core.stdc.config;
18 | public import core.stdc.stddef; // for wchar_t
19 |
20 | version (OSX)
21 | version = Darwin;
22 | else version (iOS)
23 | version = Darwin;
24 | else version (TVOS)
25 | version = Darwin;
26 | else version (WatchOS)
27 | version = Darwin;
28 |
29 | extern (C):
30 | @system:
31 |
32 | /* Placed outside @nogc in order to not constrain what the callback does.
33 | */
34 | ///
35 | alias int function(scope const void*, scope const void*) _compare_fp_t;
36 | ///
37 | inout(void)* bsearch(scope const void* key, scope inout(void)* base, size_t nmemb, size_t size, _compare_fp_t compar);
38 | ///
39 | void qsort(scope void* base, size_t nmemb, size_t size, _compare_fp_t compar);
40 |
41 |
42 | nothrow:
43 | @nogc:
44 |
45 | ///
46 | struct div_t
47 | {
48 | int quot,
49 | rem;
50 | }
51 |
52 | ///
53 | struct ldiv_t
54 | {
55 | int quot,
56 | rem;
57 | }
58 |
59 | ///
60 | struct lldiv_t
61 | {
62 | long quot,
63 | rem;
64 | }
65 |
66 | ///
67 | enum EXIT_SUCCESS = 0;
68 | ///
69 | enum EXIT_FAILURE = 1;
70 | ///
71 | enum MB_CUR_MAX = 1;
72 |
73 | ///
74 | version(Windows) enum RAND_MAX = 0x7fff;
75 | else version(CRuntime_Glibc) enum RAND_MAX = 0x7fffffff;
76 | else version(Darwin) enum RAND_MAX = 0x7fffffff;
77 | else version(FreeBSD) enum RAND_MAX = 0x7fffffff;
78 | else version(NetBSD) enum RAND_MAX = 0x7fffffff;
79 | else version(OpenBSD) enum RAND_MAX = 0x7fffffff;
80 | else version(Solaris) enum RAND_MAX = 0x7fff;
81 | else version(CRuntime_Bionic) enum RAND_MAX = 0x7fffffff;
82 | else version(dscripten) enum RAND_MAX = 0x7fffffff; // TODO!
83 | else static assert( false, "Unsupported platform" );
84 |
85 | ///
86 | double atof(scope const char* nptr);
87 | ///
88 | int atoi(scope const char* nptr);
89 | ///
90 | c_long atol(scope const char* nptr);
91 | ///
92 | long atoll(scope const char* nptr);
93 |
94 | ///
95 | double strtod(scope inout(char)* nptr, scope inout(char)** endptr);
96 | ///
97 | float strtof(scope inout(char)* nptr, scope inout(char)** endptr);
98 | ///
99 | c_long strtol(scope inout(char)* nptr, scope inout(char)** endptr, int base);
100 | ///
101 | long strtoll(scope inout(char)* nptr, scope inout(char)** endptr, int base);
102 | ///
103 | c_ulong strtoul(scope inout(char)* nptr, scope inout(char)** endptr, int base);
104 | ///
105 | ulong strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);
106 |
107 | version (CRuntime_Microsoft)
108 | {
109 | // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
110 | ///
111 | extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
112 | { // Fake it 'till we make it
113 | return strtod(nptr, endptr);
114 | }
115 | }
116 | else version (MinGW)
117 | {
118 | ///
119 | real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
120 | ///
121 | alias __mingw_strtold strtold;
122 | }
123 | else version (CRuntime_Bionic)
124 | {
125 | ///
126 | real strtold(scope inout(char)* nptr, scope inout(char)** endptr)
127 | { // Fake it again till we make it
128 | return strtod(nptr, endptr);
129 | }
130 | }
131 | else
132 | {
133 | ///
134 | real strtold(scope inout(char)* nptr, scope inout(char)** endptr);
135 | }
136 |
137 | // No unsafe pointer manipulation.
138 | @trusted
139 | {
140 | version(CRuntime_Bionic)
141 | {
142 | import core.sys.posix.stdlib: lrand48, srand48;
143 | ///
144 | alias core.sys.posix.stdlib.lrand48 rand;
145 | ///
146 | alias core.sys.posix.stdlib.srand48 srand;
147 | }
148 | else
149 | {
150 | ///
151 | int rand();
152 | ///
153 | void srand(uint seed);
154 | }
155 | }
156 |
157 | // We don't mark these @trusted. Given that they return a void*, one has
158 | // to do a pointer cast to do anything sensible with the result. Thus,
159 | // functions using these already have to be @trusted, allowing them to
160 | // call @system stuff anyway.
161 | ///
162 | void* malloc(size_t size);
163 | ///
164 | void* calloc(size_t nmemb, size_t size);
165 | ///
166 | void* realloc(void* ptr, size_t size);
167 | ///
168 | void free(void* ptr);
169 |
170 | ///
171 | void abort() @safe;
172 | ///
173 | void exit(int status);
174 | ///
175 | int atexit(void function() func);
176 | ///
177 | void _Exit(int status);
178 |
179 | ///
180 | char* getenv(scope const char* name);
181 | ///
182 | int system(scope const char* string);
183 |
184 | // These only operate on integer values.
185 | @trusted
186 | {
187 | ///
188 | pure int abs(int j);
189 | ///
190 | pure c_long labs(c_long j);
191 | ///
192 | pure long llabs(long j);
193 |
194 | ///
195 | div_t div(int numer, int denom);
196 | ///
197 | ldiv_t ldiv(c_long numer, c_long denom);
198 | ///
199 | lldiv_t lldiv(long numer, long denom);
200 | }
201 |
202 | ///
203 | int mblen(scope const char* s, size_t n);
204 | ///
205 | int mbtowc(scope wchar_t* pwc, scope const char* s, size_t n);
206 | ///
207 | int wctomb(scope char* s, wchar_t wc);
208 | ///
209 | size_t mbstowcs(scope wchar_t* pwcs, scope const char* s, size_t n);
210 | ///
211 | size_t wcstombs(scope char* s, scope const wchar_t* pwcs, size_t n);
212 |
213 | ///
214 | version( DigitalMars )
215 | {
216 | // See malloc comment about @trusted.
217 | void* alloca(size_t size) pure; // non-standard
218 | }
219 | else version( GNU )
220 | {
221 | void* alloca(size_t size) pure; // compiler intrinsic
222 | }
223 | else version( LDC )
224 | {
225 | pragma(LDC_alloca)
226 | void* alloca(size_t size) pure;
227 | }
228 |
229 | version( CRuntime_Microsoft )
230 | {
231 | ///
232 | ulong _strtoui64(scope inout(char)*, scope inout(char)**,int);
233 | ///
234 | ulong _wcstoui64(scope inout(wchar)*, scope inout(wchar)**,int);
235 |
236 | ///
237 | long _strtoi64(scope inout(char)*, scope inout(char)**,int);
238 | ///
239 | long _wcstoi64(scope inout(wchar)*, scope inout(wchar)**,int);
240 | }
241 |
--------------------------------------------------------------------------------
/rt/core/stdc/time.d:
--------------------------------------------------------------------------------
1 | /**
2 | * D header file for C99.
3 | *
4 | * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_time.h.html, _time.h)
5 | *
6 | * Copyright: Copyright Sean Kelly 2005 - 2009.
7 | * License: Distributed under the
8 | * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
9 | * (See accompanying file LICENSE)
10 | * Authors: Sean Kelly,
11 | * Alex Rønne Petersen
12 | * Source: $(DRUNTIMESRC core/stdc/_time.d)
13 | * Standards: ISO/IEC 9899:1999 (E)
14 | */
15 |
16 | module core.stdc.time;
17 |
18 | private import core.stdc.config;
19 |
20 | version (OSX)
21 | version = Darwin;
22 | else version (iOS)
23 | version = Darwin;
24 | else version (TVOS)
25 | version = Darwin;
26 | else version (WatchOS)
27 | version = Darwin;
28 |
29 | extern (C):
30 | @trusted: // There are only a few functions here that use unsafe C strings.
31 | nothrow:
32 | @nogc:
33 |
34 | version( Windows )
35 | {
36 | ///
37 | struct tm
38 | {
39 | int tm_sec; /// seconds after the minute - [0, 60]
40 | int tm_min; /// minutes after the hour - [0, 59]
41 | int tm_hour; /// hours since midnight - [0, 23]
42 | int tm_mday; /// day of the month - [1, 31]
43 | int tm_mon; /// months since January - [0, 11]
44 | int tm_year; /// years since 1900
45 | int tm_wday; /// days since Sunday - [0, 6]
46 | int tm_yday; /// days since January 1 - [0, 365]
47 | int tm_isdst; /// Daylight Saving Time flag
48 | }
49 | }
50 | else version( Posix )
51 | {
52 | ///
53 | struct tm
54 | {
55 | int tm_sec; /// seconds after the minute [0-60]
56 | int tm_min; /// minutes after the hour [0-59]
57 | int tm_hour; /// hours since midnight [0-23]
58 | int tm_mday; /// day of the month [1-31]
59 | int tm_mon; /// months since January [0-11]
60 | int tm_year; /// years since 1900
61 | int tm_wday; /// days since Sunday [0-6]
62 | int tm_yday; /// days since January 1 [0-365]
63 | int tm_isdst; /// Daylight Savings Time flag
64 | c_long tm_gmtoff; /// offset from CUT in seconds
65 | char* tm_zone; /// timezone abbreviation
66 | }
67 | }
68 | else version( dscripten )
69 | {
70 | // TODO
71 | struct tm
72 | {
73 | int tm_sec; /// seconds after the minute [0-60]
74 | int tm_min; /// minutes after the hour [0-59]
75 | int tm_hour; /// hours since midnight [0-23]
76 | int tm_mday; /// day of the month [1-31]
77 | int tm_mon; /// months since January [0-11]
78 | int tm_year; /// years since 1900
79 | int tm_wday; /// days since Sunday [0-6]
80 | int tm_yday; /// days since January 1 [0-365]
81 | int tm_isdst; /// Daylight Savings Time flag
82 | }
83 | }
84 |
85 | version ( Posix )
86 | {
87 | public import core.sys.posix.sys.types : time_t, clock_t;
88 | }
89 | else version ( Windows )
90 | {
91 | ///
92 | alias c_long time_t;
93 | ///
94 | alias c_long clock_t;
95 | }
96 | else version ( dscripten )
97 | {
98 | alias int time_t; // TODO
99 | alias int clock_t; // TODO
100 | }
101 |
102 | ///
103 | version( Windows )
104 | {
105 | enum clock_t CLOCKS_PER_SEC = 1000;
106 | }
107 | else version( OSX )
108 | {
109 | enum clock_t CLOCKS_PER_SEC = 100;
110 | }
111 | else version( Darwin ) // other Darwins (iOS, TVOS, WatchOS)
112 | {
113 | enum clock_t CLOCKS_PER_SEC = 1_000_000;
114 | }
115 | else version( FreeBSD )
116 | {
117 | enum clock_t CLOCKS_PER_SEC = 128;
118 | }
119 | else version( NetBSD )
120 | {
121 | enum clock_t CLOCKS_PER_SEC = 100;
122 | }
123 | else version( OpenBSD )
124 | {
125 | enum clock_t CLOCKS_PER_SEC = 100;
126 | }
127 | else version (CRuntime_Glibc)
128 | {
129 | enum clock_t CLOCKS_PER_SEC = 1_000_000;
130 | }
131 | else version (CRuntime_Bionic)
132 | {
133 | enum clock_t CLOCKS_PER_SEC = 1_000_000;
134 | }
135 |
136 | ///
137 | clock_t clock();
138 | ///
139 | double difftime(time_t time1, time_t time0);
140 | ///
141 | time_t mktime(tm* timeptr);
142 | ///
143 | time_t time(time_t* timer);
144 | ///
145 | char* asctime(in tm* timeptr);
146 | ///
147 | char* ctime(in time_t* timer);
148 | ///
149 | tm* gmtime(in time_t* timer);
150 | ///
151 | tm* localtime(in time_t* timer);
152 | ///
153 | @system size_t strftime(char* s, size_t maxsize, in char* format, in tm* timeptr);
154 |
155 | version( Windows )
156 | {
157 | ///
158 | void tzset(); // non-standard
159 | ///
160 | void _tzset(); // non-standard
161 | ///
162 | @system char* _strdate(char* s); // non-standard
163 | ///
164 | @system char* _strtime(char* s); // non-standard
165 |
166 | ///
167 | extern __gshared const(char)*[2] tzname; // non-standard
168 | }
169 | else version( Darwin )
170 | {
171 | ///
172 | void tzset(); // non-standard
173 | ///
174 | extern __gshared const(char)*[2] tzname; // non-standard
175 | }
176 | else version( CRuntime_Glibc )
177 | {
178 | ///
179 | void tzset(); // non-standard
180 | ///
181 | extern __gshared const(char)*[2] tzname; // non-standard
182 | }
183 | else version( FreeBSD )
184 | {
185 | ///
186 | void tzset(); // non-standard
187 | ///
188 | extern __gshared const(char)*[2] tzname; // non-standard
189 | }
190 | else version( NetBSD )
191 | {
192 | ///
193 | void tzset(); // non-standard
194 | ///
195 | extern __gshared const(char)*[2] tzname; // non-standard
196 | }
197 | else version( OpenBSD )
198 | {
199 | ///
200 | void tzset(); // non-standard
201 | ///
202 | extern __gshared const(char)*[2] tzname; // non-standard
203 | }
204 | else version (Solaris)
205 | {
206 | ///
207 | void tzset();
208 | ///
209 | extern __gshared const(char)*[2] tzname;
210 | }
211 | else version( CRuntime_Bionic )
212 | {
213 | ///
214 | void tzset();
215 | ///
216 | extern __gshared const(char)*[2] tzname;
217 | }
218 | else version( dscripten )
219 | {
220 | }
221 | else
222 | {
223 | static assert(false, "Unsupported platform");
224 | }
225 |
--------------------------------------------------------------------------------
/rt/core/sys/posix/stdio.d:
--------------------------------------------------------------------------------
1 | /**
2 | * D header file for POSIX.
3 | *
4 | * Copyright: Copyright Sean Kelly 2005 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Sean Kelly
7 | * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8 | */
9 |
10 | /* Copyright Sean Kelly 2005 - 2009.
11 | * Distributed under the Boost Software License, Version 1.0.
12 | * (See accompanying file LICENSE or copy at
13 | * http://www.boost.org/LICENSE_1_0.txt)
14 | */
15 | module core.sys.posix.stdio;
16 |
17 | private import core.sys.posix.config;
18 | public import core.stdc.stdio;
19 | public import core.sys.posix.sys.types; // for off_t
20 |
21 | version (OSX)
22 | version = Darwin;
23 | else version (iOS)
24 | version = Darwin;
25 | else version (TVOS)
26 | version = Darwin;
27 | else version (WatchOS)
28 | version = Darwin;
29 |
30 | version (Posix)
31 | version = Posixish;
32 | else
33 | version (dscripten)
34 | version = Posixish;
35 |
36 | version (Posixish):
37 | extern (C):
38 |
39 | nothrow:
40 | @nogc:
41 |
42 | //
43 | // Required (defined in core.stdc.stdio)
44 | //
45 | /*
46 | BUFSIZ
47 | _IOFBF
48 | _IOLBF
49 | _IONBF
50 | L_tmpnam
51 | SEEK_CUR
52 | SEEK_END
53 | SEEK_SET
54 | FILENAME_MAX
55 | FOPEN_MAX
56 | TMP_MAX
57 | EOF
58 | NULL
59 | stderr
60 | stdin
61 | stdout
62 | FILE
63 | fpos_t
64 | size_t
65 |
66 | void clearerr(FILE*);
67 | int fclose(FILE*);
68 | int feof(FILE*);
69 | int ferror(FILE*);
70 | int fflush(FILE*);
71 | int fgetc(FILE*);
72 | int fgetpos(FILE*, fpos_t *);
73 | char* fgets(char*, int, FILE*);
74 | FILE* fopen(in char*, in char*);
75 | int fprintf(FILE*, in char*, ...);
76 | int fputc(int, FILE*);
77 | int fputs(in char*, FILE*);
78 | size_t fread(void *, size_t, size_t, FILE*);
79 | FILE* freopen(in char*, in char*, FILE*);
80 | int fscanf(FILE*, in char*, ...);
81 | int fseek(FILE*, c_long, int);
82 | int fsetpos(FILE*, in fpos_t*);
83 | c_long ftell(FILE*);
84 | size_t fwrite(in void *, size_t, size_t, FILE*);
85 | int getc(FILE*);
86 | int getchar();
87 | char* gets(char*);
88 | void perror(in char*);
89 | int printf(in char*, ...);
90 | int putc(int, FILE*);
91 | int putchar(int);
92 | int puts(in char*);
93 | int remove(in char*);
94 | int rename(in char*, in char*);
95 | void rewind(FILE*);
96 | int scanf(in char*, ...);
97 | void setbuf(FILE*, char*);
98 | int setvbuf(FILE*, char*, int, size_t);
99 | int snprintf(char*, size_t, in char*, ...);
100 | int sprintf(char*, in char*, ...);
101 | int sscanf(in char*, in char*, int ...);
102 | FILE* tmpfile();
103 | char* tmpnam(char*);
104 | int ungetc(int, FILE*);
105 | int vfprintf(FILE*, in char*, va_list);
106 | int vfscanf(FILE*, in char*, va_list);
107 | int vprintf(in char*, va_list);
108 | int vscanf(in char*, va_list);
109 | int vsnprintf(char*, size_t, in char*, va_list);
110 | int vsprintf(char*, in char*, va_list);
111 | int vsscanf(in char*, in char*, va_list arg);
112 | */
113 |
114 | version( CRuntime_Glibc )
115 | {
116 | /*
117 | * actually, if __USE_FILE_OFFSET64 && !_LARGEFILE64_SOURCE
118 | * the *64 functions shouldn't be visible, but the aliases should
119 | * still be supported
120 | */
121 | static if( __USE_FILE_OFFSET64 )
122 | {
123 | int fgetpos64(FILE*, fpos_t *);
124 | alias fgetpos64 fgetpos;
125 |
126 | FILE* fopen64(in char*, in char*);
127 | alias fopen64 fopen;
128 |
129 | FILE* freopen64(in char*, in char*, FILE*);
130 | alias freopen64 freopen;
131 |
132 | int fseek(FILE*, c_long, int);
133 |
134 | int fsetpos64(FILE*, in fpos_t*);
135 | alias fsetpos64 fsetpos;
136 |
137 | FILE* tmpfile64();
138 | alias tmpfile64 tmpfile;
139 | }
140 | else
141 | {
142 | int fgetpos(FILE*, fpos_t *);
143 | FILE* fopen(in char*, in char*);
144 | FILE* freopen(in char*, in char*, FILE*);
145 | int fseek(FILE*, c_long, int);
146 | int fsetpos(FILE*, in fpos_t*);
147 | FILE* tmpfile();
148 | }
149 | }
150 | else version( CRuntime_Bionic )
151 | {
152 | int fgetpos(FILE*, fpos_t *);
153 | FILE* fopen(in char*, in char*);
154 | FILE* freopen(in char*, in char*, FILE*);
155 | int fseek(FILE*, c_long, int);
156 | int fsetpos(FILE*, in fpos_t*);
157 | }
158 |
159 | //
160 | // C Extension (CX)
161 | //
162 | /*
163 | L_ctermid
164 |
165 | char* ctermid(char*);
166 | FILE* fdopen(int, in char*);
167 | int fileno(FILE*);
168 | int fseeko(FILE*, off_t, int);
169 | off_t ftello(FILE*);
170 | char* gets(char*);
171 | int pclose(FILE*);
172 | FILE* popen(in char*, in char*);
173 | */
174 |
175 | version( CRuntime_Glibc )
176 | {
177 | enum L_ctermid = 9;
178 |
179 | static if( __USE_FILE_OFFSET64 )
180 | {
181 | int fseeko64(FILE*, off_t, int);
182 | alias fseeko64 fseeko;
183 | }
184 | else
185 | {
186 | int fseeko(FILE*, off_t, int);
187 | }
188 |
189 | static if( __USE_FILE_OFFSET64 )
190 | {
191 | off_t ftello64(FILE*);
192 | alias ftello64 ftello;
193 | }
194 | else
195 | {
196 | off_t ftello(FILE*);
197 | }
198 | }
199 | else version( dscripten )
200 | {
201 | int fseeko(FILE*, off_t, int);
202 | off_t ftello(FILE*);
203 | }
204 | else version( Posix )
205 | {
206 | int fseeko(FILE*, off_t, int);
207 | off_t ftello(FILE*);
208 | }
209 |
210 | char* ctermid(char*);
211 | FILE* fdopen(int, in char*);
212 | int fileno(FILE*);
213 | //int fseeko(FILE*, off_t, int);
214 | //off_t ftello(FILE*);
215 | char* gets(char*);
216 | int pclose(FILE*);
217 | FILE* popen(in char*, in char*);
218 |
219 |
220 | // memstream functions are conforming to POSIX.1-2008. These functions are
221 | // not specified in POSIX.1-2001 and are not widely available on other
222 | // systems.
223 | version( CRuntime_Glibc ) // as of glibc 1.0x
224 | version = HaveMemstream;
225 | else version( FreeBSD ) // as of FreeBSD 9.2
226 | version = HaveMemstream;
227 | else version( OpenBSD ) // as of OpenBSD 5.4
228 | version = HaveMemstream;
229 |
230 | version( HaveMemstream )
231 | {
232 | FILE* fmemopen(in void* buf, in size_t size, in char* mode);
233 | FILE* open_memstream(char** ptr, size_t* sizeloc);
234 | FILE* open_wmemstream(wchar_t** ptr, size_t* sizeloc);
235 | }
236 |
237 | //
238 | // Thread-Safe Functions (TSF)
239 | //
240 | /*
241 | void flockfile(FILE*);
242 | int ftrylockfile(FILE*);
243 | void funlockfile(FILE*);
244 | int getc_unlocked(FILE*);
245 | int getchar_unlocked();
246 | int putc_unlocked(int, FILE*);
247 | int putchar_unlocked(int);
248 | */
249 |
250 | version( CRuntime_Glibc )
251 | {
252 | void flockfile(FILE*);
253 | int ftrylockfile(FILE*);
254 | void funlockfile(FILE*);
255 | int getc_unlocked(FILE*);
256 | int getchar_unlocked();
257 | int putc_unlocked(int, FILE*);
258 | int putchar_unlocked(int);
259 | }
260 | else version( OpenBSD )
261 | {
262 | void flockfile(FILE*);
263 | int ftrylockfile(FILE*);
264 | void funlockfile(FILE*);
265 | int getc_unlocked(FILE*);
266 | int getchar_unlocked();
267 | int putc_unlocked(int, FILE*);
268 | int putchar_unlocked(int);
269 | }
270 | else version( Solaris )
271 | {
272 | void flockfile(FILE*);
273 | int ftrylockfile(FILE*);
274 | void funlockfile(FILE*);
275 | int getc_unlocked(FILE*);
276 | int getchar_unlocked();
277 | int putc_unlocked(int, FILE*);
278 | int putchar_unlocked(int);
279 | }
280 |
281 | //
282 | // XOpen (XSI)
283 | //
284 | /*
285 | P_tmpdir
286 | va_list (defined in core.stdc.stdarg)
287 |
288 | char* tempnam(in char*, in char*);
289 | */
290 |
291 | char* tempnam(in char*, in char*);
292 |
293 | version( CRuntime_Glibc )
294 | {
295 | enum P_tmpdir = "/tmp";
296 | }
297 | version( Darwin )
298 | {
299 | enum P_tmpdir = "/var/tmp";
300 | }
301 | version( FreeBSD )
302 | {
303 | enum P_tmpdir = "/var/tmp/";
304 | }
305 | version(NetBSD)
306 | {
307 | enum P_tmpdir = "/var/tmp/";
308 | }
309 | version( OpenBSD )
310 | {
311 | enum P_tmpdir = "/tmp/";
312 | }
313 | version( Solaris )
314 | {
315 | enum P_tmpdir = "/var/tmp/";
316 | }
317 |
318 | version( HaveMemstream )
319 | unittest
320 | { /* fmemopen */
321 | import core.stdc.string : memcmp;
322 | byte[10] buf;
323 | auto f = fmemopen(buf.ptr, 10, "w");
324 | assert(f !is null);
325 | assert(fprintf(f, "hello") == "hello".length);
326 | assert(fflush(f) == 0);
327 | assert(memcmp(buf.ptr, "hello".ptr, "hello".length) == 0);
328 | //assert(buf
329 | assert(fclose(f) == 0);
330 | }
331 |
332 | version( HaveMemstream )
333 | unittest
334 | { /* Note: open_memstream is only useful for writing */
335 | import core.stdc.string : memcmp;
336 | char* ptr = null;
337 | char[6] testdata = ['h', 'e', 'l', 'l', 'o', 0];
338 | size_t sz = 0;
339 | auto f = open_memstream(&ptr, &sz);
340 | assert(f !is null);
341 | assert(fprintf(f, "%s", testdata.ptr) == 5);
342 | assert(fflush(f) == 0);
343 | assert(memcmp(ptr, testdata.ptr, testdata.length) == 0);
344 | assert(fclose(f) == 0);
345 | }
346 |
347 | version( HaveMemstream )
348 | unittest
349 | { /* Note: open_wmemstream is only useful for writing */
350 | import core.stdc.string : memcmp;
351 | import core.stdc.wchar_ : fwprintf;
352 | wchar_t* ptr = null;
353 | wchar_t[6] testdata = ['h', 'e', 'l', 'l', 'o', 0];
354 | size_t sz = 0;
355 | auto f = open_wmemstream(&ptr, &sz);
356 | assert(f !is null);
357 | assert(fwprintf(f, testdata.ptr) == 5);
358 | assert(fflush(f) == 0);
359 | assert(memcmp(ptr, testdata.ptr, testdata.length*wchar_t.sizeof) == 0);
360 | assert(fclose(f) == 0);
361 | }
362 |
363 |
364 | ssize_t getdelim (char** lineptr, size_t* n, int delimiter, FILE* stream);
365 | ssize_t getline (char** lineptr, size_t* n, FILE* stream);
366 |
--------------------------------------------------------------------------------
/rt/dscripten/emscripten.d:
--------------------------------------------------------------------------------
1 | /// Emscripten API.
2 |
3 | module dscripten.emscripten;
4 |
5 | pragma(LDC_no_moduleinfo);
6 |
7 | extern(C) void emscripten_worker_respond_provisionally(const char *, size_t);
8 | extern(C) void emscripten_worker_respond(const char *, size_t);
9 |
10 | void workerRespondProvisionally(const(void)[] buf)
11 | {
12 | emscripten_worker_respond_provisionally(cast(const(char)*)buf.ptr, buf.length);
13 | }
14 |
15 | void workerRespond(const(void)[] buf)
16 | {
17 | emscripten_worker_respond(cast(const(char)*)buf.ptr, buf.length);
18 | }
19 |
--------------------------------------------------------------------------------
/rt/dscripten/memory.d:
--------------------------------------------------------------------------------
1 | module dscripten.memory;
2 |
3 | // Pull these in:
4 | import rt.lifetime;
5 | import rt.config;
6 | import gc.proxy;
7 | import ldc.arrayinit;
8 |
9 | // Call this in your extern(C) main
10 | extern(C) void gc_init();
11 |
--------------------------------------------------------------------------------
/rt/dscripten/standard.d:
--------------------------------------------------------------------------------
1 | // minimalistic D standard library
2 | module dscripten.standard;
3 |
4 | pragma(LDC_no_moduleinfo);
5 |
6 | extern(C) void* _Dmodule_ref;
7 |
8 | void deleteStruct(T)(T * r) nothrow
9 | {
10 | .destroy(*r);
11 | free(r);
12 | }
13 |
14 | void deleteObject(T)(T o) if(is(T == class))
15 | {
16 | static if(hasMember!(T, "__dtor"))
17 | {
18 | o.__dtor();
19 | }
20 | free(cast(void*)o);
21 | }
22 |
23 | struct vector (T)
24 | {
25 | this(int n)
26 | {
27 | for(int i = 0; i < n; ++i)
28 | push_back(T.init);
29 | }
30 |
31 | ~this()
32 | {
33 | clear();
34 | }
35 |
36 | void push_back()(auto ref T val)
37 | {
38 | ++len;
39 | buffer = cast(T*) realloc(buffer, len* T.sizeof);
40 | buffer[len - 1] = val;
41 | }
42 |
43 | void opIndexAssign()(auto ref T val, int idx)
44 | {
45 | buffer[idx] = val;
46 | }
47 |
48 | void clear()
49 | {
50 | foreach(element; this.opSlice())
51 | destroy(element);
52 |
53 | free(buffer);
54 | buffer = null;
55 | len = 0;
56 | }
57 |
58 | T[] opSlice()
59 | {
60 | return buffer[0 .. len];
61 | }
62 |
63 | int size() const
64 | {
65 | return len;
66 | }
67 |
68 | bool empty() const
69 | {
70 | return len == 0;
71 | }
72 |
73 | T* data()
74 | {
75 | return buffer;
76 | }
77 |
78 | private:
79 | T* buffer;
80 | int len;
81 | }
82 |
83 | T[] newArray(T)(int length)
84 | {
85 | void* block = calloc(T.sizeof, length);
86 | return cast(T[])block[0 .. T.sizeof * length];
87 | }
88 |
89 | void deleteArray(T)(in T[] arr)
90 | {
91 | free(cast(void*)arr.ptr);
92 | }
93 |
94 | ///////////////////////////////////////////////////////////////////////////////
95 | // meta
96 |
97 | template hasMember(T, string name)
98 | {
99 | static if (is(T == struct) || is(T == class) || is(T == union) || is(T == interface))
100 | {
101 | enum bool hasMember =
102 | staticIndexOf!(name, __traits(allMembers, T)) != -1 ||
103 | __traits(compiles, { mixin("alias Sym = Identity!(T."~name~");"); });
104 | }
105 | else
106 | {
107 | enum bool hasMember = false;
108 | }
109 | }
110 |
111 | template staticIndexOf(T, TList...)
112 | {
113 | enum staticIndexOf = genericIndexOf!(T, TList).index;
114 | }
115 |
116 | template staticIndexOf(alias T, TList...)
117 | {
118 | enum staticIndexOf = genericIndexOf!(T, TList).index;
119 | }
120 |
121 | template genericIndexOf(args...)
122 | if (args.length >= 1)
123 | {
124 | alias e = Alias!(args[0]);
125 | alias tuple = args[1 .. $];
126 |
127 | static if (tuple.length)
128 | {
129 | alias head = Alias!(tuple[0]);
130 | alias tail = tuple[1 .. $];
131 |
132 | static if (isSame!(e, head))
133 | {
134 | enum index = 0;
135 | }
136 | else
137 | {
138 | enum next = genericIndexOf!(e, tail).index;
139 | enum index = (next == -1) ? -1 : 1 + next;
140 | }
141 | }
142 | else
143 | {
144 | enum index = -1;
145 | }
146 | }
147 |
148 | template Alias(alias a)
149 | {
150 | static if (__traits(compiles, { alias x = a; }))
151 | alias Alias = a;
152 | else static if (__traits(compiles, { enum x = a; }))
153 | enum Alias = a;
154 | else
155 | static assert(0, "Cannot alias " ~ a.stringof);
156 | }
157 |
158 | template Alias(a...)
159 | {
160 | alias Alias = a;
161 | }
162 |
163 | template isSame(ab...)
164 | if (ab.length == 2)
165 | {
166 | static if (__traits(compiles, expectType!(ab[0]),
167 | expectType!(ab[1])))
168 | {
169 | enum isSame = is(ab[0] == ab[1]);
170 | }
171 | else static if (!__traits(compiles, expectType!(ab[0])) &&
172 | !__traits(compiles, expectType!(ab[1])) &&
173 | __traits(compiles, expectBool!(ab[0] == ab[1])))
174 | {
175 | static if (!__traits(compiles, &ab[0]) ||
176 | !__traits(compiles, &ab[1]))
177 | enum isSame = (ab[0] == ab[1]);
178 | else
179 | enum isSame = __traits(isSame, ab[0], ab[1]);
180 | }
181 | else
182 | {
183 | enum isSame = __traits(isSame, ab[0], ab[1]);
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/rt/dscripten/test.d:
--------------------------------------------------------------------------------
1 | // tests that the minimalistic D runtime/helpers actually works
2 | pragma(LDC_no_moduleinfo);
3 | import standard;
4 |
5 | extern(C)
6 | int main()
7 | {
8 | runTest!("struct: ctor/dtor", testStructCtorAndDtor);
9 |
10 | runTest!("class: empty", testEmptyClass);
11 | runTest!("class: ctor/dtor", testClassCtorAndDtor);
12 | runTest!("class: derived", testDerivedClass);
13 |
14 | runTest!("floating point: basic", testFloatingPoint);
15 | runTest!("arrays: copy", testArrayCopy);
16 | runTest!("arrays: dynamic", testArrayDynamic);
17 |
18 | runTest!("delegates", testDelegate);
19 |
20 | return 0;
21 | }
22 |
23 | ///////////////////////////////////////////////////////////////////////////////
24 |
25 | float g_f; // global nan-initialized float compile-test
26 |
27 | void testFloatingPoint()
28 | {
29 | check(g_f != g_f);
30 |
31 | float f;
32 | check(f != f);
33 | }
34 |
35 | void testEmptyClass()
36 | {
37 | static class E
38 | {
39 | }
40 |
41 | auto o = new E;
42 | check(o !is null);
43 | deleteObject(o);
44 | }
45 |
46 | void testClassCtorAndDtor()
47 | {
48 | static class C
49 | {
50 | static bool called;
51 | static bool constructed;
52 | static bool destroyed;
53 |
54 | this() nothrow
55 | {
56 | constructed = true;
57 | }
58 |
59 | ~this() nothrow
60 | {
61 | destroyed = true;
62 | }
63 |
64 | void f() nothrow
65 | {
66 | called = true;
67 | }
68 | }
69 |
70 | auto c = new C;
71 | check(C.constructed);
72 | c.f();
73 | check(C.called);
74 |
75 | deleteObject(c);
76 | check(C.destroyed);
77 | }
78 |
79 | void testDerivedClass()
80 | {
81 | static class Base
82 | {
83 | void f()
84 | {
85 | }
86 | }
87 |
88 | // construction/destruction
89 | static class D : Base
90 | {
91 | static bool derivedObjectConstructed;
92 | static bool called;
93 |
94 | this()
95 | {
96 | derivedObjectConstructed = true;
97 | }
98 |
99 | override void f()
100 | {
101 | called = true;
102 | }
103 | }
104 |
105 | // polymorphism
106 | {
107 | Base c = new D;
108 | check(D.derivedObjectConstructed);
109 |
110 | c.f();
111 | check(D.called);
112 |
113 | deleteObject(c);
114 | }
115 | }
116 |
117 | void testStructCtorAndDtor() nothrow
118 | {
119 | static struct MyStruct
120 | {
121 | int initialized = 7654;
122 | bool ctorCalled;
123 | int ctorArg;
124 | this(int arg_) nothrow
125 | {
126 | ctorCalled = true;
127 | ctorArg = arg_;
128 | }
129 |
130 | static bool dtorCalled;
131 |
132 | ~this() nothrow
133 | {
134 | dtorCalled = true;
135 | }
136 | }
137 |
138 | // statically allocated struct
139 | {
140 | {
141 | auto s = MyStruct(123);
142 | check(s.initialized == 7654);
143 | check(s.ctorCalled);
144 | check(s.ctorArg == 123);
145 | check(!s.dtorCalled);
146 | }
147 | check(MyStruct.dtorCalled);
148 | }
149 |
150 | // dynamically allocated struct
151 | MyStruct.dtorCalled = false;
152 | {
153 | auto s = new MyStruct(123);
154 | assertEquals(7654, s.initialized);
155 | check(s.ctorCalled);
156 | assertEquals(123, s.ctorArg);
157 | check(!s.dtorCalled);
158 |
159 | deleteStruct(s);
160 | }
161 | check(MyStruct.dtorCalled);
162 | }
163 |
164 | void testArrayCopy()
165 | {
166 | int[10] tab;
167 | tab[] = 4;
168 | assertEquals(4, tab[0]);
169 | assertEquals(4, tab[9]);
170 |
171 | int[10] tab2;
172 | tab2 = tab;
173 | assertEquals(4, tab2[0]);
174 | assertEquals(4, tab2[9]);
175 | }
176 |
177 | void testArrayDynamic()
178 | {
179 | int[] tab = newArray!int(256);
180 | assertEquals(256, cast(int)tab.length);
181 | assert(tab.ptr);
182 | assertEquals(0, tab[0]);
183 | tab[1] = 1234;
184 |
185 | deleteArray(tab);
186 | }
187 |
188 | void testDelegate()
189 | {
190 | static class C
191 | {
192 | int a;
193 | void f()
194 | {
195 | ++a;
196 | }
197 | }
198 |
199 | static void callMe(void delegate() func)
200 | {
201 | for(int i=0;i < 123;++i)
202 | func();
203 | }
204 |
205 | auto c = new C;
206 | callMe(&c.f);
207 | assertEquals(123, c.a);
208 | }
209 |
210 | ///////////////////////////////////////////////////////////////////////////////
211 | void runTest(string name, alias f)()
212 | {
213 | printf("Test: %s\n", name.ptr);
214 | f();
215 | }
216 |
217 | void assertEquals(int expected, int actual, string file=__FILE__, int line=__LINE__) nothrow
218 | {
219 | if(expected == actual)
220 | return;
221 |
222 | printf("At %s(%d): expected %d, got %d\n", file.ptr, line, expected, actual);
223 | exit(1);
224 | }
225 |
226 | void check(bool condition, string file=__FILE__, int line=__LINE__) nothrow
227 | {
228 | if(condition)
229 | return;
230 |
231 | printf("At %s(%d): assertion failure\n", file.ptr, line);
232 | exit(1);
233 | }
234 |
235 |
--------------------------------------------------------------------------------
/rt/dscripten/typeinfo.d:
--------------------------------------------------------------------------------
1 | module dscripten.typeinfo;
2 |
3 | // Pull these in. TODO should probably compile them unconditionally somehow
4 | import rt.typeinfo.ti_Acdouble;
5 | import rt.typeinfo.ti_Acfloat;
6 | import rt.typeinfo.ti_Acreal;
7 | import rt.typeinfo.ti_Adouble;
8 | import rt.typeinfo.ti_Afloat;
9 | import rt.typeinfo.ti_Ag;
10 | import rt.typeinfo.ti_Aint;
11 | import rt.typeinfo.ti_Along;
12 | import rt.typeinfo.ti_Areal;
13 | import rt.typeinfo.ti_Ashort;
14 | import rt.typeinfo.ti_byte;
15 | import rt.typeinfo.ti_C;
16 | import rt.typeinfo.ti_cdouble;
17 | import rt.typeinfo.ti_cent;
18 | import rt.typeinfo.ti_cfloat;
19 | import rt.typeinfo.ti_char;
20 | import rt.typeinfo.ti_creal;
21 | import rt.typeinfo.ti_dchar;
22 | import rt.typeinfo.ti_delegate;
23 | import rt.typeinfo.ti_double;
24 | import rt.typeinfo.ti_float;
25 | import rt.typeinfo.ti_idouble;
26 | import rt.typeinfo.ti_ifloat;
27 | import rt.typeinfo.ti_int;
28 | import rt.typeinfo.ti_ireal;
29 | import rt.typeinfo.ti_long;
30 | import rt.typeinfo.ti_n;
31 | import rt.typeinfo.ti_ptr;
32 | import rt.typeinfo.ti_real;
33 | import rt.typeinfo.ti_short;
34 | import rt.typeinfo.ti_ubyte;
35 | import rt.typeinfo.ti_ucent;
36 | import rt.typeinfo.ti_uint;
37 | import rt.typeinfo.ti_ulong;
38 | import rt.typeinfo.ti_ushort;
39 | import rt.typeinfo.ti_void;
40 | import rt.typeinfo.ti_wchar;
41 |
--------------------------------------------------------------------------------
/rt/gc/config.d:
--------------------------------------------------------------------------------
1 | /**
2 | * Contains the garbage collector configuration.
3 | *
4 | * Copyright: Copyright Digital Mars 2016
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | */
7 |
8 | module gc.config;
9 |
10 | import core.stdc.stdio;
11 | import core.internal.parseoptions;
12 |
13 | __gshared Config config;
14 |
15 | struct Config
16 | {
17 | bool disable; // start disabled
18 | ubyte profile; // enable profiling with summary when terminating program
19 | string gc = "manual"; // select gc implementation conservative|manual
20 |
21 | size_t initReserve; // initial reserve (MB)
22 | size_t minPoolSize = 1; // initial and minimum pool size (MB)
23 | size_t maxPoolSize = 64; // maximum pool size (MB)
24 | size_t incPoolSize = 3; // pool size increment (MB)
25 | float heapSizeFactor = 2.0; // heap size to used memory ratio
26 |
27 | @nogc nothrow:
28 |
29 | bool initialize()
30 | {
31 | return initConfigOptions(this, "gcopt");
32 | }
33 |
34 | void help() @nogc nothrow
35 | {
36 | string s = "GC options are specified as whitespace separated assignments:
37 | disable:0|1 - start disabled (%d)
38 | profile:0|1|2 - enable profiling with summary when terminating program (%d)
39 | gc:conservative|manual - select gc implementation (default = conservative)
40 |
41 | initReserve:N - initial memory to reserve in MB (%lld)
42 | minPoolSize:N - initial and minimum pool size in MB (%lld)
43 | maxPoolSize:N - maximum pool size in MB (%lld)
44 | incPoolSize:N - pool size increment MB (%lld)
45 | heapSizeFactor:N - targeted heap size to used memory ratio (%g)
46 | ";
47 | printf(s.ptr, disable, profile, cast(long)initReserve, cast(long)minPoolSize,
48 | cast(long)maxPoolSize, cast(long)incPoolSize, heapSizeFactor);
49 | }
50 |
51 | string errorName() @nogc nothrow { return "GC"; }
52 | }
53 |
--------------------------------------------------------------------------------
/rt/gc/gcinterface.d:
--------------------------------------------------------------------------------
1 | /**
2 | * Contains the internal GC interface.
3 | *
4 | * Copyright: Copyright Digital Mars 2016.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright, Sean Kelly, Jeremy DeHaan
7 | */
8 |
9 | /* Copyright Digital Mars 2016.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module gc.gcinterface;
15 |
16 | static import core.memory;
17 | alias BlkAttr = core.memory.GC.BlkAttr;
18 | alias BlkInfo = core.memory.GC.BlkInfo;
19 |
20 | alias RootIterator = int delegate(scope int delegate(ref Root) nothrow dg);
21 | alias RangeIterator = int delegate(scope int delegate(ref Range) nothrow dg);
22 |
23 |
24 | struct Root
25 | {
26 | void* proot;
27 | alias proot this;
28 | }
29 |
30 | struct Range
31 | {
32 | void* pbot;
33 | void* ptop;
34 | TypeInfo ti; // should be tail const, but doesn't exist for references
35 | alias pbot this; // only consider pbot for relative ordering (opCmp)
36 | }
37 |
38 | interface GC
39 | {
40 |
41 | /*
42 | *
43 | */
44 | void Dtor();
45 |
46 | /**
47 | *
48 | */
49 | void enable();
50 |
51 | /**
52 | *
53 | */
54 | void disable();
55 |
56 | /**
57 | *
58 | */
59 | void collect() nothrow;
60 |
61 | /**
62 | *
63 | */
64 | void collectNoStack() nothrow;
65 |
66 | /**
67 | * minimize free space usage
68 | */
69 | void minimize() nothrow;
70 |
71 | /**
72 | *
73 | */
74 | uint getAttr(void* p) nothrow;
75 |
76 | /**
77 | *
78 | */
79 | uint setAttr(void* p, uint mask) nothrow;
80 |
81 | /**
82 | *
83 | */
84 | uint clrAttr(void* p, uint mask) nothrow;
85 |
86 | /**
87 | *
88 | */
89 | void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow;
90 |
91 | /*
92 | *
93 | */
94 | BlkInfo qalloc(size_t size, uint bits, const TypeInfo ti) nothrow;
95 |
96 | /*
97 | *
98 | */
99 | void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow;
100 |
101 | /*
102 | *
103 | */
104 | void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow;
105 |
106 | /**
107 | * Attempt to in-place enlarge the memory block pointed to by p by at least
108 | * minsize bytes, up to a maximum of maxsize additional bytes.
109 | * This does not attempt to move the memory block (like realloc() does).
110 | *
111 | * Returns:
112 | * 0 if could not extend p,
113 | * total size of entire memory block if successful.
114 | */
115 | size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow;
116 |
117 | /**
118 | *
119 | */
120 | size_t reserve(size_t size) nothrow;
121 |
122 | /**
123 | *
124 | */
125 | void free(void* p) nothrow @nogc;
126 |
127 | /**
128 | * Determine the base address of the block containing p. If p is not a gc
129 | * allocated pointer, return null.
130 | */
131 | void* addrOf(void* p) nothrow @nogc;
132 |
133 | /**
134 | * Determine the allocated size of pointer p. If p is an interior pointer
135 | * or not a gc allocated pointer, return 0.
136 | */
137 | size_t sizeOf(void* p) nothrow @nogc;
138 |
139 | /**
140 | * Determine the base address of the block containing p. If p is not a gc
141 | * allocated pointer, return null.
142 | */
143 | BlkInfo query(void* p) nothrow;
144 |
145 | /**
146 | * Retrieve statistics about garbage collection.
147 | * Useful for debugging and tuning.
148 | */
149 | core.memory.GC.Stats stats() nothrow;
150 |
151 | /**
152 | * add p to list of roots
153 | */
154 | void addRoot(void* p) nothrow @nogc;
155 |
156 | /**
157 | * remove p from list of roots
158 | */
159 | void removeRoot(void* p) nothrow @nogc;
160 |
161 | /**
162 | *
163 | */
164 | @property RootIterator rootIter() @nogc;
165 |
166 | /**
167 | * add range to scan for roots
168 | */
169 | void addRange(void* p, size_t sz, const TypeInfo ti) nothrow @nogc;
170 |
171 | /**
172 | * remove range
173 | */
174 | void removeRange(void* p) nothrow @nogc;
175 |
176 | /**
177 | *
178 | */
179 | @property RangeIterator rangeIter() @nogc;
180 |
181 | /**
182 | * run finalizers
183 | */
184 | void runFinalizers(in void[] segment) nothrow;
185 |
186 | /*
187 | *
188 | */
189 | bool inFinalizer() nothrow;
190 | }
191 |
--------------------------------------------------------------------------------
/rt/gc/impl/manual/gc.d:
--------------------------------------------------------------------------------
1 | /**
2 | * This module contains a minimal garbage collector implementation according to
3 | * published requirements. This library is mostly intended to serve as an
4 | * example, but it is usable in applications which do not rely on a garbage
5 | * collector to clean up memory (ie. when dynamic array resizing is not used,
6 | * and all memory allocated with 'new' is freed deterministically with
7 | * 'delete').
8 | *
9 | * Please note that block attribute data must be tracked, or at a minimum, the
10 | * FINALIZE bit must be tracked for any allocated memory block because calling
11 | * rt_finalize on a non-object block can result in an access violation. In the
12 | * allocator below, this tracking is done via a leading uint bitmask. A real
13 | * allocator may do better to store this data separately, similar to the basic
14 | * GC.
15 | *
16 | * Copyright: Copyright Sean Kelly 2005 - 2016.
17 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
18 | * Authors: Sean Kelly
19 | */
20 |
21 | /* Copyright Sean Kelly 2005 - 2016.
22 | * Distributed under the Boost Software License, Version 1.0.
23 | * (See accompanying file LICENSE or copy at
24 | * http://www.boost.org/LICENSE_1_0.txt)
25 | */
26 | module gc.impl.manual.gc;
27 |
28 | import gc.config;
29 | import gc.gcinterface;
30 |
31 | import rt.util.container.array;
32 |
33 | import cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc;
34 | static import core.memory;
35 |
36 | extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */
37 |
38 | class ManualGC : GC
39 | {
40 | __gshared Array!Root roots;
41 | __gshared Array!Range ranges;
42 |
43 | static void initialize(ref GC gc)
44 | {
45 | import core.stdc.string;
46 |
47 | if (config.gc != "manual")
48 | return;
49 |
50 | auto p = cstdlib.malloc(__traits(classInstanceSize, ManualGC));
51 | if (!p)
52 | onOutOfMemoryError();
53 |
54 | auto init = typeid(ManualGC).initializer();
55 | assert(init.length == __traits(classInstanceSize, ManualGC));
56 | auto instance = cast(ManualGC) memcpy(p, init.ptr, init.length);
57 | instance.__ctor();
58 |
59 | gc = instance;
60 | }
61 |
62 | static void finalize(ref GC gc)
63 | {
64 | if (config.gc != "manual")
65 | return;
66 |
67 | auto instance = cast(ManualGC) gc;
68 | instance.Dtor();
69 | cstdlib.free(cast(void*) instance);
70 | }
71 |
72 | this()
73 | {
74 | }
75 |
76 | void Dtor()
77 | {
78 | }
79 |
80 | void enable()
81 | {
82 | }
83 |
84 | void disable()
85 | {
86 | }
87 |
88 | void collect() nothrow
89 | {
90 | }
91 |
92 | void collectNoStack() nothrow
93 | {
94 | }
95 |
96 | void minimize() nothrow
97 | {
98 | }
99 |
100 | uint getAttr(void* p) nothrow
101 | {
102 | return 0;
103 | }
104 |
105 | uint setAttr(void* p, uint mask) nothrow
106 | {
107 | return 0;
108 | }
109 |
110 | uint clrAttr(void* p, uint mask) nothrow
111 | {
112 | return 0;
113 | }
114 |
115 | void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow
116 | {
117 | void* p = cstdlib.malloc(size);
118 |
119 | if (size && p is null)
120 | onOutOfMemoryError();
121 | return p;
122 | }
123 |
124 | BlkInfo qalloc(size_t size, uint bits, const TypeInfo ti) nothrow
125 | {
126 | BlkInfo retval;
127 | retval.base = malloc(size, bits, ti);
128 | retval.size = size;
129 | retval.attr = bits;
130 | return retval;
131 | }
132 |
133 | void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow
134 | {
135 | void* p = cstdlib.calloc(1, size);
136 |
137 | if (size && p is null)
138 | onOutOfMemoryError();
139 | return p;
140 | }
141 |
142 | void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow
143 | {
144 | p = cstdlib.realloc(p, size);
145 |
146 | if (size && p is null)
147 | onOutOfMemoryError();
148 | return p;
149 | }
150 |
151 | size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti) nothrow
152 | {
153 | return 0;
154 | }
155 |
156 | size_t reserve(size_t size) nothrow
157 | {
158 | return 0;
159 | }
160 |
161 | void free(void* p) nothrow @nogc
162 | {
163 | cstdlib.free(p);
164 | }
165 |
166 | /**
167 | * Determine the base address of the block containing p. If p is not a gc
168 | * allocated pointer, return null.
169 | */
170 | void* addrOf(void* p) nothrow @nogc
171 | {
172 | return null;
173 | }
174 |
175 | /**
176 | * Determine the allocated size of pointer p. If p is an interior pointer
177 | * or not a gc allocated pointer, return 0.
178 | */
179 | size_t sizeOf(void* p) nothrow @nogc
180 | {
181 | return 0;
182 | }
183 |
184 | /**
185 | * Determine the base address of the block containing p. If p is not a gc
186 | * allocated pointer, return null.
187 | */
188 | BlkInfo query(void* p) nothrow
189 | {
190 | return BlkInfo.init;
191 | }
192 |
193 | core.memory.GC.Stats stats() nothrow
194 | {
195 | return typeof(return).init;
196 | }
197 |
198 | void addRoot(void* p) nothrow @nogc
199 | {
200 | roots.insertBack(Root(p));
201 | }
202 |
203 | void removeRoot(void* p) nothrow @nogc
204 | {
205 | foreach (ref r; roots)
206 | {
207 | if (r is p)
208 | {
209 | r = roots.back;
210 | roots.popBack();
211 | return;
212 | }
213 | }
214 | assert(false);
215 | }
216 |
217 | @property RootIterator rootIter() return @nogc
218 | {
219 | return &rootsApply;
220 | }
221 |
222 | private int rootsApply(scope int delegate(ref Root) nothrow dg)
223 | {
224 | foreach (ref r; roots)
225 | {
226 | if (auto result = dg(r))
227 | return result;
228 | }
229 | return 0;
230 | }
231 |
232 | void addRange(void* p, size_t sz, const TypeInfo ti = null) nothrow @nogc
233 | {
234 | ranges.insertBack(Range(p, p + sz, cast() ti));
235 | }
236 |
237 | void removeRange(void* p) nothrow @nogc
238 | {
239 | foreach (ref r; ranges)
240 | {
241 | if (r.pbot is p)
242 | {
243 | r = ranges.back;
244 | ranges.popBack();
245 | return;
246 | }
247 | }
248 | assert(false);
249 | }
250 |
251 | @property RangeIterator rangeIter() return @nogc
252 | {
253 | return &rangesApply;
254 | }
255 |
256 | private int rangesApply(scope int delegate(ref Range) nothrow dg)
257 | {
258 | foreach (ref r; ranges)
259 | {
260 | if (auto result = dg(r))
261 | return result;
262 | }
263 | return 0;
264 | }
265 |
266 | void runFinalizers(in void[] segment) nothrow
267 | {
268 | }
269 |
270 | bool inFinalizer() nothrow
271 | {
272 | return false;
273 | }
274 | }
275 |
--------------------------------------------------------------------------------
/rt/gc/proxy.d:
--------------------------------------------------------------------------------
1 | /**
2 | * Contains the external GC interface.
3 | *
4 | * Copyright: Copyright Digital Mars 2005 - 2016.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright, Sean Kelly
7 | */
8 |
9 | /* Copyright Digital Mars 2005 - 2016.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module gc.proxy;
15 |
16 | //import gc.impl.conservative.gc;
17 | import gc.impl.manual.gc;
18 | import gc.config;
19 | import gc.gcinterface;
20 |
21 | static import core.memory;
22 |
23 | private
24 | {
25 | static import core.memory;
26 | alias BlkInfo = core.memory.GC.BlkInfo;
27 |
28 | // extern (C) void thread_init();
29 | // extern (C) void thread_term();
30 |
31 | __gshared GC instance;
32 | __gshared GC proxiedGC; // used to iterate roots of Windows DLLs
33 |
34 | }
35 |
36 |
37 | extern (C)
38 | {
39 |
40 | void gc_init()
41 | {
42 | config.initialize();
43 | ManualGC.initialize(instance);
44 | //ConservativeGC.initialize(instance);
45 | if (instance is null)
46 | {
47 | import core.stdc.stdio : fprintf, stderr;
48 | import core.stdc.stdlib : exit;
49 |
50 | fprintf(stderr, "No GC was initialized, please recheck the name of the selected GC ('%.*s').\n", cast(int)config.gc.length, config.gc.ptr);
51 | exit(1);
52 | }
53 |
54 | // NOTE: The GC must initialize the thread library
55 | // before its first collection.
56 | // thread_init();
57 | }
58 |
59 | void gc_term()
60 | {
61 | // NOTE: There may be daemons threads still running when this routine is
62 | // called. If so, cleaning memory out from under then is a good
63 | // way to make them crash horribly. This probably doesn't matter
64 | // much since the app is supposed to be shutting down anyway, but
65 | // I'm disabling cleanup for now until I can think about it some
66 | // more.
67 | //
68 | // NOTE: Due to popular demand, this has been re-enabled. It still has
69 | // the problems mentioned above though, so I guess we'll see.
70 |
71 | instance.collectNoStack(); // not really a 'collect all' -- still scans
72 | // static data area, roots, and ranges.
73 |
74 | // thread_term();
75 |
76 | ManualGC.finalize(instance);
77 | //ConservativeGC.finalize(instance);
78 | }
79 |
80 | void gc_enable()
81 | {
82 | instance.enable();
83 | }
84 |
85 | void gc_disable()
86 | {
87 | instance.disable();
88 | }
89 |
90 | void gc_collect() nothrow
91 | {
92 | instance.collect();
93 | }
94 |
95 | void gc_minimize() nothrow
96 | {
97 | instance.minimize();
98 | }
99 |
100 | uint gc_getAttr( void* p ) nothrow
101 | {
102 | return instance.getAttr(p);
103 | }
104 |
105 | uint gc_setAttr( void* p, uint a ) nothrow
106 | {
107 | return instance.setAttr(p, a);
108 | }
109 |
110 | uint gc_clrAttr( void* p, uint a ) nothrow
111 | {
112 | return instance.clrAttr(p, a);
113 | }
114 |
115 | void* gc_malloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow
116 | {
117 | return instance.malloc(sz, ba, ti);
118 | }
119 |
120 | BlkInfo gc_qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow
121 | {
122 | return instance.qalloc( sz, ba, ti );
123 | }
124 |
125 | void* gc_calloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow
126 | {
127 | return instance.calloc( sz, ba, ti );
128 | }
129 |
130 | void* gc_realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow
131 | {
132 | return instance.realloc( p, sz, ba, ti );
133 | }
134 |
135 | size_t gc_extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null ) nothrow
136 | {
137 | return instance.extend( p, mx, sz,ti );
138 | }
139 |
140 | size_t gc_reserve( size_t sz ) nothrow
141 | {
142 | return instance.reserve( sz );
143 | }
144 |
145 | void gc_free( void* p ) nothrow @nogc
146 | {
147 | return instance.free( p );
148 | }
149 |
150 | void* gc_addrOf( void* p ) nothrow @nogc
151 | {
152 | return instance.addrOf( p );
153 | }
154 |
155 | size_t gc_sizeOf( void* p ) nothrow @nogc
156 | {
157 | return instance.sizeOf( p );
158 | }
159 |
160 | BlkInfo gc_query( void* p ) nothrow
161 | {
162 | return instance.query( p );
163 | }
164 |
165 | core.memory.GC.Stats gc_stats() nothrow
166 | {
167 | return instance.stats();
168 | }
169 |
170 | void gc_addRoot( void* p ) nothrow
171 | {
172 | return instance.addRoot( p );
173 | }
174 |
175 | void gc_addRange( void* p, size_t sz, const TypeInfo ti = null ) nothrow
176 | {
177 | return instance.addRange( p, sz, ti );
178 | }
179 |
180 | void gc_removeRoot( void* p ) nothrow
181 | {
182 | return instance.removeRoot( p );
183 | }
184 |
185 | void gc_removeRange( void* p ) nothrow
186 | {
187 | return instance.removeRange( p );
188 | }
189 |
190 | void gc_runFinalizers( in void[] segment ) nothrow
191 | {
192 | return instance.runFinalizers( segment );
193 | }
194 |
195 | bool gc_inFinalizer() nothrow
196 | {
197 | return instance.inFinalizer();
198 | }
199 |
200 | GC gc_getProxy() nothrow
201 | {
202 | return instance;
203 | }
204 |
205 | // LDC: Don't export these functions by default for each binary linked statically against druntime.
206 | //export
207 | //{
208 | void gc_setProxy( GC proxy )
209 | {
210 | foreach(root; instance.rootIter)
211 | {
212 | proxy.addRoot(root);
213 | }
214 |
215 | foreach(range; instance.rangeIter)
216 | {
217 | proxy.addRange(range.pbot, range.ptop - range.pbot, range.ti);
218 | }
219 |
220 | proxiedGC = instance; // remember initial GC to later remove roots
221 | instance = proxy;
222 | }
223 |
224 | void gc_clrProxy()
225 | {
226 | foreach(root; proxiedGC.rootIter)
227 | {
228 | instance.removeRoot(root);
229 | }
230 |
231 | foreach(range; proxiedGC.rangeIter)
232 | {
233 | instance.removeRange(range);
234 | }
235 |
236 | instance = proxiedGC;
237 | proxiedGC = null;
238 | }
239 | //}
240 | }
241 |
--------------------------------------------------------------------------------
/rt/mainloop.c:
--------------------------------------------------------------------------------
1 | void startup();
2 | void mainLoop();
3 |
4 | static int mustQuit;
5 |
6 | #ifdef __EMSCRIPTEN__
7 |
8 | void emscripten_set_main_loop(void (*function)(), int fps, int simulate_infinite_loop);
9 |
10 | int main()
11 | {
12 | startup();
13 | emscripten_set_main_loop(&mainLoop, 60, 1);
14 | return 0;
15 | }
16 |
17 | #else
18 |
19 | void SDL_Delay(int);
20 |
21 | int main()
22 | {
23 | startup();
24 |
25 | while(!mustQuit)
26 | {
27 | mainLoop();
28 | SDL_Delay(16);
29 | }
30 | return 0;
31 | }
32 |
33 | #endif
34 |
35 | void quit()
36 | {
37 | mustQuit = 1;
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/rt/rt/config.d:
--------------------------------------------------------------------------------
1 | /**
2 | * Configuration options for druntime
3 | *
4 | * Copyright: Copyright Digital Mars 2014.
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: Rainer Schuetze
9 | * Source: $(DRUNTIMESRC src/rt/_config.d)
10 | */
11 |
12 | module rt.config;
13 |
14 | alias rt_configCallBack = string delegate(string) @nogc nothrow;
15 | string rt_configOption(string opt, scope rt_configCallBack dg = null, bool reverse = false) @nogc nothrow { return null; }
16 |
17 | version(none):
18 | // The default way to configure the runtime is by passing command line arguments
19 | // starting with "--DRT-" and followed by the option name, e.g. "--DRT-gcopt" to
20 | // configure the GC.
21 | // Command line options starting with "--DRT-" are filtered out before calling main,
22 | // so the program will not see them. They are still available via rt_args().
23 | //
24 | // Configuration via the command line can be disabled by declaring a variable for the
25 | // linker to pick up before using it's default from the runtime:
26 | //
27 | // extern(C) __gshared bool rt_cmdline_enabled = false;
28 | //
29 | // Likewise, declare a boolean rt_envvars_enabled to enable configuration via the
30 | // environment variable "DRT_" followed by the option name, e.g. "DRT_GCOPT":
31 | //
32 | // extern(C) __gshared bool rt_envvars_enabled = true;
33 | //
34 | // Setting default configuration properties in the executable can be done by specifying an
35 | // array of options named rt_options:
36 | //
37 | // extern(C) __gshared string[] rt_options = [ "gcopt=precise:1 profile:1"];
38 | //
39 | // Evaluation order of options is rt_options, then environment variables, then command
40 | // line arguments, i.e. if command line arguments are not disabled, they can override
41 | // options specified through the environment or embedded in the executable.
42 |
43 | // put each variable in its own COMDAT by making them template instances
44 | template rt_envvars_enabled()
45 | {
46 | extern(C) pragma(mangle, "rt_envvars_enabled") __gshared bool rt_envvars_enabled = false;
47 | }
48 | template rt_cmdline_enabled()
49 | {
50 | extern(C) pragma(mangle, "rt_cmdline_enabled") __gshared bool rt_cmdline_enabled = true;
51 | }
52 | template rt_options()
53 | {
54 | extern(C) pragma(mangle, "rt_options") __gshared string[] rt_options = [];
55 | }
56 |
57 | import core.stdc.ctype : toupper;
58 | import core.stdc.stdlib : getenv;
59 | import core.stdc.string : strlen;
60 |
61 | extern extern(C) string[] rt_args() @nogc nothrow;
62 |
63 | alias rt_configCallBack = string delegate(string) @nogc nothrow;
64 |
65 | /**
66 | * get a druntime config option using standard configuration options
67 | * opt name of the option to retreive
68 | * dg if non-null, passes the option through this
69 | * delegate and only returns its return value if non-null
70 | * reverse reverse the default processing order cmdline/envvar/rt_options
71 | * to allow overwriting settings in the delegate with values
72 | * from higher priority
73 | *
74 | * returns the options' value if
75 | * - set on the command line as "--DRT-=value" (rt_cmdline_enabled enabled)
76 | * - the environment variable "DRT_" is set (rt_envvars_enabled enabled)
77 | * - rt_options[] contains an entry "=value"
78 | * - null otherwise
79 | */
80 | string rt_configOption(string opt, scope rt_configCallBack dg = null, bool reverse = false) @nogc nothrow
81 | {
82 | if (!dg)
83 | dg = (string s) => s;
84 |
85 | string s = (reverse ? rt_linkOption(opt, dg) : rt_cmdlineOption(opt, dg));
86 | if (s != null)
87 | return s;
88 | s = rt_envvarsOption(opt, dg);
89 | if (s != null)
90 | return s;
91 | s = (reverse ? rt_cmdlineOption(opt, dg) : rt_linkOption(opt, dg));
92 | return s;
93 | }
94 |
95 | string rt_cmdlineOption(string opt, scope rt_configCallBack dg) @nogc nothrow
96 | {
97 | if(rt_cmdline_enabled!())
98 | {
99 | foreach (a; rt_args)
100 | {
101 | if (a.length >= opt.length + 7 && a[0..6] == "--DRT-" &&
102 | a[6 .. 6 + opt.length] == opt && a[6 + opt.length] == '=')
103 | {
104 | string s = dg(a[7 + opt.length .. $]);
105 | if (s != null)
106 | return s;
107 | }
108 | }
109 | }
110 | return null;
111 | }
112 |
113 | string rt_envvarsOption(string opt, scope rt_configCallBack dg) @nogc nothrow
114 | {
115 | if(rt_envvars_enabled!())
116 | {
117 | if (opt.length >= 32)
118 | assert(0);
119 |
120 | char[40] var;
121 | var[0 .. 4] = "DRT_";
122 | foreach (i, c; opt)
123 | var[4 + i] = cast(char) toupper(c);
124 | var[4 + opt.length] = 0;
125 |
126 | auto p = getenv(var.ptr);
127 | if (p)
128 | {
129 | string s = dg(cast(string) p[0 .. strlen(p)]);
130 | if (s != null)
131 | return s;
132 | }
133 | }
134 | return null;
135 | }
136 |
137 | string rt_linkOption(string opt, scope rt_configCallBack dg) @nogc nothrow
138 | {
139 | foreach (a; rt_options!())
140 | {
141 | if(a.length > opt.length && a[0..opt.length] == opt && a[opt.length] == '=')
142 | {
143 | string s = dg(a[opt.length + 1 .. $]);
144 | if (s != null)
145 | return s;
146 | }
147 | }
148 | return null;
149 | }
150 |
--------------------------------------------------------------------------------
/rt/rt/deh.d:
--------------------------------------------------------------------------------
1 | /**
2 | * Implementation of exception handling support routines.
3 | *
4 | * Copyright: Copyright Digital Mars 1999 - 2013.
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/deh.d)
10 | */
11 |
12 | module rt.deh;
13 |
14 | extern (C)
15 | {
16 | Throwable.TraceInfo _d_traceContext(void* ptr = null);
17 | void _d_createTrace(Object o, void* context)
18 | {
19 | auto t = cast(Throwable) o;
20 |
21 | if (t !is null && t.info is null &&
22 | cast(byte*) t !is typeid(t).initializer.ptr)
23 | {
24 | t.info = _d_traceContext(context);
25 | }
26 | }
27 | }
28 |
29 | version (dscripten)
30 | {}
31 | else version (LDC)
32 | public import rt.deh_win64_posix;
33 | else version (Win32)
34 | public import rt.deh_win32;
35 | else version (Win64)
36 | public import rt.deh_win64_posix;
37 | else version (Posix)
38 | public import rt.deh_win64_posix;
39 | else
40 | static assert (0, "Unsupported architecture");
41 |
42 |
--------------------------------------------------------------------------------
/rt/rt/invariant_.d:
--------------------------------------------------------------------------------
1 | /**
2 | * Implementation of invariant support routines.
3 | *
4 | * Copyright: Copyright Digital Mars 2007 - 2010.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2007 - 2010.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.invariant_;
15 |
16 | /**
17 | *
18 | */
19 | pragma(mangle, "_D9invariant12_d_invariantFC6ObjectZv")
20 | void _d_invariant(Object o)
21 | { ClassInfo c;
22 |
23 | //printf("__d_invariant(%p)\n", o);
24 |
25 | // BUG: needs to be filename/line of caller, not library routine
26 | assert(o !is null); // just do null check, not invariant check
27 |
28 | c = typeid(o);
29 | do
30 | {
31 | if (c.classInvariant)
32 | {
33 | (*c.classInvariant)(o);
34 | }
35 | c = c.base;
36 | } while (c);
37 | }
38 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_Acdouble.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_Acdouble;
15 |
16 | private import rt.util.typeinfo;
17 |
18 | // cdouble[]
19 |
20 | class TypeInfo_Ar : TypeInfo_Array
21 | {
22 | alias F = cdouble;
23 |
24 | override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
25 |
26 | override string toString() const { return (F[]).stringof; }
27 |
28 | override size_t getHash(in void* p) @trusted const
29 | {
30 | return Array!F.hashOf(*cast(F[]*)p);
31 | }
32 |
33 | override bool equals(in void* p1, in void* p2) const
34 | {
35 | return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
36 | }
37 |
38 | override int compare(in void* p1, in void* p2) const
39 | {
40 | return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
41 | }
42 |
43 | override @property inout(TypeInfo) next() inout
44 | {
45 | return cast(inout)typeid(F);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_Acfloat.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_Acfloat;
15 |
16 | private import rt.util.typeinfo;
17 |
18 | // cfloat[]
19 |
20 | class TypeInfo_Aq : TypeInfo_Array
21 | {
22 | alias F = cfloat;
23 |
24 | override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
25 |
26 | override string toString() const { return (F[]).stringof; }
27 |
28 | override size_t getHash(in void* p) @trusted const
29 | {
30 | return Array!F.hashOf(*cast(F[]*)p);
31 | }
32 |
33 | override bool equals(in void* p1, in void* p2) const
34 | {
35 | return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
36 | }
37 |
38 | override int compare(in void* p1, in void* p2) const
39 | {
40 | return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
41 | }
42 |
43 | override @property inout(TypeInfo) next() inout
44 | {
45 | return cast(inout)typeid(F);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_Acreal.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_Acreal;
15 |
16 | private import rt.util.typeinfo;
17 |
18 | // creal[]
19 |
20 | class TypeInfo_Ac : TypeInfo_Array
21 | {
22 | alias F = creal;
23 |
24 | override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
25 |
26 | override string toString() const { return (F[]).stringof; }
27 |
28 | override size_t getHash(in void* p) @trusted const
29 | {
30 | return Array!F.hashOf(*cast(F[]*)p);
31 | }
32 |
33 | override bool equals(in void* p1, in void* p2) const
34 | {
35 | return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
36 | }
37 |
38 | override int compare(in void* p1, in void* p2) const
39 | {
40 | return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
41 | }
42 |
43 | override @property inout(TypeInfo) next() inout
44 | {
45 | return cast(inout)typeid(F);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_Adouble.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_Adouble;
15 |
16 | private import rt.util.typeinfo;
17 |
18 | // double[]
19 |
20 | class TypeInfo_Ad : TypeInfo_Array
21 | {
22 | alias F = double;
23 |
24 | override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
25 |
26 | override string toString() const { return (F[]).stringof; }
27 |
28 | override size_t getHash(in void* p) @trusted const
29 | {
30 | return Array!F.hashOf(*cast(F[]*)p);
31 | }
32 |
33 | override bool equals(in void* p1, in void* p2) const
34 | {
35 | return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
36 | }
37 |
38 | override int compare(in void* p1, in void* p2) const
39 | {
40 | return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
41 | }
42 |
43 | override @property inout(TypeInfo) next() inout
44 | {
45 | return cast(inout)typeid(F);
46 | }
47 | }
48 |
49 | // idouble[]
50 |
51 | class TypeInfo_Ap : TypeInfo_Ad
52 | {
53 | alias F = idouble;
54 |
55 | override string toString() const { return (F[]).stringof; }
56 |
57 | override @property inout(TypeInfo) next() inout
58 | {
59 | return cast(inout)typeid(F);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_Afloat.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_Afloat;
15 |
16 | private import rt.util.typeinfo;
17 |
18 | // float[]
19 |
20 | class TypeInfo_Af : TypeInfo_Array
21 | {
22 | alias F = float;
23 |
24 | override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
25 |
26 | override string toString() const { return (F[]).stringof; }
27 |
28 | override size_t getHash(in void* p) @trusted const
29 | {
30 | return Array!F.hashOf(*cast(F[]*)p);
31 | }
32 |
33 | override bool equals(in void* p1, in void* p2) const
34 | {
35 | return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
36 | }
37 |
38 | override int compare(in void* p1, in void* p2) const
39 | {
40 | return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
41 | }
42 |
43 | override @property inout(TypeInfo) next() inout
44 | {
45 | return cast(inout)typeid(F);
46 | }
47 | }
48 |
49 | // ifloat[]
50 |
51 | class TypeInfo_Ao : TypeInfo_Af
52 | {
53 | alias F = ifloat;
54 |
55 | override string toString() const { return (F[]).stringof; }
56 |
57 | override @property inout(TypeInfo) next() inout
58 | {
59 | return cast(inout)typeid(F);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_Ag.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_Ag;
15 |
16 | private import core.stdc.string;
17 | private import rt.util.hash;
18 | private import core.internal.string;
19 |
20 | // byte[]
21 |
22 | class TypeInfo_Ag : TypeInfo_Array
23 | {
24 | override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
25 |
26 | override string toString() const { return "byte[]"; }
27 |
28 | override size_t getHash(in void* p) @trusted const
29 | {
30 | const s = *cast(const void[]*)p;
31 | return rt.util.hash.hashOf(s, 0);
32 | }
33 |
34 | override bool equals(in void* p1, in void* p2) const
35 | {
36 | byte[] s1 = *cast(byte[]*)p1;
37 | byte[] s2 = *cast(byte[]*)p2;
38 |
39 | return s1.length == s2.length &&
40 | memcmp(cast(byte *)s1, cast(byte *)s2, s1.length) == 0;
41 | }
42 |
43 | override int compare(in void* p1, in void* p2) const
44 | {
45 | byte[] s1 = *cast(byte[]*)p1;
46 | byte[] s2 = *cast(byte[]*)p2;
47 | size_t len = s1.length;
48 |
49 | if (s2.length < len)
50 | len = s2.length;
51 | for (size_t u = 0; u < len; u++)
52 | {
53 | int result = s1[u] - s2[u];
54 | if (result)
55 | return result;
56 | }
57 | if (s1.length < s2.length)
58 | return -1;
59 | else if (s1.length > s2.length)
60 | return 1;
61 | return 0;
62 | }
63 |
64 | override @property inout(TypeInfo) next() inout
65 | {
66 | return cast(inout)typeid(byte);
67 | }
68 | }
69 |
70 |
71 | // ubyte[]
72 |
73 | class TypeInfo_Ah : TypeInfo_Ag
74 | {
75 | override string toString() const { return "ubyte[]"; }
76 |
77 | override int compare(in void* p1, in void* p2) const
78 | {
79 | char[] s1 = *cast(char[]*)p1;
80 | char[] s2 = *cast(char[]*)p2;
81 |
82 | return dstrcmp(s1, s2);
83 | }
84 |
85 | override @property inout(TypeInfo) next() inout
86 | {
87 | return cast(inout)typeid(ubyte);
88 | }
89 | }
90 |
91 | // void[]
92 |
93 | class TypeInfo_Av : TypeInfo_Ah
94 | {
95 | override string toString() const { return "void[]"; }
96 |
97 | override @property inout(TypeInfo) next() inout
98 | {
99 | return cast(inout)typeid(void);
100 | }
101 | }
102 |
103 | // bool[]
104 |
105 | class TypeInfo_Ab : TypeInfo_Ah
106 | {
107 | override string toString() const { return "bool[]"; }
108 |
109 | override @property inout(TypeInfo) next() inout
110 | {
111 | return cast(inout)typeid(bool);
112 | }
113 | }
114 |
115 | // char[]
116 |
117 | class TypeInfo_Aa : TypeInfo_Ah
118 | {
119 | override string toString() const { return "char[]"; }
120 |
121 | override size_t getHash(in void* p) @trusted const
122 | {
123 | char[] s = *cast(char[]*)p;
124 | size_t hash = 0;
125 |
126 | version (all)
127 | {
128 | foreach (char c; s)
129 | hash = hash * 11 + c;
130 | }
131 | else
132 | {
133 | size_t len = s.length;
134 | char *str = s;
135 |
136 | while (1)
137 | {
138 | switch (len)
139 | {
140 | case 0:
141 | return hash;
142 |
143 | case 1:
144 | hash *= 9;
145 | hash += *cast(ubyte *)str;
146 | return hash;
147 |
148 | case 2:
149 | hash *= 9;
150 | hash += *cast(ushort *)str;
151 | return hash;
152 |
153 | case 3:
154 | hash *= 9;
155 | hash += (*cast(ushort *)str << 8) +
156 | (cast(ubyte *)str)[2];
157 | return hash;
158 |
159 | default:
160 | hash *= 9;
161 | hash += *cast(uint *)str;
162 | str += 4;
163 | len -= 4;
164 | break;
165 | }
166 | }
167 | }
168 | return hash;
169 | }
170 |
171 | override @property inout(TypeInfo) next() inout
172 | {
173 | return cast(inout)typeid(char);
174 | }
175 | }
176 |
177 | // string
178 |
179 | class TypeInfo_Aya : TypeInfo_Aa
180 | {
181 | override string toString() const { return "immutable(char)[]"; }
182 |
183 | override @property inout(TypeInfo) next() inout
184 | {
185 | return cast(inout)typeid(immutable(char));
186 | }
187 | }
188 |
189 | // const(char)[]
190 |
191 | class TypeInfo_Axa : TypeInfo_Aa
192 | {
193 | override string toString() const { return "const(char)[]"; }
194 |
195 | override @property inout(TypeInfo) next() inout
196 | {
197 | return cast(inout)typeid(const(char));
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_Aint.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_Aint;
15 |
16 | private import core.stdc.string;
17 | private import rt.util.hash;
18 |
19 | extern (C) void[] _adSort(void[] a, TypeInfo ti);
20 |
21 | // int[]
22 |
23 | class TypeInfo_Ai : TypeInfo_Array
24 | {
25 | override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
26 |
27 | override string toString() const { return "int[]"; }
28 |
29 | override size_t getHash(in void* p) @trusted const
30 | {
31 | const s = *cast(const int[]*)p;
32 | return rt.util.hash.hashOf(s, 0);
33 | }
34 |
35 | override bool equals(in void* p1, in void* p2) const
36 | {
37 | int[] s1 = *cast(int[]*)p1;
38 | int[] s2 = *cast(int[]*)p2;
39 |
40 | return s1.length == s2.length &&
41 | memcmp(cast(void *)s1, cast(void *)s2, s1.length * int.sizeof) == 0;
42 | }
43 |
44 | override int compare(in void* p1, in void* p2) const
45 | {
46 | int[] s1 = *cast(int[]*)p1;
47 | int[] s2 = *cast(int[]*)p2;
48 | size_t len = s1.length;
49 |
50 | if (s2.length < len)
51 | len = s2.length;
52 | for (size_t u = 0; u < len; u++)
53 | {
54 | if (s1[u] < s2[u])
55 | return -1;
56 | else if (s1[u] > s2[u])
57 | return 1;
58 | }
59 | if (s1.length < s2.length)
60 | return -1;
61 | else if (s1.length > s2.length)
62 | return 1;
63 | return 0;
64 | }
65 |
66 | override @property inout(TypeInfo) next() inout
67 | {
68 | return cast(inout)typeid(int);
69 | }
70 | }
71 |
72 | unittest
73 | {
74 | int[][] a = [[5,3,8,7], [2,5,3,8,7]];
75 | _adSort(*cast(void[]*)&a, typeid(a[0]));
76 | assert(a == [[2,5,3,8,7], [5,3,8,7]]);
77 |
78 | a = [[5,3,8,7], [5,3,8]];
79 | _adSort(*cast(void[]*)&a, typeid(a[0]));
80 | assert(a == [[5,3,8], [5,3,8,7]]);
81 | }
82 |
83 | unittest
84 | {
85 | // Issue 13073: original code uses int subtraction which is susceptible to
86 | // integer overflow, causing the following case to fail.
87 | int[] a = [int.max, int.max];
88 | int[] b = [int.min, int.min];
89 | assert(a > b);
90 | assert(b < a);
91 | }
92 |
93 | // uint[]
94 |
95 | class TypeInfo_Ak : TypeInfo_Ai
96 | {
97 | override string toString() const { return "uint[]"; }
98 |
99 | override int compare(in void* p1, in void* p2) const
100 | {
101 | uint[] s1 = *cast(uint[]*)p1;
102 | uint[] s2 = *cast(uint[]*)p2;
103 | size_t len = s1.length;
104 |
105 | if (s2.length < len)
106 | len = s2.length;
107 | for (size_t u = 0; u < len; u++)
108 | {
109 | if (s1[u] < s2[u])
110 | return -1;
111 | else if (s1[u] > s2[u])
112 | return 1;
113 | }
114 | if (s1.length < s2.length)
115 | return -1;
116 | else if (s1.length > s2.length)
117 | return 1;
118 | return 0;
119 | }
120 |
121 | override @property inout(TypeInfo) next() inout
122 | {
123 | return cast(inout)typeid(uint);
124 | }
125 | }
126 |
127 | unittest
128 | {
129 | // Original test case from issue 13073
130 | uint x = 0x22_DF_FF_FF;
131 | uint y = 0xA2_DF_FF_FF;
132 | assert(!(x < y && y < x));
133 | uint[] a = [x];
134 | uint[] b = [y];
135 | assert(!(a < b && b < a)); // Original failing case
136 | uint[1] a1 = [x];
137 | uint[1] b1 = [y];
138 | assert(!(a1 < b1 && b1 < a1)); // Original failing case
139 | }
140 |
141 | // dchar[]
142 |
143 | class TypeInfo_Aw : TypeInfo_Ak
144 | {
145 | override string toString() const { return "dchar[]"; }
146 |
147 | override @property inout(TypeInfo) next() inout
148 | {
149 | return cast(inout)typeid(dchar);
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_Along.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_Along;
15 |
16 | private import core.stdc.string;
17 | private import rt.util.hash;
18 |
19 | // long[]
20 |
21 | class TypeInfo_Al : TypeInfo_Array
22 | {
23 | override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
24 |
25 | override string toString() const { return "long[]"; }
26 |
27 | override size_t getHash(in void* p) @trusted const
28 | {
29 | const s = *cast(const long[]*)p;
30 | return rt.util.hash.hashOf(s, 0);
31 | }
32 |
33 | override bool equals(in void* p1, in void* p2) const
34 | {
35 | long[] s1 = *cast(long[]*)p1;
36 | long[] s2 = *cast(long[]*)p2;
37 |
38 | return s1.length == s2.length &&
39 | memcmp(cast(void *)s1, cast(void *)s2, s1.length * long.sizeof) == 0;
40 | }
41 |
42 | override int compare(in void* p1, in void* p2) const
43 | {
44 | long[] s1 = *cast(long[]*)p1;
45 | long[] s2 = *cast(long[]*)p2;
46 | size_t len = s1.length;
47 |
48 | if (s2.length < len)
49 | len = s2.length;
50 | for (size_t u = 0; u < len; u++)
51 | {
52 | if (s1[u] < s2[u])
53 | return -1;
54 | else if (s1[u] > s2[u])
55 | return 1;
56 | }
57 | if (s1.length < s2.length)
58 | return -1;
59 | else if (s1.length > s2.length)
60 | return 1;
61 | return 0;
62 | }
63 |
64 | override @property inout(TypeInfo) next() inout
65 | {
66 | return cast(inout)typeid(long);
67 | }
68 | }
69 |
70 |
71 | // ulong[]
72 |
73 | class TypeInfo_Am : TypeInfo_Al
74 | {
75 | override string toString() const { return "ulong[]"; }
76 |
77 | override int compare(in void* p1, in void* p2) const
78 | {
79 | ulong[] s1 = *cast(ulong[]*)p1;
80 | ulong[] s2 = *cast(ulong[]*)p2;
81 | size_t len = s1.length;
82 |
83 | if (s2.length < len)
84 | len = s2.length;
85 | for (size_t u = 0; u < len; u++)
86 | {
87 | if (s1[u] < s2[u])
88 | return -1;
89 | else if (s1[u] > s2[u])
90 | return 1;
91 | }
92 | if (s1.length < s2.length)
93 | return -1;
94 | else if (s1.length > s2.length)
95 | return 1;
96 | return 0;
97 | }
98 |
99 | override @property inout(TypeInfo) next() inout
100 | {
101 | return cast(inout)typeid(ulong);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_Areal.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_Areal;
15 |
16 | private import rt.util.typeinfo;
17 |
18 | // real[]
19 |
20 | class TypeInfo_Ae : TypeInfo_Array
21 | {
22 | alias F = real;
23 |
24 | override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
25 |
26 | override string toString() const { return (F[]).stringof; }
27 |
28 | override size_t getHash(in void* p) @trusted const
29 | {
30 | return Array!F.hashOf(*cast(F[]*)p);
31 | }
32 |
33 | override bool equals(in void* p1, in void* p2) const
34 | {
35 | return Array!F.equals(*cast(F[]*)p1, *cast(F[]*)p2);
36 | }
37 |
38 | override int compare(in void* p1, in void* p2) const
39 | {
40 | return Array!F.compare(*cast(F[]*)p1, *cast(F[]*)p2);
41 | }
42 |
43 | override @property inout(TypeInfo) next() inout
44 | {
45 | return cast(inout)typeid(F);
46 | }
47 | }
48 |
49 | // ireal[]
50 |
51 | class TypeInfo_Aj : TypeInfo_Ae
52 | {
53 | alias F = ireal;
54 |
55 | override string toString() const { return (F[]).stringof; }
56 |
57 | override @property inout(TypeInfo) next() inout
58 | {
59 | return cast(inout)typeid(F);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_Ashort.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_Ashort;
15 |
16 | private import core.stdc.string;
17 | private import rt.util.hash;
18 |
19 | // short[]
20 |
21 | class TypeInfo_As : TypeInfo_Array
22 | {
23 | override bool opEquals(Object o) { return TypeInfo.opEquals(o); }
24 |
25 | override string toString() const { return "short[]"; }
26 |
27 | override size_t getHash(in void* p) @trusted const
28 | {
29 | const s = *cast(const short[]*)p;
30 | return rt.util.hash.hashOf(s, 0);
31 | }
32 |
33 | override bool equals(in void* p1, in void* p2) const
34 | {
35 | short[] s1 = *cast(short[]*)p1;
36 | short[] s2 = *cast(short[]*)p2;
37 |
38 | return s1.length == s2.length &&
39 | memcmp(cast(void *)s1, cast(void *)s2, s1.length * short.sizeof) == 0;
40 | }
41 |
42 | override int compare(in void* p1, in void* p2) const
43 | {
44 | short[] s1 = *cast(short[]*)p1;
45 | short[] s2 = *cast(short[]*)p2;
46 | size_t len = s1.length;
47 |
48 | if (s2.length < len)
49 | len = s2.length;
50 | for (size_t u = 0; u < len; u++)
51 | {
52 | int result = s1[u] - s2[u];
53 | if (result)
54 | return result;
55 | }
56 | if (s1.length < s2.length)
57 | return -1;
58 | else if (s1.length > s2.length)
59 | return 1;
60 | return 0;
61 | }
62 |
63 | override @property inout(TypeInfo) next() inout
64 | {
65 | return cast(inout)typeid(short);
66 | }
67 | }
68 |
69 |
70 | // ushort[]
71 |
72 | class TypeInfo_At : TypeInfo_As
73 | {
74 | override string toString() const { return "ushort[]"; }
75 |
76 | override int compare(in void* p1, in void* p2) const
77 | {
78 | ushort[] s1 = *cast(ushort[]*)p1;
79 | ushort[] s2 = *cast(ushort[]*)p2;
80 | size_t len = s1.length;
81 |
82 | if (s2.length < len)
83 | len = s2.length;
84 | for (size_t u = 0; u < len; u++)
85 | {
86 | int result = s1[u] - s2[u];
87 | if (result)
88 | return result;
89 | }
90 | if (s1.length < s2.length)
91 | return -1;
92 | else if (s1.length > s2.length)
93 | return 1;
94 | return 0;
95 | }
96 |
97 | override @property inout(TypeInfo) next() inout
98 | {
99 | return cast(inout)typeid(ushort);
100 | }
101 | }
102 |
103 | // wchar[]
104 |
105 | class TypeInfo_Au : TypeInfo_At
106 | {
107 | override string toString() const { return "wchar[]"; }
108 |
109 | override @property inout(TypeInfo) next() inout
110 | {
111 | return cast(inout)typeid(wchar);
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_C.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_C;
15 |
16 | // Object
17 |
18 | class TypeInfo_C : TypeInfo
19 | {
20 | @trusted:
21 | const:
22 | //pure:
23 | //nothrow:
24 |
25 | override size_t getHash(in void* p)
26 | {
27 | Object o = *cast(Object*)p;
28 | return o ? o.toHash() : 0;
29 | }
30 |
31 | override bool equals(in void* p1, in void* p2)
32 | {
33 | Object o1 = *cast(Object*)p1;
34 | Object o2 = *cast(Object*)p2;
35 |
36 | return o1 == o2;
37 | }
38 |
39 | override int compare(in void* p1, in void* p2)
40 | {
41 | Object o1 = *cast(Object*)p1;
42 | Object o2 = *cast(Object*)p2;
43 | int c = 0;
44 |
45 | // Regard null references as always being "less than"
46 | if (!(o1 is o2))
47 | {
48 | if (o1)
49 | {
50 | if (!o2)
51 | c = 1;
52 | else
53 | c = o1.opCmp(o2);
54 | }
55 | else
56 | c = -1;
57 | }
58 | return c;
59 | }
60 |
61 | override @property size_t tsize() nothrow pure
62 | {
63 | return Object.sizeof;
64 | }
65 |
66 | override const(void)[] initializer() const @trusted
67 | {
68 | return (cast(void *)null)[0 .. Object.sizeof];
69 | }
70 |
71 | override @property uint flags() nothrow pure
72 | {
73 | return 1;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_byte.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_byte;
15 |
16 | // byte
17 |
18 | class TypeInfo_g : TypeInfo
19 | {
20 | @trusted:
21 | const:
22 | pure:
23 | nothrow:
24 |
25 | override string toString() const pure nothrow @safe { return "byte"; }
26 |
27 | override size_t getHash(in void* p)
28 | {
29 | return *cast(byte *)p;
30 | }
31 |
32 | override bool equals(in void* p1, in void* p2)
33 | {
34 | return *cast(byte *)p1 == *cast(byte *)p2;
35 | }
36 |
37 | override int compare(in void* p1, in void* p2)
38 | {
39 | return *cast(byte *)p1 - *cast(byte *)p2;
40 | }
41 |
42 | override @property size_t tsize() nothrow pure
43 | {
44 | return byte.sizeof;
45 | }
46 |
47 | override const(void)[] initializer() @trusted
48 | {
49 | return (cast(void *)null)[0 .. byte.sizeof];
50 | }
51 |
52 | override void swap(void *p1, void *p2)
53 | {
54 | byte t;
55 |
56 | t = *cast(byte *)p1;
57 | *cast(byte *)p1 = *cast(byte *)p2;
58 | *cast(byte *)p2 = t;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_cdouble.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_cdouble;
15 |
16 | private import rt.util.typeinfo;
17 |
18 | // cdouble
19 |
20 | class TypeInfo_r : TypeInfo
21 | {
22 | pure:
23 | nothrow:
24 | @safe:
25 |
26 | alias F = cdouble;
27 |
28 | override string toString() const { return F.stringof; }
29 |
30 | override size_t getHash(in void* p) const @trusted
31 | {
32 | return Floating!F.hashOf(*cast(F*)p);
33 | }
34 |
35 | override bool equals(in void* p1, in void* p2) const @trusted
36 | {
37 | return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);
38 | }
39 |
40 | override int compare(in void* p1, in void* p2) const @trusted
41 | {
42 | return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);
43 | }
44 |
45 | override @property size_t tsize() const
46 | {
47 | return F.sizeof;
48 | }
49 |
50 | override void swap(void *p1, void *p2) const @trusted
51 | {
52 | F t = *cast(F*)p1;
53 | *cast(F*)p1 = *cast(F*)p2;
54 | *cast(F*)p2 = t;
55 | }
56 |
57 | override const(void)[] initializer() const @trusted
58 | {
59 | static immutable F r;
60 | return (&r)[0 .. 1];
61 | }
62 |
63 | override @property size_t talign() const
64 | {
65 | return F.alignof;
66 | }
67 |
68 | version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
69 | {
70 | arg1 = typeid(double);
71 | arg2 = typeid(double);
72 | return 0;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_cent.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2015.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2015.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_cent;
15 |
16 | private import rt.util.hash;
17 |
18 | static if(is(cent)):
19 |
20 | // cent
21 |
22 | class TypeInfo_zi : TypeInfo
23 | {
24 | @trusted:
25 | const:
26 | pure:
27 | nothrow:
28 |
29 | override string toString() const pure nothrow @safe { return "cent"; }
30 |
31 | override size_t getHash(in void* p)
32 | {
33 | return rt.util.hash.hashOf(p[0 .. cent.sizeof], 0);
34 | }
35 |
36 | override bool equals(in void* p1, in void* p2)
37 | {
38 | return *cast(cent *)p1 == *cast(cent *)p2;
39 | }
40 |
41 | override int compare(in void* p1, in void* p2)
42 | {
43 | if (*cast(cent *)p1 < *cast(cent *)p2)
44 | return -1;
45 | else if (*cast(cent *)p1 > *cast(cent *)p2)
46 | return 1;
47 | return 0;
48 | }
49 |
50 | override @property size_t tsize() nothrow pure
51 | {
52 | return cent.sizeof;
53 | }
54 |
55 | override const(void)[] initializer() const @trusted
56 | {
57 | return (cast(void *)null)[0 .. cent.sizeof];
58 | }
59 |
60 | override void swap(void *p1, void *p2)
61 | {
62 | cent t;
63 |
64 | t = *cast(cent *)p1;
65 | *cast(cent *)p1 = *cast(cent *)p2;
66 | *cast(cent *)p2 = t;
67 | }
68 |
69 | override @property size_t talign() nothrow pure
70 | {
71 | return cent.alignof;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_cfloat.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_cfloat;
15 |
16 | private import rt.util.typeinfo;
17 |
18 | // cfloat
19 |
20 | class TypeInfo_q : TypeInfo
21 | {
22 | pure:
23 | nothrow:
24 | @safe:
25 |
26 | alias F = cfloat;
27 |
28 | override string toString() const { return F.stringof; }
29 |
30 | override size_t getHash(in void* p) const @trusted
31 | {
32 | return Floating!F.hashOf(*cast(F*)p);
33 | }
34 |
35 | override bool equals(in void* p1, in void* p2) const @trusted
36 | {
37 | return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);
38 | }
39 |
40 | override int compare(in void* p1, in void* p2) const @trusted
41 | {
42 | return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);
43 | }
44 |
45 | override @property size_t tsize() const
46 | {
47 | return F.sizeof;
48 | }
49 |
50 | override void swap(void *p1, void *p2) const @trusted
51 | {
52 | F t = *cast(F*)p1;
53 | *cast(F*)p1 = *cast(F*)p2;
54 | *cast(F*)p2 = t;
55 | }
56 |
57 | override const(void)[] initializer() const @trusted
58 | {
59 | static immutable F r;
60 | return (&r)[0 .. 1];
61 | }
62 |
63 | override @property size_t talign() const
64 | {
65 | return F.alignof;
66 | }
67 |
68 | version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
69 | {
70 | arg1 = typeid(double);
71 | return 0;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_char.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_char;
15 |
16 | // char
17 |
18 | class TypeInfo_a : TypeInfo
19 | {
20 | @trusted:
21 | const:
22 | pure:
23 | nothrow:
24 |
25 | override string toString() const pure nothrow @safe { return "char"; }
26 |
27 | override size_t getHash(in void* p)
28 | {
29 | return *cast(char *)p;
30 | }
31 |
32 | override bool equals(in void* p1, in void* p2)
33 | {
34 | return *cast(char *)p1 == *cast(char *)p2;
35 | }
36 |
37 | override int compare(in void* p1, in void* p2)
38 | {
39 | return *cast(char *)p1 - *cast(char *)p2;
40 | }
41 |
42 | override @property size_t tsize() nothrow pure
43 | {
44 | return char.sizeof;
45 | }
46 |
47 | override void swap(void *p1, void *p2)
48 | {
49 | char t;
50 |
51 | t = *cast(char *)p1;
52 | *cast(char *)p1 = *cast(char *)p2;
53 | *cast(char *)p2 = t;
54 | }
55 |
56 | override const(void)[] initializer() const @trusted
57 | {
58 | static immutable char c;
59 |
60 | return (&c)[0 .. 1];
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_creal.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_creal;
15 |
16 | private import rt.util.typeinfo;
17 |
18 | // creal
19 |
20 | class TypeInfo_c : TypeInfo
21 | {
22 | pure:
23 | nothrow:
24 | @safe:
25 |
26 | alias F = creal;
27 |
28 | override string toString() const { return F.stringof; }
29 |
30 | override size_t getHash(in void* p) const @trusted
31 | {
32 | return Floating!F.hashOf(*cast(F*)p);
33 | }
34 |
35 | override bool equals(in void* p1, in void* p2) const @trusted
36 | {
37 | return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);
38 | }
39 |
40 | override int compare(in void* p1, in void* p2) const @trusted
41 | {
42 | return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);
43 | }
44 |
45 | override @property size_t tsize() const
46 | {
47 | return F.sizeof;
48 | }
49 |
50 | override void swap(void *p1, void *p2) const @trusted
51 | {
52 | F t = *cast(F*)p1;
53 | *cast(F*)p1 = *cast(F*)p2;
54 | *cast(F*)p2 = t;
55 | }
56 |
57 | override const(void)[] initializer() const @trusted
58 | {
59 | static immutable F r;
60 | return (&r)[0 .. 1];
61 | }
62 |
63 | override @property size_t talign() const
64 | {
65 | return F.alignof;
66 | }
67 |
68 | version (X86_64) override int argTypes(out TypeInfo arg1, out TypeInfo arg2)
69 | {
70 | arg1 = typeid(real);
71 | arg2 = typeid(real);
72 | return 0;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_dchar.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_dchar;
15 |
16 | // dchar
17 |
18 | class TypeInfo_w : TypeInfo
19 | {
20 | @trusted:
21 | const:
22 | pure:
23 | nothrow:
24 |
25 | override string toString() const pure nothrow @safe { return "dchar"; }
26 |
27 | override size_t getHash(in void* p)
28 | {
29 | return *cast(dchar *)p;
30 | }
31 |
32 | override bool equals(in void* p1, in void* p2)
33 | {
34 | return *cast(dchar *)p1 == *cast(dchar *)p2;
35 | }
36 |
37 | override int compare(in void* p1, in void* p2)
38 | {
39 | return *cast(dchar *)p1 - *cast(dchar *)p2;
40 | }
41 |
42 | override @property size_t tsize() nothrow pure
43 | {
44 | return dchar.sizeof;
45 | }
46 |
47 | override void swap(void *p1, void *p2)
48 | {
49 | dchar t;
50 |
51 | t = *cast(dchar *)p1;
52 | *cast(dchar *)p1 = *cast(dchar *)p2;
53 | *cast(dchar *)p2 = t;
54 | }
55 |
56 | override const(void)[] initializer() const @trusted
57 | {
58 | static immutable dchar c;
59 |
60 | return (&c)[0 .. 1];
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_delegate.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_delegate;
15 |
16 | private import rt.util.hash;
17 |
18 | // delegate
19 |
20 | alias void delegate(int) dg;
21 |
22 | class TypeInfo_D : TypeInfo
23 | {
24 | @trusted:
25 | const:
26 | pure:
27 | nothrow:
28 |
29 | override size_t getHash(in void* p)
30 | {
31 | return rt.util.hash.hashOf(p[0 .. dg.sizeof], 0);
32 | }
33 |
34 | override bool equals(in void* p1, in void* p2)
35 | {
36 | return *cast(dg *)p1 == *cast(dg *)p2;
37 | }
38 |
39 | override @property size_t tsize() nothrow pure
40 | {
41 | return dg.sizeof;
42 | }
43 |
44 | override void swap(void *p1, void *p2)
45 | {
46 | dg t;
47 |
48 | t = *cast(dg *)p1;
49 | *cast(dg *)p1 = *cast(dg *)p2;
50 | *cast(dg *)p2 = t;
51 | }
52 |
53 | override const(void)[] initializer() const @trusted
54 | {
55 | static immutable dg d;
56 |
57 | return (cast(void *)null)[0 .. dg.sizeof];
58 | }
59 |
60 | override @property uint flags() nothrow pure
61 | {
62 | return 1;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_double.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_double;
15 |
16 | private import rt.util.typeinfo;
17 |
18 | // double
19 |
20 | class TypeInfo_d : TypeInfo
21 | {
22 | pure:
23 | nothrow:
24 | @safe:
25 |
26 | alias F = double;
27 |
28 | override string toString() const { return F.stringof; }
29 |
30 | override size_t getHash(in void* p) const @trusted
31 | {
32 | return Floating!F.hashOf(*cast(F*)p);
33 | }
34 |
35 | override bool equals(in void* p1, in void* p2) const @trusted
36 | {
37 | return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);
38 | }
39 |
40 | override int compare(in void* p1, in void* p2) const @trusted
41 | {
42 | return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);
43 | }
44 |
45 | override @property size_t tsize() const
46 | {
47 | return F.sizeof;
48 | }
49 |
50 | override void swap(void *p1, void *p2) const @trusted
51 | {
52 | F t = *cast(F*)p1;
53 | *cast(F*)p1 = *cast(F*)p2;
54 | *cast(F*)p2 = t;
55 | }
56 |
57 | override const(void)[] initializer() const @trusted
58 | {
59 | static immutable F r;
60 | return (&r)[0 .. 1];
61 | }
62 |
63 | override @property size_t talign() const
64 | {
65 | return F.alignof;
66 | }
67 |
68 | version (Windows)
69 | {
70 | }
71 | else version (X86_64)
72 | {
73 | // 2 means arg to function is passed in XMM registers
74 | override @property uint flags() const { return 2; }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_float.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_float;
15 |
16 | private import rt.util.typeinfo;
17 |
18 | // float
19 |
20 | class TypeInfo_f : TypeInfo
21 | {
22 | pure:
23 | nothrow:
24 | @safe:
25 |
26 | alias F = float;
27 |
28 | override string toString() const { return F.stringof; }
29 |
30 | override size_t getHash(in void* p) const @trusted
31 | {
32 | return Floating!F.hashOf(*cast(F*)p);
33 | }
34 |
35 | override bool equals(in void* p1, in void* p2) const @trusted
36 | {
37 | return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);
38 | }
39 |
40 | override int compare(in void* p1, in void* p2) const @trusted
41 | {
42 | return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);
43 | }
44 |
45 | override @property size_t tsize() const
46 | {
47 | return F.sizeof;
48 | }
49 |
50 | override void swap(void *p1, void *p2) const @trusted
51 | {
52 | F t = *cast(F*)p1;
53 | *cast(F*)p1 = *cast(F*)p2;
54 | *cast(F*)p2 = t;
55 | }
56 |
57 | override const(void)[] initializer() const @trusted
58 | {
59 | static immutable F r;
60 | return (&r)[0 .. 1];
61 | }
62 |
63 | version (Windows)
64 | {
65 | }
66 | else version (X86_64)
67 | {
68 | // 2 means arg to function is passed in XMM registers
69 | override @property uint flags() const { return 2; }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_idouble.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_idouble;
15 |
16 | private import rt.typeinfo.ti_double;
17 |
18 | // idouble
19 |
20 | class TypeInfo_p : TypeInfo_d
21 | {
22 | pure:
23 | nothrow:
24 | @safe:
25 |
26 | override string toString() const { return idouble.stringof; }
27 | }
28 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_ifloat.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_ifloat;
15 |
16 | private import rt.typeinfo.ti_float;
17 |
18 | // ifloat
19 |
20 | class TypeInfo_o : TypeInfo_f
21 | {
22 | pure:
23 | nothrow:
24 | @safe:
25 |
26 | override string toString() const { return ifloat.stringof; }
27 | }
28 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_int.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_int;
15 |
16 | // int
17 |
18 | class TypeInfo_i : TypeInfo
19 | {
20 | @trusted:
21 | const:
22 | pure:
23 | nothrow:
24 |
25 | override string toString() const pure nothrow @safe { return "int"; }
26 |
27 | override size_t getHash(in void* p)
28 | {
29 | return *cast(uint *)p;
30 | }
31 |
32 | override bool equals(in void* p1, in void* p2)
33 | {
34 | return *cast(uint *)p1 == *cast(uint *)p2;
35 | }
36 |
37 | override int compare(in void* p1, in void* p2)
38 | {
39 | if (*cast(int*) p1 < *cast(int*) p2)
40 | return -1;
41 | else if (*cast(int*) p1 > *cast(int*) p2)
42 | return 1;
43 | return 0;
44 | }
45 |
46 | override @property size_t tsize() nothrow pure
47 | {
48 | return int.sizeof;
49 | }
50 |
51 | override const(void)[] initializer() const @trusted
52 | {
53 | return (cast(void *)null)[0 .. int.sizeof];
54 | }
55 |
56 | override void swap(void *p1, void *p2)
57 | {
58 | int t;
59 |
60 | t = *cast(int *)p1;
61 | *cast(int *)p1 = *cast(int *)p2;
62 | *cast(int *)p2 = t;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_ireal.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_ireal;
15 |
16 | private import rt.typeinfo.ti_real;
17 |
18 | // ireal
19 |
20 | class TypeInfo_j : TypeInfo_e
21 | {
22 | pure:
23 | nothrow:
24 | @safe:
25 |
26 | override string toString() const { return ireal.stringof; }
27 | }
28 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_long.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_long;
15 |
16 | private import rt.util.hash;
17 |
18 | // long
19 |
20 | class TypeInfo_l : TypeInfo
21 | {
22 | @trusted:
23 | const:
24 | pure:
25 | nothrow:
26 |
27 | override string toString() const pure nothrow @safe { return "long"; }
28 |
29 | override size_t getHash(in void* p)
30 | {
31 | return rt.util.hash.hashOf(p[0 .. long.sizeof], 0);
32 | }
33 |
34 | override bool equals(in void* p1, in void* p2)
35 | {
36 | return *cast(long *)p1 == *cast(long *)p2;
37 | }
38 |
39 | override int compare(in void* p1, in void* p2)
40 | {
41 | if (*cast(long *)p1 < *cast(long *)p2)
42 | return -1;
43 | else if (*cast(long *)p1 > *cast(long *)p2)
44 | return 1;
45 | return 0;
46 | }
47 |
48 | override @property size_t tsize() nothrow pure
49 | {
50 | return long.sizeof;
51 | }
52 |
53 | override const(void)[] initializer() const @trusted
54 | {
55 | return (cast(void *)null)[0 .. long.sizeof];
56 | }
57 |
58 | override void swap(void *p1, void *p2)
59 | {
60 | long t;
61 |
62 | t = *cast(long *)p1;
63 | *cast(long *)p1 = *cast(long *)p2;
64 | *cast(long *)p2 = t;
65 | }
66 |
67 | override @property size_t talign() nothrow pure
68 | {
69 | return long.alignof;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_n.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2016.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Kenji Hara
7 | */
8 |
9 | /* Copyright Digital Mars 2016.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_n;
15 |
16 | // typeof(null)
17 |
18 | class TypeInfo_n : TypeInfo
19 | {
20 | override string toString() const @safe { return "typeof(null)"; }
21 |
22 | override size_t getHash(in void* p) const
23 | {
24 | return 0;
25 | }
26 |
27 | override bool equals(in void* p1, in void* p2) const @trusted
28 | {
29 | //return *cast(typeof(null)*)p1 is *cast(typeof(null)*)p2;
30 | return true;
31 | }
32 |
33 | override int compare(in void* p1, in void* p2) const @trusted
34 | {
35 | //if (*cast(int*) p1 < *cast(int*) p2)
36 | // return -1;
37 | //else if (*cast(int*) p1 > *cast(int*) p2)
38 | // return 1;
39 | return 0;
40 | }
41 |
42 | override @property size_t tsize() const
43 | {
44 | return typeof(null).sizeof;
45 | }
46 |
47 | override const(void)[] initializer() const @trusted
48 | {
49 | return (cast(void*)null)[0 .. typeof(null).sizeof];
50 | }
51 |
52 | override void swap(void *p1, void *p2) const @trusted
53 | {
54 | //auto t = *cast(typeof(null)*)p1;
55 | //*cast(typeof(null)*)p1 = *cast(typeof(null)*)p2;
56 | //*cast(typeof(null)*)p2 = t;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_ptr.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_ptr;
15 |
16 | // internal typeinfo for any pointer type
17 | // please keep in sync with TypeInfo_Pointer
18 |
19 | class TypeInfo_P : TypeInfo
20 | {
21 | @trusted:
22 | const:
23 | pure:
24 | nothrow:
25 |
26 | override size_t getHash(in void* p)
27 | {
28 | return cast(size_t)*cast(void**)p;
29 | }
30 |
31 | override bool equals(in void* p1, in void* p2)
32 | {
33 | return *cast(void**)p1 == *cast(void**)p2;
34 | }
35 |
36 | override int compare(in void* p1, in void* p2)
37 | {
38 | if (*cast(void**)p1 < *cast(void**)p2)
39 | return -1;
40 | else if (*cast(void**)p1 > *cast(void**)p2)
41 | return 1;
42 | else
43 | return 0;
44 | }
45 |
46 | override @property size_t tsize() nothrow pure
47 | {
48 | return (void*).sizeof;
49 | }
50 |
51 | override const(void)[] initializer() const @trusted
52 | {
53 | return (cast(void *)null)[0 .. (void*).sizeof];
54 | }
55 |
56 | override void swap(void *p1, void *p2)
57 | {
58 | void* tmp = *cast(void**)p1;
59 | *cast(void**)p1 = *cast(void**)p2;
60 | *cast(void**)p2 = tmp;
61 | }
62 |
63 | override @property uint flags() nothrow pure const { return 1; }
64 | }
65 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_real.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_real;
15 |
16 | private import rt.util.typeinfo;
17 |
18 | // real
19 |
20 | class TypeInfo_e : TypeInfo
21 | {
22 | pure:
23 | nothrow:
24 | @safe:
25 |
26 | alias F = real;
27 |
28 | override string toString() const { return F.stringof; }
29 |
30 | override size_t getHash(in void* p) const @trusted
31 | {
32 | return Floating!F.hashOf(*cast(F*)p);
33 | }
34 |
35 | override bool equals(in void* p1, in void* p2) const @trusted
36 | {
37 | return Floating!F.equals(*cast(F*)p1, *cast(F*)p2);
38 | }
39 |
40 | override int compare(in void* p1, in void* p2) const @trusted
41 | {
42 | return Floating!F.compare(*cast(F*)p1, *cast(F*)p2);
43 | }
44 |
45 | override @property size_t tsize() const
46 | {
47 | return F.sizeof;
48 | }
49 |
50 | override void swap(void *p1, void *p2) const @trusted
51 | {
52 | F t = *cast(F*)p1;
53 | *cast(F*)p1 = *cast(F*)p2;
54 | *cast(F*)p2 = t;
55 | }
56 |
57 | override const(void)[] initializer() const @trusted
58 | {
59 | static immutable F r;
60 | return (&r)[0 .. 1];
61 | }
62 |
63 | override @property size_t talign() const
64 | {
65 | return F.alignof;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_short.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_short;
15 |
16 | // short
17 |
18 | class TypeInfo_s : TypeInfo
19 | {
20 | @trusted:
21 | const:
22 | pure:
23 | nothrow:
24 |
25 | override string toString() const pure nothrow @safe { return "short"; }
26 |
27 | override size_t getHash(in void* p)
28 | {
29 | return *cast(short *)p;
30 | }
31 |
32 | override bool equals(in void* p1, in void* p2)
33 | {
34 | return *cast(short *)p1 == *cast(short *)p2;
35 | }
36 |
37 | override int compare(in void* p1, in void* p2)
38 | {
39 | return *cast(short *)p1 - *cast(short *)p2;
40 | }
41 |
42 | override @property size_t tsize() nothrow pure
43 | {
44 | return short.sizeof;
45 | }
46 |
47 | override const(void)[] initializer() const @trusted
48 | {
49 | return (cast(void *)null)[0 .. short.sizeof];
50 | }
51 |
52 | override void swap(void *p1, void *p2)
53 | {
54 | short t;
55 |
56 | t = *cast(short *)p1;
57 | *cast(short *)p1 = *cast(short *)p2;
58 | *cast(short *)p2 = t;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_ubyte.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_ubyte;
15 |
16 | // ubyte
17 |
18 | class TypeInfo_h : TypeInfo
19 | {
20 | @trusted:
21 | const:
22 | pure:
23 | nothrow:
24 |
25 | override string toString() const pure nothrow @safe { return "ubyte"; }
26 |
27 | override size_t getHash(in void* p)
28 | {
29 | return *cast(ubyte *)p;
30 | }
31 |
32 | override bool equals(in void* p1, in void* p2)
33 | {
34 | return *cast(ubyte *)p1 == *cast(ubyte *)p2;
35 | }
36 |
37 | override int compare(in void* p1, in void* p2)
38 | {
39 | return *cast(ubyte *)p1 - *cast(ubyte *)p2;
40 | }
41 |
42 | override @property size_t tsize() nothrow pure
43 | {
44 | return ubyte.sizeof;
45 | }
46 |
47 | override const(void)[] initializer() const @trusted
48 | {
49 | return (cast(void *)null)[0 .. ubyte.sizeof];
50 | }
51 |
52 | override void swap(void *p1, void *p2)
53 | {
54 | ubyte t;
55 |
56 | t = *cast(ubyte *)p1;
57 | *cast(ubyte *)p1 = *cast(ubyte *)p2;
58 | *cast(ubyte *)p2 = t;
59 | }
60 | }
61 |
62 | class TypeInfo_b : TypeInfo_h
63 | {
64 | @trusted:
65 | const:
66 | pure:
67 | nothrow:
68 |
69 | override string toString() const pure nothrow @safe { return "bool"; }
70 | }
71 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_ucent.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2015.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2015.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_ucent;
15 |
16 | private import rt.util.hash;
17 |
18 | static if (is(ucent)):
19 |
20 | // ucent
21 |
22 | class TypeInfo_zk : TypeInfo
23 | {
24 | @trusted:
25 | const:
26 | pure:
27 | nothrow:
28 |
29 | override string toString() const pure nothrow @safe { return "ucent"; }
30 |
31 | override size_t getHash(in void* p)
32 | {
33 | return rt.util.hash.hashOf(p[0 .. ucent.sizeof], 0);
34 | }
35 |
36 | override bool equals(in void* p1, in void* p2)
37 | {
38 | return *cast(ucent *)p1 == *cast(ucent *)p2;
39 | }
40 |
41 | override int compare(in void* p1, in void* p2)
42 | {
43 | if (*cast(ucent *)p1 < *cast(ucent *)p2)
44 | return -1;
45 | else if (*cast(ucent *)p1 > *cast(ucent *)p2)
46 | return 1;
47 | return 0;
48 | }
49 |
50 | override @property size_t tsize() nothrow pure
51 | {
52 | return ucent.sizeof;
53 | }
54 |
55 | override const(void)[] initializer() const @trusted
56 | {
57 | return (cast(void *)null)[0 .. ucent.sizeof];
58 | }
59 |
60 | override void swap(void *p1, void *p2)
61 | {
62 | ucent t;
63 |
64 | t = *cast(ucent *)p1;
65 | *cast(ucent *)p1 = *cast(ucent *)p2;
66 | *cast(ucent *)p2 = t;
67 | }
68 |
69 | override @property size_t talign() nothrow pure
70 | {
71 | return ucent.alignof;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_uint.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_uint;
15 |
16 | // uint
17 |
18 | class TypeInfo_k : TypeInfo
19 | {
20 | @trusted:
21 | const:
22 | pure:
23 | nothrow:
24 |
25 | override string toString() const pure nothrow @safe { return "uint"; }
26 |
27 | override size_t getHash(in void* p)
28 | {
29 | return *cast(uint *)p;
30 | }
31 |
32 | override bool equals(in void* p1, in void* p2)
33 | {
34 | return *cast(uint *)p1 == *cast(uint *)p2;
35 | }
36 |
37 | override int compare(in void* p1, in void* p2)
38 | {
39 | if (*cast(uint*) p1 < *cast(uint*) p2)
40 | return -1;
41 | else if (*cast(uint*) p1 > *cast(uint*) p2)
42 | return 1;
43 | return 0;
44 | }
45 |
46 | override @property size_t tsize() nothrow pure
47 | {
48 | return uint.sizeof;
49 | }
50 |
51 | override const(void)[] initializer() const @trusted
52 | {
53 | return (cast(void *)null)[0 .. uint.sizeof];
54 | }
55 |
56 | override void swap(void *p1, void *p2)
57 | {
58 | int t;
59 |
60 | t = *cast(uint *)p1;
61 | *cast(uint *)p1 = *cast(uint *)p2;
62 | *cast(uint *)p2 = t;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_ulong.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_ulong;
15 |
16 | private import rt.util.hash;
17 |
18 | // ulong
19 |
20 | class TypeInfo_m : TypeInfo
21 | {
22 | @trusted:
23 | const:
24 | pure:
25 | nothrow:
26 |
27 | override string toString() const pure nothrow @safe { return "ulong"; }
28 |
29 | override size_t getHash(in void* p)
30 | {
31 | return rt.util.hash.hashOf(p[0 .. ulong.sizeof], 0);
32 | }
33 |
34 | override bool equals(in void* p1, in void* p2)
35 | {
36 | return *cast(ulong *)p1 == *cast(ulong *)p2;
37 | }
38 |
39 | override int compare(in void* p1, in void* p2)
40 | {
41 | if (*cast(ulong *)p1 < *cast(ulong *)p2)
42 | return -1;
43 | else if (*cast(ulong *)p1 > *cast(ulong *)p2)
44 | return 1;
45 | return 0;
46 | }
47 |
48 | override @property size_t tsize() nothrow pure
49 | {
50 | return ulong.sizeof;
51 | }
52 |
53 | override const(void)[] initializer() const @trusted
54 | {
55 | return (cast(void *)null)[0 .. ulong.sizeof];
56 | }
57 |
58 | override void swap(void *p1, void *p2)
59 | {
60 | ulong t;
61 |
62 | t = *cast(ulong *)p1;
63 | *cast(ulong *)p1 = *cast(ulong *)p2;
64 | *cast(ulong *)p2 = t;
65 | }
66 |
67 | override @property size_t talign() nothrow pure
68 | {
69 | return ulong.alignof;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_ushort.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_ushort;
15 |
16 | // ushort
17 |
18 | class TypeInfo_t : TypeInfo
19 | {
20 | @trusted:
21 | const:
22 | pure:
23 | nothrow:
24 |
25 | override string toString() const pure nothrow @safe { return "ushort"; }
26 |
27 | override size_t getHash(in void* p)
28 | {
29 | return *cast(ushort *)p;
30 | }
31 |
32 | override bool equals(in void* p1, in void* p2)
33 | {
34 | return *cast(ushort *)p1 == *cast(ushort *)p2;
35 | }
36 |
37 | override int compare(in void* p1, in void* p2)
38 | {
39 | return *cast(ushort *)p1 - *cast(ushort *)p2;
40 | }
41 |
42 | override @property size_t tsize() nothrow pure
43 | {
44 | return ushort.sizeof;
45 | }
46 |
47 | override const(void)[] initializer() const @trusted
48 | {
49 | return (cast(void *)null)[0 .. ushort.sizeof];
50 | }
51 |
52 | override void swap(void *p1, void *p2)
53 | {
54 | ushort t;
55 |
56 | t = *cast(ushort *)p1;
57 | *cast(ushort *)p1 = *cast(ushort *)p2;
58 | *cast(ushort *)p2 = t;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_void.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_void;
15 |
16 | // void
17 |
18 | class TypeInfo_v : TypeInfo
19 | {
20 | @trusted:
21 | const:
22 | pure:
23 | nothrow:
24 |
25 | override string toString() const pure nothrow @safe { return "void"; }
26 |
27 | override size_t getHash(in void* p)
28 | {
29 | assert(0);
30 | }
31 |
32 | override bool equals(in void* p1, in void* p2)
33 | {
34 | return *cast(byte *)p1 == *cast(byte *)p2;
35 | }
36 |
37 | override int compare(in void* p1, in void* p2)
38 | {
39 | return *cast(byte *)p1 - *cast(byte *)p2;
40 | }
41 |
42 | override @property size_t tsize() nothrow pure
43 | {
44 | return void.sizeof;
45 | }
46 |
47 | override const(void)[] initializer() const @trusted
48 | {
49 | return (cast(void *)null)[0 .. void.sizeof];
50 | }
51 |
52 | override void swap(void *p1, void *p2)
53 | {
54 | byte t;
55 |
56 | t = *cast(byte *)p1;
57 | *cast(byte *)p1 = *cast(byte *)p2;
58 | *cast(byte *)p2 = t;
59 | }
60 |
61 | override @property uint flags() nothrow pure
62 | {
63 | return 1;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/rt/rt/typeinfo/ti_wchar.d:
--------------------------------------------------------------------------------
1 | /**
2 | * TypeInfo support code.
3 | *
4 | * Copyright: Copyright Digital Mars 2004 - 2009.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Walter Bright
7 | */
8 |
9 | /* Copyright Digital Mars 2004 - 2009.
10 | * Distributed under the Boost Software License, Version 1.0.
11 | * (See accompanying file LICENSE or copy at
12 | * http://www.boost.org/LICENSE_1_0.txt)
13 | */
14 | module rt.typeinfo.ti_wchar;
15 |
16 | // wchar
17 |
18 | class TypeInfo_u : TypeInfo
19 | {
20 | @trusted:
21 | const:
22 | pure:
23 | nothrow:
24 |
25 | override string toString() { return "wchar"; }
26 |
27 | override size_t getHash(in void* p)
28 | {
29 | return *cast(wchar *)p;
30 | }
31 |
32 | override bool equals(in void* p1, in void* p2)
33 | {
34 | return *cast(wchar *)p1 == *cast(wchar *)p2;
35 | }
36 |
37 | override int compare(in void* p1, in void* p2)
38 | {
39 | return *cast(wchar *)p1 - *cast(wchar *)p2;
40 | }
41 |
42 | override @property size_t tsize()
43 | {
44 | return wchar.sizeof;
45 | }
46 |
47 | override void swap(void *p1, void *p2)
48 | {
49 | wchar t;
50 |
51 | t = *cast(wchar *)p1;
52 | *cast(wchar *)p1 = *cast(wchar *)p2;
53 | *cast(wchar *)p2 = t;
54 | }
55 |
56 | override const(void)[] initializer() const @trusted
57 | {
58 | static immutable wchar c;
59 |
60 | return (&c)[0 .. 1];
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/rt/rt/util/container/array.d:
--------------------------------------------------------------------------------
1 | /**
2 | * Array container for internal usage.
3 | *
4 | * Copyright: Copyright Martin Nowak 2013.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Martin Nowak
7 | */
8 | module rt.util.container.array;
9 |
10 | static import common = rt.util.container.common;
11 |
12 | import core.exception : onOutOfMemoryErrorNoGC;
13 |
14 | struct Array(T)
15 | {
16 | nothrow:
17 | @disable this(this);
18 |
19 | ~this()
20 | {
21 | reset();
22 | }
23 |
24 | void reset()
25 | {
26 | length = 0;
27 | }
28 |
29 | @property size_t length() const
30 | {
31 | return _length;
32 | }
33 |
34 | @property void length(size_t nlength)
35 | {
36 | import core.checkedint : mulu;
37 |
38 | bool overflow = false;
39 | size_t reqsize = mulu(T.sizeof, nlength, overflow);
40 | if (!overflow)
41 | {
42 | if (nlength < _length)
43 | foreach (ref val; _ptr[nlength .. _length]) common.destroy(val);
44 | _ptr = cast(T*)common.xrealloc(_ptr, reqsize);
45 | if (nlength > _length)
46 | foreach (ref val; _ptr[_length .. nlength]) common.initialize(val);
47 | _length = nlength;
48 | }
49 | else
50 | onOutOfMemoryErrorNoGC();
51 |
52 | }
53 |
54 | @property bool empty() const
55 | {
56 | return !length;
57 | }
58 |
59 | @property ref inout(T) front() inout
60 | in { assert(!empty); }
61 | do
62 | {
63 | return _ptr[0];
64 | }
65 |
66 | @property ref inout(T) back() inout
67 | in { assert(!empty); }
68 | do
69 | {
70 | return _ptr[_length - 1];
71 | }
72 |
73 | ref inout(T) opIndex(size_t idx) inout
74 | in { assert(idx < length); }
75 | do
76 | {
77 | return _ptr[idx];
78 | }
79 |
80 | inout(T)[] opSlice() inout
81 | {
82 | return _ptr[0 .. _length];
83 | }
84 |
85 | inout(T)[] opSlice(size_t a, size_t b) inout
86 | in { assert(a < b && b <= length); }
87 | do
88 | {
89 | return _ptr[a .. b];
90 | }
91 |
92 | alias length opDollar;
93 |
94 | void insertBack()(auto ref T val)
95 | {
96 | import core.checkedint : addu;
97 |
98 | bool overflow = false;
99 | size_t newlength = addu(length, 1, overflow);
100 | if (!overflow)
101 | {
102 | length = newlength;
103 | back = val;
104 | }
105 | else
106 | onOutOfMemoryErrorNoGC();
107 | }
108 |
109 | void popBack()
110 | {
111 | length = length - 1;
112 | }
113 |
114 | void remove(size_t idx)
115 | in { assert(idx < length); }
116 | do
117 | {
118 | foreach (i; idx .. length - 1)
119 | _ptr[i] = _ptr[i+1];
120 | popBack();
121 | }
122 |
123 | void swap(ref Array other)
124 | {
125 | auto ptr = _ptr;
126 | _ptr = other._ptr;
127 | other._ptr = ptr;
128 | immutable len = _length;
129 | _length = other._length;
130 | other._length = len;
131 | }
132 |
133 | invariant
134 | {
135 | assert(!_ptr == !_length);
136 | }
137 |
138 | private:
139 | T* _ptr;
140 | size_t _length;
141 | }
142 |
143 | unittest
144 | {
145 | Array!size_t ary;
146 |
147 | assert(ary[] == []);
148 | ary.insertBack(5);
149 | assert(ary[] == [5]);
150 | assert(ary[$-1] == 5);
151 | ary.popBack();
152 | assert(ary[] == []);
153 | ary.insertBack(0);
154 | ary.insertBack(1);
155 | assert(ary[] == [0, 1]);
156 | assert(ary[0 .. 1] == [0]);
157 | assert(ary[1 .. 2] == [1]);
158 | assert(ary[$ - 2 .. $] == [0, 1]);
159 | size_t idx;
160 | foreach (val; ary) assert(idx++ == val);
161 | foreach_reverse (val; ary) assert(--idx == val);
162 | foreach (i, val; ary) assert(i == val);
163 | foreach_reverse (i, val; ary) assert(i == val);
164 |
165 | ary.insertBack(2);
166 | ary.remove(1);
167 | assert(ary[] == [0, 2]);
168 |
169 | assert(!ary.empty);
170 | ary.reset();
171 | assert(ary.empty);
172 | ary.insertBack(0);
173 | assert(!ary.empty);
174 | destroy(ary);
175 | assert(ary.empty);
176 |
177 | // not copyable
178 | static assert(!__traits(compiles, { Array!size_t ary2 = ary; }));
179 | Array!size_t ary2;
180 | static assert(!__traits(compiles, ary = ary2));
181 | static void foo(Array!size_t copy) {}
182 | static assert(!__traits(compiles, foo(ary)));
183 |
184 | ary2.insertBack(0);
185 | assert(ary.empty);
186 | assert(ary2[] == [0]);
187 | ary.swap(ary2);
188 | assert(ary[] == [0]);
189 | assert(ary2.empty);
190 | }
191 |
192 | unittest
193 | {
194 | alias RC = common.RC;
195 | Array!RC ary;
196 |
197 | size_t cnt;
198 | assert(cnt == 0);
199 | ary.insertBack(RC(&cnt));
200 | assert(cnt == 1);
201 | ary.insertBack(RC(&cnt));
202 | assert(cnt == 2);
203 | ary.back = ary.front;
204 | assert(cnt == 2);
205 | ary.popBack();
206 | assert(cnt == 1);
207 | ary.popBack();
208 | assert(cnt == 0);
209 | }
210 |
211 | unittest
212 | {
213 | import core.exception;
214 | try
215 | {
216 | // Overflow ary.length.
217 | auto ary = Array!size_t(cast(size_t*)0xdeadbeef, -1);
218 | ary.insertBack(0);
219 | }
220 | catch(OutOfMemoryError)
221 | {
222 | }
223 | try
224 | {
225 | // Overflow requested memory size for common.xrealloc().
226 | auto ary = Array!size_t(cast(size_t*)0xdeadbeef, -2);
227 | ary.insertBack(0);
228 | }
229 | catch(OutOfMemoryError)
230 | {
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/rt/rt/util/container/common.d:
--------------------------------------------------------------------------------
1 | /**
2 | * Common code for writing containers.
3 | *
4 | * Copyright: Copyright Martin Nowak 2013.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Martin Nowak
7 | */
8 | module rt.util.container.common;
9 |
10 | import core.stdc.stdlib : malloc, realloc;
11 | public import core.stdc.stdlib : free;
12 | import core.internal.traits : dtorIsNothrow;
13 | nothrow:
14 |
15 | void* xrealloc(void* ptr, size_t sz) nothrow @nogc
16 | {
17 | import core.exception;
18 |
19 | if (!sz) { .free(ptr); return null; }
20 | if (auto nptr = .realloc(ptr, sz)) return nptr;
21 | .free(ptr); onOutOfMemoryErrorNoGC();
22 | assert(0);
23 | }
24 |
25 | void* xmalloc(size_t sz) nothrow @nogc
26 | {
27 | import core.exception;
28 | if (auto nptr = .malloc(sz))
29 | return nptr;
30 | onOutOfMemoryErrorNoGC();
31 | assert(0);
32 | }
33 |
34 | void destroy(T)(ref T t) if (is(T == struct) && dtorIsNothrow!T)
35 | {
36 | scope (failure) assert(0); // nothrow hack
37 | object.destroy(t);
38 | }
39 |
40 | void destroy(T)(ref T t) if (!is(T == struct))
41 | {
42 | t = T.init;
43 | }
44 |
45 | void initialize(T)(ref T t) if (is(T == struct))
46 | {
47 | import core.stdc.string;
48 | if(auto p = typeid(T).initializer().ptr)
49 | memcpy(&t, p, T.sizeof);
50 | else
51 | memset(&t, 0, T.sizeof);
52 | }
53 |
54 | void initialize(T)(ref T t) if (!is(T == struct))
55 | {
56 | t = T.init;
57 | }
58 |
59 | version (unittest) struct RC
60 | {
61 | nothrow:
62 | this(size_t* cnt) { ++*(_cnt = cnt); }
63 | ~this() { if (_cnt) --*_cnt; }
64 | this(this) { if (_cnt) ++*_cnt; }
65 | size_t* _cnt;
66 | }
67 |
--------------------------------------------------------------------------------
/rt/rt/util/container/hashtab.d:
--------------------------------------------------------------------------------
1 | /**
2 | * HashTab container for internal usage.
3 | *
4 | * Copyright: Copyright Martin Nowak 2013.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Martin Nowak
7 | */
8 | module rt.util.container.hashtab;
9 |
10 | import rt.util.container.array;
11 | static import common = rt.util.container.common;
12 |
13 | struct HashTab(Key, Value)
14 | {
15 | static struct Node
16 | {
17 | Key _key;
18 | Value _value;
19 | Node* _next;
20 | }
21 |
22 | @disable this(this);
23 |
24 | ~this()
25 | {
26 | reset();
27 | }
28 |
29 | void reset()
30 | {
31 | foreach (p; _buckets)
32 | {
33 | while (p !is null)
34 | {
35 | auto pn = p._next;
36 | common.destroy(*p);
37 | common.free(p);
38 | p = pn;
39 | }
40 | }
41 | _buckets.reset();
42 | _length = 0;
43 | }
44 |
45 | @property size_t length() const
46 | {
47 | return _length;
48 | }
49 |
50 | @property bool empty() const
51 | {
52 | return !_length;
53 | }
54 |
55 | void remove(in Key key)
56 | in { assert(key in this); }
57 | do
58 | {
59 | ensureNotInOpApply();
60 |
61 | immutable hash = hashOf(key) & mask;
62 | auto pp = &_buckets[hash];
63 | while (*pp)
64 | {
65 | auto p = *pp;
66 | if (p._key == key)
67 | {
68 | *pp = p._next;
69 | common.destroy(*p);
70 | common.free(p);
71 | if (--_length < _buckets.length && _length >= 4)
72 | shrink();
73 | return;
74 | }
75 | else
76 | {
77 | pp = &p._next;
78 | }
79 | }
80 | assert(0);
81 | }
82 |
83 | ref inout(Value) opIndex(Key key) inout
84 | {
85 | return *opIn_r(key);
86 | }
87 |
88 | void opIndexAssign(Value value, Key key)
89 | {
90 | *get(key) = value;
91 | }
92 |
93 | inout(Value)* opIn_r(in Key key) inout
94 | {
95 | if (_buckets.length)
96 | {
97 | immutable hash = hashOf(key) & mask;
98 | for (inout(Node)* p = _buckets[hash]; p !is null; p = p._next)
99 | {
100 | if (p._key == key)
101 | return &p._value;
102 | }
103 | }
104 | return null;
105 | }
106 |
107 | int opApply(scope int delegate(ref Key, ref Value) dg)
108 | {
109 | immutable save = _inOpApply;
110 | _inOpApply = true;
111 | scope (exit) _inOpApply = save;
112 | foreach (p; _buckets)
113 | {
114 | while (p !is null)
115 | {
116 | if (auto res = dg(p._key, p._value))
117 | return res;
118 | p = p._next;
119 | }
120 | }
121 | return 0;
122 | }
123 |
124 | private:
125 |
126 | Value* get(Key key)
127 | {
128 | if (auto p = opIn_r(key))
129 | return p;
130 |
131 | ensureNotInOpApply();
132 |
133 | if (!_buckets.length)
134 | _buckets.length = 4;
135 |
136 | immutable hash = hashOf(key) & mask;
137 | auto p = cast(Node*)common.xmalloc(Node.sizeof);
138 | common.initialize(*p);
139 | p._key = key;
140 | p._next = _buckets[hash];
141 | _buckets[hash] = p;
142 | if (++_length >= 2 * _buckets.length)
143 | grow();
144 | return &p._value;
145 | }
146 |
147 | static hash_t hashOf(in ref Key key) @trusted
148 | {
149 | import rt.util.hash : hashOf;
150 | static if (is(Key U : U[]))
151 | return hashOf(key, 0);
152 | else
153 | return hashOf((&key)[0 .. 1], 0);
154 | }
155 |
156 | @property hash_t mask() const
157 | {
158 | return _buckets.length - 1;
159 | }
160 |
161 | void grow()
162 | in
163 | {
164 | assert(_buckets.length);
165 | }
166 | do
167 | {
168 | immutable ocnt = _buckets.length;
169 | immutable nmask = 2 * ocnt - 1;
170 | _buckets.length = 2 * ocnt;
171 | for (size_t i = 0; i < ocnt; ++i)
172 | {
173 | auto pp = &_buckets[i];
174 | while (*pp)
175 | {
176 | auto p = *pp;
177 |
178 | immutable nidx = hashOf(p._key) & nmask;
179 | if (nidx != i)
180 | {
181 | *pp = p._next;
182 | p._next = _buckets[nidx];
183 | _buckets[nidx] = p;
184 | }
185 | else
186 | {
187 | pp = &p._next;
188 | }
189 | }
190 | }
191 | }
192 |
193 | void shrink()
194 | in
195 | {
196 | assert(_buckets.length >= 2);
197 | }
198 | do
199 | {
200 | immutable ocnt = _buckets.length;
201 | immutable ncnt = ocnt >> 1;
202 | immutable nmask = ncnt - 1;
203 |
204 | for (size_t i = ncnt; i < ocnt; ++i)
205 | {
206 | if (auto tail = _buckets[i])
207 | {
208 | immutable nidx = i & nmask;
209 | auto pp = &_buckets[nidx];
210 | while (*pp)
211 | pp = &(*pp)._next;
212 | *pp = tail;
213 | _buckets[i] = null;
214 | }
215 | }
216 | _buckets.length = ncnt;
217 | }
218 |
219 | void ensureNotInOpApply()
220 | {
221 | if (_inOpApply)
222 | assert(0, "Invalid HashTab manipulation during opApply iteration.");
223 | }
224 |
225 | Array!(Node*) _buckets;
226 | size_t _length;
227 | bool _inOpApply;
228 | }
229 |
230 | unittest
231 | {
232 | HashTab!(int, int) tab;
233 |
234 | foreach(i; 0 .. 100)
235 | tab[i] = 100 - i;
236 |
237 | foreach(i; 0 .. 100)
238 | assert(tab[i] == 100 - i);
239 |
240 | foreach (k, v; tab)
241 | assert(v == 100 - k);
242 |
243 | foreach(i; 0 .. 50)
244 | tab.remove(2 * i);
245 |
246 | assert(tab.length == 50);
247 |
248 | foreach(i; 0 .. 50)
249 | assert(tab[2 * i + 1] == 100 - 2 * i - 1);
250 |
251 | assert(tab.length == 50);
252 |
253 | tab.reset();
254 | assert(tab.empty);
255 | tab[0] = 0;
256 | assert(!tab.empty);
257 | destroy(tab);
258 | assert(tab.empty);
259 |
260 | // not copyable
261 | static assert(!__traits(compiles, { HashTab!(int, int) tab2 = tab; }));
262 | HashTab!(int, int) tab2;
263 | static assert(!__traits(compiles, tab = tab2));
264 | static void foo(HashTab!(int, int) copy) {}
265 | static assert(!__traits(compiles, foo(tab)));
266 | }
267 |
268 | unittest
269 | {
270 | HashTab!(string, size_t) tab;
271 |
272 | tab["foo"] = 0;
273 | assert(tab["foo"] == 0);
274 | ++tab["foo"];
275 | assert(tab["foo"] == 1);
276 | tab["foo"]++;
277 | assert(tab["foo"] == 2);
278 |
279 | auto s = "fo";
280 | s ~= "o";
281 | assert(tab[s] == 2);
282 | assert(tab.length == 1);
283 | tab[s] -= 2;
284 | assert(tab[s] == 0);
285 | tab["foo"] = 12;
286 | assert(tab[s] == 12);
287 |
288 | tab.remove("foo");
289 | assert(tab.empty);
290 | }
291 |
292 | unittest
293 | {
294 | alias RC = common.RC;
295 | HashTab!(size_t, RC) tab;
296 |
297 | size_t cnt;
298 | assert(cnt == 0);
299 | tab[0] = RC(&cnt);
300 | assert(cnt == 1);
301 | tab[1] = tab[0];
302 | assert(cnt == 2);
303 | tab.remove(0);
304 | assert(cnt == 1);
305 | tab.remove(1);
306 | assert(cnt == 0);
307 | }
308 |
309 | unittest
310 | {
311 | import core.exception;
312 |
313 | HashTab!(uint, uint) tab;
314 | foreach (i; 0 .. 5)
315 | tab[i] = i;
316 | bool thrown;
317 | foreach (k, v; tab)
318 | {
319 | try
320 | {
321 | if (k == 3) tab.remove(k);
322 | }
323 | catch (AssertError e)
324 | {
325 | thrown = true;
326 | }
327 | }
328 | assert(thrown);
329 | assert(tab[3] == 3);
330 | }
331 |
--------------------------------------------------------------------------------
/rt/rt/util/hash.d:
--------------------------------------------------------------------------------
1 | /**
2 | * The default hash implementation.
3 | *
4 | * Copyright: Copyright Sean Kelly 2009 - 2016.
5 | * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 | * Authors: Sean Kelly
7 | * Source: $(DRUNTIMESRC src/rt/util/_hash.d)
8 | */
9 | module rt.util.hash;
10 |
11 |
12 | version( X86 )
13 | version = AnyX86;
14 | version( X86_64 )
15 | version = AnyX86;
16 | version( AnyX86 )
17 | version = HasUnalignedOps;
18 |
19 |
20 | @trusted pure nothrow @nogc
21 | size_t hashOf( const(void)[] buf, size_t seed )
22 | {
23 | /*
24 | * This is Paul Hsieh's SuperFastHash algorithm, described here:
25 | * http://www.azillionmonkeys.com/qed/hash.html
26 | * It is protected by the following open source license:
27 | * http://www.azillionmonkeys.com/qed/weblicense.html
28 | */
29 | static uint get16bits( const (ubyte)* x ) pure nothrow @nogc
30 | {
31 | // CTFE doesn't support casting ubyte* -> ushort*, so revert to
32 | // per-byte access when in CTFE.
33 | version( HasUnalignedOps )
34 | {
35 | if (!__ctfe)
36 | return *cast(ushort*) x;
37 | }
38 |
39 | return ((cast(uint) x[1]) << 8) + (cast(uint) x[0]);
40 | }
41 |
42 | // NOTE: SuperFastHash normally starts with a zero hash value. The seed
43 | // value was incorporated to allow chaining.
44 | auto data = cast(const(ubyte)*) buf.ptr;
45 | auto len = buf.length;
46 | auto hash = seed;
47 |
48 | if( len == 0 || data is null )
49 | return 0;
50 |
51 | int rem = len & 3;
52 | len >>= 2;
53 |
54 | for( ; len > 0; len-- )
55 | {
56 | hash += get16bits( data );
57 | auto tmp = (get16bits( data + 2 ) << 11) ^ hash;
58 | hash = (hash << 16) ^ tmp;
59 | data += 2 * ushort.sizeof;
60 | hash += hash >> 11;
61 | }
62 |
63 | switch( rem )
64 | {
65 | case 3: hash += get16bits( data );
66 | hash ^= hash << 16;
67 | hash ^= data[ushort.sizeof] << 18;
68 | hash += hash >> 11;
69 | break;
70 | case 2: hash += get16bits( data );
71 | hash ^= hash << 11;
72 | hash += hash >> 17;
73 | break;
74 | case 1: hash += *data;
75 | hash ^= hash << 10;
76 | hash += hash >> 1;
77 | break;
78 | default:
79 | break;
80 | }
81 |
82 | /* Force "avalanching" of final 127 bits */
83 | hash ^= hash << 3;
84 | hash += hash >> 5;
85 | hash ^= hash << 4;
86 | hash += hash >> 17;
87 | hash ^= hash << 25;
88 | hash += hash >> 6;
89 |
90 | return hash;
91 | }
92 |
93 | unittest
94 | {
95 | enum test_str = "Sample string";
96 | size_t hashval = hashOf(test_str, 5);
97 |
98 | //import core.stdc.stdio;
99 | //printf("hashval = %lld\n", cast(long)hashval);
100 |
101 | if (hashval.sizeof == 4)
102 | assert(hashval == 528740845);
103 | else if (hashval.sizeof == 8)
104 | assert(hashval == 8106800467257150594L);
105 | else
106 | assert(0);
107 | }
108 |
--------------------------------------------------------------------------------
/rt/rt/util/typeinfo.d:
--------------------------------------------------------------------------------
1 | /**
2 | * This module contains utilities for TypeInfo implementation.
3 | *
4 | * Copyright: Copyright Kenji Hara 2014-.
5 | * License: Boost License 1.0.
6 | * Authors: Kenji Hara
7 | */
8 | module rt.util.typeinfo;
9 |
10 | private enum isX87Real(T) = (T.mant_dig == 64 && T.max_exp == 16384);
11 |
12 | template Floating(T)
13 | if (is(T == float) || is(T == double) || is(T == real))
14 | {
15 | pure nothrow @safe:
16 |
17 | bool equals(T f1, T f2)
18 | {
19 | return f1 == f2;
20 | }
21 |
22 | int compare(T d1, T d2)
23 | {
24 | if (d1 != d1 || d2 != d2) // if either are NaN
25 | {
26 | if (d1 != d1)
27 | {
28 | if (d2 != d2)
29 | return 0;
30 | return -1;
31 | }
32 | return 1;
33 | }
34 | return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
35 | }
36 |
37 | size_t hashOf(T value) @trusted
38 | {
39 | if (value == 0) // +0.0 and -0.0
40 | value = 0;
41 |
42 | static if (is(T == float)) // special case?
43 | return *cast(uint*)&value;
44 | else
45 | {
46 | import rt.util.hash;
47 | static if (isX87Real!T) // Only consider the non-padding bytes.
48 | return rt.util.hash.hashOf((cast(void*) &value)[0 .. 10], 0);
49 | else
50 | return rt.util.hash.hashOf((&value)[0 .. 1], 0);
51 | }
52 | }
53 | }
54 | template Floating(T)
55 | if (is(T == cfloat) || is(T == cdouble) || is(T == creal))
56 | {
57 | pure nothrow @safe:
58 |
59 | bool equals(T f1, T f2)
60 | {
61 | return f1 == f2;
62 | }
63 |
64 | int compare(T f1, T f2)
65 | {
66 | int result;
67 |
68 | if (f1.re < f2.re)
69 | result = -1;
70 | else if (f1.re > f2.re)
71 | result = 1;
72 | else if (f1.im < f2.im)
73 | result = -1;
74 | else if (f1.im > f2.im)
75 | result = 1;
76 | else
77 | result = 0;
78 | return result;
79 | }
80 |
81 | size_t hashOf(T value) @trusted
82 | {
83 | if (value == 0 + 0i)
84 | value = 0 + 0i;
85 | import rt.util.hash;
86 | static if (isX87Real!(typeof(T.init.re))) // Only consider the non-padding bytes.
87 | {
88 | real* ptr = cast(real*) &value;
89 | return rt.util.hash.hashOf((cast(void*) &ptr[0])[0 .. 10],
90 | rt.util.hash.hashOf((cast(void*) &ptr[1])[0 .. 10], 0));
91 | }
92 | else
93 | return rt.util.hash.hashOf((&value)[0 .. 1], 0);
94 | }
95 | }
96 |
97 | template Array(T)
98 | if (is(T == float) || is(T == double) || is(T == real) ||
99 | is(T == cfloat) || is(T == cdouble) || is(T == creal))
100 | {
101 | pure nothrow @safe:
102 |
103 | bool equals(T[] s1, T[] s2)
104 | {
105 | size_t len = s1.length;
106 | if (len != s2.length)
107 | return false;
108 | for (size_t u = 0; u < len; u++)
109 | {
110 | if (!Floating!T.equals(s1[u], s2[u]))
111 | return false;
112 | }
113 | return true;
114 | }
115 |
116 | int compare(T[] s1, T[] s2)
117 | {
118 | size_t len = s1.length;
119 | if (s2.length < len)
120 | len = s2.length;
121 | for (size_t u = 0; u < len; u++)
122 | {
123 | if (int c = Floating!T.compare(s1[u], s2[u]))
124 | return c;
125 | }
126 | if (s1.length < s2.length)
127 | return -1;
128 | else if (s1.length > s2.length)
129 | return 1;
130 | return 0;
131 | }
132 |
133 | size_t hashOf(T[] value)
134 | {
135 | size_t h = 0;
136 | foreach (e; value)
137 | h += Floating!T.hashOf(e);
138 | return h;
139 | }
140 | }
141 |
142 | version(unittest)
143 | {
144 | alias TypeTuple(T...) = T;
145 | }
146 | unittest
147 | {
148 | // Bugzilla 13052
149 |
150 | static struct SX(F) { F f; }
151 | TypeInfo ti;
152 |
153 | // real types
154 | foreach (F; TypeTuple!(float, double, real))
155 | (){ // workaround #2396
156 | alias S = SX!F;
157 | F f1 = +0.0,
158 | f2 = -0.0;
159 |
160 | assert(f1 == f2);
161 | assert(f1 !is f2);
162 | ti = typeid(F);
163 | assert(ti.getHash(&f1) == ti.getHash(&f2));
164 |
165 | F[] a1 = [f1, f1, f1];
166 | F[] a2 = [f2, f2, f2];
167 | assert(a1 == a2);
168 | assert(a1 !is a2);
169 | ti = typeid(F[]);
170 | assert(ti.getHash(&a1) == ti.getHash(&a2));
171 |
172 | F[][] aa1 = [a1, a1, a1];
173 | F[][] aa2 = [a2, a2, a2];
174 | assert(aa1 == aa2);
175 | assert(aa1 !is aa2);
176 | ti = typeid(F[][]);
177 | assert(ti.getHash(&aa1) == ti.getHash(&aa2));
178 |
179 | S s1 = {f1},
180 | s2 = {f2};
181 | assert(s1 == s2);
182 | assert(s1 !is s2);
183 | ti = typeid(S);
184 | assert(ti.getHash(&s1) == ti.getHash(&s2));
185 |
186 | S[] da1 = [S(f1), S(f1), S(f1)],
187 | da2 = [S(f2), S(f2), S(f2)];
188 | assert(da1 == da2);
189 | assert(da1 !is da2);
190 | ti = typeid(S[]);
191 | assert(ti.getHash(&da1) == ti.getHash(&da2));
192 |
193 | S[3] sa1 = {f1},
194 | sa2 = {f2};
195 | assert(sa1 == sa2);
196 | assert(sa1[] !is sa2[]);
197 | ti = typeid(S[3]);
198 | assert(ti.getHash(&sa1) == ti.getHash(&sa2));
199 | }();
200 |
201 | // imaginary types
202 | foreach (F; TypeTuple!(ifloat, idouble, ireal))
203 | (){ // workaround #2396
204 | alias S = SX!F;
205 | F f1 = +0.0i,
206 | f2 = -0.0i;
207 |
208 | assert(f1 == f2);
209 | assert(f1 !is f2);
210 | ti = typeid(F);
211 | assert(ti.getHash(&f1) == ti.getHash(&f2));
212 |
213 | F[] a1 = [f1, f1, f1];
214 | F[] a2 = [f2, f2, f2];
215 | assert(a1 == a2);
216 | assert(a1 !is a2);
217 | ti = typeid(F[]);
218 | assert(ti.getHash(&a1) == ti.getHash(&a2));
219 |
220 | F[][] aa1 = [a1, a1, a1];
221 | F[][] aa2 = [a2, a2, a2];
222 | assert(aa1 == aa2);
223 | assert(aa1 !is aa2);
224 | ti = typeid(F[][]);
225 | assert(ti.getHash(&aa1) == ti.getHash(&aa2));
226 |
227 | S s1 = {f1},
228 | s2 = {f2};
229 | assert(s1 == s2);
230 | assert(s1 !is s2);
231 | ti = typeid(S);
232 | assert(ti.getHash(&s1) == ti.getHash(&s2));
233 |
234 | S[] da1 = [S(f1), S(f1), S(f1)],
235 | da2 = [S(f2), S(f2), S(f2)];
236 | assert(da1 == da2);
237 | assert(da1 !is da2);
238 | ti = typeid(S[]);
239 | assert(ti.getHash(&da1) == ti.getHash(&da2));
240 |
241 | S[3] sa1 = {f1},
242 | sa2 = {f2};
243 | assert(sa1 == sa2);
244 | assert(sa1[] !is sa2[]);
245 | ti = typeid(S[3]);
246 | assert(ti.getHash(&sa1) == ti.getHash(&sa2));
247 | }();
248 |
249 | // complex types
250 | foreach (F; TypeTuple!(cfloat, cdouble, creal))
251 | (){ // workaround #2396
252 | alias S = SX!F;
253 | F[4] f = [+0.0 + 0.0i,
254 | +0.0 - 0.0i,
255 | -0.0 + 0.0i,
256 | -0.0 - 0.0i];
257 |
258 | foreach (i, f1; f) foreach (j, f2; f) if (i != j)
259 | {
260 | assert(f1 == 0 + 0i);
261 |
262 | assert(f1 == f2);
263 | assert(f1 !is f2);
264 | ti = typeid(F);
265 | assert(ti.getHash(&f1) == ti.getHash(&f2));
266 |
267 | F[] a1 = [f1, f1, f1];
268 | F[] a2 = [f2, f2, f2];
269 | assert(a1 == a2);
270 | assert(a1 !is a2);
271 | ti = typeid(F[]);
272 | assert(ti.getHash(&a1) == ti.getHash(&a2));
273 |
274 | F[][] aa1 = [a1, a1, a1];
275 | F[][] aa2 = [a2, a2, a2];
276 | assert(aa1 == aa2);
277 | assert(aa1 !is aa2);
278 | ti = typeid(F[][]);
279 | assert(ti.getHash(&aa1) == ti.getHash(&aa2));
280 |
281 | S s1 = {f1},
282 | s2 = {f2};
283 | assert(s1 == s2);
284 | assert(s1 !is s2);
285 | ti = typeid(S);
286 | assert(ti.getHash(&s1) == ti.getHash(&s2));
287 |
288 | S[] da1 = [S(f1), S(f1), S(f1)],
289 | da2 = [S(f2), S(f2), S(f2)];
290 | assert(da1 == da2);
291 | assert(da1 !is da2);
292 | ti = typeid(S[]);
293 | assert(ti.getHash(&da1) == ti.getHash(&da2));
294 |
295 | S[3] sa1 = {f1},
296 | sa2 = {f2};
297 | assert(sa1 == sa2);
298 | assert(sa1[] !is sa2[]);
299 | ti = typeid(S[3]);
300 | assert(ti.getHash(&sa1) == ti.getHash(&sa2));
301 | }
302 | }();
303 | }
304 |
--------------------------------------------------------------------------------
/rt/runtime.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | ///////////////////////////////////////////////////////////////////////////////
5 |
6 | void not_implemented(const char* file, int line)
7 | {
8 | printf("Not implemented: %s(%d)\n", file, line);
9 | exit(123);
10 | }
11 |
12 | #define NOT_IMPLEMENTED not_implemented(__FILE__, __LINE__)
13 |
14 | ///////////////////////////////////////////////////////////////////////////////
15 | // make link work. will most probably crash if actually used during runtime.
16 | // can't get rid of those, seems to be refered-to by compiler-inserted code
17 | int _D10TypeInfo_v6__initZ;
18 | int _D10TypeInfo_m6__initZ;
19 | int _D11TypeInfo_Ai6__initZ;
20 | void _d_throw_exception() { NOT_IMPLEMENTED; }
21 | ///////////////////////////////////////////////////////////////////////////////
22 |
23 |
--------------------------------------------------------------------------------
/rt/std/experimental/allocator/mallocator.d:
--------------------------------------------------------------------------------
1 | // Written in the D programming language.
2 | /**
3 | The C heap allocator.
4 |
5 | Source: $(PHOBOSSRC std/experimental/allocator/_mallocator.d)
6 | */
7 | module std.experimental.allocator.mallocator;
8 | import std.experimental.allocator.common;
9 |
10 | /**
11 | The C heap allocator.
12 | */
13 | struct Mallocator
14 | {
15 | @system unittest { testAllocator!(() => Mallocator.instance); }
16 |
17 | /**
18 | The alignment is a static constant equal to $(D platformAlignment), which
19 | ensures proper alignment for any D data type.
20 | */
21 | enum uint alignment = platformAlignment;
22 |
23 | /**
24 | Standard allocator methods per the semantics defined above. The
25 | $(D deallocate) and $(D reallocate) methods are $(D @system) because they
26 | may move memory around, leaving dangling pointers in user code. Somewhat
27 | paradoxically, $(D malloc) is $(D @safe) but that's only useful to safe
28 | programs that can afford to leak memory allocated.
29 | */
30 | @trusted @nogc nothrow
31 | void[] allocate(size_t bytes) shared
32 | {
33 | import core.stdc.stdlib : malloc;
34 | if (!bytes) return null;
35 | auto p = malloc(bytes);
36 | return p ? p[0 .. bytes] : null;
37 | }
38 |
39 | /// Ditto
40 | @system @nogc nothrow
41 | bool deallocate(void[] b) shared
42 | {
43 | import core.stdc.stdlib : free;
44 | free(b.ptr);
45 | return true;
46 | }
47 |
48 | /// Ditto
49 | @system @nogc nothrow
50 | bool reallocate(ref void[] b, size_t s) shared
51 | {
52 | import core.stdc.stdlib : realloc;
53 | if (!s)
54 | {
55 | // fuzzy area in the C standard, see http://goo.gl/ZpWeSE
56 | // so just deallocate and nullify the pointer
57 | deallocate(b);
58 | b = null;
59 | return true;
60 | }
61 | auto p = cast(ubyte*) realloc(b.ptr, s);
62 | if (!p) return false;
63 | b = p[0 .. s];
64 | return true;
65 | }
66 |
67 | /**
68 | Returns the global instance of this allocator type. The C heap allocator is
69 | thread-safe, therefore all of its methods and `it` itself are
70 | $(D shared).
71 | */
72 | static shared Mallocator instance;
73 | }
74 |
75 | ///
76 | @nogc @system nothrow unittest
77 | {
78 | auto buffer = Mallocator.instance.allocate(1024 * 1024 * 4);
79 | scope(exit) Mallocator.instance.deallocate(buffer);
80 | //...
81 | }
82 |
83 | @nogc @system nothrow unittest
84 | {
85 | @nogc nothrow
86 | static void test(A)()
87 | {
88 | int* p = null;
89 | p = cast(int*) A.instance.allocate(int.sizeof);
90 | scope(exit) () nothrow @nogc { A.instance.deallocate(p[0 .. int.sizeof]); }();
91 | *p = 42;
92 | assert(*p == 42);
93 | }
94 | test!Mallocator();
95 | }
96 |
97 | @nogc @system nothrow unittest
98 | {
99 | static void test(A)()
100 | {
101 | import std.experimental.allocator : make;
102 | Object p = null;
103 | p = A.instance.make!Object();
104 | assert(p !is null);
105 | }
106 |
107 | test!Mallocator();
108 | }
109 |
110 | version (Windows)
111 | {
112 | // DMD Win 32 bit, DigitalMars C standard library misses the _aligned_xxx
113 | // functions family (snn.lib)
114 | version(CRuntime_DigitalMars)
115 | {
116 | // Helper to cast the infos written before the aligned pointer
117 | // this header keeps track of the size (required to realloc) and of
118 | // the base ptr (required to free).
119 | private struct AlignInfo
120 | {
121 | void* basePtr;
122 | size_t size;
123 |
124 | @nogc nothrow
125 | static AlignInfo* opCall(void* ptr)
126 | {
127 | return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
128 | }
129 | }
130 |
131 | @nogc nothrow
132 | private void* _aligned_malloc(size_t size, size_t alignment)
133 | {
134 | import std.c.stdlib : malloc;
135 | size_t offset = alignment + size_t.sizeof * 2 - 1;
136 |
137 | // unaligned chunk
138 | void* basePtr = malloc(size + offset);
139 | if (!basePtr) return null;
140 |
141 | // get aligned location within the chunk
142 | void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
143 | & ~(alignment - 1));
144 |
145 | // write the header before the aligned pointer
146 | AlignInfo* head = AlignInfo(alignedPtr);
147 | head.basePtr = basePtr;
148 | head.size = size;
149 |
150 | return alignedPtr;
151 | }
152 |
153 | @nogc nothrow
154 | private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
155 | {
156 | import std.c.stdlib : free;
157 | import std.c.string : memcpy;
158 |
159 | if (!ptr) return _aligned_malloc(size, alignment);
160 |
161 | // gets the header from the exising pointer
162 | AlignInfo* head = AlignInfo(ptr);
163 |
164 | // gets a new aligned pointer
165 | void* alignedPtr = _aligned_malloc(size, alignment);
166 | if (!alignedPtr)
167 | {
168 | //to https://msdn.microsoft.com/en-us/library/ms235462.aspx
169 | //see Return value: in this case the original block is unchanged
170 | return null;
171 | }
172 |
173 | // copy exising data
174 | memcpy(alignedPtr, ptr, head.size);
175 | free(head.basePtr);
176 |
177 | return alignedPtr;
178 | }
179 |
180 | @nogc nothrow
181 | private void _aligned_free(void *ptr)
182 | {
183 | import std.c.stdlib : free;
184 | if (!ptr) return;
185 | AlignInfo* head = AlignInfo(ptr);
186 | free(head.basePtr);
187 | }
188 |
189 | }
190 | // DMD Win 64 bit, uses microsoft standard C library which implements them
191 | else
192 | {
193 | @nogc nothrow private extern(C) void* _aligned_malloc(size_t, size_t);
194 | @nogc nothrow private extern(C) void _aligned_free(void *memblock);
195 | @nogc nothrow private extern(C) void* _aligned_realloc(void *, size_t, size_t);
196 | }
197 | }
198 |
199 | /**
200 | Aligned allocator using OS-specific primitives, under a uniform API.
201 | */
202 | version (dscripten) {} else
203 | struct AlignedMallocator
204 | {
205 | @system unittest { testAllocator!(() => typeof(this).instance); }
206 |
207 | /**
208 | The default alignment is $(D platformAlignment).
209 | */
210 | enum uint alignment = platformAlignment;
211 |
212 | /**
213 | Forwards to $(D alignedAllocate(bytes, platformAlignment)).
214 | */
215 | @trusted @nogc nothrow
216 | void[] allocate(size_t bytes) shared
217 | {
218 | if (!bytes) return null;
219 | return alignedAllocate(bytes, alignment);
220 | }
221 |
222 | /**
223 | Uses $(HTTP man7.org/linux/man-pages/man3/posix_memalign.3.html,
224 | $(D posix_memalign)) on Posix and
225 | $(HTTP msdn.microsoft.com/en-us/library/8z34s9c6(v=vs.80).aspx,
226 | $(D __aligned_malloc)) on Windows.
227 | */
228 | version(Posix)
229 | @trusted @nogc nothrow
230 | void[] alignedAllocate(size_t bytes, uint a) shared
231 | {
232 | import core.stdc.errno : ENOMEM, EINVAL;
233 | import core.sys.posix.stdlib : posix_memalign;
234 | assert(a.isGoodDynamicAlignment);
235 | void* result;
236 | auto code = posix_memalign(&result, a, bytes);
237 | if (code == ENOMEM)
238 | return null;
239 |
240 | else if (code == EINVAL)
241 | {
242 | assert(0, "AlignedMallocator.alignment is not a power of two "
243 | ~"multiple of (void*).sizeof, according to posix_memalign!");
244 | }
245 | else if (code != 0)
246 | assert(0, "posix_memalign returned an unknown code!");
247 |
248 | else
249 | return result[0 .. bytes];
250 | }
251 | else version(Windows)
252 | @trusted @nogc nothrow
253 | void[] alignedAllocate(size_t bytes, uint a) shared
254 | {
255 | auto result = _aligned_malloc(bytes, a);
256 | return result ? result[0 .. bytes] : null;
257 | }
258 | else static assert(0);
259 |
260 | /**
261 | Calls $(D free(b.ptr)) on Posix and
262 | $(HTTP msdn.microsoft.com/en-US/library/17b5h8td(v=vs.80).aspx,
263 | $(D __aligned_free(b.ptr))) on Windows.
264 | */
265 | version (Posix)
266 | @system @nogc nothrow
267 | bool deallocate(void[] b) shared
268 | {
269 | import core.stdc.stdlib : free;
270 | free(b.ptr);
271 | return true;
272 | }
273 | else version (Windows)
274 | @system @nogc nothrow
275 | bool deallocate(void[] b) shared
276 | {
277 | _aligned_free(b.ptr);
278 | return true;
279 | }
280 | else static assert(0);
281 |
282 | /**
283 | Forwards to $(D alignedReallocate(b, newSize, platformAlignment)).
284 | Should be used with bocks obtained with `allocate` otherwise the custom
285 | alignment passed with `alignedAllocate` can be lost.
286 | */
287 | @system @nogc nothrow
288 | bool reallocate(ref void[] b, size_t newSize) shared
289 | {
290 | return alignedReallocate(b, newSize, alignment);
291 | }
292 |
293 | /**
294 | On Posix there is no `realloc` for aligned memory, so `alignedReallocate` emulates
295 | the needed behavior by using `alignedAllocate` to get a new block. The existing
296 | block is copied to the new block and then freed.
297 | On Windows, calls $(HTTPS msdn.microsoft.com/en-us/library/y69db7sx.aspx,
298 | $(D __aligned_realloc(b.ptr, newSize, a))).
299 | */
300 | version (Windows)
301 | @system @nogc nothrow
302 | bool alignedReallocate(ref void[] b, size_t s, uint a) shared
303 | {
304 | if (!s)
305 | {
306 | deallocate(b);
307 | b = null;
308 | return true;
309 | }
310 | auto p = cast(ubyte*) _aligned_realloc(b.ptr, s, a);
311 | if (!p) return false;
312 | b = p[0 .. s];
313 | return true;
314 | }
315 |
316 | /// ditto
317 | version (Posix)
318 | @system @nogc nothrow
319 | bool alignedReallocate(ref void[] b, size_t s, uint a) shared
320 | {
321 | if (!s)
322 | {
323 | deallocate(b);
324 | b = null;
325 | return true;
326 | }
327 | auto p = alignedAllocate(s, a);
328 | if (!p.ptr)
329 | {
330 | return false;
331 | }
332 | import std.algorithm.comparison : min;
333 | const upTo = min(s, b.length);
334 | p[0 .. upTo] = b[0 .. upTo];
335 | deallocate(b);
336 | b = p;
337 | return true;
338 | }
339 |
340 | /**
341 | Returns the global instance of this allocator type. The C heap allocator is
342 | thread-safe, therefore all of its methods and `instance` itself are
343 | $(D shared).
344 | */
345 | static shared AlignedMallocator instance;
346 | }
347 |
348 | ///
349 | @nogc @system nothrow unittest
350 | {
351 | auto buffer = AlignedMallocator.instance.alignedAllocate(1024 * 1024 * 4,
352 | 128);
353 | scope(exit) AlignedMallocator.instance.deallocate(buffer);
354 | //...
355 | }
356 |
357 | version(unittest) version(CRuntime_DigitalMars)
358 | @nogc nothrow
359 | size_t addr(ref void* ptr) { return cast(size_t) ptr; }
360 |
361 | version(Posix)
362 | @nogc @system nothrow unittest
363 | {
364 | // 16398 : test the "pseudo" alignedReallocate for Posix
365 | void[] s = AlignedMallocator.instance.alignedAllocate(16, 32);
366 | (cast(ubyte[]) s)[] = ubyte(1);
367 | AlignedMallocator.instance.alignedReallocate(s, 32, 32);
368 | ubyte[16] o;
369 | o[] = 1;
370 | assert((cast(ubyte[]) s)[0 .. 16] == o);
371 | AlignedMallocator.instance.alignedReallocate(s, 4, 32);
372 | assert((cast(ubyte[]) s)[0 .. 3] == o[0 .. 3]);
373 | AlignedMallocator.instance.alignedReallocate(s, 128, 32);
374 | assert((cast(ubyte[]) s)[0 .. 3] == o[0 .. 3]);
375 | AlignedMallocator.instance.deallocate(s);
376 |
377 | void[] c;
378 | AlignedMallocator.instance.alignedReallocate(c, 32, 32);
379 | assert(c.ptr);
380 |
381 | assert(!AlignedMallocator.instance.alignedReallocate(c, size_t.max, 4096));
382 | AlignedMallocator.instance.deallocate(c);
383 | }
384 |
385 | version(CRuntime_DigitalMars)
386 | @nogc @system nothrow unittest
387 | {
388 | void* m;
389 |
390 | m = _aligned_malloc(16, 0x10);
391 | if (m)
392 | {
393 | assert((m.addr & 0xF) == 0);
394 | _aligned_free(m);
395 | }
396 |
397 | m = _aligned_malloc(16, 0x100);
398 | if (m)
399 | {
400 | assert((m.addr & 0xFF) == 0);
401 | _aligned_free(m);
402 | }
403 |
404 | m = _aligned_malloc(16, 0x1000);
405 | if (m)
406 | {
407 | assert((m.addr & 0xFFF) == 0);
408 | _aligned_free(m);
409 | }
410 |
411 | m = _aligned_malloc(16, 0x10);
412 | if (m)
413 | {
414 | assert((cast(size_t) m & 0xF) == 0);
415 | m = _aligned_realloc(m, 32, 0x10000);
416 | if (m) assert((m.addr & 0xFFFF) == 0);
417 | _aligned_free(m);
418 | }
419 |
420 | m = _aligned_malloc(8, 0x10);
421 | if (m)
422 | {
423 | *cast(ulong*) m = 0X01234567_89ABCDEF;
424 | m = _aligned_realloc(m, 0x800, 0x1000);
425 | if (m) assert(*cast(ulong*) m == 0X01234567_89ABCDEF);
426 | _aligned_free(m);
427 | }
428 | }
429 |
--------------------------------------------------------------------------------
/rt/std/system.d:
--------------------------------------------------------------------------------
1 | // Written in the D programming language.
2 |
3 | /**
4 | * Information about the target operating system, environment, and CPU.
5 | *
6 | * Copyright: Copyright Digital Mars 2000 - 2011
7 | * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
8 | * Authors: $(HTTP digitalmars.com, Walter Bright) and Jonathan M Davis
9 | * Source: $(PHOBOSSRC std/_system.d)
10 | */
11 | module std.system;
12 |
13 | immutable
14 | {
15 | /++
16 | Operating system.
17 |
18 | Note:
19 | This is for cases where you need a value representing the OS at
20 | runtime. If you're doing something which should compile differently
21 | on different OSes, then please use $(D version(Windows)),
22 | $(D version(linux)), etc.
23 |
24 | See_Also:
25 | $(DDSUBLINK spec/version,PredefinedVersions, Predefined Versions)
26 | +/
27 | enum OS
28 | {
29 | win32 = 1, /// Microsoft 32 bit Windows systems
30 | win64, /// Microsoft 64 bit Windows systems
31 | linux, /// All Linux Systems
32 | osx, /// Mac OS X
33 | freeBSD, /// FreeBSD
34 | netBSD, /// NetBSD
35 | solaris, /// Solaris
36 | android, /// Android
37 | otherPosix /// Other Posix Systems
38 | }
39 |
40 | /// The OS that the program was compiled for.
41 | version(Win32) OS os = OS.win32;
42 | else version(Win64) OS os = OS.win64;
43 | else version(Android) OS os = OS.android;
44 | else version(linux) OS os = OS.linux;
45 | else version(OSX) OS os = OS.osx;
46 | else version(FreeBSD) OS os = OS.freeBSD;
47 | else version(NetBSD) OS os = OS.netBSD;
48 | else version(Posix) OS os = OS.otherPosix;
49 | else version(dscripten) OS os = OS.otherPosix;
50 | else static assert(0, "Unknown OS.");
51 |
52 | /++
53 | Byte order endianness.
54 |
55 | Note:
56 | This is intended for cases where you need to deal with endianness at
57 | runtime. If you're doing something which should compile differently
58 | depending on whether you're compiling on a big endian or little
59 | endian machine, then please use $(D version(BigEndian)) and
60 | $(D version(LittleEndian)).
61 |
62 | See_Also:
63 | $(DDSUBLINK spec/version,PredefinedVersions, Predefined Versions)
64 | +/
65 | enum Endian
66 | {
67 | bigEndian, /// Big endian byte order
68 | littleEndian /// Little endian byte order
69 | }
70 |
71 | /// The endianness that the program was compiled for.
72 | version(LittleEndian) Endian endian = Endian.littleEndian;
73 | else Endian endian = Endian.bigEndian;
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/rt/stdx/allocator/mallocator.d:
--------------------------------------------------------------------------------
1 | ///
2 | module stdx.allocator.mallocator;
3 | import stdx.allocator.common;
4 |
5 | /**
6 | The C heap allocator.
7 | */
8 | struct Mallocator
9 | {
10 | @system unittest { testAllocator!(() => Mallocator.instance); }
11 |
12 | /**
13 | The alignment is a static constant equal to $(D platformAlignment), which
14 | ensures proper alignment for any D data type.
15 | */
16 | enum uint alignment = platformAlignment;
17 |
18 | /**
19 | Standard allocator methods per the semantics defined above. The
20 | $(D deallocate) and $(D reallocate) methods are $(D @system) because they
21 | may move memory around, leaving dangling pointers in user code. Somewhat
22 | paradoxically, $(D malloc) is $(D @safe) but that's only useful to safe
23 | programs that can afford to leak memory allocated.
24 | */
25 | @trusted @nogc nothrow
26 | void[] allocate(size_t bytes) shared
27 | {
28 | import core.stdc.stdlib : malloc;
29 | if (!bytes) return null;
30 | auto p = malloc(bytes);
31 | return p ? p[0 .. bytes] : null;
32 | }
33 |
34 | /// Ditto
35 | @system @nogc nothrow
36 | bool deallocate(void[] b) shared
37 | {
38 | import core.stdc.stdlib : free;
39 | free(b.ptr);
40 | return true;
41 | }
42 |
43 | /// Ditto
44 | @system @nogc nothrow
45 | bool reallocate(ref void[] b, size_t s) shared
46 | {
47 | import core.stdc.stdlib : realloc;
48 | if (!s)
49 | {
50 | // fuzzy area in the C standard, see http://goo.gl/ZpWeSE
51 | // so just deallocate and nullify the pointer
52 | deallocate(b);
53 | b = null;
54 | return true;
55 | }
56 | auto p = cast(ubyte*) realloc(b.ptr, s);
57 | if (!p) return false;
58 | b = p[0 .. s];
59 | return true;
60 | }
61 |
62 | /**
63 | Returns the global instance of this allocator type. The C heap allocator is
64 | thread-safe, therefore all of its methods and `it` itself are
65 | $(D shared).
66 | */
67 | static shared Mallocator instance;
68 | }
69 |
70 | ///
71 | @nogc nothrow
72 | @system unittest
73 | {
74 | auto buffer = Mallocator.instance.allocate(1024 * 1024 * 4);
75 | scope(exit) Mallocator.instance.deallocate(buffer);
76 | //...
77 | }
78 |
79 | @nogc nothrow
80 | @system unittest
81 | {
82 | @nogc nothrow
83 | static void test(A)()
84 | {
85 | int* p = null;
86 | p = cast(int*) A.instance.allocate(int.sizeof);
87 | scope(exit) A.instance.deallocate(p[0 .. int.sizeof]);
88 | *p = 42;
89 | assert(*p == 42);
90 | }
91 | test!Mallocator();
92 | }
93 |
94 | @nogc nothrow
95 | @system unittest
96 | {
97 | static void test(A)()
98 | {
99 | import stdx.allocator : make;
100 | Object p = null;
101 | p = A.instance.make!Object();
102 | assert(p !is null);
103 | }
104 |
105 | test!Mallocator();
106 | }
107 |
108 | version (Posix)
109 | @nogc nothrow
110 | private extern(C) int posix_memalign(void**, size_t, size_t);
111 |
112 | version (Windows)
113 | {
114 | // DMD Win 32 bit, DigitalMars C standard library misses the _aligned_xxx
115 | // functions family (snn.lib)
116 | version(CRuntime_DigitalMars)
117 | {
118 | // Helper to cast the infos written before the aligned pointer
119 | // this header keeps track of the size (required to realloc) and of
120 | // the base ptr (required to free).
121 | private struct AlignInfo
122 | {
123 | void* basePtr;
124 | size_t size;
125 |
126 | @nogc nothrow
127 | static AlignInfo* opCall(void* ptr)
128 | {
129 | return cast(AlignInfo*) (ptr - AlignInfo.sizeof);
130 | }
131 | }
132 |
133 | @nogc nothrow
134 | private void* _aligned_malloc(size_t size, size_t alignment)
135 | {
136 | import std.c.stdlib : malloc;
137 | size_t offset = alignment + size_t.sizeof * 2 - 1;
138 |
139 | // unaligned chunk
140 | void* basePtr = malloc(size + offset);
141 | if (!basePtr) return null;
142 |
143 | // get aligned location within the chunk
144 | void* alignedPtr = cast(void**)((cast(size_t)(basePtr) + offset)
145 | & ~(alignment - 1));
146 |
147 | // write the header before the aligned pointer
148 | AlignInfo* head = AlignInfo(alignedPtr);
149 | head.basePtr = basePtr;
150 | head.size = size;
151 |
152 | return alignedPtr;
153 | }
154 |
155 | @nogc nothrow
156 | private void* _aligned_realloc(void* ptr, size_t size, size_t alignment)
157 | {
158 | import std.c.stdlib : free;
159 | import std.c.string : memcpy;
160 |
161 | if (!ptr) return _aligned_malloc(size, alignment);
162 |
163 | // gets the header from the exising pointer
164 | AlignInfo* head = AlignInfo(ptr);
165 |
166 | // gets a new aligned pointer
167 | void* alignedPtr = _aligned_malloc(size, alignment);
168 | if (!alignedPtr)
169 | {
170 | //to https://msdn.microsoft.com/en-us/library/ms235462.aspx
171 | //see Return value: in this case the original block is unchanged
172 | return null;
173 | }
174 |
175 | // copy exising data
176 | memcpy(alignedPtr, ptr, head.size);
177 | free(head.basePtr);
178 |
179 | return alignedPtr;
180 | }
181 |
182 | @nogc nothrow
183 | private void _aligned_free(void *ptr)
184 | {
185 | import std.c.stdlib : free;
186 | if (!ptr) return;
187 | AlignInfo* head = AlignInfo(ptr);
188 | free(head.basePtr);
189 | }
190 |
191 | }
192 | // DMD Win 64 bit, uses microsoft standard C library which implements them
193 | else
194 | {
195 | @nogc nothrow private extern(C) void* _aligned_malloc(size_t, size_t);
196 | @nogc nothrow private extern(C) void _aligned_free(void *memblock);
197 | @nogc nothrow private extern(C) void* _aligned_realloc(void *, size_t, size_t);
198 | }
199 | }
200 |
201 | /**
202 | Aligned allocator using OS-specific primitives, under a uniform API.
203 | */
204 | version (dscripten) {} else
205 | struct AlignedMallocator
206 | {
207 | @system unittest { testAllocator!(() => typeof(this).instance); }
208 |
209 | /**
210 | The default alignment is $(D platformAlignment).
211 | */
212 | enum uint alignment = platformAlignment;
213 |
214 | /**
215 | Forwards to $(D alignedAllocate(bytes, platformAlignment)).
216 | */
217 | @trusted @nogc nothrow
218 | void[] allocate(size_t bytes) shared
219 | {
220 | if (!bytes) return null;
221 | return alignedAllocate(bytes, alignment);
222 | }
223 |
224 | /**
225 | Uses $(HTTP man7.org/linux/man-pages/man3/posix_memalign.3.html,
226 | $(D posix_memalign)) on Posix and
227 | $(HTTP msdn.microsoft.com/en-us/library/8z34s9c6(v=vs.80).aspx,
228 | $(D __aligned_malloc)) on Windows.
229 | */
230 | version(Posix)
231 | @trusted @nogc nothrow
232 | void[] alignedAllocate(size_t bytes, uint a) shared
233 | {
234 | import core.stdc.errno : ENOMEM, EINVAL;
235 | assert(a.isGoodDynamicAlignment);
236 | void* result;
237 | auto code = posix_memalign(&result, a, bytes);
238 | if (code == ENOMEM)
239 | return null;
240 |
241 | else if (code == EINVAL)
242 | {
243 | assert(0, "AlignedMallocator.alignment is not a power of two "
244 | ~"multiple of (void*).sizeof, according to posix_memalign!");
245 | }
246 | else if (code != 0)
247 | assert(0, "posix_memalign returned an unknown code!");
248 |
249 | else
250 | return result[0 .. bytes];
251 | }
252 | else version(Windows)
253 | @trusted @nogc nothrow
254 | void[] alignedAllocate(size_t bytes, uint a) shared
255 | {
256 | auto result = _aligned_malloc(bytes, a);
257 | return result ? result[0 .. bytes] : null;
258 | }
259 | else static assert(0);
260 |
261 | /**
262 | Calls $(D free(b.ptr)) on Posix and
263 | $(HTTP msdn.microsoft.com/en-US/library/17b5h8td(v=vs.80).aspx,
264 | $(D __aligned_free(b.ptr))) on Windows.
265 | */
266 | version (Posix)
267 | @system @nogc nothrow
268 | bool deallocate(void[] b) shared
269 | {
270 | import core.stdc.stdlib : free;
271 | free(b.ptr);
272 | return true;
273 | }
274 | else version (Windows)
275 | @system @nogc nothrow
276 | bool deallocate(void[] b) shared
277 | {
278 | _aligned_free(b.ptr);
279 | return true;
280 | }
281 | else static assert(0);
282 |
283 | /**
284 | On Posix, forwards to $(D realloc). On Windows, forwards to
285 | $(D alignedReallocate(b, newSize, platformAlignment)).
286 | */
287 | version (Posix)
288 | @system @nogc nothrow
289 | bool reallocate(ref void[] b, size_t newSize) shared
290 | {
291 | return Mallocator.instance.reallocate(b, newSize);
292 | }
293 | version (Windows)
294 | @system @nogc nothrow
295 | bool reallocate(ref void[] b, size_t newSize) shared
296 | {
297 | return alignedReallocate(b, newSize, alignment);
298 | }
299 |
300 | /**
301 | On Posix, uses $(D alignedAllocate) and copies data around because there is
302 | no realloc for aligned memory. On Windows, calls
303 | $(HTTP msdn.microsoft.com/en-US/library/y69db7sx(v=vs.80).aspx,
304 | $(D __aligned_realloc(b.ptr, newSize, a))).
305 | */
306 | version (Windows)
307 | @system @nogc nothrow
308 | bool alignedReallocate(ref void[] b, size_t s, uint a) shared
309 | {
310 | if (!s)
311 | {
312 | deallocate(b);
313 | b = null;
314 | return true;
315 | }
316 | auto p = cast(ubyte*) _aligned_realloc(b.ptr, s, a);
317 | if (!p) return false;
318 | b = p[0 .. s];
319 | return true;
320 | }
321 |
322 | /**
323 | Returns the global instance of this allocator type. The C heap allocator is
324 | thread-safe, therefore all of its methods and `instance` itself are
325 | $(D shared).
326 | */
327 | static shared AlignedMallocator instance;
328 | }
329 |
330 | ///
331 | @nogc nothrow
332 | @system unittest
333 | {
334 | auto buffer = AlignedMallocator.instance.alignedAllocate(1024 * 1024 * 4,
335 | 128);
336 | scope(exit) AlignedMallocator.instance.deallocate(buffer);
337 | //...
338 | }
339 |
340 | version(unittest) version(CRuntime_DigitalMars)
341 | @nogc nothrow
342 | size_t addr(ref void* ptr) { return cast(size_t) ptr; }
343 |
344 | version(CRuntime_DigitalMars)
345 | @nogc nothrow
346 | @system unittest
347 | {
348 | void* m;
349 |
350 | m = _aligned_malloc(16, 0x10);
351 | if (m)
352 | {
353 | assert((m.addr & 0xF) == 0);
354 | _aligned_free(m);
355 | }
356 |
357 | m = _aligned_malloc(16, 0x100);
358 | if (m)
359 | {
360 | assert((m.addr & 0xFF) == 0);
361 | _aligned_free(m);
362 | }
363 |
364 | m = _aligned_malloc(16, 0x1000);
365 | if (m)
366 | {
367 | assert((m.addr & 0xFFF) == 0);
368 | _aligned_free(m);
369 | }
370 |
371 | m = _aligned_malloc(16, 0x10);
372 | if (m)
373 | {
374 | assert((cast(size_t) m & 0xF) == 0);
375 | m = _aligned_realloc(m, 32, 0x10000);
376 | if (m) assert((m.addr & 0xFFFF) == 0);
377 | _aligned_free(m);
378 | }
379 |
380 | m = _aligned_malloc(8, 0x10);
381 | if (m)
382 | {
383 | *cast(ulong*) m = 0X01234567_89ABCDEF;
384 | m = _aligned_realloc(m, 0x800, 0x1000);
385 | if (m) assert(*cast(ulong*) m == 0X01234567_89ABCDEF);
386 | _aligned_free(m);
387 | }
388 | }
389 |
--------------------------------------------------------------------------------
/test/.gitignore:
--------------------------------------------------------------------------------
1 | /t*/*.js
2 | /t*/*.wasm
3 | /t*/output.txt
4 |
--------------------------------------------------------------------------------
/test/run-tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -euo pipefail
3 | shopt -s lastpipe
4 |
5 | for dir in ./t????-*
6 | do
7 | (
8 | cd "$dir"
9 | ./run-test.sh
10 | )
11 | done
12 |
13 | printf 'All tests OK!\n' 1>&2
14 |
--------------------------------------------------------------------------------
/test/t0001-basic/output.exp:
--------------------------------------------------------------------------------
1 | Hello, world!
2 |
--------------------------------------------------------------------------------
/test/t0001-basic/run-test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | source ../test-lib.sh
3 | RunTest
4 |
--------------------------------------------------------------------------------
/test/t0001-basic/test.d:
--------------------------------------------------------------------------------
1 | import core.stdc.stdio;
2 |
3 | import dscripten.standard; // TODO: should be unnecessary
4 |
5 | extern(C)
6 | int main()
7 | {
8 | printf("Hello, world!\n");
9 | return 0;
10 | }
11 |
--------------------------------------------------------------------------------
/test/t0002-c/output.exp:
--------------------------------------------------------------------------------
1 | The result is 42!
2 |
--------------------------------------------------------------------------------
/test/t0002-c/run-test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | source ../test-lib.sh
3 | extra_args+=(--extra-file=test.c)
4 | RunTest
5 |
--------------------------------------------------------------------------------
/test/t0002-c/test.c:
--------------------------------------------------------------------------------
1 | int test_add(int a, int b)
2 | {
3 | return a + b;
4 | }
5 |
--------------------------------------------------------------------------------
/test/t0002-c/test.d:
--------------------------------------------------------------------------------
1 | import core.stdc.stdio;
2 |
3 | import dscripten.standard; // TODO: should be unnecessary
4 |
5 | extern(C) int test_add(int, int);
6 |
7 | extern(C)
8 | int main()
9 | {
10 | int ret = test_add(17, 25);
11 | printf("The result is %d!\n", ret);
12 | return 0;
13 | }
14 |
--------------------------------------------------------------------------------
/test/t0003-c-types/output.exp:
--------------------------------------------------------------------------------
1 | ok
2 | ok
3 | ok
4 | ok
5 |
--------------------------------------------------------------------------------
/test/t0003-c-types/run-test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | source ../test-lib.sh
3 | extra_args+=(--extra-file=test.c)
4 | RunTest
5 |
--------------------------------------------------------------------------------
/test/t0003-c-types/test.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int sizeOfInt() { return sizeof(int); }
4 | int sizeOfLong() { return sizeof(long); }
5 | int sizeOfSizet() { return sizeof(size_t); }
6 | int sizeOfWchar() { return sizeof(wchar_t); }
7 |
--------------------------------------------------------------------------------
/test/t0003-c-types/test.d:
--------------------------------------------------------------------------------
1 | import core.stdc.config;
2 | import core.stdc.stddef;
3 | import core.stdc.stdio;
4 |
5 | import dscripten.standard; // TODO: should be unnecessary
6 |
7 | extern(C) int sizeOfInt();
8 | extern(C) int sizeOfLong();
9 | extern(C) int sizeOfSizet();
10 | extern(C) int sizeOfWchar();
11 |
12 | extern(C)
13 | int main()
14 | {
15 | printf("%s\n", sizeOfInt() == int.sizeof ? "ok".ptr : "mismatch".ptr);
16 | printf("%s\n", sizeOfLong() == c_long.sizeof ? "ok".ptr : "mismatch".ptr);
17 | printf("%s\n", sizeOfSizet() == size_t.sizeof ? "ok".ptr : "mismatch".ptr);
18 | printf("%s\n", sizeOfWchar() == wchar_t.sizeof ? "ok".ptr : "mismatch".ptr);
19 | return 0;
20 | }
21 |
--------------------------------------------------------------------------------
/test/t0004-c-includes/output.exp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberShadow/dscripten-tools/e2ce05318810d0aac4a9bf291552b78dab92dbe3/test/t0004-c-includes/output.exp
--------------------------------------------------------------------------------
/test/t0004-c-includes/run-test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | source ../test-lib.sh
3 | extra_args+=(--extra-file=test.c)
4 | RunTest
5 |
--------------------------------------------------------------------------------
/test/t0004-c-includes/test.c:
--------------------------------------------------------------------------------
1 | // Ensure the include path is set up correctly.
2 |
3 | #include
4 |
--------------------------------------------------------------------------------
/test/t0004-c-includes/test.d:
--------------------------------------------------------------------------------
1 | import dscripten.standard; // TODO: should be unnecessary
2 |
3 | extern(C)
4 | int main()
5 | {
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/test/t0100-phobos/output.exp:
--------------------------------------------------------------------------------
1 | 1.414214
2 | 2 + 2 = 4
3 | On the heap!
4 |
--------------------------------------------------------------------------------
/test/t0100-phobos/run-test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | source ../test-lib.sh
3 | RunTest
4 |
--------------------------------------------------------------------------------
/test/t0100-phobos/test.d:
--------------------------------------------------------------------------------
1 | // Some limited Phobos tests
2 |
3 | import std.array;
4 | import std.format;
5 | import std.math;
6 |
7 | import core.stdc.stdio;
8 |
9 | import dscripten.standard; // TODO: should be unnecessary
10 | import dscripten.memory;
11 |
12 | void puts(in char[] s)
13 | {
14 | printf("%.*s\n", s.length, s.ptr);
15 | }
16 |
17 | extern(C)
18 | int main()
19 | {
20 | printf("%f\n", sqrt(2.0));
21 | gc_init();
22 | Appender!string app;
23 | formattedWrite(app, "%d + %d = %d", 2, 2, 4);
24 | puts(app.data);
25 | puts(format("On the %s!", "heap"));
26 | return 0;
27 | }
28 |
--------------------------------------------------------------------------------
/test/t0101-d-main/output.exp:
--------------------------------------------------------------------------------
1 | Hello, world!
2 |
--------------------------------------------------------------------------------
/test/t0101-d-main/run-test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | source ../test-lib.sh
3 | RunTest
4 |
--------------------------------------------------------------------------------
/test/t0101-d-main/test.d:
--------------------------------------------------------------------------------
1 | import dscripten.standard; // TODO: should be unnecessary
2 | import dscripten.memory;
3 | import rt.dmain2;
4 |
5 | import core.stdc.stdio;
6 |
7 | // This is a D (not extern(C)) main!
8 | void main()
9 | {
10 | printf("Hello, world!\n");
11 | }
12 |
--------------------------------------------------------------------------------
/test/t0102-writeln/output.exp:
--------------------------------------------------------------------------------
1 | Hello, world!
2 |
--------------------------------------------------------------------------------
/test/t0102-writeln/run-test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | source ../test-lib.sh
3 | RunTest
4 |
--------------------------------------------------------------------------------
/test/t0102-writeln/test.d:
--------------------------------------------------------------------------------
1 | import dscripten.standard; // TODO: should be unnecessary
2 |
3 | import std.stdio;
4 |
5 | extern(C)
6 | void main()
7 | {
8 | writeln("Hello, world!");
9 | }
10 |
--------------------------------------------------------------------------------
/test/t0200-wasm/output.exp:
--------------------------------------------------------------------------------
1 | Hello, world!
2 |
--------------------------------------------------------------------------------
/test/t0200-wasm/run-test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | source ../test-lib.sh
3 |
4 | if [[ -n ${TRAVIS+x} ]]
5 | then
6 | # Travis' GCC seems to crash / run out of resources while
7 | # attempting to build Binaryen.
8 | # https://travis-ci.org/CyberShadow/dscripten-tools/builds/377109592
9 | SkipTest
10 | fi
11 |
12 | extra_args+=(--wasm)
13 | RunTest
14 |
--------------------------------------------------------------------------------
/test/t0200-wasm/test.d:
--------------------------------------------------------------------------------
1 | import core.stdc.stdio;
2 |
3 | import dscripten.standard; // TODO: should be unnecessary
4 |
5 | extern(C)
6 | int main()
7 | {
8 | printf("Hello, world!\n");
9 | return 0;
10 | }
11 |
--------------------------------------------------------------------------------
/test/test-lib.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -euo pipefail
3 | shopt -s lastpipe
4 |
5 | printf '%s:\n' "$(basename "$PWD")" 1>&2
6 |
7 | extra_args=()
8 |
9 | function BuildTools() {
10 | (
11 | cd ../..
12 | for prog in {dmd,rdmd}-dscripten
13 | do
14 | rdmd --build-only -g $prog
15 | done
16 | )
17 | }
18 |
19 | function RunTest() {
20 | # Ensure tools are built
21 | BuildTools
22 |
23 | local args=(
24 | ../../rdmd-dscripten
25 | --compiler=../../dmd-dscripten
26 | --build-only
27 | )
28 |
29 | if [[ ${#extra_args[@]} -gt 0 ]]
30 | then
31 | args+=("${extra_args[@]}")
32 | fi
33 |
34 | "${args[@]}" test.d
35 |
36 | node test.js > output.txt
37 | diff -u output.exp output.txt
38 |
39 | printf ' >>> OK\n' 1>&2
40 | }
41 |
42 | function SkipTest() {
43 | printf ' >>> Skipped!\n' 1>&2
44 | exit 0
45 | }
46 |
--------------------------------------------------------------------------------