diff options
author | jfrijters <jfrijters> | 2015-04-21 11:19:33 +0300 |
---|---|---|
committer | jfrijters <jfrijters> | 2015-04-21 11:19:33 +0300 |
commit | 1a0e8b574865260d533eb3f1cd672781e3d5672d (patch) | |
tree | 279068760b6f044987f3ea986505a62e810b7a60 /reflect | |
parent | 893a468486fbfcab73ea10df21e24f4a3576934b (diff) |
Optimized built-in type handling a bit.
Diffstat (limited to 'reflect')
-rw-r--r-- | reflect/Emit/TypeBuilder.cs | 2 | ||||
-rw-r--r-- | reflect/Missing.cs | 2 | ||||
-rw-r--r-- | reflect/Reader/TypeDefImpl.cs | 2 | ||||
-rw-r--r-- | reflect/Signature.cs | 73 | ||||
-rw-r--r-- | reflect/Type.cs | 154 |
5 files changed, 116 insertions, 117 deletions
diff --git a/reflect/Emit/TypeBuilder.cs b/reflect/Emit/TypeBuilder.cs index 7b852740..9f274ca3 100644 --- a/reflect/Emit/TypeBuilder.cs +++ b/reflect/Emit/TypeBuilder.cs @@ -277,7 +277,7 @@ namespace IKVM.Reflection.Emit this.name = name; this.typeNameSpace = ns == null ? 0 : this.ModuleBuilder.Strings.Add(ns); this.typeName = this.ModuleBuilder.Strings.Add(name); - MarkEnumOrValueType(ns, name); + MarkKnownType(ns, name); } public ConstructorBuilder DefineDefaultConstructor(MethodAttributes attributes) diff --git a/reflect/Missing.cs b/reflect/Missing.cs index 283a1326..a84d466b 100644 --- a/reflect/Missing.cs +++ b/reflect/Missing.cs @@ -406,7 +406,7 @@ namespace IKVM.Reflection this.declaringType = declaringType; this.ns = ns; this.name = name; - MarkEnumOrValueType(ns, name); + MarkKnownType(ns, name); // HACK we need to handle the Windows Runtime projected types that change from ValueType to Class or v.v. if (WindowsRuntimeProjection.IsProjectedValueType(ns, name, module)) diff --git a/reflect/Reader/TypeDefImpl.cs b/reflect/Reader/TypeDefImpl.cs index e001e552..a03afec1 100644 --- a/reflect/Reader/TypeDefImpl.cs +++ b/reflect/Reader/TypeDefImpl.cs @@ -43,7 +43,7 @@ namespace IKVM.Reflection.Reader this.index = index; this.typeName = module.GetString(module.TypeDef.records[index].TypeName); this.typeNamespace = module.GetString(module.TypeDef.records[index].TypeNamespace); - MarkEnumOrValueType(typeNamespace, typeName); + MarkKnownType(typeNamespace, typeName); } public override Type BaseType diff --git a/reflect/Signature.cs b/reflect/Signature.cs index 35c9a65b..dffad248 100644 --- a/reflect/Signature.cs +++ b/reflect/Signature.cs @@ -377,78 +377,9 @@ namespace IKVM.Reflection WriteCustomModifiers(module, bb, type.__GetCustomModifiers()); type = type.GetElementType(); } - Universe u = module.universe; - if (type == u.System_Void) + if (type.__IsBuiltIn) { - bb.Write(ELEMENT_TYPE_VOID); - } - else if (type == u.System_Int32) - { - bb.Write(ELEMENT_TYPE_I4); - } - else if (type == u.System_Boolean) - { - bb.Write(ELEMENT_TYPE_BOOLEAN); - } - else if (type == u.System_String) - { - bb.Write(ELEMENT_TYPE_STRING); - } - else if (type == u.System_Char) - { - bb.Write(ELEMENT_TYPE_CHAR); - } - else if (type == u.System_SByte) - { - bb.Write(ELEMENT_TYPE_I1); - } - else if (type == u.System_Byte) - { - bb.Write(ELEMENT_TYPE_U1); - } - else if (type == u.System_Int16) - { - bb.Write(ELEMENT_TYPE_I2); - } - else if (type == u.System_UInt16) - { - bb.Write(ELEMENT_TYPE_U2); - } - else if (type == u.System_UInt32) - { - bb.Write(ELEMENT_TYPE_U4); - } - else if (type == u.System_Int64) - { - bb.Write(ELEMENT_TYPE_I8); - } - else if (type == u.System_UInt64) - { - bb.Write(ELEMENT_TYPE_U8); - } - else if (type == u.System_Single) - { - bb.Write(ELEMENT_TYPE_R4); - } - else if (type == u.System_Double) - { - bb.Write(ELEMENT_TYPE_R8); - } - else if (type == u.System_IntPtr) - { - bb.Write(ELEMENT_TYPE_I); - } - else if (type == u.System_UIntPtr) - { - bb.Write(ELEMENT_TYPE_U); - } - else if (type == u.System_TypedReference) - { - bb.Write(ELEMENT_TYPE_TYPEDBYREF); - } - else if (type == u.System_Object) - { - bb.Write(ELEMENT_TYPE_OBJECT); + bb.Write(type.BuiltInElementType); } else if (type.IsGenericParameter) { diff --git a/reflect/Type.cs b/reflect/Type.cs index 4153ef13..3436b140 100644 --- a/reflect/Type.cs +++ b/reflect/Type.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2009-2013 Jeroen Frijters + Copyright (C) 2009-2015 Jeroen Frijters This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -46,9 +46,10 @@ namespace IKVM.Reflection public static readonly Type[] EmptyTypes = Empty<Type>.Array; protected readonly Type underlyingType; protected TypeFlags typeFlags; + private byte elementType; // only used if __IsBuiltIn returns true [Flags] - protected enum TypeFlags + protected enum TypeFlags : ushort { // for use by TypeBuilder or TypeDefImpl IsGenericTypeDefinition = 1, @@ -74,6 +75,10 @@ namespace IKVM.Reflection ContainsMissingType_Yes = 512, ContainsMissingType_No = 256 | 512, ContainsMissingType_Mask = 256 | 512, + + // built-in type support + PotentialBuiltIn = 1024, + BuiltIn = 2048, } // prevent subclassing by outsiders @@ -1227,22 +1232,10 @@ namespace IKVM.Reflection { get { - Universe u = this.Universe; - return this == u.System_Boolean - || this == u.System_Byte - || this == u.System_SByte - || this == u.System_Int16 - || this == u.System_UInt16 - || this == u.System_Int32 - || this == u.System_UInt32 - || this == u.System_Int64 - || this == u.System_UInt64 - || this == u.System_IntPtr - || this == u.System_UIntPtr - || this == u.System_Char - || this == u.System_Double - || this == u.System_Single - ; + return __IsBuiltIn + && ((elementType >= Signature.ELEMENT_TYPE_BOOLEAN && elementType <= Signature.ELEMENT_TYPE_R8) + || elementType == Signature.ELEMENT_TYPE_I + || elementType == Signature.ELEMENT_TYPE_U); } } @@ -1250,30 +1243,80 @@ namespace IKVM.Reflection { get { - // [ECMA 335] 8.2.2 Built-in value and reference types - Universe u = this.Universe; - return this == u.System_Boolean - || this == u.System_Char - || this == u.System_Object - || this == u.System_String - || this == u.System_Single - || this == u.System_Double - || this == u.System_SByte - || this == u.System_Int16 - || this == u.System_Int32 - || this == u.System_Int64 - || this == u.System_IntPtr - || this == u.System_UIntPtr - || this == u.System_TypedReference - || this == u.System_Byte - || this == u.System_UInt16 - || this == u.System_UInt32 - || this == u.System_UInt64 - || this == u.System_Void // [LAMESPEC] missing from ECMA list for some reason - ; + return (typeFlags & (TypeFlags.BuiltIn | TypeFlags.PotentialBuiltIn)) != 0 + && ((typeFlags & TypeFlags.BuiltIn) != 0 || ResolvePotentialBuiltInType()); + } + } + + internal byte BuiltInElementType + { + get + { + // this property can only be called after __IsBuiltIn returned true + System.Diagnostics.Debug.Assert((typeFlags & TypeFlags.BuiltIn) != 0); + return elementType; + } + } + + private bool ResolvePotentialBuiltInType() + { + // [ECMA 335] 8.2.2 Built-in value and reference types + typeFlags &= ~TypeFlags.PotentialBuiltIn; + Universe u = this.Universe; + switch (__Name) + { + case "Boolean": + return ResolvePotentialBuiltInType(u.System_Boolean, Signature.ELEMENT_TYPE_BOOLEAN); + case "Char": + return ResolvePotentialBuiltInType(u.System_Char, Signature.ELEMENT_TYPE_CHAR); + case "Object": + return ResolvePotentialBuiltInType(u.System_Object, Signature.ELEMENT_TYPE_OBJECT); + case "String": + return ResolvePotentialBuiltInType(u.System_String, Signature.ELEMENT_TYPE_STRING); + case "Single": + return ResolvePotentialBuiltInType(u.System_Single, Signature.ELEMENT_TYPE_R4); + case "Double": + return ResolvePotentialBuiltInType(u.System_Double, Signature.ELEMENT_TYPE_R8); + case "SByte": + return ResolvePotentialBuiltInType(u.System_SByte, Signature.ELEMENT_TYPE_I1); + case "Int16": + return ResolvePotentialBuiltInType(u.System_Int16, Signature.ELEMENT_TYPE_I2); + case "Int32": + return ResolvePotentialBuiltInType(u.System_Int32, Signature.ELEMENT_TYPE_I4); + case "Int64": + return ResolvePotentialBuiltInType(u.System_Int64, Signature.ELEMENT_TYPE_I8); + case "IntPtr": + return ResolvePotentialBuiltInType(u.System_IntPtr, Signature.ELEMENT_TYPE_I); + case "UIntPtr": + return ResolvePotentialBuiltInType(u.System_UIntPtr, Signature.ELEMENT_TYPE_U); + case "TypedReference": + return ResolvePotentialBuiltInType(u.System_TypedReference, Signature.ELEMENT_TYPE_TYPEDBYREF); + case "Byte": + return ResolvePotentialBuiltInType(u.System_Byte, Signature.ELEMENT_TYPE_U1); + case "UInt16": + return ResolvePotentialBuiltInType(u.System_UInt16, Signature.ELEMENT_TYPE_U2); + case "UInt32": + return ResolvePotentialBuiltInType(u.System_UInt32, Signature.ELEMENT_TYPE_U4); + case "UInt64": + return ResolvePotentialBuiltInType(u.System_UInt64, Signature.ELEMENT_TYPE_U8); + case "Void": // [LAMESPEC] missing from ECMA list for some reason + return ResolvePotentialBuiltInType(u.System_Void, Signature.ELEMENT_TYPE_VOID); + default: + throw new InvalidOperationException(); } } + private bool ResolvePotentialBuiltInType(Type builtIn, byte elementType) + { + if (this == builtIn) + { + typeFlags |= TypeFlags.BuiltIn; + this.elementType = elementType; + return true; + } + return false; + } + public bool IsEnum { get @@ -2104,14 +2147,39 @@ namespace IKVM.Reflection return this; } - protected void MarkEnumOrValueType(string typeNamespace, string typeName) + protected void MarkKnownType(string typeNamespace, string typeName) { // we assume that mscorlib won't have nested types with these names, // so we don't check that we're not a nested type - if (typeNamespace == "System" - && (typeName == "Enum" || typeName == "ValueType")) + if (typeNamespace == "System") { - typeFlags |= TypeFlags.PotentialEnumOrValueType; + switch (typeName) + { + case "Boolean": + case "Char": + case "Object": + case "String": + case "Single": + case "Double": + case "SByte": + case "Int16": + case "Int32": + case "Int64": + case "IntPtr": + case "UIntPtr": + case "TypedReference": + case "Byte": + case "UInt16": + case "UInt32": + case "UInt64": + case "Void": + typeFlags |= TypeFlags.PotentialBuiltIn; + break; + case "Enum": + case "ValueType": + typeFlags |= TypeFlags.PotentialEnumOrValueType; + break; + } } } |