Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Greene <hippiehunterenator@gmail.com>2017-11-06 11:23:49 +0300
committerMorgan Brown <morganbr@users.noreply.github.com>2017-11-06 11:23:49 +0300
commit9a819d14db26b678e8fd9338084abd1665b18148 (patch)
tree34f3291b1c44adc621ca894059d0f03265074b00 /src/ILCompiler.WebAssembly
parentff7decc2fdfc22c32c627734c2ff4eda2696911b (diff)
added support for box/unbox/unbox_any for WASM using malloc (#4731)
Diffstat (limited to 'src/ILCompiler.WebAssembly')
-rw-r--r--src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs57
1 files changed, 55 insertions, 2 deletions
diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs
index ebe4a44bf..745dd0d20 100644
--- a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs
+++ b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs
@@ -804,6 +804,11 @@ namespace Internal.IL
{
MetadataType metadataType = (MetadataType)type;
int objectSize = metadataType.InstanceByteCount.AsInt;
+ if (metadataType.IsValueType)
+ {
+ objectSize += type.Context.Target.PointerSize;
+ }
+
LLVMValueRef allocatedMemory = LLVM.BuildMalloc(_builder, LLVM.ArrayType(LLVM.Int8Type(), (uint)objectSize), "newobj");
LLVMValueRef castMemory = LLVM.BuildPointerCast(_builder, allocatedMemory, LLVM.PointerType(LLVM.Int8Type(), 0), "castnewobj");
ImportCallMemset(castMemory, 0, objectSize);
@@ -1428,6 +1433,37 @@ namespace Internal.IL
private void ImportUnbox(int token, ILOpcode opCode)
{
+ TypeDesc type = ResolveTypeToken(token);
+ if (type.IsNullable)
+ throw new NotImplementedException();
+
+ if (opCode == ILOpcode.unbox)
+ {
+ var unboxResult = _stack.Pop().ValueAsType(LLVM.PointerType(LLVM.Int8Type(), 0), _builder);
+ LLVMValueRef unboxData = LLVM.BuildGEP(_builder, unboxResult, new LLVMValueRef[] { BuildConstInt32(type.Context.Target.PointerSize) }, "unboxData");
+ //push the pointer to the data, but it shouldnt be implicitly dereferenced
+ PushExpression(GetStackValueKind(type), "unboxed", unboxData, type);
+ }
+ else //unbox_any
+ {
+ Debug.Assert(opCode == ILOpcode.unbox_any);
+
+ //TODO: when the runtime is ready switch this to calling the real RhUnboxAny
+ //LLVMValueRef eeType = GetEETypeForTypeDesc(type);
+ //var eeTypeDesc = _compilation.TypeSystemContext.SystemModule.GetKnownType("System", "EETypePtr");
+ //LLVMValueRef untypedObjectValue = LLVM.BuildAlloca(_builder, GetLLVMTypeForTypeDesc(type), "objptr");
+ //PushExpression(StackValueKind.ByRef, "objPtr", untypedObjectValue, type.MakePointerType());
+ //PushExpression(StackValueKind.ByRef, "eeType", eeType, eeTypeDesc);
+ //CallRuntimeExport(_compilation.TypeSystemContext, "RhUnboxAny");
+ //PushLoadExpression(GetStackValueKind(type), "unboxed", untypedObjectValue, type);
+ //this can be removed once we can call RhUnboxAny
+ if (!type.IsValueType)
+ throw new NotImplementedException();
+
+ var unboxResult = _stack.Pop().ValueAsType(LLVM.PointerType(LLVM.Int8Type(), 0), _builder);
+ LLVMValueRef unboxData = LLVM.BuildGEP(_builder, unboxResult, new LLVMValueRef[] { BuildConstInt32(type.Context.Target.PointerSize) }, "unboxData");
+ PushLoadExpression(GetStackValueKind(type), "unboxed", unboxData, type);
+ }
}
private void ImportRefAnyVal(int token)
@@ -1542,7 +1578,6 @@ namespace Internal.IL
var objectType = objectEntry.Type ?? field.OwningType;
LLVMValueRef untypedObjectValue;
LLVMTypeRef llvmObjectType = GetLLVMTypeForTypeDesc(objectType);
-
if (objectType.IsValueType && !objectType.IsPointer && objectEntry.Kind != StackValueKind.NativeInt && objectEntry.Kind != StackValueKind.ByRef)
{
if (objectEntry is LoadExpressionEntry)
@@ -1560,7 +1595,6 @@ namespace Internal.IL
{
untypedObjectValue = objectEntry.ValueAsType(LLVM.PointerType(LLVMTypeRef.Int8Type(), 0), _builder);
}
-
if (field.Offset.AsInt == 0)
{
return untypedObjectValue;
@@ -1649,7 +1683,19 @@ namespace Internal.IL
private void ImportBox(int token)
{
+ TypeDesc type = ResolveTypeToken(token);
+ if (type.IsValueType)
+ {
+ if (type.IsNullable)
+ throw new NotImplementedException();
+ var value = _stack.Pop();
+ ExpressionEntry boxTarget = AllocateObject(type);
+ LLVMValueRef boxData = LLVM.BuildGEP(_builder, boxTarget.RawLLVMValue, new LLVMValueRef[] { BuildConstInt32(type.Context.Target.PointerSize) }, "boxData");
+ LLVMValueRef typedBoxData = LLVM.BuildPointerCast(_builder, boxData, LLVM.PointerType(GetLLVMTypeForTypeDesc(type), 0), "typedBoxData");
+ LLVM.BuildStore(_builder, value.ValueAsType(type, _builder), typedBoxData);
+ _stack.Push(boxTarget);
+ }
}
private void ImportLeave(BasicBlock target)
@@ -1762,6 +1808,13 @@ namespace Internal.IL
}
+ private void CallRuntimeExport(TypeSystemContext context, string methodName)
+ {
+ MetadataType helperType = context.SystemModule.GetKnownType("System.Runtime", "RuntimeExports");
+ MethodDesc helperMethod = helperType.GetKnownMethod(methodName, null);
+ HandleCall(helperMethod);
+ }
+
private StackEntry NewSpillSlot(StackEntry entry)
{
if (entry is SpilledExpressionEntry)