📄 emitter.vb
字号:
Info.ILGen.Emit(OpCodes.Box, Info.Compiler.TypeCache.System_Decimal) converted = True Case TypeCombinations.DateTime_Object Info.ILGen.Emit(OpCodes.Box, Info.Compiler.TypeCache.System_DateTime) converted = True Case TypeCombinations.Boolean_Object Info.ILGen.Emit(OpCodes.Box, Info.Compiler.TypeCache.System_Boolean) converted = True Case TypeCombinations.Char_Object Info.ILGen.Emit(OpCodes.Box, Info.Compiler.TypeCache.System_Char) converted = True Case TypeCombinations.DBNull_Object converted = True 'Nothing to object Case TypeCombinations.Object_String Emitter.EmitCastClass(Info, Info.Compiler.TypeCache.System_Object, Info.Compiler.TypeCache.System_String) converted = True Case Else Info.Compiler.Report.WriteLine(vbnc.Report.ReportLevels.Debug, "Missed option: " & Switch.ToString) Helper.Stop() End Select If Not converted Then Info.Compiler.Report.WriteLine(vbnc.Report.ReportLevels.Debug, "Skipped option: " & Switch.ToString) Helper.Stop() Else Info.Stack.Pop(FromType) Info.Stack.Push(ToType) End If End Sub ''' <summary> ''' Loads Me onto the evaluation stack. ''' </summary> ''' <param name="Info"></param> ''' <remarks></remarks> Shared Sub EmitLoadMe(ByVal Info As EmitInfo, ByVal TypeOfMe As Type) TypeOfMe = Helper.GetTypeOrTypeBuilder(TypeOfMe) Info.ILGen.Emit(OpCodes.Ldarg_0) If TypeOfMe.IsValueType Then Info.Stack.Push(Info.Compiler.TypeManager.MakeByRefType(CType(Info.Method, ParsedObject), TypeOfMe)) Else Info.Stack.Push(TypeOfMe) End If End Sub Shared Sub EmitCall(ByVal Info As EmitInfo, ByVal Method As MethodBase) Dim OriginalMethod As MethodBase = Method Helper.Assert(Method IsNot Nothing) Dim minfo As MethodInfo = TryCast(Method, MethodInfo) Dim cinfo As ConstructorInfo = TryCast(Method, ConstructorInfo) If minfo IsNot Nothing Then Emitter.EmitCall(Info, minfo) ElseIf cinfo IsNot Nothing Then Emitter.EmitCall(Info, cinfo) Else Helper.Stop() End If End Sub Shared Sub EmitCall(ByVal Info As EmitInfo, ByVal Method As MethodInfo) Dim OriginalMethod As MethodBase = Method Helper.Assert(Method IsNot Nothing, "The method Is Nothing") Dim minfo As MethodInfo minfo = Helper.GetMethodOrMethodBuilder(Method) minfo = SwitchVersionedMethods(Info, minfo) PopParameters(Info, Helper.GetParameters(Info.Compiler, Method)) If Method.IsStatic Then Info.ILGen.Emit(OpCodes.Call, minfo) ElseIf Method.DeclaringType.IsValueType Then Info.Stack.Pop(Info.Compiler.TypeManager.MakeByRefType(CType(Info.Method, ParsedObject), Method.DeclaringType)) Info.ILGen.Emit(OpCodes.Call, minfo) Else Info.Stack.Pop(Method.DeclaringType) Info.ILGen.Emit(OpCodes.Call, minfo) End If If minfo.ReturnType IsNot Nothing AndAlso Helper.CompareType(minfo.ReturnType, Info.Compiler.TypeCache.System_Void) = False Then Info.Stack.Push(DirectCast(OriginalMethod, MethodInfo).ReturnType) End If End Sub Shared Sub EmitCallOrCallVirt(ByVal Info As EmitInfo, ByVal Method As MethodBase) Dim minfo As MethodInfo = TryCast(Method, MethodInfo) Dim cinfo As ConstructorInfo = TryCast(Method, ConstructorInfo) If minfo IsNot Nothing Then EmitCallOrCallVirt(Info, minfo) ElseIf cinfo IsNot Nothing Then EmitCall(Info, cinfo) Else Helper.Stop() End If End Sub Shared Sub EmitCallOrCallVirt(ByVal Info As EmitInfo, ByVal Method As MethodInfo) Helper.Assert(Method IsNot Nothing) If Method.IsStatic OrElse Method.DeclaringType.IsValueType Then EmitCall(Info, Method) Else EmitCallVirt(Info, Method) End If End Sub Shared Sub EmitLoadToken(ByVal Info As EmitInfo, ByVal Type As Type) Type = Helper.GetTypeOrTypeBuilder(Type) Helper.Assert(Type IsNot Nothing) Info.ILGen.Emit(OpCodes.Ldtoken, Type) Info.Stack.Push(Info.Compiler.TypeCache.System_RuntimeTypeHandle) End Sub Shared Sub EmitConstrained(ByVal Info As EmitInfo, ByVal Type As Type) Dim OriginalType As Type = Type Type = Helper.GetTypeOrTypeBuilder(Type) Info.ILGen.Emit(OpCodes.Constrained, Type) End Sub ''' <summary> ''' Emits a constrained callvirt instructions. ''' Throws an exception if the method is a shared method. ''' </summary> ''' <param name="Info"></param> ''' <param name="Method"></param> ''' <remarks></remarks> Shared Sub EmitConstrainedCallVirt(ByVal Info As EmitInfo, ByVal Method As MethodBase, ByVal ConstrainedType As Type) Dim OriginalMethod As MethodBase = Method Helper.Assert(Method IsNot Nothing) Helper.Assert(ConstrainedType IsNot Nothing) EmitConstrained(Info, ConstrainedType) EmitCallVirt(Info, Method) End Sub Shared Sub EmitCallVirt(ByVal Info As EmitInfo, ByVal Method As MethodBase) Select Case Method.MemberType Case MemberTypes.Method EmitCallVirt(Info, DirectCast(Method, MethodInfo)) Case Else Helper.NotImplemented() Throw New InternalException("") End Select End Sub ''' <summary> ''' Emits a callvirt instructions. ''' Throws an exception if the method is a shared method. ''' </summary> ''' <param name="Info"></param> ''' <param name="Method"></param> ''' <remarks></remarks> Shared Sub EmitCallVirt(ByVal Info As EmitInfo, ByVal Method As MethodInfo) Dim OriginalMethod As MethodInfo = Method Helper.Assert(Method IsNot Nothing) PopParameters(Info, Helper.GetParameters(Info.Compiler, Method)) Method = Helper.GetMethodOrMethodBuilder(OriginalMethod) Method = SwitchVersionedMethods(Info, Method)#If DEBUG Then If Method.GetType.Name <> "SymbolMethod" Then If Method.IsStatic Then Throw New InternalException("") ElseIf Method.DeclaringType.IsValueType Then Throw New InternalException("") End If End If#End If Info.Stack.Pop(Method.DeclaringType) Info.ILGen.EmitCall(OpCodes.Callvirt, Method, Nothing) If OriginalMethod.ReturnType IsNot Nothing AndAlso Helper.CompareType(OriginalMethod.ReturnType, Info.Compiler.TypeCache.System_Void) = False Then Info.Stack.Push(OriginalMethod.ReturnType) End If End Sub ''' <summary> ''' Emits a call to a constructor (not a new expression) ''' Throws an exception if the method is a shared method. ''' </summary> ''' <param name="Info"></param> ''' <param name="Method"></param> ''' <remarks></remarks> Shared Sub EmitCall(ByVal Info As EmitInfo, ByVal Method As ConstructorInfo) Helper.Assert(Method IsNot Nothing) PopParameters(Info, Helper.GetParameters(Info.Compiler, Method)) Method = Helper.GetCtorOrCtorBuilder(Method) If Method.IsStatic Then Throw New InternalException("") Else Method = Helper.GetCtorOrCtorBuilder(Method) Info.Stack.Pop(Method.DeclaringType) Info.ILGen.Emit(OpCodes.Call, Method) End If End Sub Shared Sub EmitNewArr(ByVal Info As EmitInfo, ByVal Type As Type) Type = Helper.GetTypeOrTypeBuilder(Type) Info.Stack.Pop(Info.Compiler.TypeCache.System_Int32) Info.ILGen.Emit(OpCodes.Newarr, Type) Info.Stack.Push(Type.MakeArrayType) End Sub Shared Sub EmitLoadElementAddress(ByVal Info As EmitInfo, ByVal ElementType As Type, ByVal ArrayType As Type) ArrayType = Helper.GetTypeOrTypeBuilder(ArrayType) ElementType = Helper.GetTypeOrTypeBuilder(ElementType) Info.ILGen.Emit(OpCodes.Ldelema, ElementType) Info.Stack.Pop(Info.Compiler.TypeCache.System_Int32) Info.Stack.Pop(ArrayType) Info.Stack.Push(Info.Compiler.TypeManager.MakeByRefType(CType(Info.Method, ParsedObject), ElementType)) End Sub Shared Sub EmitLoadElement(ByVal Info As EmitInfo, ByVal ArrayType As Type) ArrayType = Helper.GetTypeOrTypeBuilder(ArrayType) Info.Stack.Pop(Info.Compiler.TypeCache.System_Int32) Info.Stack.Pop(ArrayType) Dim ElementType As Type = ArrayType.GetElementType Select Case Helper.GetTypeCode(Info.Compiler, ElementType) Case TypeCode.Byte Info.ILGen.Emit(OpCodes.Ldelem_U1) Case TypeCode.SByte, TypeCode.Boolean Info.ILGen.Emit(OpCodes.Ldelem_I1) Case TypeCode.UInt16, TypeCode.Char Info.ILGen.Emit(OpCodes.Ldelem_U2) Case TypeCode.Int16 Info.ILGen.Emit(OpCodes.Ldelem_I2) Case TypeCode.UInt32 Info.ILGen.Emit(OpCodes.Ldelem_U4) Case TypeCode.Int32 Info.ILGen.Emit(OpCodes.Ldelem_I4) Case TypeCode.UInt64, TypeCode.Int64 Info.ILGen.Emit(OpCodes.Ldelem_I8) Case TypeCode.Single Info.ILGen.Emit(OpCodes.Ldelem_R4) Case TypeCode.Double Info.ILGen.Emit(OpCodes.Ldelem_R8) Case TypeCode.Object, TypeCode.String, TypeCode.DateTime, TypeCode.Decimal If ElementType.IsValueType Then Throw New InternalException("") Else Info.ILGen.Emit(OpCodes.Ldelem_Ref) End If Case Else Helper.NotImplemented() End Select Info.Stack.Push(ElementType) End Sub Shared Sub LoadElement(ByVal Info As EmitInfo, ByVal ElementType As Type) ElementType = Helper.GetTypeOrTypeBuilder(ElementType) Select Case Helper.GetTypeCode(Info.Compiler, ElementType) Case TypeCode.Byte Info.ILGen.Emit(OpCodes.Ldelem_U1) Case TypeCode.UInt16, TypeCode.Char Info.ILGen.Emit(OpCodes.Ldelem_U2) Case TypeCode.UInt32 Info.ILGen.Emit(OpCodes.Ldelem_U4) Case TypeCode.UInt64 Info.ILGen.Emit(OpCodes.Ldelem_I8) Case TypeCode.SByte, TypeCode.Boolean Info.ILGen.Emit(OpCodes.Ldelem_I1) Case TypeCode.Int16 Info.ILGen.Emit(OpCodes.Ldelem_I2) Case TypeCode.Int32 Info.ILGen.Emit(OpCodes.Ldelem_I4) Case TypeCode.Int64 Info.ILGen.Emit(OpCodes.Ldelem_I8) Case TypeCode.Single Info.ILGen.Emit(OpCodes.Ldelem_R4) Case TypeCode.Double Info.ILGen.Emit(OpCodes.Ldelem_R8) Case TypeCode.DateTime, TypeCode.Decimal Info.ILGen.Emit(OpCodes.Ldelema, ElementType) Info.ILGen.Emit(OpCodes.Ldobj, ElementType) Case TypeCode.String Info.ILGen.Emit(OpCodes.Ldelem_Ref) Case Else Helper.NotImplemented() End Select Info.Stack.Pop(Info.Compiler.TypeCache.System_Int32) Info.Stack.Pop(ElementType.MakeArrayType) Info.Stack.Push(ElementType) End Sub ''' <summary> ''' Type = the type of the element. (not of the array.) ''' </summary> ''' <param name="Info"></param> ''' <param name="ElementType"></param> ''' <remarks></remarks> Shared Sub EmitStoreElement(ByVal Info As EmitInfo, ByVal ElementType As Type, ByVal ArrayType As Type) ArrayType = Helper.GetTypeOrTypeBuilder(ArrayType) ElementType = Helper.GetTypeOrTypeBuilder(ElementType) Select Case Helper.GetTypeCode(Info.Compiler, ElementType) Case TypeCode.Int32, TypeCode.UInt32 Info.ILGen.Emit(OpCodes.Stelem_I4) Case TypeCode.SByte, TypeCode.Byte, TypeCode.Boolean Info.ILGen.Emit(OpCodes.Stelem_I1) Case TypeCode.Int16, TypeCode.UInt16, TypeCode.Char Info.ILGen.Emit(OpCodes.Stelem_I2) Case TypeCode.Int64, TypeCode.UInt64 Info.ILGen.Emit(OpCodes.Stelem_I8) Case TypeCode.Single Info.ILGen.Emit(OpCodes.Stelem_R4) Case TypeCode.Double Info.ILGen.Emit(OpCodes.Stelem_R8)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -