Skip to content

Commit

Permalink
[c] Array.Fill with a non-default value.
Browse files Browse the repository at this point in the history
  • Loading branch information
pfusik committed Nov 26, 2021
1 parent 14a5684 commit 3828a2d
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 36 deletions.
55 changes: 38 additions & 17 deletions GenC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,25 @@ void WriteSizeofCompare(CiArrayType array)
this.Compares.Add(typeCode);
}

protected void WriteArrayFill(CiExpr obj, CiExpr[] args)
{
Write("for (size_t _i = 0; _i < ");
if (args.Length == 1)
Write(((CiArrayStorageType) obj.Type).Length);
else
args[2].Accept(this, CiPriority.Rel); // FIXME: side effect in every iteration
WriteLine("; _i++)");
Write('\t');
obj.Accept(this, CiPriority.Primary); // FIXME: side effect in every iteration
Write('[');
if (args.Length > 1 && !args[1].IsLiteralZero) {
args[1].Accept(this, CiPriority.Add); // FIXME: side effect in every iteration
Write(" + ");
}
Write("_i] = ");
args[0].Accept(this, CiPriority.Argument); // FIXME: side effect in every iteration
}

void WriteListAddInsert(CiExpr obj, bool insert, string function, CiExpr[] args)
{
// TODO: don't emit temporary variable if already a var/field of matching type - beware of integer promotions!
Expand Down Expand Up @@ -1403,25 +1422,27 @@ protected override void WriteCall(CiExpr obj, CiMethod method, CiExpr[] args, Ci
Write(')');
}
else if (obj.Type is CiArrayType array3 && method.Name == "Fill") {
if (!(args[0] is CiLiteral literal) || !literal.IsDefaultValue)
throw new NotImplementedException("Only null, zero and false supported");
Include("string.h");
Write("memset(");
if (args.Length == 1) {
obj.Accept(this, CiPriority.Argument);
Write(", 0, sizeof(");
obj.Accept(this, CiPriority.Argument);
Write(')');
}
else {
WriteArrayPtrAdd(obj, args[1]);
Write(", 0, ");
args[2].Accept(this, CiPriority.Mul);
Write(" * sizeof(");
Write(array3.ElementType, false);
if (args[0] is CiLiteral literal && literal.IsDefaultValue) {
Include("string.h");
Write("memset(");
if (args.Length == 1) {
obj.Accept(this, CiPriority.Argument);
Write(", 0, sizeof(");
obj.Accept(this, CiPriority.Argument);
Write(')');
}
else {
WriteArrayPtrAdd(obj, args[1]);
Write(", 0, ");
args[2].Accept(this, CiPriority.Mul);
Write(" * sizeof(");
Write(array3.ElementType, false);
Write(')');
}
Write(')');
}
Write(')');
else
WriteArrayFill(obj, args);
}
else if (method == CiSystem.CollectionSortAll) {
TypeCode typeCode = GetTypeCode(((CiArrayType) obj.Type).ElementType, false);
Expand Down
19 changes: 2 additions & 17 deletions GenCl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,23 +187,8 @@ protected override void WriteCall(CiExpr obj, CiMethod method, CiExpr[] args, Ci
}
Write("_i]");
}
else if (obj.Type is CiArrayType && method.Name == "Fill") {
Write("for (size_t _i = 0; _i < ");
if (args.Length == 1)
Write(((CiArrayStorageType) obj.Type).Length);
else
args[2].Accept(this, CiPriority.Rel); // FIXME: side effect in every iteration
WriteLine("; _i++)");
Write('\t');
obj.Accept(this, CiPriority.Primary); // FIXME: side effect in every iteration
Write('[');
if (args.Length > 1 && !args[1].IsLiteralZero) {
args[1].Accept(this, CiPriority.Add); // FIXME: side effect in every iteration
Write(" + ");
}
Write("_i] = ");
args[0].Accept(this, CiPriority.Argument); // FIXME: side effect in every iteration
}
else if (obj.Type is CiArrayType && method.Name == "Fill")
WriteArrayFill(obj, args);
else if (method == CiSystem.UTF8GetByteCount)
WriteStringLength(args[0]);
else if (method == CiSystem.UTF8GetBytes) {
Expand Down
4 changes: 2 additions & 2 deletions test/ArrayFill.ci
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ public static class Test
d[i] = a[i] = (i + 1) * 5;
a.Fill(0, 1, 2);
int[]! p = a;
p.Fill(0, 4, 2);
p.Fill(10, 4, 2); //FAIL: cs - .NET Core but not .NET Framework 4.8
d.Fill(0, 2, 3);
return a[0] == 5 && a[1] == 0 && a[2] == 0 && a[3] == 20
&& a[4] == 0 && a[5] == 0 && a[6] == 35
&& a[4] == 10 && a[5] == 10 && a[6] == 35
&& d[0] == 5 && d[1] == 10 && d[2] == 0 && d[3] == 0 && d[4] == 0 && d[5] == 30 && d[6] == 35;
}
}

0 comments on commit 3828a2d

Please sign in to comment.