From 7cf78c8b3d5c253e0c6021c4d05360fc1d38f56e Mon Sep 17 00:00:00 2001 From: JinShil Date: Sat, 30 Mar 2019 14:47:39 +0900 Subject: [PATCH] Replace call to runtime hook _d_arraycast with call to template object.__ArrayCast - Take 2 --- src/dmd/e2ir.d | 7 ++----- src/dmd/expressionsem.d | 39 +++++++++++++++++++++++++++++++++++++++ src/dmd/id.d | 1 + 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/dmd/e2ir.d b/src/dmd/e2ir.d index 3ec819db196d..40e177a406e5 100644 --- a/src/dmd/e2ir.d +++ b/src/dmd/e2ir.d @@ -4187,11 +4187,8 @@ elem *toElem(Expression e, IRState *irs) e = el_pair(totym(ce.type), elen2, eptr); } else - { // Runtime check needed in case arrays don't line up - if (config.exe == EX_WIN64) - e = addressElem(e, t, true); - elem *ep = el_params(e, el_long(TYsize_t, fsize), el_long(TYsize_t, tsize), null); - e = el_bin(OPcall, totym(ce.type), el_var(getRtlsym(RTLSYM_ARRAYCAST)), ep); + { + assert(false, "This case should have been rewritten to `__ArrayCast` in the semantic phase"); } } goto Lret; diff --git a/src/dmd/expressionsem.d b/src/dmd/expressionsem.d index a7049bbfe250..bb0acb798dde 100644 --- a/src/dmd/expressionsem.d +++ b/src/dmd/expressionsem.d @@ -6715,6 +6715,45 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setError(); } + // `object.__ArrayCast` is a rewrite of an old runtime hook `_d_arraycast`. `_d_arraycast` was not built + // to handle certain casts. Those casts which `object.__ArrayCast` does not support are filtered out. + // See `e2ir.toElemCast` for other types of casts. If `object.__ArrayCast` is improved to support more + // casts these conditions and potentially some logic in `e2ir.toElemCast` can be removed. + if (tob.ty == Tarray && t1b.ty == Tarray && exp.e1.op != TOK.string_ && exp.e1.op != TOK.arrayLiteral) + { + auto tFrom = t1b.nextOf(); + auto tTo = tob.nextOf(); + + const uint fromSize = cast(uint)tFrom.size(); + const uint toSize = cast(uint)tTo.size(); + + // If array element sizes do not match, we must adjust the dimensions + if (fromSize != toSize) + { + // A runtime check is needed in case arrays don't line up. That check should + // be done in the implementation of `object.__ArrayCast` + if ((fromSize % toSize) != 0) + { + // lower to `object.__ArrayCast!(TFrom, TTo)(from)` + + auto id = Id.__ArrayCast; + + auto tiargs = new Objects(); + tiargs.push(tFrom); + tiargs.push(tTo); + auto ti = new TemplateInstance(exp.loc, id, tiargs); + Expression __ArrayCast = new ScopeExp(exp.loc, ti); + + auto arguments = new Expressions(); + arguments.push(exp.e1); + __ArrayCast = new CallExp(exp.loc, __ArrayCast, arguments); + + result = expressionSemantic(__ArrayCast, sc); + return; + } + } + } + result = ex; } diff --git a/src/dmd/id.d b/src/dmd/id.d index db5f11f44f6c..10ef44c83530 100644 --- a/src/dmd/id.d +++ b/src/dmd/id.d @@ -342,6 +342,7 @@ immutable Msgtable[] msgtable = { "__equals"}, { "__switch"}, { "__switch_error"}, + { "__ArrayCast"}, // varargs implementation { "va_start" },