public Type[] AdjustStack(Instruction i, Type[] stack) { var t = stackBefore(i, stack); var u = stackAfter(i, stack); return stack .Take(stack.Length - t.Length).Concat(u).ToArray(); }
public IEnumerable<string> SpecializeCodeForContext(Instruction i, Type[] stack) { foreach (var s in code) { var t = s.Contains("%imm") ? s.Replace("%imm", i.GetImmediateValue().ToString()) : s; // todo: more substitutions yield return t; } }
public bool IsApplicable(Instruction i, Type[] stack) { if (!names.Contains(i.GetName())) return false; var t = stackBefore(i, stack); if (t.Length > stack.Length) return false; for (int j = 0; j < t.Length; j++) if (!IsCompatible(t[j], stack[stack.Length - t.Length + j])) return false; if (i.oc == OpCodes.Ret) if (t.Length != stack.Length) return false; return true; }
public static IEnumerable<InstructionImpl> FindMatches(Instruction i, Type[] stack) { foreach (var impl in impls) if (impl.IsApplicable(i, stack)) yield return impl; }
public static Type[] EvalTypesInContext(string s, Instruction i, Type[] stack) { s = s.Trim().Replace(" ", ""); if (s.Contains(',')) return s.Split(',').SelectMany( f => EvalTypesInContext(f, i, stack)).ToArray(); if (s.Contains("%imm")) s = s.Replace("%imm", i.GetImmediateValue().ToString()); if (s == "%top") return new Type[] { stack.LastOrDefault() }; if (s == "()") return new Type[] { }; if (s == "I4") return new Type[] { typeof(int) }; if (s == "Ref") return new Type[] { typeof(object) }; for (int j = 0; j < i.resolver.GetNumArgs(); j++) if (s == "%arg_type[" + j + "]") return new Type[] { i.resolver.GetArgType(j) }; for (int j = 0; j < i.resolver.GetNumLocals(); j++) if (s == "%local_type[" + j + "]") return new Type[] { i.resolver.GetLocalType(j) }; if (s == "%tok_ret") return new Type[] { i.GetMethodReturnType() }; if (s == "%tok_args") return i.GetMethodArgs(); if (s == "%tok_decltype") return new Type[] { i.GetTokenDeclaringType() }; if (s == "%tok_type") return new Type[] { i.GetTokenType() }; throw new NotImplementedException(); }