Пример #1
0
        public void EnsureStringBuilderOnStackTop()
        {
            switch (StackTop)
            {
            case StringMangleStackTop.Unknown:
                LoadOrCreateStringBuilder();
                break;

            case StringMangleStackTop.String:
                using (Emitter.UseTempLocal <string>(out var stringVar))
                {
                    Emitter.Stloc(stringVar);
                    LoadOrCreateStringBuilder();
                    Emitter.Ldloc(stringVar);
                }
                Emitter.Callvirt(SmUtils.Method_StringBuilder_Append_String);
                break;

            case StringMangleStackTop.StringBuilder:
                break;

            default: throw new CodeBug.Unreachable();
            }
            StackTop = StringMangleStackTop.StringBuilder;
        }
Пример #2
0
        internal void Use(IStringMangleMethod demangler)
        {
            if (StackTop == StringMangleStackTop.String) // means we have more than one part, and previous demangler left us with a string
            {
                EnsureStringBuilderOnStackTop();
            }
            var top = demangler.Emit(this);

            if (!top.HasValue)
            {
                return;                // demangler refused to process current piece, calling code will select another demangler
            }
            switch (top.Value)
            {
            case StringMangleStackTop.String:
                switch (StackTop)
                {
                case StringMangleStackTop.String:
                    using (Emitter.UseTempLocal <int>(out var stringVar1))
                        using (Emitter.UseTempLocal <int>(out var stringVar2))
                        {
                            Emitter.Stloc(stringVar1);
                            Emitter.Stloc(stringVar2);
                            LoadOrCreateStringBuilder(stringVar1);
                            Emitter.Ldloc(stringVar2);
                        }
                    Emitter.Callvirt(SmUtils.Method_StringBuilder_Append_String);
                    break;

                case StringMangleStackTop.StringBuilder:
                    Emitter.Callvirt(SmUtils.Method_StringBuilder_Append_String);
                    top = StringMangleStackTop.StringBuilder;
                    break;
                }
                break;

            case StringMangleStackTop.StringBuilder:
                if (StackTop == StringMangleStackTop.String)
                {
                    throw Mangler.Context.Error("demangler must call EnsureStringBuilderOnStackTop() if it needs a string builder instead of creating its own");
                }
                // StackTop == Unknown is Okay, means StringBuilder was created (and hopefully populated) by the demangler
                // StackTop == StringBuilder is Okay, means StringBuilder was added to (and hopefully not created) by the demangler
                break;

            default: throw Mangler.Context.Error("demangler must leave either string or StringBuilder on stack");
            }
            StackTop = top.Value;
        }