summaryrefslogtreecommitdiff
path: root/src/ToolBox/superpmi/superpmi-shared/typeutils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ToolBox/superpmi/superpmi-shared/typeutils.cpp')
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/typeutils.cpp169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/ToolBox/superpmi/superpmi-shared/typeutils.cpp b/src/ToolBox/superpmi/superpmi-shared/typeutils.cpp
new file mode 100644
index 0000000000..0b2eee6b4a
--- /dev/null
+++ b/src/ToolBox/superpmi/superpmi-shared/typeutils.cpp
@@ -0,0 +1,169 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+//----------------------------------------------------------
+// TypeUtils.cpp - Utility code for working with managed types
+//----------------------------------------------------------
+
+#include "standardpch.h"
+#include "typeutils.h"
+#include "errorhandling.h"
+
+// Returns a string representation of the given CorInfoType. The naming scheme is based on JITtype2varType
+// in src/jit/ee_il_dll.hpp.
+const char *TypeUtils::GetCorInfoTypeName(CorInfoType type)
+{
+ switch (type)
+ {
+ case CORINFO_TYPE_VOID:
+ return "void";
+
+ case CORINFO_TYPE_BOOL:
+ return "bool";
+
+ case CORINFO_TYPE_CHAR:
+ return "char";
+
+ case CORINFO_TYPE_BYTE:
+ return "byte";
+
+ case CORINFO_TYPE_UBYTE:
+ return "ubyte";
+
+ case CORINFO_TYPE_SHORT:
+ return "short";
+
+ case CORINFO_TYPE_USHORT:
+ return "ushort";
+
+ case CORINFO_TYPE_INT:
+ return "int";
+
+ case CORINFO_TYPE_UINT:
+ return "uint";
+
+ case CORINFO_TYPE_LONG:
+ return "long";
+
+ case CORINFO_TYPE_ULONG:
+ return "ulong";
+
+ case CORINFO_TYPE_FLOAT:
+ return "float";
+
+ case CORINFO_TYPE_DOUBLE:
+ return "double";
+
+ case CORINFO_TYPE_BYREF:
+ return "byref";
+
+ case CORINFO_TYPE_VALUECLASS:
+ case CORINFO_TYPE_REFANY:
+ return "struct";
+
+ case CORINFO_TYPE_STRING:
+ case CORINFO_TYPE_CLASS:
+ case CORINFO_TYPE_VAR:
+ return "ref";
+
+ case CORINFO_TYPE_NATIVEINT:
+ case CORINFO_TYPE_NATIVEUINT:
+ // Emulates the JIT's concept of TYP_I_IMPL
+#if defined(_TARGET_AMD64_) // TODO: should be _TARGET_64BIT_
+ return "long";
+#else
+ return "int";
+#endif
+
+ case CORINFO_TYPE_PTR:
+ // The JIT just treats this as a TYP_I_IMPL because this isn't a GC root,
+ // but we don't care about GC-ness: we care about pointer-sized.
+ return "ptr";
+
+ default:
+ LogException(EXCEPTIONCODE_TYPEUTILS, "Unknown type passed into GetCorInfoTypeName (0x%x)", type);
+ return "UNKNOWN";
+ }
+}
+
+bool TypeUtils::IsFloatingPoint(CorInfoType type)
+{
+ return (type == CORINFO_TYPE_FLOAT || type == CORINFO_TYPE_DOUBLE);
+}
+
+bool TypeUtils::IsPointer(CorInfoType type)
+{
+ return (type == CORINFO_TYPE_STRING || type == CORINFO_TYPE_PTR ||
+ type == CORINFO_TYPE_BYREF || type == CORINFO_TYPE_CLASS);
+}
+
+bool TypeUtils::IsValueClass(CorInfoType type)
+{
+ return (type == CORINFO_TYPE_VALUECLASS || type == CORINFO_TYPE_REFANY);
+}
+
+// Determines if a value class, represented by the given class handle, is required to be passed
+// by reference (i.e. it cannot be stuffed as-is into a register or stack slot).
+bool TypeUtils::ValueClassRequiresByref(MethodContext *mc, CORINFO_CLASS_HANDLE clsHnd)
+{
+#if defined(_TARGET_AMD64_)
+ size_t size = mc->repGetClassSize(clsHnd);
+ return ((size > sizeof(void *)) || ((size & (size - 1)) != 0));
+#else
+ LogException(EXCEPTIONCODE_TYPEUTILS, "unsupported architecture", "");
+ return false;
+#endif
+}
+
+// Returns the size of the given CorInfoType. If there is no applicable size (e.g. CORINFO_TYPE_VOID,
+// CORINFO_TYPE_UNDEF), this throws an exception and returns -1. Taken largely from the MSDN documentation
+// for managed sizeof.
+size_t TypeUtils::SizeOfCorInfoType(CorInfoType type)
+{
+ switch (type)
+ {
+ case CORINFO_TYPE_BYTE:
+ case CORINFO_TYPE_UBYTE:
+ case CORINFO_TYPE_BOOL:
+ return sizeof(BYTE);
+
+ case CORINFO_TYPE_CHAR: // 2 bytes for Unicode
+ case CORINFO_TYPE_SHORT:
+ case CORINFO_TYPE_USHORT:
+ return sizeof(WORD);
+
+ case CORINFO_TYPE_INT:
+ case CORINFO_TYPE_UINT:
+ case CORINFO_TYPE_FLOAT:
+ return sizeof(DWORD);
+
+ case CORINFO_TYPE_LONG:
+ case CORINFO_TYPE_ULONG:
+ case CORINFO_TYPE_DOUBLE:
+ return sizeof(DWORDLONG);
+
+ case CORINFO_TYPE_NATIVEINT:
+ case CORINFO_TYPE_NATIVEUINT:
+ case CORINFO_TYPE_STRING:
+ case CORINFO_TYPE_PTR:
+ case CORINFO_TYPE_BYREF:
+ case CORINFO_TYPE_CLASS:
+ return sizeof(void *);
+
+ // This should be obtained via repGetClassSize
+ case CORINFO_TYPE_VALUECLASS:
+ case CORINFO_TYPE_REFANY:
+ LogException(EXCEPTIONCODE_TYPEUTILS,
+ "SizeOfCorInfoType does not support value types; use repGetClassSize instead (type: 0x%x)",
+ type);
+ return 0;
+
+ case CORINFO_TYPE_UNDEF:
+ case CORINFO_TYPE_VOID:
+ default:
+ LogException(EXCEPTIONCODE_TYPEUTILS, "Unsupported type (0x%x) passed into SizeOfCorInfoType", type);
+ return 0;
+ }
+}