Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac3
-rw-r--r--mcs/build/profiles/mobile_static.make2
-rw-r--r--mcs/build/rules.make2
-rw-r--r--mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs11
-rw-r--r--mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs7
-rw-r--r--mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs11
-rw-r--r--mcs/class/reference-assemblies/Makefile12
-rw-r--r--mcs/tools/corcompare/Util.cs107
-rw-r--r--mcs/tools/corcompare/WellFormedXmlWriter.cs5
-rw-r--r--mcs/tools/corcompare/mono-api-html/ApiChange.cs16
-rw-r--r--mcs/tools/corcompare/mono-api-html/ApiDiff.cs86
-rw-r--r--mcs/tools/corcompare/mono-api-html/AssemblyComparer.cs2
-rw-r--r--mcs/tools/corcompare/mono-api-html/ClassComparer.cs24
-rw-r--r--mcs/tools/corcompare/mono-api-html/Comparer.cs4
-rw-r--r--mcs/tools/corcompare/mono-api-html/FieldComparer.cs5
-rw-r--r--mcs/tools/corcompare/mono-api-html/MemberComparer.cs41
-rw-r--r--mcs/tools/corcompare/mono-api-html/MethodComparer.cs11
-rw-r--r--mcs/tools/corcompare/mono-api-html/NamespaceComparer.cs16
-rw-r--r--mcs/tools/corcompare/mono-api-html/mono-api-html.csproj1
-rw-r--r--mcs/tools/corcompare/mono-api-info.cs655
-rw-r--r--mcs/tools/xbuild/frameworks/net_2.0.xml2
-rw-r--r--mcs/tools/xbuild/frameworks/net_3.0.xml2
-rw-r--r--mcs/tools/xbuild/frameworks/net_3.5.xml2
-rw-r--r--mcs/tools/xbuild/frameworks/net_4.0.xml2
-rw-r--r--mcs/tools/xbuild/frameworks/net_4.0_client.xml2
-rw-r--r--mono/metadata/cominterop.c16
-rw-r--r--mono/metadata/cominterop.h3
-rw-r--r--mono/metadata/coree.c8
-rw-r--r--mono/metadata/loader.c18
-rw-r--r--mono/metadata/loader.h6
-rw-r--r--mono/metadata/object-internals.h14
-rw-r--r--mono/metadata/object.c64
-rw-r--r--mono/metadata/remoting.c2
-rw-r--r--mono/mini/aot-runtime.c5
-rw-r--r--mono/mini/jit-icalls.c89
-rw-r--r--mono/mini/method-to-ir.c26
-rw-r--r--mono/mini/mini-generic-sharing.c67
-rw-r--r--mono/mini/mini-runtime.c82
-rw-r--r--mono/mini/mini-trampolines.c102
-rw-r--r--mono/mini/mini.c94
-rw-r--r--mono/mini/mini.h8
-rw-r--r--mono/utils/mono-error-internals.h4
-rw-r--r--mono/utils/mono-error.c5
-rw-r--r--mono/utils/mono-publib.h16
44 files changed, 1093 insertions, 567 deletions
diff --git a/configure.ac b/configure.ac
index 600ad4c6d28..33c4d28a82c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3651,6 +3651,9 @@ AC_SUBST(CFLAGS)
AC_SUBST(CPPFLAGS)
AC_SUBST(LDFLAGS)
+#This must always be defined when building the runtime
+AC_DEFINE(MONO_INSIDE_RUNTIME,1, [Disable banned functions from being used by the runtime])
+
mono_build_root=`pwd`
AC_SUBST(mono_build_root)
diff --git a/mcs/build/profiles/mobile_static.make b/mcs/build/profiles/mobile_static.make
index f68e07be883..0c3c8125cfd 100644
--- a/mcs/build/profiles/mobile_static.make
+++ b/mcs/build/profiles/mobile_static.make
@@ -48,7 +48,7 @@ ifndef MONO_DISABLE_GSHAREDVT
GSHAREDVT_FLAG = -O=gsharedvt
endif
-ifeq ($(MONO_LLVMONLY),TRUE)
+ifneq ($(MONO_LLVMONLY),)
AOT_BUILD_FLAGS_PREFIX = --aot=llvmonly,
AOT_RUN_FLAGS = --llvmonly
else
diff --git a/mcs/build/rules.make b/mcs/build/rules.make
index 7ff27755ec1..b79132991eb 100644
--- a/mcs/build/rules.make
+++ b/mcs/build/rules.make
@@ -143,7 +143,7 @@ endif
# Set the options for building and running AOT
# The trampoline numbers are provisional, they are what is required
# to run the corlib test suite. They should be considered a lower bound.
-INVARIANT_AOT_OPTIONS=bind-to-runtime-version,nimt-trampolines=900,ntrampolines=8000
+INVARIANT_AOT_OPTIONS=nimt-trampolines=900,ntrampolines=8000
ifndef MONO_DISABLE_GSHAREDVT
INVARIANT_AOT_OPTIONS:=$(INVARIANT_AOT_OPTIONS),ngsharedvt-trampolines=900
diff --git a/mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs b/mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs
index aded011e986..f70bd99464b 100644
--- a/mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs
+++ b/mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs
@@ -646,8 +646,15 @@ namespace System.Xml.Serialization
{
if (memberValue == null) return null;
Type type = memberValue.GetType();
- foreach (XmlTypeMapElementInfo elem in _itemInfo)
- if (elem.TypeData.Type == type) return elem;
+ XmlTypeMapElementInfo bestMatch = null;
+ foreach (XmlTypeMapElementInfo elem in _itemInfo) {
+ if (elem.TypeData.Type == type)
+ return elem;
+ if (elem.TypeData.Type.IsAssignableFrom (type) &&
+ (bestMatch == null || elem.TypeData.Type.IsAssignableFrom (bestMatch.TypeData.Type)))
+ bestMatch = elem;
+ }
+ return bestMatch;
}
return null;
}
diff --git a/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs b/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs
index 597acd1df54..116bbe323ad 100644
--- a/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs
+++ b/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs
@@ -711,6 +711,13 @@ namespace MonoTests.System.Xml.TestClasses
public object data;
}
+ public class SubclassTestList
+ {
+ [XmlElement ("a", typeof (SimpleClass))]
+ [XmlElement ("b", typeof (SubclassTestBase))]
+ public List<object> Items;
+ }
+
public class DictionaryWithIndexer : DictionaryBase
{
public TimeSpan this[int index]
diff --git a/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs b/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs
index 4e51eceae03..bdd08aa7c69 100644
--- a/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs
+++ b/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs
@@ -1939,6 +1939,17 @@ namespace MonoTests.System.XmlSerialization
Assert.AreEqual (Infoset (res), WriterText);
}
+ [Test] // Covers #36829
+ public void TestSubclassElementList ()
+ {
+ var o = new SubclassTestList () { Items = new List<object> () { new SubclassTestSub () } };
+ Serialize (o);
+
+ string res = "<SubclassTestList xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>";
+ res += "<b xsi:type=\"SubclassTestSub\"/></SubclassTestList>";
+ Assert.AreEqual (Infoset (res), WriterText);
+ }
+
[Test]
[ExpectedException (typeof (InvalidOperationException))]
public void TestArrayAttributeWithWrongDataType ()
diff --git a/mcs/class/reference-assemblies/Makefile b/mcs/class/reference-assemblies/Makefile
index dc8c9988fc9..20ff20005ca 100644
--- a/mcs/class/reference-assemblies/Makefile
+++ b/mcs/class/reference-assemblies/Makefile
@@ -7,13 +7,13 @@ all-local:
PROFILE_DIR=$(DESTDIR)$(mono_libdir)/mono
install-local:
- $(MKINSTALLDIRS) $(PROFILE_DIR)/2.0
- $(MKINSTALLDIRS) $(PROFILE_DIR)/3.5
- $(MKINSTALLDIRS) $(PROFILE_DIR)/4.0
+ $(MKINSTALLDIRS) $(PROFILE_DIR)/2.0-api
+ $(MKINSTALLDIRS) $(PROFILE_DIR)/3.5-api
+ $(MKINSTALLDIRS) $(PROFILE_DIR)/4.0-api
$(MKINSTALLDIRS) $(PROFILE_DIR)/4.5-api
- $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v2.0/* $(PROFILE_DIR)/2.0
- $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v3.5/* $(PROFILE_DIR)/3.5
- $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.0/* $(PROFILE_DIR)/4.0
+ $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v2.0/* $(PROFILE_DIR)/2.0-api
+ $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v3.5/* $(PROFILE_DIR)/3.5-api
+ $(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.0/* $(PROFILE_DIR)/4.0-api
$(INSTALL_LIB) ../../../external/binary-reference-assemblies/v4.5/* $(PROFILE_DIR)/4.5-api
DISTFILES = $(wildcard ../../../external/binary-reference-assemblies/v4.5/*) $(wildcard ../../../external/binary-reference-assemblies/v4.0/*) $(wildcard ../../../external/binary-reference-assemblies/v3.5/*) $(wildcard ../../../external/binary-reference-assemblies/v2.0/*) Makefile
diff --git a/mcs/tools/corcompare/Util.cs b/mcs/tools/corcompare/Util.cs
index 782280535dd..fa643ed20f8 100644
--- a/mcs/tools/corcompare/Util.cs
+++ b/mcs/tools/corcompare/Util.cs
@@ -83,5 +83,112 @@ namespace CorCompare {
{
return att.AttributeType.Resolve ();
}
+
+ static bool IsOverride (MethodDefinition method)
+ {
+ return method.IsVirtual && !method.IsNewSlot;
+ }
+
+ public static MethodDefinition GetBaseMethodInTypeHierarchy (MethodDefinition method)
+ {
+ if (!IsOverride (method))
+ return method;
+
+ var @base = GetBaseType (method.DeclaringType);
+ while (@base != null) {
+ MethodDefinition base_method = TryMatchMethod (@base.Resolve (), method);
+ if (base_method != null)
+ return GetBaseMethodInTypeHierarchy (base_method) ?? base_method;
+
+ @base = GetBaseType (@base);
+ }
+
+ return method;
+ }
+
+ static MethodDefinition TryMatchMethod (TypeDefinition type, MethodDefinition method)
+ {
+ if (!type.HasMethods)
+ return null;
+
+ foreach (MethodDefinition candidate in type.Methods)
+ if (MethodMatch (candidate, method))
+ return candidate;
+
+ return null;
+ }
+
+ static bool MethodMatch (MethodDefinition candidate, MethodDefinition method)
+ {
+ if (!candidate.IsVirtual)
+ return false;
+
+ if (candidate.Name != method.Name)
+ return false;
+
+ if (!TypeMatch (candidate.ReturnType, method.ReturnType))
+ return false;
+
+ if (candidate.Parameters.Count != method.Parameters.Count)
+ return false;
+
+ for (int i = 0; i < candidate.Parameters.Count; i++)
+ if (!TypeMatch (candidate.Parameters [i].ParameterType, method.Parameters [i].ParameterType))
+ return false;
+
+ return true;
+ }
+
+ public static bool TypeMatch (IModifierType a, IModifierType b)
+ {
+ if (!TypeMatch (a.ModifierType, b.ModifierType))
+ return false;
+
+ return TypeMatch (a.ElementType, b.ElementType);
+ }
+
+ public static bool TypeMatch (TypeSpecification a, TypeSpecification b)
+ {
+ if (a is GenericInstanceType)
+ return TypeMatch ((GenericInstanceType) a, (GenericInstanceType) b);
+
+ if (a is IModifierType)
+ return TypeMatch ((IModifierType) a, (IModifierType) b);
+
+ return TypeMatch (a.ElementType, b.ElementType);
+ }
+
+ public static bool TypeMatch (GenericInstanceType a, GenericInstanceType b)
+ {
+ if (!TypeMatch (a.ElementType, b.ElementType))
+ return false;
+
+ if (a.GenericArguments.Count != b.GenericArguments.Count)
+ return false;
+
+ if (a.GenericArguments.Count == 0)
+ return true;
+
+ for (int i = 0; i < a.GenericArguments.Count; i++)
+ if (!TypeMatch (a.GenericArguments [i], b.GenericArguments [i]))
+ return false;
+
+ return true;
+ }
+
+ public static bool TypeMatch (TypeReference a, TypeReference b)
+ {
+ if (a is GenericParameter)
+ return true;
+
+ if (a is TypeSpecification || b is TypeSpecification) {
+ if (a.GetType () != b.GetType ())
+ return false;
+
+ return TypeMatch ((TypeSpecification) a, (TypeSpecification) b);
+ }
+
+ return a.FullName == b.FullName;
+ }
}
}
diff --git a/mcs/tools/corcompare/WellFormedXmlWriter.cs b/mcs/tools/corcompare/WellFormedXmlWriter.cs
index 334c57fab33..8f663c657c1 100644
--- a/mcs/tools/corcompare/WellFormedXmlWriter.cs
+++ b/mcs/tools/corcompare/WellFormedXmlWriter.cs
@@ -15,11 +15,6 @@ namespace CorCompare {
public class WellFormedXmlWriter : DefaultXmlWriter
{
- public static bool IsValid (int ch)
- {
- return !IsInvalid (ch);
- }
-
public static bool IsInvalid (int ch)
{
switch (ch) {
diff --git a/mcs/tools/corcompare/mono-api-html/ApiChange.cs b/mcs/tools/corcompare/mono-api-html/ApiChange.cs
index 72e905b8c58..1d902cacfad 100644
--- a/mcs/tools/corcompare/mono-api-html/ApiChange.cs
+++ b/mcs/tools/corcompare/mono-api-html/ApiChange.cs
@@ -21,15 +21,9 @@ namespace Xamarin.ApiDiff
public ApiChange AppendAdded (string text, bool breaking = false)
{
- if (breaking)
- Member.Append ("<span style='text-decoration: underline'>");
- if (State.Colorize)
- Member.Append ("<span style='color:green'>");
+ Member.Append ("<span class='added ").Append (breaking ? "added-breaking-inline" : string.Empty).Append ("'>");
Member.Append (text);
- if (State.Colorize)
- Member.Append ("</span>");
- if (breaking)
- Member.Append ("</span>");
+ Member.Append ("</span>");
Breaking |= breaking;
AnyChange = true;
return this;
@@ -37,12 +31,8 @@ namespace Xamarin.ApiDiff
public ApiChange AppendRemoved (string text, bool breaking = true)
{
- Member.Append ("<span style='text-decoration: line-through'>");
- if (State.Colorize && breaking)
- Member.Append ("<span style='color:red'>");
+ Member.Append ("<span class='removed removed-inline ").Append (breaking ? "removed-breaking-inline" : string.Empty).Append ("'>");
Member.Append (text);
- if (State.Colorize && breaking)
- Member.Append ("</span>");
Member.Append ("</span>");
Breaking |= breaking;
AnyChange = true;
diff --git a/mcs/tools/corcompare/mono-api-html/ApiDiff.cs b/mcs/tools/corcompare/mono-api-html/ApiDiff.cs
index 69454e1184c..8fe27844852 100644
--- a/mcs/tools/corcompare/mono-api-html/ApiDiff.cs
+++ b/mcs/tools/corcompare/mono-api-html/ApiDiff.cs
@@ -168,12 +168,98 @@ namespace Xamarin.ApiDiff {
}
if (diffHtml.Length > 0) {
using (var file = new StreamWriter (diff)) {
+ file.WriteLine ("<div>");
+ if (State.Colorize) {
+ file.WriteLine ("<style scoped>");
+ file.WriteLine ("\t.obsolete { color: gray; }");
+ file.WriteLine ("\t.added { color: green; }");
+ file.WriteLine ("\t.removed-inline { text-decoration: line-through; }");
+ file.WriteLine ("\t.removed-breaking-inline { color: red;}");
+ file.WriteLine ("\t.added-breaking-inline { text-decoration: underline; }");
+ file.WriteLine ("\t.nonbreaking { color: black; }");
+ file.WriteLine ("\t.breaking { color: red; }");
+ file.WriteLine ("</style>");
+ }
+ file.WriteLine (
+@"<script type=""text/javascript"">
+ // Only some elements have 'data-is-[non-]breaking' attributes. Here we
+ // iterate over all descendents elements, and set 'data-is-[non-]breaking'
+ // depending on whether there are any descendents with that attribute.
+ function propagateDataAttribute (element)
+ {
+ if (element.hasAttribute ('data-is-propagated'))
+ return;
+
+ var i;
+ var any_breaking = element.hasAttribute ('data-is-breaking');
+ var any_non_breaking = element.hasAttribute ('data-is-non-breaking');
+ for (i = 0; i < element.children.length; i++) {
+ var el = element.children [i];
+ propagateDataAttribute (el);
+ any_breaking |= el.hasAttribute ('data-is-breaking');
+ any_non_breaking |= el.hasAttribute ('data-is-non-breaking');
+ }
+
+ if (any_breaking)
+ element.setAttribute ('data-is-breaking', null);
+ else if (any_non_breaking)
+ element.setAttribute ('data-is-non-breaking', null);
+ element.setAttribute ('data-is-propagated', null);
+ }
+
+ function hideNonBreakingChanges ()
+ {
+ var topNodes = document.querySelectorAll ('[data-is-topmost]');
+ var n;
+ var i;
+ for (n = 0; n < topNodes.length; n++) {
+ propagateDataAttribute (topNodes [n]);
+ var elements = topNodes [n].querySelectorAll ('[data-is-non-breaking]');
+ for (i = 0; i < elements.length; i++) {
+ var el = elements [i];
+ if (!el.hasAttribute ('data-original-display'))
+ el.setAttribute ('data-original-display', el.style.display);
+ el.style.display = 'none';
+ }
+ }
+
+ var links = document.getElementsByClassName ('hide-nonbreaking');
+ for (i = 0; i < links.length; i++)
+ links [i].style.display = 'none';
+ links = document.getElementsByClassName ('restore-nonbreaking');
+ for (i = 0; i < links.length; i++)
+ links [i].style.display = '';
+ }
+
+ function showNonBreakingChanges ()
+ {
+ var elements = document.querySelectorAll ('[data-original-display]');
+ var i;
+ for (i = 0; i < elements.length; i++) {
+ var el = elements [i];
+ el.style.display = el.getAttribute ('data-original-display');
+ }
+
+ var links = document.getElementsByClassName ('hide-nonbreaking');
+ for (i = 0; i < links.length; i++)
+ links [i].style.display = '';
+ links = document.getElementsByClassName ('restore-nonbreaking');
+ for (i = 0; i < links.length; i++)
+ links [i].style.display = 'none';
+ }
+</script>");
if (ac.SourceAssembly == ac.TargetAssembly) {
file.WriteLine ("<h1>{0}.dll</h1>", ac.SourceAssembly);
} else {
file.WriteLine ("<h1>{0}.dll vs {1}.dll</h1>", ac.SourceAssembly, ac.TargetAssembly);
}
+ file.WriteLine ("<a href='javascript: hideNonBreakingChanges (); ' class='hide-nonbreaking'>Hide non-breaking changes</a>");
+ file.WriteLine ("<a href='javascript: showNonBreakingChanges (); ' class='restore-nonbreaking' style='display: none;'>Show non-breaking changes</a>");
+ file.WriteLine ("<br/>");
+ file.WriteLine ("<div data-is-topmost>");
file.Write (diffHtml);
+ file.WriteLine ("</div> <!-- end topmost div -->");
+ file.WriteLine ("</div>");
}
}
} else {
diff --git a/mcs/tools/corcompare/mono-api-html/AssemblyComparer.cs b/mcs/tools/corcompare/mono-api-html/AssemblyComparer.cs
index ff5326d9c8b..adbd862eb92 100644
--- a/mcs/tools/corcompare/mono-api-html/AssemblyComparer.cs
+++ b/mcs/tools/corcompare/mono-api-html/AssemblyComparer.cs
@@ -57,7 +57,7 @@ namespace Xamarin.ApiDiff {
State.Assembly = current.GetAttribute ("name");
}
- public override void Added (XElement target)
+ public override void Added (XElement target, bool wasParentAdded)
{
// one assembly per xml file
}
diff --git a/mcs/tools/corcompare/mono-api-html/ClassComparer.cs b/mcs/tools/corcompare/mono-api-html/ClassComparer.cs
index 761f87a5552..a3399fbef04 100644
--- a/mcs/tools/corcompare/mono-api-html/ClassComparer.cs
+++ b/mcs/tools/corcompare/mono-api-html/ClassComparer.cs
@@ -67,16 +67,18 @@ namespace Xamarin.ApiDiff {
Compare (s.Elements ("class"), t.Elements ("class"));
}
- public override void Added (XElement target)
+ public override void Added (XElement target, bool wasParentAdded)
{
string name = target.Attribute ("name").Value;
if (State.IgnoreNew.Any (re => re.IsMatch (name)))
return;
+ Output.WriteLine ("<div> <!-- start type {0} -->", name);
Output.WriteLine ("<h3>New Type {0}.{1}</h3>", State.Namespace, name);
- Output.WriteLine (State.Colorize ? "<pre style='color: green'>" : "<pre>");
+ Output.WriteLine ("<pre class='added' data-is-non-breaking>");
State.Indent = 0;
AddedInner (target);
Output.WriteLine ("</pre>");
+ Output.WriteLine ("</div> <!-- end type {0} -->", name);
}
public void AddedInner (XElement target)
@@ -149,7 +151,7 @@ namespace Xamarin.ApiDiff {
if (t != null) {
Indent ().WriteLine ("\t// constructors");
foreach (var ctor in t.Elements ("constructor"))
- ccomparer.Added (ctor);
+ ccomparer.Added (ctor, true);
}
t = target.Element ("fields");
@@ -159,28 +161,28 @@ namespace Xamarin.ApiDiff {
else
SetContext (target);
foreach (var field in t.Elements ("field"))
- fcomparer.Added (field);
+ fcomparer.Added (field, true);
}
t = target.Element ("properties");
if (t != null) {
Indent ().WriteLine ("\t// properties");
foreach (var property in t.Elements ("property"))
- pcomparer.Added (property);
+ pcomparer.Added (property, true);
}
t = target.Element ("events");
if (t != null) {
Indent ().WriteLine ("\t// events");
foreach (var evnt in t.Elements ("event"))
- ecomparer.Added (evnt);
+ ecomparer.Added (evnt, true);
}
t = target.Element ("methods");
if (t != null) {
Indent ().WriteLine ("\t// methods");
foreach (var method in t.Elements ("method"))
- mcomparer.Added (method);
+ mcomparer.Added (method, true);
}
t = target.Element ("classes");
@@ -226,17 +228,17 @@ namespace Xamarin.ApiDiff {
var s = (Output as StringWriter).ToString ();
State.Output = output;
if (s.Length > 0) {
+ var tn = GetTypeName (target);
+ Output.WriteLine ("<!-- start type {0} --> <div>", tn);
Output.WriteLine ("<h3>Type Changed: {0}.{1}</h3>", State.Namespace, GetTypeName (target));
Output.WriteLine (s);
+ Output.WriteLine ("</div> <!-- end type {0} -->", tn);
}
}
public override void Removed (XElement source)
{
- var style = string.Empty;
- if (State.Colorize)
- style = "style='color: red'";
- Output.Write ("<h3>Removed Type <span {0}>{1}.{2}</span></h3>", style, State.Namespace, GetTypeName (source));
+ Output.Write ("<h3>Removed Type <span class='breaking' data-is-breaking>{0}.{1}</span></h3>", State.Namespace, GetTypeName (source));
}
public virtual string GetTypeName (XElement type)
diff --git a/mcs/tools/corcompare/mono-api-html/Comparer.cs b/mcs/tools/corcompare/mono-api-html/Comparer.cs
index 8c692a03a9a..4210b9b95fb 100644
--- a/mcs/tools/corcompare/mono-api-html/Comparer.cs
+++ b/mcs/tools/corcompare/mono-api-html/Comparer.cs
@@ -48,7 +48,7 @@ namespace Xamarin.ApiDiff {
return State.Output;
}
- public abstract void Added (XElement target);
+ public abstract void Added (XElement target, bool wasParentAdded);
public abstract void Modified (XElement source, XElement target, ApiChanges changes);
public abstract void Removed (XElement source);
@@ -90,7 +90,7 @@ namespace Xamarin.ApiDiff {
if (target != null) {
foreach (var item in target) {
SetContext (item);
- Added (item);
+ Added (item, false);
}
}
}
diff --git a/mcs/tools/corcompare/mono-api-html/FieldComparer.cs b/mcs/tools/corcompare/mono-api-html/FieldComparer.cs
index bb4f6c6b075..a2b0225b448 100644
--- a/mcs/tools/corcompare/mono-api-html/FieldComparer.cs
+++ b/mcs/tools/corcompare/mono-api-html/FieldComparer.cs
@@ -189,8 +189,9 @@ namespace Xamarin.ApiDiff {
{
first = true;
if (State.BaseType == "System.Enum") {
+ Output.WriteLine ("<div>");
Output.WriteLine ("<p>Added value{0}:</p>", list.Count () > 1 ? "s" : String.Empty);
- Output.WriteLine (State.Colorize ? "<pre style='color: green'>" : "<pre>");
+ Output.WriteLine ("<pre class='added' data-is-non-breaking>");
} else {
base.BeforeAdding (list);
}
@@ -201,7 +202,7 @@ namespace Xamarin.ApiDiff {
first = true;
if (State.BaseType == "System.Enum") {
Output.WriteLine ("<p>Removed value{0}:</p>", list.Count () > 1 ? "s" : String.Empty);
- Output.WriteLine (State.Colorize ? "<pre style='color: red'>" : "<pre>");
+ Output.WriteLine ("<pre class='removed' data-is-breaking>");
} else {
base.BeforeRemoving (list);
}
diff --git a/mcs/tools/corcompare/mono-api-html/MemberComparer.cs b/mcs/tools/corcompare/mono-api-html/MemberComparer.cs
index dee528ebc7a..d12d86625c2 100644
--- a/mcs/tools/corcompare/mono-api-html/MemberComparer.cs
+++ b/mcs/tools/corcompare/mono-api-html/MemberComparer.cs
@@ -41,6 +41,11 @@ namespace Xamarin.ApiDiff {
public abstract string GroupName { get; }
public abstract string ElementName { get; }
+ protected virtual bool IsBreakingRemoval (XElement e)
+ {
+ return true;
+ }
+
public void Compare (XElement source, XElement target)
{
var s = source.Element (GroupName);
@@ -124,7 +129,7 @@ namespace Xamarin.ApiDiff {
BeforeAdding (elements);
a = true;
}
- Added (item);
+ Added (item, false);
}
if (a)
AfterAdding ();
@@ -136,8 +141,10 @@ namespace Xamarin.ApiDiff {
Output.WriteLine ("<p>{0}:</p>", changes.Key);
Output.WriteLine ("<pre>");
foreach (var element in changes.Value) {
+ Output.Write ("<div {0}>", element.Breaking ? "data-is-breaking" : "data-is-non-breaking");
foreach (var line in element.Member.ToString ().Split ('\n'))
Output.WriteLine ("\t{0}", line);
+ Output.Write ("</div>");
}
Output.WriteLine ("</pre>");
@@ -192,24 +199,28 @@ namespace Xamarin.ApiDiff {
public virtual void BeforeAdding (IEnumerable<XElement> list)
{
first = true;
+ Output.WriteLine ("<div>");
Output.WriteLine ("<p>Added {0}:</p>", list.Count () > 1 ? GroupName : ElementName);
-
- bool isInterface = list.Count () > 0 && IsInInterface (list.First ());
- Output.WriteLine (State.Colorize ? string.Format ("<pre style='color: {0}'>", isInterface ? "red" : "green") : "<pre>");
+ Output.WriteLine ("<pre>");
}
- public override void Added (XElement target)
+ public override void Added (XElement target, bool wasParentAdded)
{
var o = GetObsoleteMessage (target);
if (!first && (o.Length > 0))
Output.WriteLine ();
- Indent ().WriteLine ("\t{0}{1}", o, GetDescription (target));
+ Indent ();
+ bool isInterfaceBreakingChange = !wasParentAdded && IsInInterface (target);
+ Output.Write ("\t<span class='added added-{0} {1}' {2}>", ElementName, isInterfaceBreakingChange ? "breaking" : string.Empty, isInterfaceBreakingChange ? "data-is-breaking" : "data-is-non-breaking");
+ Output.Write ("{0}{1}", o, GetDescription (target));
+ Output.WriteLine ("</span>");
first = false;
}
public virtual void AfterAdding ()
{
- Output.WriteLine ("</pre>");;
+ Output.WriteLine ("</pre>");
+ Output.WriteLine ("</div>");
}
public override void Modified (XElement source, XElement target, ApiChanges change)
@@ -220,7 +231,7 @@ namespace Xamarin.ApiDiff {
{
first = true;
Output.WriteLine ("<p>Removed {0}:</p>\n", list.Count () > 1 ? GroupName : ElementName);
- Output.WriteLine (State.Colorize ? "<pre style='color: red'>" : "<pre>");
+ Output.WriteLine ("<pre>");
}
public override void Removed (XElement source)
@@ -228,7 +239,13 @@ namespace Xamarin.ApiDiff {
var o = GetObsoleteMessage (source);
if (!first && (o.Length > 0))
Output.WriteLine ();
- Indent ().WriteLine ("\t{0}{1}", o, GetDescription (source));
+
+ bool is_breaking = IsBreakingRemoval (source);
+
+ Indent ();
+ Output.Write ("\t<span class='removed removed-{0} {2}' {1}>", ElementName, is_breaking ? "data-is-breaking" : "data-is-non-breaking", is_breaking ? "breaking" : string.Empty);
+ Output.Write ("{0}{1}", o, GetDescription (source));
+ Output.WriteLine ("</span>");
first = false;
}
@@ -558,15 +575,13 @@ namespace Xamarin.ApiDiff {
return; // neither is obsolete
var change = new ApiChange ();
change.Header = "Obsoleted " + GroupName;
- if (State.Colorize)
- change.Append ("<span style='color:gray'>");
+ change.Append (string.Format ("<span class='obsolete obsolete-{0}' data-is-non-breaking>", ElementName));
change.Append ("[Obsolete (");
if (tgtObsolete != string.Empty)
change.Append ("\"").Append (tgtObsolete).Append ("\"");
change.Append (")]\n");
change.Append (GetDescription (target));
- if (State.Colorize)
- change.Append ("</span>");
+ change.Append ("</span>");
change.AnyChange = true;
changes.Add (source, target, change);
} else if (tgtObsolete == null) {
diff --git a/mcs/tools/corcompare/mono-api-html/MethodComparer.cs b/mcs/tools/corcompare/mono-api-html/MethodComparer.cs
index 1dffa17dfcc..4c893e757ec 100644
--- a/mcs/tools/corcompare/mono-api-html/MethodComparer.cs
+++ b/mcs/tools/corcompare/mono-api-html/MethodComparer.cs
@@ -26,6 +26,7 @@
using System;
using System.Linq;
+using System.Reflection;
using System.Xml.Linq;
namespace Xamarin.ApiDiff {
@@ -62,5 +63,15 @@ namespace Xamarin.ApiDiff {
return eGPs.Count () == sGPs.Count ();
}
}
+
+ protected override bool IsBreakingRemoval (XElement e)
+ {
+ // Removing virtual methods that override another method is not a breaking change.
+ var is_override = e.Attribute ("is-override");
+ if (is_override != null)
+ return is_override.Value != "true";
+
+ return true; // all other removals are breaking changes
+ }
}
} \ No newline at end of file
diff --git a/mcs/tools/corcompare/mono-api-html/NamespaceComparer.cs b/mcs/tools/corcompare/mono-api-html/NamespaceComparer.cs
index 258374c6b9d..063e34ecbf7 100644
--- a/mcs/tools/corcompare/mono-api-html/NamespaceComparer.cs
+++ b/mcs/tools/corcompare/mono-api-html/NamespaceComparer.cs
@@ -55,17 +55,19 @@ namespace Xamarin.ApiDiff {
State.Namespace = current.Attribute ("name").Value;
}
- public override void Added (XElement target)
+ public override void Added (XElement target, bool wasParentAdded)
{
string name = target.Attribute ("name").Value;
if (State.IgnoreNew.Any (re => re.IsMatch (name)))
return;
+ Output.WriteLine ("<!-- start namespace {0} --> <div> ", name);
Output.WriteLine ("<h2>New Namespace {0}</h2>", name);
Output.WriteLine ();
// list all new types
foreach (var addedType in target.Element ("classes").Elements ("class"))
- comparer.Added (addedType);
+ comparer.Added (addedType, true);
+ Output.WriteLine ("</div> <!-- end namespace {0} -->", name);
Output.WriteLine ();
}
@@ -78,18 +80,24 @@ namespace Xamarin.ApiDiff {
var s = Output.ToString ();
State.Output = output;
if (s.Length > 0) {
- Output.WriteLine ("<h2>Namespace {0}</h2>", target.Attribute ("name").Value);
+ var name = target.Attribute ("name").Value;
+ Output.WriteLine ("<!-- start namespace {0} --> <div> ", name);
+ Output.WriteLine ("<h2>Namespace {0}</h2>", name);
Output.WriteLine (s);
+ Output.WriteLine ("</div> <!-- end namespace {0} -->", name);
}
}
public override void Removed (XElement source)
{
- Output.WriteLine ("<h2>Removed Namespace {0}</h2>", source.Attribute ("name").Value);
+ var name = source.Attribute ("name").Value;
+ Output.WriteLine ("<!-- start namespace {0} --> <div>", name);
+ Output.WriteLine ("<h2>Removed Namespace {0}</h2>", name);
Output.WriteLine ();
// list all removed types
foreach (var removedType in source.Element ("classes").Elements ("class"))
comparer.Removed (removedType);
+ Output.WriteLine ("</div> <!-- end namespace {0} -->", name);
Output.WriteLine ();
}
}
diff --git a/mcs/tools/corcompare/mono-api-html/mono-api-html.csproj b/mcs/tools/corcompare/mono-api-html/mono-api-html.csproj
index 286a4d0192a..6ac0f241ade 100644
--- a/mcs/tools/corcompare/mono-api-html/mono-api-html.csproj
+++ b/mcs/tools/corcompare/mono-api-html/mono-api-html.csproj
@@ -19,7 +19,6 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
- <Commandlineparameters>/Developer/MonoTouch/Source/monotouch/tools/apidiff/references/compat/monotouch.xml /Developer/MonoTouch/Source/monotouch/tools/apidiff/temp/compat/monotouch.xml -i INSObjectProtocol /tmp/diff.html</Commandlineparameters>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
diff --git a/mcs/tools/corcompare/mono-api-info.cs b/mcs/tools/corcompare/mono-api-info.cs
index 0886d14b3bd..8b1ad945095 100644
--- a/mcs/tools/corcompare/mono-api-info.cs
+++ b/mcs/tools/corcompare/mono-api-info.cs
@@ -93,18 +93,20 @@ namespace CorCompare
}
}
- XmlDocument doc = new XmlDocument ();
- acoll.Document = doc;
- acoll.DoOutput ();
-
- TextWriter outputStream = null;
+ StreamWriter outputStream = null;
if (!string.IsNullOrEmpty (output))
outputStream = new StreamWriter (output);
try {
- var writer = new WellFormedXmlWriter (new XmlTextWriter (outputStream ?? Console.Out) { Formatting = Formatting.Indented });
- XmlNode decl = doc.CreateXmlDeclaration ("1.0", "utf-8", null);
- doc.InsertBefore (decl, doc.DocumentElement);
- doc.WriteTo (writer);
+ TextWriter outStream = outputStream ?? Console.Out;
+ var settings = new XmlWriterSettings ();
+ settings.Indent = true;
+ var textWriter = XmlWriter.Create (outStream, settings);
+ var writer = new WellFormedXmlWriter (textWriter);
+ writer.WriteStartDocument ();
+ acoll.Writer = writer;
+ acoll.DoOutput ();
+ writer.WriteEndDocument ();
+ writer.Flush ();
} finally {
if (outputStream != null)
outputStream.Dispose ();
@@ -117,6 +119,7 @@ namespace CorCompare
}
public class Utils {
+ static char[] CharsToCleanup = new char[] { '<', '>', '/' };
public static string CleanupTypeName (TypeReference type)
{
@@ -125,13 +128,33 @@ namespace CorCompare
public static string CleanupTypeName (string t)
{
- return t.Replace ('<', '[').Replace ('>', ']').Replace ('/', '+');
+ if (t.IndexOfAny (CharsToCleanup) == -1)
+ return t;
+ var sb = new StringBuilder (t.Length);
+ for (int i = 0; i < t.Length; i++) {
+ var ch = t [i];
+ switch (ch) {
+ case '<':
+ sb.Append ('[');
+ break;
+ case '>':
+ sb.Append (']');
+ break;
+ case '/':
+ sb.Append ('+');
+ break;
+ default:
+ sb.Append (ch);
+ break;
+ }
+ }
+ return sb.ToString ();
}
}
class AssemblyCollection
{
- XmlDocument document;
+ XmlWriter writer;
List<AssemblyDefinition> assemblies = new List<AssemblyDefinition> ();
public AssemblyCollection ()
@@ -152,19 +175,19 @@ namespace CorCompare
public void DoOutput ()
{
- if (document == null)
+ if (writer == null)
throw new InvalidOperationException ("Document not set");
- XmlNode nassemblies = document.CreateElement ("assemblies", null);
- document.AppendChild (nassemblies);
+ writer.WriteStartElement ("assemblies");
foreach (AssemblyDefinition a in assemblies) {
- AssemblyData data = new AssemblyData (document, nassemblies, a);
+ AssemblyData data = new AssemblyData (writer, a);
data.DoOutput ();
}
+ writer.WriteEndElement ();
}
- public XmlDocument Document {
- set { document = value; }
+ public XmlWriter Writer {
+ set { writer = value; }
}
AssemblyDefinition LoadAssembly (string assembly)
@@ -183,22 +206,18 @@ namespace CorCompare
abstract class BaseData
{
- protected XmlDocument document;
- protected XmlNode parent;
+ protected XmlWriter writer;
- protected BaseData (XmlDocument doc, XmlNode parent)
+ protected BaseData (XmlWriter writer)
{
- this.document = doc;
- this.parent = parent;
+ this.writer = writer;
}
public abstract void DoOutput ();
- protected void AddAttribute (XmlNode node, string name, string value)
+ protected void AddAttribute (string name, string value)
{
- XmlAttribute attr = document.CreateAttribute (name);
- attr.Value = value;
- node.Attributes.Append (attr);
+ writer.WriteAttributeString (name, value);
}
}
@@ -206,38 +225,34 @@ namespace CorCompare
{
AssemblyDefinition ass;
- public TypeForwardedToData (XmlDocument document, XmlNode parent, AssemblyDefinition ass)
- : base (document, parent)
+ public TypeForwardedToData (XmlWriter writer, AssemblyDefinition ass)
+ : base (writer)
{
this.ass = ass;
}
public override void DoOutput ()
{
- XmlNode natts = parent.SelectSingleNode("attributes");
- if (natts == null) {
- natts = document.CreateElement ("attributes", null);
- parent.AppendChild (natts);
- }
-
foreach (ExportedType type in ass.MainModule.ExportedTypes) {
if (((uint)type.Attributes & 0x200000u) == 0)
continue;
- XmlNode node = document.CreateElement ("attribute");
- AddAttribute (node, "name", typeof (TypeForwardedToAttribute).FullName);
- XmlNode properties = node.AppendChild (document.CreateElement ("properties"));
- XmlNode property = properties.AppendChild (document.CreateElement ("property"));
- AddAttribute (property, "name", "Destination");
- AddAttribute (property, "value", Utils.CleanupTypeName (type.FullName));
- natts.AppendChild (node);
+ writer.WriteStartElement ("attribute");
+ AddAttribute ("name", typeof (TypeForwardedToAttribute).FullName);
+ writer.WriteStartElement ("properties");
+ writer.WriteStartElement ("property");
+ AddAttribute ("name", "Destination");
+ AddAttribute ("value", Utils.CleanupTypeName (type.FullName));
+ writer.WriteEndElement (); // properties
+ writer.WriteEndElement (); // properties
+ writer.WriteEndElement (); // attribute
}
}
- public static void OutputForwarders (XmlDocument document, XmlNode parent, AssemblyDefinition ass)
+ public static void OutputForwarders (XmlWriter writer, AssemblyDefinition ass)
{
- TypeForwardedToData tftd = new TypeForwardedToData (document, parent, ass);
+ TypeForwardedToData tftd = new TypeForwardedToData (writer, ass);
tftd.DoOutput ();
}
}
@@ -246,28 +261,23 @@ namespace CorCompare
{
AssemblyDefinition ass;
- public AssemblyData (XmlDocument document, XmlNode parent, AssemblyDefinition ass)
- : base (document, parent)
+ public AssemblyData (XmlWriter writer, AssemblyDefinition ass)
+ : base (writer)
{
this.ass = ass;
}
public override void DoOutput ()
{
- if (document == null)
+ if (writer == null)
throw new InvalidOperationException ("Document not set");
- XmlNode nassembly = document.CreateElement ("assembly", null);
+ writer.WriteStartElement ("assembly");
AssemblyNameDefinition aname = ass.Name;
- AddAttribute (nassembly, "name", aname.Name);
- AddAttribute (nassembly, "version", aname.Version.ToString ());
- parent.AppendChild (nassembly);
-
- if (!Driver.FollowForwarders) {
- TypeForwardedToData.OutputForwarders (document, nassembly, ass);
- }
+ AddAttribute ("name", aname.Name);
+ AddAttribute ("version", aname.Version.ToString ());
- AttributeData.OutputAttributes (document, nassembly, ass);
+ AttributeData.OutputAttributes (writer, ass);
var types = new List<TypeDefinition> ();
if (ass.MainModule.Types != null) {
@@ -285,17 +295,16 @@ namespace CorCompare
}
if (types.Count == 0) {
+ writer.WriteEndElement (); // assembly
return;
}
types.Sort (TypeReferenceComparer.Default);
- XmlNode nss = document.CreateElement ("namespaces", null);
- nassembly.AppendChild (nss);
+ writer.WriteStartElement ("namespaces");
string current_namespace = "$%&$&";
- XmlNode ns = null;
- XmlNode classes = null;
+ bool in_namespace = false;
foreach (TypeDefinition t in types) {
if (string.IsNullOrEmpty (t.Namespace))
continue;
@@ -308,16 +317,30 @@ namespace CorCompare
if (t.Namespace != current_namespace) {
current_namespace = t.Namespace;
- ns = document.CreateElement ("namespace", null);
- AddAttribute (ns, "name", current_namespace);
- nss.AppendChild (ns);
- classes = document.CreateElement ("classes", null);
- ns.AppendChild (classes);
+ if (in_namespace) {
+ writer.WriteEndElement (); // classes
+ writer.WriteEndElement (); // namespace
+ } else {
+ in_namespace = true;
+ }
+ writer.WriteStartElement ("namespace");
+ AddAttribute ("name", current_namespace);
+ writer.WriteStartElement ("classes");
}
- TypeData bd = new TypeData (document, classes, t);
+ TypeData bd = new TypeData (writer, t);
bd.DoOutput ();
+
}
+
+ if (in_namespace) {
+ writer.WriteEndElement (); // classes
+ writer.WriteEndElement (); // namespace
+ }
+
+ writer.WriteEndElement (); // namespaces
+
+ writer.WriteEndElement (); // assembly
}
}
@@ -325,31 +348,42 @@ namespace CorCompare
{
MemberReference [] members;
- public MemberData (XmlDocument document, XmlNode parent, MemberReference [] members)
- : base (document, parent)
+ public MemberData (XmlWriter writer, MemberReference [] members)
+ : base (writer)
{
this.members = members;
}
+ protected virtual ICustomAttributeProvider GetAdditionalCustomAttributeProvider (MemberReference member)
+ {
+ return null;
+ }
+
public override void DoOutput ()
{
- XmlNode mclass = document.CreateElement (ParentTag, null);
- parent.AppendChild (mclass);
+ writer.WriteStartElement (ParentTag);
foreach (MemberReference member in members) {
- XmlNode mnode = document.CreateElement (Tag, null);
- mclass.AppendChild (mnode);
- AddAttribute (mnode, "name", GetName (member));
+ writer.WriteStartElement (Tag);
+ AddAttribute ("name", GetName (member));
if (!NoMemberAttributes)
- AddAttribute (mnode, "attrib", GetMemberAttributes (member));
+ AddAttribute ("attrib", GetMemberAttributes (member));
+ AddExtraAttributes (member);
- AttributeData.OutputAttributes (document, mnode, (ICustomAttributeProvider) member);
+ AttributeData.OutputAttributes (writer, (ICustomAttributeProvider) member, GetAdditionalCustomAttributeProvider (member));
- AddExtraData (mnode, member);
+ AddExtraData (member);
+ writer.WriteEndElement (); // Tag
}
+
+ writer.WriteEndElement (); // ParentTag
+ }
+
+ protected virtual void AddExtraData (MemberReference memberDefenition)
+ {
}
- protected virtual void AddExtraData (XmlNode p, MemberReference memberDefenition)
+ protected virtual void AddExtraAttributes (MemberReference memberDefinition)
{
}
@@ -376,39 +410,42 @@ namespace CorCompare
get { return "NoTAG"; }
}
- public static void OutputGenericParameters (XmlDocument document, XmlNode nclass, IGenericParameterProvider provider)
+ public static void OutputGenericParameters (XmlWriter writer, IGenericParameterProvider provider)
{
if (provider.GenericParameters.Count == 0)
return;
var gparameters = provider.GenericParameters;
- XmlElement ngeneric = document.CreateElement ("generic-parameters");
- nclass.AppendChild (ngeneric);
+ writer.WriteStartElement ("generic-parameters");
foreach (GenericParameter gp in gparameters) {
- XmlElement nparam = document.CreateElement ("generic-parameter");
- nparam.SetAttribute ("name", gp.Name);
- nparam.SetAttribute ("attributes", ((int) gp.Attributes).ToString ());
+ writer.WriteStartElement ("generic-parameter");
+ writer.WriteAttributeString ("name", gp.Name);
+ writer.WriteAttributeString ("attributes", ((int) gp.Attributes).ToString ());
- AttributeData.OutputAttributes (document, nparam, gp);
-
- ngeneric.AppendChild (nparam);
+ AttributeData.OutputAttributes (writer, gp);
var constraints = gp.Constraints;
- if (constraints.Count == 0)
+ if (constraints.Count == 0) {
+ writer.WriteEndElement (); // generic-parameter
continue;
+ }
- XmlElement nconstraint = document.CreateElement ("generic-parameter-constraints");
+ writer.WriteStartElement ("generic-parameter-constraints");
foreach (TypeReference constraint in constraints) {
- XmlElement ncons = document.CreateElement ("generic-parameter-constraint");
- ncons.SetAttribute ("name", Utils.CleanupTypeName (constraint));
- nconstraint.AppendChild (ncons);
+ writer.WriteStartElement ("generic-parameter-constraint");
+ writer.WriteAttributeString ("name", Utils.CleanupTypeName (constraint));
+ writer.WriteEndElement (); // generic-parameter-constraint
}
- nparam.AppendChild (nconstraint);
+ writer.WriteEndElement (); // generic-parameter-constraints
+
+ writer.WriteEndElement (); // generic-parameter
}
+
+ writer.WriteEndElement (); // generic-parameters
}
}
@@ -416,112 +453,107 @@ namespace CorCompare
{
TypeDefinition type;
- public TypeData (XmlDocument document, XmlNode parent, TypeDefinition type)
- : base (document, parent, null)
+ public TypeData (XmlWriter writer, TypeDefinition type)
+ : base (writer, null)
{
this.type = type;
}
public override void DoOutput ()
{
- if (document == null)
+ if (writer == null)
throw new InvalidOperationException ("Document not set");
- XmlNode nclass = document.CreateElement ("class", null);
- AddAttribute (nclass, "name", type.Name);
+ writer.WriteStartElement ("class");
+ AddAttribute ("name", type.Name);
string classType = GetClassType (type);
- AddAttribute (nclass, "type", classType);
+ AddAttribute ("type", classType);
if (type.BaseType != null)
- AddAttribute (nclass, "base", Utils.CleanupTypeName (type.BaseType));
+ AddAttribute ("base", Utils.CleanupTypeName (type.BaseType));
if (type.IsSealed)
- AddAttribute (nclass, "sealed", "true");
+ AddAttribute ("sealed", "true");
if (type.IsAbstract)
- AddAttribute (nclass, "abstract", "true");
+ AddAttribute ("abstract", "true");
if ( (type.Attributes & TypeAttributes.Serializable) != 0 || type.IsEnum)
- AddAttribute (nclass, "serializable", "true");
+ AddAttribute ("serializable", "true");
string charSet = GetCharSet (type);
- AddAttribute (nclass, "charset", charSet);
+ AddAttribute ("charset", charSet);
string layout = GetLayout (type);
if (layout != null)
- AddAttribute (nclass, "layout", layout);
+ AddAttribute ("layout", layout);
if (type.PackingSize >= 0) {
- AddAttribute (nclass, "pack", type.PackingSize.ToString ());
+ AddAttribute ("pack", type.PackingSize.ToString ());
}
if (type.ClassSize >= 0) {
- AddAttribute (nclass, "size", type.ClassSize.ToString ());
+ AddAttribute ("size", type.ClassSize.ToString ());
}
- parent.AppendChild (nclass);
+ if (type.IsEnum) {
+ var value_type = GetEnumValueField (type);
+ if (value_type == null)
+ throw new NotSupportedException ();
- AttributeData.OutputAttributes (document, nclass, type);
+ AddAttribute ("enumtype", Utils.CleanupTypeName (value_type.FieldType));
+ }
- XmlNode ifaces = null;
+ AttributeData.OutputAttributes (writer, type);
- foreach (TypeReference iface in TypeHelper.GetInterfaces (type).OrderBy (s => s.FullName)) {
- if (!TypeHelper.IsPublic (iface))
- // we're only interested in public interfaces
- continue;
+ var ifaces = TypeHelper.GetInterfaces (type).
+ Where ((iface) => TypeHelper.IsPublic (iface)). // we're only interested in public interfaces
+ OrderBy (s => s.FullName, StringComparer.Ordinal);
- if (ifaces == null) {
- ifaces = document.CreateElement ("interfaces", null);
- nclass.AppendChild (ifaces);
+ if (ifaces.Any ()) {
+ writer.WriteStartElement ("interfaces");
+ foreach (TypeReference iface in ifaces) {
+ writer.WriteStartElement ("interface");
+ AddAttribute ("name", Utils.CleanupTypeName (iface));
+ writer.WriteEndElement (); // interface
}
-
- XmlNode iface_node = document.CreateElement ("interface", null);
- AddAttribute (iface_node, "name", Utils.CleanupTypeName (iface));
- ifaces.AppendChild (iface_node);
+ writer.WriteEndElement (); // interfaces
}
- MemberData.OutputGenericParameters (document, nclass, type);
+ MemberData.OutputGenericParameters (writer, type);
ArrayList members = new ArrayList ();
FieldDefinition [] fields = GetFields (type);
if (fields.Length > 0) {
Array.Sort (fields, MemberReferenceComparer.Default);
- FieldData fd = new FieldData (document, nclass, fields);
+ FieldData fd = new FieldData (writer, fields);
members.Add (fd);
}
- if (type.IsEnum) {
- var value_type = GetEnumValueField (type);
- if (value_type == null)
- throw new NotSupportedException ();
-
- AddAttribute (nclass, "enumtype", Utils.CleanupTypeName (value_type.FieldType));
- }
-
if (!Driver.AbiMode) {
MethodDefinition [] ctors = GetConstructors (type);
if (ctors.Length > 0) {
Array.Sort (ctors, MethodDefinitionComparer.Default);
- members.Add (new ConstructorData (document, nclass, ctors));
+ members.Add (new ConstructorData (writer, ctors));
}
PropertyDefinition[] properties = GetProperties (type);
if (properties.Length > 0) {
Array.Sort (properties, PropertyDefinitionComparer.Default);
- members.Add (new PropertyData (document, nclass, properties));
+ members.Add (new PropertyData (writer, properties));
}
EventDefinition [] events = GetEvents (type);
if (events.Length > 0) {
Array.Sort (events, MemberReferenceComparer.Default);
- members.Add (new EventData (document, nclass, events));
+ members.Add (new EventData (writer, events));
}
MethodDefinition [] methods = GetMethods (type);
if (methods.Length > 0) {
Array.Sort (methods, MethodDefinitionComparer.Default);
- members.Add (new MethodData (document, nclass, methods));
+ members.Add (new MethodData (writer, methods));
}
}
@@ -547,13 +579,15 @@ namespace CorCompare
var nestedArray = nested.ToArray ();
Array.Sort (nestedArray, TypeReferenceComparer.Default);
- XmlNode classes = document.CreateElement ("classes", null);
- nclass.AppendChild (classes);
+ writer.WriteStartElement ("classes");
foreach (TypeDefinition t in nestedArray) {
- TypeData td = new TypeData (document, classes, t);
+ TypeData td = new TypeData (writer, t);
td.DoOutput ();
}
+ writer.WriteEndElement (); // classes
}
+
+ writer.WriteEndElement (); // class
}
static FieldReference GetEnumValueField (TypeDefinition type)
@@ -686,7 +720,7 @@ namespace CorCompare
var methods = type.Methods;//type.GetMethods (flags);
foreach (MethodDefinition method in methods) {
- if (method.IsSpecialName && !method.Name.StartsWith ("op_"))
+ if (method.IsSpecialName && !method.Name.StartsWith ("op_", StringComparison.Ordinal))
continue;
// we're only interested in public or protected members
@@ -758,8 +792,8 @@ namespace CorCompare
class FieldData : MemberData
{
- public FieldData (XmlDocument document, XmlNode parent, FieldDefinition [] members)
- : base (document, parent, members)
+ public FieldData (XmlWriter writer, FieldDefinition [] members)
+ : base (writer, members)
{
}
@@ -775,11 +809,12 @@ namespace CorCompare
return ((int) field.Attributes).ToString (CultureInfo.InvariantCulture);
}
- protected override void AddExtraData (XmlNode p, MemberReference memberDefenition)
+ protected override void AddExtraAttributes (MemberReference memberDefinition)
{
- base.AddExtraData (p, memberDefenition);
- FieldDefinition field = (FieldDefinition) memberDefenition;
- AddAttribute (p, "fieldtype", Utils.CleanupTypeName (field.FieldType));
+ base.AddExtraAttributes (memberDefinition);
+
+ FieldDefinition field = (FieldDefinition) memberDefinition;
+ AddAttribute ("fieldtype", Utils.CleanupTypeName (field.FieldType));
if (field.IsLiteral) {
object value = field.Constant;//object value = field.GetValue (null);
@@ -791,11 +826,11 @@ namespace CorCompare
// stringValue = ((Enum) value).ToString ("D", CultureInfo.InvariantCulture);
//}
//else {
- stringValue = Convert.ToString (value, CultureInfo.InvariantCulture);
+ stringValue = Convert.ToString (value, CultureInfo.InvariantCulture);
//}
if (stringValue != null)
- AddAttribute (p, "value", stringValue);
+ AddAttribute ("value", stringValue);
}
}
@@ -810,8 +845,8 @@ namespace CorCompare
class PropertyData : MemberData
{
- public PropertyData (XmlDocument document, XmlNode parent, PropertyDefinition [] members)
- : base (document, parent, members)
+ public PropertyData (XmlWriter writer, PropertyDefinition [] members)
+ : base (writer, members)
{
}
@@ -821,15 +856,13 @@ namespace CorCompare
return prop.Name;
}
- protected override void AddExtraData (XmlNode p, MemberReference memberDefenition)
+ MethodDefinition [] GetMethods (PropertyDefinition prop, out bool haveParameters)
{
- base.AddExtraData (p, memberDefenition);
- PropertyDefinition prop = (PropertyDefinition) memberDefenition;
- AddAttribute (p, "ptype", Utils.CleanupTypeName (prop.PropertyType));
MethodDefinition _get = prop.GetMethod;
MethodDefinition _set = prop.SetMethod;
bool haveGet = (_get != null && TypeData.MustDocumentMethod(_get));
bool haveSet = (_set != null && TypeData.MustDocumentMethod(_set));
+ haveParameters = haveGet || (haveSet && _set.Parameters.Count > 1);
MethodDefinition [] methods;
if (haveGet && haveSet) {
@@ -840,16 +873,41 @@ namespace CorCompare
methods = new MethodDefinition [] { _set };
} else {
//odd
- return;
+ return null;
}
- if (haveGet || _set.Parameters.Count > 1) {
+ return methods;
+ }
+
+ protected override void AddExtraAttributes (MemberReference memberDefinition)
+ {
+ base.AddExtraAttributes (memberDefinition);
+
+ PropertyDefinition prop = (PropertyDefinition) memberDefinition;
+ AddAttribute ("ptype", Utils.CleanupTypeName (prop.PropertyType));
+
+ bool haveParameters;
+ MethodDefinition [] methods = GetMethods ((PropertyDefinition) memberDefinition, out haveParameters);
+
+ if (methods != null && haveParameters) {
string parms = Parameters.GetSignature (methods [0].Parameters);
if (!string.IsNullOrEmpty (parms))
- AddAttribute (p, "params", parms);
+ AddAttribute ("params", parms);
}
- MethodData data = new MethodData (document, p, methods);
+ }
+
+ protected override void AddExtraData (MemberReference memberDefenition)
+ {
+ base.AddExtraData (memberDefenition);
+
+ bool haveParameters;
+ MethodDefinition [] methods = GetMethods ((PropertyDefinition) memberDefenition, out haveParameters);
+
+ if (methods == null)
+ return;
+
+ MethodData data = new MethodData (writer, methods);
//data.NoMemberAttributes = true;
data.DoOutput ();
}
@@ -871,8 +929,8 @@ namespace CorCompare
class EventData : MemberData
{
- public EventData (XmlDocument document, XmlNode parent, EventDefinition [] members)
- : base (document, parent, members)
+ public EventData (XmlWriter writer, EventDefinition [] members)
+ : base (writer, members)
{
}
@@ -888,11 +946,12 @@ namespace CorCompare
return ((int) evt.Attributes).ToString (CultureInfo.InvariantCulture);
}
- protected override void AddExtraData (XmlNode p, MemberReference memberDefenition)
+ protected override void AddExtraAttributes (MemberReference memberDefinition)
{
- base.AddExtraData (p, memberDefenition);
- EventDefinition evt = (EventDefinition) memberDefenition;
- AddAttribute (p, "eventtype", Utils.CleanupTypeName (evt.EventType));
+ base.AddExtraAttributes (memberDefinition);
+
+ EventDefinition evt = (EventDefinition) memberDefinition;
+ AddAttribute ("eventtype", Utils.CleanupTypeName (evt.EventType));
}
public override string ParentTag {
@@ -908,8 +967,8 @@ namespace CorCompare
{
bool noAtts;
- public MethodData (XmlDocument document, XmlNode parent, MethodDefinition [] members)
- : base (document, parent, members)
+ public MethodData (XmlWriter writer, MethodDefinition [] members)
+ : base (writer, members)
{
}
@@ -928,34 +987,59 @@ namespace CorCompare
return ((int)( method.Attributes)).ToString (CultureInfo.InvariantCulture);
}
- protected override void AddExtraData (XmlNode p, MemberReference memberDefenition)
+ protected override ICustomAttributeProvider GetAdditionalCustomAttributeProvider (MemberReference member)
{
- base.AddExtraData (p, memberDefenition);
+ var mbase = (MethodDefinition) member;
+ return mbase.MethodReturnType;
+ }
- if (!(memberDefenition is MethodDefinition))
- return;
+ protected override void AddExtraAttributes (MemberReference memberDefinition)
+ {
+ base.AddExtraAttributes (memberDefinition);
- MethodDefinition mbase = (MethodDefinition) memberDefenition;
+ if (!(memberDefinition is MethodDefinition))
+ return;
- ParameterData parms = new ParameterData (document, p, mbase.Parameters);
- parms.DoOutput ();
+ MethodDefinition mbase = (MethodDefinition) memberDefinition;
if (mbase.IsAbstract)
- AddAttribute (p, "abstract", "true");
+ AddAttribute ("abstract", "true");
if (mbase.IsVirtual)
- AddAttribute (p, "virtual", "true");
+ AddAttribute ("virtual", "true");
if (mbase.IsFinal && mbase.IsVirtual && mbase.IsReuseSlot)
- AddAttribute (p, "sealed", "true");
+ AddAttribute ("sealed", "true");
if (mbase.IsStatic)
- AddAttribute (p, "static", "true");
-
+ AddAttribute ("static", "true");
+ var baseMethod = TypeHelper.GetBaseMethodInTypeHierarchy (mbase);
+ if (baseMethod != null && baseMethod != mbase) {
+ // This indicates whether this method is an override of another method.
+ // This information is not necessarily available in the api info for any
+ // particular assembly, because a method is only overriding another if
+ // there is a base virtual function with the same signature, and that
+ // base method can come from another assembly.
+ AddAttribute ("is-override", "true");
+ }
string rettype = Utils.CleanupTypeName (mbase.MethodReturnType.ReturnType);
if (rettype != "System.Void" || !mbase.IsConstructor)
- AddAttribute (p, "returntype", (rettype));
+ AddAttribute ("returntype", (rettype));
+//
+// if (mbase.MethodReturnType.HasCustomAttributes)
+// AttributeData.OutputAttributes (writer, mbase.MethodReturnType);
+ }
+
+ protected override void AddExtraData (MemberReference memberDefenition)
+ {
+ base.AddExtraData (memberDefenition);
+
+ if (!(memberDefenition is MethodDefinition))
+ return;
+
+ MethodDefinition mbase = (MethodDefinition) memberDefenition;
- AttributeData.OutputAttributes (document, p, mbase.MethodReturnType);
+ ParameterData parms = new ParameterData (writer, mbase.Parameters);
+ parms.DoOutput ();
- MemberData.OutputGenericParameters (document, p, mbase);
+ MemberData.OutputGenericParameters (writer, mbase);
}
public override bool NoMemberAttributes {
@@ -974,8 +1058,8 @@ namespace CorCompare
class ConstructorData : MethodData
{
- public ConstructorData (XmlDocument document, XmlNode parent, MethodDefinition [] members)
- : base (document, parent, members)
+ public ConstructorData (XmlWriter writer, MethodDefinition [] members)
+ : base (writer, members)
{
}
@@ -992,23 +1076,20 @@ namespace CorCompare
{
private IList<ParameterDefinition> parameters;
- public ParameterData (XmlDocument document, XmlNode parent, IList<ParameterDefinition> parameters)
- : base (document, parent)
+ public ParameterData (XmlWriter writer, IList<ParameterDefinition> parameters)
+ : base (writer)
{
this.parameters = parameters;
}
public override void DoOutput ()
{
- XmlNode parametersNode = document.CreateElement ("parameters");
- parent.AppendChild (parametersNode);
-
+ writer.WriteStartElement ("parameters");
foreach (ParameterDefinition parameter in parameters) {
- XmlNode paramNode = document.CreateElement ("parameter");
- parametersNode.AppendChild (paramNode);
- AddAttribute (paramNode, "name", parameter.Name);
- AddAttribute (paramNode, "position", parameter.Method.Parameters.IndexOf(parameter).ToString(CultureInfo.InvariantCulture));
- AddAttribute (paramNode, "attrib", ((int) parameter.Attributes).ToString());
+ writer.WriteStartElement ("parameter");
+ AddAttribute ("name", parameter.Name);
+ AddAttribute ("position", parameter.Method.Parameters.IndexOf(parameter).ToString(CultureInfo.InvariantCulture));
+ AddAttribute ("attrib", ((int) parameter.Attributes).ToString());
string direction = "in";
@@ -1016,102 +1097,111 @@ namespace CorCompare
direction = parameter.IsOut ? "out" : "ref";
TypeReference t = parameter.ParameterType;
- AddAttribute (paramNode, "type", Utils.CleanupTypeName (t));
+ AddAttribute ("type", Utils.CleanupTypeName (t));
if (parameter.IsOptional) {
- AddAttribute (paramNode, "optional", "true");
+ AddAttribute ("optional", "true");
if (parameter.HasConstant)
- AddAttribute (paramNode, "defaultValue", parameter.Constant == null ? "NULL" : parameter.Constant.ToString ());
+ AddAttribute ("defaultValue", parameter.Constant == null ? "NULL" : parameter.Constant.ToString ());
}
if (direction != "in")
- AddAttribute (paramNode, "direction", direction);
+ AddAttribute ("direction", direction);
- AttributeData.OutputAttributes (document, paramNode, parameter);
+ AttributeData.OutputAttributes (writer, parameter);
+ writer.WriteEndElement (); // parameter
}
+ writer.WriteEndElement (); // parameters
}
}
- class AttributeData : BaseData
+ class AttributeData
{
- IList<CustomAttribute> atts;
-
- AttributeData (XmlDocument doc, XmlNode parent, IList<CustomAttribute> attributes)
- : base (doc, parent)
- {
- atts = attributes;
- }
-
- public override void DoOutput ()
+ public static void DoOutput (XmlWriter writer, IList<ICustomAttributeProvider> providers)
{
- if (document == null)
+ if (writer == null)
throw new InvalidOperationException ("Document not set");
- if (atts == null || atts.Count == 0)
+ if (providers == null || providers.Count == 0)
+ return;
+
+ if (!providers.Any ((provider) => provider != null && provider.HasCustomAttributes))
return;
- XmlNode natts = parent.SelectSingleNode("attributes");
- if (natts == null) {
- natts = document.CreateElement ("attributes", null);
- parent.AppendChild (natts);
- }
+ writer.WriteStartElement ("attributes");
- foreach (var att in atts.OrderBy ((a) => a.Constructor.DeclaringType.FullName)) {
- string attName = Utils.CleanupTypeName (att.Constructor.DeclaringType);
- if (SkipAttribute (att))
+ foreach (var provider in providers) {
+ if (provider == null)
+ continue;
+
+ if (!provider.HasCustomAttributes)
continue;
- XmlNode node = document.CreateElement ("attribute");
- AddAttribute (node, "name", attName);
-
- XmlNode properties = null;
-
- Dictionary<string, object> attribute_mapping = CreateAttributeMapping (att);
-
- foreach (string name in attribute_mapping.Keys) {
- if (name == "TypeId")
- continue;
-
- if (properties == null) {
- properties = node.AppendChild (document.CreateElement ("properties"));
- }
-
- object o = attribute_mapping [name];
-
- XmlNode n = properties.AppendChild (document.CreateElement ("property"));
- AddAttribute (n, "name", name);
- if (o == null) {
- AddAttribute (n, "value", "null");
- continue;
+ var ass = provider as AssemblyDefinition;
+ if (ass != null && !Driver.FollowForwarders)
+ TypeForwardedToData.OutputForwarders (writer, ass);
+
+ var attributes = provider.CustomAttributes.
+ Where ((att) => !SkipAttribute (att)).
+ OrderBy ((a) => a.Constructor.DeclaringType.FullName, StringComparer.Ordinal);
+
+ foreach (var att in attributes) {
+ string attName = Utils.CleanupTypeName (att.Constructor.DeclaringType);
+
+ writer.WriteStartElement ("attribute");
+ writer.WriteAttributeString ("name", attName);
+
+ var attribute_mapping = CreateAttributeMapping (att);
+
+ if (attribute_mapping != null) {
+ var mapping = attribute_mapping.Where ((attr) => attr.Key != "TypeId");
+ if (mapping.Any ()) {
+ writer.WriteStartElement ("properties");
+ foreach (var kvp in mapping) {
+ string name = kvp.Key;
+ object o = kvp.Value;
+
+ writer.WriteStartElement ("property");
+ writer.WriteAttributeString ("name", name);
+
+ if (o == null) {
+ writer.WriteAttributeString ("value", "null");
+ } else {
+ string value = o.ToString ();
+ if (attName.EndsWith ("GuidAttribute", StringComparison.Ordinal))
+ value = value.ToUpper ();
+ writer.WriteAttributeString ("value", value);
+ }
+
+ writer.WriteEndElement (); // property
+ }
+ writer.WriteEndElement (); // properties
+ }
}
-
- string value = o.ToString ();
- if (attName.EndsWith ("GuidAttribute"))
- value = value.ToUpper ();
- AddAttribute (n, "value", value);
+ writer.WriteEndElement (); // attribute
}
-
- natts.AppendChild (node);
}
+
+ writer.WriteEndElement (); // attributes
}
static Dictionary<string, object> CreateAttributeMapping (CustomAttribute attribute)
{
- var mapping = new Dictionary<string, object> ();
+ Dictionary<string, object> mapping = null;
- PopulateMapping (mapping, attribute);
+ PopulateMapping (ref mapping, attribute);
var constructor = attribute.Constructor.Resolve ();
if (constructor == null || !constructor.HasParameters)
return mapping;
- PopulateMapping (mapping, constructor, attribute);
+ PopulateMapping (ref mapping, constructor, attribute);
return mapping;
}
- static void PopulateMapping (Dictionary<string, object> mapping, CustomAttribute attribute)
+ static void PopulateMapping (ref Dictionary<string, object> mapping, CustomAttribute attribute)
{
if (!attribute.HasProperties)
return;
@@ -1123,13 +1213,15 @@ namespace CorCompare
if (arg.Value is CustomAttributeArgument)
arg = (CustomAttributeArgument) arg.Value;
+ if (mapping == null)
+ mapping = new Dictionary<string, object> (StringComparer.Ordinal);
mapping.Add (name, GetArgumentValue (arg.Type, arg.Value));
}
}
static Dictionary<FieldReference, int> CreateArgumentFieldMapping (MethodDefinition constructor)
{
- Dictionary<FieldReference, int> field_mapping = new Dictionary<FieldReference, int> ();
+ Dictionary<FieldReference, int> field_mapping = null;
int? argument = null;
@@ -1157,6 +1249,9 @@ namespace CorCompare
if (!argument.HasValue)
break;
+ if (field_mapping == null)
+ field_mapping = new Dictionary<FieldReference, int> ();
+
if (!field_mapping.ContainsKey (field))
field_mapping.Add (field, (int) argument - 1);
@@ -1170,7 +1265,7 @@ namespace CorCompare
static Dictionary<PropertyDefinition, FieldReference> CreatePropertyFieldMapping (TypeDefinition type)
{
- Dictionary<PropertyDefinition, FieldReference> property_mapping = new Dictionary<PropertyDefinition, FieldReference> ();
+ Dictionary<PropertyDefinition, FieldReference> property_mapping = null;
foreach (PropertyDefinition property in type.Properties) {
if (property.GetMethod == null)
@@ -1186,6 +1281,8 @@ namespace CorCompare
if (field.DeclaringType.FullName != type.FullName)
continue;
+ if (property_mapping == null)
+ property_mapping = new Dictionary<PropertyDefinition, FieldReference> ();
property_mapping.Add (property, field);
break;
}
@@ -1194,7 +1291,7 @@ namespace CorCompare
return property_mapping;
}
- static void PopulateMapping (Dictionary<string, object> mapping, MethodDefinition constructor, CustomAttribute attribute)
+ static void PopulateMapping (ref Dictionary<string, object> mapping, MethodDefinition constructor, CustomAttribute attribute)
{
if (!constructor.HasBody)
return;
@@ -1207,6 +1304,8 @@ namespace CorCompare
new DecimalConstantAttribute ((byte) ca[0].Value, (byte) ca[1].Value, (int) ca[2].Value, (int) ca[3].Value, (int) ca[4].Value) :
new DecimalConstantAttribute ((byte) ca[0].Value, (byte) ca[1].Value, (uint) ca[2].Value, (uint) ca[3].Value, (uint) ca[4].Value);
+ if (mapping == null)
+ mapping = new Dictionary<string, object> (StringComparer.Ordinal);
mapping.Add ("Value", dca.Value);
return;
case "System.ComponentModel.BindableAttribute":
@@ -1214,6 +1313,8 @@ namespace CorCompare
break;
if (constructor.Parameters[0].ParameterType == constructor.Module.TypeSystem.Boolean) {
+ if (mapping == null)
+ mapping = new Dictionary<string, object> (StringComparer.Ordinal);
mapping.Add ("Bindable", ca[0].Value);
} else {
throw new NotImplementedException ();
@@ -1223,18 +1324,24 @@ namespace CorCompare
}
var field_mapping = CreateArgumentFieldMapping (constructor);
- var property_mapping = CreatePropertyFieldMapping ((TypeDefinition) constructor.DeclaringType);
-
- foreach (var pair in property_mapping) {
- int argument;
- if (!field_mapping.TryGetValue (pair.Value, out argument))
- continue;
-
- var ca_arg = ca [argument];
- if (ca_arg.Value is CustomAttributeArgument)
- ca_arg = (CustomAttributeArgument) ca_arg.Value;
-
- mapping.Add (pair.Key.Name, GetArgumentValue (ca_arg.Type, ca_arg.Value));
+ if (field_mapping != null) {
+ var property_mapping = CreatePropertyFieldMapping ((TypeDefinition) constructor.DeclaringType);
+
+ if (property_mapping != null) {
+ foreach (var pair in property_mapping) {
+ int argument;
+ if (!field_mapping.TryGetValue (pair.Value, out argument))
+ continue;
+
+ var ca_arg = ca [argument];
+ if (ca_arg.Value is CustomAttributeArgument)
+ ca_arg = (CustomAttributeArgument)ca_arg.Value;
+
+ if (mapping == null)
+ mapping = new Dictionary<string, object> (StringComparer.Ordinal);
+ mapping.Add (pair.Key.Name, GetArgumentValue (ca_arg.Type, ca_arg.Value));
+ }
+ }
}
}
@@ -1342,19 +1449,15 @@ namespace CorCompare
static bool SkipAttribute (CustomAttribute attribute)
{
- var type_name = Utils.CleanupTypeName (attribute.Constructor.DeclaringType);
-
- return !TypeHelper.IsPublic (attribute)
- || type_name.EndsWith ("TODOAttribute");
+ if (!TypeHelper.IsPublic (attribute))
+ return true;
+
+ return attribute.Constructor.DeclaringType.Name.EndsWith ("TODOAttribute", StringComparison.Ordinal);
}
- public static void OutputAttributes (XmlDocument doc, XmlNode parent, ICustomAttributeProvider provider)
+ public static void OutputAttributes (XmlWriter writer, params ICustomAttributeProvider[] providers)
{
- if (!provider.HasCustomAttributes)
- return;
-
- AttributeData ad = new AttributeData (doc, parent, provider.CustomAttributes);
- ad.DoOutput ();
+ AttributeData.DoOutput (writer, providers);
}
}
@@ -1426,7 +1529,7 @@ namespace CorCompare
public int Compare (PropertyDefinition ma, PropertyDefinition mb)
{
- int res = String.Compare (ma.Name, mb.Name);
+ int res = String.Compare (ma.Name, mb.Name, StringComparison.Ordinal);
if (res != 0)
return res;
@@ -1451,7 +1554,7 @@ namespace CorCompare
{
MethodDefinition ma = (MethodDefinition) a;
MethodDefinition mb = (MethodDefinition) b;
- int res = String.Compare (ma.Name, mb.Name);
+ int res = String.Compare (ma.Name, mb.Name, StringComparison.Ordinal);
if (res != 0)
return res;
@@ -1480,7 +1583,7 @@ namespace CorCompare
string siga = Parameters.GetSignature (pia);
string sigb = Parameters.GetSignature (pib);
- return String.Compare (siga, sigb);
+ return String.Compare (siga, sigb, StringComparison.Ordinal);
}
}
}
diff --git a/mcs/tools/xbuild/frameworks/net_2.0.xml b/mcs/tools/xbuild/frameworks/net_2.0.xml
index 2b8bd9b1dff..4265fcc50ee 100644
--- a/mcs/tools/xbuild/frameworks/net_2.0.xml
+++ b/mcs/tools/xbuild/frameworks/net_2.0.xml
@@ -1,3 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
-<FileList Name=".NET Framework 2.0" TargetFrameworkDirectory="..\..\..\..\2.0">
+<FileList Name=".NET Framework 2.0" TargetFrameworkDirectory="..\..\..\..\2.0-api">
</FileList>
diff --git a/mcs/tools/xbuild/frameworks/net_3.0.xml b/mcs/tools/xbuild/frameworks/net_3.0.xml
index ae06c8818c1..1a56750d51b 100644
--- a/mcs/tools/xbuild/frameworks/net_3.0.xml
+++ b/mcs/tools/xbuild/frameworks/net_3.0.xml
@@ -1,3 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
-<FileList Name=".NET Framework 3.0" TargetFrameworkDirectory="..\..\..\..\2.0">
+<FileList Name=".NET Framework 3.0" TargetFrameworkDirectory="..\..\..\..\2.0-api">
</FileList>
diff --git a/mcs/tools/xbuild/frameworks/net_3.5.xml b/mcs/tools/xbuild/frameworks/net_3.5.xml
index 122584299a1..3e711014768 100644
--- a/mcs/tools/xbuild/frameworks/net_3.5.xml
+++ b/mcs/tools/xbuild/frameworks/net_3.5.xml
@@ -1,3 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
-<FileList Name=".NET Framework 3.5" TargetFrameworkDirectory="..\..\..\..\3.5" IncludeFramework="v3.0">
+<FileList Name=".NET Framework 3.5" TargetFrameworkDirectory="..\..\..\..\3.5-api" IncludeFramework="v3.0">
</FileList>
diff --git a/mcs/tools/xbuild/frameworks/net_4.0.xml b/mcs/tools/xbuild/frameworks/net_4.0.xml
index 701279497fd..841cc536e62 100644
--- a/mcs/tools/xbuild/frameworks/net_4.0.xml
+++ b/mcs/tools/xbuild/frameworks/net_4.0.xml
@@ -1,3 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
-<FileList Name=".NET Framework 4" TargetFrameworkDirectory="..\..\..\..\4.0">
+<FileList Name=".NET Framework 4" TargetFrameworkDirectory="..\..\..\..\4.0-api">
</FileList>
diff --git a/mcs/tools/xbuild/frameworks/net_4.0_client.xml b/mcs/tools/xbuild/frameworks/net_4.0_client.xml
index 951933a2f9a..d3fd85ccc0b 100644
--- a/mcs/tools/xbuild/frameworks/net_4.0_client.xml
+++ b/mcs/tools/xbuild/frameworks/net_4.0_client.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<FileList Name=".NET Framework 4 Client Profile" TargetFrameworkDirectory="..\..\..\..\..\..\4.0">
+<FileList Name=".NET Framework 4 Client Profile" TargetFrameworkDirectory="..\..\..\..\..\..\4.0-api">
<File AssemblyName="System" Version="4.0.0.0" PublicKeyToken="b77a5c561934e089" />
<File AssemblyName="System.Activities" Version="4.0.0.0" PublicKeyToken="31bf3856ad364e35" />
<File AssemblyName="System.Dynamic" Version="4.0.0.0" PublicKeyToken="b03f5f7f11d50a3a" />
diff --git a/mono/metadata/cominterop.c b/mono/metadata/cominterop.c
index 162e7436406..15007be0d5b 100644
--- a/mono/metadata/cominterop.c
+++ b/mono/metadata/cominterop.c
@@ -170,6 +170,22 @@ mono_marshal_safearray_set_value (gpointer safearray, gpointer indices, gpointer
static void
mono_marshal_safearray_free_indices (gpointer indices);
+MonoClass*
+mono_class_try_get_com_object_class (void)
+{
+ static MonoClass *tmp_class;
+ static gboolean inited;
+ MonoClass *klass;
+ if (!inited) {
+ klass = mono_class_from_name (mono_defaults.corlib, "System", "__ComObject");
+ mono_memory_barrier ();
+ tmp_class = klass;
+ mono_memory_barrier ();
+ inited = TRUE;
+ }
+ return tmp_class;
+}
+
/**
* cominterop_method_signature:
* @method: a method
diff --git a/mono/metadata/cominterop.h b/mono/metadata/cominterop.h
index 6a15374f16c..1338bd3b5bc 100644
--- a/mono/metadata/cominterop.h
+++ b/mono/metadata/cominterop.h
@@ -53,4 +53,7 @@ mono_string_from_bstr (gpointer bstr);
MONO_API void
mono_free_bstr (gpointer bstr);
+MonoClass*
+mono_class_try_get_com_object_class (void);
+
#endif /* __MONO_COMINTEROP_H__ */
diff --git a/mono/metadata/coree.c b/mono/metadata/coree.c
index 7c4be6afe7e..c2e47b9ca7b 100644
--- a/mono/metadata/coree.c
+++ b/mono/metadata/coree.c
@@ -143,7 +143,7 @@ __int32 STDMETHODCALLTYPE _CorExeMain(void)
MonoMethod* method;
guint32 entry;
gchar* file_name;
- gchar* error;
+ gchar* corlib_version_error;
int argc;
gunichar2** argvw;
gchar** argv;
@@ -153,9 +153,9 @@ __int32 STDMETHODCALLTYPE _CorExeMain(void)
init_from_coree = TRUE;
domain = mono_runtime_load (file_name, NULL);
- error = (gchar*) mono_check_corlib_version ();
- if (error) {
- g_free (error);
+ corlib_version_error = (gchar*) mono_check_corlib_version ();
+ if (corlib_version_error) {
+ g_free (corlib_version_error);
g_free (file_name);
MessageBox (NULL, L"Corlib not in sync with this runtime.", NULL, MB_ICONERROR);
mono_runtime_quit ();
diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c
index 55a02988f30..142a56e7b18 100644
--- a/mono/metadata/loader.c
+++ b/mono/metadata/loader.c
@@ -1970,7 +1970,10 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass,
MonoMethod *
mono_get_method (MonoImage *image, guint32 token, MonoClass *klass)
{
- return mono_get_method_full (image, token, klass, NULL);
+ MonoError error;
+ MonoMethod *result = mono_get_method_checked (image, token, klass, NULL, &error);
+ mono_error_cleanup (&error);
+ return result;
}
MonoMethod *
@@ -1979,11 +1982,7 @@ mono_get_method_full (MonoImage *image, guint32 token, MonoClass *klass,
{
MonoError error;
MonoMethod *result = mono_get_method_checked (image, token, klass, context, &error);
- mono_loader_assert_no_error ();
- if (!mono_error_ok (&error)) {
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error);
- }
+ mono_error_cleanup (&error);
return result;
}
@@ -2126,12 +2125,7 @@ mono_get_method_constrained (MonoImage *image, guint32 token, MonoClass *constra
{
MonoError error;
MonoMethod *result = mono_get_method_constrained_checked (image, token, constrained_class, context, cil_method, &error);
-
- mono_loader_assert_no_error ();
- if (!mono_error_ok (&error)) {
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error);
- }
+ mono_error_cleanup (&error);
return result;
}
diff --git a/mono/metadata/loader.h b/mono/metadata/loader.h
index 74d82817bb8..6999f81961d 100644
--- a/mono/metadata/loader.h
+++ b/mono/metadata/loader.h
@@ -8,14 +8,14 @@ MONO_BEGIN_DECLS
typedef mono_bool (*MonoStackWalk) (MonoMethod *method, int32_t native_offset, int32_t il_offset, mono_bool managed, void* data);
-MONO_API MonoMethod *
+MONO_RT_EXTERNAL_ONLY MONO_API MonoMethod *
mono_get_method (MonoImage *image, uint32_t token, MonoClass *klass);
-MONO_API MonoMethod *
+MONO_RT_EXTERNAL_ONLY MONO_API MonoMethod *
mono_get_method_full (MonoImage *image, uint32_t token, MonoClass *klass,
MonoGenericContext *context);
-MONO_API MonoMethod *
+MONO_RT_EXTERNAL_ONLY MONO_API MonoMethod *
mono_get_method_constrained (MonoImage *image, uint32_t token, MonoClass *constrained_class,
MonoGenericContext *context, MonoMethod **cil_method);
diff --git a/mono/metadata/object-internals.h b/mono/metadata/object-internals.h
index 3700043213c..d82bf5dc072 100644
--- a/mono/metadata/object-internals.h
+++ b/mono/metadata/object-internals.h
@@ -618,6 +618,8 @@ typedef struct {
gboolean (*debug_log_is_enabled) (void);
gboolean (*tls_key_supported) (MonoTlsKey key);
void (*init_delegate) (MonoDelegate *del);
+ MonoObject* (*runtime_invoke) (MonoMethod *method, void *obj, void **params, MonoError *error, MonoObject **exc);
+ void* (*compile_method) (MonoMethod *method, MonoError *error);
} MonoRuntimeCallbacks;
typedef gboolean (*MonoInternalStackWalk) (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data);
@@ -632,12 +634,8 @@ typedef struct {
gboolean (*mono_install_handler_block_guard) (MonoThreadUnwindState *unwind_state);
} MonoRuntimeExceptionHandlingCallbacks;
-
/* used to free a dynamic method */
-typedef void (*MonoFreeMethodFunc) (MonoDomain *domain, MonoMethod *method);
-
-/* Used to initialize the method pointers inside vtables */
-typedef gboolean (*MonoInitVTableFunc) (MonoVTable *vtable);
+typedef void (*MonoFreeMethodFunc) (MonoDomain *domain, MonoMethod *method);
MONO_COLD void mono_set_pending_exception (MonoException *exc);
@@ -683,12 +681,6 @@ mono_class_get_allocation_ftn (MonoVTable *vtable, gboolean for_box, gboolean *p
void
mono_runtime_free_method (MonoDomain *domain, MonoMethod *method);
-void
-mono_install_runtime_invoke (MonoInvokeFunc func);
-
-void
-mono_install_compile_method (MonoCompileFunc func);
-
void
mono_install_free_method (MonoFreeMethodFunc func);
diff --git a/mono/metadata/object.c b/mono/metadata/object.c
index bd31aaa2a8b..94c29712f16 100644
--- a/mono/metadata/object.c
+++ b/mono/metadata/object.c
@@ -584,20 +584,6 @@ mono_set_always_build_imt_thunks (gboolean value)
always_build_imt_thunks = value;
}
-static MonoCompileFunc default_mono_compile_method = NULL;
-
-/**
- * mono_install_compile_method:
- * @func: function to install
- *
- * This is a VM internal routine
- */
-void
-mono_install_compile_method (MonoCompileFunc func)
-{
- default_mono_compile_method = func;
-}
-
/**
* mono_compile_method:
* @method: The method to compile.
@@ -608,13 +594,19 @@ mono_install_compile_method (MonoCompileFunc func)
gpointer
mono_compile_method (MonoMethod *method)
{
+ gpointer res;
+ MonoError error;
+
MONO_REQ_GC_NEUTRAL_MODE
- if (!default_mono_compile_method) {
+ if (!callbacks.compile_method) {
g_error ("compile method called on uninitialized runtime");
return NULL;
}
- return default_mono_compile_method (method);
+ res = callbacks.compile_method (method, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
+ return res;
}
gpointer
@@ -2846,13 +2838,24 @@ mono_object_get_virtual_method (MonoObject *obj, MonoMethod *method)
}
static MonoObject*
-dummy_mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
+do_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
{
- g_error ("runtime invoke called on uninitialized runtime");
- return NULL;
-}
+ MonoObject *result = NULL;
+ MonoError error;
-static MonoInvokeFunc default_mono_runtime_invoke = dummy_mono_runtime_invoke;
+ g_assert (callbacks.runtime_invoke);
+ result = callbacks.runtime_invoke (method, obj, params, &error, exc);
+ if (!mono_error_ok (&error)) {
+ if (exc) {
+ *exc = (MonoObject*)mono_error_convert_to_exception (&error);
+ return NULL;
+ } else {
+ mono_error_raise_exception (&error);
+ }
+ }
+
+ return result;
+}
/**
* mono_runtime_invoke:
@@ -2901,7 +2904,7 @@ mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_start_invoke (method);
- result = default_mono_runtime_invoke (method, obj, params, exc);
+ result = do_runtime_invoke (method, obj, params, exc);
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_end_invoke (method);
@@ -3473,7 +3476,7 @@ mono_property_set_value (MonoProperty *prop, void *obj, void **params, MonoObjec
{
MONO_REQ_GC_UNSAFE_MODE;
- default_mono_runtime_invoke (prop->set, obj, params, exc);
+ do_runtime_invoke (prop->set, obj, params, exc);
}
/**
@@ -3498,7 +3501,7 @@ mono_property_get_value (MonoProperty *prop, void *obj, void **params, MonoObjec
{
MONO_REQ_GC_UNSAFE_MODE;
- return default_mono_runtime_invoke (prop->get, obj, params, exc);
+ return do_runtime_invoke (prop->get, obj, params, exc);
}
/*
@@ -4254,19 +4257,6 @@ mono_runtime_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
}
/**
- * mono_install_runtime_invoke:
- * @func: Function to install
- *
- * This is a VM internal routine
- */
-void
-mono_install_runtime_invoke (MonoInvokeFunc func)
-{
- default_mono_runtime_invoke = func ? func: dummy_mono_runtime_invoke;
-}
-
-
-/**
* mono_runtime_invoke_array:
* @method: method to invoke
* @obJ: object instance
diff --git a/mono/metadata/remoting.c b/mono/metadata/remoting.c
index 8ca8ae62fdb..6e84ab7c0c4 100644
--- a/mono/metadata/remoting.c
+++ b/mono/metadata/remoting.c
@@ -408,7 +408,7 @@ mono_marshal_get_remoting_invoke (MonoMethod *method)
/* this seems to be the best plase to put this, as all remoting invokes seem to get filtered through here */
#ifndef DISABLE_COM
- if (mono_class_is_com_object (method->klass) || method->klass == mono_class_get_com_object_class ()) {
+ if (mono_class_is_com_object (method->klass) || method->klass == mono_class_try_get_com_object_class ()) {
MonoVTable *vtable = mono_class_vtable (mono_domain_get (), method->klass);
g_assert (vtable); /*FIXME do proper error handling*/
diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c
index 437d82f05f8..98c346de4cd 100644
--- a/mono/mini/aot-runtime.c
+++ b/mono/mini/aot-runtime.c
@@ -4607,6 +4607,7 @@ mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code
MonoAotModule *module = (MonoAotModule*)aot_module;
gboolean res, no_ftnptr = FALSE;
MonoMemPool *mp;
+ MonoError error;
gboolean using_gsharedvt = FALSE;
//printf ("DYN: %p %d\n", aot_module, plt_info_offset);
@@ -4635,7 +4636,9 @@ mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code
*/
if (mono_aot_only && ji.type == MONO_PATCH_INFO_METHOD && !ji.data.method->is_generic && !mono_method_check_context_used (ji.data.method) && !(ji.data.method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) &&
!mono_method_needs_static_rgctx_invoke (ji.data.method, FALSE) && !using_gsharedvt) {
- target = (guint8 *)mono_jit_compile_method (ji.data.method);
+ target = (guint8 *)mono_jit_compile_method (ji.data.method, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
no_ftnptr = TRUE;
} else {
target = (guint8 *)mono_resolve_patch_target (NULL, mono_domain_get (), NULL, &ji, TRUE);
diff --git a/mono/mini/jit-icalls.c b/mono/mini/jit-icalls.c
index f049daca1ca..79fb7d74e1b 100644
--- a/mono/mini/jit-icalls.c
+++ b/mono/mini/jit-icalls.c
@@ -1372,13 +1372,29 @@ mono_generic_class_init (MonoVTable *vtable)
gpointer
mono_fill_class_rgctx (MonoVTable *vtable, int index)
{
- return mono_class_fill_runtime_generic_context (vtable, index);
+ MonoError error;
+ gpointer res;
+
+ res = mono_class_fill_runtime_generic_context (vtable, index, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
gpointer
mono_fill_method_rgctx (MonoMethodRuntimeGenericContext *mrgctx, int index)
{
- return mono_method_fill_runtime_generic_context (mrgctx, index);
+ MonoError error;
+ gpointer res;
+
+ res = mono_method_fill_runtime_generic_context (mrgctx, index, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
/*
@@ -1735,16 +1751,75 @@ mono_llvmonly_set_calling_assembly (MonoImage *image)
jit_tls->calling_image = image;
}
+
+static gboolean
+get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
+{
+ MonoMethod **dest = (MonoMethod **)data;
+
+ /* skip unmanaged frames */
+ if (!managed)
+ return FALSE;
+
+ if (!(*dest)) {
+ if (!strcmp (m->klass->name_space, "System.Reflection"))
+ return FALSE;
+ *dest = m;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean
+get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
+{
+ MonoMethod **dest = (MonoMethod **)data;
+
+ /* skip unmanaged frames */
+ if (!managed)
+ return FALSE;
+
+ if (m->wrapper_type != MONO_WRAPPER_NONE)
+ return FALSE;
+
+ if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
+ return FALSE;
+
+ if (m == *dest) {
+ *dest = NULL;
+ return FALSE;
+ }
+ if (!(*dest)) {
+ *dest = m;
+ return TRUE;
+ }
+ return FALSE;
+}
+
MonoObject*
mono_llvmonly_get_calling_assembly (void)
{
MonoJitTlsData *jit_tls = NULL;
+ MonoMethod *m;
+ MonoMethod *dest;
+ MonoAssembly *assembly;
- jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id);
- g_assert (jit_tls);
- if (!jit_tls->calling_image) {
- mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
- return NULL;
+ dest = NULL;
+ mono_stack_walk_no_il (get_executing, &dest);
+ m = dest;
+ mono_stack_walk_no_il (get_caller_no_reflection, &dest);
+
+ if (!dest) {
+ /* Fall back to TLS */
+ jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id);
+ g_assert (jit_tls);
+ if (!jit_tls->calling_image) {
+ mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
+ return NULL;
+ }
+ assembly = jit_tls->calling_image->assembly;
+ } else {
+ assembly = dest->klass->image->assembly;
}
return (MonoObject*)mono_assembly_get_object (mono_domain_get (), jit_tls->calling_image->assembly);
}
diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c
index 2ff04067b88..130c62165ba 100644
--- a/mono/mini/method-to-ir.c
+++ b/mono/mini/method-to-ir.c
@@ -7084,12 +7084,12 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
cheader = mono_method_get_header (cmethod);
if (cheader == NULL || mono_loader_get_last_error ()) {
- MonoLoaderError *error = mono_loader_get_last_error ();
-
if (cheader)
mono_metadata_free_mh (cheader);
- if (inline_always && error)
- mono_cfg_set_exception (cfg, error->exception_type);
+ if (inline_always && mono_loader_get_last_error ()) {
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+ mono_error_set_from_loader_error (&cfg->error);
+ }
mono_loader_clear_error ();
return 0;
@@ -8152,10 +8152,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
image = method->klass->image;
header = mono_method_get_header (method);
if (!header) {
- MonoLoaderError *error;
-
- if ((error = mono_loader_get_last_error ())) {
- mono_cfg_set_exception (cfg, error->exception_type);
+ if (mono_loader_get_last_error ()) {
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+ mono_error_set_from_loader_error (&cfg->error);
} else {
mono_cfg_set_exception_invalid_program (cfg, g_strdup_printf ("Missing or incorrect header for method %s", cfg->method->name));
}
@@ -9220,8 +9219,15 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
}
}
- if (!cmethod || mono_loader_get_last_error ())
- LOAD_ERROR;
+ if (!cmethod || mono_loader_get_last_error ()) {
+ if (mono_loader_get_last_error ()) {
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+ mono_error_set_from_loader_error (&cfg->error);
+ CHECK_CFG_ERROR;
+ } else {
+ LOAD_ERROR;
+ }
+ }
if (!dont_verify && !cfg->skip_visibility) {
MonoMethod *target_method = cil_method;
if (method->is_inflated) {
diff --git a/mono/mini/mini-generic-sharing.c b/mono/mini/mini-generic-sharing.c
index 94312a18f43..af1c8f5a0b6 100644
--- a/mono/mini/mini-generic-sharing.c
+++ b/mono/mini/mini-generic-sharing.c
@@ -840,13 +840,17 @@ class_get_rgctx_template_oti (MonoClass *klass, int type_argc, guint32 slot, gbo
}
static gpointer
-class_type_info (MonoDomain *domain, MonoClass *klass, MonoRgctxInfoType info_type)
+class_type_info (MonoDomain *domain, MonoClass *klass, MonoRgctxInfoType info_type, MonoError *error)
{
+ mono_error_init (error);
+
switch (info_type) {
case MONO_RGCTX_INFO_STATIC_DATA: {
MonoVTable *vtable = mono_class_vtable (domain, klass);
- if (!vtable)
- mono_raise_exception (mono_class_get_exception_for_failure (klass));
+ if (!vtable) {
+ mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (klass));
+ return NULL;
+ }
return mono_vtable_get_static_field_data (vtable);
}
case MONO_RGCTX_INFO_KLASS:
@@ -855,8 +859,10 @@ class_type_info (MonoDomain *domain, MonoClass *klass, MonoRgctxInfoType info_ty
return klass->element_class;
case MONO_RGCTX_INFO_VTABLE: {
MonoVTable *vtable = mono_class_vtable (domain, klass);
- if (!vtable)
- mono_raise_exception (mono_class_get_exception_for_failure (klass));
+ if (!vtable) {
+ mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (klass));
+ return NULL;
+ }
return vtable;
}
case MONO_RGCTX_INFO_CAST_CACHE: {
@@ -960,7 +966,9 @@ class_type_info (MonoDomain *domain, MonoClass *klass, MonoRgctxInfoType info_ty
else
method = mono_class_get_method_from_name (klass, "Unbox", 1);
- addr = mono_compile_method (method);
+ addr = mono_jit_compile_method (method, error);
+ if (!mono_error_ok (error))
+ return NULL;
// The caller uses the gsharedvt call signature
@@ -1465,14 +1473,20 @@ mini_get_gsharedvt_wrapper (gboolean gsharedvt_in, gpointer addr, MonoMethodSign
return addr;
}
+/*
+ * instantiate_info:
+ *
+ * Instantiate the info given by OTI for context CONTEXT.
+ */
static gpointer
instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti,
- MonoGenericContext *context, MonoClass *klass)
+ MonoGenericContext *context, MonoClass *klass, MonoError *error)
{
- MonoError error;
gpointer data;
gboolean temporary;
+ mono_error_init (error);
+
if (!oti->data)
return NULL;
@@ -1514,13 +1528,12 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
if (oti->info_type == MONO_RGCTX_INFO_KLASS)
mono_class_compute_gc_descriptor (arg_class);
- return class_type_info (domain, arg_class, oti->info_type);
+ return class_type_info (domain, arg_class, oti->info_type, error);
}
case MONO_RGCTX_INFO_TYPE:
return data;
case MONO_RGCTX_INFO_REFLECTION_TYPE: {
- MonoReflectionType *ret = mono_type_get_object_checked (domain, (MonoType *)data, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoReflectionType *ret = mono_type_get_object_checked (domain, (MonoType *)data, error);
return ret;
}
@@ -1573,7 +1586,6 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
MonoJumpInfoVirtMethod *info = (MonoJumpInfoVirtMethod *)data;
MonoClass *iface_class = info->method->klass;
MonoMethod *method;
- MonoError error;
int ioffset, slot;
gpointer addr;
@@ -1590,8 +1602,9 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
g_assert (info->klass->vtable);
method = info->klass->vtable [ioffset + slot];
- method = mono_class_inflate_generic_method_checked (method, context, &error);
-
+ method = mono_class_inflate_generic_method_checked (method, context, error);
+ if (!mono_error_ok (error))
+ return NULL;
addr = mono_compile_method (method);
return mini_add_method_trampoline (method, addr, mono_method_needs_static_rgctx_invoke (method, FALSE), FALSE);
}
@@ -1648,8 +1661,10 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
g_assert (method->context.method_inst);
vtable = mono_class_vtable (domain, method->method.method.klass);
- if (!vtable)
- mono_raise_exception (mono_class_get_exception_for_failure (method->method.method.klass));
+ if (!vtable) {
+ mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (method->method.method.klass));
+ return NULL;
+ }
return mono_method_lookup_rgctx (vtable, method->context.method_inst);
}
@@ -1860,7 +1875,9 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
offset += size;
break;
default:
- res->entries [i] = instantiate_info (domain, template_, context, klass);
+ res->entries [i] = instantiate_info (domain, template_, context, klass, error);
+ if (!mono_error_ok (error))
+ return NULL;
break;
}
}
@@ -2231,7 +2248,7 @@ alloc_rgctx_array (MonoDomain *domain, int n, gboolean is_mrgctx)
static gpointer
fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContext *rgctx, guint32 slot,
- MonoGenericInst *method_inst)
+ MonoGenericInst *method_inst, MonoError *error)
{
gpointer info;
int i, first_slot, size;
@@ -2243,6 +2260,8 @@ fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContex
int rgctx_index;
gboolean do_free;
+ mono_error_init (error);
+
g_assert (rgctx);
mono_domain_lock (domain);
@@ -2285,7 +2304,7 @@ fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContex
oti = class_get_rgctx_template_oti (get_shared_class (klass),
method_inst ? method_inst->type_argc : 0, slot, TRUE, TRUE, &do_free);
/* This might take the loader lock */
- info = instantiate_info (domain, &oti, &context, klass);
+ info = instantiate_info (domain, &oti, &context, klass, error);
g_assert (info);
/*
@@ -2319,7 +2338,7 @@ fill_runtime_generic_context (MonoVTable *class_vtable, MonoRuntimeGenericContex
* Instantiates a slot in the RGCTX, returning its value.
*/
gpointer
-mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot)
+mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot, MonoError *error)
{
static gboolean inited = FALSE;
static int num_alloced = 0;
@@ -2328,6 +2347,8 @@ mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot)
MonoRuntimeGenericContext *rgctx;
gpointer info;
+ mono_error_init (error);
+
mono_domain_lock (domain);
if (!inited) {
@@ -2344,7 +2365,7 @@ mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot)
mono_domain_unlock (domain);
- info = fill_runtime_generic_context (class_vtable, rgctx, slot, 0);
+ info = fill_runtime_generic_context (class_vtable, rgctx, slot, 0, error);
DEBUG (printf ("get rgctx slot: %s %d -> %p\n", mono_type_full_name (&class_vtable->klass->byval_arg), slot, info));
@@ -2359,11 +2380,11 @@ mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot)
* Instantiates a slot in the MRGCTX.
*/
gpointer
-mono_method_fill_runtime_generic_context (MonoMethodRuntimeGenericContext *mrgctx, guint32 slot)
+mono_method_fill_runtime_generic_context (MonoMethodRuntimeGenericContext *mrgctx, guint32 slot, MonoError *error)
{
gpointer info;
- info = fill_runtime_generic_context (mrgctx->class_vtable, (MonoRuntimeGenericContext*)mrgctx, slot, mrgctx->method_inst);
+ info = fill_runtime_generic_context (mrgctx->class_vtable, (MonoRuntimeGenericContext*)mrgctx, slot, mrgctx->method_inst, error);
return info;
}
diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c
index 159e3e4affb..4640672dd54 100644
--- a/mono/mini/mini-runtime.c
+++ b/mono/mini/mini-runtime.c
@@ -1846,7 +1846,7 @@ no_gsharedvt_in_wrapper (void)
}
static gpointer
-mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException **ex)
+mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoError *error)
{
MonoDomain *target_domain, *domain = mono_domain_get ();
MonoJitInfo *info;
@@ -1855,6 +1855,8 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
MonoJitICallInfo *callinfo = NULL;
WrapperInfo *winfo = NULL;
+ mono_error_init (error);
+
/*
* ICALL wrappers are handled specially, since there is only one copy of them
* shared by all appdomains.
@@ -1887,9 +1889,8 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
ctx = mono_method_get_context (method);
method = info->d.synchronized_inner.method;
if (ctx) {
- MonoError error;
- method = mono_class_inflate_generic_method_checked (method, ctx, &error);
- g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
+ method = mono_class_inflate_generic_method_checked (method, ctx, error);
+ g_assert (mono_error_ok (error)); /* FIXME don't swallow the error */
}
}
}
@@ -1904,9 +1905,9 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
mono_jit_stats.methods_lookups++;
vtable = mono_class_vtable (domain, method->klass);
g_assert (vtable);
- tmpEx = mono_runtime_class_init_full (vtable, ex == NULL);
+ tmpEx = mono_runtime_class_init_full (vtable, FALSE);
if (tmpEx) {
- *ex = tmpEx;
+ mono_error_set_exception_instance (error, tmpEx);
return NULL;
}
return mono_create_ftnptr (target_domain, info->code_start);
@@ -1937,7 +1938,9 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
#endif
if (!code)
- code = mono_jit_compile_method_inner (method, target_domain, opt, ex);
+ code = mono_jit_compile_method_inner (method, target_domain, opt, error);
+ if (!mono_error_ok (error))
+ return NULL;
if (!code && mono_llvm_only) {
if (method->wrapper_type == MONO_WRAPPER_UNKNOWN) {
@@ -1988,17 +1991,11 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
}
gpointer
-mono_jit_compile_method (MonoMethod *method)
+mono_jit_compile_method (MonoMethod *method, MonoError *error)
{
- MonoException *ex = NULL;
gpointer code;
- code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), &ex);
- if (!code) {
- g_assert (ex);
- mono_raise_exception (ex);
- }
-
+ code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), error);
return code;
}
@@ -2199,7 +2196,7 @@ typedef struct {
} RuntimeInvokeInfo;
static RuntimeInvokeInfo*
-create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer compiled_method, gboolean callee_gsharedvt)
+create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer compiled_method, gboolean callee_gsharedvt, MonoError *error)
{
MonoMethod *invoke;
RuntimeInvokeInfo *info;
@@ -2302,7 +2299,11 @@ create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer com
invoke = mono_marshal_get_runtime_invoke_for_sig (wrapper_sig);
g_free (wrapper_sig);
- info->compiled_method = mono_jit_compile_method (wrapper);
+ info->compiled_method = mono_jit_compile_method (wrapper, error);
+ if (!mono_error_ok (error)) {
+ g_free (info);
+ return NULL;
+ }
} else {
/* Gsharedvt methods can be invoked the same way */
/* The out wrapper has the same signature as the compiled gsharedvt method */
@@ -2314,7 +2315,11 @@ create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer com
g_free (wrapper_sig);
}
}
- info->runtime_invoke = mono_jit_compile_method (invoke);
+ info->runtime_invoke = mono_jit_compile_method (invoke, error);
+ if (!mono_error_ok (error)) {
+ g_free (info);
+ return NULL;
+ }
}
return info;
@@ -2396,10 +2401,11 @@ mono_llvmonly_runtime_invoke (MonoMethod *method, RuntimeInvokeInfo *info, void
* @method: the method to invoke
* @obj: this pointer
* @params: array of parameter values.
+ * @error: error
* @exc: used to catch exceptions objects
*/
static MonoObject*
-mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
+mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoError *error, MonoObject **exc)
{
MonoMethod *invoke, *callee;
MonoObject *(*runtime_invoke) (MonoObject *this_obj, void **params, MonoObject **exc, void* compiled_method);
@@ -2409,6 +2415,8 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
MonoJitInfo *ji = NULL;
gboolean callee_gsharedvt = FALSE;
+ mono_error_init (error);
+
if (obj == NULL && !(method->flags & METHOD_ATTRIBUTE_STATIC) && !method->string_ctor && (method->wrapper_type == 0)) {
g_warning ("Ignoring invocation of an instance method on a NULL instance.\n");
return NULL;
@@ -2458,18 +2466,10 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
}
if (callee) {
- MonoException *jit_ex = NULL;
-
- compiled_method = mono_jit_compile_method_with_opt (callee, mono_get_optimizations_for_method (callee, default_opt), &jit_ex);
+ compiled_method = mono_jit_compile_method_with_opt (callee, mono_get_optimizations_for_method (callee, default_opt), error);
if (!compiled_method) {
- g_assert (jit_ex);
- if (exc) {
- *exc = (MonoObject*)jit_ex;
- return NULL;
- } else {
- mono_raise_exception (jit_ex);
- /* coverity[unreachable] */
- }
+ g_assert (!mono_error_ok (error));
+ return NULL;
}
if (mono_llvm_only) {
@@ -2485,7 +2485,9 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
compiled_method = NULL;
}
- info = create_runtime_invoke_info (domain, method, compiled_method, callee_gsharedvt);
+ info = create_runtime_invoke_info (domain, method, compiled_method, callee_gsharedvt, error);
+ if (!mono_error_ok (error))
+ return NULL;
mono_domain_lock (domain);
info2 = (RuntimeInvokeInfo *)mono_conc_hashtable_insert (domain_info->runtime_invoke_hash, method, info);
@@ -2523,7 +2525,9 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
if (!dyn_runtime_invoke) {
invoke = mono_marshal_get_runtime_invoke_dynamic ();
- dyn_runtime_invoke = (RuntimeInvokeDynamicFunction)mono_jit_compile_method (invoke);
+ dyn_runtime_invoke = (RuntimeInvokeDynamicFunction)mono_jit_compile_method (invoke, error);
+ if (!mono_error_ok (error))
+ return NULL;
}
/* Convert the arguments to the format expected by start_dyn_call () */
@@ -3491,6 +3495,14 @@ mini_init (const char *filename, const char *runtime_version)
callbacks.get_imt_trampoline = mini_get_imt_trampoline;
callbacks.imt_entry_inited = mini_imt_entry_inited;
callbacks.init_delegate = mini_init_delegate;
+#define JIT_INVOKE_WORKS
+#ifdef JIT_INVOKE_WORKS
+ callbacks.runtime_invoke = mono_jit_runtime_invoke;
+#endif
+#define JIT_TRAMPOLINES_WORK
+#ifdef JIT_TRAMPOLINES_WORK
+ callbacks.compile_method = mono_jit_compile_method;
+#endif
mono_install_callbacks (&callbacks);
@@ -3560,9 +3572,7 @@ mini_init (const char *filename, const char *runtime_version)
#endif
mono_threads_install_cleanup (mini_thread_cleanup);
-#define JIT_TRAMPOLINES_WORK
#ifdef JIT_TRAMPOLINES_WORK
- mono_install_compile_method (mono_jit_compile_method);
mono_install_free_method (mono_jit_free_method);
mono_install_trampoline (mono_create_jit_trampoline);
mono_install_jump_trampoline (mono_create_jump_trampoline);
@@ -3573,10 +3583,6 @@ mini_init (const char *filename, const char *runtime_version)
mono_install_create_domain_hook (mini_create_jit_domain_info);
mono_install_free_domain_hook (mini_free_jit_domain_info);
#endif
-#define JIT_INVOKE_WORKS
-#ifdef JIT_INVOKE_WORKS
- mono_install_runtime_invoke (mono_jit_runtime_invoke);
-#endif
mono_install_get_cached_class_info (mono_aot_get_cached_class_info);
mono_install_get_class_from_name (mono_aot_get_class_from_name);
mono_install_jit_info_find_in_aot (mono_aot_find_jit_info);
diff --git a/mono/mini/mini-trampolines.c b/mono/mini/mini-trampolines.c
index f1fe616b969..a28fd9168d3 100644
--- a/mono/mini/mini-trampolines.c
+++ b/mono/mini/mini-trampolines.c
@@ -501,13 +501,13 @@ mini_add_method_wrappers_llvmonly (MonoMethod *m, gpointer compiled_method, gboo
}
/**
- * common_call_trampoline:
+ * common_call_trampoline_inner:
*
* The code to handle normal, virtual, and interface method calls and jumps, both
* from JITted and LLVM compiled code.
*/
static gpointer
-common_call_trampoline_inner (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *vt, gpointer *vtable_slot)
+common_call_trampoline_inner (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *vt, gpointer *vtable_slot, MonoError *error)
{
gpointer addr, compiled_method;
gboolean generic_shared = FALSE;
@@ -520,6 +520,8 @@ common_call_trampoline_inner (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVT
gpointer *orig_vtable_slot, *vtable_slot_to_patch = NULL;
MonoJitInfo *ji = NULL;
+ mono_error_init (error);
+
virtual_ = vt && (gpointer)vtable_slot > (gpointer)vt;
imt_call = vt && (gpointer)vtable_slot < (gpointer)vt;
@@ -691,8 +693,9 @@ common_call_trampoline_inner (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVT
if (!code && mono_method_needs_static_rgctx_invoke (m, FALSE))
need_rgctx_tramp = TRUE;
- addr = compiled_method = mono_compile_method (m);
- g_assert (addr);
+ addr = compiled_method = mono_jit_compile_method (m, error);
+ if (!addr)
+ return NULL;
if (generic_virtual || variant_iface) {
if (vt->klass->valuetype) /*FIXME is this required variant iface?*/
@@ -801,11 +804,11 @@ common_call_trampoline_inner (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVT
}
static gpointer
-common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *vt, gpointer *vtable_slot)
+common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *vt, gpointer *vtable_slot, MonoError *error)
{
gpointer res;
MONO_PREPARE_RESET_BLOCKING;
- res = common_call_trampoline_inner (regs, code, m, vt, vtable_slot);
+ res = common_call_trampoline_inner (regs, code, m, vt, vtable_slot, error);
MONO_FINISH_RESET_BLOCKING;
return res;
}
@@ -818,9 +821,17 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, MonoVTable *
gpointer
mono_magic_trampoline (mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp)
{
+ MonoError error;
+ gpointer res;
+
trampoline_calls ++;
- return common_call_trampoline (regs, code, (MonoMethod *)arg, NULL, NULL);
+ res = common_call_trampoline (regs, code, (MonoMethod *)arg, NULL, NULL, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
/**
@@ -835,7 +846,8 @@ mono_vcall_trampoline (mgreg_t *regs, guint8 *code, int slot, guint8 *tramp)
MonoVTable *vt;
gpointer *vtable_slot;
MonoMethod *m;
- gpointer addr;
+ MonoError error;
+ gpointer addr, res;
trampoline_calls ++;
@@ -889,7 +901,12 @@ mono_vcall_trampoline (mgreg_t *regs, guint8 *code, int slot, guint8 *tramp)
m = NULL;
}
- return common_call_trampoline (regs, code, m, vt, vtable_slot);
+ res = common_call_trampoline (regs, code, m, vt, vtable_slot, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
#ifndef DISABLE_REMOTING
@@ -922,7 +939,11 @@ mono_generic_virtual_remoting_trampoline (mgreg_t *regs, guint8 *code, MonoMetho
g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */;
m = mono_marshal_get_remoting_invoke_with_check (m);
- addr = mono_compile_method (m);
+ addr = mono_jit_compile_method (m, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
g_assert (addr);
return addr;
@@ -990,8 +1011,14 @@ mono_aot_plt_trampoline (mgreg_t *regs, guint8 *code, guint8 *aot_module,
res = mono_aot_plt_resolve (aot_module, plt_info_offset, code);
if (!res) {
- if (mono_loader_get_last_error ())
- mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
+ if (mono_loader_get_last_error ()) {
+ MonoError error;
+
+ mono_error_init (&error);
+ mono_error_set_from_loader_error (&error);
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
// FIXME: Error handling (how ?)
g_assert (res);
}
@@ -1010,6 +1037,8 @@ mono_rgctx_lazy_fetch_trampoline (mgreg_t *regs, guint8 *code, gpointer data, gu
gpointer arg = (gpointer)(gssize)r [MONO_ARCH_VTABLE_REG];
guint32 index = MONO_RGCTX_SLOT_INDEX (slot);
gboolean mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
+ MonoError error;
+ gpointer res;
trampoline_calls ++;
@@ -1021,9 +1050,14 @@ mono_rgctx_lazy_fetch_trampoline (mgreg_t *regs, guint8 *code, gpointer data, gu
num_lookups++;
if (mrgctx)
- return mono_method_fill_runtime_generic_context ((MonoMethodRuntimeGenericContext *)arg, index);
+ res = mono_method_fill_runtime_generic_context ((MonoMethodRuntimeGenericContext *)arg, index, &error);
else
- return mono_class_fill_runtime_generic_context ((MonoVTable *)arg, index);
+ res = mono_class_fill_runtime_generic_context ((MonoVTable *)arg, index, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
/*
@@ -1070,6 +1104,7 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
MonoJitInfo *ji;
MonoMethod *m;
MonoMethod *method = NULL;
+ MonoError error;
gboolean multicast, callvirt = FALSE, closed_over_null = FALSE;
gboolean need_rgctx_tramp = FALSE;
gboolean need_unbox_tramp = FALSE;
@@ -1114,8 +1149,10 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
if (!(sig && method == tramp_info->method)) {
mono_error_init (&err);
sig = mono_method_signature_checked (method, &err);
- if (!sig)
- mono_error_raise_exception (&err);
+ if (!sig) {
+ mono_error_set_pending_exception (&err);
+ return NULL;
+ }
}
if (sig->hasthis && method->klass->valuetype) {
@@ -1146,8 +1183,10 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
if (!(sig && method == tramp_info->method)) {
mono_error_init (&err);
sig = mono_method_signature_checked (method, &err);
- if (!sig)
- mono_error_raise_exception (&err);
+ if (!sig) {
+ mono_error_set_pending_exception (&err);
+ return NULL;
+ }
}
callvirt = !delegate->target && sig->hasthis;
@@ -1196,7 +1235,11 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
if (enable_caching && delegate->method_code && *delegate->method_code) {
delegate->method_ptr = *delegate->method_code;
} else {
- compiled_method = addr = mono_compile_method (method);
+ compiled_method = addr = mono_jit_compile_method (method, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
addr = mini_add_method_trampoline (method, compiled_method, need_rgctx_tramp, need_unbox_tramp);
delegate->method_ptr = addr;
if (enable_caching && delegate->method_code)
@@ -1222,7 +1265,11 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *arg, guint8* tr
if (!code) {
/* The general, unoptimized case */
m = mono_marshal_get_delegate_invoke (invoke, delegate);
- code = (guint8 *)mono_compile_method (m);
+ code = (guint8 *)mono_jit_compile_method (m, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
code = (guint8 *)mini_add_method_trampoline (m, code, mono_method_needs_static_rgctx_invoke (m, FALSE), FALSE);
}
@@ -1407,6 +1454,7 @@ mono_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, M
gpointer
mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper)
{
+ MonoError error;
MonoJitInfo *ji;
gpointer code;
guint32 code_size = 0;
@@ -1421,8 +1469,12 @@ mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean ad
if (code && !ji->has_generic_jit_info && !(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED))
return code;
- if (mono_llvm_only)
- return mono_jit_compile_method (method);
+ if (mono_llvm_only) {
+ code = mono_jit_compile_method (method, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
+ return code;
+ }
mono_domain_lock (domain);
code = g_hash_table_lookup (domain_jit_info (domain)->jump_trampoline_hash, method);
@@ -1461,6 +1513,7 @@ method_not_found (void)
gpointer
mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method)
{
+ MonoError error;
gpointer tramp;
if (mono_aot_only) {
@@ -1475,7 +1528,10 @@ mono_create_jit_trampoline_in_domain (MonoDomain *domain, MonoMethod *method)
/* These wrappers are not generated */
return method_not_found;
/* Methods are lazily initialized on first call, so this can't lead recursion */
- return mono_compile_method (method);
+ code = mono_jit_compile_method (method, &error);
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
+ return code;
}
}
diff --git a/mono/mini/mini.c b/mono/mini/mini.c
index ba5577ef60a..c7306b08998 100644
--- a/mono/mini/mini.c
+++ b/mono/mini/mini.c
@@ -1208,7 +1208,7 @@ mini_assembly_can_skip_verification (MonoDomain *domain, MonoMethod *method)
/*
* mini_method_verify:
*
- * Verify the method using the new verfier.
+ * Verify the method using the verfier.
*
* Returns true if the method is invalid.
*/
@@ -1217,7 +1217,6 @@ mini_method_verify (MonoCompile *cfg, MonoMethod *method, gboolean fail_compile)
{
GSList *tmp, *res;
gboolean is_fulltrust;
- MonoLoaderError *error;
if (method->verification_success)
return FALSE;
@@ -1230,11 +1229,13 @@ mini_method_verify (MonoCompile *cfg, MonoMethod *method, gboolean fail_compile)
res = mono_method_verify_with_current_settings (method, cfg->skip_visibility, is_fulltrust);
- if ((error = mono_loader_get_last_error ())) {
- if (fail_compile)
- cfg->exception_type = error->exception_type;
- else
+ if (mono_loader_get_last_error ()) {
+ if (fail_compile) {
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+ mono_error_set_from_loader_error (&cfg->error);
+ } else {
mono_loader_clear_error ();
+ }
if (res)
mono_free_verify_list (res);
return TRUE;
@@ -1256,16 +1257,20 @@ mini_method_verify (MonoCompile *cfg, MonoMethod *method, gboolean fail_compile)
if (info->info.status == MONO_VERIFY_NOT_VERIFIABLE && (!is_fulltrust || info->exception_type == MONO_EXCEPTION_METHOD_ACCESS || info->exception_type == MONO_EXCEPTION_FIELD_ACCESS)) {
if (fail_compile) {
char *method_name = mono_method_full_name (method, TRUE);
-
- if (info->exception_type == MONO_EXCEPTION_METHOD_ACCESS || info->exception_type == MONO_EXCEPTION_FIELD_ACCESS) {
- if (info->exception_type == MONO_EXCEPTION_METHOD_ACCESS)
- mono_error_set_generic_error (&cfg->error, "System", "MethodAccessException", "Error verifying %s: %s", method_name, info->info.message);
- else
- mono_error_set_generic_error (&cfg->error, "System", "FieldAccessException", "Error verifying %s: %s", method_name, info->info.message);
- cfg->exception_type = MONO_EXCEPTION_MONO_ERROR;
+ char *msg = g_strdup_printf ("Error verifying %s: %s", method_name, info->info.message);
+
+ if (info->exception_type == MONO_EXCEPTION_METHOD_ACCESS)
+ mono_error_set_generic_error (&cfg->error, "System", "MethodAccessException", "%s", msg);
+ else if (info->exception_type == info->exception_type == MONO_EXCEPTION_FIELD_ACCESS)
+ mono_error_set_generic_error (&cfg->error, "System", "FieldAccessException", "%s", msg);
+ else if (info->exception_type == MONO_EXCEPTION_UNVERIFIABLE_IL)
+ mono_error_set_generic_error (&cfg->error, "System.Security", "VerificationException", msg);
+ if (!mono_error_ok (&cfg->error)) {
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+ g_free (msg);
} else {
cfg->exception_type = info->exception_type;
- cfg->exception_message = g_strdup_printf ("Error verifying %s: %s", method_name, info->info.message);
+ cfg->exception_message = msg;
}
g_free (method_name);
}
@@ -3481,10 +3486,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
header = cfg->header;
if (!header) {
- MonoLoaderError *error;
-
- if ((error = mono_loader_get_last_error ())) {
- cfg->exception_type = error->exception_type;
+ if (mono_loader_get_last_error ()) {
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
+ mono_error_set_from_loader_error (&cfg->error);
} else {
mono_cfg_set_exception_invalid_program (cfg, g_strdup_printf ("Missing or incorrect header for method %s", cfg->method->name));
}
@@ -4186,7 +4190,7 @@ create_jit_info_for_trampoline (MonoMethod *wrapper, MonoTrampInfo *info)
* Main entry point for the JIT.
*/
gpointer
-mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt, MonoException **jit_ex)
+mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt, MonoError *error)
{
MonoCompile *cfg;
gpointer code = NULL;
@@ -4197,6 +4201,8 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
GTimer *jit_timer;
MonoMethod *prof_method, *shared;
+ mono_error_init (error);
+
if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
MonoMethod *nm;
@@ -4259,7 +4265,8 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
full_name = mono_method_full_name (method, TRUE);
msg = g_strdup_printf ("Unrecognizable runtime implemented method '%s'", full_name);
- *jit_ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", msg);
+ ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", msg);
+ mono_error_set_exception_instance (error, ex);
g_free (full_name);
g_free (msg);
return NULL;
@@ -4302,7 +4309,8 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
char *fullname = mono_method_full_name (method, TRUE);
char *msg = g_strdup_printf ("Attempting to JIT compile method '%s' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.\n", fullname);
- *jit_ex = mono_get_exception_execution_engine (msg);
+ ex = mono_get_exception_execution_engine (msg);
+ mono_error_set_exception_instance (error, ex);
g_free (fullname);
g_free (msg);
@@ -4327,34 +4335,26 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
case MONO_EXCEPTION_FILE_NOT_FOUND:
case MONO_EXCEPTION_BAD_IMAGE: {
/* Throw a type load exception if needed */
- MonoLoaderError *error = mono_loader_get_last_error ();
-
- if (error) {
- ex = mono_loader_error_prepare_exception (error);
+ if (cfg->exception_ptr) {
+ ex = mono_class_get_exception_for_failure ((MonoClass *)cfg->exception_ptr);
} else {
- if (cfg->exception_ptr) {
- ex = mono_class_get_exception_for_failure ((MonoClass *)cfg->exception_ptr);
- } else {
- if (cfg->exception_type == MONO_EXCEPTION_MISSING_FIELD)
- ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MissingFieldException", cfg->exception_message);
- else if (cfg->exception_type == MONO_EXCEPTION_MISSING_METHOD)
- ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MissingMethodException", cfg->exception_message);
- else if (cfg->exception_type == MONO_EXCEPTION_TYPE_LOAD)
- ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "TypeLoadException", cfg->exception_message);
- else if (cfg->exception_type == MONO_EXCEPTION_FILE_NOT_FOUND)
- ex = mono_exception_from_name_msg (mono_defaults.corlib, "System.IO", "FileNotFoundException", cfg->exception_message);
- else if (cfg->exception_type == MONO_EXCEPTION_BAD_IMAGE)
- ex = mono_get_exception_bad_image_format (cfg->exception_message);
- else
- g_assert_not_reached ();
- }
+ if (cfg->exception_type == MONO_EXCEPTION_MISSING_FIELD)
+ ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MissingFieldException", cfg->exception_message);
+ else if (cfg->exception_type == MONO_EXCEPTION_MISSING_METHOD)
+ ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MissingMethodException", cfg->exception_message);
+ else if (cfg->exception_type == MONO_EXCEPTION_TYPE_LOAD)
+ ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "TypeLoadException", cfg->exception_message);
+ else if (cfg->exception_type == MONO_EXCEPTION_FILE_NOT_FOUND)
+ ex = mono_exception_from_name_msg (mono_defaults.corlib, "System.IO", "FileNotFoundException", cfg->exception_message);
+ else if (cfg->exception_type == MONO_EXCEPTION_BAD_IMAGE)
+ ex = mono_get_exception_bad_image_format (cfg->exception_message);
+ else
+ g_assert_not_reached ();
}
break;
}
- case MONO_EXCEPTION_UNVERIFIABLE_IL:
- ex = mono_exception_from_name_msg (mono_defaults.corlib, "System.Security", "VerificationException", cfg->exception_message);
- break;
case MONO_EXCEPTION_MONO_ERROR:
+ // FIXME: MonoError has no copy ctor
g_assert (!mono_error_ok (&cfg->error));
ex = mono_error_convert_to_exception (&cfg->error);
break;
@@ -4367,7 +4367,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
mono_profiler_method_end_jit (method, NULL, MONO_PROFILE_FAILED);
mono_destroy_compile (cfg);
- *jit_ex = ex;
+ mono_error_set_exception_instance (error, ex);
return NULL;
}
@@ -4464,7 +4464,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
if (!vtable) {
ex = mono_class_get_exception_for_failure (method->klass);
g_assert (ex);
- *jit_ex = ex;
+ mono_error_set_exception_instance (error, ex);
return NULL;
}
@@ -4484,7 +4484,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
ex = mono_runtime_class_init_full (vtable, FALSE);
if (ex) {
- *jit_ex = ex;
+ mono_error_set_exception_instance (error, ex);
return NULL;
}
return code;
diff --git a/mono/mini/mini.h b/mono/mini/mini.h
index 592d2945d2f..db5c133266f 100644
--- a/mono/mini/mini.h
+++ b/mono/mini/mini.h
@@ -2325,8 +2325,8 @@ MonoJumpInfo *mono_patch_info_list_prepend (MonoJumpInfo *list, int ip, MonoJum
gpointer mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *patch_info, gboolean run_cctors) MONO_LLVM_INTERNAL;
gpointer mono_jit_find_compiled_method_with_jit_info (MonoDomain *domain, MonoMethod *method, MonoJitInfo **ji);
gpointer mono_jit_find_compiled_method (MonoDomain *domain, MonoMethod *method);
-gpointer mono_jit_compile_method (MonoMethod *method);
-gpointer mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt, MonoException **jit_ex);
+gpointer mono_jit_compile_method (MonoMethod *method, MonoError *error);
+gpointer mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt, MonoError *error);
MonoLMF * mono_get_lmf (void);
MonoLMF** mono_get_lmf_addr (void);
void mono_set_lmf (MonoLMF *lmf);
@@ -2913,10 +2913,10 @@ gboolean
mono_class_generic_sharing_enabled (MonoClass *klass);
gpointer
-mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot);
+mono_class_fill_runtime_generic_context (MonoVTable *class_vtable, guint32 slot, MonoError *error);
gpointer
-mono_method_fill_runtime_generic_context (MonoMethodRuntimeGenericContext *mrgctx, guint32 slot);
+mono_method_fill_runtime_generic_context (MonoMethodRuntimeGenericContext *mrgctx, guint32 slot, MonoError *error);
MonoMethodRuntimeGenericContext*
mono_method_lookup_rgctx (MonoVTable *class_vtable, MonoGenericInst *method_inst);
diff --git a/mono/utils/mono-error-internals.h b/mono/utils/mono-error-internals.h
index 926e76c9bbd..d16f9ef6602 100644
--- a/mono/utils/mono-error-internals.h
+++ b/mono/utils/mono-error-internals.h
@@ -40,7 +40,9 @@ typedef struct {
#define is_ok(error) ((error)->error_code == MONO_ERROR_NONE)
void
-mono_error_assert_ok (MonoError *error);
+mono_error_assert_ok_pos (MonoError *error, const char* filename, int lineno);
+
+#define mono_error_assert_ok(e) mono_error_assert_ok_pos (e, __FILE__, __LINE__);
void
mono_error_dup_strings (MonoError *error, gboolean dup_strings);
diff --git a/mono/utils/mono-error.c b/mono/utils/mono-error.c
index ca3350c5fd4..5673719059b 100644
--- a/mono/utils/mono-error.c
+++ b/mono/utils/mono-error.c
@@ -119,12 +119,12 @@ mono_error_ok (MonoError *error)
}
void
-mono_error_assert_ok (MonoError *error)
+mono_error_assert_ok_pos (MonoError *error, const char* filename, int lineno)
{
if (mono_error_ok (error))
return;
- g_error ("%s\n", mono_error_get_message (error));
+ g_error ("%s:%d: %s\n", filename, lineno, mono_error_get_message (error));
}
unsigned short
@@ -347,6 +347,7 @@ mono_error_set_exception_instance (MonoError *oerror, MonoException *exc)
{
MonoErrorInternal *error = (MonoErrorInternal*)oerror;
+ mono_error_prepare (error);
error->error_code = MONO_ERROR_EXCEPTION_INSTANCE;
error->exn.instance_handle = mono_gchandle_new (exc ? &exc->object : NULL, FALSE);
}
diff --git a/mono/utils/mono-publib.h b/mono/utils/mono-publib.h
index c9becb2bf5e..30c80704399 100644
--- a/mono/utils/mono-publib.h
+++ b/mono/utils/mono-publib.h
@@ -73,6 +73,22 @@ MONO_API void mono_free (void *);
#define MONO_CONST_RETURN const
+
+#if defined (MONO_INSIDE_RUNTIME)
+
+#if defined (__clang__)
+#define MONO_RT_EXTERNAL_ONLY __attribute__ ((unavailable("The mono runtime must not call this function")))
+#elif defined (__GNUC__)
+#define MONO_RT_EXTERNAL_ONLY __attribute__ ((error("The mono runtime must not call this function")))
+#else
+#define MONO_RT_EXTERNAL_ONLY
+#endif /* __clang__ */
+
+#else
+#define MONO_RT_EXTERNAL_ONLY
+#endif /* MONO_INSIDE_RUNTIME */
+
+
MONO_END_DECLS
#endif /* __MONO_PUBLIB_H__ */