//private int trydepth; public void buildAS3Try(CompileEnv env, ASTool.AS3.AS3Try as3try, Builder builder) { //***先编译Try块 //trydepth++; int tryid = as3try.holdTryId; //string LBL_BEGIN_TRY = "BEGIN_TRY_" + tryid; //string LBL_END_TRY = "END_TRY_" + tryid; string LBL_BEGIN_FINALLY = "BEGIN_FINALLY_" + tryid; string LBL_END_FINALLY = "END_FINALLY_" + tryid; string LBL_CATCH = "BEGIN_CATCH_" + tryid; //OpStep begintry = new OpStep(OpCode.flag, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile)); //begintry.flag = LBL_BEGIN_TRY; //env.block.opSteps.Add(begintry); //**包装一个block** ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3try.Token); tempblock.CodeList = as3try.TryBlock; tempblock.label = as3try.label; { OpStep enter_try = new OpStep(OpCode.enter_try, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile)); enter_try.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid)); enter_try.arg1Type = RunTimeDataType.rt_int; env.block.opSteps.Add(enter_try); } builder.buildStmt(env, tempblock); { OpStep quit_try = new OpStep(OpCode.quit_try, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile)); quit_try.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid)); quit_try.arg1Type = RunTimeDataType.rt_int; env.block.opSteps.Add(quit_try); } //OpStep endtry= new OpStep(OpCode.flag, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile)); //endtry.flag = LBL_END_TRY; //env.block.opSteps.Add(endtry); //***跳转到Finally块*** { jumpTo(env, as3try, builder, LBL_BEGIN_FINALLY); } OpStep startCatch = new OpStep(OpCode.flag, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile)); startCatch.flag = LBL_CATCH; env.block.opSteps.Add(startCatch); //***编译Catch块*** for (int i = 0; i < as3try.CatchList.Count; i++) { var c = as3try.CatchList[i]; //c.CatchVariable.Name = "0"+c.CatchVariable.Name + "_" + i; VariableBase rtVariable = new Variable(c.CatchVariable.Name, env.block.scope.members.Count, true, env.block.id); rtVariable.valueType = TypeReader.fromSourceCodeStr(c.CatchVariable.TypeStr, c.CatchVariable.token, builder); env.block.scope.members.Add(rtVariable); //builder.buildVariables(env, c.CatchVariable); //string catchvariablename = "0" + c.CatchVariable.Name + "_" + i + "_" + tryid; //Variable rtVariable = (Variable)MemberFinder.find(catchvariablename, env); //rtVariable.resetName(c.CatchVariable.Name); //rtVariable.valueType = RunTimeDataType.rt_void; OpStep op = new OpStep(OpCode.catch_error, new SourceToken(c.CatchVariable.token.line, c.CatchVariable.token.ptr, c.CatchVariable.token.sourceFile)); op.reg = rtVariable; op.regType = TypeReader.fromSourceCodeStr(c.CatchVariable.TypeStr, c.CatchVariable.token, builder); op.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid)); op.arg1Type = RunTimeDataType.rt_int; op.arg2 = null; op.arg2Type = RunTimeDataType.unknown; env.block.opSteps.Add(op); { OpStep enter_catch = new OpStep(OpCode.enter_catch, new SourceToken(c.CatchVariable.token.line, c.CatchVariable.token.ptr, c.CatchVariable.token.sourceFile)); enter_catch.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid)); enter_catch.arg1Type = RunTimeDataType.rt_int; env.block.opSteps.Add(enter_catch); } int bstidx = env.block.opSteps.Count; for (int j = 0; j < c.CatchBlock.Count; j++) { builder.buildStmt(env, c.CatchBlock[j]); } for (int k = bstidx; k < env.block.opSteps.Count; k++) { var oop = env.block.opSteps[k]; if (Equals(oop.reg, rtVariable)) { ((Variable)oop.reg).resetName("0" + rtVariable.name + "_" + i + "_" + tryid); } if (Equals(oop.arg1, rtVariable)) { ((Variable)oop.arg1).resetName("0" + rtVariable.name + "_" + i + "_" + tryid); } if (Equals(oop.arg2, rtVariable)) { ((Variable)oop.arg2).resetName("0" + rtVariable.name + "_" + i + "_" + tryid); } } rtVariable.resetName("0" + rtVariable.name + "_" + i + "_" + tryid); { OpStep quit_catch = new OpStep(OpCode.quit_catch, new SourceToken(c.CatchVariable.token.line, c.CatchVariable.token.ptr, c.CatchVariable.token.sourceFile)); quit_catch.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid)); quit_catch.arg1Type = RunTimeDataType.rt_int; env.block.opSteps.Add(quit_catch); } { jumpTo(env, as3try, builder, LBL_BEGIN_FINALLY); } } //FINALLY { OpStep finallylbl = new OpStep(OpCode.flag, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile)); finallylbl.flag = LBL_BEGIN_FINALLY; env.block.opSteps.Add(finallylbl); { OpStep enter_finally = new OpStep(OpCode.enter_finally, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile)); enter_finally.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid)); enter_finally.arg1Type = RunTimeDataType.rt_int; env.block.opSteps.Add(enter_finally); } if (as3try.FinallyBlock != null) { for (int i = 0; i < as3try.FinallyBlock.Count; i++) { builder.buildStmt(env, as3try.FinallyBlock[i]); } } else { if (as3try.CatchList.Count == 0) { throw new BuildException(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile, "try块至少要有1个catch块或1个finally块."); } } { OpStep quit_finally = new OpStep(OpCode.quit_finally, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile)); quit_finally.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(tryid)); quit_finally.arg1Type = RunTimeDataType.rt_int; env.block.opSteps.Add(quit_finally); } OpStep endfinally = new OpStep(OpCode.flag, new SourceToken(as3try.Token.line, as3try.Token.ptr, as3try.Token.sourceFile)); endfinally.flag = LBL_END_FINALLY; env.block.opSteps.Add(endfinally); } //trydepth--; //throw new BuildException(as3try.Token.line,as3try.Token.ptr,as3try.Token.sourceFile,"try catch finally编译没实现"); }