Пример #1
0
        protected void EmitExceptionHandlingNode(ProtoCore.AST.Node node, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            #if ENABLE_EXCEPTION_HANDLING
            if (!IsParsingGlobal() && !IsParsingGlobalFunctionBody())
            {
                return;
            }

            ExceptionHandlingNode exceptionNode = node as ExceptionHandlingNode;
            if (exceptionNode == null)
                return;

            tryLevel++;
            ExceptionHandler exceptionHandler = new ExceptionHandler();
            exceptionHandler.TryLevel = tryLevel;

            ExceptionRegistration registration = core.ExceptionHandlingManager.Register(codeBlock.codeBlockId, globalProcIndex, globalClassIndex);
            registration.Add(exceptionHandler);

            exceptionHandler.StartPc = pc;
            TryBlockNode tryNode = exceptionNode.tryBlock;
            Debug.Assert(tryNode != null);
            foreach (var subnode in tryNode.body)
            {
                ProtoCore.Type inferedType = new ProtoCore.Type();
                inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                inferedType.IsIndexable = false;
                DfsTraverse(subnode, ref inferedType, false, graphNode, subPass);
            }
            exceptionHandler.EndPc = pc;

            // Jmp to code after catch block
            BackpatchTable backpatchTable = new BackpatchTable();
            backpatchTable.Append(pc);
            EmitJmp(ProtoCore.DSASM.Constants.kInvalidIndex);

            foreach (var catchBlock in exceptionNode.catchBlocks)
            {
                CatchHandler catchHandler = new CatchHandler();
                exceptionHandler.AddCatchHandler(catchHandler);

                CatchFilterNode filterNode = catchBlock.catchFilter;
                Debug.Assert(filterNode != null);
                catchHandler.FilterTypeUID = core.TypeSystem.GetType(filterNode.type.Name);
                if (catchHandler.FilterTypeUID == (int)PrimitiveType.kInvalidType)
                {
                    string message = String.Format(ProtoCore.BuildData.WarningMessage.kExceptionTypeUndefined, filterNode.type.Name);
                    buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kTypeUndefined, message, null, filterNode.line, filterNode.col);
                    catchHandler.FilterTypeUID = (int)PrimitiveType.kTypeVar;
                }

                // For filter expression catch(e:int), generate an assignment
                //    e = LX;
                catchHandler.Entry = pc;

                EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regLX);
                ProtoCore.DSASM.StackValue opLx = new ProtoCore.DSASM.StackValue();
                opLx.optype = ProtoCore.DSASM.AddressType.Register;
                opLx.opdata = (int)ProtoCore.DSASM.Registers.LX;
                EmitPush(opLx);

                ProtoCore.DSASM.SymbolNode excpVarSymbol = null;
                bool stub;
                bool isAllocated = VerifyAllocation(filterNode.var.Value, globalClassIndex, globalProcIndex, out excpVarSymbol, out stub);
                int runtimeIndex = (!isAllocated) ? codeBlock.symbolTable.runtimeIndex : excpVarSymbol.runtimeTableIndex;
                if (!isAllocated)
                {
                    excpVarSymbol = Allocate(filterNode.var.Value, globalProcIndex, new ProtoCore.Type());
                }
                EmitPushVarData(runtimeIndex, 0, (int)PrimitiveType.kTypeVar, 0);
                EmitInstrConsole(ProtoCore.DSASM.kw.pop, filterNode.var.Value);
                EmitPopForSymbol(excpVarSymbol, filterNode.var.line, filterNode.var.col, filterNode.var.endLine, filterNode.var.endCol);

                ProtoCore.Type inferedType = new ProtoCore.Type();
                inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                inferedType.IsIndexable = false;

                foreach (var subnode in catchBlock.body)
                {
                    inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                    inferedType.IsIndexable = false;
                    DfsTraverse(subnode, ref inferedType, false, graphNode, subPass);
                }

                // Jmp to code after catch block
                backpatchTable.Append(pc);
                EmitJmp(ProtoCore.DSASM.Constants.kInvalidIndex);
            }

            Backpatch(backpatchTable.backpatchList, pc);

            tryLevel--;
            #endif
        }
Пример #2
0
        protected void EmitExceptionHandlingNode(ProtoCore.AST.Node node, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (!IsParsingGlobal() && !IsParsingGlobalFunctionBody())
            {
                return;
            }

            ExceptionHandlingNode exceptionNode = node as ExceptionHandlingNode;
            if (exceptionNode == null)
                return;

            ExceptionRegistration registration = compileState.ExceptionHandlingManager.ExceptionTable.GetExceptionRegistration(codeBlock.codeBlockId, globalProcIndex, globalClassIndex);
            if (registration == null)
            {
                registration = compileState.ExceptionHandlingManager.ExceptionTable.Register(codeBlock.codeBlockId, globalProcIndex, globalClassIndex);
                Debug.Assert(registration != null);
            }

            tryLevel++;

            ExceptionHandler exceptionHandler = new ExceptionHandler();
            exceptionHandler.TryLevel = tryLevel;
            registration.Add(exceptionHandler);
            TryBlockNode tryNode = exceptionNode.tryBlock;
            Debug.Assert(tryNode != null);
            foreach (var subnode in tryNode.body)
            {
                ProtoCore.Type inferedType = new ProtoCore.Type();
                inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                inferedType.IsIndexable = false;
                DfsTraverse(subnode, ref inferedType, false, graphNode, subPass);
            }

            // Jmp to code after catch block

            foreach (var catchBlock in exceptionNode.catchBlocks)
            {
                CatchHandler catchHandler = new CatchHandler();
                exceptionHandler.AddCatchHandler(catchHandler);

                CatchFilterNode filterNode = catchBlock.catchFilter;
                Debug.Assert(filterNode != null);
                catchHandler.FilterTypeUID = compileState.TypeSystem.GetType(filterNode.type.Name);

                // For filter expression catch(e:int), generate an assignment
                //    e = %tmpExp;
                BinaryExpressionNode exceptionAssignmentNode = new BinaryExpressionNode()
                {
                    LeftNode = filterNode.var,
                    Optr = ProtoCore.DSASM.Operator.assign,
                    RightNode = new IdentifierNode()
                    {
                        Name = ProtoCore.DSASM.Constants.kTempExceptionVar,
                        Value = ProtoCore.DSASM.Constants.kTempExceptionVar,
                        datatype = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, false),
                    }
                };
                ProtoCore.Type inferedType = new ProtoCore.Type();
                inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                inferedType.IsIndexable = false;
                DfsTraverse(exceptionAssignmentNode, ref inferedType, false, graphNode, subPass);

                foreach (var subnode in catchBlock.body)
                {
                    inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                    inferedType.IsIndexable = false;
                    DfsTraverse(subnode, ref inferedType, false, graphNode, subPass);
                }

                // Jmp to code after catch block
            }

            tryLevel--;
        }
Пример #3
0
        protected void EmitExceptionHandlingNode(AssociativeNode node, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            #if ENABLE_EXCEPTION_HANDLING
            if (!IsParsingGlobal() && !IsParsingGlobalFunctionBody() && !IsParsingMemberFunctionBody())
            {
                return;
            }

            tryLevel++;

            ExceptionHandlingNode exceptionNode = node as ExceptionHandlingNode;
            if (exceptionNode == null)
                return;

            ExceptionHandler exceptionHandler = new ExceptionHandler();
            exceptionHandler.TryLevel = tryLevel;

            ExceptionRegistration registration = core.ExceptionHandlingManager.Register(codeBlock.codeBlockId, globalProcIndex, globalClassIndex);
            registration.Add(exceptionHandler);

            exceptionHandler.StartPc = pc;
            TryBlockNode tryNode = exceptionNode.tryBlock;
            Debug.Assert(tryNode != null);
            foreach (var subnode in tryNode.body)
            {
                ProtoCore.Type inferedType = new ProtoCore.Type();
                inferedType.UID = (int) ProtoCore.PrimitiveType.kTypeVar;
                inferedType.IsIndexable = false;
                DfsTraverse(subnode, ref inferedType, false, graphNode, subPass);
            }
            exceptionHandler.EndPc = pc;

            // Jmp to code after catch block
            BackpatchTable backpatchTable = new BackpatchTable();
            backpatchTable.Append(pc);
            EmitJmp(ProtoCore.DSASM.Constants.kInvalidIndex);

            foreach (var catchBlock in exceptionNode.catchBlocks)
            {
                CatchHandler catchHandler = new CatchHandler();
                exceptionHandler.AddCatchHandler(catchHandler);

                CatchFilterNode filterNode = catchBlock.catchFilter;
                Debug.Assert(filterNode != null);
                catchHandler.FilterTypeUID = core.TypeSystem.GetType(filterNode.type.Name);
                if (catchHandler.FilterTypeUID == (int)PrimitiveType.kInvalidType)
                {
                    string message = String.Format(ProtoCore.BuildData.WarningMessage.kExceptionTypeUndefined, filterNode.type.Name);
                    buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kTypeUndefined, message, core.CurrentDSFileName, filterNode.line, filterNode.col);
                    catchHandler.FilterTypeUID = (int)PrimitiveType.kTypeVar;
                }

                ProtoCore.Type inferedType = new ProtoCore.Type();
                inferedType.UID = (int) ProtoCore.PrimitiveType.kTypeVar;
                inferedType.IsIndexable = false;
                DfsTraverse(filterNode.var, ref inferedType, false, graphNode, subPass);

                catchHandler.Entry = pc;
                foreach (var subnode in catchBlock.body)
                {
                    inferedType.UID = (int) ProtoCore.PrimitiveType.kTypeVar;
                    inferedType.IsIndexable = false;
                    DfsTraverse(subnode, ref inferedType, false, graphNode, subPass);
                }

                // Jmp to code after catch block
                backpatchTable.Append(pc);
                EmitJmp(ProtoCore.DSASM.Constants.kInvalidIndex);
            }

            Backpatch(backpatchTable.backpatchList, pc);

            tryLevel--;
            #endif
        }
Пример #4
0
        protected void EmitExceptionHandlingNode(AssociativeNode node, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone)
        {
            if (!IsParsingGlobal() && !IsParsingGlobalFunctionBody() && !IsParsingMemberFunctionBody())
                return;

            tryLevel++;

            ExceptionHandlingNode exceptionNode = node as ExceptionHandlingNode;
            if (exceptionNode == null)
                return;

            ExceptionHandler exceptionHandler = new ExceptionHandler();
            exceptionHandler.TryLevel = tryLevel;

            ExceptionRegistration registration = core.ExceptionHandlingManager.ExceptionTable.GetExceptionRegistration(codeBlock.codeBlockId, globalProcIndex, globalClassIndex);
            if (registration == null)
            {
                registration = core.ExceptionHandlingManager.ExceptionTable.Register(codeBlock.codeBlockId, globalProcIndex, globalClassIndex);
                Debug.Assert(registration != null);
            }
            registration.Add(exceptionHandler);

            TryBlockNode tryNode = exceptionNode.tryBlock;
            Debug.Assert(tryNode != null);
            foreach (var subnode in tryNode.body)
            {
                ProtoCore.Type inferedType = new ProtoCore.Type();
                inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                inferedType.IsIndexable = false;
                DfsTraverse(subnode, ref inferedType, false, graphNode, subPass);
            }

            foreach (var catchBlock in exceptionNode.catchBlocks)
            {
                CatchHandler catchHandler = new CatchHandler();
                exceptionHandler.AddCatchHandler(catchHandler);

                CatchFilterNode filterNode = catchBlock.catchFilter;
                Debug.Assert(filterNode != null);
                catchHandler.FilterTypeUID = core.TypeSystem.GetType(filterNode.type.Name);

                ProtoCore.Type inferedType = new ProtoCore.Type();
                inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                inferedType.IsIndexable = false;
                DfsTraverse(filterNode.var, ref inferedType, false, graphNode, subPass);

                foreach (var subnode in catchBlock.body)
                {
                    inferedType.UID = (int)ProtoCore.PrimitiveType.kTypeVar;
                    inferedType.IsIndexable = false;
                    DfsTraverse(subnode, ref inferedType, false, graphNode, subPass);
                }

                // Jmp to code after catch block
            }

            tryLevel--;
        }