internal void Merge(GOpFrame frame) { foreach (var kvp in frame.variables) { int off = kvp.Key; LocalVariable lv = kvp.Value; if (!variables.ContainsKey(off)) { variables[off] = lv; } } foreach (var kvp in frame.instances) { int off = kvp.Key; LocalInstance li = kvp.Value; if (!instances.ContainsKey(off)) { instances[off] = li; } } }
internal bool CanMerge(GOpFrame frame) { foreach (var kvp in frame.variables) { int off = kvp.Key; LocalVariable lv2 = kvp.Value; LocalVariable lv1; if (!variables.TryGetValue(off, out lv1)) { continue; } if (lv1.ltype.IsRestricted || lv2.ltype.IsRestricted) { if (lv1.ltype != lv2.ltype) { return(false); } } if (lv1.len != lv2.len) { return(false); } } foreach (var kvp in frame.instances) { int off = kvp.Key; LocalInstance li2 = kvp.Value; LocalInstance li1; if (!instances.TryGetValue(off, out li1)) { continue; } if (li1.ltype != li2.ltype) { return(false); } } return(true); }
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); } } }