📄 codeblock.vb
字号:
' ' Visual Basic.Net Compiler' Copyright (C) 2004 - 2007 Rolf Bjarne Kvinge, RKvinge@novell.com' ' This library is free software; you can redistribute it and/or' modify it under the terms of the GNU Lesser General Public' License as published by the Free Software Foundation; either' version 2.1 of the License, or (at your option) any later version.' ' This library is distributed in the hope that it will be useful,' but WITHOUT ANY WARRANTY; without even the implied warranty of' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU' Lesser General Public License for more details.' ' You should have received a copy of the GNU Lesser General Public' License along with this library; if not, write to the Free Software' Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA' #Const DEBUGPARSERESULT = True#Const EXTENDEDDEBUG = 0Public Class CodeBlock Inherits ParsedObject ''' <summary> ''' A list of all the variables in this code block. ''' This is just a cache, all the variables are also in m_Statements. ''' </summary> ''' <remarks></remarks> Private m_Variables As New Nameables(Of VariableDeclaration)(Me) Private m_StaticVariables As Generic.List(Of VariableDeclaration) ''' <summary> ''' A list of all the statements (expressions) in this code block. ''' </summary> ''' <remarks></remarks> Private m_Statements As New BaseObjects(Of Statement)(Compiler) Private m_BlockStatements As Generic.List(Of BlockStatement) Private m_Sequence As New BaseObjects(Of BaseObject)(Me) ''' <summary> ''' A list of all the labels in this code block. ''' </summary> ''' <remarks></remarks> Private m_Labels As New Generic.List(Of LabelDeclarationStatement) Private m_FirstStatement As Statement Private m_HasStructuredExceptionHandling As Boolean Private m_HasUnstructuredExceptionHandling As Boolean Private m_HasResume As Boolean Public EndUnstructuredExceptionHandler As Label ''' <summary> ''' This is the variable informing which handler should handle an exception. ''' </summary> ''' <remarks></remarks> Public UnstructuredExceptionHandlerVariable As LocalBuilder ''' <summary> ''' A value is stored here to check if the running code is in the unstructured handler ''' 0: not in the handler ''' -1: in the handler. ''' </summary> ''' <remarks></remarks> Public IsInUnstructuredHandler As LocalBuilder Public UnstructuredExceptionHandler As Label Public UnstructuredSwitchHandler As Label ''' <summary> ''' The end of the switch. The code here jumps to the end of the method. ''' </summary> ''' <remarks></remarks> Public UnstructuredSwitchHandlerEnd As Label ''' <summary> ''' The resume next exception handler. Index 1 of the switch table ''' </summary> ''' <remarks></remarks> Public ResumeNextExceptionHandler As Label ''' <summary> ''' The index into the jump table of the current instruction. ''' </summary> ''' <remarks></remarks> Public CurrentInstruction As LocalBuilder Public UnstructuredExceptionLabels As Generic.List(Of Label) Public EndMethodLabel As Label ''' <summary> ''' The location of the code that throws an internal exception. ''' </summary> ''' <remarks></remarks> Private m_InternalExceptionLocation As Label Private m_EndOfMethodLabel As Nullable(Of Label) ReadOnly Property BlockStatements() As Generic.List(Of BlockStatement) Get If m_BlockStatements Is Nothing Then m_BlockStatements = New Generic.List(Of BlockStatement) For Each stmt As Statement In m_Statements Dim blockStmt As BlockStatement blockStmt = TryCast(stmt, BlockStatement) If blockStmt IsNot Nothing Then m_BlockStatements.Add(blockStmt) Next End If Return m_BlockStatements End Get End Property Sub FindStaticVariables(ByVal list As Generic.List(Of VariableDeclaration)) If m_StaticVariables IsNot Nothing Then list.AddRange(m_StaticVariables) Return End If For Each var As VariableDeclaration In m_Variables If var.Modifiers.Is(ModifierMasks.Static) Then list.Add(var) End If Next For Each stmt As BlockStatement In BlockStatements stmt.CodeBlock.FindStaticVariables(list) Next m_StaticVariables = list End Sub Sub New(ByVal Parent As ParsedObject) MyBase.New(Parent) End Sub Sub AddStatement(ByVal Statement As Statement) m_Statements.Add(Statement) m_Sequence.Add(Statement) End Sub Sub AddLabel(ByVal lbl As LabelDeclarationStatement) m_Labels.Add(lbl) Dim cb As CodeBlock = Me.FindFirstParent(Of CodeBlock)() If cb IsNot Nothing Then cb.AddLabel(lbl) End Sub Sub AddVariable(ByVal var As VariableDeclaration) m_Variables.Add(var) m_Sequence.Add(var) End Sub Sub AddVariables(ByVal list As Generic.ICollection(Of VariableDeclaration)) For Each var As VariableDeclaration In list AddVariable(var) Next End Sub ''' <summary> ''' A label to just before the last ret instruction of the method. ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks> ReadOnly Property EndOfMethodLabel() As Label Get If m_EndOfMethodLabel.HasValue Then Return m_EndOfMethodLabel.Value Else Helper.Assert(Me IsNot UpmostBlock) Return Me.UpmostBlock.EndOfMethodLabel End If End Get End Property Property FirstStatement() As Statement Get Return m_FirstStatement End Get Set(ByVal value As Statement) m_FirstStatement = value End Set End Property ReadOnly Property Statements() As Generic.List(Of Statement) Get Return m_Statements End Get End Property Sub RemoveStatement(ByVal Statement As Statement) m_Statements.Remove(Statement) m_Sequence.Remove(Statement) End Sub Property HasResume() As Boolean Get Return m_HasResume End Get Set(ByVal value As Boolean) Helper.Assert(value = True) m_HasResume = value Dim parent As CodeBlock = Me.FindFirstParent(Of CodeBlock)() If parent IsNot Nothing Then parent.HasResume = value End Set End Property Property HasUnstructuredExceptionHandling() As Boolean Get Return m_HasUnstructuredExceptionHandling End Get Set(ByVal value As Boolean) m_HasUnstructuredExceptionHandling = True Dim parent As CodeBlock = Me.FindFirstParent(Of CodeBlock)() If parent IsNot Nothing Then parent.HasUnstructuredExceptionHandling = value End Set End Property Property HasStructuredExceptionHandling() As Boolean Get Return m_HasStructuredExceptionHandling End Get Set(ByVal value As Boolean) m_HasStructuredExceptionHandling = True Dim parent As CodeBlock = Me.FindFirstParent(Of CodeBlock)() parent.HasStructuredExceptionHandling = value End Set End Property ReadOnly Property Labels() As Generic.List(Of LabelDeclarationStatement) Get Return m_Labels End Get End Property Function FindLabel(ByVal Name As Token) As LabelDeclarationStatement Dim cb As CodeBlock = Me.FindFirstParent(Of CodeBlock)() If cb IsNot Nothing Then Return cb.FindLabel(Name) Else For Each l As LabelDeclarationStatement In m_Labels If l.Label.Equals(Name) Then Return l End If Next End If Return Nothing End Function Private Function GenerateUnstructuredStart(ByVal Info As EmitInfo) As Boolean Dim result As Boolean = True EndMethodLabel = Info.ILGen.DefineLabel m_InternalExceptionLocation = Info.ILGen.DefineLabel UnstructuredExceptionHandler = Info.ILGen.DefineLabel UnstructuredSwitchHandler = Info.ILGen.DefineLabel UnstructuredSwitchHandlerEnd = Info.ILGen.DefineLabel UnstructuredExceptionHandlerVariable = Info.ILGen.DeclareLocal(Compiler.TypeCache.System_Int32) IsInUnstructuredHandler = Info.ILGen.DeclareLocal(Compiler.TypeCache.System_Int32) EndUnstructuredExceptionHandler = Info.ILGen.BeginExceptionBlock() UnstructuredExceptionLabels = New Generic.List(Of Label) 'At entry to the method, the exception-handler location and the exception are both set to Nothing. Emitter.EmitCall(Info, Compiler.TypeCache.MS_VB_CS_ProjectData__ClearProjectError) UnstructuredExceptionLabels.Add(UnstructuredSwitchHandlerEnd) 'index 0 If Me.HasResume Then Me.CurrentInstruction = Info.ILGen.DeclareLocal(Compiler.TypeCache.System_Int32) ResumeNextExceptionHandler = Info.ILGen.DefineLabel UnstructuredExceptionLabels.Add(ResumeNextExceptionHandler) 'index 1 Else UnstructuredExceptionLabels.Add(UnstructuredSwitchHandlerEnd) 'index 1 End If Return result End Function Private Function GenerateUnstructuredEnd(ByVal Method As IMethod, ByVal Info As EmitInfo) As Boolean Dim result As Boolean = True Dim retvar As LocalBuilder = Method.DefaultReturnVariable 'Add a label to the end of the code as the last item in the switch. If retvar IsNot Nothing Then Emitter.EmitLeave(Info, Me.EndMethodLabel)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -