Exemplo n.º 1
0
        private SLOT _getArgementSlot(int id)
        {
            var signature = toCallFunc.signature;

            if (signature.onStackParameters > 0)
            {
                ASBinCode.rtti.FunctionParameter fp = signature.parameters[id];

                if (fp.isOnStack)
                {
                    StackSlotAccessor r = (StackSlotAccessor)fp.varorreg;
                    //int index = invokerFrame.offset + invokerFrame.block.totalRegisters + 1 + 1 + invokerFrame.call_parameter_slotCount + r._index;
                    int index = invokerFrame.baseBottomSlotIndex + invokerFrame.call_parameter_slotCount + r._index;
                    return(invokerFrame.stack[index]);
                }
                else
                {
                    return(CallFuncHeap[((Variable)fp.varorreg).indexOfMembers]);
                }
            }
            else
            {
                return(CallFuncHeap[id]);
            }
        }
Exemplo n.º 2
0
        private void _storeArgementToSlot(int id,RunTimeValueBase v)
        {
            var signature = toCallFunc.signature;

            if (signature.onStackParameters > 0)
            {
                ASBinCode.rtti.FunctionParameter fp = signature.parameters[id];

                if (fp.isOnStack)
                {
                    StackSlotAccessor r = (StackSlotAccessor)fp.varorreg;
                    //int index = invokerFrame.offset + invokerFrame.block.totalRegisters + 1 + 1+ invokerFrame.call_parameter_slotCount + r._index;
                    int index = invokerFrame.baseBottomSlotIndex + invokerFrame.call_parameter_slotCount + r._index;
                    invokerFrame.stack[index].directSet(v);
                }
                else
                {
                    CallFuncHeap[((Variable)fp.varorreg).indexOfMembers].directSet(
                        v

                        );
                }
            }
            else
            {
                CallFuncHeap[id].directSet(v);
            }
        }
        private static void _execSuffixDec_toString_Callbacker(ASBinCode.RunTimeValueBase v1, ASBinCode.RunTimeValueBase v2,
                                                               StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope)
        {
            double n = TypeConverter.ConvertToNumber(v1);

            step.reg.getSlot(scope, frame).setValue(n);

            ASBinCode.rtData.rtNumber num      = new ASBinCode.rtData.rtNumber(--n);
            StackSlotAccessor         register = step.arg1 as StackSlotAccessor;

            if (register != null)
            {
                bool issuccess;
                register.getSlotForAssign(scope, frame).assign(num, out issuccess);
                if (!issuccess)
                {
                    frame.throwError(step.token, 0, "操作失败");
                }
            }
            else
            {
                ((ASBinCode.LeftValueBase)step.arg1).getSlot(scope, frame).directSet(num);
            }


            frame.endStep(step);
        }
Exemplo n.º 4
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 static void _execSuffixInc_ValueOf_Callbacker(ASBinCode.RunTimeValueBase v1, ASBinCode.RunTimeValueBase v2,
                                                              StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope)
        {
            if (v1.rtType > ASBinCode.RunTimeDataType.unknown)
            {
                OpCast.InvokeTwoToString(v1, ASBinCode.rtData.rtNull.nullptr,
                                         frame, step.token, scope, frame._tempSlot1, frame._tempSlot2,
                                         step, _execSuffixInc_toString_Callbacker);
            }
            else
            {
                double n = TypeConverter.ConvertToNumber(v1);

                step.reg.getSlot(scope, frame).setValue(n);

                ASBinCode.rtData.rtNumber num = new ASBinCode.rtData.rtNumber(++n);

                StackSlotAccessor register = step.arg1 as StackSlotAccessor;
                if (register != null)
                {
                    bool issuccess;
                    ((StackSlot)register.getSlotForAssign(scope, frame)).assign(num, out issuccess);
                    if (!issuccess)
                    {
                        frame.throwError(step.token, 0, "操作失败");
                    }
                }
                else
                {
                    ((ASBinCode.LeftValueBase)step.arg1).getSlot(scope, frame).directSet(num);
                }

                frame.endStep(step);
            }
        }
        public static void execDecInt(StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope)
        {
            var v = step.arg1.getValue(scope, frame);
            StackSlotAccessor register = step.arg1 as StackSlotAccessor;

            if (register != null)
            {
                ((StackSlot)register.getSlotForAssign(scope, frame)).linkTo(null);
            }
            {
                ASBinCode.rtData.rtInt iv = (ASBinCode.rtData.rtInt)v;
                iv.value--;
                ((LeftValueBase)step.arg1).getSlot(scope, frame).directSet(iv);
                ((ASBinCode.LeftValueBase)step.reg).getSlot(scope, frame).setValue(iv.value);
            }
            //frame.endStep(step);
            frame.endStepNoError();
        }
Exemplo n.º 7
0
        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 build_class(CompileEnv env,
                                ASBinCode.rtti.Class _class,
                                ASTool.Token token, Builder builder,
                                StackSlotAccessor outeax,
                                List <ASTool.AS3.Expr.AS3DataStackElement> args
                                )
        {
            //***查找构造函数**
            if (_class.constructor != null)
            {
                MethodGetterBase field = (MethodGetterBase)_class.constructor.bindField; //(Field)builder._classbuildingEnv[_class].block.scope.members[_class.constructor.index];
                int blockid            = field.refdefinedinblockid;

                var signature =
                    builder.dictSignatures[blockid][field];

                FuncCallBuilder funcbuilder = new FuncCallBuilder();
                funcbuilder.createParaOp(args, signature, token, env, field, builder, true, _class);
            }
            else
            {
                OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_argement,
                                               new SourceToken(token.line, token.ptr, token.sourceFile));
                opMakeArgs.arg1     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(_class.classid));
                opMakeArgs.arg1Type = RunTimeDataType.rt_int;
                env.block.opSteps.Add(opMakeArgs);
            }

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

            op.arg1     = new RightValue(new rtInt(_class.classid));
            op.arg1Type = _class.getRtType();

            outeax.setEAXTypeWhenCompile(_class.getRtType());
            op.reg     = outeax;
            op.regType = _class.getRtType();

            env.block.opSteps.Add(op);
        }
        public static void exec_link(StackFrame frame, OpStep step, RunTimeScope scope)
        {
            StackSlot l = (StackSlot)step.reg.getSlot(scope, frame);

            int classid = ((ASBinCode.rtData.rtInt)step.arg2.getValue(scope, frame)).value;

            var outscope = frame.player.outpackage_runtimescope[classid];

            SLOT outpackagescopeslot = ((VariableBase)step.arg1).getSlot(outscope,null);

            StackSlotAccessor register = (StackSlotAccessor)step.reg;

            if (register._isassigntarget || register._hasUnaryOrShuffixOrDelete)
            {
                l.linkTo(outpackagescopeslot);
            }
            else
            {
                l.directSet(outpackagescopeslot.getValue());
            }
            frame.endStep(step);
        }
        public static void execIncrement(StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope)
        {
            var v = step.arg1.getValue(scope, frame);

            StackSlotAccessor register = step.arg1 as StackSlotAccessor;

            if (register != null)
            {
                ((StackSlot)register.getSlotForAssign(scope, frame)).linkTo(null);
            }

            switch (v.rtType)
            {
            case ASBinCode.RunTimeDataType.rt_int:
            {
                ASBinCode.rtData.rtInt iv = (ASBinCode.rtData.rtInt)v;
                iv.value++;
                ((LeftValueBase)step.arg1).getSlot(scope, frame).directSet(iv);
                step.reg.getSlot(scope, frame).setValue(iv.value);
            }
            break;

            case ASBinCode.RunTimeDataType.rt_uint:
            {
                ASBinCode.rtData.rtUInt iv = (ASBinCode.rtData.rtUInt)v;
                iv.value++;
                ((LeftValueBase)step.arg1).getSlot(scope, frame).directSet(iv);
                step.reg.getSlot(scope, frame).setValue(iv.value);
            }
            break;

            case ASBinCode.RunTimeDataType.rt_number:
            {
                ASBinCode.rtData.rtNumber iv = (ASBinCode.rtData.rtNumber)v;
                iv.value++;
                ((LeftValueBase)step.arg1).getSlot(scope, frame).directSet(iv);
                step.reg.getSlot(scope, frame).setValue(iv.value);
            }
            break;

            case ASBinCode.RunTimeDataType.rt_string:

            {
                double n = TypeConverter.ConvertToNumber(v);
                if (string.IsNullOrEmpty(((ASBinCode.rtData.rtString)v).value))
                {
                    n = 0;
                }

                ASBinCode.rtData.rtNumber num = new ASBinCode.rtData.rtNumber(++n);
                step.reg.getSlot(scope, frame).directSet(num);
            }
            break;

            case ASBinCode.RunTimeDataType.rt_boolean:
            case ASBinCode.RunTimeDataType.rt_void:
            case ASBinCode.RunTimeDataType.rt_null:
            {
                double n = TypeConverter.ConvertToNumber(v);
                ASBinCode.rtData.rtNumber num = new ASBinCode.rtData.rtNumber(++n);
                ((ASBinCode.LeftValueBase)step.reg).getSlot(scope, frame).directSet(num);
            }
            break;

            case ASBinCode.RunTimeDataType.unknown:
            default:
            {
                OpCast.InvokeTwoValueOf(v, ASBinCode.rtData.rtNull.nullptr, frame, step.token,
                                        scope, frame._tempSlot1,
                                        frame._tempSlot2, step, _execIncrement_ValueOf_Callbacker);
                return;
            }
            }

            //frame.endStep(step);
            frame.endStepNoError();
        }
Exemplo n.º 11
0
        private void build_class(CompileEnv env,
                                 ASBinCode.rtti.Class _class,
                                 ASTool.AS3.Expr.AS3ExprStep step, Builder builder)
        {
            //***参数检查***



            List <ASTool.AS3.Expr.AS3DataStackElement> args;

            if (!step.Arg2.IsReg && step.Arg2.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.as3_vector)
            {
                ASTool.AS3.AS3Vector vector = (ASTool.AS3.AS3Vector)step.Arg2.Data.Value;



                if (vector.Constructor == null)
                {
                    args = new List <ASTool.AS3.Expr.AS3DataStackElement>();
                }
                else
                {
                    if (vector.isInitData)
                    {
                        args = new List <ASTool.AS3.Expr.AS3DataStackElement>();
                    }
                    else
                    {
                        args = (List <ASTool.AS3.Expr.AS3DataStackElement>)vector.Constructor.Data.Value;
                    }
                }
            }
            else
            {
                if (step.Arg3 != null)
                {
                    args = (List <ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value;
                }
                else
                {
                    args = new List <ASTool.AS3.Expr.AS3DataStackElement>();
                }
            }

            StackSlotAccessor insEax = env.createASTRegister(step.Arg1.Reg);

            build_class(env, _class, step.token, builder,
                        insEax,
                        args
                        );

            if (!step.Arg2.IsReg && step.Arg2.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.as3_vector)
            {
                ASTool.AS3.AS3Vector vector = (ASTool.AS3.AS3Vector)step.Arg2.Data.Value;
                if (vector.Constructor != null && vector.isInitData)
                {
                    //***追加初始化Vector***
                    var initdata = (List <ASTool.AS3.Expr.AS3DataStackElement>)vector.Constructor.Data.Value;

                    var vt = builder.bin.dict_Vector_type[_class];

                    for (int i = 0; i < initdata.Count; i++)
                    {
                        var d = ExpressionBuilder.getRightValue(env, initdata[i], step.token, builder);

                        if (!ASRuntime.TypeConverter.testImplicitConvert(d.valueType, vt, builder))
                        {
                            throw(new BuildException(new BuildError(step.token.line, step.token.ptr, step.token.sourceFile,
                                                                    "不能将[" + d.valueType + "]类型存入Vector.<" + vt + ">")));
                        }

                        if (d.valueType != vt)
                        {
                            d = ExpressionBuilder.addCastOpStep(env, d, vt,
                                                                new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)
                                                                , builder);
                        }

                        OpStep oppush = new OpStep(OpCode.vector_push, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
                        oppush.reg      = null;
                        oppush.regType  = RunTimeDataType.unknown;
                        oppush.arg1     = insEax;
                        oppush.arg1Type = insEax.valueType;
                        oppush.arg2     = d;
                        oppush.arg2Type = d.valueType;

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



                    //throw new NotImplementedException();
                }
            }


            ////***查找构造函数**
            //if (_class.constructor != null)
            //{
            //    ClassMethodGetter field = (ClassMethodGetter)_class.constructor.bindField; //(Field)builder._classbuildingEnv[_class].block.scope.members[_class.constructor.index];
            //    int blockid = field.refdefinedinblockid;

            //    var signature =
            //            builder.dictSignatures[blockid][field];
            //    //***参数检查***
            //    List<ASTool.AS3.Expr.AS3DataStackElement> args;
            //    if (step.Arg3 != null)
            //    {
            //        args = (List<ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value;
            //    }
            //    else
            //    {
            //        args = new List<ASTool.AS3.Expr.AS3DataStackElement>();
            //    }
            //    FuncCallBuilder funcbuilder = new FuncCallBuilder();
            //    funcbuilder.createParaOp(args, signature, step, env, field, builder, true, _class);
            //}
            //else
            //{
            //    OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_argement,
            //        new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
            //    opMakeArgs.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(_class.classid));
            //    opMakeArgs.arg1Type = RunTimeDataType.rt_int;
            //    env.block.opSteps.Add(opMakeArgs);
            //}

            //OpStep op = new OpStep(OpCode.new_instance, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile));
            //op.arg1 = new RightValue(new rtInt(_class.classid));
            //op.arg1Type = _class.getRtType();
            //Register eax = env.createASTRegister(step.Arg1.Reg.ID);
            //eax.setEAXTypeWhenCompile(_class.getRtType());
            //op.reg = eax;
            //op.regType = _class.getRtType();

            //env.block.opSteps.Add(op);
        }
Exemplo n.º 12
0
        public void build_class(CompileEnv env,
                                ASBinCode.rtti.Class _class,
                                ASTool.Token token, Builder builder,
                                StackSlotAccessor outeax,
                                List <ASTool.AS3.Expr.AS3DataStackElement> args
                                )
        {
            var _cls = _class;

            if (_cls.staticClass == null)
            {
                _cls = _cls.instanceClass;
            }
            if (_cls.isLink_System)
            {
                OpStep stepInitClass = new OpStep(OpCode.init_staticclass,
                                                  new SourceToken(token.line, token.ptr, token.sourceFile));
                stepInitClass.arg1 = new ASBinCode.rtData.RightValue(
                    new ASBinCode.rtData.rtInt(_cls.classid));
                stepInitClass.arg1Type = _cls.staticClass.getRtType();
                env.block.opSteps.Add(stepInitClass);
            }

            //***查找构造函数**
            if (_class.constructor != null)
            {
                MethodGetterBase field = (MethodGetterBase)_class.constructor.bindField; //(Field)builder._classbuildingEnv[_class].block.scope.members[_class.constructor.index];
                int blockid            = field.refdefinedinblockid;

                var signature =
                    builder.dictSignatures[blockid][field];

                FuncCallBuilder funcbuilder = new FuncCallBuilder();
                OpStep          opMakeArgs  = null;
                funcbuilder.createParaOp(out opMakeArgs, args, signature, token, env, field, builder, true, _class);

                if (_cls.isLink_System)
                {
                    if (signature.parameters.Count == 0)
                    {
                        opMakeArgs.opCode    = OpCode.prepare_constructor_argement_linksystem;
                        opMakeArgs.memregid1 = 0;
                    }
                    else
                    {
                        bool canconvert = true;
                        for (int i = 0; i < signature.parameters.Count; i++)
                        {
                            if (signature.parameters[i].defaultValue != null || signature.parameters[i].isPara)
                            {
                                canconvert = false;
                            }
                        }
                        if (canconvert)
                        {
                            opMakeArgs.opCode    = OpCode.prepare_constructor_argement_linksystem;
                            opMakeArgs.memregid1 = (short)signature.parameters.Count;
                        }
                    }
                }
            }
            else
            {
                OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_argement,
                                               new SourceToken(token.line, token.ptr, token.sourceFile));
                opMakeArgs.arg1     = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(_class.classid));
                opMakeArgs.arg1Type = RunTimeDataType.rt_int;
                env.block.opSteps.Add(opMakeArgs);

                if (_cls.isLink_System)
                {
                    opMakeArgs.opCode    = OpCode.prepare_constructor_argement_linksystem;
                    opMakeArgs.memregid1 = 0;
                }
            }

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

            op.arg1     = new RightValue(new rtInt(_class.classid));
            op.arg1Type = _class.getRtType();

            outeax.setEAXTypeWhenCompile(_class.getRtType());
            op.reg     = outeax;
            op.regType = _class.getRtType();

            env.block.opSteps.Add(op);
        }
        public static void exec_AccessorBind_ConvertIdx(StackFrame frame, OpStep step, RunTimeScope scope)
        {
            RunTimeValueBase obj = step.arg1.getValue(scope, frame);

            if (rtNull.nullptr.Equals(obj))
            {
                frame.throwError(

                    step.token, 1009, "Cannot access a property or method of a null object reference."

                    );
                frame.endStep();
                return;
            }
            ASBinCode.rtti.Vector_Data vector =
                (ASBinCode.rtti.Vector_Data)((ASBinCode.rtti.HostedObject)((ASBinCode.rtData.rtObjectBase)obj).value).hosted_object;


            var idxvalue = step.arg2.getValue(scope, frame);

            double idx = double.NaN;

            if (idxvalue.rtType > RunTimeDataType.unknown)
            {
                RunTimeDataType ot;
                if (TypeConverter.Object_CanImplicit_ToPrimitive(idxvalue.rtType, frame.player.swc, out ot))
                {
                    var v = TypeConverter.ObjectImplicit_ToPrimitive((rtObjectBase)idxvalue);
                    idx = TypeConverter.ConvertToNumber(v);
                }
            }
            else if (idxvalue.rtType == RunTimeDataType.rt_string ||
                     idxvalue.rtType == RunTimeDataType.rt_int ||
                     idxvalue.rtType == RunTimeDataType.rt_number ||
                     idxvalue.rtType == RunTimeDataType.rt_uint
                     )
            {
                idx = TypeConverter.ConvertToNumber(idxvalue);
            }

            if (double.IsNaN(idx))
            {
                frame.throwError(

                    step.token, 0,
                    "索引" + idxvalue + "不能转为int"

                    );
            }
            else
            {
                int index = (int)idx;

                if (index < 0 || index > vector.innnerList.Count)
                {
                    frame.throwError(step.token, 1125,
                                     "The index " + index + " is out of range " + vector.innnerList.Count + ".");
                }

                StackSlotAccessor reg = (StackSlotAccessor)step.reg;

                if (idx == vector.innnerList.Count)
                {
                    if (vector.isFixed || !reg._isassigntarget)
                    {
                        frame.throwError(step.token,
                                         1125,
                                         "The index " + idx + " is out of range " + vector.innnerList.Count + ".");
                        frame.endStep(step);
                        return;
                    }
                    else
                    {
                        vector.innnerList.Add(TypeConverter.getDefaultValue(vector.vector_type).getValue(null, null));
                    }
                }


                StackSlot slot = (StackSlot)step.reg.getSlot(scope, frame);

                if (reg._isassigntarget || reg._hasUnaryOrShuffixOrDelete)
                {
                    slot._cache_vectorSlot.idx         = index;
                    slot._cache_vectorSlot.vector_data = vector;

                    slot.linkTo(slot._cache_vectorSlot);
                }
                else
                {
                    slot.directSet(vector.innnerList[index]);
                }
            }


            frame.endStep(step);
        }
        public static void exec_AccessorBind(StackFrame frame, OpStep step, RunTimeScope scope)
        {
            RunTimeValueBase obj = step.arg1.getValue(scope, frame);

            if (rtNull.nullptr.Equals(obj))
            {
                frame.throwError(

                    step.token, 1009, "Cannot access a property or method of a null object reference."

                    );
                frame.endStep();
                return;
            }


            ASBinCode.rtti.Vector_Data vector =
                (ASBinCode.rtti.Vector_Data)((ASBinCode.rtti.HostedObject)((rtObjectBase)obj).value).hosted_object;

            int idx = TypeConverter.ConvertToInt(step.arg2.getValue(scope, frame));

            if (idx < 0 || idx > vector.innnerList.Count)
            {
                frame.throwError(step.token, 1125,
                                 "The index " + idx + " is out of range " + vector.innnerList.Count + ".");
            }

            StackSlotAccessor reg = (StackSlotAccessor)step.reg;

            if (idx == vector.innnerList.Count)
            {
                if (vector.isFixed || !reg._isassigntarget)
                {
                    frame.throwError(step.token, 1125,
                                     "The index " + idx + " is out of range " + vector.innnerList.Count + "."
                                     );
                    frame.endStep(step);
                    return;
                }
                else
                {
                    vector.innnerList.Add(TypeConverter.getDefaultValue(vector.vector_type).getValue(null, null));
                }
            }



            StackSlot slot = (StackSlot)step.reg.getSlot(scope, frame);

            if (reg._isassigntarget || reg._hasUnaryOrShuffixOrDelete)
            {
                slot._cache_vectorSlot.idx         = idx;
                slot._cache_vectorSlot.vector_data = vector;

                slot.linkTo(slot._cache_vectorSlot);
            }
            else
            {
                slot.directSet(vector.innnerList[idx]);
            }

            frame.endStep(step);
        }
Exemplo n.º 15
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);
                }
            }
        }