Beispiel #1
0
        public static CodeBlock Deserialize(BinaryReader reader, CSWCSerizlizer serizlizer, IDictionary <int, object> serizlized, int key)
        {
            var id              = reader.ReadInt32();
            var name            = reader.ReadString();   //writer.Write(name);
            var define_class_id = reader.ReadInt32();    //writer.Write(define_class_id);
            var isoutclass      = reader.ReadBoolean();  //writer.Write(isoutclass);
            var hasTryStmt      = reader.ReadBoolean();  // writer.Write(hasTryStmt);

            CodeBlock block = new CodeBlock(id, name, define_class_id, isoutclass);

            block.hasTryStmt = hasTryStmt;
            serizlized.Add(key, block);

            block.totalStackSlots = reader.ReadUInt16();
            block.scope           = serizlizer.DeserializeObject <scopes.ScopeBase>(reader, scopes.ScopeBase.Deserialize);

            int stepscount = reader.ReadUInt16();

            block.instructions = new OpStep[stepscount]; block.opSteps = null;
            for (int i = 0; i < stepscount; i++)
            {
                OpStep step = serizlizer.DeserializeObject <OpStep>(reader, OpStep.Deserialize);
                //block.opSteps.Add(step);
                block.instructions[i] = step;
            }

            int regconvcount = reader.ReadUInt16();

            block.regConvFromVar = new StackSlotAccessor[regconvcount];
            for (int i = 0; i < regconvcount; i++)
            {
                StackSlotAccessor register = (StackSlotAccessor)serizlizer.DeserializeObject <ISWCSerializable>(reader, ISWCSerializableLoader.LoadIMember);
                block.regConvFromVar[i] = register;
            }

            return(block);
        }
        public static void clear_thispointer(StackFrame frame, ASBinCode.OpStep step, RunTimeScope scope)
        {
            RunTimeValueBase rv;
            rtFunction       toclear = null;

            if (step.arg1 is MethodGetterBase)
            {
                rv      = ((ClassMethodGetter)step.arg1).getMethodForClearThis(frame.scope);
                toclear = (rtFunction)rv;
            }
            else
            {
                rv = step.arg1.getValue(frame.scope, frame);
            }

            if (rv.rtType > RunTimeDataType.unknown && ClassMemberFinder.check_isinherits(rv, RunTimeDataType._OBJECT + 2, frame.player.swc))
            {
                //***说明要调用强制类型转换***
                ASBinCode.rtti.Class cls = ((rtObjectBase)rv).value._class;

                if (cls.explicit_from != null)
                {
                    var member = (MethodGetterBase)cls.explicit_from.bindField;
                    var func   = member.getValue(((rtObjectBase)rv).objScope, null);

                    step.reg.getSlot(scope, frame).directSet(func);
                }
                else if (cls.implicit_from != null)
                {
                    var member = (MethodGetterBase)cls.implicit_from.bindField;
                    var func   = member.getValue(((rtObjectBase)rv).objScope, null);

                    step.reg.getSlot(scope, frame).directSet(func);
                }
                else
                {
                    frame.typeconvertoperator            = new typeConvertOperator();
                    frame.typeconvertoperator.targettype = cls;

                    step.reg.getSlot(scope, frame).directSet(rv);
                }

                if (toclear != null)
                {
                    toclear.Clear();
                }

                frame.endStepNoError();
                //frame.endStep(step);
                return;
            }


            if (rv.rtType != RunTimeDataType.rt_function)
            {
                frame.throwError(
                    step.token, 0, "value is not a function");
                if (toclear != null)
                {
                    toclear.Clear();
                }

                frame.endStep(step);
                return;
            }
            else
            {
                ASBinCode.rtData.rtFunction function = (ASBinCode.rtData.rtFunction)rv;

                step.reg.getSlot(scope, frame).directSet(rv);

                if (!function.ismethod)
                {
                    int          classid = ((ASBinCode.rtData.rtInt)step.arg2.getValue(scope, frame)).value;
                    RunTimeScope o;
                    if (frame.player.outpackage_runtimescope.TryGetValue(classid, out o))
                    {
                        _do_clear_thispointer(frame.player, (ASBinCode.rtData.rtFunction)step.reg.getValue(scope, frame), frame, o.this_pointer);
                    }
                }

                if (toclear != null)
                {
                    toclear.Clear();
                }

                frame.endStepNoError();
            }
        }
        public static void create_paraScope_WithSignature_NoParameters(StackFrame frame, ASBinCode.OpStep step, RunTimeScope scope)
        {
            rtFunction function
                = (rtFunction)step.arg1.getValue(frame.scope, frame);

            var functionDefine = frame.player.swc.functions[function.functionId];

            var funcCaller = frame.player.funcCallerPool.create(frame, step.token);

            funcCaller.SetFunction(function); function.Clear();
            funcCaller.toCallFunc   = functionDefine;
            frame.funCaller         = funcCaller;
            funcCaller.CallFuncHeap = Player.emptyMembers;

            frame.endStepNoError();
        }
Beispiel #4
0
        public static void exec(StackFrame frame, ASBinCode.OpStep step, RunTimeScope scope)
        {
#if DEBUG
            #region 函数调用检查  现基本不需要了
            //         RunTimeValueBase rv;rtFunction toclear = null;
            //if (step.arg1 is MethodGetterBase)
            //{
            //	rv = ((MethodGetterBase)step.arg1).getMethod(frame.scope); toclear = (rtFunction)rv;
            //}

            //else
            //{
            //	rv = step.arg1.getValue(frame.scope, frame);
            //}
            //         if (rv.rtType == frame.player.swc.FunctionClass.getRtType())
            //         {
            //             rv = TypeConverter.ObjectImplicit_ToPrimitive((rtObject)rv);
            //         }
            //         if (rv.rtType > RunTimeDataType.unknown && ClassMemberFinder.check_isinherits(rv, RunTimeDataType._OBJECT + 2, frame.player.swc))
            //         {
            //             //***说明要调用强制类型转换***
            //             ASBinCode.rtti.Class cls = ((rtObject)rv).value._class;
            //             if (frame.typeconvertoperator == null || frame.typeconvertoperator.targettype != cls

            //                 )
            //             {
            //                 frame.throwError(new error.InternalError(frame.player.swc, step.token, "应该是强制类型转换,内部异常"));

            //                 frame.endStep(step);
            //                 return;
            //             }
            //             else if (frame.typeconvertoperator.inputvalue == null)
            //             {
            //                 frame.throwError(step.token,0, "Argument count mismatch on class coercion.  Expected 1, got 0."
            //                     );

            //                 frame.endStep(step);
            //                 return;
            //             }
            //         }
            //         else
            //         {
            //             if (rv.rtType != RunTimeDataType.rt_function)
            //             {
            //                 frame.throwError(step.token,0, "value is not a function"
            //                     );

            //                 frame.endStep(step);
            //                 return;
            //             }

            //             ASBinCode.rtData.rtFunction function = (ASBinCode.rtData.rtFunction)rv;
            //             ASBinCode.rtti.FunctionDefine funcDefine = frame.player.swc.functions[function.functionId];


            //             if (!frame.funCaller.isFuncEquals(function))
            //             {
            //		if (toclear != null) { toclear.Clear(); }
            //                 frame.throwError(new error.InternalError(frame.player.swc, step.token, "运行时异常,调用函数不对"));
            //                 frame.endStep(step);
            //                 return;
            //             }
            //         }
            #endregion
#endif

            if (frame.typeconvertoperator == null)
            {
                var funCaller = frame.funCaller;
                funCaller.callbacker = funCaller;
                funCaller.returnSlot = step.reg.getSlot(frame.scope, frame);
                funCaller.call();

                frame.funCaller = null;
            }
            else
            {
                if (frame.typeconvertoperator.targettype.instanceClass == null)
                {
                    frame.throwError(new error.InternalError(frame.player.swc, step.token, "强制类型转换类型错误",
                                                             new ASBinCode.rtData.rtString("强制类型转换类型错误")));

                    frame.endStep(step);
                    return;
                }
                else
                {
                    BlockCallBackBase cb = frame.player.blockCallBackPool.create();
                    cb.step = step;
                    cb.args = frame;
                    cb.setCallBacker(_convert_cb);



                    OpCast.CastValue(frame.typeconvertoperator.inputvalue,
                                     frame.typeconvertoperator.targettype.instanceClass.getRtType(),
                                     frame, step.token, frame.scope, step.reg.getSlot(frame.scope, frame),
                                     cb,
                                     false);
                    frame.typeconvertoperator = null;
                }
            }
        }
Beispiel #5
0
        public static OpStep Deserialize(BinaryReader reader, CSWCSerizlizer serizlizer, IDictionary <int, object> serizlized, int key)
        {
            //public OpCode opCode;
            OpCode opCode = (OpCode)reader.ReadByte();
            //	public SourceToken token;
            SourceToken token = serizlizer.DeserializeObject <SourceToken>(reader, SourceToken.LoadToken);

            OpStep step = new OpStep(opCode, token); serizlized.Add(key, step);

            ///// <summary>
            ///// 行标
            ///// </summary>
            //public string flag;
            if (reader.ReadBoolean())
            {
                step.flag = reader.ReadString();
            }

            ///// <summary>
            ///// 跳转偏移量
            ///// </summary>
            //public int jumoffset;
            step.jumoffset = reader.ReadInt32();
            ///// <summary>
            ///// 所属标签
            ///// </summary>
            //public Stack<string> labels;

            if (reader.ReadBoolean())
            {
                step.labels = new Stack <string>();
                int count = reader.ReadInt32();
                for (int i = 0; i < count; i++)
                {
                    step.labels.Push(reader.ReadString());
                }
            }

            //string[] lbls = labels.ToArray();
            //writer.Write(lbls.Length);
            //for (int i = 0; i < lbls.Length; i++)
            //{
            //	writer.Write(lbls[i]);
            //}



            ///// <summary>
            ///// 当前行在哪个try块里
            ///// -1表示不在任何try块里
            ///// </summary>
            //public int tryid;
            step.tryid = reader.ReadInt32();
            ///// <summary>
            ///// 当前块所属try类型
            ///// 0 try 1 catch 2 finally
            ///// </summary>
            //public int trytype;
            step.trytype = reader.ReadInt32();

            //public LeftValueBase reg;
            step.reg = (LeftValueBase)serizlizer.DeserializeObject <ISWCSerializable>(reader, ISWCSerializableLoader.LoadIMember);
            //public RightValueBase arg1;
            step.arg1 = (RightValueBase)serizlizer.DeserializeObject <ISWCSerializable>(reader, ISWCSerializableLoader.LoadIMember);
            //public RightValueBase arg2;
            step.arg2 = (RightValueBase)serizlizer.DeserializeObject <ISWCSerializable>(reader, ISWCSerializableLoader.LoadIMember);

            ///// <summary>
            ///// 输出结果类型
            ///// </summary>
            //public RunTimeDataType regType;
            step.regType = reader.ReadInt32();
            ///// <summary>
            ///// 输入参数1类型
            ///// </summary>
            //public RunTimeDataType arg1Type;
            step.arg1Type = reader.ReadInt32();
            ///// <summary>
            ///// 输入参数2类型
            ///// </summary>
            //public RunTimeDataType arg2Type;
            step.arg2Type = reader.ReadInt32();


            step.memregid1 = reader.ReadInt16();
            step.memregid2 = reader.ReadInt16();
            step.memregid3 = reader.ReadInt16();

            step.constnumber1 = reader.ReadDouble();
            step.constnumber2 = reader.ReadDouble();

            return(step);
        }
Beispiel #6
0
        public static void create_paraScope_Method_NotNativeConstPara_AllParaOnStack(StackFrame frame, ASBinCode.OpStep step, RunTimeScope scope)
        {
            rtFunction function
                = (rtFunction)((MethodGetterBase)step.arg1).getMethod(frame.scope);

            var functionDefine = frame.player.swc.functions[function.functionId];

            if (frame.baseBottomSlotIndex + frame.call_parameter_slotCount + functionDefine.signature.onStackParameters >= Player.STACKSLOTLENGTH)
            {
                frame.throwError(new error.InternalError(frame.player.swc, step.token, "stack overflow"));
                frame.endStep();
                return;
            }

            var funcCaller = frame.player.funcCallerPool.create(frame, step.token);

            funcCaller.SetFunction(function); function.Clear();
            funcCaller.toCallFunc = functionDefine;
            frame.funCaller       = funcCaller;

            frame.call_parameter_slotCount  += functionDefine.signature.onStackParameters;
            funcCaller.onstackparametercount = functionDefine.signature.onStackParameters;
            funcCaller.CallFuncHeap          = Player.emptyMembers;

            var parameters = functionDefine.signature.parameters; int len = parameters.Count; int parast = frame.baseBottomSlotIndex + frame.call_parameter_slotCount;

            for (int i = step.jumoffset; i < len; i++)
            {
                var parameter = parameters[i];
                if (parameter.defaultValue != null)
                {
                    var dv = FunctionCaller.getDefaultParameterValue(parameter.type, parameter.defaultValue.getValue(null, null));

                    frame.stack[parast - i - 1].directSet(dv);
                    //_storeArgementToSlot(i, dv);
                }
                else if (parameter.isPara)
                {
                    frame.stack[parast - i - 1].directSet(new ASBinCode.rtData.rtArray());
                    //_storeArgementToSlot(i, new ASBinCode.rtData.rtArray());
                }
            }



            frame.endStepNoError();
        }
Beispiel #7
0
        public static void create_paraScope(StackFrame frame, ASBinCode.OpStep step, RunTimeScope scope)
        {
            RunTimeValueBase rv; rtFunction toclear = null;

            if (step.arg1 is MethodGetterBase)
            {
                rv = ((MethodGetterBase)step.arg1).getMethod(frame.scope); toclear = (rtFunction)rv;
            }
            else
            {
                rv = step.arg1.getValue(frame.scope, frame);
            }

            if (rv.rtType > RunTimeDataType.unknown && ClassMemberFinder.check_isinherits(rv, RunTimeDataType._OBJECT + 2, frame.player.swc))
            {
                //***说明要调用强制类型转换***
                ASBinCode.rtti.Class cls = ((rtObjectBase)rv).value._class;
                if (frame.typeconvertoperator != null)
                {
                    frame.endStepNoError();
                    //frame.endStep(step);
                    return;
                }
                else if (frame.typeconvertoperator.targettype.instanceClass == null
                         ||
                         frame.typeconvertoperator.targettype != cls
                         )
                {
                    frame.throwError(new error.InternalError(frame.player.swc, step.token, "类型转换函数发现内部错误"
                                                             ));
                    frame.endStep(step);
                    return;
                }
            }

            if (rv.rtType == frame.player.swc.FunctionClass.getRtType())
            {
                rv = TypeConverter.ObjectImplicit_ToPrimitive((rtObjectBase)rv);
            }

            if (rv.rtType != RunTimeDataType.rt_function)
            {
                frame.throwError(step.token, 0, "value is not a function");
                frame.endStep(step);
            }
            else
            {
                ASBinCode.rtData.rtFunction function = (ASBinCode.rtData.rtFunction)rv;
                var funcCaller = frame.player.funcCallerPool.create(frame, step.token);
                funcCaller.SetFunction(function); if (toclear != null)
                {
                    toclear.Clear();
                }
                funcCaller._tempSlot = frame._tempSlot1;
                funcCaller.loadDefineFromFunction();
                if (!funcCaller.createParaScope())
                {
                    return;
                }

                frame.funCaller = funcCaller;
                frame.endStepNoError();
            }
        }
Beispiel #8
0
        public static void bind(StackFrame frame, ASBinCode.OpStep step, RunTimeScope scope)
        {
            var rv = step.arg1.getValue(frame.scope, frame);

            if (rv.rtType != RunTimeDataType.rt_function)
            {
                frame.throwError(
                    step.token, 0, "value is not a function");
                frame.endStep(step);
                return;
            }
            else
            {
                ASBinCode.rtData.rtFunction function = (ASBinCode.rtData.rtFunction)rv;

                if (function.bindScope == null
                    ||
                    function.bindScope.blockId == frame.scope.blockId
                    )
                {
                    function.bind(frame.scope);
                }

                if (!function.ismethod)
                {
                    if (function.this_pointer == null)
                    {
                        var s = frame.scope;
                        if (s.this_pointer != null && s.this_pointer is rtObjectBase)
                        {
                            rtObjectBase obj = (rtObjectBase)s.this_pointer;

                            if (obj.value is Global_Object)
                            {
                                function.setThis(obj);
                            }
                            else
                            {
                                var cls = obj.value._class;
                                if (cls.staticClass == null)
                                {
                                    cls = cls.instanceClass;
                                }
                                if (cls.mainClass != null)
                                {
                                    cls = cls.mainClass;
                                }

                                var ot = frame.player.outpackage_runtimescope[cls.classid];
                                function.setThis(ot.this_pointer);
                            }
                        }
                        else
                        {
                            if (frame.player.infoOutput != null)
                            {
                                frame.player.infoOutput.Warring("当前函数没有this指针。也许不是从文档类启动,而是从包外代码启动的");
                            }
                        }
                    }
                }
                frame.endStepNoError();
            }
        }
        public static void prepareConstructorClassArgements(StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope)
        {
            var rv = step.arg1.getValue(scope, frame);

            if (rv.rtType > RunTimeDataType.unknown)
            {
                var player = frame.player;
                var _class = getClass(player, frame, step, scope);
                if (_class != null && !_class.no_constructor)
                {
                    //frame.instanceCreator = new InstanceCreator(player, frame, step.token, _class);
                    frame.activeInstanceCreator(step.token, _class);
                    if (_class.constructor != null)
                    {
                        if (!frame.instanceCreator.prepareConstructorArgements())
                        {
                            return;
                        }
                    }
                    //if (_class.constructor != null)
                    //{
                    //    ASBinCode.rtti.FunctionDefine funcDefine = player.swc.functions[_class.constructor_functionid];
                    //    ASBinCode.rtti.FunctionSignature signature = funcDefine.signature;

                    //    frame.funCaller = new FunctionCaller(player, frame, step.token);
                    //    frame.funCaller.toCallFunc = funcDefine;
                    //    frame.funCaller.createParaScope();

                    //}
                }
                else if (_class.isInterface)
                {
                    frame.throwError(step.token, 0, _class.name + " Interfaces cannot be instantiated with the new operator.");
                }
                else
                {
                    frame.throwError(step.token, 0, _class.name + " is not a constructor");
                }
            }
            else
            {
                if (rv.rtType == RunTimeDataType.rt_function)
                {
                    ASBinCode.rtData.rtFunction func = (ASBinCode.rtData.rtFunction)rv;
                    if (func.ismethod)
                    {
                        frame.throwError(step.token, 0,
                                         "Method cannot be used as a constructor."
                                         );
                    }
                    else
                    {
                        //***创建一个Object对象,创建完毕之后,使用此函数执行初始化。将此对象作为此函数的this指针执行一次。
                        OpCast.Primitive_to_Object((ASBinCode.rtData.rtFunction)rv,
                                                   frame, step.token, scope, frame._tempSlot1, step, _func_ToObj
                                                   );

                        return;
                    }
                }
                else
                {
                    frame.throwCastException(step.token, rv.rtType, RunTimeDataType.rt_function);

                    //new error.InternalError( step.token,"原始类型转对象未实现",new ASBinCode.rtData.rtString("原始类型转对象未实现") ));
                }
            }
            frame.endStep(step);
        }
        private static ASBinCode.rtti.Class getClass(Player player, StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope)
        {
            var rv = step.arg1.getValue(frame.scope, frame);

            if (rv.rtType > RunTimeDataType.unknown)
            {
                var _class = ((ASBinCode.rtData.rtObjectBase)rv).value._class;

                if (_class.instanceClass == null)
                {
                    frame.throwError(
                        step.token, 0,
                        "不是Class类型对象不能new"

                        );
                    return(null);
                }
                _class = _class.instanceClass;
                return(_class);
            }
            else
            {
                frame.throwError(
                    step.token, 0,
                    "此类型不能new" + rv.rtType

                    );
                return(null);
            }
        }
        public static void execAssigning(StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope)
        {
            ASBinCode.SLOT slot = step.reg.getSlotForAssign(scope,frame);

            ASBinCode.RunTimeValueBase v = step.arg1.getValue(scope,frame);
            bool success;

            var lt = slot.assign(v,out success);


            if (!success)                 //(!slot.directSet(v))
            {
                if (!(slot is StackSlot)) //直接赋值时
                {
                    //ext = "Illegal assignment to function " + ((MethodGetterBase)step.reg).name + ".";
                }
                else
                {
                    StackSlot oslot = (StackSlot)slot;
                    //if (oslot.linktarget != null)
                    {
                        //slot = oslot.linktarget;
                        slot = lt;
                    }

                    if (step.arg1 is IMemReg)
                    {
                        //将其暂存到临时槽内
                        frame._tempSlot2.directSet(v);
                        v = frame._tempSlot2.getValue();
                    }

                    if (slot is SetThisItemSlot)
                    {
                        _doSetThisItem(((SetThisItemSlot)slot).bindObj,((SetThisItemSlot)slot).set_this_item,v,((SetThisItemSlot)slot).setindex,oslot,frame,step);

                        return;
                    }

                    if (slot is ClassPropertyGetter.PropertySlot)
                    {
                        ClassPropertyGetter.PropertySlot propslot =
                            (ASBinCode.ClassPropertyGetter.PropertySlot)slot;
                        //***调用访问器。***
                        ASBinCode.ClassPropertyGetter prop = oslot.stackObjects.propGetSet;                         //propslot.property;

                        _doPropAssigning(prop,frame,step,frame.player,scope,
                                         //propslot.bindObj
                                         oslot.stackObjects.propBindObj
                                         ,v,
                                         oslot
                                         );
                        return;
                    }

                    if (slot is OpVector.vectorSLot)                        //Vector类型不匹配
                    {
                        BlockCallBackBase cb = frame.player.blockCallBackPool.create();
                        cb.scope = scope;
                        cb.step  = step;
                        cb.args  = frame;
                        cb.setCallBacker(D_vectorConvertCallBacker);
                        cb.cacheObjects[0] = slot;

                        //***调用强制类型转换***
                        OpCast.CastValue(v,((OpVector.vectorSLot)slot).vector_data.vector_type,
                                         frame,step.token,scope,frame._tempSlot1,cb,false);

                        return;
                    }

                    if (slot is ObjectMemberSlot && !((ObjectMemberSlot)slot).isConstMember)
                    {
                        BlockCallBackBase cb = frame.player.blockCallBackPool.create();
                        cb.scope = scope;
                        cb.step  = step;
                        cb.args  = frame;
                        cb.setCallBacker(D_objectmemberslotConvertCallbacker);
                        cb.cacheObjects[0] = slot;

                        //***调用强制类型转换***
                        OpCast.CastValue(v,((ObjectMemberSlot)slot).slottype,
                                         frame,step.token,scope,frame._tempSlot1,cb,false);

                        return;
                    }
                }
                string ext = String.Empty;

                if (slot is MethodGetterBase.MethodSlot)
                {
                    ext = "Cannot assign to a method ";                    // + ((ASBinCode.ClassMethodGetter.MethodSlot)slot).method;
                }
                else if (slot is ObjectMemberSlot)
                {
                    ext = "Illegal write to read-only property ";
                    //+ ((ObjectMemberSlot)slot).obj.value._class.name
                    //+" on ppp.PPC."
                }
                else if (slot is ClassPropertyGetter.PropertySlot)
                {
                    ext = "Illegal write to read-only property ";
                }
                else if (slot is OpAccess_Dot.prototypeSlot)
                {
                    ext = "Cannot create property "
                          + ((OpAccess_Dot.prototypeSlot)slot)._protoname +
                          " on " + ((OpAccess_Dot.prototypeSlot)slot)._protoRootObj.value._class.name;
                }

                frame.throwError(
                    step.token,0,ext
                    );
                frame.endStep(step);
            }
            else
            {
                frame.endStepNoError();
            }
        }
        private static void _execMulti_CallBacker(ASBinCode.RunTimeValueBase v1, ASBinCode.RunTimeValueBase v2, StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope)
        {
            double n1 = v1.toNumber();

            double n2 = v2.toNumber();

            {
                step.reg.getSlot(scope, frame).setValue(n1 * n2);// ((ASBinCode.rtData.rtNumber)v1).value - ((ASBinCode.rtData.rtNumber)v2).value);//new ASBinCode.rtData.rtNumber(((ASBinCode.rtData.rtNumber)v1).value - ((ASBinCode.rtData.rtNumber)v2).value));
            }
            //frame.endStep(step);
            frame.endStepNoError();
        }