Example #1
0
        public static void make_dotStep(CompileEnv env, ASBinCode.rtti.ClassMember member, ASTool.Token token,
                                        StackSlotAccessor eax, RightValueBase rvObj
                                        )
        {
            OpStep op = new OpStep(
                member.bindField is MethodGetterBase ?
                OpCode.access_method
                                :
                OpCode.access_dot

                , new SourceToken(token.line, token.ptr, token.sourceFile));


            RightValueBase field = (RightValueBase)member.bindField;



            op.reg      = eax; eax._isDotAccessTarget = true;
            op.regType  = eax.valueType;
            op.arg1     = rvObj;
            op.arg1Type = rvObj.valueType;
            op.arg2     = field;
            op.arg2Type = member.valueType;

            env.block.opSteps.Add(op);
        }
        private void build_void(CompileEnv env, RightValueBase cls, ASTool.AS3.Expr.AS3ExprStep step, Builder builder)
        {
            OpStep opnewclass = new OpStep(OpCode.new_instance_class,
                                           new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));

            opnewclass.arg1     = cls;
            opnewclass.arg1Type = RunTimeDataType.rt_void;
            StackSlotAccessor _eax = env.createASTRegister(step.Arg1.Reg);

            _eax.setEAXTypeWhenCompile(RunTimeDataType.rt_void);
            opnewclass.reg     = _eax;
            opnewclass.regType = RunTimeDataType.rt_void;


            OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_class_argement, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));

            opMakeArgs.arg1     = cls;
            opMakeArgs.arg1Type = RunTimeDataType.rt_void;
            env.block.opSteps.Add(opMakeArgs);

            if (step.Arg3 != null)
            {
                List <ASTool.AS3.Expr.AS3DataStackElement> args
                    = (List <ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value;
                for (int i = 0; i < args.Count; i++)
                {
                    ASTool.AS3.Expr.AS3DataStackElement argData = args[i];
                    RightValueBase arg = builds.ExpressionBuilder.getRightValue(env, argData, step.token, builder);
                    //***参数准备***
                    OpStep opPushArgs = new OpStep(OpCode.push_parameter_class, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                    opPushArgs.arg1     = arg;
                    opPushArgs.arg1Type = arg.valueType;
                    opPushArgs.arg2     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(i));
                    opPushArgs.arg2Type = RunTimeDataType.rt_int;
                    env.block.opSteps.Add(opPushArgs);
                }
            }



            env.block.opSteps.Add(opnewclass);
        }
        public void buildAS3Throw(CompileEnv env, ASTool.AS3.AS3Throw as3throw, Builder builder)
        {
            if (as3throw.Exception != null)
            {
                var testV = ExpressionEval.Eval(as3throw.Exception);
                if (testV != null && as3throw.Exception.Value.IsReg)
                {
                    OpStep op = new OpStep(OpCode.raise_error, new SourceToken(as3throw.Token.line, as3throw.Token.ptr, as3throw.Token.sourceFile));

                    op.arg1     = new ASBinCode.rtData.RightValue(testV);
                    op.arg1Type = testV.rtType;
                    op.arg2     = null;
                    op.arg2Type = RunTimeDataType.unknown;
                    op.reg      = null;
                    op.regType  = RunTimeDataType.unknown;

                    env.block.opSteps.Add(op);
                }
                else
                {
                    builder.buildExpression(env, as3throw.Exception);

                    OpStep op = new OpStep(OpCode.raise_error, new SourceToken(as3throw.Token.line, as3throw.Token.ptr, as3throw.Token.sourceFile));

                    RightValueBase lv = builds.ExpressionBuilder.getRightValue(env, as3throw.Exception.Value, as3throw.Token, builder);
                    op.arg1     = lv;
                    op.arg1Type = lv.valueType;
                    op.arg2     = null;
                    op.arg2Type = RunTimeDataType.unknown;
                    op.reg      = null;
                    op.regType  = RunTimeDataType.unknown;

                    env.block.opSteps.Add(op);
                }
            }
            else
            {
                //***只有在catch块中才能throw***;
                int l = 0;
                for (int i = 0; i < env.block.opSteps.Count; i++)
                {
                    if (env.block.opSteps[i].opCode == OpCode.enter_catch)
                    {
                        l++;
                    }
                    else if (env.block.opSteps[i].opCode == OpCode.quit_catch)
                    {
                        l--;
                    }
                }

                if (l < 1)
                {
                    throw new BuildException(as3throw.Token.line, as3throw.Token.ptr, as3throw.Token.sourceFile,
                                             "此处不能有throw;"
                                             );
                }

                throw new BuildException(as3throw.Token.line, as3throw.Token.ptr, as3throw.Token.sourceFile,
                                         "throw必须有抛出的对象;"
                                         );

                //OpStep op = new OpStep(OpCode.raise_error, new SourceToken(as3throw.Token.line, as3throw.Token.ptr, as3throw.Token.sourceFile));

                //op.arg1 = null;
                //op.arg1Type =  RunTimeDataType.unknown;
                //op.arg2 = null;
                //op.arg2Type = RunTimeDataType.unknown;
                //op.reg = null;
                //op.regType = RunTimeDataType.unknown;

                //env.block.opSteps.Add(op);
            }
        }
Example #4
0
        private static void build_bracket_access(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1, Builder builder)
        {
            ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg);
            eax.setEAXTypeWhenCompile(RunTimeDataType.rt_void);

            var v2 = ExpressionBuilder.getRightValue(env, step.Arg3, step.token, builder);

            if (v1.valueType == RunTimeDataType.rt_void
                )
            {
                OpStep op = new OpStep(OpCode.bracket_access, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                op.reg      = eax; eax._isDotAccessTarget = true;
                op.regType  = eax.valueType;
                op.arg1     = v1;
                op.arg1Type = v1.valueType;
                op.arg2     = v2;
                op.arg2Type = v2.valueType;


                env.block.opSteps.Add(op);
            }
            else if (v1.valueType > RunTimeDataType.unknown
                     &&
                     builder.bin.dict_Vector_type.ContainsKey(builder.getClassByRunTimeDataType(v1.valueType))
                     )
            {
                ASBinCode.rtti.Class vector = builder.getClassByRunTimeDataType(v1.valueType);
                RunTimeDataType      vt     = builder.bin.dict_Vector_type[vector];

                if (v2.valueType > RunTimeDataType.unknown)
                {
                    v2 = ExpressionBuilder.addCastToPrimitive(env, v2, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile), builder);
                }

                if (v2.valueType == RunTimeDataType.rt_int ||
                    v2.valueType == RunTimeDataType.rt_number ||
                    v2.valueType == RunTimeDataType.rt_uint
                    )
                {
                    v2 = ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int,
                                                         new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                         , builder);
                    eax.setEAXTypeWhenCompile(vt);

                    {
                        OpStep op = new OpStep(OpCode.vectorAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                        op.reg      = eax; eax._isDotAccessTarget = true;
                        op.regType  = eax.valueType;
                        op.arg1     = v1;
                        op.arg1Type = v1.valueType;
                        op.arg2     = v2;
                        op.arg2Type = v2.valueType;
                        env.block.opSteps.Add(op);
                    }
                }
                else
                {
                    OpStep op = new OpStep(OpCode.vectorAccessor_convertidx, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                    op.reg      = eax; eax._isDotAccessTarget = true;
                    op.regType  = eax.valueType;
                    op.arg1     = v1;
                    op.arg1Type = v1.valueType;
                    op.arg2     = v2;
                    op.arg2Type = v2.valueType;
                    env.block.opSteps.Add(op);
                }

                //if (v2.valueType != RunTimeDataType.rt_int)
                //{
                //    v2=ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int,
                //        new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                //        , builder);
                //}

                //eax.setEAXTypeWhenCompile(vt);
                //eax._vector_Type = vt;
                //{

                //    OpStep op = new OpStep(OpCode.vectorAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                //    op.reg = eax;
                //    op.regType = eax.valueType;
                //    op.arg1 = v1;
                //    op.arg1Type = v1.valueType;
                //    op.arg2 = v2;
                //    op.arg2Type = v2.valueType;
                //    env.block.opSteps.Add(op);
                //}
            }
            else if (builder.bin.ArrayClass != null && builder.bin.ArrayClass.getRtType() == v1.valueType
                     &&
                     (v2.valueType == RunTimeDataType.rt_int ||
                      v2.valueType == RunTimeDataType.rt_number ||
                      v2.valueType == RunTimeDataType.rt_uint
                     )

                     )
            {
                v1 = builds.ExpressionBuilder.addCastToPrimitive(env, v1, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile), builder);
                v2 = ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int,
                                                     new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                     , builder);


                OpStep op = new OpStep(OpCode.arrayAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                op.reg      = eax; eax._isDotAccessTarget = true;
                op.regType  = eax.valueType;
                op.arg1     = v1;
                op.arg1Type = v1.valueType;
                op.arg2     = v2;
                op.arg2Type = v2.valueType;
                env.block.opSteps.Add(op);
            }
            else if (v1.valueType == RunTimeDataType.rt_array
                     &&
                     (v2.valueType == RunTimeDataType.rt_int ||
                      v2.valueType == RunTimeDataType.rt_number ||
                      v2.valueType == RunTimeDataType.rt_uint
                     )
                     )
            {
                v2 = ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int,
                                                     new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                     , builder);


                OpStep op = new OpStep(OpCode.arrayAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                op.reg      = eax; eax._isDotAccessTarget = true;
                op.regType  = eax.valueType;
                op.arg1     = v1;
                op.arg1Type = v1.valueType;
                op.arg2     = v2;
                op.arg2Type = v2.valueType;
                env.block.opSteps.Add(op);
            }
            else
            {
                OpStep op = new OpStep(OpCode.bracket_byname, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                op.reg      = eax; eax._isDotAccessTarget = true;
                op.regType  = eax.valueType;
                op.arg1     = v1;
                op.arg1Type = v1.valueType;
                op.arg2     = v2;
                op.arg2Type = v2.valueType;
                env.block.opSteps.Add(op);
            }
        }
Example #5
0
        private static void build_dot_name(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1)
        {
            ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg);
            eax.setEAXTypeWhenCompile(RunTimeDataType.rt_void);

            OpStep op = new OpStep(OpCode.access_dot_byname, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));

            op.reg      = eax; eax._isDotAccessTarget = true;
            op.regType  = eax.valueType;
            op.arg1     = v1;
            op.arg1Type = v1.valueType;
            op.arg2     = new ASBinCode.rtData.RightValue(
                new ASBinCode.rtData.rtString(step.Arg3.Data.Value.ToString()));
            op.arg2Type = RunTimeDataType.rt_string;
            env.block.opSteps.Add(op);
        }
Example #6
0
        private static void build_dot(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1, ASBinCode.rtti.ClassMember member)
        {
            ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg);
            eax._regMember       = member;
            eax._regMemberSrcObj = v1;

            eax.setEAXTypeWhenCompile(member.valueType);

            make_dotStep(env, member, step.token, eax, v1);

            //OpStep op = new OpStep(
            //    member.bindField is ClassMethodGetter?
            //    OpCode.access_method
            //    :
            //    OpCode.access_dot

            //    , new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
            //op.reg = eax;
            //op.regType = eax.valueType;
            //op.arg1 = v1;
            //op.arg1Type = v1.valueType;
            //op.arg2 = (IRightValue)member.bindField; //new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(member.index));
            //op.arg2Type = member.valueType; //RunTimeDataType.rt_int;

            //env.block.opSteps.Add(op);
        }
Example #7
0
        private static void build_class(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1, ASBinCode.rtti.Class cls, Builder builder)
        {
            if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier)
            {
                ASBinCode.rtti.ClassMember member = null;



                //***查找对象成员***
                member = MemberFinder.findClassMember(cls, step.Arg3.Data.Value.ToString(), env, builder);

                if (member == null)
                {
                    if (cls.dynamic
                        &&
                        cls.staticClass != null                         //***编译时检查不能向Class动态加属性。
                        )
                    {
                        //***此处编译为动态属性***
                        build_dot_name(env, step, v1);
                        return;
                    }
                }

                if (member == null)
                {
                    if (step.Arg3.Data.Value.ToString() == "hasOwnProperty"
                        )                         //***这是Object原型链对象,特殊处理
                    {
                        //***此处编译为动态属性***
                        build_dot_name(env, step, v1);
                        return;
                    }

                    if (v1 is SuperPointer)
                    {
                        throw new BuildException(
                                  new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                 "Attempted access of inaccessible property " + step.Arg3.Data.Value + " through a reference with static type " + ((SuperPointer)v1).thisClass.name + "."));
                    }
                    else
                    {
                        throw new BuildException(
                                  new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                 cls.name + "对象成员" + step.Arg3.Data.Value + "未找到"));
                    }
                }
                if (!member.isConst && env.isEval)
                {
                    throw new BuildException(
                              new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                             "Eval时忽略非Const成员"));
                }

                build_dot(env, step, v1, member);
            }
            else
            {
                throw new BuildException(
                          new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                         "静态成员名期待一个identifier"));
            }
        }
Example #8
0
        public static ASBinCode.RunTimeValueBase Eval(ASTool.AS3.AS3Expression expression,
                                                      Builder importBuilder = null
                                                      )
        {
            try
            {
                Builder builder = new Builder(new BuildOptions()
                {
                    isConsoleOut = false
                }, true);

                int bid = builder.getBlockId();

                if (importBuilder != null && importBuilder._currentImports.Count > 0)
                {
                    List <ASBinCode.rtti.Class> imps = new List <ASBinCode.rtti.Class>();
                    imps.AddRange(importBuilder._currentImports.Peek());

                    builder._currentImports.Push(imps);

                    bid = importBuilder.bin.blocks.Count;
                }

                CompileEnv tempEnv = new CompileEnv(new CodeBlock(bid, "temp", -65535, true), true);
                tempEnv.block.scope = new ASBinCode.scopes.StartUpBlockScope();
                builder.buildExpressNotEval(tempEnv, expression);

                tempEnv.completSteps(builder);
                tempEnv.block.totalStackSlots = tempEnv.combieNeedStackSlots();

                if (builder.buildErrors.Count == 0)
                {
                    RightValueBase value = builds.ExpressionBuilder.getRightValue(tempEnv, expression.Value, expression.token, builder);

                    if (player == null)
                    {
                        player = new ASRuntime.Player(null);
                    }
                    CSWC tempswc = new CSWC();
                    if (importBuilder != null)
                    {
                        tempswc.blocks.AddRange(importBuilder.bin.blocks);
                        tempswc.classes.AddRange(importBuilder.bin.classes);
                        tempswc.functions.AddRange(importBuilder.bin.functions);
                    }
                    tempswc.blocks.Add(tempEnv.block);

                    Variable variableResult = new Variable("@@", tempEnv.block.scope.members.Count, tempEnv.block.id);
                    tempEnv.block.scope.members.Add(variableResult);
                    OpStep step = new OpStep(OpCode.assigning, new SourceToken(0, 0, ""));
                    step.reg  = variableResult;
                    step.arg1 = value;
                    tempEnv.block.opSteps.Add(step);
                    tempEnv.block.instructions = tempEnv.block.opSteps.ToArray();
                    tempEnv.block.opSteps      = null;
                    player.loadCode(tempswc, tempEnv.block);

                    RunTimeValueBase result = player.run(variableResult);

                    return(result);
                    //IRunTimeScope scope = player.run();

                    //if (player.runtimeError ==null)
                    //{
                    //    return value.getValue(scope);
                    //}
                    //else
                    //{
                    //    return null;
                    //}
                }
                else
                {
                    return(null);
                }
            }
            catch (BuildException)
            {
                return(null);
            }
        }
Example #9
0
        public void buildAS3ForEach(CompileEnv env, ASTool.AS3.AS3ForEach as3foreach, Builder builder)
        {
            if (!string.IsNullOrEmpty(as3foreach.label))
            {
                //**包装一个block**
                ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3foreach.Token);
                tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>();
                tempblock.CodeList.Add(as3foreach);
                tempblock.label  = as3foreach.label;
                as3foreach.label = null;


                OpStep lbl_forlabel = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                lbl_forlabel.flag = "LOOP_LABEL_START_" + tempblock.label;
                env.block.opSteps.Add(lbl_forlabel);

                builder.buildStmt(env, tempblock);


                OpStep lbl_forlabel_end = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                lbl_forlabel_end.flag = "LOOP_LABEL_END_" + tempblock.label;
                env.block.opSteps.Add(lbl_forlabel_end);
            }
            else
            {
                int lblid = env.getLabelId();

                builder.buildStmt(env, as3foreach.ForArg);

                LeftValueBase varvalue = null;

                if (as3foreach.ForArg is ASTool.AS3.AS3StmtExpressions)
                {
                    ASTool.AS3.AS3StmtExpressions exprs = (ASTool.AS3.AS3StmtExpressions)as3foreach.ForArg;
                    if (exprs.as3exprlist.Count != 1)
                    {
                        throw new BuildException(
                                  as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile, "Syntax error: invalid for-in initializer, only 1 expression expected.");
                    }

                    ASTool.AS3.AS3Expression expr = exprs.as3exprlist[0];
                    varvalue = (LeftValueBase)ExpressionBuilder.getRightValue(env, expr.Value, expr.token, builder);
                }
                else if (as3foreach.ForArg is ASTool.AS3.AS3Variable)
                {
                    ASTool.AS3.AS3Variable v = (ASTool.AS3.AS3Variable)as3foreach.ForArg;
                    varvalue = (VariableBase)MemberFinder.find(v.Name, env, false, builder, v.token);
                }
                else
                {
                    throw new BuildException(
                              as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile, "异常错误,获得的变量类型不正确");
                }

                builder.buildExpression(env, as3foreach.ForExpr);
                RightValueBase enumerator = ExpressionBuilder.getRightValue(env, as3foreach.ForExpr.Value, as3foreach.ForExpr.token, builder);

                if (enumerator.valueType == RunTimeDataType.rt_void
                    ||
                    enumerator.valueType < RunTimeDataType.unknown
                    )
                {
                    enumerator = ExpressionBuilder.addCastOpStep(env, enumerator, RunTimeDataType._OBJECT,
                                                                 new SourceToken(as3foreach.ForExpr.token.line,
                                                                                 as3foreach.ForExpr.token.ptr,
                                                                                 as3foreach.ForExpr.token.sourceFile)
                                                                 ,
                                                                 builder);
                }

                //Register regSaveEnumerator = env.getAdditionalRegister();
                Variable varSaveEnumerator = new Variable("@saveEnumeraor_" + env.block.scope.members.Count, env.block.scope.members.Count, env.block.id);
                env.block.scope.members.Add(varSaveEnumerator);
                varSaveEnumerator.valueType = (RunTimeDataType.rt_void);
                {
                    //**IEnumerator Get And Reset();
                    OpStep opGetEnumerator = new OpStep(OpCode.foreach_get_enumerator,
                                                        new SourceToken(as3foreach.Token.line,
                                                                        as3foreach.Token.ptr,
                                                                        as3foreach.Token.sourceFile)
                                                        );

                    opGetEnumerator.reg      = varSaveEnumerator;
                    opGetEnumerator.regType  = RunTimeDataType.rt_void;
                    opGetEnumerator.arg1     = enumerator;
                    opGetEnumerator.arg1Type = enumerator.valueType;

                    env.block.opSteps.Add(opGetEnumerator);
                }

                string loopstart    = "LOOP_START_" + lblid;
                string loopbody     = "LOOP_BODY_" + lblid;
                string loopcontinue = "LOOP_CONTINUE_" + lblid;
                string loopend      = "LOOP_END_" + lblid;

                {
                    OpStep lbl_loopstart = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                    lbl_loopstart.flag = loopstart;
                    env.block.opSteps.Add(lbl_loopstart);
                }

                StackSlotAccessor eaxismovenext = env.getAdditionalRegister();
                eaxismovenext.setEAXTypeWhenCompile(RunTimeDataType.rt_boolean);
                {
                    //**IEnumerator MoveNext()
                    OpStep opMoveNext = new OpStep(OpCode.enumerator_movenext,
                                                   new SourceToken(as3foreach.Token.line,
                                                                   as3foreach.Token.ptr,
                                                                   as3foreach.Token.sourceFile)
                                                   );

                    opMoveNext.reg      = eaxismovenext;
                    opMoveNext.regType  = RunTimeDataType.rt_boolean;
                    opMoveNext.arg1     = varSaveEnumerator;
                    opMoveNext.arg1Type = varSaveEnumerator.valueType;

                    env.block.opSteps.Add(opMoveNext);
                }

                {
                    OpStep op = new OpStep(OpCode.if_jmp, new SourceToken(as3foreach.ForExpr.token.line,
                                                                          as3foreach.ForExpr.token.ptr, as3foreach.ForExpr.token.sourceFile));
                    op.reg      = null;
                    op.regType  = RunTimeDataType.unknown;
                    op.arg1     = eaxismovenext;
                    op.arg1Type = eaxismovenext.valueType;
                    op.arg2     = new ASBinCode.rtData.RightValue(
                        new ASBinCode.rtData.rtString(loopbody));
                    op.arg2Type = RunTimeDataType.rt_string;

                    env.block.opSteps.Add(op);
                }
                {
                    ASTool.AS3.AS3StmtExpressions jumptoend = new ASTool.AS3.AS3StmtExpressions(as3foreach.Token);
                    jumptoend.as3exprlist = new List <ASTool.AS3.AS3Expression>();

                    ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3foreach.Token);
                    expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();

                    ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3foreach.Token);
                    step.Type   = ASTool.AS3.Expr.OpType.GotoFlag;
                    step.OpCode = loopend;
                    expression.exprStepList.Add(step);

                    jumptoend.as3exprlist.Add(expression);
                    builder.buildStmt(env, jumptoend);
                }
                {
                    OpStep lbl_loopbody = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                    lbl_loopbody.flag = loopbody;
                    env.block.opSteps.Add(lbl_loopbody);
                }

                {
                    RightValueBase loadValue = env.getAdditionalRegister();
                    ((StackSlotAccessor)loadValue).setEAXTypeWhenCompile(RunTimeDataType.rt_void);

                    //**IEnumerator Current()
                    OpStep opCurrent = new OpStep(OpCode.enumerator_current,
                                                  new SourceToken(as3foreach.Token.line,
                                                                  as3foreach.Token.ptr,
                                                                  as3foreach.Token.sourceFile)
                                                  );

                    opCurrent.reg      = (StackSlotAccessor)loadValue;
                    opCurrent.regType  = RunTimeDataType.rt_void;
                    opCurrent.arg1     = varSaveEnumerator;
                    opCurrent.arg1Type = varSaveEnumerator.valueType;

                    env.block.opSteps.Add(opCurrent);

                    if (varvalue.valueType != RunTimeDataType.rt_void)
                    {
                        loadValue = ExpressionBuilder.addCastOpStep(env, loadValue, varvalue.valueType,
                                                                    new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)
                                                                    ,
                                                                    builder
                                                                    );
                    }

                    var op = new OpStep(OpCode.assigning, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                    op.reg      = varvalue;
                    op.regType  = varvalue.valueType;
                    op.arg1     = loadValue;
                    op.arg1Type = loadValue.valueType;
                    op.arg2     = null;
                    op.arg2Type = RunTimeDataType.unknown;

                    env.block.opSteps.Add(op);
                }
                if (as3foreach.Body != null)
                {
                    for (int i = 0; i < as3foreach.Body.Count; i++)
                    {
                        builder.buildStmt(env, as3foreach.Body[i]);
                    }
                }
                {
                    OpStep lbl_loopcontinue = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                    lbl_loopcontinue.flag = loopcontinue;
                    env.block.opSteps.Add(lbl_loopcontinue);
                }
                {
                    //强行跳回开始
                    ASTool.AS3.AS3StmtExpressions jumptostart = new ASTool.AS3.AS3StmtExpressions(as3foreach.Token);
                    jumptostart.as3exprlist = new List <ASTool.AS3.AS3Expression>();

                    ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3foreach.Token);
                    expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList();

                    ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3foreach.Token);
                    step.Type   = ASTool.AS3.Expr.OpType.GotoFlag;
                    step.OpCode = loopstart;
                    expression.exprStepList.Add(step);

                    jumptostart.as3exprlist.Add(expression);
                    builder.buildStmt(env, jumptostart);
                }
                {
                    //结束标记
                    OpStep lbl_loopend = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                    lbl_loopend.flag = loopend;
                    env.block.opSteps.Add(lbl_loopend);
                }
                {
                    OpStep opClose = new OpStep(OpCode.enumerator_close, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile));
                    opClose.reg      = null;
                    opClose.regType  = RunTimeDataType.unknown;
                    opClose.arg1     = varSaveEnumerator;
                    opClose.arg1Type = RunTimeDataType.rt_void;
                    opClose.arg2     = null;
                    opClose.arg2Type = RunTimeDataType.rt_void;

                    env.block.opSteps.Add(opClose);
                }
            }
        }