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; }
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; }