Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
/ druntime Public archive
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mak/COPY
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ COPY=\
$(IMPDIR)\rt\array\equality.d \
$(IMPDIR)\rt\array\casting.d \
$(IMPDIR)\rt\array\capacity.d \
$(IMPDIR)\rt\array\concatenation.d \
\
$(IMPDIR)\rt\util\array.d \
\
Expand Down
1 change: 1 addition & 0 deletions mak/DOCS
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ DOCS=\
$(DOCDIR)\rt_array_comparison.html \
$(DOCDIR)\rt_array_construction.html \
$(DOCDIR)\rt_array_equality.html \
$(DOCDIR)\rt_array_concatenation.html \
\
$(DOCDIR)\rt_arrayassign.html \
$(DOCDIR)\rt_arraycat.html \
Expand Down
1 change: 1 addition & 0 deletions mak/SRCS
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ SRCS=\
src\rt\array\equality.d \
src\rt\array\casting.d \
src\rt\array\capacity.d \
src\rt\array\concatenation.d \
\
src\rt\backtrace\dwarf.d \
src\rt\backtrace\elf.d \
Expand Down
3 changes: 3 additions & 0 deletions mak/WINDOWS
Original file line number Diff line number Diff line change
Expand Up @@ -1202,5 +1202,8 @@ $(IMPDIR)\rt\array\casting.d : src\rt\array\casting.d
$(IMPDIR)\rt\array\capacity.d : src\rt\array\capacity.d
copy $** $@

$(IMPDIR)\rt\array\concatenation.d : src\rt\array\concatenation.d
copy $** $@

$(IMPDIR)\rt\util\array.d : src\rt\util\array.d
copy $** $@
2 changes: 2 additions & 0 deletions src/object.d
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public import rt.array.equality : __equals;
public import rt.array.equality : __ArrayEq;
/// See $(REF __ArrayCast, rt,array,casting)
public import rt.array.casting: __ArrayCast;
/// See $(REF _d_arraycatnTXImpl, rt,array,concatenation)
public import rt.array.concatenation : _d_arraycatnTXImpl;
/// See $(REF _d_arrayctor, rt,array,construction)
public import rt.array.construction : _d_arrayctor;
/// See $(REF _d_arraysetctor, rt,array,construction)
Expand Down
117 changes: 117 additions & 0 deletions src/rt/array/concatenation.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
This module contains support for controlling dynamic arrays' concatenation
Copyright: Copyright Digital Mars 2000 - 2019.
License: Distributed under the
$(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
(See accompanying file LICENSE)
Source: $(DRUNTIMESRC rt/_array/_concatenation.d)
*/
module rt.array.concatenation;

/// See $(REF _d_arraycatnTX, rt,lifetime)
private extern (C) void[] _d_arraycatnTX(const TypeInfo ti, byte[][] arrs) pure nothrow;

// This wrapper is needed because a externDFunc cannot be cast()ed directly.
private void accumulate(string file, uint line, string funcname, string type, ulong sz) @nogc
{
import core.internal.traits : externDFunc;

alias func = externDFunc!("rt.profilegc.accumulate", void function(string file, uint line, string funcname, string type, ulong sz) @nogc);
return func(file, line, funcname, type, sz);
}

/// Implementation of `_d_arraycatnTX` and `_d_arraycatnTXTrace`
template _d_arraycatnTXImpl(Tarr : ResultArrT[], ResultArrT : T[], T)
{
/**
* Concatenating the arrays inside of `arrs`.
* `_d_arraycatnTX([a, b, c])` means `a ~ b ~ c`.
* Params:
* arrs = Array containing arrays that will be concatenated.
* Returns:
* A newly allocated array that contains all the elements from all the arrays in `arrs`.
* Bugs:
* This function template was ported from a much older runtime hook that bypassed safety,
* purity, and throwabilty checks. To prevent breaking existing code, this function template
* is temporarily declared `@trusted pure nothrow` until the implementation can be brought up to modern D expectations.
*/
ResultArrT _d_arraycatnTX(scope const Tarr arrs) @trusted pure nothrow
{
pragma(inline, false);
version (D_TypeInfo)
{
auto ti = typeid(ResultArrT);

byte[][] arrs2 = (cast(byte[]*)arrs.ptr)[0 .. arrs.length];
void[] result = ._d_arraycatnTX(ti, arrs2);
return (cast(T*)result.ptr)[0 .. result.length];
}
else
assert(0, "Cannot concatenate arrays if compiling without support for runtime type information!");
}

/**
* TraceGC wrapper around $(REF _d_arraycatnTX, rt,array,concat).
* Bugs:
* This function template was ported from a much older runtime hook that bypassed safety,
* purity, and throwabilty checks. To prevent breaking existing code, this function template
* is temporarily declared `@trusted pure nothrow` until the implementation can be brought up to modern D expectations.
*/
ResultArrT _d_arraycatnTXTrace(string file, int line, string funcname, scope const Tarr arrs) @trusted pure nothrow
{
pragma(inline, false);
version (D_TypeInfo)
{
import core.memory : GC;
auto accumulate = cast(void function(string file, uint line, string funcname, string type, ulong sz) @nogc nothrow pure)&accumulate;
auto gcStats = cast(GC.Stats function() nothrow pure)&GC.stats;

string name = ResultArrT.stringof;

// FIXME: use rt.tracegc.accumulator when it is accessable in the future.
version (tracegc)
{
import core.stdc.stdio;

printf("%s file = '%.*s' line = %d function = '%.*s' type = %.*s\n",
__FUNCTION__.ptr,
file.length, file.ptr,
line,
funcname.length, funcname.ptr,
name.length, name.ptr
);
}

ulong currentlyAllocated = gcStats().allocatedInCurrentThread;

scope(exit)
{
ulong size = gcStats().allocatedInCurrentThread - currentlyAllocated;
if (size > 0)
accumulate(file, line, funcname, name, size);
}
return _d_arraycatnTX(arrs);
}
else
assert(0, "Cannot concatenate arrays if compiling without support for runtime type information!");
}
}

@safe unittest
{
int counter;
struct S
{
int val;
this(this)
{
counter++;
}
}

S[][] arr = [[S(0), S(1), S(2), S(3)], [S(4), S(5), S(6), S(7)]];
S[] result = _d_arraycatnTXImpl!(typeof(arr))._d_arraycatnTX(arr);

assert(counter == 8);
assert(result == [S(0), S(1), S(2), S(3), S(4), S(5), S(6), S(7)]);
}