private FuncBuilder(Namespace ns, FuncBuilderHints builderHints, ActionOnFuncBuilder action) { Instance=this; this.namespaceAndNextIndex=new NamespaceAndNextIndex(ns, 0); this.BuilderHints=builderHints; var pt=builderHints.PassTraits; this.Scratch0=pt.Scratch0; this.Scratch1=pt.Scratch1; var emitter=CodeGenerator.Emitter; var passTraits=BuilderHints.PassTraits; var preserveLr=passTraits.PreserveLinkRegister; var regsToPreserve=passTraits.RegisterMask&0xf0; emitter.EmitIfNecessary(Format14OpCode.PUSH, preserveLr, (byte)regsToPreserve); if(preserveLr) { StackPointer+=-4; } while(regsToPreserve!=0) { StackPointer+=-4; regsToPreserve&=(regsToPreserve-1); } this.EndOfVariableRegion=StackPointer; var avo=passTraits.AllocatedVariableOffset; emitter.EmitIfNecessary(Format13OpCode.ADDSP, avo); StackPointer+=avo; this.TheExitLabel=DeclareLabel("leave"); action(this); TheExitLabel.Mark(); StackPointer+=-avo; emitter.EmitIfNecessary(Format13OpCode.ADDSP, -avo); regsToPreserve=passTraits.RegisterMask&0xf0; emitter.EmitIfNecessary(Format14OpCode.POP, false, (byte)regsToPreserve); Register bxRegister; if(passTraits.PreserveLinkRegister) { bxRegister=new LowRegister(1); emitter.EmitIfNecessary(Format14OpCode.POP, false, 1<<1); } else { bxRegister=Register.LR; } emitter.Emit(Format5OpCode.BX, null, bxRegister); if(inflightUtterances.Count>0) { var allUtterances=""; foreach(string utterance in inflightUtterances.Values) { if(allUtterances.Length>0) { allUtterances+=","; } allUtterances+=utterance; } throw new Exception(allUtterances); } }
public IDisposable OpenScope(string name) { this.namespaceAndNextIndex=this.namespaceAndNextIndex.Nest(name); this.localVariableToInfo=this.localVariableToInfo.Nest(); return new ScopeMaster(); }