Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace call to runtime hook _d_arraycast with call to template object.__ArrayCast - Take 2 #9516

Merged
merged 1 commit into from
Mar 31, 2019
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
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 @@ -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;
}

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