summaryrefslogtreecommitdiff
path: root/libphobos/libdruntime/core/internal/array/construction.d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2023-11-12 14:21:43 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2023-11-21 15:07:47 +0100
commit1250858ac9c1426da06116823bd3e1fca64c7d56 (patch)
treedc9a47116061b7711436b7e5851db51417b0ef44 /libphobos/libdruntime/core/internal/array/construction.d
parent8faae311a60a552ed3d506de28c50c77fa49b229 (diff)
d: Merge upstream dmd ff57fec515, druntime ff57fec515, phobos 17bafda79.
D front-end changes: - Import dmd v2.106.0-rc.1. - New'ing multi-dimensional arrays are now are converted to a single template call `_d_newarraymTX'. D runtime changes: - Import druntime v2.106.0-rc.1. Phobos changes: - Import phobos v2.106.0-rc.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd ff57fec515. * dmd/VERSION: Bump version to v2.106.0-rc.1. * expr.cc (ExprVisitor::visit (CatAssignExp *)): Update for new front-end interface. (ExprVisitor::visit (NewExp *)): Likewise. * runtime.def (NEWARRAYMTX): Remove. (NEWARRAYMITX): Remove. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime ff57fec515. * src/MERGE: Merge upstream phobos 17bafda79. gcc/testsuite/ChangeLog: * gdc.dg/asm1.d: Adjust expected diagnostic.
Diffstat (limited to 'libphobos/libdruntime/core/internal/array/construction.d')
-rw-r--r--libphobos/libdruntime/core/internal/array/construction.d108
1 files changed, 108 insertions, 0 deletions
diff --git a/libphobos/libdruntime/core/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d
index 54f8767139c..655acc8db57 100644
--- a/libphobos/libdruntime/core/internal/array/construction.d
+++ b/libphobos/libdruntime/core/internal/array/construction.d
@@ -486,3 +486,111 @@ version (D_ProfileGC)
assert(0, "Cannot create new array if compiling without support for runtime type information!");
}
}
+
+/**
+ * Create a new multi-dimensional array. Also initalize elements if their type has an initializer.
+ * Otherwise, not zero-initialize the array.
+ *
+ * ---
+ * void main()
+ * {
+ * S[][] s = new S[][](2, 3)
+ *
+ * // lowering:
+ * S[] s = _d_newarraymTX!(S[][], S)([2, 3]);
+ * }
+ * ---
+ *
+ * Params:
+ * dims = array length values for each dimension
+ * isShared = whether the array should be shared
+ *
+ * Returns:
+ * newly allocated array
+ */
+Tarr _d_newarraymTX(Tarr : U[], T, U)(size_t[] dims, bool isShared=false) @trusted
+{
+ debug(PRINTF) printf("_d_newarraymTX(dims.length = %d)\n", dims.length);
+
+ if (dims.length == 0)
+ return null;
+
+ alias UnqT = Unqual!(T);
+
+ void[] __allocateInnerArray(size_t[] dims)
+ {
+ import core.internal.array.utils : __arrayStart, __setArrayAllocLength, __arrayAlloc;
+
+ auto dim = dims[0];
+
+ debug(PRINTF) printf("__allocateInnerArray(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, dims.length);
+ if (dims.length == 1)
+ {
+ auto r = _d_newarrayT!UnqT(dim, isShared);
+ return *cast(void[]*)(&r);
+ }
+
+ auto allocSize = (void[]).sizeof * dim;
+ auto info = __arrayAlloc!UnqT(allocSize);
+ __setArrayAllocLength!UnqT(info, allocSize, isShared);
+ auto p = __arrayStart(info)[0 .. dim];
+
+ foreach (i; 0..dim)
+ {
+ (cast(void[]*)p.ptr)[i] = __allocateInnerArray(dims[1..$]);
+ }
+ return p;
+ }
+
+ auto result = __allocateInnerArray(dims);
+ debug(PRINTF) printf("result = %llx\n", result.ptr);
+
+ return (cast(U*) result.ptr)[0 .. dims[0]];
+}
+
+unittest
+{
+ int[][] a = _d_newarraymTX!(int[][], int)([2, 3]);
+
+ assert(a.length == 2);
+ for (size_t i = 0; i < a.length; i++)
+ {
+ assert(a[i].length == 3);
+ for (size_t j = 0; j < a[i].length; j++)
+ assert(a[i][j] == 0);
+ }
+}
+
+unittest
+{
+ struct S { int x = 1; }
+
+ S[][] a = _d_newarraymTX!(S[][], S)([2, 3]);
+
+ assert(a.length == 2);
+ for (size_t i = 0; i < a.length; i++)
+ {
+ assert(a[i].length == 3);
+ for (size_t j = 0; j < a[i].length; j++)
+ assert(a[i][j].x == 1);
+ }
+}
+
+version (D_ProfileGC)
+{
+ /**
+ * TraceGC wrapper around $(REF _d_newarraymT, core,internal,array,construction).
+ */
+ Tarr _d_newarraymTXTrace(Tarr : U[], T, U)(string file, int line, string funcname, size_t[] dims, bool isShared=false) @trusted
+ {
+ version (D_TypeInfo)
+ {
+ import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure;
+ mixin(TraceHook!(T.stringof, "_d_newarraymTX"));
+
+ return _d_newarraymTX!(Tarr, T)(dims, isShared);
+ }
+ else
+ assert(0, "Cannot create new multi-dimensional array if compiling without support for runtime type information!");
+ }
+}