namespace FlexSwitch { using System; using Benchmark; /* Jump between basic block inside cases of flexswitches ----------------------------------------------------- Each basic block in a function and in its "childs" (i.e. the cases generated by flexswitches) is numbered with an unique ID. To jump to a specific block, you need to instantiate a subclass of NonLocalJump; the "label" field will contain the ID of the block, the other fields the arguments to pass across the link. The main function has a block named "dispatch_jump" which switches over the label and jump to the right block; in case of blocks inside flexswitch cases, the child function is invoked with the NonLocalJump as an argument and does the dispatch inside (XXX: not implemented yet). Each block is responsible to decode the args stored in the NonLocalJump subclass. Each flexswictch case returns a NonLocalJump, which is then passed to dispatch_jump to decide where to pass the control next. */ class NonLocalJump { public int label; // the number of the block to jump to public NonLocalJump(int label) { this.label = label; } } // example subclass with only one int argument class NonLocalJumpInt: NonLocalJump { public int value0; public NonLocalJumpInt(int label, int value0): base(label) { this.value0 = value0; } } delegate NonLocalJump SwitchCase(NonLocalJump entrypoint); delegate NonLocalJump SwitchDefaultCase(FlexSwitch obj, object value); class FlexSwitch { public int numcases = 0; public object[] values = new object[10]; public SwitchCase[] cases = new SwitchCase[10]; public SwitchDefaultCase defaultcase; public void addcase(object v, SwitchCase c) { values[numcases] = v; cases[numcases] = c; numcases++; } public NonLocalJump execute(object v, NonLocalJump args) { for(int i=0; i= bytecode.Length) return accumulator; continue; // goto fetch // XXX: this block of code should be outside the loop, // but C# compiler does not allow to jump inside a // loop from the outside dispatch_jump: int label = jumpto.label; if (label == FETCH) goto fetch; else if (label == EXEC) goto exec; else if (label == NEXT) goto next; else throw new Exception("error in dispatch_jump"); } } } }