From 0ce7bbd84a97c6587f170bca00fd6abf80402663 Mon Sep 17 00:00:00 2001 From: hippiehunter Date: Fri, 2 Feb 2018 20:57:50 -0800 Subject: [PATCH] Fixed ldind failure and properly zext unsigned types that are smaller than 32bit --- .../src/CodeGen/ILToWebAssemblyImporter.cs | 6 +++- tests/src/Simple/HelloWasm/Program.cs | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs index c3174407633..4623fa0e4c5 100644 --- a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs +++ b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs @@ -392,6 +392,10 @@ private static LLVMValueRef CastIntValue(LLVMBuilderRef builder, LLVMValueRef va { return LLVM.BuildSExtOrBitCast(builder, value, type, "SExtOrBitCast"); } + else if (type.GetIntTypeWidth() > LLVM.TypeOf(value).GetIntTypeWidth()) + { + return LLVM.BuildZExtOrBitCast(builder, value, type, "ZExtOrBitCast"); + } else { Debug.Assert(typeKind == LLVMTypeKind.LLVMIntegerTypeKind); @@ -1547,7 +1551,7 @@ private void ImportLoadIndirect(TypeDesc type) LLVMValueRef pointerElementType = pointer.ValueAsType(type.MakePointerType(), _builder); _stack.Push(new LoadExpressionEntry(type != null ? GetStackValueKind(type) : StackValueKind.ByRef, "ldind", - pointerElementType, type.MakePointerType())); + pointerElementType, type)); } private void ImportStoreIndirect(int token) diff --git a/tests/src/Simple/HelloWasm/Program.cs b/tests/src/Simple/HelloWasm/Program.cs index 66080a425f1..51735379261 100644 --- a/tests/src/Simple/HelloWasm/Program.cs +++ b/tests/src/Simple/HelloWasm/Program.cs @@ -181,6 +181,8 @@ private static unsafe void Main(string[] args) IntToStringTest(); + ldindTest(); + PrintLine("Done"); } @@ -280,6 +282,35 @@ private static void IntToStringTest() PrintLine(intString); } + private unsafe static void ldindTest() + { + var ldindTarget = new TwoByteStr { first = byte.MaxValue, second = byte.MinValue }; + var ldindField = &ldindTarget.first; + if((*ldindField) == byte.MaxValue) + { + ldindTarget.second = byte.MaxValue; + *ldindField = byte.MinValue; + //ensure there isnt any overwrite of nearby fields + if(ldindTarget.first == byte.MinValue && ldindTarget.second == byte.MaxValue) + { + PrintLine("ldind test: Ok."); + } + else if(ldindTarget.first != byte.MinValue) + { + PrintLine("ldind test: Failed didnt update target."); + } + else + { + PrintLine("ldind test: Failed overwrote data"); + } + } + else + { + uint ldindFieldValue = *ldindField; + PrintLine("ldind test: Failed." + ldindFieldValue.ToString()); + } + } + [DllImport("*")] private static unsafe extern int printf(byte* str, byte* unused); }