Skip to content
This repository was archived by the owner on Aug 24, 2022. It is now read-only.

Commit c9bf285

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 2b3d60d + 88331ac commit c9bf285

21 files changed

+739
-128
lines changed

Build/Projects/JSIL.Tests.definition

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@
9393
<None Include="AnalysisTestCases\Issue696.cs" />
9494
<None Include="EmscriptenTestCases\EnumRoundTrip.cs" />
9595
<None Include="AnalysisTestCases\FNABaseOffset.cs" />
96+
<None Include="EmscriptenTestCases\OutUnionParameter.cs" />
97+
<None Include="EmscriptenTestCases\OutComplexUnionParameter.cs" />
9698
<Compile Include="EmscriptenTestCases\ProxiedExternFunction.cs" />
9799
<None Include="EmscriptenTestCases\IntPtrZeroEquality.cs" />
98100
<None Include="EmscriptenTestCases\StringArrayParameter.cs" />
@@ -383,6 +385,10 @@
383385
<None Include="UnsafeTestCases\IgnorePointerFields.cs" />
384386
<None Include="UnsafeTestCases\PointerWriteConversion_Issue686.cs" />
385387
<None Include="UnsafeTestCases\ModifyPackedStructArrayElementStructField.cs" />
388+
<None Include="UnsafeTestCases\CustomPacking.cs" />
389+
<None Include="UnsafeTestCases\CustomFieldOffset.cs" />
390+
<None Include="UnsafeTestCases\CustomFieldOffsetUnion.cs" />
391+
<None Include="UnsafeTestCases\UnionContainingEnum.cs" />
386392
<Compile Include="XMLTests.cs" />
387393
<Compile Include="DependencyTests.cs" />
388394
<None Include="TestCases\GenericParameterNameShadowing.cs" />

JSIL/AST/JSExpressionTypes.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1608,12 +1608,14 @@ public class JSMemberDescriptor : JSExpression {
16081608
public readonly bool IsStatic;
16091609
public readonly bool IsVirtual;
16101610
public readonly bool IsReadonly;
1611+
public readonly int? Offset;
16111612

1612-
public JSMemberDescriptor (bool isPublic, bool isStatic, bool isVirtual = false, bool isReadonly = false) {
1613+
public JSMemberDescriptor (bool isPublic, bool isStatic, bool isVirtual = false, bool isReadonly = false, int? offset = null) {
16131614
IsPublic = isPublic;
16141615
IsStatic = isStatic;
16151616
IsVirtual = isVirtual;
16161617
IsReadonly = isReadonly;
1618+
Offset = offset;
16171619
}
16181620

16191621
public override bool IsConstant {

JSIL/AssemblyTranslator.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,32 @@ protected void DeclareType (
14801480
output.NewLine();
14811481
}
14821482

1483+
if (typedef.IsExplicitLayout) {
1484+
output.WriteRaw("ExplicitLayout: true");
1485+
output.Comma();
1486+
output.NewLine();
1487+
} else if (typedef.IsSequentialLayout) {
1488+
output.WriteRaw("SequentialLayout: true");
1489+
output.Comma();
1490+
output.NewLine();
1491+
}
1492+
1493+
if (typedef.HasLayoutInfo) {
1494+
if (typedef.PackingSize != 0) {
1495+
output.WriteRaw("Pack: ");
1496+
output.Value(typedef.PackingSize);
1497+
output.Comma();
1498+
output.NewLine();
1499+
}
1500+
1501+
if (typedef.ClassSize != 0) {
1502+
output.WriteRaw("SizeBytes: ");
1503+
output.Value(typedef.ClassSize);
1504+
output.Comma();
1505+
output.NewLine();
1506+
}
1507+
}
1508+
14831509
output.CloseBrace(false);
14841510
}
14851511

@@ -2119,7 +2145,11 @@ protected JSExpression TranslateField (
21192145

21202146
var dollarIdentifier = new JSRawOutputIdentifier(field.DeclaringType, dollar.Format, dollar.Arguments);
21212147
var descriptor = new JSMemberDescriptor(
2122-
field.IsPublic, field.IsStatic, isReadonly: field.IsInitOnly
2148+
field.IsPublic, field.IsStatic,
2149+
isReadonly: field.IsInitOnly,
2150+
offset: field.DeclaringType.IsExplicitLayout
2151+
? (int?)field.Offset
2152+
: null
21232153
);
21242154

21252155
var fieldName = Util.EscapeIdentifier(fieldInfo.Name, EscapingMode.MemberIdentifier);

JSIL/ILBlockTranslator.cs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,28 +1129,42 @@ public JSExpression TranslateNode (ILExpression expression) {
11291129
(expression.InferredType != null) &&
11301130
!TypeUtil.TypesAreAssignable(TypeInfo, expression.ExpectedType, expression.InferredType)
11311131
) {
1132+
var expectedType = expression.ExpectedType;
1133+
11321134
// HACK: Expected types inside of comparison expressions are wrong, so we need to suppress
11331135
// the casts they would normally generate sometimes.
11341136
bool shouldAutoCast = (
11351137
AutoCastingState.Peek() ||
11361138
(
11371139
// Comparisons between value types still need a cast.
1138-
!TypeUtil.IsReferenceType(expression.ExpectedType) ||
1140+
!TypeUtil.IsReferenceType(expectedType) ||
11391141
!TypeUtil.IsReferenceType(expression.InferredType)
11401142
)
11411143
);
11421144

1145+
// HACK: ILSpy improperly decompiles sequences like:
1146+
// byte * px = ...;
1147+
// *((A*)px) = new A()
1148+
// into a cast of the form ((A&)px) = new A()
1149+
if (
1150+
(expectedType is ByReferenceType) &&
1151+
(expression.InferredType is PointerType) &&
1152+
!TypeUtil.TypesAreEqual(expectedType.GetElementType(), expression.InferredType.GetElementType())
1153+
) {
1154+
expectedType = new PointerType(expectedType.GetElementType());
1155+
}
1156+
11431157
bool specialNullableCast = (
1144-
TypeUtil.IsNullable(expression.ExpectedType) ||
1158+
TypeUtil.IsNullable(expectedType) ||
11451159
TypeUtil.IsNullable(expression.InferredType) ||
11461160
(expression.Code == ILCode.ValueOf)
11471161
);
11481162

11491163
if (shouldAutoCast) {
11501164
if (specialNullableCast)
1151-
return new JSNullableCastExpression(result, new JSType(expression.ExpectedType));
1165+
return new JSNullableCastExpression(result, new JSType(expectedType));
11521166
else
1153-
return JSCastExpression.New(result, expression.ExpectedType, TypeSystem, isCoercion: true);
1167+
return JSCastExpression.New(result, expectedType, TypeSystem, isCoercion: true);
11541168
} else {
11551169
// FIXME: Should this be JSChangeTypeExpression to preserve type information?
11561170
// I think not, because a lot of these ExpectedTypes are wrong.

JSIL/JavascriptAstEmitter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2062,7 +2062,7 @@ public void VisitNode (JSArrayExpression array) {
20622062
}
20632063

20642064
public void VisitNode (JSMemberDescriptor desc) {
2065-
Output.MemberDescriptor(desc.IsPublic, desc.IsStatic, desc.IsVirtual, desc.IsReadonly);
2065+
Output.MemberDescriptor(desc.IsPublic, desc.IsStatic, desc.IsVirtual, desc.IsReadonly, desc.Offset);
20662066
}
20672067

20682068
public void VisitNode (JSObjectExpression obj) {

JSIL/JavascriptFormatter.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,11 @@ public void TypeReference (TypeInfo type, TypeReferenceContext context) {
743743
TypeReference(type.Definition, context);
744744
}
745745

746-
public void MemberDescriptor (bool isPublic, bool isStatic, bool isVirtual = false, bool isReadonly = false) {
746+
public void MemberDescriptor (
747+
bool isPublic, bool isStatic,
748+
bool isVirtual = false, bool isReadonly = false,
749+
int? offset = null
750+
) {
747751
WriteRaw("{");
748752

749753
WriteRaw("Static");
@@ -776,6 +780,13 @@ public void MemberDescriptor (bool isPublic, bool isStatic, bool isVirtual = fal
776780
WriteRaw("true ");
777781
}
778782

783+
if (offset.HasValue) {
784+
Comma();
785+
786+
WriteRaw("Offset: ");
787+
Value(offset.Value);
788+
}
789+
779790
WriteRaw("}");
780791
}
781792

Libraries/JSIL.Bootstrap.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4537,7 +4537,7 @@ $jsilcore.GetSerializationScratchBuffers = function () {
45374537

45384538
var result = new Uint8Array(byteCount);
45394539
for (var i = 0; i < byteCount; i++)
4540-
result[i] = this.uint8[i];
4540+
result[i] = uint8[i];
45414541

45424542
return result;
45434543
},
@@ -4549,7 +4549,7 @@ $jsilcore.GetSerializationScratchBuffers = function () {
45494549
JSIL.RuntimeError("bytes cannot be null");
45504550

45514551
for (var i = 0; i < count; i++)
4552-
this.uint8[i] = bytes[offset + i];
4552+
uint8[i] = bytes[offset + i];
45534553
}
45544554
};
45554555
}

0 commit comments

Comments
 (0)