Skip to content

Commit

Permalink
Merge pull request #9516 from JinShil/lower_array_cast_take2
Browse files Browse the repository at this point in the history
Replace call to runtime hook  _d_arraycast with call to template object.__ArrayCast - Take 2
merged-on-behalf-of: Nicholas Wilson <[email protected]>
  • Loading branch information
dlang-bot authored Mar 31, 2019
2 parents bfc4d8b + 7cf78c8 commit d76781e
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
7 changes: 2 additions & 5 deletions src/dmd/e2ir.d
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
39 changes: 39 additions & 0 deletions src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -6724,6 +6724,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;
}

Expand Down
1 change: 1 addition & 0 deletions src/dmd/id.d
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ immutable Msgtable[] msgtable =
{ "__equals"},
{ "__switch"},
{ "__switch_error"},
{ "__ArrayCast"},

// varargs implementation
{ "va_start" },
Expand Down

0 comments on commit d76781e

Please sign in to comment.