internal GOp ToGOp(int off, CCNodeOpcode node) { GOp g = code[off].ToGOp(node); g.addr = off; return(g); }
/* * Merge the provided GFunctionInterpreted into this one. If the * merge is not possible, this instance is not modified, and * false is returned. */ bool Merge(GFunctionInterpreted gf) { /* * Normally, Merge() is not invoked for a distinct function, * but an extra test here is cheap. */ if (fi != gf.fi) { return(false); } /* * We first test the frames, but do not complete their * merge until the operation is confirmed. */ if (!frame.CanMerge(gf.frame)) { return(false); } /* * Since the two GFunctionInterpreted relate to the same * interpreted function, all opcodes are naturally * compatible, except possibly the Call opcodes, which * must be checked. */ GOp[] spec3 = new GOp[spec.Length]; for (int i = 0; i < spec.Length; i++) { GOp g1 = spec[i]; GOp g2 = gf.spec[i]; if ((g1 is GOpCall) && (g2 is GOpCall)) { GOpCall g3 = ((GOpCall)g1).Merge((GOpCall)g2); if (g3 == null) { return(false); } spec3[i] = g3; } else { if (g1 is GOpZero) { spec3[i] = g2; } else { spec3[i] = g1; } } } spec = spec3; AdjustJumps(); /* * Merge the frames. */ frame.Merge(gf.frame); return(true); }
internal void Add(GOp g) { code.Add(g); }
GFunctionInterpreted(CCFunctionInterpreted cfi) : base(cfi.fi) { this.fi = cfi.fi; /* * Specialize opcodes. In this step: * * - For each source opcode, we create an appropriate GOp * instance. Type specialization for local fields * happens here. * * - Unreachable opcodes (whose entry stack is null) yield * a GOpZero. */ List <GOp> specOps = new List <GOp>(); int srcLen = cfi.nodes.Length; for (int i = 0; i < srcLen; i++) { GOp g = cfi.ToGOp(i); if (g == null) { throw new Exception("NYI (GOp)"); } specOps.Add(g); } spec = specOps.ToArray(); AdjustJumps(); /* * Compute local frame elements: * * - For local fields, only putlocal and putlocalindexed * matter; we check that each local has a single storage * type. * * - For local instances, we use reflocal and * reflocalindexed. */ frame = new GOpFrame(this); for (int i = 0; i < spec.Length; i++) { var pl = spec[i] as GOpPutLocal; if (pl != null) { frame.AddLocalVariable(pl.off, pl.ltype); } var pli = spec[i] as GOpPutLocalIndexed; if (pli != null) { frame.AddLocalVariableArray( pli.off, pli.len, pli.ltype); } var rl = spec[i] as GOpRefLocal; if (rl != null) { frame.AddLocalInstance(rl.off, rl.ltype); } var rli = spec[i] as GOpRefLocalIndexed; if (rli != null) { frame.AddLocalInstanceArray( rli.off, rli.len, rli.ltype); } } }