예제 #1
0
        /// <summary>Adapts the tag base to CIL.</summary>
        /// <param name="ilgen">IL Generator.</param>
        /// <param name="tab">The TagArgumentBit.</param>
        /// <param name="values">Related adaptation values.</param>
        /// <returns>Whether any adaptation was done.</returns>
        public override bool AdaptToCIL(ILGeneratorTracker ilgen, TagArgumentBit tab, CILAdaptationValues values)
        {
            int index = (int)((tab.Bits[0].Variable.Bits[0] as TextArgumentBit).InputValue as IntegerTag).Internal;

            ilgen.Emit(OpCodes.Ldarg_0);                                      // Load argument: TagData
            ilgen.Emit(OpCodes.Ldfld, TagData.Field_TagData_Runnable);        // Load TagData.Runnable
            ilgen.Emit(OpCodes.Ldfld, values.LocalVariableData(index).Field); // Load Runnable.Var
            return(true);
        }
예제 #2
0
        /// <summary>Adapts a command entry to CIL.</summary>
        /// <param name="values">The adaptation-relevant values.</param>
        /// <param name="entry">The present entry ID.</param>
        public override void AdaptToCIL(CILAdaptationValues values, int entry)
        {
            CommandEntry cent = values.CommandAt(entry);
            bool         db   = cent.DBMode <= DebugMode.FULL;

            if (cent.IsCallback)
            {
                string sn           = values.Entry.Entries[cent.BlockStart - 1].GetSaveNameNoParse("repeat_index");
                int    lvar_ind_loc = cent.VarLoc(sn);
                values.LoadRunnable();
                values.LoadLocalVariable(lvar_ind_loc);
                values.ILGen.Emit(OpCodes.Ldc_I8, 1L);
                values.ILGen.Emit(OpCodes.Add);
                values.ILGen.Emit(OpCodes.Stfld, values.LocalVariableData(lvar_ind_loc).Field);
                values.LoadQueue();
                if (db)
                {
                    values.LoadEntry(entry);
                }
                else
                {
                    values.ILGen.Emit(OpCodes.Ldc_I4, cent.BlockStart - 1);
                }
                values.ILGen.Emit(OpCodes.Call, db ? TryRepeatCILMethod : TryRepeatCILMethodNoDebug);
                values.ILGen.Emit(OpCodes.Brtrue, values.Entry.AdaptedILPoints[cent.BlockStart]);
                return;
            }
            string arg = cent.Arguments[0].ToString();

            if (arg == "stop")
            {
                for (int i = entry - 1; i >= 0; i--)
                {
                    CommandEntry nextEntry = values.Entry.Entries[i];
                    if (nextEntry.Command is not RepeatCommand || nextEntry.IsCallback)
                    {
                        continue;
                    }
                    string a0 = nextEntry.Arguments[0].ToString();
                    if (a0 != "stop" && a0 != "next" && nextEntry.InnerCommandBlock != null)
                    {
                        if (db)
                        {
                            values.LoadQueue();
                            values.LoadEntry(entry);
                            values.ILGen.Emit(OpCodes.Call, DebugStopMethod);
                        }
                        values.ILGen.Emit(OpCodes.Br, values.Entry.AdaptedILPoints[nextEntry.BlockEnd + 2]);
                        return;
                    }
                }
                throw new ErrorInducedException("Invalid 'repeat stop' command: not inside a repeat block!");
            }
            else if (arg == "next")
            {
                for (int i = entry - 1; i >= 0; i--)
                {
                    CommandEntry nextEntry = values.Entry.Entries[i];
                    if (nextEntry.Command is not RepeatCommand || nextEntry.IsCallback)
                    {
                        continue;
                    }
                    string a0 = nextEntry.ToString();
                    if (a0 != "stop" && a0 != "next" && nextEntry.InnerCommandBlock != null)
                    {
                        if (db)
                        {
                            values.LoadQueue();
                            values.LoadEntry(entry);
                            values.ILGen.Emit(OpCodes.Call, DebugNextMethod);
                        }
                        values.ILGen.Emit(OpCodes.Br, values.Entry.AdaptedILPoints[nextEntry.BlockEnd + 1]);
                        return;
                    }
                }
                throw new ErrorInducedException("Invalid 'repeat next' command: not inside a repeat block!");
            }
            else
            {
                values.LoadRunnable();
                values.ILGen.Emit(OpCodes.Ldc_I8, 1L);
                values.ILGen.Emit(OpCodes.Stfld, cent.VarLookup[cent.GetSaveNameNoParse("repeat_index")].Field);
                values.LoadQueue();
                values.LoadEntry(entry);
                values.ILGen.Emit(OpCodes.Call, db ? TryRepeatNumberedCILMethod : TryRepeatNumberedCIL_NoDebugMethod);
                values.ILGen.Emit(OpCodes.Brfalse, values.Entry.AdaptedILPoints[cent.BlockEnd + 2]);
            }
        }