Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
thisdir = tools/ictool
SUBDIRS =
include ../../build/rules.make
PROGRAM = ictool.exe
EXTRA_DISTFILES = ictool-config.xml
include ../../build/executable.make

View File

@@ -0,0 +1,69 @@
//
// file: depgraph.cs
// author: Dan Lewis (dihlewis@yahoo.co.uk)
// (C) 2002
//
using System;
using System.Collections;
class DependencyGraph {
public DependencyGraph () {
nodes = new Hashtable ();
}
public void AddNode (object o) {
if (!nodes.Contains (o))
nodes.Add (o, new Node (o));
}
public void AddEdge (object from, object to) {
if (!nodes.Contains (from))
AddNode (from);
if (!nodes.Contains (to))
AddNode (from);
Node from_node = (Node)nodes[from];
Node to_node = (Node)nodes[to];
from_node.edges.Add (to_node);
}
public IList TopologicalSort () {
foreach (Node node in nodes.Values)
node.marked = false;
IList list = new ArrayList ();
foreach (Node node in nodes.Values) {
if (!node.marked)
Visit (node, list);
}
return list;
}
// private
private void Visit (Node node, IList list) {
node.marked = true;
foreach (Node adj in node.edges) {
if (!adj.marked)
Visit (adj, list);
}
list.Insert (0, node.value);
}
private class Node {
public Node (object o) {
this.value = o;
this.edges = new ArrayList ();
}
public object value;
public ArrayList edges;
public bool marked;
}
private Hashtable nodes;
}

View File

@@ -0,0 +1,105 @@
<config>
<!-- assembly inputs -->
<assemblypath path="..\..\class\lib"/>
<assembly file="corlib_cmp.dll"/>
<assembly file="System.dll"/>
<!-- output files -->
<outputpath path="."/>
<outputfile name="types" file="icall_types.h">
<include><![CDATA[#include "icall.h"]]></include>
</outputfile>
<outputfile name="methods" file="icall_methods.h"/>
<outputfile name="map" file="icall_map.c"/>
<!-- typemap -->
<typemap>
<!-- base types -->
<namespace name="System">
<!-- default types are taken from the running assembly -->
<type name="Object" peer="MonoObject" opaque="true" default="true"/>
<type name="Void" peer="void" opaque="true" default="true"/>
<type name="Boolean" peer="MonoBoolean" opaque="true" default="true"/>
<type name="Int64" peer="gint64" opaque="true" default="true"/>
<type name="Int32" peer="gint32" opaque="true" default="true"/>
<type name="Int16" peer="gint16" opaque="true" default="true"/>
<type name="Byte" peer="gint8" opaque="true" default="true"/>
<type name="UInt64" peer="guint64" opaque="true" default="true"/>
<type name="UInt32" peer="guint32" opaque="true" default="true"/>
<type name="UInt16" peer="guint16" opaque="true" default="true"/>
<type name="SByte" peer="guint8" opaque="true" default="true"/>
<type name="IntPtr" peer="gpointer" opaque="true" default="true"/>
<type name="UIntPtr" peer="gpointer" opaque="true" default="true"/>
<type name="Single" peer="gfloat" opaque="true" default="true"/>
<type name="Double" peer="gdouble" opaque="true" default="true"/>
<type name="Char" peer="gunichar2" opaque="true" default="true"/>
<type name="Array" peer="MonoArray" opaque="true" default="true"/>
<!-- non-defaulting system types -->
<type name="Decimal" peer="decimal_repr" opaque="true"/>
<type name="String" peer="MonoString" opaque="true"/>
</namespace>
<!-- reflection types -->
<namespace name="System">
<type name="RuntimeTypeHandle" peer="MonoType *" opaque="true"/>
<type name="RuntimeMethodHandle" peer="MonoMethod *" opaque="true"/>
<type name="RuntimeFieldHandle" peer="MonoClassField *" opaque="true"/>
<type name="Type" peer="MonoReflectionType"/>
<type name="MonoTypeInfo" peer="MonoTypeInfo"/>
<type name="MonoEnumInfo" peer="MonoEnumInfo"/>
</namespace>
<namespace name="System.Reflection">
<type name="MonoMethod" peer="MonoReflectionMethod"/>
<type name="MonoField" peer="MonoReflectionField"/>
<type name="MonoFieldInfo" peer="MonoFieldInfo"/>
<type name="MonoProperty" peer="MonoReflectionProperty"/>
<type name="ParameterInfo" peer="MonoParameterInfo"/>
<type name="MonoMethodInfo" peer="MonoMethodInfo"/>
<type name="MonoPropertyInfo" peer="MonoPropertyInfo"/>
<type name="Assembly" peer="MonoReflectionAssembly"/>
<type name="Module" peer="MonoReflectionModule"/>
<type name="AssemblyName" peer="MonoReflectionAssemblyName"/>
</namespace>
<namespace name="System.Reflection.Emit">
<type name="ILGenerator" peer="MonoReflectionILGen"/>
<type name="ILExceptionInfo" peer="MonoILExceptionInfo"/>
<type name="ILExceptionBlock" peer="MonoILExceptionBlock"/>
<type name="LocalBuilder" peer="MonoReflectionLocalBuilder"/>
<type name="ParameterBuilder" peer="MonoReflectionParamBuilder"/>
<type name="ConstructorBuilder" peer="MonoReflectionCtorBuilder"/>
<type name="MethodBuilder" peer="MonoReflectionMethodBuilder"/>
<type name="FieldBuilder" peer="MonoReflectionFieldBuilder"/>
<type name="PropertyBuilder" peer="MonoReflectionPropertyBuilder"/>
<type name="ModuleBuilder" peer="MonoReflectionModuleBuilder"/>
<type name="TypeBuilder" peer="MonoReflectionTypeBuilder"/>
<type name="Label" peer="MonoReflectionLabel"/>
</namespace>
<!-- enumerations -->
<namespace name="System.Net.Sockets">
<type name="SocketType" peer="MonoSocketType"/>
<type name="AddressFamily" peer="MonoAddressFamily"/>
<type name="ProtocolType" peer="MonoProtocolType"/>
<type name="SocketOptionLevel" peer="MonoSocketOptionLevel"/>
<type name="SocketOptionName" peer="MonoSocketOptionName"/>
</namespace>
</typemap>
</config>

428
mcs/tools/ictool/ictool.cs Normal file
View File

@@ -0,0 +1,428 @@
//
// file: ictool.cs
// author: Dan Lewis (dihlewis@yahoo.co.uk)
// (C) 2002
//
// description:
//
// Tool for generating C prototypes and structures suitable for use by the runtime
// from a list of supplied assemblies. See ictool-config.xml for configuration details.
//
using System;
using System.IO;
using System.Xml;
using System.Reflection;
using System.Collections;
public class ICTool {
public static void Main (string[] args) {
string filename = "ictool-config.xml";
if (args.Length == 1) {
filename = args[0];
}
else if (args.Length > 1) {
Console.Error.WriteLine ("Usage: ictool.exe [config.xml]");
Environment.Exit (-1);
}
try {
Stream config = File.OpenRead (filename);
Configure (config);
}
catch (Exception e) {
Console.Error.WriteLine ("Error: could not read configuration file.");
Console.Error.WriteLine (e);
Environment.Exit (-1);
}
EmitPrototypes ();
EmitStructures ();
}
// private
private static void EmitPrototypes () {
StreamWriter methods_file = GetOutputFile ("methods");
StreamWriter map_file = GetOutputFile ("map");
// includes
methods_file.WriteLine ("#include \"{0}\"\n", output_files["types"]);
map_file.WriteLine ("#include \"{0}\"\n", output_files["methods"]);
map_file.Write (
"static gpointer icall_map [] = {\n\t"
);
ArrayList map_lines = new ArrayList ();
BindingFlags binding =
BindingFlags.DeclaredOnly |
BindingFlags.Instance |
BindingFlags.Static |
BindingFlags.Public |
BindingFlags.NonPublic;
foreach (Type type in types.Values) {
bool has_icall = false;
MethodInfo[] methods = type.GetMethods (binding);
foreach (MethodInfo method in methods) {
if (IsInternalCall (method)) {
has_icall = true;
break;
}
}
if (!has_icall)
continue;
methods_file.WriteLine ("\n/* {0} */\n", type.FullName);
//map_lines.Add (String.Format ("\n/* {0} */\n", type.FullName));
foreach (MethodInfo method in methods) {
if (!IsInternalCall (method))
continue;
// function name
string func_name = String.Format ("ves_icall_{0}_{1}",
type.FullName,
method.Name
);
func_name = func_name.Replace ('.', '_');
// map file
map_lines.Add (String.Format (
"\"{0}::{1}\", {2}",
type.FullName.Replace ('.', '_'),
method.Name,
func_name
));
// methods file
ArrayList args = new ArrayList ();
// FIXME: return types that are structs need to be inserted
// into the argument list as a destination pointer
// object/value instance pointer
if (IsInstanceMethod (method)) {
args.Add (String.Format (
"{0}{1}",
peer_map.GetPeer (method.DeclaringType).GetTypedef (1),
"this"
));
}
// arguments
foreach (ParameterInfo param in method.GetParameters ()) {
Type arg_type = param.ParameterType;
int refs = 0;
if (arg_type.IsByRef) {
arg_type = arg_type.GetElementType ();
++ refs;
}
Peer arg_peer = peer_map.GetPeer (arg_type);
if (!arg_peer.IsValueType)
++ refs;
args.Add (String.Format ("{0}{1}", arg_peer.GetTypedef (refs), param.Name));
}
Peer ret = peer_map.GetPeer (method.ReturnType);
methods_file.WriteLine ("static {0}", ret.GetTypedef (ret.IsValueType ? 0 : 1));
methods_file.WriteLine ("{0} ({1});",
func_name,
Join (", ", args)
);
methods_file.WriteLine ();
}
}
methods_file.Close ();
// write map file and close it
map_file.Write (
"{0}\n}};\n", Join (",\n\t", map_lines)
);
map_file.Close ();
}
private static bool IsInternalCall (MethodInfo meth) {
return (meth.GetMethodImplementationFlags () & MethodImplAttributes.InternalCall) != 0;
}
private static bool IsInstanceMethod (MethodInfo meth) {
return (meth.CallingConvention & CallingConventions.HasThis) != 0;
}
private static void EmitStructures () {
StreamWriter file = GetOutputFile ("types");
// build dependency graph
DependencyGraph dg = new DependencyGraph ();
foreach (Peer peer in peer_map.Peers) {
dg.AddNode (peer);
// peer depends on nearest base
if (peer.NearestBase != null)
dg.AddEdge (peer.NearestBase, peer);
// peer depends on any value types used for fields
foreach (PeerField field in peer.Fields) {
if (field.Peer.IsValueType)
dg.AddEdge (field.Peer, peer);
}
}
// write structures in order
foreach (Peer peer in dg.TopologicalSort ()) {
if (peer.IsOpaque)
continue;
if (peer.IsEnum) {
file.WriteLine ("typedef {0} {1};", peer.UnderlyingPeer.Name, peer.Name);
file.WriteLine ("enum _{0} {{", peer.Name);
ArrayList enum_lines = new ArrayList ();
foreach (string name in peer.EnumConstants.Keys) {
enum_lines.Add (String.Format ("\t{0}_{1} = {2}",
peer.Name,
name,
peer.EnumConstants[name]
));
}
file.WriteLine ("{0}\n}};\n", Join (",\n", enum_lines));
}
else {
file.WriteLine ("typedef struct _{0} {{", peer.Name);
// base type
if (peer.NearestBase != null) {
file.WriteLine ("\t{0} __base;", peer.NearestBase.Name);
file.WriteLine ();
}
// fields
foreach (PeerField field in peer.Fields) {
bool use_struct = true;
if (field.Peer.IsValueType || field.Peer.IsOpaque)
use_struct = false;
file.WriteLine ("\t{0}{1}{2};",
use_struct ? "struct _" : "",
field.Peer.GetTypedef (field.Peer.IsValueType ? 0 : 1),
field.Name
);
}
file.WriteLine ("}} {0};\n", peer.Name);
}
}
}
private static void LoadAssemblies () {
types = new Hashtable ();
foreach (string filename in assemblies) {
Assembly assembly;
// find assembly
FileInfo info = null;
foreach (string path in assembly_paths) {
info = new FileInfo (Path.Combine (path, filename));
if (info.Exists)
break;
}
if (!info.Exists) {
Console.Error.WriteLine ("Error: assembly {0} not found.", filename);
Environment.Exit (-1);
}
// load assembly
assembly = Assembly.LoadFrom (info.FullName);
// load types
ArrayList loaded_types;
try {
loaded_types = new ArrayList (assembly.GetTypes ());
}
catch (ReflectionTypeLoadException e) {
loaded_types = new ArrayList ();
foreach (Type type in e.Types) {
if (type != null)
loaded_types.Add (type);
}
foreach (Exception f in e.LoaderExceptions) {
if (f is TypeLoadException) {
Console.Error.WriteLine ("Warning: {0} could not be loaded from assembly {1}.",
((TypeLoadException)f).TypeName,
filename
);
}
else
Console.Error.WriteLine (f);
}
}
// add to type dictionary
foreach (Type type in loaded_types) {
if (!types.Contains (type.FullName))
types.Add (type.FullName, type);
}
}
}
private static void Configure (Stream input) {
XmlDocument doc = new XmlDocument ();
doc.Load (input);
// assemblies
assembly_paths = new ArrayList ();
assembly_paths.Add (".");
foreach (XmlNode node in doc.SelectNodes ("config/assemblypath")) {
assembly_paths.Add (node.Attributes["path"].Value);
}
assemblies = new ArrayList ();
foreach (XmlNode node in doc.SelectNodes ("config/assembly")) {
assemblies.Add (node.Attributes["file"].Value);
}
LoadAssemblies ();
// outputfiles
output_path = ".";
XmlNode path_node = doc.SelectSingleNode ("config/outputpath");
if (path_node != null)
output_path = path_node.Attributes["path"].Value;
output_files = new Hashtable ();
output_includes = new Hashtable ();
foreach (XmlNode node in doc.SelectNodes ("config/outputfile")) {
string name = node.Attributes["name"].Value;
output_files.Add (name, node.Attributes["file"].Value);
foreach (XmlNode child in node.ChildNodes) {
if (child.Name == "include")
output_includes[name] = child.InnerText;
}
}
// typemap
peer_map = new PeerMap ();
foreach (XmlNode node in doc.SelectNodes ("config/typemap/namespace")) {
string ns = node.Attributes["name"].Value;
foreach (XmlNode child in node.ChildNodes) {
if (child.Name == "type") {
string name = child.Attributes["name"].Value;
string peer_name = child.Attributes["peer"].Value;
bool opaque = false;
if (child.Attributes["opaque"] != null && child.Attributes["opaque"].Value == "true")
opaque = true;
String fullname = String.Format ("{0}.{1}", ns, name);
Type type;
if (child.Attributes["default"] != null && child.Attributes["default"].Value == "true")
type = Type.GetType (fullname);
else
type = (Type)types [fullname];
if (type != null)
peer_map.Add (new Peer (type, peer_name, opaque));
}
}
}
peer_map.ResolvePeers ();
}
private static StreamWriter GetOutputFile (string name) {
string filename = Path.Combine (output_path, (string)output_files[name]);
StreamWriter file = File.CreateText (filename);
file.AutoFlush = true;
file.Write (
// (verbatim string)
@"/**
* {0}
*
* This file was automatically generated on {1} by ictool.exe from
* the following assemblies:
* {2}
*/
",
output_files[name],
DateTime.Now.ToString ("d"),
Join (", ", assemblies)
);
if (output_includes.Contains (name)) {
file.WriteLine (output_includes [name]);
file.WriteLine ();
}
return file;
}
private static string Join (string separator, ICollection values) {
// note to microsoft: please implement this in String :)
string[] strs = new string[values.Count];
int i = 0;
foreach (object value in values)
strs[i ++] = value.ToString ();
return String.Join (separator, strs);
}
private static ArrayList assembly_paths;
private static ArrayList assemblies;
private static string output_path;
private static Hashtable output_files;
private static Hashtable output_includes;
private static PeerMap peer_map;
private static Hashtable types;
}

View File

@@ -0,0 +1,3 @@
depgraph.cs
ictool.cs
peer.cs

284
mcs/tools/ictool/peer.cs Normal file
View File

@@ -0,0 +1,284 @@
//
// file: peer.cs
// author: Dan Lewis (dihlewis@yahoo.co.uk)
// (C) 2002
//
using System;
using System.Reflection;
using System.Collections;
class Peer {
public Peer (Type clr_type, string name, bool is_opaque) {
this.clr_type = clr_type;
this.name = name;
this.is_opaque = is_opaque;
this.nearest_base = null; // resolve later
this.underlying = null;
this.enum_constants = null;
this.fields = new PeerFieldCollection ();
this.is_enum = CLRIsEnum (clr_type);
this.is_value_type = CLRIsValueType (clr_type);
}
public string Name {
get { return name; }
}
public Type CLRType {
get { return clr_type; }
}
public bool IsOpaque {
get { return is_opaque; }
}
public bool IsValueType {
get { return is_value_type; }
}
public bool IsEnum {
get { return is_enum; }
}
public Peer NearestBase {
get { return nearest_base; }
set { nearest_base = value; }
}
public Peer UnderlyingPeer {
get { return underlying; }
set { underlying = value; }
}
public IDictionary EnumConstants {
get { return enum_constants; }
set { enum_constants = value; }
}
public PeerFieldCollection Fields {
get { return fields; }
}
public string GetTypedef (int refs) {
if (refs == 0)
return String.Format ("{0} ", name);
return String.Format ("{0} {1}", name, new string ('*', refs));
}
// internal
internal static bool CLRIsValueType (Type clr_type) {
return clr_type.IsValueType;
/*
if (clr_type.BaseType == null)
return false;
return
clr_type.BaseType.FullName == "System.ValueType" ||
clr_type.BaseType.FullName == "System.Enum";
*/
}
internal static bool CLRIsEnum (Type clr_type) {
return clr_type.IsEnum;
/*
if (clr_type.BaseType == null)
return false;
return clr_type.BaseType.FullName == "System.Enum";
*/
}
internal static Type CLRUnderlyingType (Type clr_type) {
return Enum.GetUnderlyingType (clr_type);
/*
Type ebase = type.BaseType;
return (Type)ebase.InvokeMember ("GetUnderlyingType",
BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static,
null, null,
new object[] { type }
);
*/
}
// private
private Type clr_type;
private bool is_opaque;
private bool is_value_type;
private bool is_enum;
private string name;
private Peer nearest_base;
private Peer underlying;
private IDictionary enum_constants;
private PeerFieldCollection fields;
}
class PeerField {
public PeerField (Peer peer, string name) {
this.peer = peer;
this.name = name;
}
public Peer Peer {
get { return peer; }
}
public string Name {
get { return name; }
}
private Peer peer;
private string name;
}
class PeerFieldCollection : CollectionBase {
public void Add (PeerField f) {
List.Add (f);
}
public PeerField this[int i] {
get { return (PeerField)List[i]; }
}
}
class PeerMap {
public PeerMap () {
peers = new Hashtable ();
}
public void Add (Peer peer) {
Add (peer.CLRType, peer);
}
public void Add (Type clr_type, Peer peer) {
peers.Add (clr_type, peer);
}
public ICollection Peers {
get { return peers.Values; }
}
public Peer this[Type clr_type] {
get {
if (peers.Contains (clr_type))
return (Peer)peers[clr_type];
return null;
}
}
public Peer GetPeer (Type clr_type) {
Peer peer;
if (Peer.CLRIsValueType (clr_type)) {
peer = this[clr_type];
if (peer != null)
return peer;
if (Peer.CLRIsEnum (clr_type)) {
peer = this[Peer.CLRUnderlyingType (clr_type)];
if (peer != null)
return peer;
throw new ArgumentException ("Could not find peer or underlying peer for enum " + clr_type);
}
else
throw new ArgumentException ("Could not find peer for value type " + clr_type);
}
else {
Type type = clr_type;
while (type != null) {
peer = this[type];
if (peer != null)
return peer;
type = type.BaseType;
}
throw new ArgumentException ("Could not find peer for class " + clr_type);
}
}
public void ResolvePeers () {
BindingFlags binding =
BindingFlags.DeclaredOnly |
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public;
// base type
foreach (Peer peer in Peers) {
if (peer.IsOpaque || peer.IsValueType || peer.CLRType.BaseType == null)
continue;
peer.NearestBase = GetPeer (peer.CLRType.BaseType);
if (peer.NearestBase == null) {
Console.Error.WriteLine ("Error: cannot find an internal base type for {0}.", peer.Name);
Environment.Exit (-1);
}
}
// fields
foreach (Peer peer in Peers) {
if (peer.IsOpaque || peer.IsEnum)
continue;
Type clr_base = null;
if (peer.NearestBase != null)
clr_base = peer.NearestBase.CLRType;
Stack declared = new Stack ();
Type type = peer.CLRType;
while (type != clr_base) {
declared.Push (type);
type = type.BaseType;
}
// build declared field list
while (declared.Count > 0) {
type = (Type)declared.Pop ();
foreach (FieldInfo info in type.GetFields (binding)) {
PeerField field = new PeerField (
GetPeer (info.FieldType),
info.Name
);
peer.Fields.Add (field);
}
}
}
// enums
foreach (Peer peer in Peers) {
if (peer.IsOpaque || !peer.IsEnum)
continue;
Type clr_type = peer.CLRType;
// constants
Hashtable constants = new Hashtable ();
foreach (string name in Enum.GetNames (clr_type))
constants.Add (name, (int)Enum.Parse (clr_type, name));
peer.UnderlyingPeer = GetPeer (Enum.GetUnderlyingType (clr_type));
peer.EnumConstants = constants;
}
}
// private
private Hashtable peers;
}