internal Instr GenJmp(OpCode op, int pc, out int pos) { vm.CurrentScope.lastpc = vm.CurrentScope.pc; Instr instr = AppendInstruction(new Instr(op, pc)); vm.CurrentScope.pc++; pos = vm.CurrentScope.pc; return(instr); }
public CodeGenScope PushOP(Instr instr) { if (pc >= MAX_INSTR_SIZE) { throw new Exception("too big code block"); } lastpc = pc; iseq.Add(instr); pc++; return(this); }
public Instr Emit_Array(ArrayNode node) { int n; GenValues(node, out n); Instr instr = null; if (n >= 0) { Pop(n); AppendInstruction(GenOp_2(OpCode.Array, vm.CurrentScope.sp, n)); Push(); } return(instr); }
private void GenReturn(CodeGenScope s, OpCode op, int src) { if (no_peephole(s)) { GenOp_1(s, op, src); } else { Instr data = s.Last; if (data.insn == OpCode.Move && src == data.a) { s.pc = s.lastpc; GenOp_1(s, op, data.b); } else if (data.insn != OpCode.Return) { GenOp_1(s, op, src); } } }
private int GenJmp2(CodeGenScope scope, OpCode op, int a, int pc, int val) { int pos; if (val != NOVAL) { Instr instr = scope.Last; if (instr.insn == OpCode.Move && instr.a == a) { scope.pc = scope.lastpc; a = instr.b; } } scope.lastpc = scope.pc; scope.PushOP(new Instr(op, a, pc)); pos = scope.pc; return(pos); }
public Instr Emit_Hash(HashNode node) { int len = 0; for (var i = 0; i < node.keys.Count; ++i) { node.keys[i].Compile(this); node.values[i].Compile(this); len++; } Instr instr = null; if (len >= 0) { Pop(len * 2); AppendInstruction(GenOp_2(OpCode.Hash, vm.CurrentScope.sp, len)); Push(); } return(instr); }
internal Instr GenMove(int dst, int src, bool nopeep) { if (true) { goto normal; } else { Scope s = vm.CurrentScope; Instr data = s.Last; switch (data.insn) { case OpCode.Move: if (dst == src) { return(null); /* remove useless MOVE */ } if (data.b == dst && data.a == src) /* skip swapping MOVE */ { return(null); } goto normal; case OpCode.LoadNIL: case OpCode.LoadSelf: if (nopeep || data.a != src /*|| data.a < s->nlocals*/) { goto normal; } s.pc = s.lastpc; GenOp_1(data.insn, dst); break; case OpCode.LoadI: case OpCode.GetGV: case OpCode.GetIV: case OpCode.GetCV: case OpCode.GetConst: case OpCode.String: case OpCode.Lambda: case OpCode.Block: case OpCode.Method: if (nopeep || data.a != src /*|| data.a < s.nlocals*/) { goto normal; } s.pc = s.lastpc; GenOp_2(data.insn, dst, data.b); break; default: goto normal; } } return(null); normal: return(AppendInstruction(new Instr(OpCode.Move, dst, src))); // TODO: on_eval //return; }
internal Instr AppendInstruction(Instr c) { Code.Add(c); return(c); }
private void GenMove(CodeGenScope s, int dst, int src, bool nopeep) { if (no_peephole(s)) { goto normal; } else { Instr data = s.Last; switch (data.insn) { case OpCode.Move: if (dst == src) { return; /* remove useless MOVE */ } if (data.b == dst && data.a == src) /* skip swapping MOVE */ { return; } goto normal; case OpCode.LoadNIL: case OpCode.LoadSelf: if (nopeep || data.a != src /*|| data.a < s->nlocals*/) { goto normal; } s.pc = s.lastpc; GenOp_1(s, data.insn, dst); break; case OpCode.LoadI: case OpCode.GetGV: case OpCode.GetIV: case OpCode.GetCV: case OpCode.GetConst: case OpCode.String: case OpCode.Lambda: case OpCode.Block: case OpCode.Method: if (nopeep || data.a != src /*|| data.a < s.nlocals*/) { goto normal; } s.pc = s.lastpc; GenOp_2(s, data.insn, dst, data.b); break; default: goto normal; } } return; normal: s.PushOP(new Instr(OpCode.Move, dst, src)); // TODO: on_eval return; }