From: Marek Safar Date: Wed, 10 Sep 2014 05:40:10 +0000 (-0900) Subject: Merge pull request #1267 from ramtinkermani/master X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=5846c522477b1ed736857348e2c711e3537c7b78;hp=6cb9a04fca7adaf2e912013e2efec35d857228dd;p=mono.git Merge pull request #1267 from ramtinkermani/master The ShouldTrace method's conditions are fixed to correctly trace the events based... --- diff --git a/README.md b/README.md index 609b9fa4660..b061956eee2 100644 --- a/README.md +++ b/README.md @@ -494,16 +494,12 @@ Directory Roadmap * `dis/` - CIL executable Disassembler - * `cli/` - Common code for the JIT and the interpreter. - * `io-layer/` - The I/O layer and system abstraction for emulating the .NET IO model. * `cil/` - Common Intermediate Representation, XML definition of the CIL bytecodes. - * `interp/` - Interpreter for CLI executables (obsolete). - * `arch/` - Architecture specific portions. * `man/` - Manual pages for the various Mono commands and programs. diff --git a/configure.ac b/configure.ac index 2d78df23994..0de87159a12 100644 --- a/configure.ac +++ b/configure.ac @@ -2499,7 +2499,6 @@ TARGET="unknown" ACCESS_UNALIGNED="yes" JIT_SUPPORTED=no -INTERP_SUPPORTED=no LIBC="libc.so.6" INTL="libc.so.6" SQLITE="libsqlite.so.0" @@ -2512,7 +2511,6 @@ XINERAMA="libXinerama.so.1" sizeof_register="SIZEOF_VOID_P" jit_wanted=true -interp_wanted=false sgen_supported=false boehm_supported=true case "$host" in @@ -2940,18 +2938,10 @@ if test x$JIT_SUPPORTED = xyes; then USEJIT=true jit_status="Building and using the JIT" else - if $interp_wanted; then - jit_status="Building the JIT, defaulting to the interpreter" - else - AC_ERROR(No JIT or interpreter support available or selected.) - fi + AC_ERROR(No JIT support available or selected.) fi else - if test x$interp_wanted = xtrue; then - jit_status="interpreter" - else - AC_ERROR(No JIT or interpreter support available or selected.) - fi + AC_ERROR(No JIT support available or selected.) fi AM_CONDITIONAL(USE_JIT, test x$USEJIT = xtrue) @@ -3358,7 +3348,6 @@ AM_CONDITIONAL(HOST_ARM64, test x$HOST = xARM64) AM_CONDITIONAL(CROSS_COMPILE, test "x$host" != "x$target") AM_CONDITIONAL(JIT_SUPPORTED, test x$JIT_SUPPORTED = xyes) -AM_CONDITIONAL(INTERP_SUPPORTED, test x$interp_wanted = xtrue) AM_CONDITIONAL(INCLUDED_LIBGC, test x$libgc = xincluded) AC_SUBST(LIBC) @@ -3378,11 +3367,7 @@ AC_SUBST(LDFLAGS) mono_build_root=`pwd` AC_SUBST(mono_build_root) -if test x$USEJIT = xtrue; then - mono_runtime=mono/mini/mono -else - mono_runtime=mono/interpreter/mint -fi +mono_runtime=mono/mini/mono AC_SUBST(mono_runtime) mono_cfg_root=$mono_build_root/runtime @@ -3579,7 +3564,6 @@ mono/arch/arm/Makefile mono/arch/arm64/Makefile mono/arch/ia64/Makefile mono/arch/mips/Makefile -mono/interpreter/Makefile mono/tests/Makefile mono/tests/tests-config mono/tests/assemblyresolve/Makefile diff --git a/data/Makefile.am b/data/Makefile.am index 71cdc650fbc..32a13623cb9 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -27,13 +27,8 @@ SGENPCFILE= endif if JIT_SUPPORTED -if INTERP_SUPPORTED -pkgconfig_DATA= mono.pc mono-2.pc mint.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ - system.web.extensions.design_1.0.pc system.web.mvc.pc system.web.mvc2.pc system.web.mvc3.pc aspnetwebstack.pc reactive.pc xbuild12.pc $(SGENPCFILE) -else pkgconfig_DATA= mono.pc mono-2.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ system.web.extensions.design_1.0.pc system.web.mvc.pc system.web.mvc2.pc system.web.mvc3.pc aspnetwebstack.pc reactive.pc xbuild12.pc $(SGENPCFILE) -endif else pkgconfig_DATA= mint.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc endif diff --git a/mcs/class/Commons.Xml.Relaxng/Test/NvdlValidatingReaderTests.cs b/mcs/class/Commons.Xml.Relaxng/Test/NvdlValidatingReaderTests.cs index e7d600c5ea0..8f0ae73cf6d 100644 --- a/mcs/class/Commons.Xml.Relaxng/Test/NvdlValidatingReaderTests.cs +++ b/mcs/class/Commons.Xml.Relaxng/Test/NvdlValidatingReaderTests.cs @@ -13,7 +13,7 @@ using System.Xml; using Commons.Xml.Nvdl; using NUnit.Framework; -namespace MonoTests.Commons.Xml.Nvdl +namespace MonoTests.Commons.Xml.Relaxng { [TestFixture] public class NvdlValidatingReaderTests diff --git a/mcs/class/Mono.Data.Tds/Test/bug-4786.cs b/mcs/class/Mono.Data.Tds/Test/bug-4786.cs index e8436a7deca..91f8a06fc1a 100644 --- a/mcs/class/Mono.Data.Tds/Test/bug-4786.cs +++ b/mcs/class/Mono.Data.Tds/Test/bug-4786.cs @@ -27,11 +27,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -namespace bug4786test +namespace MonoTests.Mono.Data.Tds { using NUnit.Framework; - using Mono.Data.Tds.Protocol; + using global::Mono.Data.Tds.Protocol; using System; using System.Net; using System.Net.Sockets; diff --git a/mcs/class/Mono.Options/Test/Mono.Options/OptionContextTest.cs b/mcs/class/Mono.Options/Test/Mono.Options/OptionContextTest.cs index 8eb61b2c93b..ec3fb02270f 100644 --- a/mcs/class/Mono.Options/Test/Mono.Options/OptionContextTest.cs +++ b/mcs/class/Mono.Options/Test/Mono.Options/OptionContextTest.cs @@ -39,7 +39,7 @@ using NUnit.Framework; #if NDESK_OPTIONS namespace Tests.NDesk.Options #else -namespace Tests.Mono.Options +namespace MonoTests.Mono.Options #endif { [TestFixture] diff --git a/mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs b/mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs index 086c6d9c8c2..688297a0f68 100644 --- a/mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs +++ b/mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs @@ -46,7 +46,7 @@ using NUnit.Framework; #if NDESK_OPTIONS namespace Tests.NDesk.Options #else -namespace Tests.Mono.Options +namespace MonoTests.Mono.Options #endif { class FooConverter : TypeConverter { diff --git a/mcs/class/Mono.Options/Test/Mono.Options/OptionTest.cs b/mcs/class/Mono.Options/Test/Mono.Options/OptionTest.cs index 5242609162a..fad1b484784 100644 --- a/mcs/class/Mono.Options/Test/Mono.Options/OptionTest.cs +++ b/mcs/class/Mono.Options/Test/Mono.Options/OptionTest.cs @@ -39,7 +39,7 @@ using NUnit.Framework; #if NDESK_OPTIONS namespace Tests.NDesk.Options #else -namespace Tests.Mono.Options +namespace MonoTests.Mono.Options #endif { class DefaultOption : Option { diff --git a/mcs/class/Mono.Options/Test/Mono.Options/Utils.cs b/mcs/class/Mono.Options/Test/Mono.Options/Utils.cs index e5439aae4c3..074478e3e21 100644 --- a/mcs/class/Mono.Options/Test/Mono.Options/Utils.cs +++ b/mcs/class/Mono.Options/Test/Mono.Options/Utils.cs @@ -31,7 +31,7 @@ using System; #if NDESK_OPTIONS namespace Tests.NDesk.Options #else -namespace Tests.Mono.Options +namespace MonoTests.Mono.Options #endif { static class Utils { diff --git a/mcs/class/System.Data.Services/Test/ChangeInterceptorAttributeTests.cs b/mcs/class/System.Data.Services/Test/ChangeInterceptorAttributeTests.cs index d8d0e157a8e..3cc769d05e3 100644 --- a/mcs/class/System.Data.Services/Test/ChangeInterceptorAttributeTests.cs +++ b/mcs/class/System.Data.Services/Test/ChangeInterceptorAttributeTests.cs @@ -26,9 +26,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class ChangeInterceptorAttributeTests { [Test] @@ -45,4 +47,4 @@ namespace System.Data.Services.Tests { Assert.AreEqual ("setName", ci.EntitySetName); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/DataServiceExceptionTests.cs b/mcs/class/System.Data.Services/Test/DataServiceExceptionTests.cs index 6058fc3e386..5f9758a44c5 100644 --- a/mcs/class/System.Data.Services/Test/DataServiceExceptionTests.cs +++ b/mcs/class/System.Data.Services/Test/DataServiceExceptionTests.cs @@ -26,9 +26,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class DataServiceExceptionTests { [Test] @@ -68,4 +70,4 @@ namespace System.Data.Services.Tests { Assert.AreEqual (inner, ex.InnerException); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/DataServiceTests.cs b/mcs/class/System.Data.Services/Test/DataServiceTests.cs index 58b67859593..2bcc6a9dd75 100644 --- a/mcs/class/System.Data.Services/Test/DataServiceTests.cs +++ b/mcs/class/System.Data.Services/Test/DataServiceTests.cs @@ -26,9 +26,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class DataServiceTests { [Test] @@ -79,4 +81,4 @@ namespace System.Data.Services.Tests { this.OnStartProcessingRequest (args); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/ETagAttributeTests.cs b/mcs/class/System.Data.Services/Test/ETagAttributeTests.cs index 8b40de6c5bd..706e02c6992 100644 --- a/mcs/class/System.Data.Services/Test/ETagAttributeTests.cs +++ b/mcs/class/System.Data.Services/Test/ETagAttributeTests.cs @@ -26,10 +26,12 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using System.Linq; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class ETagAttributeTests { [Test] @@ -63,4 +65,4 @@ namespace System.Data.Services.Tests { Assert.AreEqual ("bar", e.PropertyNames[1]); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/ExpandSegmentCollectionTests.cs b/mcs/class/System.Data.Services/Test/ExpandSegmentCollectionTests.cs index e0eb629d5be..cd5e9a1d31f 100644 --- a/mcs/class/System.Data.Services/Test/ExpandSegmentCollectionTests.cs +++ b/mcs/class/System.Data.Services/Test/ExpandSegmentCollectionTests.cs @@ -26,10 +26,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System.Data.Services; using System.Linq.Expressions; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class ExpandSegmentCollectionTests { [Test] @@ -101,4 +102,4 @@ namespace System.Data.Services.Tests { Assert.IsFalse (esc.HasFilter); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/ExpandSegmentTests.cs b/mcs/class/System.Data.Services/Test/ExpandSegmentTests.cs index f64faa8fad2..ce6712c94e0 100644 --- a/mcs/class/System.Data.Services/Test/ExpandSegmentTests.cs +++ b/mcs/class/System.Data.Services/Test/ExpandSegmentTests.cs @@ -26,10 +26,12 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using System.Linq.Expressions; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class ExpandSegmentTests { [Test] @@ -84,4 +86,4 @@ namespace System.Data.Services.Tests { { new ExpandSegment ("first", null), new ExpandSegment ("second", null), new ExpandSegment ("third", null) })); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/IgnorePropertiesAttributeTests.cs b/mcs/class/System.Data.Services/Test/IgnorePropertiesAttributeTests.cs index 04c17e3d3ce..090b3bf64bd 100644 --- a/mcs/class/System.Data.Services/Test/IgnorePropertiesAttributeTests.cs +++ b/mcs/class/System.Data.Services/Test/IgnorePropertiesAttributeTests.cs @@ -26,10 +26,12 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using System.Linq; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class IgnorePropertiesAttributeTests { [Test] @@ -63,4 +65,4 @@ namespace System.Data.Services.Tests { Assert.AreEqual ("bar", e.PropertyNames[1]); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/MimeTypeAttributeTests.cs b/mcs/class/System.Data.Services/Test/MimeTypeAttributeTests.cs index 6b5533ffa50..824cab9fcb1 100644 --- a/mcs/class/System.Data.Services/Test/MimeTypeAttributeTests.cs +++ b/mcs/class/System.Data.Services/Test/MimeTypeAttributeTests.cs @@ -26,9 +26,10 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System.Data.Services; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class MimeTypeAttributeTests { [Test] @@ -39,4 +40,4 @@ namespace System.Data.Services.Tests { Assert.AreEqual ("type", mt.MimeType); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/QueryInterceptorAttributeTests.cs b/mcs/class/System.Data.Services/Test/QueryInterceptorAttributeTests.cs index b483fbe1cdd..e4b0147cccd 100644 --- a/mcs/class/System.Data.Services/Test/QueryInterceptorAttributeTests.cs +++ b/mcs/class/System.Data.Services/Test/QueryInterceptorAttributeTests.cs @@ -26,9 +26,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class QueryInterceptorAttributeTests { [Test] @@ -45,4 +47,4 @@ namespace System.Data.Services.Tests { new QueryInterceptorAttribute (null); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderMock.cs b/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderMock.cs index 5d561b44dd5..2957cd73deb 100644 --- a/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderMock.cs +++ b/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderMock.cs @@ -31,7 +31,7 @@ using System.Data; using System.Data.Common; using System.IO; -namespace Test.System.Data.Common +namespace MonoTests.System.Data.Common { internal class DbDataReaderMock : DbDataReader { diff --git a/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderTest.cs b/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderTest.cs index 0a7235f1b90..20d5c1ab0bf 100644 --- a/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderTest.cs +++ b/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderTest.cs @@ -32,7 +32,7 @@ using System.Data; using System.Data.Common; using System.IO; -namespace Test.System.Data.Common +namespace MonoTests.System.Data.Common { [TestFixture] public class DbDataReaderTest diff --git a/mcs/class/System.Data/Test/System.Data/BinarySerializationTest.cs b/mcs/class/System.Data/Test/System.Data/BinarySerializationTest.cs index 5eae92a3963..efbe64a1a4a 100644 --- a/mcs/class/System.Data/Test/System.Data/BinarySerializationTest.cs +++ b/mcs/class/System.Data/Test/System.Data/BinarySerializationTest.cs @@ -12,6 +12,8 @@ using System.Threading; using NUnit.Framework; +namespace MonoTests.System.Data +{ [TestFixture] public class BinarySerializationTest { @@ -751,3 +753,4 @@ public class BinarySerializationTest } #endif +} diff --git a/mcs/class/System.Data/Test/System.Data/ConstraintExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/ConstraintExceptionTest.cs index c98a03c5aa4..fe575137ea4 100644 --- a/mcs/class/System.Data/Test/System.Data/ConstraintExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/ConstraintExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class ConstraintExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/DBConcurrencyExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/DBConcurrencyExceptionTest.cs index bfae78d6e6e..35e876ff51f 100644 --- a/mcs/class/System.Data/Test/System.Data/DBConcurrencyExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/DBConcurrencyExceptionTest.cs @@ -31,7 +31,7 @@ using System.Data; using NUnit.Framework; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DBConcurrencyExceptionTest diff --git a/mcs/class/System.Data/Test/System.Data/DataSetTest2.cs b/mcs/class/System.Data/Test/System.Data/DataSetTest2.cs index 27df0f58984..6e338558389 100644 --- a/mcs/class/System.Data/Test/System.Data/DataSetTest2.cs +++ b/mcs/class/System.Data/Test/System.Data/DataSetTest2.cs @@ -39,7 +39,7 @@ using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Globalization; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataSetTest2 @@ -448,7 +448,7 @@ namespace MonoTests_System.Data dt.Rows.Add(new object[] {2,"Value3","Value4"}); dt.Rows.Add(new object[] {3,"Value5","Value5"}); - System.Text.StringBuilder resultXML = new System.Text.StringBuilder(); + StringBuilder resultXML = new StringBuilder(); resultXML.Append("<" + ds.DataSetName + "xmlns=\"namespace\">"); @@ -975,13 +975,13 @@ namespace MonoTests_System.Data [Test] public void Locale() { DataSet ds = new DataSet("MyDataSet"); - System.Globalization.CultureInfo culInfo = System.Globalization.CultureInfo.CurrentCulture ; + CultureInfo culInfo = CultureInfo.CurrentCulture ; // Checking Locale default from system Assert.AreEqual(culInfo, ds.Locale , "DS156"); // Checking Locale get/set - culInfo = new System.Globalization.CultureInfo("fr"); // = french + culInfo = new CultureInfo("fr"); // = french ds.Locale = culInfo ; Assert.AreEqual(culInfo , ds.Locale , "DS157"); } @@ -1998,11 +1998,11 @@ namespace MonoTests_System.Data ds1.Tables.Add(DataProvider.CreateParentDataTable()); ds1.Tables.Add(DataProvider.CreateChildDataTable()); - System.IO.MemoryStream ms = new System.IO.MemoryStream(); + MemoryStream ms = new MemoryStream(); //write xml schema only ds1.WriteXmlSchema(ms); - System.IO.MemoryStream ms1 = new System.IO.MemoryStream(ms.GetBuffer()); + MemoryStream ms1 = new MemoryStream(ms.GetBuffer()); //copy schema DataSet ds2 = new DataSet(); ds2.ReadXmlSchema(ms1); @@ -2073,7 +2073,7 @@ namespace MonoTests_System.Data Assert.AreEqual(0, ds2.Tables[1].Rows.Count , "DS282"); //try to delete the file - System.IO.File.Delete(sTempFileName); + File.Delete(sTempFileName); } [Test] public void ReadXmlSchema_ByTextReader() @@ -2082,11 +2082,11 @@ namespace MonoTests_System.Data ds1.Tables.Add(DataProvider.CreateParentDataTable()); ds1.Tables.Add(DataProvider.CreateChildDataTable()); - System.IO.StringWriter sw = new System.IO.StringWriter(); + StringWriter sw = new StringWriter(); //write xml file, schema only ds1.WriteXmlSchema(sw); - System.IO.StringReader sr = new System.IO.StringReader(sw.GetStringBuilder().ToString()); + StringReader sr = new StringReader(sw.GetStringBuilder().ToString()); //copy both data and schema DataSet ds2 = new DataSet(); ds2.ReadXmlSchema(sr); @@ -2122,14 +2122,14 @@ namespace MonoTests_System.Data ds1.Tables.Add(DataProvider.CreateParentDataTable()); ds1.Tables.Add(DataProvider.CreateChildDataTable()); - System.IO.StringWriter sw = new System.IO.StringWriter(); - System.Xml.XmlTextWriter xmlTW = new System.Xml.XmlTextWriter(sw); + StringWriter sw = new StringWriter(); + XmlTextWriter xmlTW = new XmlTextWriter(sw); //write xml file, schema only ds1.WriteXmlSchema(xmlTW); xmlTW.Flush(); - System.IO.StringReader sr = new System.IO.StringReader(sw.ToString()); - System.Xml.XmlTextReader xmlTR = new System.Xml.XmlTextReader(sr); + StringReader sr = new StringReader(sw.ToString()); + XmlTextReader xmlTR = new XmlTextReader(sr); //copy both data and schema DataSet ds2 = new DataSet(); @@ -2196,7 +2196,7 @@ namespace MonoTests_System.Data Assert.AreEqual(ds2.Tables[1].Rows.Count, ds1.Tables[1].Rows.Count , "DS299"); //try to delete the file - System.IO.File.Delete(sTempFileName); + File.Delete(sTempFileName); } [Test] @@ -2212,7 +2212,7 @@ namespace MonoTests_System.Data ds1.Tables[1].Rows.Add(new object[] {7,2," "," ",new DateTime(2000,1,1,0,0,0,0),35}); ds1.Tables[1].Rows.Add(new object[] {7,3,"","",new DateTime(2000,1,1,0,0,0,0),35}); - System.IO.MemoryStream ms = new System.IO.MemoryStream(); + MemoryStream ms = new MemoryStream(); //write xml file, data only ds1.WriteXml(ms); @@ -2241,7 +2241,7 @@ namespace MonoTests_System.Data { string input = string.Empty; - System.IO.StringReader sr; + StringReader sr; DataSet ds = new DataSet(); input += ""; @@ -2261,7 +2261,7 @@ namespace MonoTests_System.Data input += " "; input += ""; - sr = new System.IO.StringReader(input); + sr = new StringReader(input); ds.ReadXml(sr); @@ -2311,7 +2311,7 @@ namespace MonoTests_System.Data { DataSet ds = new DataSet("TestDataSet"); string input = string.Empty; - System.IO.StringReader sr; + StringReader sr; input += ""; input += "10.0"; @@ -2320,7 +2320,7 @@ namespace MonoTests_System.Data input += "22.2302/12/2001"; input += "1.9704/20/20033.0"; input += "TODAY"; - sr = new System.IO.StringReader(input); + sr = new StringReader(input); ds.EnforceConstraints = false; ds.ReadXml(sr); @@ -2339,7 +2339,7 @@ namespace MonoTests_System.Data { m_ds = new DataSet("Stocks"); string input = string.Empty; - System.IO.StringReader sr; + StringReader sr; input += ""; input += ""; @@ -2408,7 +2408,7 @@ namespace MonoTests_System.Data input += " "; input += ""; - sr = new System.IO.StringReader(input); + sr = new StringReader(input); m_ds.EnforceConstraints = true; m_ds.ReadXml(sr); this.privateTestCase("TestCase 1", "Company", "name='Microsoft Corp.'", "Stock", "name='MSFT'", "DS320"); @@ -2444,14 +2444,14 @@ namespace MonoTests_System.Data #region "TestCase 1 - Empty string" // Empty string DataSet ds = new DataSet(); - System.IO.StringReader sr = new System.IO.StringReader (string.Empty); - System.Xml.XmlTextReader xReader = new System.Xml.XmlTextReader(sr); + StringReader sr = new StringReader (string.Empty); + XmlTextReader xReader = new XmlTextReader(sr); try { ds.ReadXml (xReader); Assert.Fail("DS335: ReadXml Failed to throw XmlException"); } - catch (System.Xml.XmlException) {} + catch (XmlException) {} catch (AssertionException exc) {throw exc;} catch (Exception exc) { @@ -2635,8 +2635,8 @@ namespace MonoTests_System.Data private void PrivateTestCase(string a_name, string a_expected, string a_xmlData) { DataSet ds = new DataSet(); - System.IO.StringReader sr = new System.IO.StringReader(a_xmlData) ; - System.Xml.XmlTextReader xReader = new System.Xml.XmlTextReader(sr) ; + StringReader sr = new StringReader(a_xmlData) ; + XmlTextReader xReader = new XmlTextReader(sr) ; ds.ReadXml (xReader); Assert.AreEqual(a_expected, this.dataSetDescription(ds), "DS337"); } @@ -2681,8 +2681,8 @@ namespace MonoTests_System.Data xmlData += "3"; xmlData += ""; xmlData += ""; - System.IO.StringReader sr = new System.IO.StringReader(xmlData) ; - System.Xml.XmlTextReader xReader = new System.Xml.XmlTextReader(sr) ; + StringReader sr = new StringReader(xmlData) ; + XmlTextReader xReader = new XmlTextReader(sr) ; ds.ReadXml (xReader); Assert.AreEqual(3, ds.Tables["c"].Rows.Count, "DS338"); } @@ -2738,7 +2738,7 @@ namespace MonoTests_System.Data ds1.Tables[1].Rows.Add(new object[] {7,2," "," ",new DateTime(2000,1,1,0,0,0,0),35}); ds1.Tables[1].Rows.Add(new object[] {7,3,"","",new DateTime(2000,1,1,0,0,0,0),35}); - System.IO.StringWriter sw = new System.IO.StringWriter(); + StringWriter sw = new StringWriter(); //write xml file, data only ds1.WriteXml(sw); @@ -2747,7 +2747,7 @@ namespace MonoTests_System.Data //clear the data ds2.Clear(); - System.IO.StringReader sr = new System.IO.StringReader(sw.GetStringBuilder().ToString()); + StringReader sr = new StringReader(sw.GetStringBuilder().ToString()); ds2.ReadXml(sr); //check xml data @@ -2777,8 +2777,8 @@ namespace MonoTests_System.Data ds1.Tables[1].Rows.Add(new object[] {7,2," "," ",new DateTime(2000,1,1,0,0,0,0),35}); ds1.Tables[1].Rows.Add(new object[] {7,3,"","",new DateTime(2000,1,1,0,0,0,0),35}); - System.IO.StringWriter sw = new System.IO.StringWriter(); - System.Xml.XmlTextWriter xmlTW = new System.Xml.XmlTextWriter(sw); + StringWriter sw = new StringWriter(); + XmlTextWriter xmlTW = new XmlTextWriter(sw); //write xml file, data only ds1.WriteXml(xmlTW); @@ -2788,8 +2788,8 @@ namespace MonoTests_System.Data DataSet ds2 = ds1.Copy(); //clear the data ds2.Clear(); - System.IO.StringReader sr = new System.IO.StringReader(sw.ToString()); - System.Xml.XmlTextReader xmlTR = new System.Xml.XmlTextReader(sr); + StringReader sr = new StringReader(sw.ToString()); + XmlTextReader xmlTR = new XmlTextReader(sr); ds2.ReadXml(xmlTR); //check xml data @@ -2847,8 +2847,8 @@ namespace MonoTests_System.Data [Test] public void WriteXmlSchema_Relations_ForeignKeys () { - System.IO.MemoryStream ms = null; - System.IO.MemoryStream ms1 = null; + MemoryStream ms = null; + MemoryStream ms1 = null; DataSet ds1 = new DataSet(); @@ -2884,10 +2884,10 @@ namespace MonoTests_System.Data new DataColumn[] {col1_5, col1_6}, new DataColumn[] {col2_5, col2_6}); - ms = new System.IO.MemoryStream(); + ms = new MemoryStream(); ds1.WriteXmlSchema (ms); - ms1 = new System.IO.MemoryStream (ms.GetBuffer()); + ms1 = new MemoryStream (ms.GetBuffer()); DataSet ds2 = new DataSet(); ds2.ReadXmlSchema(ms1); @@ -3096,18 +3096,18 @@ namespace MonoTests_System.Data [Test] public void WriteXml_ByTextWriterXmlWriteMode() { - System.IO.StringReader sr = null; - System.IO.StringWriter sw = null; + StringReader sr = null; + StringWriter sw = null; try // For real { // ReadXml - DataSetOut DataSet oDataset = new DataSet("DataSetOut"); - sw = new System.IO.StringWriter(); - oDataset.WriteXml(sw,System.Data.XmlWriteMode.WriteSchema); + sw = new StringWriter(); + oDataset.WriteXml(sw, XmlWriteMode.WriteSchema); - sr = new System.IO.StringReader(sw.GetStringBuilder().ToString()); + sr = new StringReader(sw.GetStringBuilder().ToString()); oDataset = new DataSet("DataSetOut"); oDataset.ReadXml(sr); @@ -3252,13 +3252,13 @@ namespace MonoTests_System.Data { DataSet ds = new DataSet(); string input = "2"; - System.IO.StringReader sr = new System.IO.StringReader(input) ; - System.Xml.XmlTextReader xReader = new System.Xml.XmlTextReader(sr) ; + StringReader sr = new StringReader(input) ; + XmlTextReader xReader = new XmlTextReader(sr) ; ds.ReadXml (xReader); - System.Text.StringBuilder sb = new System.Text.StringBuilder(); - System.IO.StringWriter sw = new System.IO.StringWriter(sb); - System.Xml.XmlTextWriter xWriter = new System.Xml.XmlTextWriter(sw); + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); + XmlTextWriter xWriter = new XmlTextWriter(sw); ds.WriteXml(xWriter); string output = sb.ToString(); Assert.AreEqual(input,output, "DS76"); @@ -3267,20 +3267,20 @@ namespace MonoTests_System.Data DataSet ds = new DataSet(); string input = "2"; string expectedOutput = "2"; - System.IO.StringReader sr = new System.IO.StringReader(input) ; - System.Xml.XmlTextReader xReader = new System.Xml.XmlTextReader(sr) ; + StringReader sr = new StringReader(input) ; + XmlTextReader xReader = new XmlTextReader(sr) ; ds.ReadXml (xReader); - System.Text.StringBuilder sb = new System.Text.StringBuilder(); - System.IO.StringWriter sw = new System.IO.StringWriter(sb); - System.Xml.XmlTextWriter xWriter = new System.Xml.XmlTextWriter(sw); + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); + XmlTextWriter xWriter = new XmlTextWriter(sw); ds.WriteXml(xWriter); string output = sb.ToString(); Assert.AreEqual(expectedOutput,output, "DS77"); } { DataSet ds = new DataSet("DSName"); - System.IO.StringWriter sr = new System.IO.StringWriter(); + StringWriter sr = new StringWriter(); ds.WriteXml(sr); Assert.AreEqual("",sr.ToString(), "DS78"); } @@ -3315,7 +3315,7 @@ namespace MonoTests_System.Data ds.Tables.Remove("ChildTable"); //Get the xml representation of the dataset. - System.IO.StringWriter sr = new System.IO.StringWriter(); + StringWriter sr = new StringWriter(); ds.WriteXml(sr); string xml = sr.ToString(); diff --git a/mcs/class/System.Data/Test/System.Data/DataTableCollectionTest2.cs b/mcs/class/System.Data/Test/System.Data/DataTableCollectionTest2.cs index 9229265648c..053825e3501 100644 --- a/mcs/class/System.Data/Test/System.Data/DataTableCollectionTest2.cs +++ b/mcs/class/System.Data/Test/System.Data/DataTableCollectionTest2.cs @@ -28,10 +28,12 @@ using NUnit.Framework; using System; +using System.Collections; +using System.ComponentModel; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataTableCollectionTest2 { @@ -143,7 +145,7 @@ namespace MonoTests_System.Data { counter = 0; DataSet ds = new DataSet(); - ds.Tables.CollectionChanged+=new System.ComponentModel.CollectionChangeEventHandler(Tables_CollectionChanged); + ds.Tables.CollectionChanged+=new CollectionChangeEventHandler(Tables_CollectionChanged); ds.Tables.Add(); ds.Tables.Add(); Assert.AreEqual(2, counter, "DTC15"); @@ -153,7 +155,7 @@ namespace MonoTests_System.Data Assert.AreEqual(4, counter, "DTC16"); } - private void Tables_CollectionChanged(object sender, System.ComponentModel.CollectionChangeEventArgs e) + private void Tables_CollectionChanged(object sender, CollectionChangeEventArgs e) { counter++; } @@ -163,7 +165,7 @@ namespace MonoTests_System.Data { counter = 0; DataSet ds = new DataSet(); - ds.Tables.CollectionChanging+=new System.ComponentModel.CollectionChangeEventHandler(Tables_CollectionChanging); + ds.Tables.CollectionChanging+=new CollectionChangeEventHandler(Tables_CollectionChanging); ds.Tables.Add(); ds.Tables.Add(); Assert.AreEqual(2, counter, "DTC17"); @@ -173,7 +175,7 @@ namespace MonoTests_System.Data Assert.AreEqual(4, counter, "DTC18"); } - private void Tables_CollectionChanging(object sender, System.ComponentModel.CollectionChangeEventArgs e) + private void Tables_CollectionChanging(object sender, CollectionChangeEventArgs e) { counter++; } @@ -233,7 +235,7 @@ namespace MonoTests_System.Data ds.Tables.Add(); int count=0; - System.Collections.IEnumerator myEnumerator = ds.Tables.GetEnumerator(); + IEnumerator myEnumerator = ds.Tables.GetEnumerator(); while (myEnumerator.MoveNext()) { diff --git a/mcs/class/System.Data/Test/System.Data/DataTableTest2.cs b/mcs/class/System.Data/Test/System.Data/DataTableTest2.cs index 331875ac888..bed6e55e50c 100644 --- a/mcs/class/System.Data/Test/System.Data/DataTableTest2.cs +++ b/mcs/class/System.Data/Test/System.Data/DataTableTest2.cs @@ -36,7 +36,7 @@ using MonoTests.System.Data.Utils; using NUnit.Framework; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataTableTest2 diff --git a/mcs/class/System.Data/Test/System.Data/DataTableTest3.cs b/mcs/class/System.Data/Test/System.Data/DataTableTest3.cs index 6fc2d64b20b..c706778c67b 100644 --- a/mcs/class/System.Data/Test/System.Data/DataTableTest3.cs +++ b/mcs/class/System.Data/Test/System.Data/DataTableTest3.cs @@ -31,7 +31,7 @@ using System.Xml; using NUnit.Framework; -namespace Monotests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataTableTest3 diff --git a/mcs/class/System.Data/Test/System.Data/DataTableTest4.cs b/mcs/class/System.Data/Test/System.Data/DataTableTest4.cs index 2cdd5af913b..c7cb3a35e85 100644 --- a/mcs/class/System.Data/Test/System.Data/DataTableTest4.cs +++ b/mcs/class/System.Data/Test/System.Data/DataTableTest4.cs @@ -31,7 +31,7 @@ using System.IO; using System.Xml; using NUnit.Framework; -namespace Monotests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataTableTest4 @@ -1600,7 +1600,7 @@ namespace Monotests_System.Data DataSet ds = new DataSet (); DataTable table = new DataTable ("ParentTable"); XmlReadMode mode = XmlReadMode.Auto; - table.Columns.Add (new DataColumn ("id", System.Type.GetType ("System.Int32"))); + table.Columns.Add (new DataColumn ("id", Type.GetType ("System.Int32"))); ds.Tables.Add (table); using (FileStream stream = new FileStream (tempFile, FileMode.Open)) { @@ -1638,7 +1638,7 @@ namespace Monotests_System.Data using (FileStream stream = new FileStream (tempFile, FileMode.Open)) { DataSet ds = new DataSet (); DataTable table = new DataTable ("Table1"); - table.Columns.Add (new DataColumn ("id", System.Type.GetType ("System.Int32"))); + table.Columns.Add (new DataColumn ("id", Type.GetType ("System.Int32"))); ds.Tables.Add (table); try { @@ -1852,7 +1852,7 @@ namespace Monotests_System.Data DataTable table = new DataTable ("DummyTable"); //define the table schame partially with a column name which does not match with any //table columns in the diffgram - table.Columns.Add (new DataColumn ("WrongColumnName", System.Type.GetType ("System.String"))); + table.Columns.Add (new DataColumn ("WrongColumnName", Type.GetType ("System.String"))); XmlReadMode mode = XmlReadMode.Auto; @@ -2013,8 +2013,8 @@ namespace Monotests_System.Data Assert.AreEqual ("NewDataSet", table.DataSet.DataSetName, "#2"); Assert.AreEqual (2, table.Columns.Count, "#3"); Assert.AreEqual (2, table.Rows.Count, "#4"); - Assert.AreEqual (typeof (System.Int32), table.Columns [0].DataType, "#5"); - Assert.AreEqual (typeof (System.String), table.Columns [1].DataType, "#6"); + Assert.AreEqual (typeof (Int32), table.Columns [0].DataType, "#5"); + Assert.AreEqual (typeof (String), table.Columns [1].DataType, "#6"); Assert.AreEqual (1, table.Constraints.Count, "#7"); Assert.AreEqual (typeof (UniqueConstraint), table.Constraints [0].GetType (), "#8"); Assert.AreEqual (1, table.ChildRelations.Count, "#9"); @@ -2027,9 +2027,9 @@ namespace Monotests_System.Data Assert.AreEqual ("NewDataSet", table1.DataSet.DataSetName, "#14"); Assert.AreEqual (3, table1.Columns.Count, "#15"); Assert.AreEqual (4, table1.Rows.Count, "#16"); - Assert.AreEqual (typeof (System.Int32), table1.Columns [0].DataType, "#17"); - Assert.AreEqual (typeof (System.String), table1.Columns [1].DataType, "#18"); - Assert.AreEqual (typeof (System.Int32), table1.Columns [2].DataType, "#19"); + Assert.AreEqual (typeof (Int32), table1.Columns [0].DataType, "#17"); + Assert.AreEqual (typeof (String), table1.Columns [1].DataType, "#18"); + Assert.AreEqual (typeof (Int32), table1.Columns [2].DataType, "#19"); Assert.AreEqual (2, table1.Constraints.Count, "#20"); Assert.AreEqual (typeof (UniqueConstraint), table1.Constraints [0].GetType (), "#21"); Assert.AreEqual (typeof (ForeignKeyConstraint), table1.Constraints [1].GetType (), "#22"); @@ -2045,8 +2045,8 @@ namespace Monotests_System.Data Assert.AreEqual ("NewDataSet", table1.DataSet.DataSetName, "#29"); Assert.AreEqual (2, table1.Columns.Count, "#30"); Assert.AreEqual (8, table1.Rows.Count, "#31"); - Assert.AreEqual (typeof (System.Int32), table1.Columns [0].DataType, "#32"); - Assert.AreEqual (typeof (System.String), table1.Columns [1].DataType, "#33"); + Assert.AreEqual (typeof (Int32), table1.Columns [0].DataType, "#32"); + Assert.AreEqual (typeof (String), table1.Columns [1].DataType, "#33"); Assert.AreEqual (1, table1.Constraints.Count, "#34"); Assert.AreEqual (typeof (ForeignKeyConstraint), table1.Constraints [0].GetType (), "#35"); Assert.AreEqual (1, table1.ParentRelations.Count, "#36"); diff --git a/mcs/class/System.Data/Test/System.Data/DataTableTest5.cs b/mcs/class/System.Data/Test/System.Data/DataTableTest5.cs index 3bcbf75889a..0cacc8ea9ef 100644 --- a/mcs/class/System.Data/Test/System.Data/DataTableTest5.cs +++ b/mcs/class/System.Data/Test/System.Data/DataTableTest5.cs @@ -34,7 +34,7 @@ using System.Xml.Serialization; using NUnit.Framework; -namespace Monotests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataTableTest5 diff --git a/mcs/class/System.Data/Test/System.Data/DataViewTest2.cs b/mcs/class/System.Data/Test/System.Data/DataViewTest2.cs index f6c6b3f9a8c..58ca232fb53 100644 --- a/mcs/class/System.Data/Test/System.Data/DataViewTest2.cs +++ b/mcs/class/System.Data/Test/System.Data/DataViewTest2.cs @@ -28,12 +28,13 @@ using NUnit.Framework; using System; -using System.IO; +using System.Collections; using System.ComponentModel; +using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataViewTest2 { @@ -41,7 +42,7 @@ namespace MonoTests_System.Data class EventProperties //hold the event properties to be checked { - public System.ComponentModel.ListChangedType lstType ; + public ListChangedType lstType ; public int NewIndex; public int OldIndex; } @@ -508,7 +509,7 @@ namespace MonoTests_System.Data //create the dataview for the table DataView dv = new DataView(dt); - System.Collections.IEnumerator ienm = null; + IEnumerator ienm = null; // GetEnumerator != null ienm = dv.GetEnumerator(); @@ -549,7 +550,7 @@ namespace MonoTests_System.Data DataView dv = new DataView(dt); //add event handler - dv.ListChanged +=new System.ComponentModel.ListChangedEventHandler(dv_ListChanged); + dv.ListChanged +=new ListChangedEventHandler(dv_ListChanged); // ----- Change Value --------- evProp = null; @@ -557,7 +558,7 @@ namespace MonoTests_System.Data dv[1]["String1"] = "something"; Assert.AreEqual(true , evProp!=null , "DV58"); // change value - ListChangedType - Assert.AreEqual(System.ComponentModel.ListChangedType.ItemChanged, evProp.lstType , "DV59"); + Assert.AreEqual(ListChangedType.ItemChanged, evProp.lstType , "DV59"); // change value - NewIndex Assert.AreEqual(1, evProp.NewIndex, "DV60"); // change value - OldIndex @@ -569,7 +570,7 @@ namespace MonoTests_System.Data dv.AddNew(); Assert.AreEqual(true , evProp!=null , "DV62"); // Add New - ListChangedType - Assert.AreEqual(System.ComponentModel.ListChangedType.ItemAdded , evProp.lstType , "DV63"); + Assert.AreEqual(ListChangedType.ItemAdded , evProp.lstType , "DV63"); // Add New - NewIndex Assert.AreEqual(6, evProp.NewIndex, "DV64"); // Add New - OldIndex @@ -581,7 +582,7 @@ namespace MonoTests_System.Data dv.Sort = "ParentId Desc"; Assert.AreEqual(true , evProp!=null , "DV66"); // sort - ListChangedType - Assert.AreEqual(System.ComponentModel.ListChangedType.Reset , evProp.lstType , "DV67"); + Assert.AreEqual(ListChangedType.Reset , evProp.lstType , "DV67"); // sort - NewIndex Assert.AreEqual(-1, evProp.NewIndex, "DV68"); // sort - OldIndex @@ -627,12 +628,12 @@ namespace MonoTests_System.Data Assert.AreEqual(true , evProp != null , "DV168"); // Clear DataTable - should emit ListChangedType.Reset - Assert.AreEqual(System.ComponentModel.ListChangedType.Reset , evProp.lstType , "DV169"); + Assert.AreEqual(ListChangedType.Reset , evProp.lstType , "DV169"); // Clear DataTable - should clear view count Assert.AreEqual(0, dt.DefaultView.Count , "DV169"); } - private void dv_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e) + private void dv_ListChanged(object sender, ListChangedEventArgs e) { evProp = new EventProperties(); evProp.lstType = e.ListChangedType; @@ -646,7 +647,7 @@ namespace MonoTests_System.Data // this test also check DataView.Count property DataRowView[] drvResult = null; - System.Collections.ArrayList al = new System.Collections.ArrayList(); + ArrayList al = new ArrayList(); //create the source datatable DataTable dt = DataProvider.CreateChildDataTable(); @@ -763,7 +764,7 @@ namespace MonoTests_System.Data */ //DataRowView[] drvResult = null; - System.Collections.ArrayList al = new System.Collections.ArrayList(); + ArrayList al = new ArrayList(); DataTable dt = DataProvider.CreateParentDataTable(); @@ -821,7 +822,7 @@ namespace MonoTests_System.Data private DataRow[] GetResultRows(DataTable dt,DataRowState State) { //get expected rows - System.Collections.ArrayList al = new System.Collections.ArrayList(); + ArrayList al = new ArrayList(); DataRowVersion drVer = DataRowVersion.Current; //From MSDN - The row the default version for the current DataRowState. diff --git a/mcs/class/System.Data/Test/System.Data/DeletedRowInaccessibleExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/DeletedRowInaccessibleExceptionTest.cs index 89fdeb547b1..be2810330fd 100644 --- a/mcs/class/System.Data/Test/System.Data/DeletedRowInaccessibleExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/DeletedRowInaccessibleExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DeletedRowInaccessibleExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/DuplicateNameExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/DuplicateNameExceptionTest.cs index c26a71db1e1..77cf583fc81 100644 --- a/mcs/class/System.Data/Test/System.Data/DuplicateNameExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/DuplicateNameExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DuplicateNameExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/EvaluateExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/EvaluateExceptionTest.cs index dd6fe52c914..a9c41f0c2a1 100644 --- a/mcs/class/System.Data/Test/System.Data/EvaluateExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/EvaluateExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; //using GHTUtils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class EvaluateExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/ForeignKeyConstraintTest2.cs b/mcs/class/System.Data/Test/System.Data/ForeignKeyConstraintTest2.cs index c0ed174c96d..591fef23f04 100644 --- a/mcs/class/System.Data/Test/System.Data/ForeignKeyConstraintTest2.cs +++ b/mcs/class/System.Data/Test/System.Data/ForeignKeyConstraintTest2.cs @@ -31,7 +31,7 @@ using System; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class ForeignKeyConstraintTest2 { diff --git a/mcs/class/System.Data/Test/System.Data/InRowChangingEventExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/InRowChangingEventExceptionTest.cs index 08dd7f08c69..549076cbb39 100644 --- a/mcs/class/System.Data/Test/System.Data/InRowChangingEventExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/InRowChangingEventExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class InRowChangingEventExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/InvalidConstraintExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/InvalidConstraintExceptionTest.cs index 1aacff1ee99..04c19bfc75f 100644 --- a/mcs/class/System.Data/Test/System.Data/InvalidConstraintExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/InvalidConstraintExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class InvalidConstraintExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/MissingPrimaryKeyExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/MissingPrimaryKeyExceptionTest.cs index 75791b325b4..14404f2b35f 100644 --- a/mcs/class/System.Data/Test/System.Data/MissingPrimaryKeyExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/MissingPrimaryKeyExceptionTest.cs @@ -32,7 +32,7 @@ using System.Data; using NUnit.Framework; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] class MissingPrimaryKeyExceptionTest @@ -57,4 +57,4 @@ namespace MonoTests_System.Data tbl.Rows.Contains("Something"); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data/Test/System.Data/NoNullAllowedExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/NoNullAllowedExceptionTest.cs index 5b1506a857d..45a5c5f3f76 100644 --- a/mcs/class/System.Data/Test/System.Data/NoNullAllowedExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/NoNullAllowedExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class NoNullAllowedExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/ReadOnlyExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/ReadOnlyExceptionTest.cs index 4969ea0a93d..dd16e85714a 100644 --- a/mcs/class/System.Data/Test/System.Data/ReadOnlyExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/ReadOnlyExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class ReadOnlyExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/RowNotInTableExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/RowNotInTableExceptionTest.cs index 349bdb8ae88..edade038354 100644 --- a/mcs/class/System.Data/Test/System.Data/RowNotInTableExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/RowNotInTableExceptionTest.cs @@ -31,7 +31,7 @@ using System; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class RowNotInTableExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/SyntaxErrorExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/SyntaxErrorExceptionTest.cs index 875be983894..e1e2b08e24b 100644 --- a/mcs/class/System.Data/Test/System.Data/SyntaxErrorExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/SyntaxErrorExceptionTest.cs @@ -32,7 +32,7 @@ using System.Text; using System.IO; using System.Data; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class SyntaxErrorExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/TrailingSpaceTest.cs b/mcs/class/System.Data/Test/System.Data/TrailingSpaceTest.cs index 788cc5a390e..8c6d6a0d863 100644 --- a/mcs/class/System.Data/Test/System.Data/TrailingSpaceTest.cs +++ b/mcs/class/System.Data/Test/System.Data/TrailingSpaceTest.cs @@ -2,7 +2,7 @@ using NUnit.Framework; using System; using System.Data; -namespace Monotests_Mono.Data.SqlExpressions +namespace MonoTests.System.Data { [TestFixture] public class ComparisonTest { @@ -10,7 +10,7 @@ namespace Monotests_Mono.Data.SqlExpressions [Test] public void TestStringTrailingSpaceHandling () { // test for bug 79695 - does not ignore certain trailing whitespace chars when comparing strings - System.Data.DataTable dataTable = new System.Data.DataTable ("Person"); + DataTable dataTable = new DataTable ("Person"); dataTable.Columns.Add ("Name", typeof (string)); dataTable.Rows.Add (new object[] {"Mike "}); DataRow[] selectedRows = dataTable.Select ("Name = 'Mike'"); diff --git a/mcs/class/System.Data/Test/System.Data/UniqueConstraintTest2.cs b/mcs/class/System.Data/Test/System.Data/UniqueConstraintTest2.cs index a21d94f1883..4e0224430c0 100644 --- a/mcs/class/System.Data/Test/System.Data/UniqueConstraintTest2.cs +++ b/mcs/class/System.Data/Test/System.Data/UniqueConstraintTest2.cs @@ -31,7 +31,7 @@ using System; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class UniqueConstraintTest2 { diff --git a/mcs/class/System.Data/Test/System.Data/VersionNotFoundException.cs b/mcs/class/System.Data/Test/System.Data/VersionNotFoundException.cs index 8c2e7a9f7f1..235e30890a2 100644 --- a/mcs/class/System.Data/Test/System.Data/VersionNotFoundException.cs +++ b/mcs/class/System.Data/Test/System.Data/VersionNotFoundException.cs @@ -32,7 +32,7 @@ using System.Data; using NUnit.Framework; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] class VersionNotFoundExceptionTest @@ -73,4 +73,4 @@ namespace MonoTests_System.Data object obj = drParent[0,DataRowVersion.Original]; } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data/Test/System.Data/XmlDataLoaderTest.cs b/mcs/class/System.Data/Test/System.Data/XmlDataLoaderTest.cs index dee7e6e378f..2e0fe018304 100644 --- a/mcs/class/System.Data/Test/System.Data/XmlDataLoaderTest.cs +++ b/mcs/class/System.Data/Test/System.Data/XmlDataLoaderTest.cs @@ -32,7 +32,7 @@ using System.Xml; using NUnit.Framework; -namespace Monotests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class XmlDataLoaderTest @@ -74,7 +74,7 @@ namespace Monotests_System.Data DataSet ds = new DataSet ("Set"); DataTable dt = new DataTable ("Test"); dt.Columns.Add ("CustName", typeof (String)); - dt.Columns.Add ("Type", typeof (System.Type)); + dt.Columns.Add ("Type", typeof (Type)); ds.Tables.Add (dt); return ds; } diff --git a/mcs/class/System.Data/Test/System.Data/XmlDataReaderTest.cs b/mcs/class/System.Data/Test/System.Data/XmlDataReaderTest.cs index 546db60bfb9..9bff68d0b92 100644 --- a/mcs/class/System.Data/Test/System.Data/XmlDataReaderTest.cs +++ b/mcs/class/System.Data/Test/System.Data/XmlDataReaderTest.cs @@ -33,7 +33,7 @@ using System.Xml.Serialization; using System.Xml.Schema; using NUnit.Framework; -namespace Monotests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class XmlDataReaderTest @@ -103,7 +103,7 @@ namespace Monotests_System.Data StringReader sr = new StringReader (xml); XmlTextReader xr = new XmlTextReader (sr); DataTable tbl = new DataTable("CustomTypesTable"); - tbl.Columns.Add("Dummy", typeof(System.UInt32)); + tbl.Columns.Add("Dummy", typeof(UInt32)); tbl.Columns.Add("FuncXml", typeof(CustomTypeXml)); DataSet ds = new DataSet("CustomTypesData"); diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentRangeHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentRangeHeaderValue.cs index 118d65085f7..1bea52b76e8 100644 --- a/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentRangeHeaderValue.cs +++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentRangeHeaderValue.cs @@ -170,7 +170,7 @@ namespace System.Net.Http.Headers } else { value.From = nvalue; - t = lexer.Scan (); + t = lexer.Scan (recognizeDash: true); if (t != Token.Type.SeparatorDash) return false; diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs index 5bd7d093acf..622e36b0ec2 100644 --- a/mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs +++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs @@ -247,7 +247,7 @@ namespace System.Net.Http.Headers return false; } - public Token Scan () + public Token Scan (bool recognizeDash = false) { int start = pos; if (s == null) @@ -279,8 +279,12 @@ namespace System.Net.Http.Headers ttype = Token.Type.SeparatorSlash; break; case '-': - ttype = Token.Type.SeparatorDash; - break; + if (recognizeDash) { + ttype = Token.Type.SeparatorDash; + break; + } + + goto default; case ',': ttype = Token.Type.SeparatorComma; break; diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/RangeHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/RangeHeaderValue.cs index ad8e7e2b4f3..36e9c806157 100644 --- a/mcs/class/System.Net.Http/System.Net.Http.Headers/RangeHeaderValue.cs +++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/RangeHeaderValue.cs @@ -127,7 +127,7 @@ namespace System.Net.Http.Headers int number; token_read = false; - t = lexer.Scan (); + t = lexer.Scan (recognizeDash: true); switch (t.Kind) { case Token.Type.SeparatorDash: t = lexer.Scan (); @@ -144,7 +144,7 @@ namespace System.Net.Http.Headers switch (values.Length) { case 1: - t = lexer.Scan (); + t = lexer.Scan (recognizeDash: true); from = number; switch (t.Kind) { case Token.Type.SeparatorDash: diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs index 865a8062b77..b4de2a029cf 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs @@ -50,7 +50,6 @@ namespace System.Net.Http bool useProxy; ClientCertificateOption certificate; bool sentRequest; - HttpWebRequest wrequest; string connectionGroupName; bool disposed; @@ -221,12 +220,9 @@ namespace System.Net.Http protected override void Dispose (bool disposing) { - if (disposing) { - if (wrequest != null) { - wrequest.ServicePoint.CloseConnectionGroup (wrequest.ConnectionGroupName); - Volatile.Write (ref wrequest, null); - } + if (disposing && !disposed) { Volatile.Write (ref disposed, true); + ServicePointManager.CloseConnectionGroup (connectionGroupName); } base.Dispose (disposing); @@ -317,7 +313,7 @@ namespace System.Net.Http throw new ObjectDisposedException (GetType ().ToString ()); Volatile.Write (ref sentRequest, true); - wrequest = CreateWebRequest (request); + var wrequest = CreateWebRequest (request); if (request.Content != null) { var headers = wrequest.Headers; diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/MediaTypeHeaderValueTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/MediaTypeHeaderValueTest.cs index afbf8274b9f..c4b882467aa 100644 --- a/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/MediaTypeHeaderValueTest.cs +++ b/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/MediaTypeHeaderValueTest.cs @@ -31,6 +31,7 @@ using System.Collections; using System.Collections.Generic; using NUnit.Framework; using System.Net.Http.Headers; +using System.Linq; namespace MonoTests.System.Net.Http.Headers { @@ -81,6 +82,13 @@ namespace MonoTests.System.Net.Http.Headers Assert.AreEqual ("mu/m", res.MediaType, "#2"); Assert.AreEqual ("jj'", res.CharSet, "#2b"); Assert.AreEqual ("mu/m; CHarset=jj'", res.ToString (), "#2c"); + + res = MediaTypeHeaderValue.Parse ("multipart/form-data; boundary=----Wk"); + Assert.AreEqual ("multipart/form-data", res.MediaType, "#3"); + Assert.IsNull (res.CharSet, "#3b"); + Assert.AreEqual (1, res.Parameters.Count, "#3c"); + Assert.AreEqual (new NameValueHeaderValue ("boundary", "----Wk"), res.Parameters.First (), "#3d"); + Assert.AreEqual ("multipart/form-data; boundary=----Wk", res.ToString (), "#3e"); } [Test] diff --git a/mcs/class/System.Numerics/System.Numerics/BigInteger.cs b/mcs/class/System.Numerics/System.Numerics/BigInteger.cs index 329f91eed1f..93fb7b939e4 100644 --- a/mcs/class/System.Numerics/System.Numerics/BigInteger.cs +++ b/mcs/class/System.Numerics/System.Numerics/BigInteger.cs @@ -1,10 +1,12 @@ // // System.Numerics.BigInteger // -// Rodrigo Kumpera (rkumpera@novell.com) - +// Authors: +// Rodrigo Kumpera (rkumpera@novell.com) +// Marek Safar // // Copyright (C) 2010 Novell, Inc (http://www.novell.com) +// Copyright (C) 2014 Xamarin Inc (http://www.xamarin.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -68,7 +70,6 @@ namespace System.Numerics { readonly uint[] data; readonly short sign; - static readonly uint[] ZERO = new uint [1]; static readonly uint[] ONE = new uint [1] { 1 }; BigInteger (short sign, uint[] data) @@ -81,7 +82,7 @@ namespace System.Numerics { { if (value == 0) { sign = 0; - data = ZERO; + data = null; } else if (value > 0) { sign = 1; data = new uint[] { (uint) value }; @@ -96,7 +97,7 @@ namespace System.Numerics { { if (value == 0) { sign = 0; - data = ZERO; + data = null; } else { sign = 1; data = new uint [1] { value }; @@ -107,7 +108,7 @@ namespace System.Numerics { { if (value == 0) { sign = 0; - data = ZERO; + data = null; } else if (value > 0) { sign = 1; uint low = (uint)value; @@ -135,7 +136,7 @@ namespace System.Numerics { { if (value == 0) { sign = 0; - data = ZERO; + data = null; } else { sign = 1; uint low = (uint)value; @@ -180,7 +181,7 @@ namespace System.Numerics { int exponent = Exponent (bytes); if (exponent == 0) { sign = 0; - data = ZERO; + data = null; return; } @@ -217,7 +218,7 @@ namespace System.Numerics { if (size == 0) { sign = 0; - data = ZERO; + data = null; return; } @@ -241,7 +242,7 @@ namespace System.Numerics { if (len == 0 || (len == 1 && value [0] == 0)) { sign = 0; - data = ZERO; + data = null; return; } @@ -254,7 +255,7 @@ namespace System.Numerics { while (value [len - 1] == 0) { if (--len == 0) { sign = 0; - data = ZERO; + data = null; return; } } @@ -456,12 +457,12 @@ namespace System.Numerics { } public static BigInteger Zero { - get { return new BigInteger (0, ZERO); } + get { return new BigInteger (0); } } public static explicit operator int (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return 0; if (value.data.Length > 1) throw new OverflowException (); @@ -483,7 +484,7 @@ namespace System.Numerics { [CLSCompliantAttribute (false)] public static explicit operator uint (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return 0; if (value.data.Length > 1 || value.sign == -1) throw new OverflowException (); @@ -527,7 +528,7 @@ namespace System.Numerics { public static explicit operator long (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return 0; if (value.data.Length > 2) @@ -569,7 +570,7 @@ namespace System.Numerics { [CLSCompliantAttribute (false)] public static explicit operator ulong (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return 0; if (value.data.Length > 2 || value.sign == -1) throw new OverflowException (); @@ -584,9 +585,10 @@ namespace System.Numerics { public static explicit operator double (BigInteger value) { - switch (value.data.Length) { - case 0: + if (value.data == null) return 0.0; + + switch (value.data.Length) { case 1: return BuildDouble (value.sign, value.data [0], 0); case 2: @@ -613,7 +615,7 @@ namespace System.Numerics { public static explicit operator decimal (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return Decimal.Zero; uint[] data = value.data; @@ -703,7 +705,7 @@ namespace System.Numerics { int r = CoreCompare (left.data, right.data); if (r == 0) - return new BigInteger (0, ZERO); + return Zero; if (r > 0) //left > right return new BigInteger (left.sign, CoreSub (left.data, right.data)); @@ -722,7 +724,7 @@ namespace System.Numerics { int r = CoreCompare (left.data, right.data); if (r == 0) - return new BigInteger (0, ZERO); + return Zero; if (r > 0) //left > right return new BigInteger (left.sign, CoreSub (left.data, right.data)); @@ -736,7 +738,7 @@ namespace System.Numerics { public static BigInteger operator* (BigInteger left, BigInteger right) { if (left.sign == 0 || right.sign == 0) - return new BigInteger (0, ZERO); + return Zero; if (left.data [0] == 1 && left.data.Length == 1) { if (left.sign == 1) @@ -797,7 +799,7 @@ namespace System.Numerics { int i; for (i = quotient.Length - 1; i >= 0 && quotient [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < quotient.Length - 1) quotient = Resize (quotient, i + 1); @@ -820,7 +822,7 @@ namespace System.Numerics { int i; for (i = remainder_value.Length - 1; i >= 0 && remainder_value [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < remainder_value.Length - 1) remainder_value = Resize (remainder_value, i + 1); @@ -829,7 +831,7 @@ namespace System.Numerics { public static BigInteger operator- (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return value; return new BigInteger ((short)-value.sign, value.data); } @@ -841,14 +843,14 @@ namespace System.Numerics { public static BigInteger operator++ (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return One; short sign = value.sign; uint[] data = value.data; if (data.Length == 1) { if (sign == -1 && data [0] == 1) - return new BigInteger (0, ZERO); + return Zero; if (sign == 0) return new BigInteger (1, ONE); } @@ -863,14 +865,14 @@ namespace System.Numerics { public static BigInteger operator-- (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return MinusOne; short sign = value.sign; uint[] data = value.data; if (data.Length == 1) { if (sign == 1 && data [0] == 1) - return new BigInteger (0, ZERO); + return Zero; if (sign == 0) return new BigInteger (-1, ONE); } @@ -935,7 +937,7 @@ namespace System.Numerics { for (i = result.Length - 1; i >= 0 && result [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < result.Length - 1) result = Resize (result, i + 1); @@ -995,7 +997,7 @@ namespace System.Numerics { for (i = result.Length - 1; i >= 0 && result [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < result.Length - 1) result = Resize (result, i + 1); @@ -1055,7 +1057,7 @@ namespace System.Numerics { for (i = result.Length - 1; i >= 0 && result [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < result.Length - 1) result = Resize (result, i + 1); @@ -1065,7 +1067,7 @@ namespace System.Numerics { public static BigInteger operator~ (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return new BigInteger (-1, ONE); uint[] data = value.data; @@ -1099,7 +1101,7 @@ namespace System.Numerics { for (i = result.Length - 1; i >= 0 && result [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < result.Length - 1) result = Resize (result, i + 1); @@ -1121,7 +1123,7 @@ namespace System.Numerics { public static BigInteger operator<< (BigInteger value, int shift) { - if (shift == 0 || value.sign == 0) + if (shift == 0 || value.data == null) return value; if (shift < 0) return value >> -shift; @@ -1177,7 +1179,7 @@ namespace System.Numerics { if (size <= 0) { if (sign == 1) - return new BigInteger (0, ZERO); + return Zero; return new BigInteger (-1, ONE); } @@ -2142,7 +2144,7 @@ namespace System.Numerics { int i; for (i = remainder_value.Length - 1; i >= 0 && remainder_value [i] == 0; --i) ; if (i == -1) { - remainder = new BigInteger (0, ZERO); + remainder = Zero; } else { if (i < remainder_value.Length - 1) remainder_value = Resize (remainder_value, i + 1); @@ -2151,7 +2153,7 @@ namespace System.Numerics { for (i = quotient.Length - 1; i >= 0 && quotient [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < quotient.Length - 1) quotient = Resize (quotient, i + 1); @@ -2264,7 +2266,7 @@ namespace System.Numerics { if (baseValue == 0.0d || baseValue == Double.PositiveInfinity) return value.IsOne ? 0 : double.NaN; - if (value.sign == 0) + if (value.data == null) return double.NegativeInfinity; int length = value.data.Length - 1; diff --git a/mcs/class/System.Numerics/Test/System.Numerics/BigIntegerTest.cs b/mcs/class/System.Numerics/Test/System.Numerics/BigIntegerTest.cs index 817d13e40c1..c4ad9e811ee 100644 --- a/mcs/class/System.Numerics/Test/System.Numerics/BigIntegerTest.cs +++ b/mcs/class/System.Numerics/Test/System.Numerics/BigIntegerTest.cs @@ -625,10 +625,12 @@ namespace MonoTests.System.Numerics Assert.IsTrue (new BigInteger (1).IsOne, "#7"); Assert.IsTrue (new BigInteger (32).IsPowerOfTwo, "#8"); Assert.IsTrue (new BigInteger (0).IsZero, "#9"); + Assert.IsTrue (new BigInteger ().IsZero, "#9b"); Assert.AreEqual (0, new BigInteger (0).Sign, "#10"); Assert.AreEqual (-1, new BigInteger (-99999).Sign, "#11"); Assert.IsFalse (new BigInteger (0).IsPowerOfTwo, "#12"); + Assert.IsFalse (new BigInteger ().IsPowerOfTwo, "#12b"); Assert.IsFalse (new BigInteger (-16).IsPowerOfTwo, "#13"); Assert.IsTrue (new BigInteger (1).IsPowerOfTwo, "#14"); } @@ -647,6 +649,7 @@ namespace MonoTests.System.Numerics Assert.AreEqual ("0000000005", new BigInteger (5).ToString ("d10"), "#2"); Assert.AreEqual ("0A8", new BigInteger (168).ToString ("X"), "#3"); Assert.AreEqual ("0", new BigInteger (0).ToString ("X"), "#4"); + Assert.AreEqual ("0", new BigInteger ().ToString ("X"), "#4b"); Assert.AreEqual ("1", new BigInteger (1).ToString ("X"), "#5"); Assert.AreEqual ("0A", new BigInteger (10).ToString ("X"), "#6"); Assert.AreEqual ("F6", new BigInteger (-10).ToString ("X"), "#7"); @@ -750,6 +753,7 @@ namespace MonoTests.System.Numerics Assert.AreEqual (new byte[] { 0x7F }, new BigInteger (0x7F).ToByteArray (), "#10"); Assert.AreEqual (new byte[] { 0x45, 0xCC, 0xD0 }, new BigInteger (-0x2F33BB).ToByteArray (), "#11"); Assert.AreEqual (new byte[] { 0 }, new BigInteger (0).ToByteArray (), "#12"); + Assert.AreEqual (new byte[] { 0 }, new BigInteger ().ToByteArray (), "#13"); } [Test] @@ -886,6 +890,7 @@ namespace MonoTests.System.Numerics Assert.AreEqual (-1m, (decimal)new BigInteger (-1), "#6"); Assert.AreEqual (9999999999999999999999999999m, (decimal)new BigInteger (9999999999999999999999999999m), "#7"); + Assert.AreEqual (0m, (decimal)new BigInteger (), "#8"); } [Test] @@ -1276,6 +1281,9 @@ namespace MonoTests.System.Numerics a = new BigInteger (); Assert.AreEqual (BigInteger.Zero.GetHashCode (), a.GetHashCode (), "#15"); + + a = new BigInteger (); + Assert.AreEqual (BigInteger.Zero, a, "#16"); } [Test] diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CommunicationObjectSyncTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CommunicationObjectSyncTest.cs index 1650bead02d..798a77915f1 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CommunicationObjectSyncTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CommunicationObjectSyncTest.cs @@ -35,7 +35,7 @@ using System.ServiceModel.Channels; using Microsoft.VisualStudio.TestTools.UnitTesting; using Mono.Moonlight.UnitTesting; -namespace MoonTest.ServiceModel { +namespace MonoTests.System.ServiceModel.Channels { [TestClass] public class CommunicationObjectSyncTest { diff --git a/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceBaseTest.cs b/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceBaseTest.cs index 7a3c014f7cd..ec6a3a236b8 100644 --- a/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceBaseTest.cs +++ b/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceBaseTest.cs @@ -27,10 +27,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System.ComponentModel; using System.ServiceProcess; using NUnit.Framework; -namespace Test +namespace MonoTests.System.ServiceProcess { [TestFixture] public class ServiceBaseTest @@ -84,7 +85,7 @@ namespace Test /// /// Required designer variable. /// - private System.ComponentModel.IContainer components = null; + private IContainer components = null; /// /// Clean up any resources being used. @@ -107,7 +108,7 @@ namespace Test /// private void InitializeComponent() { - components = new System.ComponentModel.Container(); + components = new Container(); this.ServiceName = "ServiceFoo"; } diff --git a/mcs/class/System.Web.Extensions/System.Web.Script.Services/LogicalTypeInfo.cs b/mcs/class/System.Web.Extensions/System.Web.Script.Services/LogicalTypeInfo.cs index 5f8defbff81..a9b6fc01711 100644 --- a/mcs/class/System.Web.Extensions/System.Web.Script.Services/LogicalTypeInfo.cs +++ b/mcs/class/System.Web.Extensions/System.Web.Script.Services/LogicalTypeInfo.cs @@ -411,7 +411,7 @@ if (typeof({0}) === 'undefined') {{", className); var ret = new Dictionary (); for (int i = nvc.Count - 1; i >= 0; i--) - ret.Add (nvc.GetKey (i), JavaScriptSerializer.DefaultSerializer.DeserializeObjectInternal (nvc.Get (i))); + ret.Add (nvc.GetKey (i), nvc.Get (i)); return ret; } diff --git a/mcs/class/System.Web/System.Web/MimeTypes.cs b/mcs/class/System.Web/System.Web/MimeTypes.cs index 8b7bfcadf75..673507d1cf8 100644 --- a/mcs/class/System.Web/System.Web/MimeTypes.cs +++ b/mcs/class/System.Web/System.Web/MimeTypes.cs @@ -233,6 +233,7 @@ namespace System.Web mimeTypes.Add ("la", "audio/nspaudio"); mimeTypes.Add ("lam", "audio/x-liveaudio"); mimeTypes.Add ("latex", "application/x-latex"); + mimeTypes.Add ("less", "text/css"); mimeTypes.Add ("list", "text/plain"); mimeTypes.Add ("lma", "audio/nspaudio"); mimeTypes.Add ("log", "text/plain"); @@ -529,7 +530,7 @@ namespace System.Web mimeTypes.Add ("wmls", "text/vnd.wap.wmlscript"); mimeTypes.Add ("wml", "text/vnd.wap.wml"); mimeTypes.Add ("wmp", "video/x-ms-wmp"); - mimeTypes.Add ("woff", "application/x-woff"); + mimeTypes.Add ("woff", "application/font-woff"); mimeTypes.Add ("word", "application/msword"); mimeTypes.Add ("wp5", "application/wordperfect"); mimeTypes.Add ("wp6", "application/wordperfect"); diff --git a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnnotationPathPointTest.cs b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnnotationPathPointTest.cs index 1933373d27b..a802e4b8c03 100644 --- a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnnotationPathPointTest.cs +++ b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnnotationPathPointTest.cs @@ -27,7 +27,7 @@ using System; using System.Windows.Forms.DataVisualization.Charting; using NUnit.Framework; -namespace ChartingTests +namespace MonoTests.System.Windows.Forms.DataVisualization.Charting { [TestFixture] public class AnnotationPathPointTest diff --git a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnovaResultTest.cs b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnovaResultTest.cs index 8a146d266bd..ef1f648777d 100644 --- a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnovaResultTest.cs +++ b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnovaResultTest.cs @@ -27,7 +27,7 @@ using System; using System.Windows.Forms.DataVisualization.Charting; using NUnit.Framework; -namespace ChartingTests +namespace MonoTests.System.Windows.Forms.DataVisualization.Charting { [TestFixture] public class AnovaResultTest diff --git a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ArrowAnnotationTest.cs b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ArrowAnnotationTest.cs index ccc57005014..9fced81aade 100644 --- a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ArrowAnnotationTest.cs +++ b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ArrowAnnotationTest.cs @@ -27,7 +27,7 @@ using System; using System.Windows.Forms.DataVisualization.Charting; using NUnit.Framework; -namespace ChartingTests +namespace MonoTests.System.Windows.Forms.DataVisualization.Charting { [TestFixture] public class ArrowAnnotationTest diff --git a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AxisScaleBreakStyleTest.cs b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AxisScaleBreakStyleTest.cs index e820427d526..3871898efdf 100644 --- a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AxisScaleBreakStyleTest.cs +++ b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AxisScaleBreakStyleTest.cs @@ -28,7 +28,7 @@ using System.Windows.Forms.DataVisualization.Charting; using NUnit.Framework; using System.Drawing; -namespace ChartingTests +namespace MonoTests.System.Windows.Forms.DataVisualization.Charting { [TestFixture] public class AxisScaleBreakStyleTest diff --git a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ChartElementTest.cs b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ChartElementTest.cs index c7053c6a7ee..3afeffe4238 100644 --- a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ChartElementTest.cs +++ b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ChartElementTest.cs @@ -27,7 +27,7 @@ using System; using System.Windows.Forms.DataVisualization.Charting; using NUnit.Framework; -namespace ChartingTests +namespace MonoTests.System.Windows.Forms.DataVisualization.Charting { [TestFixture] public class ChartElementTest diff --git a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/DataPointTest.cs b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/DataPointTest.cs index 5431d77ea52..ec98463aa9b 100644 --- a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/DataPointTest.cs +++ b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/DataPointTest.cs @@ -27,7 +27,7 @@ using System; using System.Windows.Forms.DataVisualization.Charting; using NUnit.Framework; -namespace ChartingTests +namespace MonoTests.System.Windows.Forms.DataVisualization.Charting { [TestFixture] public class DataPointTest diff --git a/mcs/class/System.XML/Test/System.Xml/XmlResolverTest.cs b/mcs/class/System.XML/Test/System.Xml/XmlResolverTest.cs index fcdc34e7f7a..80a46e5c99f 100644 --- a/mcs/class/System.XML/Test/System.Xml/XmlResolverTest.cs +++ b/mcs/class/System.XML/Test/System.Xml/XmlResolverTest.cs @@ -33,7 +33,7 @@ using System.Xml; using NUnit.Framework; -namespace MonoTest.System.Xml { +namespace MonoTests.System.Xml { [TestFixture] public class XmlResolverTest { diff --git a/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverCas.cs b/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverCas.cs index 52de90d1414..2e5316c1ffe 100644 --- a/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverCas.cs +++ b/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverCas.cs @@ -38,7 +38,7 @@ using System.Security.Permissions; using System.Security.Policy; using System.Xml; -using MonoTestsXml; +using MonoTests.System.Xml; namespace MonoCasTests.System.Xml { @@ -85,4 +85,4 @@ namespace MonoCasTests.System.Xml { } } -#endif \ No newline at end of file +#endif diff --git a/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverTests.cs b/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverTests.cs index c97407de984..a2eaa8b1064 100644 --- a/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverTests.cs +++ b/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverTests.cs @@ -20,7 +20,7 @@ using System.Security.Permissions; using System.Xml; using NUnit.Framework; -namespace MonoTestsXml +namespace MonoTests.System.Xml { [TestFixture] public class XmlSecureResolverTests diff --git a/mcs/class/System/System.Net/ServicePointManager.cs b/mcs/class/System/System.Net/ServicePointManager.cs index b6095b08904..dc7412d725a 100644 --- a/mcs/class/System/System.Net/ServicePointManager.cs +++ b/mcs/class/System/System.Net/ServicePointManager.cs @@ -369,6 +369,15 @@ namespace System.Net return sp; } + + internal static void CloseConnectionGroup (string connectionGroupName) + { + lock (servicePoints) { + foreach (ServicePoint sp in servicePoints.Values) { + sp.CloseConnectionGroup (connectionGroupName); + } + } + } #if SECURITY_DEP internal class ChainValidationHelper { diff --git a/mcs/class/System/System/Uri.cs b/mcs/class/System/System/Uri.cs index 105004e39c8..fb9c14eead1 100644 --- a/mcs/class/System/System/Uri.cs +++ b/mcs/class/System/System/Uri.cs @@ -1725,7 +1725,7 @@ namespace System { private UriParser Parser { get { if (parser == null) { - parser = UriParser.GetParser (Scheme); + parser = UriParser.GetParser (scheme); // no specific parser ? then use a default one if (parser == null) parser = new DefaultUriParser ("*"); @@ -1737,6 +1737,9 @@ namespace System { public string GetComponents (UriComponents components, UriFormat format) { + if ((components & UriComponents.SerializationInfoString) == 0) + EnsureAbsoluteUri (); + return Parser.GetComponents (this, components, format); } diff --git a/mcs/class/System/System/UriParser.cs b/mcs/class/System/System/UriParser.cs index 8abfdc9b359..5eda9aadc17 100644 --- a/mcs/class/System/System/UriParser.cs +++ b/mcs/class/System/System/UriParser.cs @@ -50,6 +50,16 @@ namespace System { if ((format < UriFormat.UriEscaped) || (format > UriFormat.SafeUnescaped)) throw new ArgumentOutOfRangeException ("format"); + if ((components & UriComponents.SerializationInfoString) != 0) { + if (components != UriComponents.SerializationInfoString) + throw new ArgumentOutOfRangeException ("components", "UriComponents.SerializationInfoString must not be combined with other UriComponents."); + + if (!uri.IsAbsoluteUri) + return UriHelper.FormatRelative (uri.OriginalString, "", format); + + components |= UriComponents.AbsoluteUri; + } + return GetComponentsHelper (uri, components, format); } diff --git a/mcs/class/System/Test/System.Net/NetworkCredentialTest.cs b/mcs/class/System/Test/System.Net/NetworkCredentialTest.cs index 610b4aca31f..dbe3255cd68 100644 --- a/mcs/class/System/Test/System.Net/NetworkCredentialTest.cs +++ b/mcs/class/System/Test/System.Net/NetworkCredentialTest.cs @@ -31,7 +31,7 @@ using System.Net; using NUnit.Framework; -namespace MoonTest.System.Net { +namespace MonoTests.System.Net { [TestFixture] public class NetworkCredentialTest { diff --git a/mcs/class/System/Test/System/UriTest.cs b/mcs/class/System/Test/System/UriTest.cs index f0a67b7a7cd..b3b33170c58 100644 --- a/mcs/class/System/Test/System/UriTest.cs +++ b/mcs/class/System/Test/System/UriTest.cs @@ -1951,6 +1951,23 @@ namespace MonoTests.System Assert.IsTrue (Uri.TryCreate (mainUri, uriPath, out result), "#1"); Assert.AreEqual ("http://www.imdb.com/title/tt0106521", result.ToString (), "#2"); } + + [Test] + public void GetSerializationInfoStringOnRelativeUri () + { + var uri = new Uri ("/relative/path", UriKind.Relative); + var result = uri.GetComponents (UriComponents.SerializationInfoString, UriFormat.UriEscaped); + + Assert.AreEqual (uri.OriginalString, result); + } + + [Test] + [ExpectedException (typeof (ArgumentOutOfRangeException))] + public void GetSerializationInfoStringException () + { + var uri = new Uri ("/relative/path", UriKind.Relative); + uri.GetComponents (UriComponents.SerializationInfoString | UriComponents.Host, UriFormat.UriEscaped); + } } // Tests non default IriParsing diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackage.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackage.cs index 54df0eb5e8e..2818cd5e453 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackage.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackage.cs @@ -25,9 +25,11 @@ using System; +using System.IO; +using System.IO.Packaging; using System.Collections.Generic; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { public class FakePackage : Package { Dictionary Parts { get; set; } @@ -77,4 +79,4 @@ namespace System.IO.Packaging.Tests { return p; } } -} \ No newline at end of file +} diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePart.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePart.cs index 9a7871c6ed0..1ca0bb20f05 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePart.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePart.cs @@ -24,9 +24,11 @@ // using System; +using System.IO; +using System.IO.Packaging; using System.Collections.Generic; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { class FakePackagePart : PackagePart { diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePartTests.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePartTests.cs index 731aed62ff9..216a1686f64 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePartTests.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePartTests.cs @@ -26,9 +26,12 @@ using System; using System.Linq; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; +using System.Xml; using NUnit.Framework; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { [TestFixture] public class FakePackagePartTests : TestBase { @@ -146,7 +149,7 @@ namespace System.IO.Packaging.Tests { } [Test] - [ExpectedException (typeof (Xml.XmlException))] + [ExpectedException (typeof (XmlException))] public void CreateDupeRelationship () { part.CreateRelationship (uris [1], TargetMode.External, "blah", "asda"); @@ -154,7 +157,7 @@ namespace System.IO.Packaging.Tests { } [Test] - [ExpectedException (typeof (Xml.XmlException))] + [ExpectedException (typeof (XmlException))] public void CreateDupeRelationshipId () { part.CreateRelationship (uris [1], TargetMode.External, "blah", "asda"); diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackageTests.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackageTests.cs index bd751542927..bfea3c84973 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackageTests.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackageTests.cs @@ -26,11 +26,13 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; using System.Linq; using System.Text; using NUnit.Framework; -namespace System.IO.Packaging.Tests +namespace MonoTests.System.IO.Packaging { [TestFixture] diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakeStream.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakeStream.cs index b095375b177..aafc02e25ed 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakeStream.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakeStream.cs @@ -25,9 +25,10 @@ using System; +using System.IO; using System.Collections.Generic; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { public class FakeStream : MemoryStream { public bool canRead; diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackUriHelperTests.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackUriHelperTests.cs index c5361214f7b..d231315a0e9 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackUriHelperTests.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackUriHelperTests.cs @@ -8,7 +8,7 @@ using System; using System.IO.Packaging; using NUnit.Framework; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { [TestFixture] public class PackUriHelperTests { diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartFileTests.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartFileTests.cs index 3f2850b602b..557e4a98b51 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartFileTests.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartFileTests.cs @@ -3,7 +3,7 @@ using System.IO; using System.IO.Packaging; using NUnit.Framework; -namespace System.IO.Packaging.Tests +namespace MonoTests.System.IO.Packaging { [TestFixture] public class PackagePartFileTests @@ -135,4 +135,4 @@ namespace System.IO.Packaging.Tests } } } -} \ No newline at end of file +} diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartStreamTests.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartStreamTests.cs index 915c2a09a98..1bf60221082 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartStreamTests.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartStreamTests.cs @@ -26,11 +26,13 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; using System.Linq; using System.Text; using NUnit.Framework; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { [TestFixture] public class PackagePartStreamTests : TestBase { @@ -190,4 +192,4 @@ namespace System.IO.Packaging.Tests { Assert.IsTrue (stream.Length > buffer.Length * 2, "#4"); } } -} \ No newline at end of file +} diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartTest.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartTest.cs index 07015c20173..ad7eb968c3a 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartTest.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartTest.cs @@ -26,12 +26,14 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; using System.Linq; using System.Text; using NUnit.Framework; using System.Xml; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { [TestFixture] public class PackagePartTest : TestBase { diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageRelationshipTests.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageRelationshipTests.cs index 8c4b031de95..6ce92d31e57 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageRelationshipTests.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageRelationshipTests.cs @@ -28,12 +28,14 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; using System.Linq; using System.Text; using System.Xml; using NUnit.Framework; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { [TestFixture] public class PackageRelationshipTests : TestBase { diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageTest.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageTest.cs index ae7c5945de9..933449052f3 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageTest.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageTest.cs @@ -26,11 +26,13 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; using System.Linq; using System.Text; using NUnit.Framework; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { [TestFixture] public class PackageTest : TestBase { @@ -411,8 +413,8 @@ namespace System.IO.Packaging.Tests { [ExpectedException (typeof (FileFormatException))] public void WriteOnlyAccessExists () { - System.IO.File.Create (path).Close (); + File.Create (path).Close (); package = Package.Open (path, FileMode.OpenOrCreate, FileAccess.Write); } } -} \ No newline at end of file +} diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/TestBase.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/TestBase.cs index 6d8b43d057e..28afcd43151 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/TestBase.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/TestBase.cs @@ -26,11 +26,13 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; using System.Linq; using System.Text; using NUnit.Framework; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { public abstract class TestBase { protected string contentType = "mime/type"; diff --git a/mcs/class/corlib/System/DateTime.cs b/mcs/class/corlib/System/DateTime.cs index 735599680c5..ce698f9c620 100644 --- a/mcs/class/corlib/System/DateTime.cs +++ b/mcs/class/corlib/System/DateTime.cs @@ -107,7 +107,7 @@ namespace System "H:mzzz", "H:m", "H tt", // Specifies AM to disallow '8'. - "H'\u6642'm'\u5206's'\u79D2'", + "H'\u6642'm'\u5206's'\u79D2'" }; // DateTime.Parse date patterns extend ParseExact patterns as follows: @@ -885,6 +885,9 @@ namespace System if (_DoParse (s, firstPart, ParseTimeFormats [j], false, out result, out dto, dfi, styles, true, ref incompleteFormat, ref longYear)) return true; } + + if (_DoParse (s, firstPart, "zzz", false, out result, out dto, dfi, styles, true, ref incompleteFormat, ref longYear)) + return true; } // @@ -1466,6 +1469,25 @@ namespace System if (num_parsed == -1) return false; fractionalSeconds = decimalNumber / Math.Pow(10.0, num_parsed); + + //Parse ISO8601 with an unlimited number of fractional digits. + if (!exact && num == 6 && hour != -1 && minute != -1 && second != -1) { + var total_num_parsed = num_parsed; + while (true) { + valuePos += num_parsed; + decimalNumber = (double) _ParseNumber (s, valuePos, 0, 1, leading_zeros, sloppy_parsing, out num_parsed); + if (num_parsed < 1) { + num_parsed = 0; + break; + } + + total_num_parsed += num_parsed; + if (total_num_parsed > 15) + continue; //not enough precision, ignore additional digits. + + fractionalSeconds += decimalNumber / Math.Pow (10.0, total_num_parsed); + } + } break; case 't': if (!_ParseAmPm (s, valuePos, num > 0 ? 0 : 1, dfi, exact, out num_parsed, ref ampm)) diff --git a/mcs/class/corlib/Test/Mono/DataConvertTest.cs b/mcs/class/corlib/Test/Mono/DataConvertTest.cs index 89f99e918c1..f02a6a7db40 100644 --- a/mcs/class/corlib/Test/Mono/DataConvertTest.cs +++ b/mcs/class/corlib/Test/Mono/DataConvertTest.cs @@ -8,7 +8,7 @@ using Mono; using NUnit.Framework.SyntaxHelpers; #endif -namespace MonoTests { +namespace MonoTests.Mono { [TestFixture] public class DataConverterTest @@ -50,9 +50,9 @@ namespace MonoTests { [Test] public void StringAlignment () { - byte[] packed = Mono.DataConverter.Pack ("bz8", 1, TEST_STRING); + byte[] packed = global::Mono.DataConverter.Pack ("bz8", 1, TEST_STRING); - IList unpacked = Mono.DataConverter.Unpack ("bz8", packed, 0); + IList unpacked = global::Mono.DataConverter.Unpack ("bz8", packed, 0); Assert.AreEqual(1, (byte) unpacked[0]); Assert.AreEqual(TEST_STRING, new string((char[]) unpacked[1])); @@ -65,4 +65,4 @@ namespace MonoTests { Assert.That ((f - 3.14f), Is.LessThanOrEqualTo (Single.Epsilon)); } } -} \ No newline at end of file +} diff --git a/mcs/class/corlib/Test/System.IO/DirectoryInfoTest.cs b/mcs/class/corlib/Test/System.IO/DirectoryInfoTest.cs index 699f94be803..cbb58727eb4 100644 --- a/mcs/class/corlib/Test/System.IO/DirectoryInfoTest.cs +++ b/mcs/class/corlib/Test/System.IO/DirectoryInfoTest.cs @@ -1111,7 +1111,7 @@ namespace MonoTests.System.IO try { Directory.CreateDirectory (path); Directory.CreateDirectory (dir); - Mono.Unix.UnixSymbolicLinkInfo li = new Mono.Unix.UnixSymbolicLinkInfo (link); + global::Mono.Unix.UnixSymbolicLinkInfo li = new global::Mono.Unix.UnixSymbolicLinkInfo (link); li.CreateSymbolicLinkTo (dir); DirectoryInfo info = new DirectoryInfo (path); diff --git a/mcs/class/corlib/Test/System.IO/DirectoryTest.cs b/mcs/class/corlib/Test/System.IO/DirectoryTest.cs index 82536169f59..f2d7e03d3d6 100644 --- a/mcs/class/corlib/Test/System.IO/DirectoryTest.cs +++ b/mcs/class/corlib/Test/System.IO/DirectoryTest.cs @@ -374,11 +374,11 @@ public class DirectoryTest string path = TempFolder + DSC + "ExistsAccessDenied"; Directory.CreateDirectory (path); - Mono.Posix.Syscall.chmod (path, 0); + global::Mono.Posix.Syscall.chmod (path, 0); try { Assert.IsFalse (Directory.Exists(path + DSC + "b")); } finally { - Mono.Posix.Syscall.chmod (path, (Mono.Posix.FileMode) 755); + global::Mono.Posix.Syscall.chmod (path, (global::Mono.Posix.FileMode) 755); Directory.Delete (path); } } diff --git a/mcs/class/corlib/Test/System/DateTimeOffsetTest.cs b/mcs/class/corlib/Test/System/DateTimeOffsetTest.cs index a898f2db6e9..5d3609cedc9 100644 --- a/mcs/class/corlib/Test/System/DateTimeOffsetTest.cs +++ b/mcs/class/corlib/Test/System/DateTimeOffsetTest.cs @@ -705,6 +705,15 @@ namespace MonoTests.System { expected = string.Format ("{0:D2}/{1:D2}/{2} 00:00:45 +00:00", now.Month, now.Day, now.Year); Assert.AreEqual (expected, date.ToString (CultureInfo.InvariantCulture)); } + + [Test] + public void TestDateOnlyWithTimeOffset () + { + var fp = CultureInfo.InvariantCulture; + var date = DateTimeOffset.Parse("2013-11-07+11:00", fp, DateTimeStyles.AssumeUniversal); + var expected = string.Format ("{0:D2}/{1:D2}/{2} 00:00:00 +11:00", 11, 7, 2013); + Assert.AreEqual (expected, date.ToString (CultureInfo.InvariantCulture)); + } } } diff --git a/mcs/class/corlib/Test/System/DateTimeTest.cs b/mcs/class/corlib/Test/System/DateTimeTest.cs index 343e723be82..202c3d2117d 100644 --- a/mcs/class/corlib/Test/System/DateTimeTest.cs +++ b/mcs/class/corlib/Test/System/DateTimeTest.cs @@ -2584,5 +2584,40 @@ namespace MonoTests.System Assert.AreEqual (dt, parsed, "#1"); } + + [Test] + public void ISO8601FractionalDigits () + { + string date = "2014-08-25T01:20:23.601911612343423423465789789365674575676746756747467Z"; + long expectedTicks = 635445264236019116; + + var dt = DateTime.Parse (date, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); + + Assert.AreEqual (expectedTicks, dt.Ticks); + } + + [Test] + [ExpectedException (typeof (FormatException))] + public void ISO8601FractionalDigitsException1 () + { + string date = "2014-08-25T01:20:23.60191161234342342346578978936567457567:6746756747467Z"; + DateTime.Parse (date, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); + } + + [Test] + [ExpectedException (typeof (FormatException))] + public void ISO8601FractionalDigitsException2 () + { + string date = "2014-08-25T01:20:23.6019116-12343423423465789789365674575676746756747467Z"; + DateTime.Parse (date, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); + } + + [Test] + [ExpectedException (typeof (FormatException))] + public void ISO8601FractionalDigitsException3 () + { + string date = "2014-08-25T01:20:23.601911612343423423465789789365674575676746756747467%Z"; + DateTime.Parse (date, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); + } } } diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay index 84d4e3f9f1b..45f719a3738 100644 --- a/mcs/mcs/cs-parser.jay +++ b/mcs/mcs/cs-parser.jay @@ -4352,13 +4352,16 @@ pattern_expr $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, GetLocation ($1)); } | sizeof_expression - | invocation_expression | default_value_expression | STAR { $$ = new WildcardPattern (GetLocation ($1)); } - | type_name_expression OPEN_PARENS opt_pattern_list CLOSE_PARENS + | pattern_expr_invocation + ; + +pattern_expr_invocation + : type_name_expression OPEN_PARENS opt_pattern_list CLOSE_PARENS { $$ = new RecursivePattern ((ATypeNameExpression) $1, (Arguments) $3, GetLocation ($2)); } @@ -4368,9 +4371,11 @@ pattern : pattern_expr | pattern_type_expr opt_identifier { - var lt = (LocatedToken) $2; - var variable = new LocalVariable (current_block, lt.Value, lt.Location); - current_block.AddLocalName (variable); + if ($2 != null) { + var lt = (LocatedToken) $2; + var variable = new LocalVariable (current_block, lt.Value, lt.Location); + current_block.AddLocalName (variable); + } } ; @@ -5817,6 +5822,16 @@ switch_label Error_SyntaxError (yyToken); $$ = new SwitchLabel ((Expression) $2, GetLocation ($1)); } + | CASE pattern_expr_invocation COLON + { + if (lang_version != LanguageVersion.Experimental) + FeatureIsNotAvailable (GetLocation ($2), "pattern matching"); + + $$ = new SwitchLabel ((Expression) $2, GetLocation ($1)) { + PatternMatching = true + }; + lbag.AddLocation ($$, GetLocation ($3)); + } | DEFAULT_COLON { $$ = new SwitchLabel (null, GetLocation ($1)); diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs index a8573955cf3..ed2860b7766 100644 --- a/mcs/mcs/expression.cs +++ b/mcs/mcs/expression.cs @@ -1807,6 +1807,10 @@ namespace Mono.CSharp } if (ProbeType is PatternExpression) { + if (!(ProbeType is WildcardPattern) && !Convert.ImplicitConversionExists (rc, ProbeType, Expr.Type)) { + ProbeType.Error_ValueCannotBeConverted (rc, Expr.Type, false); + } + return this; } diff --git a/mcs/mcs/module.cs b/mcs/mcs/module.cs index 68f1b8ece11..138ec61638f 100644 --- a/mcs/mcs/module.cs +++ b/mcs/mcs/module.cs @@ -181,6 +181,7 @@ namespace Mono.CSharp var system_convert = new MemberAccess (new QualifiedAliasMember ("global", "System", loc), "Convert", loc); + var expl_block = new ExplicitBlock (top_block, loc, loc); // // var converted = System.Convert.ChangeType (obj, System.Convert.GetTypeCode (value)); @@ -198,7 +199,7 @@ namespace Mono.CSharp var changetype = new Invocation (new MemberAccess (system_convert, "ChangeType", loc), arguments_changetype); - top_block.AddStatement (new StatementExpression (new SimpleAssign (new LocalVariableReference (lv_converted, loc), changetype, loc))); + expl_block.AddStatement (new StatementExpression (new SimpleAssign (new LocalVariableReference (lv_converted, loc), changetype, loc))); // @@ -207,7 +208,13 @@ namespace Mono.CSharp var equals_arguments = new Arguments (1); equals_arguments.Add (new Argument (top_block.GetParameterReference (1, loc))); var equals_invocation = new Invocation (new MemberAccess (new LocalVariableReference (lv_converted, loc), "Equals"), equals_arguments); - top_block.AddStatement (new Return (equals_invocation, loc)); + expl_block.AddStatement (new Return (equals_invocation, loc)); + + var catch_block = new ExplicitBlock (top_block, loc, loc); + catch_block.AddStatement (new Return (new BoolLiteral (Compiler.BuiltinTypes, false, loc), loc)); + top_block.AddStatement (new TryCatch (expl_block, new List () { + new Catch (catch_block, loc) + }, loc, false)); m.Define (); m.PrepareEmit (); diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs index 441d65780c1..e46dca447eb 100644 --- a/mcs/mcs/statement.cs +++ b/mcs/mcs/statement.cs @@ -4471,6 +4471,8 @@ namespace Mono.CSharp { } } + public bool PatternMatching { get; set; } + public bool SectionStart { get; set; } public Label GetILLabel (EmitContext ec) @@ -4508,21 +4510,33 @@ namespace Mono.CSharp { // Resolves the expression, reduces it to a literal if possible // and then converts it to the requested type. // - bool ResolveAndReduce (BlockContext rc) + bool ResolveAndReduce (BlockContext bc) { if (IsDefault) return true; - var c = label.ResolveLabelConstant (rc); + var switch_statement = bc.Switch; + + if (PatternMatching) { + label = new Is (switch_statement.ExpressionValue, label, loc).Resolve (bc); + return label != null; + } + + var c = label.ResolveLabelConstant (bc); if (c == null) return false; - if (rc.Switch.IsNullable && c is NullLiteral) { + if (switch_statement.IsNullable && c is NullLiteral) { converted = c; return true; } - converted = c.ImplicitConversionRequired (rc, rc.Switch.SwitchType); + if (switch_statement.IsPatternMatching) { + label = new Is (switch_statement.ExpressionValue, label, loc).Resolve (bc); + return true; + } + + converted = c.ImplicitConversionRequired (bc, switch_statement.SwitchType); return converted != null; } @@ -4728,12 +4742,24 @@ namespace Mono.CSharp { } } + public bool IsPatternMatching { + get { + return new_expr == null && SwitchType != null; + } + } + public List RegisteredLabels { get { return case_labels; } } + public VariableReference ExpressionValue { + get { + return value; + } + } + // // Determines the governing type for a switch. The returned // expression might be the expression from the switch, or an @@ -4843,6 +4869,9 @@ namespace Mono.CSharp { return; } + if (sl.Converted == null) + return; + try { if (string_labels != null) { string string_value = sl.Converted.GetValue () as string; @@ -4851,7 +4880,7 @@ namespace Mono.CSharp { else string_labels.Add (string_value, sl); } else { - if (sl.Converted is NullLiteral) { + if (sl.Converted.IsNull) { case_null = sl; } else { labels.Add (sl.Converted.GetValueAsLong (), sl); @@ -5066,39 +5095,44 @@ namespace Mono.CSharp { } } + Expression switch_expr; if (new_expr == null) { - if (Expr.Type != InternalType.ErrorType) { - ec.Report.Error (151, loc, - "A switch expression of type `{0}' cannot be converted to an integral type, bool, char, string, enum or nullable type", - Expr.Type.GetSignatureForError ()); - } + if (ec.Module.Compiler.Settings.Version != LanguageVersion.Experimental) { + if (Expr.Type != InternalType.ErrorType) { + ec.Report.Error (151, loc, + "A switch expression of type `{0}' cannot be converted to an integral type, bool, char, string, enum or nullable type", + Expr.Type.GetSignatureForError ()); + } - return false; - } + return false; + } - SwitchType = new_expr.Type; - if (SwitchType.IsNullableType) { - new_expr = unwrap = Nullable.Unwrap.Create (new_expr, true); - SwitchType = Nullable.NullableInfo.GetUnderlyingType (SwitchType); - } + switch_expr = Expr; + SwitchType = Expr.Type; + } else { + switch_expr = new_expr; + SwitchType = new_expr.Type; + if (SwitchType.IsNullableType) { + new_expr = unwrap = Nullable.Unwrap.Create (new_expr, true); + SwitchType = Nullable.NullableInfo.GetUnderlyingType (SwitchType); + } - if (SwitchType.BuiltinType == BuiltinTypeSpec.Type.Bool && ec.Module.Compiler.Settings.Version == LanguageVersion.ISO_1) { - ec.Report.FeatureIsNotAvailable (ec.Module.Compiler, loc, "switch expression of boolean type"); - return false; - } + if (SwitchType.BuiltinType == BuiltinTypeSpec.Type.Bool && ec.Module.Compiler.Settings.Version == LanguageVersion.ISO_1) { + ec.Report.FeatureIsNotAvailable (ec.Module.Compiler, loc, "switch expression of boolean type"); + return false; + } - if (block.Statements.Count == 0) - return true; + if (block.Statements.Count == 0) + return true; - if (SwitchType.BuiltinType == BuiltinTypeSpec.Type.String) { - string_labels = new Dictionary (); - } else { - labels = new Dictionary (); + if (SwitchType.BuiltinType == BuiltinTypeSpec.Type.String) { + string_labels = new Dictionary (); + } else { + labels = new Dictionary (); + } } - case_labels = new List (); - - var constant = new_expr as Constant; + var constant = switch_expr as Constant; // // Don't need extra variable for constant switch or switch with @@ -5108,7 +5142,7 @@ namespace Mono.CSharp { // // Store switch expression for comparison purposes // - value = new_expr as VariableReference; + value = switch_expr as VariableReference; if (value == null && !HasOnlyDefaultSection ()) { var current_block = ec.CurrentBlock; ec.CurrentBlock = Block; @@ -5119,6 +5153,8 @@ namespace Mono.CSharp { } } + case_labels = new List (); + Switch old_switch = ec.Switch; ec.Switch = this; var parent_los = ec.EnclosingLoopOrSwitch; @@ -5411,6 +5447,11 @@ namespace Mono.CSharp { var constant = label.Converted; + if (constant == null) { + label.Label.EmitBranchable (ec, label.GetILLabel (ec), true); + continue; + } + if (equal_method != null) { value.Emit (ec); constant.Emit (ec); @@ -5436,6 +5477,11 @@ namespace Mono.CSharp { void EmitDispatch (EmitContext ec) { + if (IsPatternMatching) { + EmitShortSwitch (ec); + return; + } + if (value == null) { // // Constant switch, we've already done the work if there is only 1 label @@ -5483,12 +5529,14 @@ namespace Mono.CSharp { if (value != null) { ec.Mark (loc); + + var switch_expr = new_expr ?? Expr; if (IsNullable) { unwrap.EmitCheck (ec); ec.Emit (OpCodes.Brfalse, nullLabel); - value.EmitAssign (ec, new_expr, false, false); - } else if (new_expr != value) { - value.EmitAssign (ec, new_expr, false, false); + value.EmitAssign (ec, switch_expr, false, false); + } else if (switch_expr != value) { + value.EmitAssign (ec, switch_expr, false, false); } diff --git a/mcs/tests/test-pattern-06.cs b/mcs/tests/test-pattern-06.cs new file mode 100644 index 00000000000..3b54b840acf --- /dev/null +++ b/mcs/tests/test-pattern-06.cs @@ -0,0 +1,68 @@ +// Compiler options: -langversion:experimental + +using System; + +class RecursiveNamedPattern +{ + public static int Main () + { + if (Switch_1 (null) != 4) + return 1; + + if (Switch_1 ("x") != 5) + return 2; + + if (Switch_1 (1) != 1) + return 3; + + if (Switch_1 (new C1 ()) != 3) + return 4; + + if (Switch_1 ((byte?) 1) != 1) + return 5; + + if (Switch_2 (new C1 ()) != 3) + return 10; + + if (Switch_2 (null) != 2) + return 11; + + Console.WriteLine ("ok"); + return 0; + } + + static int Switch_1 (object o) + { + switch (o) { + case 1: + return 1; + case C1 (3): + return 2; + case C1 (2): + return 3; + case null: + return 4; + default: + return 5; + } + } + + static int Switch_2 (C1 o) + { + switch (o) { + case null: + return 2; + } + + return 3; + } +} + +public class C1 +{ + public static bool operator is (C1 c1, out int i) + { + i = 2; + return true; + } +} diff --git a/mcs/tests/ver-il-net_4_5.xml b/mcs/tests/ver-il-net_4_5.xml index 3f1b70389a4..12fab60c027 100644 --- a/mcs/tests/ver-il-net_4_5.xml +++ b/mcs/tests/ver-il-net_4_5.xml @@ -68454,7 +68454,7 @@ - 54 + 69 @@ -68520,6 +68520,35 @@ + + + + 182 + + + 149 + + + 28 + + + 7 + + + + + 13 + + + 7 + + + + + 69 + + + diff --git a/mono/Makefile.am b/mono/Makefile.am index 495f16922ed..df1a9c1c22e 100644 --- a/mono/Makefile.am +++ b/mono/Makefile.am @@ -1,5 +1,5 @@ if CROSS_COMPILING -SUBDIRS = arch utils io-layer cil metadata $(interpreter_dir) mini dis profiler +SUBDIRS = arch utils io-layer cil metadata mini dis profiler else if INSTALL_MONOTOUCH SUBDIRS = utils io-layer metadata arch mini profiler @@ -26,7 +26,7 @@ monotouch-do-clean: (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$target); \ done; else -SUBDIRS = arch utils io-layer cil metadata $(interpreter_dir) mini dis monograph tests unit-tests benchmark profiler +SUBDIRS = arch utils io-layer cil metadata mini dis monograph tests unit-tests benchmark profiler endif endif -DIST_SUBDIRS = arch utils io-layer cil metadata interpreter mini dis monograph tests unit-tests benchmark profiler +DIST_SUBDIRS = arch utils io-layer cil metadata mini dis monograph tests unit-tests benchmark profiler diff --git a/mono/arch/Makefile.am b/mono/arch/Makefile.am index 3d687949f92..87416872f6e 100644 --- a/mono/arch/Makefile.am +++ b/mono/arch/Makefile.am @@ -2,23 +2,9 @@ DIST_SUBDIRS = x86 ppc sparc arm arm64 s390x amd64 ia64 mips AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) -if INTERP_SUPPORTED -SUBDIRS = $(arch_target) -else if ARM # arm needs to build some stuff even in JIT mode SUBDIRS = $(arch_target) -endif -endif - -if INTERP_SUPPORTED - -noinst_LTLIBRARIES = libmonoarch.la - -libmonoarch_la_SOURCES = unknown.c - -libmonoarch_la_LIBADD = $(arch_target)/libmonoarch-$(arch_target).la - endif EXTRA_DIST = ChangeLog diff --git a/mono/arch/amd64/Makefile.am b/mono/arch/amd64/Makefile.am index 3c728263190..47daaaff699 100644 --- a/mono/arch/amd64/Makefile.am +++ b/mono/arch/amd64/Makefile.am @@ -1,7 +1,2 @@ - -AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) - -noinst_LTLIBRARIES = libmonoarch-amd64.la - -libmonoarch_amd64_la_SOURCES = tramp.c amd64-codegen.h +EXTRA_DIST = amd64-codegen.h diff --git a/mono/arch/amd64/tramp.c b/mono/arch/amd64/tramp.c deleted file mode 100644 index 6dbec93e859..00000000000 --- a/mono/arch/amd64/tramp.c +++ /dev/null @@ -1,1054 +0,0 @@ -/* - * Create trampolines to invoke arbitrary functions. - * - * Copyright (C) Ximian Inc. - * - * Author: - * Zalman Stern - * Based on code by: - * Paolo Molaro (lupus@ximian.com) - * Dietmar Maurer (dietmar@ximian.com) - * - * To understand this code, one will want to the calling convention section of the ABI sepc at: - * http://x86-64.org/abi.pdf - * and the AMD64 architecture docs found at amd.com . - */ - -#include "config.h" -#include -#include -#include "amd64-codegen.h" -#include "mono/metadata/class.h" -#include "mono/metadata/tabledefs.h" -#include "mono/interpreter/interp.h" -#include "mono/metadata/appdomain.h" -#include "mono/metadata/marshal.h" - -/* - * The resulting function takes the form: - * void func (void (*callme)(), void *retval, void *this_obj, stackval *arguments); - */ -#define FUNC_ADDR_POS 8 -#define RETVAL_POS 12 -#define THIS_POS 16 -#define ARGP_POS 20 -#define LOC_POS -4 - -#define ARG_SIZE sizeof (stackval) - -#define MAX_INT_ARG_REGS 6 -#define MAX_FLOAT_ARG_REGS 8 - -// TODO get these right. They are upper bounds anyway, so it doesn't much matter. -#define PUSH_INT_STACK_ARG_SIZE 16 -#define MOVE_INT_REG_ARG_SIZE 16 -#define PUSH_FLOAT_STACK_ARG_SIZE 16 -#define MOVE_FLOAT_REG_ARG_SIZE 16 -#define COPY_STRUCT_STACK_ARG_SIZE 16 - -/* Maps an argument number (starting at 0) to the register it is passed in (if it fits). - * E.g. int foo(int bar, int quux) has the foo arg in RDI and the quux arg in RSI - * There is no such map for floating point args as they go in XMM0-XMM7 in order and thus the - * index is the register number. - */ -static int int_arg_regs[] = { AMD64_RDI, AMD64_RSI, AMD64_RDX, AMD64_RCX, AMD64_R8, AMD64_R9 }; - -/* This next block of code resolves the ABI rules for passing structures in the argument registers. - * These basically amount to "Use up to two registers if they are all integer or all floating point. - * If the structure is bigger than two registers or would be in one integer register and one floating point, - * it is passed in memory instead. - * - * It is possible this code needs to be recursive to be correct in the case when one of the structure members - * is itself a structure. - * - * The 80-bit floating point stuff is ignored. - */ -typedef enum { - ARG_IN_MEMORY, - ARG_IN_INT_REGS, - ARG_IN_FLOAT_REGS -} struct_arg_type; - -static struct_arg_type compute_arg_type(MonoType *type) -{ - guint32 simpletype = type->type; - - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_I8: - return ARG_IN_INT_REGS; - break; - case MONO_TYPE_VALUETYPE: { - if (type->data.klass->enumtype) - return ARG_IN_INT_REGS; - return ARG_IN_MEMORY; - break; - } - case MONO_TYPE_R4: - case MONO_TYPE_R8: - return ARG_IN_FLOAT_REGS; - break; - default: - g_error ("Can't trampoline 0x%x", type->type); - } - - return ARG_IN_MEMORY; -} - -static struct_arg_type value_type_info(MonoClass *klass, int *native_size, int *regs_used, int *offset1, int *size1, int *offset2, int *size2) -{ - MonoMarshalType *info = mono_marshal_load_type_info (klass); - - *native_size = info->native_size; - - if (info->native_size > 8 || info->num_fields > 2) - { - *regs_used = 0; - *offset1 = -1; - *offset2 = -1; - return ARG_IN_MEMORY; - } - - if (info->num_fields == 1) - { - struct_arg_type result = compute_arg_type(info->fields[0].field->type); - if (result != ARG_IN_MEMORY) - { - *regs_used = 1; - *offset1 = info->fields[0].offset; - *size1 = mono_marshal_type_size (info->fields[0].field->type, info->fields[0].mspec, NULL, 1, 1); - } - else - { - *regs_used = 0; - *offset1 = -1; - } - - *offset2 = -1; - return result; - } - - struct_arg_type result1 = compute_arg_type(info->fields[0].field->type); - struct_arg_type result2 = compute_arg_type(info->fields[0].field->type); - - if (result1 == result2 && result1 != ARG_IN_MEMORY) - { - *regs_used = 2; - *offset1 = info->fields[0].offset; - *size1 = mono_marshal_type_size (info->fields[0].field->type, info->fields[0].mspec, NULL, 1, 1); - *offset2 = info->fields[1].offset; - *size2 = mono_marshal_type_size (info->fields[1].field->type, info->fields[1].mspec, NULL, 1, 1); - return result1; - } - - return ARG_IN_MEMORY; -} - -MonoPIFunc -mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor) -{ - unsigned char *p, *code_buffer; - guint32 stack_size = 0, code_size = 50; - guint32 arg_pos, simpletype; - int i; - static GHashTable *cache = NULL; - MonoPIFunc res; - - guint32 int_arg_regs_used = 0; - guint32 float_arg_regs_used = 0; - guint32 next_int_arg_reg = 0; - guint32 next_float_arg_reg = 0; - /* Indicates that the return value is filled in inside the called function. */ - int retval_implicit = 0; - char *arg_in_reg_bitvector; /* A set index by argument number saying if it is in a register - (integer or floating point according to type) */ - - if (!cache) - cache = g_hash_table_new ((GHashFunc)mono_signature_hash, - (GCompareFunc)mono_metadata_signature_equal); - - if ((res = (MonoPIFunc)g_hash_table_lookup (cache, sig))) - return res; - - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref && !sig->ret->data.klass->enumtype) { - int_arg_regs_used++; - code_size += MOVE_INT_REG_ARG_SIZE; - } - - if (sig->hasthis) { - int_arg_regs_used++; - code_size += MOVE_INT_REG_ARG_SIZE; - } - - /* Run through stuff to calculate code size and argument bytes that will be pushed on stack (stack_size). */ - for (i = 0; i < sig->param_count; ++i) { - if (sig->params [i]->byref) - simpletype = MONO_TYPE_PTR; - else - simpletype = sig->params [i]->type; -enum_calc_size: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_I8: - if (int_arg_regs_used++ > MAX_INT_ARG_REGS) { - stack_size += 8; - code_size += PUSH_INT_STACK_ARG_SIZE; - } - else - code_size += MOVE_INT_REG_ARG_SIZE; - break; - case MONO_TYPE_VALUETYPE: { - int size; - int arg_type; - int regs_used; - int offset1; - int size1; - int offset2; - int size2; - - if (sig->params [i]->data.klass->enumtype) { - simpletype = sig->params [i]->data.klass->enum_basetype->type; - goto enum_calc_size; - } - - arg_type = value_type_info(sig->params [i]->data.klass, &size, ®s_used, &offset1, &size1, &offset2, &size2); - if (arg_type == ARG_IN_INT_REGS && - (int_arg_regs_used + regs_used) <= MAX_INT_ARG_REGS) - { - code_size += MOVE_INT_REG_ARG_SIZE; - int_arg_regs_used += regs_used; - break; - } - - if (arg_type == ARG_IN_FLOAT_REGS && - (float_arg_regs_used + regs_used) <= MAX_FLOAT_ARG_REGS) - { - code_size += MOVE_FLOAT_REG_ARG_SIZE; - float_arg_regs_used += regs_used; - break; - } - - /* Else item is in memory. */ - - stack_size += size + 7; - stack_size &= ~7; - code_size += COPY_STRUCT_STACK_ARG_SIZE; - - break; - } - case MONO_TYPE_R4: - case MONO_TYPE_R8: - if (float_arg_regs_used++ > MAX_FLOAT_ARG_REGS) { - stack_size += 8; - code_size += PUSH_FLOAT_STACK_ARG_SIZE; - } - else - code_size += MOVE_FLOAT_REG_ARG_SIZE; - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i]->type); - } - } - /* - * FIXME: take into account large return values. - * (Comment carried over from IA32 code. Not sure what it means :-) - */ - - code_buffer = p = alloca (code_size); - - /* - * Standard function prolog. - */ - amd64_push_reg (p, AMD64_RBP); - amd64_mov_reg_reg (p, AMD64_RBP, AMD64_RSP, 8); - /* - * and align to 16 byte boundary... - */ - - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) { - MonoClass *klass = sig->ret->data.klass; - if (!klass->enumtype) { - retval_implicit = 1; - } - } - - if (sig->ret->byref || string_ctor || !(retval_implicit || sig->ret->type == MONO_TYPE_VOID)) { - /* Push the retval register so it is saved across the call. It will be addressed via RBP later. */ - amd64_push_reg (p, AMD64_RSI); - stack_size += 8; - } - - /* Ensure stack is 16 byte aligned when entering called function as required by calling convention. - * Getting this wrong results in a general protection fault on an SSE load or store somewhere in the - * code called under the trampoline. - */ - if ((stack_size & 15) != 0) - amd64_alu_reg_imm (p, X86_SUB, AMD64_RSP, 16 - (stack_size & 15)); - - /* - * On entry to generated function: - * RDI has target function address - * RSI has return value location address - * RDX has this pointer address - * RCX has the pointer to the args array. - * - * Inside the stub function: - * R10 holds the pointer to the args - * R11 holds the target function address. - * The return value address is pushed on the stack. - * The this pointer is moved into the first arg register at the start. - * - * Optimization note: we could keep the args pointer in RCX and then - * load over itself at the end. Ditto the callee addres could be left in RDI in some cases. - */ - - /* Move args pointer to temp register. */ - amd64_mov_reg_reg (p, AMD64_R10, AMD64_RCX, 8); - amd64_mov_reg_reg (p, AMD64_R11, AMD64_RDI, 8); - - /* First args register gets return value pointer, if need be. - * Note that "byref" equal true means the called function returns a pointer. - */ - if (retval_implicit) { - amd64_mov_reg_reg (p, int_arg_regs[next_int_arg_reg], AMD64_RSI, 8); - next_int_arg_reg++; - } - - /* this pointer goes in next args register. */ - if (sig->hasthis) { - amd64_mov_reg_reg (p, int_arg_regs[next_int_arg_reg], AMD64_RDX, 8); - next_int_arg_reg++; - } - - /* - * Generate code to handle arguments in registers. Stack arguments will happen in a loop after this. - */ - arg_in_reg_bitvector = (char *)alloca((sig->param_count + 7) / 8); - memset(arg_in_reg_bitvector, 0, (sig->param_count + 7) / 8); - - /* First, load all the arguments that are passed in registers into the appropriate registers. - * Below there is another loop to handle arguments passed on the stack. - */ - for (i = 0; i < sig->param_count; i++) { - arg_pos = ARG_SIZE * i; - - if (sig->params [i]->byref) - simpletype = MONO_TYPE_PTR; - else - simpletype = sig->params [i]->type; -enum_marshal: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_I8: - case MONO_TYPE_U8: - case MONO_TYPE_CLASS: - if (next_int_arg_reg < MAX_INT_ARG_REGS) { - amd64_mov_reg_membase (p, int_arg_regs[next_int_arg_reg], AMD64_R10, arg_pos, 8); - next_int_arg_reg++; - arg_in_reg_bitvector[i >> 3] |= (1 << (i & 7)); - } - break; - case MONO_TYPE_R4: - if (next_float_arg_reg < MAX_FLOAT_ARG_REGS) { - amd64_movss_reg_membase (p, next_float_arg_reg, AMD64_R10, arg_pos); - next_float_arg_reg++; - arg_in_reg_bitvector[i >> 3] |= (1 << (i & 7)); - } - break; - case MONO_TYPE_R8: - if (next_float_arg_reg < MAX_FLOAT_ARG_REGS) { - amd64_movsd_reg_membase (p, next_float_arg_reg, AMD64_R10, arg_pos); - next_float_arg_reg++; - arg_in_reg_bitvector[i >> 3] |= (1 << (i & 7)); - } - break; - case MONO_TYPE_VALUETYPE: { - if (!sig->params [i]->data.klass->enumtype) { - int size; - int arg_type; - int regs_used; - int offset1; - int size1; - int offset2; - int size2; - - arg_type = value_type_info(sig->params [i]->data.klass, &size, ®s_used, &offset1, &size1, &offset2, &size2); - - if (arg_type == ARG_IN_INT_REGS && - (next_int_arg_reg + regs_used) <= MAX_INT_ARG_REGS) - { - amd64_mov_reg_membase (p, int_arg_regs[next_int_arg_reg], AMD64_R10, arg_pos + offset1, size1); - next_int_arg_reg++; - if (regs_used > 1) - { - amd64_mov_reg_membase (p, int_arg_regs[next_int_arg_reg], AMD64_R10, arg_pos + offset2, size2); - next_int_arg_reg++; - } - arg_in_reg_bitvector[i >> 3] |= (1 << (i & 7)); - break; - } - - if (arg_type == ARG_IN_FLOAT_REGS && - (next_float_arg_reg + regs_used) <= MAX_FLOAT_ARG_REGS) - { - if (size1 == 4) - amd64_movss_reg_membase (p, next_float_arg_reg, AMD64_R10, arg_pos + offset1); - else - amd64_movsd_reg_membase (p, next_float_arg_reg, AMD64_R10, arg_pos + offset1); - next_float_arg_reg++; - - if (regs_used > 1) - { - if (size2 == 4) - amd64_movss_reg_membase (p, next_float_arg_reg, AMD64_R10, arg_pos + offset2); - else - amd64_movsd_reg_membase (p, next_float_arg_reg, AMD64_R10, arg_pos + offset2); - next_float_arg_reg++; - } - arg_in_reg_bitvector[i >> 3] |= (1 << (i & 7)); - break; - } - - /* Structs in memory are handled in the next loop. */ - } else { - /* it's an enum value */ - simpletype = sig->params [i]->data.klass->enum_basetype->type; - goto enum_marshal; - } - break; - } - default: - g_error ("Can't trampoline 0x%x", sig->params [i]->type); - } - } - - /* Handle stack arguments, pushing the rightmost argument first. */ - for (i = sig->param_count; i > 0; --i) { - arg_pos = ARG_SIZE * (i - 1); - if (sig->params [i - 1]->byref) - simpletype = MONO_TYPE_PTR; - else - simpletype = sig->params [i - 1]->type; -enum_marshal2: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_I8: - case MONO_TYPE_U8: - case MONO_TYPE_CLASS: - if ((arg_in_reg_bitvector[(i - 1) >> 3] & (1 << ((i - 1) & 7))) == 0) { - amd64_push_membase (p, AMD64_R10, arg_pos); - } - break; - case MONO_TYPE_R4: - if ((arg_in_reg_bitvector[(i - 1) >> 3] & (1 << ((i - 1) & 7))) == 0) { - amd64_push_membase (p, AMD64_R10, arg_pos); - } - break; - case MONO_TYPE_R8: - if ((arg_in_reg_bitvector[(i - 1) >> 3] & (1 << ((i - 1) & 7))) == 0) { - amd64_push_membase (p, AMD64_R10, arg_pos); - } - break; - case MONO_TYPE_VALUETYPE: - if (!sig->params [i - 1]->data.klass->enumtype) { - if ((arg_in_reg_bitvector[(i - 1) >> 3] & (1 << ((i - 1) & 7))) == 0) - { - int ss = mono_class_native_size (sig->params [i - 1]->data.klass, NULL); - ss += 7; - ss &= ~7; - - amd64_alu_reg_imm(p, X86_SUB, AMD64_RSP, ss); - /* Count register */ - amd64_mov_reg_imm(p, AMD64_RCX, ss); - /* Source register */ - amd64_lea_membase(p, AMD64_RSI, AMD64_R10, arg_pos); - /* Dest register */ - amd64_mov_reg_reg(p, AMD64_RDI, AMD64_RSP, 8); - - /* AMD64 calling convention guarantees direction flag is clear at call boundary. */ - x86_prefix(p, AMD64_REX(AMD64_REX_W)); - x86_prefix(p, X86_REP_PREFIX); - x86_movsb(p); - } - } else { - /* it's an enum value */ - simpletype = sig->params [i - 1]->data.klass->enum_basetype->type; - goto enum_marshal2; - } - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i - 1]->type); - } - } - - /* TODO: Set RAL to number of XMM registers used in case this is a varags function? */ - - /* - * Insert call to function - */ - amd64_call_reg (p, AMD64_R11); - - if (sig->ret->byref || string_ctor || !(retval_implicit || sig->ret->type == MONO_TYPE_VOID)) { - amd64_mov_reg_membase(p, AMD64_RSI, AMD64_RBP, -8, SIZEOF_VOID_P); - } - /* - * Handle retval. - * Small integer and pointer values are in EAX. - * Long integers are in EAX:EDX. - * FP values are on the FP stack. - */ - - if (sig->ret->byref || string_ctor) { - simpletype = MONO_TYPE_PTR; - } else { - simpletype = sig->ret->type; - } - enum_retvalue: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - amd64_mov_regp_reg (p, AMD64_RSI, X86_EAX, 1); - break; - case MONO_TYPE_CHAR: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - amd64_mov_regp_reg (p, AMD64_RSI, X86_EAX, 2); - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - case MONO_TYPE_STRING: - case MONO_TYPE_PTR: - amd64_mov_regp_reg (p, AMD64_RSI, X86_EAX, 8); - break; - case MONO_TYPE_R4: - amd64_movss_regp_reg (p, AMD64_RSI, AMD64_XMM0); - break; - case MONO_TYPE_R8: - amd64_movsd_regp_reg (p, AMD64_RSI, AMD64_XMM0); - break; - case MONO_TYPE_I8: - amd64_mov_regp_reg (p, AMD64_RSI, X86_EAX, 8); - break; - case MONO_TYPE_VALUETYPE: { - int size; - int arg_type; - int regs_used; - int offset1; - int size1; - int offset2; - int size2; - - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - - arg_type = value_type_info(sig->params [i]->data.klass, &size, ®s_used, &offset1, &size1, &offset2, &size2); - - if (arg_type == ARG_IN_INT_REGS) - { - amd64_mov_membase_reg (p, AMD64_RSI, offset1, AMD64_RAX, size1); - if (regs_used > 1) - amd64_mov_membase_reg (p, AMD64_RSI, offset2, AMD64_RDX, size2); - break; - } - - if (arg_type == ARG_IN_FLOAT_REGS) - { - if (size1 == 4) - amd64_movss_membase_reg (p, AMD64_RSI, offset1, AMD64_XMM0); - else - amd64_movsd_membase_reg (p, AMD64_RSI, offset1, AMD64_XMM0); - - if (regs_used > 1) - { - if (size2 == 4) - amd64_movss_membase_reg (p, AMD64_RSI, offset2, AMD64_XMM1); - else - amd64_movsd_membase_reg (p, AMD64_RSI, offset2, AMD64_XMM1); - } - break; - } - - /* Else result should have been stored in place already. */ - break; - } - case MONO_TYPE_VOID: - break; - default: - g_error ("Can't handle as return value 0x%x", sig->ret->type); - } - - /* - * Standard epilog. - */ - amd64_leave (p); - amd64_ret (p); - - g_assert (p - code_buffer < code_size); - res = (MonoPIFunc)g_memdup (code_buffer, p - code_buffer); - - g_hash_table_insert (cache, sig, res); - - return res; -} - -/* - * Returns a pointer to a native function that can be used to - * call the specified method. - * The function created will receive the arguments according - * to the call convention specified in the method. - * This function works by creating a MonoInvocation structure, - * filling the fields in and calling ves_exec_method on it. - * Still need to figure out how to handle the exception stuff - * across the managed/unmanaged boundary. - */ -void * -mono_arch_create_method_pointer (MonoMethod *method) -{ - MonoMethodSignature *sig; - MonoJitInfo *ji; - unsigned char *p, *code_buffer; - guint32 simpletype; - gint32 local_size; - gint32 stackval_pos; - gint32 mono_invocation_pos; - int i, cpos; - int *vtbuf; - int *rbpoffsets; - int int_arg_regs_used = 0; - int float_arg_regs_used = 0; - int stacked_args_size = 0; /* bytes of register passed arguments pushed on stack for safe keeping. Used to get alignment right. */ - int next_stack_arg_rbp_offset = 16; - int retval_ptr_rbp_offset = 0; - int this_reg = -1; /* Remember register this ptr is in. */ - - /* - * If it is a static P/Invoke method, we can just return the pointer - * to the method implementation. - */ - if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL && ((MonoMethodPInvoke*) method)->addr) { - ji = g_new0 (MonoJitInfo, 1); - ji->method = method; - ji->code_size = 1; - ji->code_start = ((MonoMethodPInvoke*) method)->addr; - - mono_jit_info_table_add (mono_get_root_domain (), ji); - return ((MonoMethodPInvoke*) method)->addr; - } - - sig = method->signature; - - code_buffer = p = alloca (512); /* FIXME: check for overflows... */ - vtbuf = alloca (sizeof(int)*sig->param_count); - rbpoffsets = alloca (sizeof(int)*sig->param_count); - - - /* - * Standard function prolog. - */ - amd64_push_reg (p, AMD64_RBP); - amd64_mov_reg_reg (p, AMD64_RBP, AMD64_RSP, 8); - - /* If there is an implicit return value pointer in the first args reg, save it now so - * the result can be stored through the pointer at the end. - */ - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref && !sig->ret->data.klass->enumtype) - { - amd64_push_reg (p, int_arg_regs[int_arg_regs_used]); - int_arg_regs_used++; - stacked_args_size += 8; - retval_ptr_rbp_offset = -stacked_args_size; - } - - /* - * If there is a this pointer, remember the number of the register it is in. - */ - if (sig->hasthis) { - this_reg = int_arg_regs[int_arg_regs_used++]; - } - - /* Put all arguments passed in registers on the stack. - * Record offsets from RBP to each argument. - */ - cpos = 0; - - for (i = 0; i < sig->param_count; i++) { - if (sig->params [i]->byref) - simpletype = MONO_TYPE_PTR; - else - simpletype = sig->params [i]->type; -enum_calc_size: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_I8: - if (int_arg_regs_used < MAX_INT_ARG_REGS) { - amd64_push_reg (p, int_arg_regs[int_arg_regs_used]); - int_arg_regs_used++; - stacked_args_size += 8; - rbpoffsets[i] = -stacked_args_size; - } - else - { - rbpoffsets[i] = next_stack_arg_rbp_offset; - next_stack_arg_rbp_offset += 8; - } - break; - case MONO_TYPE_VALUETYPE: { - if (sig->params [i]->data.klass->enumtype) { - simpletype = sig->params [i]->data.klass->enum_basetype->type; - goto enum_calc_size; - } - else - { - int size; - int arg_type; - int regs_used; - int offset1; - int size1; - int offset2; - int size2; - - arg_type = value_type_info(sig->params [i]->data.klass, &size, ®s_used, &offset1, &size1, &offset2, &size2); - - if (arg_type == ARG_IN_INT_REGS && - (int_arg_regs_used + regs_used) <= MAX_INT_ARG_REGS) - { - amd64_alu_reg_imm (p, X86_SUB, AMD64_RSP, size); - stacked_args_size += size; - rbpoffsets[i] = stacked_args_size; - - amd64_mov_reg_membase (p, int_arg_regs[int_arg_regs_used], AMD64_RSP, offset1, size1); - int_arg_regs_used++; - if (regs_used > 1) - { - amd64_mov_reg_membase (p, int_arg_regs[int_arg_regs_used], AMD64_RSP, offset2, size2); - int_arg_regs_used++; - } - break; - } - - if (arg_type == ARG_IN_FLOAT_REGS && - (float_arg_regs_used + regs_used) <= MAX_FLOAT_ARG_REGS) - { - amd64_alu_reg_imm (p, X86_SUB, AMD64_RSP, size); - stacked_args_size += size; - rbpoffsets[i] = stacked_args_size; - - if (size1 == 4) - amd64_movss_reg_membase (p, float_arg_regs_used, AMD64_RSP, offset1); - else - amd64_movsd_reg_membase (p, float_arg_regs_used, AMD64_RSP, offset1); - float_arg_regs_used++; - - if (regs_used > 1) - { - if (size2 == 4) - amd64_movss_reg_membase (p, float_arg_regs_used, AMD64_RSP, offset2); - else - amd64_movsd_reg_membase (p, float_arg_regs_used, AMD64_RSP, offset2); - float_arg_regs_used++; - } - break; - } - - rbpoffsets[i] = next_stack_arg_rbp_offset; - next_stack_arg_rbp_offset += size; - } - break; - } - case MONO_TYPE_R4: - if (float_arg_regs_used < MAX_FLOAT_ARG_REGS) { - amd64_alu_reg_imm (p, X86_SUB, AMD64_RSP, 8); - amd64_movss_regp_reg (p, AMD64_RSP, float_arg_regs_used); - float_arg_regs_used++; - stacked_args_size += 8; - rbpoffsets[i] = -stacked_args_size; - } - else - { - rbpoffsets[i] = next_stack_arg_rbp_offset; - next_stack_arg_rbp_offset += 8; - } - break; - case MONO_TYPE_R8: - stacked_args_size += 8; - if (float_arg_regs_used < MAX_FLOAT_ARG_REGS) { - amd64_alu_reg_imm (p, X86_SUB, AMD64_RSP, 8); - amd64_movsd_regp_reg (p, AMD64_RSP, float_arg_regs_used); - float_arg_regs_used++; - stacked_args_size += 8; - rbpoffsets[i] = -stacked_args_size; - } - else - { - rbpoffsets[i] = next_stack_arg_rbp_offset; - next_stack_arg_rbp_offset += 8; - } - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i]->type); - } - } - - local_size = sizeof (MonoInvocation) + sizeof (stackval) * (sig->param_count + 1) + stacked_args_size; - - local_size += 15; - local_size &= ~15; - - stackval_pos = -local_size; - mono_invocation_pos = stackval_pos + sizeof (stackval) * (sig->param_count + 1); - - /* stacked_args_size has already been pushed onto the stack. Make room for the rest of it. */ - amd64_alu_reg_imm (p, X86_SUB, AMD64_RSP, local_size - stacked_args_size); - - /* Be careful not to trash any arg regs before saving this_reg to MonoInvocation structure below. */ - - /* - * Initialize MonoInvocation fields, first the ones known now. - */ - amd64_alu_reg_reg (p, X86_XOR, AMD64_RAX, AMD64_RAX); - amd64_mov_membase_reg (p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, ex)), AMD64_RAX, SIZEOF_VOID_P); - amd64_mov_membase_reg (p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, ex_handler)), AMD64_RAX, SIZEOF_VOID_P); - amd64_mov_membase_reg (p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, parent)), AMD64_RAX, SIZEOF_VOID_P); - /* - * Set the method pointer. - */ - amd64_mov_membase_imm (p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, method)), (long)method, SIZEOF_VOID_P); - - /* - * Handle this. - */ - if (sig->hasthis) - amd64_mov_membase_reg(p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, obj)), this_reg, SIZEOF_VOID_P); - - /* - * Handle the arguments. stackval_pos is the offset from RBP of the stackval in the MonoInvocation args array . - * arg_pos is the offset from RBP to the incoming arg on the stack. - * We just call stackval_from_data to handle all the (nasty) issues.... - */ - amd64_lea_membase (p, AMD64_RAX, AMD64_RBP, stackval_pos); - amd64_mov_membase_reg (p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, stack_args)), AMD64_RAX, SIZEOF_VOID_P); - for (i = 0; i < sig->param_count; ++i) { -/* Need to call stackval_from_data (MonoType *type, stackval *result, char *data, gboolean pinvoke); */ - amd64_mov_reg_imm (p, AMD64_R11, stackval_from_data); - amd64_mov_reg_imm (p, int_arg_regs[0], sig->params[i]); - amd64_lea_membase (p, int_arg_regs[1], AMD64_RBP, stackval_pos); - amd64_lea_membase (p, int_arg_regs[2], AMD64_RBP, rbpoffsets[i]); - amd64_mov_reg_imm (p, int_arg_regs[3], sig->pinvoke); - amd64_call_reg (p, AMD64_R11); - stackval_pos += sizeof (stackval); -#if 0 - /* fixme: alignment */ - if (sig->pinvoke) - arg_pos += mono_type_native_stack_size (sig->params [i], &align); - else - arg_pos += mono_type_stack_size (sig->params [i], &align); -#endif - } - - /* - * Handle the return value storage area. - */ - amd64_lea_membase (p, AMD64_RAX, AMD64_RBP, stackval_pos); - amd64_mov_membase_reg (p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, retval)), AMD64_RAX, SIZEOF_VOID_P); - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) { - MonoClass *klass = sig->ret->data.klass; - if (!klass->enumtype) { - amd64_mov_reg_membase (p, AMD64_RCX, AMD64_RBP, retval_ptr_rbp_offset, SIZEOF_VOID_P); - amd64_mov_membase_reg (p, AMD64_RBP, stackval_pos, AMD64_RCX, SIZEOF_VOID_P); - } - } - - /* - * Call the method. - */ - amd64_lea_membase (p, int_arg_regs[0], AMD64_RBP, mono_invocation_pos); - amd64_mov_reg_imm (p, AMD64_R11, ves_exec_method); - amd64_call_reg (p, AMD64_R11); - - /* - * Move the return value to the proper place. - */ - amd64_lea_membase (p, AMD64_RAX, AMD64_RBP, stackval_pos); - if (sig->ret->byref) { - amd64_mov_reg_membase (p, AMD64_RAX, AMD64_RAX, 0, SIZEOF_VOID_P); - } else { - int simpletype = sig->ret->type; - enum_retvalue: - switch (sig->ret->type) { - case MONO_TYPE_VOID: - break; - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - amd64_movzx_reg_membase (p, AMD64_RAX, AMD64_RAX, 0, 1); - break; - case MONO_TYPE_CHAR: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - amd64_movzx_reg_membase (p, AMD64_RAX, AMD64_RAX, 0, 2); - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_CLASS: - amd64_movzx_reg_membase (p, AMD64_RAX, AMD64_RAX, 0, 4); - break; - case MONO_TYPE_I8: - amd64_movzx_reg_membase (p, AMD64_RAX, AMD64_RAX, 0, 8); - break; - case MONO_TYPE_R4: - amd64_movss_regp_reg (p, AMD64_RAX, AMD64_XMM0); - break; - case MONO_TYPE_R8: - amd64_movsd_regp_reg (p, AMD64_RAX, AMD64_XMM0); - break; - case MONO_TYPE_VALUETYPE: { - int size; - int arg_type; - int regs_used; - int offset1; - int size1; - int offset2; - int size2; - - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - - arg_type = value_type_info(sig->params [i]->data.klass, &size, ®s_used, &offset1, &size1, &offset2, &size2); - - if (arg_type == ARG_IN_INT_REGS) - { - if (regs_used > 1) - amd64_mov_membase_reg (p, AMD64_RAX, offset2, AMD64_RDX, size2); - amd64_mov_membase_reg (p, AMD64_RAX, offset1, AMD64_RAX, size1); - break; - } - - if (arg_type == ARG_IN_FLOAT_REGS) - { - if (size1 == 4) - amd64_movss_membase_reg (p, AMD64_RAX, offset1, AMD64_XMM0); - else - amd64_movsd_membase_reg (p, AMD64_RAX, offset1, AMD64_XMM0); - - if (regs_used > 1) - { - if (size2 == 4) - amd64_movss_membase_reg (p, AMD64_RAX, offset2, AMD64_XMM1); - else - amd64_movsd_membase_reg (p, AMD64_RAX, offset2, AMD64_XMM1); - } - break; - } - - /* Else result should have been stored in place already. IA32 code has a stackval_to_data call here, which - * looks wrong to me as the pointer in the stack val being converted is setup to point to the output area anyway. - * It all looks a bit suspect anyway. - */ - break; - } - default: - g_error ("Type 0x%x not handled yet in thunk creation", sig->ret->type); - break; - } - } - - /* - * Standard epilog. - */ - amd64_leave (p); - amd64_ret (p); - - g_assert (p - code_buffer < 512); - - ji = g_new0 (MonoJitInfo, 1); - ji->method = method; - ji->code_size = p - code_buffer; - ji->code_start = g_memdup (code_buffer, p - code_buffer); - - mono_jit_info_table_add (mono_get_root_domain (), ji); - - return ji->code_start; -} diff --git a/mono/arch/ppc/Makefile.am b/mono/arch/ppc/Makefile.am index a4e2d5d2e7c..9b209ef9400 100644 --- a/mono/arch/ppc/Makefile.am +++ b/mono/arch/ppc/Makefile.am @@ -1,11 +1 @@ -if INTERP_SUPPORTED - -AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) - -noinst_LTLIBRARIES = libmonoarch-ppc.la - -libmonoarch_ppc_la_SOURCES = tramp.c ppc-codegen.h - -noinst_PROGRAMS = test - -endif +EXTRA_DIST = ppc-codegen.h \ No newline at end of file diff --git a/mono/arch/ppc/test.c b/mono/arch/ppc/test.c deleted file mode 100644 index c19358dcab0..00000000000 --- a/mono/arch/ppc/test.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "ppc-codegen.h" -#include - -/* don't run the resulting program, it will destroy your computer, - * just objdump -d it to inspect we generated the correct assembler. - * On Mac OS X use otool[64] -v -t - */ - -int main() { - guint8 code [16000]; - guint8 *p = code; - guint8 *cp; - - printf (".text\n.align 4\n.globl main\n"); -#ifndef __APPLE__ - printf (".type main,@function\n"); -#endif - printf ("main:\n"); - - ppc_stwu (p, ppc_r1, -32, ppc_r1); - ppc_mflr (p, ppc_r0); - ppc_stw (p, ppc_r31, 28, ppc_r1); - ppc_or (p, ppc_r1, ppc_r2, ppc_r3); - ppc_mr (p, ppc_r31, ppc_r1); - ppc_lwz (p, ppc_r11, 0, ppc_r1); - ppc_mtlr (p, ppc_r0); - ppc_blr (p); - ppc_addi (p, ppc_r6, ppc_r6, 16); - - for (cp = code; cp < p; cp++) { - printf (".byte 0x%x\n", *cp); - } - - return 0; -} diff --git a/mono/arch/ppc/tramp.c b/mono/arch/ppc/tramp.c deleted file mode 100644 index 6bb1896255f..00000000000 --- a/mono/arch/ppc/tramp.c +++ /dev/null @@ -1,895 +0,0 @@ -/* - * Create trampolines to invoke arbitrary functions. - * - * Copyright (C) Radek Doulik - * - */ - -#include "config.h" -#include -#include -#include "ppc-codegen.h" -#include "mono/metadata/class.h" -#include "mono/metadata/tabledefs.h" -#include "mono/interpreter/interp.h" -#include "mono/metadata/appdomain.h" - -#ifdef NEED_MPROTECT -#include -#include /* for PAGESIZE */ -#ifndef PAGESIZE -#define PAGESIZE 4096 -#endif -#endif - -#define DEBUG(x) - -/* gpointer -fake_func (gpointer (*callme)(gpointer), stackval *retval, void *this_obj, stackval *arguments) -{ - guint32 i = 0xc002becd; - - callme = (gpointer) 0x100fabcd; - - *(gpointer*)retval = (gpointer)(*callme) (arguments [0].data.p, arguments [1].data.p, arguments [2].data.p); - *(gdouble*) retval = (gdouble)(*callme) (arguments [0].data.f); - - return (gpointer) (*callme) (((MonoType *)arguments [0]. data.p)->data.klass); -} */ - -#define MIN_CACHE_LINE 8 - -static void inline -flush_icache (guint8 *code, guint size) -{ - guint i; - guint8 *p; - - p = code; - for (i = 0; i < size; i += MIN_CACHE_LINE, p += MIN_CACHE_LINE) { - asm ("dcbst 0,%0;" : : "r"(p) : "memory"); - } - asm ("sync"); - p = code; - for (i = 0; i < size; i += MIN_CACHE_LINE, p += MIN_CACHE_LINE) { - asm ("icbi 0,%0; sync;" : : "r"(p) : "memory"); - } - asm ("sync"); - asm ("isync"); -} - -static void -disassemble (guint8 *code, int size) -{ - int i; - FILE *ofd; - const char *tmp = g_getenv("TMP"); - char *as_file; - char *o_file; - char *cmd; - - if (tmp == NULL) - tmp = "/tmp"; - as_file = g_strdup_printf ("%s/test.s", tmp); - - if (!(ofd = fopen (as_file, "w"))) - g_assert_not_reached (); - - fprintf (ofd, "tmp:\n"); - - for (i = 0; i < size; ++i) - fprintf (ofd, ".byte %d\n", (unsigned int) code [i]); - - fclose (ofd); -#ifdef __APPLE__ -#define DIS_CMD "otool -V -v -t" -#else -#define DIS_CMD "objdump -d" -#endif - o_file = g_strdup_printf ("%s/test.o", tmp); - cmd = g_strdup_printf ("as %s -o %s", as_file, o_file); - system (cmd); - g_free (cmd); - cmd = g_strdup_printf (DIS_CMD " %s", o_file); - system (cmd); - g_free (cmd); - g_free (o_file); - g_free (as_file); -} - - -#define NOT_IMPLEMENTED(x) \ - g_error ("FIXME: %s is not yet implemented. (trampoline)", x); - -#define PROLOG_INS 8 -#define CALL_INS 2 -#define EPILOG_INS 6 -#define FLOAT_REGS 8 -#define GENERAL_REGS 8 -#ifdef __APPLE__ -#define MINIMAL_STACK_SIZE 10 -#define ALWAYS_ON_STACK(s) s -#define FP_ALSO_IN_REG(s) s -#define RET_ADDR_OFFSET 8 -#define STACK_PARAM_OFFSET 24 -#else -#define MINIMAL_STACK_SIZE 5 -#define ALWAYS_ON_STACK(s) -#define FP_ALSO_IN_REG(s) s -#define ALIGN_DOUBLES -#define RET_ADDR_OFFSET 4 -#define STACK_PARAM_OFFSET 8 -#endif - -static void inline -add_general (guint *gr, guint *stack_size, guint *code_size, gboolean simple) -{ - if (simple) { - if (*gr >= GENERAL_REGS) { - *stack_size += 4; - *code_size += 8; /* load from stack, save on stack */ - } else { - ALWAYS_ON_STACK (*stack_size += 4); - *code_size += 4; /* load from stack */ - } - } else { - if (*gr >= GENERAL_REGS - 1) { - *stack_size += 8; -#ifdef ALIGN_DOUBLES - *stack_size += (*stack_size % 8); -#endif - *code_size += 16; /* 2x load from stack, 2x save to stack */ - } else { - ALWAYS_ON_STACK (*stack_size += 8); - *code_size += 8; /* 2x load from stack */ - } -#ifdef ALIGN_DOUBLES - if ((*gr) & 1) - (*gr) ++; -#endif - (*gr) ++; - } - (*gr) ++; -} - -static void inline -calculate_sizes (MonoMethodSignature *sig, guint *stack_size, guint *code_size, gboolean string_ctor, gboolean *use_memcpy) -{ - guint i, fr, gr; - guint32 simpletype; - - fr = gr = 0; - *stack_size = MINIMAL_STACK_SIZE*4; - *code_size = (PROLOG_INS + CALL_INS + EPILOG_INS)*4; - - if (sig->hasthis) { - add_general (&gr, stack_size, code_size, TRUE); - } - DEBUG(printf("params: %d\n", sig->param_count)); - for (i = 0; i < sig->param_count; ++i) { - DEBUG(printf("param %d: ", i)); - if (sig->params [i]->byref) { - DEBUG(printf("byref\n")); - add_general (&gr, stack_size, code_size, TRUE); - continue; - } - simpletype = sig->params [i]->type; - enum_calc_size: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - add_general (&gr, stack_size, code_size, TRUE); - break; - case MONO_TYPE_SZARRAY: - add_general (&gr, stack_size, code_size, TRUE); - *code_size += 4; - break; - case MONO_TYPE_VALUETYPE: { - gint size; - if (sig->params [i]->data.klass->enumtype) { - simpletype = sig->params [i]->data.klass->enum_basetype->type; - goto enum_calc_size; - } - size = mono_class_value_size (sig->params [i]->data.klass, NULL); - if (size != 4) { - DEBUG(printf ("copy %d bytes struct on stack\n", - mono_class_value_size (sig->params [i]->data.klass, NULL))); - *use_memcpy = TRUE; - *code_size += 8*4; - *stack_size += (size + 3) & (~3); - if (gr > GENERAL_REGS) { - *code_size += 4; - *stack_size += 4; - } - } else { - DEBUG(printf ("load %d bytes struct\n", - mono_class_value_size (sig->params [i]->data.klass, NULL))); - add_general (&gr, stack_size, code_size, TRUE); - *code_size += 4; - } - break; - } - case MONO_TYPE_I8: - add_general (&gr, stack_size, code_size, FALSE); - break; - case MONO_TYPE_R4: - if (fr < 7) { - *code_size += 4; - fr ++; - FP_ALSO_IN_REG (gr ++); - ALWAYS_ON_STACK (*stack_size += 4); - } else { - NOT_IMPLEMENTED ("R4 arg"); - } - break; - case MONO_TYPE_R8: - if (fr < 7) { - *code_size += 4; - fr ++; - FP_ALSO_IN_REG (gr += 2); - ALWAYS_ON_STACK (*stack_size += 8); - } else { - NOT_IMPLEMENTED ("R8 arg"); - } - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i]->type); - } - } - - if (sig->ret->byref || string_ctor) { - *code_size += 8; - } else { - simpletype = sig->ret->type; -enum_retvalue: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_R4: - case MONO_TYPE_R8: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - case MONO_TYPE_STRING: - *code_size += 8; - break; - case MONO_TYPE_I8: - *code_size += 12; - break; - case MONO_TYPE_VALUETYPE: - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - *code_size += 2*4; - break; - case MONO_TYPE_VOID: - break; - default: - g_error ("Can't handle as return value 0x%x", sig->ret->type); - } - } - - if (*use_memcpy) { - *stack_size += 2*4; /* for r14, r15 */ - *code_size += 6*4; - if (sig->hasthis) { - *stack_size += 4; /* for r16 */ - *code_size += 4; - } - } - - /* align stack size to 16 */ - DEBUG (printf (" stack size: %d (%d)\n code size: %d\n", (*stack_size + 15) & ~15, *stack_size, *code_size)); - *stack_size = (*stack_size + 15) & ~15; -} - -static inline guint8 * -emit_prolog (guint8 *p, MonoMethodSignature *sig, guint stack_size) -{ - /* function prolog */ - ppc_stwu (p, ppc_r1, -stack_size, ppc_r1); /* sp <--- sp - stack_size, sp[0] <---- sp save sp, alloc stack */ - ppc_mflr (p, ppc_r0); /* r0 <--- LR */ - ppc_stw (p, ppc_r31, stack_size - 4, ppc_r1); /* sp[+4] <--- r31 save r31 */ - ppc_stw (p, ppc_r0, stack_size + RET_ADDR_OFFSET, ppc_r1); /* sp[-4] <--- LR save return address for "callme" */ - ppc_mr (p, ppc_r31, ppc_r1); /* r31 <--- sp */ - - return p; -} - -#define ARG_BASE ppc_r12 -#define ARG_SIZE sizeof (stackval) -#define SAVE_4_IN_GENERIC_REGISTER \ - if (gr < GENERAL_REGS) { \ - ppc_lwz (p, ppc_r3 + gr, i*ARG_SIZE, ARG_BASE); \ - gr ++; \ - ALWAYS_ON_STACK (stack_par_pos += 4); \ - } else { \ - ppc_lwz (p, ppc_r11, i*ARG_SIZE, ARG_BASE); \ - ppc_stw (p, ppc_r11, stack_par_pos, ppc_r1); \ - stack_par_pos += 4; \ - } -#define SAVE_4_VAL_IN_GENERIC_REGISTER \ - if (gr < GENERAL_REGS) { \ - ppc_lwz (p, ppc_r3 + gr, i*ARG_SIZE, ARG_BASE); \ - ppc_lwz (p, ppc_r3 + gr, 0, ppc_r3 + gr); \ - gr ++; \ - ALWAYS_ON_STACK (stack_par_pos += 4); \ - } else { \ - ppc_lwz (p, ppc_r11, i*ARG_SIZE, ARG_BASE); \ - ppc_lwz (p, ppc_r11, 0, ppc_r11); \ - ppc_stw (p, ppc_r11, stack_par_pos, ppc_r1); \ - stack_par_pos += 4; \ - } - -inline static guint8* -emit_save_parameters (guint8 *p, MonoMethodSignature *sig, guint stack_size, gboolean use_memcpy) -{ - guint i, fr, gr, stack_par_pos, struct_pos, cur_struct_pos; - guint32 simpletype; - - fr = gr = 0; - stack_par_pos = STACK_PARAM_OFFSET; - - ppc_stw (p, ppc_r4, stack_size - 12, ppc_r31); /* preserve "retval", sp[+8] */ - - if (use_memcpy) { - ppc_stw (p, ppc_r14, stack_size - 16, ppc_r31); /* save r14 */ - ppc_stw (p, ppc_r15, stack_size - 20, ppc_r31); /* save r15 */ - ppc_mr (p, ppc_r14, ppc_r3); /* keep "callme" in register */ - ppc_mr (p, ppc_r15, ppc_r6); /* keep "arguments" in register */ - } else { - ppc_mr (p, ppc_r12, ppc_r6); /* keep "arguments" in register */ - ppc_mr (p, ppc_r0, ppc_r3); /* keep "callme" in register */ - } - - if (sig->hasthis) { - if (use_memcpy) { - ppc_stw (p, ppc_r16, stack_size - 24, ppc_r31); /* save r16 */ - ppc_mr (p, ppc_r16, ppc_r5); - } else - ppc_mr (p, ppc_r3, ppc_r5); - gr ++; - ALWAYS_ON_STACK (stack_par_pos += 4); - } - - if (use_memcpy) { - cur_struct_pos = struct_pos = stack_par_pos; - for (i = 0; i < sig->param_count; ++i) { - if (sig->params [i]->byref) - continue; - if (sig->params [i]->type == MONO_TYPE_VALUETYPE && !sig->params [i]->data.klass->enumtype) { - gint size; - - size = mono_class_value_size (sig->params [i]->data.klass, NULL); - if (size != 4) { - /* call memcpy */ - ppc_addi (p, ppc_r3, ppc_r1, stack_par_pos); - ppc_lwz (p, ppc_r4, i*16, ppc_r15); - /* FIXME check if size > 0xffff */ - ppc_li (p, ppc_r5, size & 0xffff); - ppc_lis (p, ppc_r0, (guint32) memcpy >> 16); - ppc_ori (p, ppc_r0, ppc_r0, (guint32) memcpy & 0xffff); - ppc_mtlr (p, ppc_r0); - ppc_blrl (p); - stack_par_pos += (size + 3) & (~3); - } - } - } - - if (sig->hasthis) { - ppc_mr (p, ppc_r3, ppc_r16); - ppc_lwz (p, ppc_r16, stack_size - 24, ppc_r31); /* restore r16 */ - } - ppc_mr (p, ppc_r0, ppc_r14); - ppc_mr (p, ppc_r12, ppc_r15); - ppc_lwz (p, ppc_r14, stack_size - 16, ppc_r31); /* restore r14 */ - ppc_lwz (p, ppc_r15, stack_size - 20, ppc_r31); /* restore r15 */ - } - - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) { - MonoClass *klass = sig->ret->data.klass; - if (!klass->enumtype) { - gint size = mono_class_native_size (klass, NULL); - - DEBUG(printf ("retval value type size: %d\n", size)); - if (size > 8) { - ppc_lwz (p, ppc_r3, stack_size - 12, ppc_r31); - ppc_lwz (p, ppc_r3, 0, ppc_r3); - gr ++; - ALWAYS_ON_STACK (stack_par_pos += 4); - } else { - NOT_IMPLEMENTED ("retval valuetype <= 8 bytes"); - } - } - } - - for (i = 0; i < sig->param_count; ++i) { - if (sig->params [i]->byref) { - SAVE_4_IN_GENERIC_REGISTER; - continue; - } - simpletype = sig->params [i]->type; - enum_calc_size: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: - SAVE_4_IN_GENERIC_REGISTER; - break; - case MONO_TYPE_VALUETYPE: { - gint size; - if (sig->params [i]->data.klass->enumtype) { - simpletype = sig->params [i]->data.klass->enum_basetype->type; - goto enum_calc_size; - } - size = mono_class_value_size (sig->params [i]->data.klass, NULL); - if (size == 4) { - SAVE_4_VAL_IN_GENERIC_REGISTER; - } else { - if (gr < GENERAL_REGS) { - ppc_addi (p, ppc_r3 + gr, ppc_r1, cur_struct_pos); - gr ++; - } else { - ppc_lwz (p, ppc_r11, cur_struct_pos, ppc_r1); - ppc_stw (p, ppc_r11, stack_par_pos, ppc_r1); - stack_par_pos += 4; - } - cur_struct_pos += (size + 3) & (~3); - } - break; - } - case MONO_TYPE_I8: -DEBUG(printf("Mono_Type_i8. gr = %d, arg_base = %d\n", gr, ARG_BASE)); -#ifdef ALIGN_DOUBLES - if (gr & 1) - gr++; -#endif - if (gr < 7) { - ppc_lwz (p, ppc_r3 + gr, i*ARG_SIZE, ARG_BASE); - ppc_lwz (p, ppc_r3 + gr + 1, i*ARG_SIZE + 4, ARG_BASE); - ALWAYS_ON_STACK (stack_par_pos += 8); - } else if (gr == 7) { - ppc_lwz (p, ppc_r3 + gr, i*ARG_SIZE, ARG_BASE); - ppc_lwz (p, ppc_r11, i*ARG_SIZE + 4, ARG_BASE); - ppc_stw (p, ppc_r11, stack_par_pos + 4, ppc_r1); - stack_par_pos += 8; - } else { - ppc_lwz (p, ppc_r11, i*ARG_SIZE, ARG_BASE); - ppc_stw (p, ppc_r11, stack_par_pos, ppc_r1); - ppc_lwz (p, ppc_r11, i*ARG_SIZE + 4, ARG_BASE); - ppc_stw (p, ppc_r11, stack_par_pos + 4, ppc_r1); - stack_par_pos += 8; - } - gr += 2; - break; - case MONO_TYPE_R4: - if (fr < 7) { - ppc_lfs (p, ppc_f1 + fr, i*ARG_SIZE, ARG_BASE); - fr ++; - FP_ALSO_IN_REG (gr ++); - ALWAYS_ON_STACK (stack_par_pos += 4); - } else { - NOT_IMPLEMENTED ("r4 on stack"); - } - break; - case MONO_TYPE_R8: - if (fr < 7) { - ppc_lfd (p, ppc_f1 + fr, i*ARG_SIZE, ARG_BASE); - fr ++; - FP_ALSO_IN_REG (gr += 2); - ALWAYS_ON_STACK (stack_par_pos += 8); - } else { - NOT_IMPLEMENTED ("r8 on stack"); - } - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i]->type); - } - } - - return p; -} - -static inline guint8 * -alloc_code_memory (guint code_size) -{ - guint8 *p; - -#ifdef NEED_MPROTECT - p = g_malloc (code_size + PAGESIZE - 1); - - /* Align to a multiple of PAGESIZE, assumed to be a power of two */ - p = (char *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1)); -#else - p = g_malloc (code_size); -#endif - DEBUG (printf (" align: %p (%d)\n", p, (guint)p % 4)); - - return p; -} - -/* static MonoString* -mono_string_new_wrapper (const char *text) -{ - return text ? mono_string_new (mono_domain_get (), text) : NULL; -} */ - -static inline guint8 * -emit_call_and_store_retval (guint8 *p, MonoMethodSignature *sig, guint stack_size, gboolean string_ctor) -{ - guint32 simpletype; - - /* call "callme" */ - ppc_mtlr (p, ppc_r0); - ppc_blrl (p); - - /* get return value */ - if (sig->ret->byref || string_ctor) { - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_stw (p, ppc_r3, 0, ppc_r9); /* save return value (r3) to "retval" */ - } else { - simpletype = sig->ret->type; -enum_retvalue: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_stb (p, ppc_r3, 0, ppc_r9); /* save return value (r3) to "retval" */ - break; - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_sth (p, ppc_r3, 0, ppc_r9); /* save return value (r3) to "retval" */ - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - case MONO_TYPE_STRING: - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_stw (p, ppc_r3, 0, ppc_r9); /* save return value (r3) to "retval" */ - break; - case MONO_TYPE_R4: - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_stfs (p, ppc_f1, 0, ppc_r9); /* save return value (f1) to "retval" */ - break; - case MONO_TYPE_R8: - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_stfd (p, ppc_f1, 0, ppc_r9); /* save return value (f1) to "retval" */ - break; - case MONO_TYPE_I8: - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_stw (p, ppc_r3, 0, ppc_r9); /* save return value (r3) to "retval" */ - ppc_stw (p, ppc_r4, 4, ppc_r9); /* save return value (r3) to "retval" */ - break; - case MONO_TYPE_VALUETYPE: - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - break; - case MONO_TYPE_VOID: - break; - default: - g_error ("Can't handle as return value 0x%x", sig->ret->type); - } - } - - return p; -} - -static inline guint8 * -emit_epilog (guint8 *p, MonoMethodSignature *sig, guint stack_size) -{ - /* function epilog */ - ppc_lwz (p, ppc_r11, 0, ppc_r1); /* r11 <--- sp[0] load backchain from caller's function */ - ppc_lwz (p, ppc_r0, RET_ADDR_OFFSET, ppc_r11); /* r0 <--- r11[4] load return address */ - ppc_mtlr (p, ppc_r0); /* LR <--- r0 set return address */ - ppc_lwz (p, ppc_r31, -4, ppc_r11); /* r31 <--- r11[-4] restore r31 */ - ppc_mr (p, ppc_r1, ppc_r11); /* sp <--- r11 restore stack */ - ppc_blr (p); /* return */ - - return p; -} - -MonoPIFunc -mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor) -{ - guint8 *p, *code_buffer; - guint stack_size, code_size; - gboolean use_memcpy = FALSE; - - DEBUG (printf ("\nPInvoke [start emiting]\n")); - calculate_sizes (sig, &stack_size, &code_size, string_ctor, &use_memcpy); - - p = code_buffer = alloc_code_memory (code_size); - p = emit_prolog (p, sig, stack_size); - p = emit_save_parameters (p, sig, stack_size, use_memcpy); - p = emit_call_and_store_retval (p, sig, stack_size, string_ctor); - p = emit_epilog (p, sig, stack_size); - - /* { - guchar *cp; - printf (".text\n.align 4\n.globl main\n.type main,@function\nmain:\n"); - for (cp = code_buffer; cp < p; cp++) { - printf (".byte 0x%x\n", *cp); - } - } */ - -#ifdef NEED_MPROTECT - if (mprotect (code_buffer, 1024, PROT_READ | PROT_WRITE | PROT_EXEC)) { - g_error ("Cannot mprotect trampoline\n"); - } -#endif - - DEBUG (printf ("emited code size: %d\n", p - code_buffer)); - flush_icache (code_buffer, p - code_buffer); - - DEBUG (printf ("PInvoke [end emiting]\n")); - - return (MonoPIFunc) code_buffer; - /* return fake_func; */ -} - - -#ifdef __APPLE__ -#define MINV_POS 40 /* MonoInvocation structure offset on stack - STACK_PARAM_OFFSET + 4 pointer args for stackval_from_data */ -#else -#define MINV_POS 8 /* MonoInvocation structure offset on stack */ -#endif -#define STACK_POS (MINV_POS - sizeof (stackval) * sig->param_count) -#define OBJ_POS 8 -#define TYPE_OFFSET (G_STRUCT_OFFSET (stackval, type)) - -/* - * Returns a pointer to a native function that can be used to - * call the specified method. - * The function created will receive the arguments according - * to the call convention specified in the method. - * This function works by creating a MonoInvocation structure, - * filling the fields in and calling ves_exec_method on it. - * Still need to figure out how to handle the exception stuff - * across the managed/unmanaged boundary. - */ -void * -mono_arch_create_method_pointer (MonoMethod *method) -{ - MonoMethodSignature *sig; - MonoJitInfo *ji; - guint8 *p, *code_buffer; - guint i, align = 0, code_size, stack_size, stackval_arg_pos, local_pos, local_start, reg_param = 0, stack_param, - cpos, vt_cur; - gint *vtbuf; - guint32 simpletype; - - code_size = 1024; - stack_size = 1024; - stack_param = 0; - - sig = mono_method_signature (method); - - p = code_buffer = g_malloc (code_size); - - DEBUG (printf ("\nDelegate [start emiting] %s\n", mono_method_get_name (method))); - - /* prolog */ - ppc_stwu (p, ppc_r1, -stack_size, ppc_r1); /* sp <--- sp - stack_size, sp[0] <---- sp save sp, alloc stack */ - ppc_mflr (p, ppc_r0); /* r0 <--- LR */ - ppc_stw (p, ppc_r31, stack_size - 4, ppc_r1); /* sp[+4] <--- r31 save r31 */ - ppc_stw (p, ppc_r0, stack_size + RET_ADDR_OFFSET, ppc_r1); /* sp[-4] <--- LR save return address for "callme" */ - ppc_mr (p, ppc_r31, ppc_r1); /* r31 <--- sp */ - - /* let's fill MonoInvocation */ - /* first zero some fields */ - ppc_li (p, ppc_r0, 0); - ppc_stw (p, ppc_r0, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex)), ppc_r31); - ppc_stw (p, ppc_r0, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex_handler)), ppc_r31); - ppc_stw (p, ppc_r0, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, parent)), ppc_r31); - - /* set method pointer */ - ppc_lis (p, ppc_r0, (guint32) method >> 16); - ppc_ori (p, ppc_r0, ppc_r0, (guint32) method & 0xffff); - ppc_stw (p, ppc_r0, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, method)), ppc_r31); - - local_start = local_pos = MINV_POS + sizeof (MonoInvocation) + (sig->param_count + 1) * sizeof (stackval); - - if (sig->hasthis) { - ppc_stw (p, ppc_r3, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, obj)), ppc_r31); - reg_param = 1; - } - - if (sig->param_count) { - gint save_count = MIN (8, sig->param_count + sig->hasthis); - for (i = reg_param; i < save_count; i ++) { - ppc_stw (p, ppc_r3 + i, local_pos, ppc_r31); - local_pos += 4; - DEBUG (printf ("save r%d\n", 4 + i)); - } - } - - /* prepare space for valuetypes */ - vt_cur = local_pos; - vtbuf = alloca (sizeof(int)*sig->param_count); - cpos = 0; - for (i = 0; i < sig->param_count; i++) { - MonoType *type = sig->params [i]; - vtbuf [i] = -1; - if (type->type == MONO_TYPE_VALUETYPE) { - MonoClass *klass = type->data.klass; - gint size; - - if (klass->enumtype) - continue; - size = mono_class_native_size (klass, &align); - cpos += align - 1; - cpos &= ~(align - 1); - vtbuf [i] = cpos; - cpos += size; - } - } - cpos += 3; - cpos &= ~3; - - local_pos += cpos; - - /* set MonoInvocation::stack_args */ - stackval_arg_pos = MINV_POS + sizeof (MonoInvocation); - ppc_addi (p, ppc_r0, ppc_r31, stackval_arg_pos); - ppc_stw (p, ppc_r0, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, stack_args)), ppc_r31); - - /* add stackval arguments */ - for (i = 0; i < sig->param_count; ++i) { - if (reg_param < 8) { - ppc_addi (p, ppc_r5, ppc_r31, local_start + i*4); - reg_param ++; - } else { - ppc_addi (p, ppc_r5, stack_size + 8 + stack_param, ppc_r31); - stack_param ++; - } - ppc_lis (p, ppc_r3, (guint32) sig->params [i] >> 16); - - if (vtbuf [i] >= 0) { - ppc_addi (p, ppc_r4, ppc_r31, vt_cur); - ppc_stw (p, ppc_r4, stackval_arg_pos, ppc_r31); - ppc_addi (p, ppc_r4, ppc_r31, stackval_arg_pos); - ppc_lwz (p, ppc_r5, 0, ppc_r5); - vt_cur += vtbuf [i]; - } else { - ppc_addi (p, ppc_r4, ppc_r31, stackval_arg_pos); - } - ppc_ori (p, ppc_r3, ppc_r3, (guint32) sig->params [i] & 0xffff); - ppc_lis (p, ppc_r0, (guint32) stackval_from_data >> 16); - ppc_li (p, ppc_r6, sig->pinvoke); - ppc_ori (p, ppc_r0, ppc_r0, (guint32) stackval_from_data & 0xffff); - ppc_mtlr (p, ppc_r0); - ppc_blrl (p); - - stackval_arg_pos += sizeof (stackval); - } - - /* return value storage */ - if (sig->param_count) { - ppc_addi (p, ppc_r0, ppc_r31, stackval_arg_pos); - } - ppc_stw (p, ppc_r0, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, retval)), ppc_r31); - - /* call ves_exec_method */ - ppc_lis (p, ppc_r0, (guint32) ves_exec_method >> 16); - ppc_addi (p, ppc_r3, ppc_r31, MINV_POS); - ppc_ori (p, ppc_r0, ppc_r0, (guint32) ves_exec_method & 0xffff); - ppc_mtlr (p, ppc_r0); - ppc_blrl (p); - - /* move retval from stackval to proper place (r3/r4/...) */ - if (sig->ret->byref) { - DEBUG (printf ("ret by ref\n")); - ppc_lwz (p, ppc_r3, stackval_arg_pos, ppc_r31); - } else { - enum_retvalue: - switch (sig->ret->type) { - case MONO_TYPE_VOID: - break; - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - ppc_lbz (p, ppc_r3, stackval_arg_pos, ppc_r31); - break; - case MONO_TYPE_I2: - case MONO_TYPE_U2: - ppc_lhz (p, ppc_r3, stackval_arg_pos, ppc_r31); - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_CLASS: - ppc_lwz (p, ppc_r3, stackval_arg_pos, ppc_r31); - break; - case MONO_TYPE_I8: - ppc_lwz (p, ppc_r3, stackval_arg_pos, ppc_r31); - ppc_lwz (p, ppc_r4, stackval_arg_pos + 4, ppc_r31); - break; - case MONO_TYPE_R4: - ppc_lfs (p, ppc_f1, stackval_arg_pos, ppc_r31); - break; - case MONO_TYPE_R8: - ppc_lfd (p, ppc_f1, stackval_arg_pos, ppc_r31); - break; - case MONO_TYPE_VALUETYPE: - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - NOT_IMPLEMENTED ("value type as ret val from delegate"); - break; - default: - g_error ("Type 0x%x not handled yet in thunk creation", sig->ret->type); - break; - } - } - - /* epilog */ - ppc_lwz (p, ppc_r11, 0, ppc_r1); /* r11 <--- sp[0] load backchain from caller's function */ - ppc_lwz (p, ppc_r0, RET_ADDR_OFFSET, ppc_r11); /* r0 <--- r11[4] load return address */ - ppc_mtlr (p, ppc_r0); /* LR <--- r0 set return address */ - ppc_lwz (p, ppc_r31, -4, ppc_r11); /* r31 <--- r11[-4] restore r31 */ - ppc_mr (p, ppc_r1, ppc_r11); /* sp <--- r11 restore stack */ - ppc_blr (p); /* return */ - - DEBUG (printf ("emited code size: %d\n", p - code_buffer)); - DEBUG (disassemble (code_buffer, p - code_buffer)); - flush_icache (code_buffer, p - code_buffer); - - DEBUG (printf ("Delegate [end emiting]\n")); - - ji = g_new0 (MonoJitInfo, 1); - ji->method = method; - ji->code_size = p - code_buffer; - ji->code_start = code_buffer; - - mono_jit_info_table_add (mono_get_root_domain (), ji); - - return ji->code_start; -} diff --git a/mono/arch/x86/Makefile.am b/mono/arch/x86/Makefile.am index 977823705ad..bab0f9e54d6 100644 --- a/mono/arch/x86/Makefile.am +++ b/mono/arch/x86/Makefile.am @@ -1,9 +1 @@ -if INTERP_SUPPORTED - -AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) - -noinst_LTLIBRARIES = libmonoarch-x86.la - -libmonoarch_x86_la_SOURCES = tramp.c x86-codegen.h - -endif +EXTRA_DIST = x86-codegen.h \ No newline at end of file diff --git a/mono/arch/x86/test.c b/mono/arch/x86/test.c deleted file mode 100644 index 3511e8fdaf0..00000000000 --- a/mono/arch/x86/test.c +++ /dev/null @@ -1,225 +0,0 @@ -#include "x86-codegen.h" -#include - -/* don't run the resulting program, it will destroy your computer, - * just objdump -d it to inspect we generated the correct assembler. - */ - -int main() { - unsigned char code [16000]; - unsigned char *p = code; - unsigned char *target, *start, *end; - unsigned long mem_addr = 0xdeadbeef; - int size, i; - - printf (".text\n.align 4\n.globl main\n.type main,@function\nmain:\n"); - - x86_prolog (p, 16, X86_CALLER_REGS); - - x86_cmpxchg_reg_reg (p, X86_EAX, X86_EBP); - x86_cmpxchg_membase_reg (p, X86_EAX, 12, X86_EBP); - - x86_xchg_reg_reg (p, X86_EAX, X86_EBP, 4); - x86_xchg_reg_reg (p, X86_EAX, X86_EBP, 1); // FIXME? - x86_xchg_membase_reg (p, X86_EAX, 12, X86_EBP, 4); - x86_xchg_membase_reg (p, X86_EAX, 12, X86_EBP, 2); - x86_xchg_membase_reg (p, X86_EAX, 12, X86_EBX, 1); // FIXME? - - x86_inc_reg (p, X86_EAX); - x86_inc_mem (p, mem_addr); - x86_inc_membase (p, X86_ESP, 4); - - x86_nop (p); - x86_nop (p); - - x86_dec_reg (p, X86_EAX); - x86_dec_reg (p, X86_ECX); - x86_dec_mem (p, mem_addr); - x86_dec_membase (p, X86_ESP, 4); - - x86_not_reg (p, X86_EDX); - x86_not_reg (p, X86_ECX); - x86_not_mem (p, mem_addr); - x86_not_membase (p, X86_ESP, 4); - x86_not_membase (p, X86_ESP, 0x4444444); - x86_not_membase (p, X86_EBP, 0x4444444); - x86_not_membase (p, X86_ECX, 0x4444444); - x86_not_membase (p, X86_EDX, 0); - x86_not_membase (p, X86_EBP, 0); - - x86_neg_reg (p, X86_EAX); - x86_neg_reg (p, X86_ECX); - x86_neg_mem (p, mem_addr); - x86_neg_membase (p, X86_ESP, 8); - - x86_alu_reg_imm (p, X86_ADD, X86_EAX, 5); - x86_alu_reg_imm (p, X86_ADD, X86_EBX, -10); - x86_alu_reg_imm (p, X86_SUB, X86_EDX, 7); - x86_alu_reg_imm (p, X86_OR, X86_ESP, 0xffffedaf); - x86_alu_reg_imm (p, X86_CMP, X86_ECX, 1); - x86_alu_mem_imm (p, X86_ADC, mem_addr, 2); - x86_alu_membase_imm (p, X86_ADC, X86_ESP, -4, 4); - x86_alu_membase_imm (p, X86_ADC, X86_ESP, -12, 0xffffedaf); - - x86_alu_mem_reg (p, X86_SUB, mem_addr, X86_EDX); - x86_alu_reg_reg (p, X86_ADD, X86_EAX, X86_EBX); - x86_alu_reg_mem (p, X86_ADD, X86_EAX, mem_addr); - x86_alu_reg_imm (p, X86_ADD, X86_EAX, 0xdeadbeef); - x86_alu_reg_membase (p, X86_XOR, X86_EDX, X86_ESP, 4); - x86_alu_membase_reg (p, X86_XOR, X86_EBP, 8, X86_ESI); - - x86_test_reg_imm (p, X86_EAX, 16); - x86_test_reg_imm (p, X86_EDX, -16); - x86_test_mem_imm (p, mem_addr, 1); - x86_test_membase_imm (p, X86_EBP, 8, 1); - - x86_test_reg_reg (p, X86_EAX, X86_EDX); - x86_test_mem_reg (p, mem_addr, X86_EDX); - x86_test_membase_reg (p, X86_ESI, 4, X86_EDX); - - x86_shift_reg_imm (p, X86_SHL, X86_EAX, 1); - x86_shift_reg_imm (p, X86_SHL, X86_EDX, 2); - - x86_shift_mem_imm (p, X86_SHL, mem_addr, 2); - x86_shift_membase_imm (p, X86_SHLR, X86_EBP, 8, 4); - - /* - * Shift by CL - */ - x86_shift_reg (p, X86_SHL, X86_EAX); - x86_shift_mem (p, X86_SHL, mem_addr); - - x86_mul_reg (p, X86_EAX, 0); - x86_mul_reg (p, X86_EAX, 1); - x86_mul_membase (p, X86_EBP, 8, 1); - - x86_imul_reg_reg (p, X86_EBX, X86_EDX); - x86_imul_reg_membase (p, X86_EBX, X86_EBP, 12); - - x86_imul_reg_reg_imm (p, X86_EBX, X86_EDX, 10); - x86_imul_reg_mem_imm (p, X86_EBX, mem_addr, 20); - x86_imul_reg_membase_imm (p, X86_EBX, X86_EBP, 16, 300); - - x86_div_reg (p, X86_EDX, 0); - x86_div_reg (p, X86_EDX, 1); - x86_div_mem (p, mem_addr, 1); - x86_div_membase (p, X86_ESI, 4, 1); - - x86_mov_mem_reg (p, mem_addr, X86_EAX, 4); - x86_mov_mem_reg (p, mem_addr, X86_EAX, 2); - x86_mov_mem_reg (p, mem_addr, X86_EAX, 1); - x86_mov_membase_reg (p, X86_EBP, 4, X86_EAX, 1); - - x86_mov_regp_reg (p, X86_EAX, X86_EAX, 4); - x86_mov_membase_reg (p, X86_EAX, 0, X86_EAX, 4); - x86_mov_reg_membase (p, X86_EAX, X86_EAX, 0, 4); - x86_mov_reg_memindex (p, X86_ECX, X86_EAX, 34, X86_EDX, 2, 4); - x86_mov_reg_memindex (p, X86_ECX, X86_NOBASEREG, 34, X86_EDX, 2, 4); - x86_mov_memindex_reg (p, X86_EAX, X86_EAX, 0, X86_EDX, 2, 4); - x86_mov_reg_reg (p, X86_EAX, X86_EAX, 1); - x86_mov_reg_reg (p, X86_EAX, X86_EAX, 4); - x86_mov_reg_mem (p, X86_EAX, mem_addr, 4); - - x86_mov_reg_imm (p, X86_EAX, 10); - x86_mov_mem_imm (p, mem_addr, 54, 4); - x86_mov_mem_imm (p, mem_addr, 54, 1); - - x86_lea_mem (p, X86_EDX, mem_addr); - /* test widen */ - x86_widen_memindex (p, X86_EDX, X86_ECX, 0, X86_EBX, 2, 1, 0); - - x86_cdq (p); - x86_wait (p); - - x86_fp_op_mem (p, X86_FADD, mem_addr, 1); - x86_fp_op_mem (p, X86_FSUB, mem_addr, 0); - x86_fp_op (p, X86_FSUB, 2); - x86_fp_op_reg (p, X86_FMUL, 1, 0); - x86_fstp (p, 2); - x86_fcompp (p); - x86_fnstsw (p); - x86_fnstcw (p, mem_addr); - x86_fnstcw_membase (p, X86_ESP, -8); - - x86_fldcw_membase (p, X86_ESP, -8); - x86_fchs (p); - x86_frem (p); - x86_fxch (p, 3); - x86_fcomip (p, 3); - x86_fld_membase (p, X86_ESP, -8, 1); - x86_fld_membase (p, X86_ESP, -8, 0); - x86_fld80_membase (p, X86_ESP, -8); - x86_fild_membase (p, X86_ESP, -8, 1); - x86_fild_membase (p, X86_ESP, -8, 0); - x86_fld_reg (p, 4); - x86_fldz (p); - x86_fld1 (p); - - x86_fst (p, mem_addr, 1, 0); - x86_fst (p, mem_addr, 1, 1); - x86_fst (p, mem_addr, 0, 1); - - x86_fist_pop_membase (p, X86_EDX, 4, 1); - x86_fist_pop_membase (p, X86_EDX, 4, 0); - - x86_push_reg (p, X86_EBX); - x86_push_membase (p, X86_EBP, 8); - x86_push_imm (p, -1); - x86_pop_reg (p, X86_EBX); - - x86_pushad (p); - x86_pushfd (p); - x86_popfd (p); - x86_popad (p); - - target = p; - - start = p; - x86_jump32 (p, mem_addr); - x86_patch (start, target); - start = p; - x86_jump8 (p, 12); - x86_patch (start, target); - x86_jump_reg (p, X86_EAX); - x86_jump_membase (p, X86_EDX, 16); - - x86_jump_code (p, target); - - x86_branch8 (p, X86_CC_EQ, 54, 1); - x86_branch32 (p, X86_CC_LT, 54, 0); - x86_branch (p, X86_CC_GT, target, 0); - x86_branch_disp (p, X86_CC_NE, -4, 0); - - x86_set_reg (p, X86_CC_EQ, X86_EAX, 0); - x86_set_membase (p, X86_CC_LE, X86_EBP, -8, 0); - - x86_call_code (p, printf); - x86_call_reg (p, X86_ECX); - - x86_sahf (p); - - x86_fsin (p); - x86_fcos (p); - x86_fabs (p); - x86_fpatan (p); - x86_fprem (p); - x86_fprem1 (p); - x86_frndint (p); - x86_fsqrt (p); - x86_fptan (p); - - x86_leave (p); - x86_ret (p); - x86_ret_imm (p, 24); - - x86_cmov_reg (p, X86_CC_GT, 1, X86_EAX, X86_EDX); - x86_cmov_membase (p, X86_CC_GT, 0, X86_EAX, X86_EDX, -4); - - x86_nop (p); - x86_epilog (p, X86_CALLER_REGS); - - size = p-code; - for (i = 0; i < size; ++i) - printf (".byte %d\n", (unsigned int) code [i]); - return 0; -} diff --git a/mono/arch/x86/tramp.c b/mono/arch/x86/tramp.c deleted file mode 100644 index fab5a55325f..00000000000 --- a/mono/arch/x86/tramp.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - * Create trampolines to invoke arbitrary functions. - * - * Copyright (C) Ximian Inc. - * - * Authors: - * Paolo Molaro (lupus@ximian.com) - * Dietmar Maurer (dietmar@ximian.com) - * - */ - -#include "config.h" -#include -#include -#include "x86-codegen.h" -#include "mono/metadata/class.h" -#include "mono/metadata/tabledefs.h" -#include "mono/interpreter/interp.h" -#include "mono/metadata/appdomain.h" -#include "mono/metadata/marshal.h" - -/* - * The resulting function takes the form: - * void func (void (*callme)(), void *retval, void *this_obj, stackval *arguments); - */ -#define FUNC_ADDR_POS 8 -#define RETVAL_POS 12 -#define THIS_POS 16 -#define ARGP_POS 20 -#define LOC_POS -4 - -#define ARG_SIZE sizeof (stackval) - -MonoPIFunc -mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor) -{ - unsigned char *p, *code_buffer; - guint32 stack_size = 0, code_size = 50; - guint32 arg_pos, simpletype; - int i, stringp; - static GHashTable *cache = NULL; - MonoPIFunc res; - - if (!cache) - cache = g_hash_table_new ((GHashFunc)mono_signature_hash, - (GCompareFunc)mono_metadata_signature_equal); - - if ((res = (MonoPIFunc)g_hash_table_lookup (cache, sig))) - return res; - - if (sig->hasthis) { - stack_size += sizeof (gpointer); - code_size += 10; - } - - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref && !sig->ret->data.klass->enumtype) { - stack_size += sizeof (gpointer); - code_size += 5; - } - - for (i = 0; i < sig->param_count; ++i) { - if (sig->params [i]->byref) { - stack_size += sizeof (gpointer); - code_size += 20; - continue; - } - simpletype = sig->params [i]->type; -enum_calc_size: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - stack_size += 4; - code_size += i < 10 ? 5 : 8; - break; - case MONO_TYPE_VALUETYPE: { - int size; - if (sig->params [i]->data.klass->enumtype) { - simpletype = sig->params [i]->data.klass->enum_basetype->type; - goto enum_calc_size; - } - if ((size = mono_class_native_size (sig->params [i]->data.klass, NULL)) != 4) { - stack_size += size + 3; - stack_size &= ~3; - code_size += 32; - } else { - stack_size += 4; - code_size += i < 10 ? 5 : 8; - } - break; - } - case MONO_TYPE_I8: - stack_size += 8; - code_size += i < 10 ? 5 : 8; - break; - case MONO_TYPE_R4: - stack_size += 4; - code_size += i < 10 ? 10 : 13; - break; - case MONO_TYPE_R8: - stack_size += 8; - code_size += i < 10 ? 7 : 10; - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i]->type); - } - } - /* - * FIXME: take into account large return values. - */ - - code_buffer = p = alloca (code_size); - - /* - * Standard function prolog. - */ - x86_push_reg (p, X86_EBP); - x86_mov_reg_reg (p, X86_EBP, X86_ESP, 4); - /* - * and align to 16 byte boundary... - */ - stack_size += 15; - stack_size &= ~15; - - if (stack_size) - x86_alu_reg_imm (p, X86_SUB, X86_ESP, stack_size); - - /* - * EDX has the pointer to the args. - */ - x86_mov_reg_membase (p, X86_EDX, X86_EBP, ARGP_POS, 4); - - /* - * Push arguments in reverse order. - */ - stringp = 0; - for (i = sig->param_count; i; --i) { - arg_pos = ARG_SIZE * (i - 1); - if (sig->params [i - 1]->byref) { - x86_push_membase (p, X86_EDX, arg_pos); - continue; - } - simpletype = sig->params [i - 1]->type; -enum_marshal: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - x86_push_membase (p, X86_EDX, arg_pos); - break; - case MONO_TYPE_R4: - x86_alu_reg_imm (p, X86_SUB, X86_ESP, 4); - x86_fld_membase (p, X86_EDX, arg_pos, TRUE); - x86_fst_membase (p, X86_ESP, 0, FALSE, TRUE); - break; - case MONO_TYPE_CLASS: - x86_push_membase (p, X86_EDX, arg_pos); - break; - case MONO_TYPE_SZARRAY: - x86_push_membase (p, X86_EDX, arg_pos); - break; - case MONO_TYPE_VALUETYPE: - if (!sig->params [i - 1]->data.klass->enumtype) { - int size = mono_class_native_size (sig->params [i - 1]->data.klass, NULL); - if (size == 4) { - /* it's a structure that fits in 4 bytes, need to push the value pointed to */ - x86_mov_reg_membase (p, X86_EAX, X86_EDX, arg_pos, 4); - x86_push_regp (p, X86_EAX); - } else { - int ss = size; - ss += 3; - ss &= ~3; - - x86_alu_reg_imm (p, X86_SUB, X86_ESP, ss); - x86_push_imm (p, size); - x86_push_membase (p, X86_EDX, arg_pos); - x86_lea_membase (p, X86_EAX, X86_ESP, 2*4); - x86_push_reg (p, X86_EAX); - x86_mov_reg_imm (p, X86_EAX, memcpy); - x86_call_reg (p, X86_EAX); - x86_alu_reg_imm (p, X86_ADD, X86_ESP, 12); - /* memcpy might clobber EDX so restore it */ - x86_mov_reg_membase (p, X86_EDX, X86_EBP, ARGP_POS, 4); - } - } else { - /* it's an enum value */ - simpletype = sig->params [i - 1]->data.klass->enum_basetype->type; - goto enum_marshal; - } - break; - case MONO_TYPE_I8: - case MONO_TYPE_U8: - case MONO_TYPE_R8: - x86_push_membase (p, X86_EDX, arg_pos + 4); - x86_push_membase (p, X86_EDX, arg_pos); - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i - 1]->type); - } - } - - if (sig->hasthis) { - if (sig->call_convention != MONO_CALL_THISCALL) { - x86_mov_reg_membase (p, X86_EDX, X86_EBP, THIS_POS, 4); - x86_push_reg (p, X86_EDX); - } else { - x86_mov_reg_membase (p, X86_ECX, X86_EBP, THIS_POS, 4); - } - } - - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) { - MonoClass *klass = sig->ret->data.klass; - if (!klass->enumtype) { - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_push_membase (p, X86_ECX, 0); - } - } - - /* - * Insert call to function - */ - x86_mov_reg_membase (p, X86_EDX, X86_EBP, FUNC_ADDR_POS, 4); - x86_call_reg (p, X86_EDX); - - /* - * Handle retval. - * Small integer and pointer values are in EAX. - * Long integers are in EAX:EDX. - * FP values are on the FP stack. - */ - - if (sig->ret->byref || string_ctor) { - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4); - } else { - simpletype = sig->ret->type; - enum_retvalue: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_mov_regp_reg (p, X86_ECX, X86_EAX, 1); - break; - case MONO_TYPE_CHAR: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_mov_regp_reg (p, X86_ECX, X86_EAX, 2); - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4); - break; - case MONO_TYPE_STRING: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4); - break; - case MONO_TYPE_R4: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_fst_membase (p, X86_ECX, 0, FALSE, TRUE); - break; - case MONO_TYPE_R8: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_fst_membase (p, X86_ECX, 0, TRUE, TRUE); - break; - case MONO_TYPE_I8: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4); - x86_mov_membase_reg (p, X86_ECX, 4, X86_EDX, 4); - break; - case MONO_TYPE_VALUETYPE: - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - case MONO_TYPE_VOID: - break; - default: - g_error ("Can't handle as return value 0x%x", sig->ret->type); - } - } - - /* - * Standard epilog. - */ - x86_leave (p); - x86_ret (p); - - g_assert (p - code_buffer < code_size); - res = (MonoPIFunc)g_memdup (code_buffer, p - code_buffer); - - g_hash_table_insert (cache, sig, res); - - return res; -} - -#define MINV_POS (- sizeof (MonoInvocation)) -#define STACK_POS (MINV_POS - sizeof (stackval) * sig->param_count) -#define TYPE_OFFSET (G_STRUCT_OFFSET (stackval, type)) - -/* - * Returns a pointer to a native function that can be used to - * call the specified method. - * The function created will receive the arguments according - * to the call convention specified in the method. - * This function works by creating a MonoInvocation structure, - * filling the fields in and calling ves_exec_method on it. - * Still need to figure out how to handle the exception stuff - * across the managed/unmanaged boundary. - */ -void * -mono_arch_create_method_pointer (MonoMethod *method) -{ - MonoMethodSignature *sig; - MonoJitInfo *ji; - unsigned char *p, *code_buffer; - gint32 local_size; - gint32 stackval_pos, arg_pos = 8; - int i, size, align, cpos; - int *vtbuf; - - sig = method->signature; - - code_buffer = p = alloca (512); /* FIXME: check for overflows... */ - vtbuf = alloca (sizeof(int)*sig->param_count); - - local_size = sizeof (MonoInvocation) + sizeof (stackval) * (sig->param_count + 1); - - local_size += 7; - local_size &= ~7; - - stackval_pos = -local_size; - - cpos = 0; - for (i = 0; i < sig->param_count; i++) { - MonoType *type = sig->params [i]; - vtbuf [i] = -1; - if (type->type == MONO_TYPE_VALUETYPE) { - MonoClass *klass = type->data.klass; - if (klass->enumtype) - continue; - size = mono_class_native_size (klass, &align); - cpos += align - 1; - cpos &= ~(align - 1); - vtbuf [i] = cpos; - cpos += size; - } - } - - cpos += 7; - cpos &= ~7; - - local_size += cpos; - - /* - * Standard function prolog. - */ - x86_push_reg (p, X86_EBP); - x86_mov_reg_reg (p, X86_EBP, X86_ESP, 4); - x86_alu_reg_imm (p, X86_SUB, X86_ESP, local_size); - - /* - * Initialize MonoInvocation fields, first the ones known now. - */ - x86_mov_reg_imm (p, X86_EAX, 0); - x86_mov_membase_reg (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex)), X86_EAX, 4); - x86_mov_membase_reg (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex_handler)), X86_EAX, 4); - x86_mov_membase_reg (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, parent)), X86_EAX, 4); - /* - * Set the method pointer. - */ - x86_mov_membase_imm (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, method)), (int)method, 4); - - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref && !sig->ret->data.klass->enumtype) - arg_pos += 4; - - /* - * Handle this. - */ - if (sig->hasthis) { - if (sig->call_convention != MONO_CALL_THISCALL) { - /* - * Grab it from the stack, otherwise it's already in ECX. - */ - x86_mov_reg_membase (p, X86_ECX, X86_EBP, arg_pos, 4); - arg_pos += 4; - } - x86_mov_membase_reg (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, obj)), X86_ECX, 4); - } - /* - * Handle the arguments. stackval_pos is the posset of the stackval array from EBP. - * arg_pos is the offset from EBP to the incoming arg on the stack. - * We just call stackval_from_data to handle all the (nasty) issues.... - */ - x86_lea_membase (p, X86_EAX, X86_EBP, stackval_pos); - x86_mov_membase_reg (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, stack_args)), X86_EAX, 4); - for (i = 0; i < sig->param_count; ++i) { - if (vtbuf [i] >= 0) { - x86_lea_membase (p, X86_EAX, X86_EBP, - local_size + vtbuf [i]); - x86_mov_membase_reg (p, X86_EBP, stackval_pos, X86_EAX, 4); - } - x86_mov_reg_imm (p, X86_ECX, stackval_from_data); - x86_lea_membase (p, X86_EDX, X86_EBP, arg_pos); - x86_lea_membase (p, X86_EAX, X86_EBP, stackval_pos); - x86_push_imm (p, sig->pinvoke); - x86_push_reg (p, X86_EDX); - x86_push_reg (p, X86_EAX); - x86_push_imm (p, sig->params [i]); - x86_call_reg (p, X86_ECX); - x86_alu_reg_imm (p, X86_SUB, X86_ESP, 16); - stackval_pos += sizeof (stackval); - /* fixme: alignment */ - if (sig->pinvoke) - arg_pos += mono_type_native_stack_size (sig->params [i], &align); - else - arg_pos += mono_type_stack_size (sig->params [i], &align); - } - - /* - * Handle the return value storage area. - */ - x86_lea_membase (p, X86_EAX, X86_EBP, stackval_pos); - x86_mov_membase_reg (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, retval)), X86_EAX, 4); - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) { - MonoClass *klass = sig->ret->data.klass; - if (!klass->enumtype) { - x86_mov_reg_membase (p, X86_ECX, X86_EBP, 8, 4); - x86_mov_membase_reg (p, X86_EBP, stackval_pos, X86_ECX, 4); - } - } - - /* - * Call the method. - */ - x86_lea_membase (p, X86_EAX, X86_EBP, MINV_POS); - x86_push_reg (p, X86_EAX); - x86_mov_reg_imm (p, X86_EDX, ves_exec_method); - x86_call_reg (p, X86_EDX); - - /* - * Move the return value to the proper place. - */ - x86_lea_membase (p, X86_EAX, X86_EBP, stackval_pos); - if (sig->ret->byref) { - x86_mov_reg_membase (p, X86_EAX, X86_EAX, 0, 4); - } else { - int simpletype = sig->ret->type; - enum_retvalue: - switch (sig->ret->type) { - case MONO_TYPE_VOID: - break; - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - x86_mov_reg_membase (p, X86_EAX, X86_EAX, 0, 1); - break; - case MONO_TYPE_CHAR: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - x86_mov_reg_membase (p, X86_EAX, X86_EAX, 0, 2); - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_CLASS: - x86_mov_reg_membase (p, X86_EAX, X86_EAX, 0, 4); - break; - case MONO_TYPE_I8: - x86_mov_reg_membase (p, X86_EDX, X86_EAX, 4, 4); - x86_mov_reg_membase (p, X86_EAX, X86_EAX, 0, 4); - break; - case MONO_TYPE_R8: - x86_fld_membase (p, X86_EAX, 0, TRUE); - break; - case MONO_TYPE_VALUETYPE: - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - - x86_push_imm (p, sig->pinvoke); - x86_push_membase (p, X86_EBP, stackval_pos); - x86_push_reg (p, X86_EAX); - x86_push_imm (p, sig->ret); - x86_mov_reg_imm (p, X86_ECX, stackval_to_data); - x86_call_reg (p, X86_ECX); - x86_alu_reg_imm (p, X86_SUB, X86_ESP, 16); - - break; - default: - g_error ("Type 0x%x not handled yet in thunk creation", sig->ret->type); - break; - } - } - - /* - * Standard epilog. - */ - x86_leave (p); - x86_ret (p); - - g_assert (p - code_buffer < 512); - - ji = g_new0 (MonoJitInfo, 1); - ji->method = method; - ji->code_size = p - code_buffer; - ji->code_start = g_memdup (code_buffer, p - code_buffer); - - mono_jit_info_table_add (mono_get_root_domain (), ji); - - return ji->code_start; -} diff --git a/mono/dis/dump.c b/mono/dis/dump.c index 2b3a4851de0..391ec7fbc77 100755 --- a/mono/dis/dump.c +++ b/mono/dis/dump.c @@ -566,6 +566,7 @@ dump_table_method (MonoImage *m) current_type = 1; last_m = first_m = 1; for (i = 1; i <= t->rows; i++){ + MonoError error; guint32 cols [MONO_METHOD_SIZE]; char *sig, *impl_flags; const char *sigblob; @@ -583,13 +584,17 @@ dump_table_method (MonoImage *m) mono_metadata_string_heap (m, mono_metadata_decode_row_col (td, current_type - 2, MONO_TYPEDEF_NAME))); first_m = last_m; type_container = mono_metadata_load_generic_params (m, MONO_TOKEN_TYPE_DEF | (current_type - 1), NULL); - if (type_container) - mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_TYPE_DEF | (current_type - 1), type_container); + if (type_container) { + mono_metadata_load_generic_param_constraints_checked (m, MONO_TOKEN_TYPE_DEF | (current_type - 1), type_container, &error); + g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/ + } } method_container = mono_metadata_load_generic_params (m, MONO_TOKEN_METHOD_DEF | i, type_container); - if (method_container) - mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_METHOD_DEF | i, method_container); + if (method_container) { + mono_metadata_load_generic_param_constraints_checked (m, MONO_TOKEN_METHOD_DEF | i, method_container, &error); + g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/ + } mono_metadata_decode_table_row (m, MONO_TABLE_METHOD, i - 1, cols, MONO_METHOD_SIZE); sigblob = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]); mono_metadata_decode_blob_size (sigblob, &sigblob); diff --git a/mono/dis/get.c b/mono/dis/get.c index 34f87b0c8ad..a3f2e7b9cac 100755 --- a/mono/dis/get.c +++ b/mono/dis/get.c @@ -889,11 +889,14 @@ dis_stringify_method_signature_full (MonoImage *m, MonoMethodSignature *method, method_name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]); param_index = cols [MONO_METHOD_PARAMLIST]; if (!method) { + MonoError error; const char *sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]); container = mono_metadata_load_generic_params (m, MONO_TOKEN_METHOD_DEF | methoddef_row, container); - if (container) - mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_METHOD_DEF | methoddef_row, container); + if (container) { + mono_metadata_load_generic_param_constraints_checked (m, MONO_TOKEN_METHOD_DEF | methoddef_row, container, &error); + g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/ + } mono_metadata_decode_blob_size (sig, &sig); method = mono_metadata_parse_method_signature_full (m, container, methoddef_row, sig, &sig); diff --git a/mono/dis/main.c b/mono/dis/main.c index 42d735b0f75..b56da24c35a 100644 --- a/mono/dis/main.c +++ b/mono/dis/main.c @@ -854,10 +854,13 @@ dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 en mono_metadata_decode_blob_size (sig, &sig); container = mono_metadata_load_generic_params (m, MONO_TOKEN_METHOD_DEF | (i + 1), type_container); - if (container) - mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_METHOD_DEF | (i + 1), container); - else + if (container) { + MonoError error; + mono_metadata_load_generic_param_constraints_checked (m, MONO_TOKEN_METHOD_DEF | (i + 1), container, &error); + g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/ + } else { container = type_container; + } ms = mono_metadata_parse_method_signature_full (m, container, i + 1, sig, &sig); if (ms != NULL){ @@ -1181,8 +1184,11 @@ dis_type (MonoImage *m, int n, int is_nested, int forward) } container = mono_metadata_load_generic_params (m, MONO_TOKEN_TYPE_DEF | (n + 1), NULL); - if (container) - mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_TYPE_DEF | (n + 1), container); + if (container) { + MonoError error; + mono_metadata_load_generic_param_constraints_checked (m, MONO_TOKEN_TYPE_DEF | (n + 1), container, &error); + g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/ + } esname = get_escaped_name (name); if ((cols [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_CLASS_SEMANTIC_MASK) == TYPE_ATTRIBUTE_CLASS){ diff --git a/mono/interpreter/.gitignore b/mono/interpreter/.gitignore deleted file mode 100644 index 58fbb5d6ab6..00000000000 --- a/mono/interpreter/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -/Makefile -/Makefile.in -/mint -/*.o -/.libs -/.deps -/interp.lo -/libmint.la -/*.lo -/semantic.cache -/TAGS diff --git a/mono/interpreter/ChangeLog b/mono/interpreter/ChangeLog deleted file mode 100644 index 80baebfc261..00000000000 --- a/mono/interpreter/ChangeLog +++ /dev/null @@ -1,1376 +0,0 @@ -2009-11-10 Andrew Jorgensen - - * Makefile.am: mint man page should be conditional also - -2009-03-20 Zoltan Varga - - * interp.c: Change location of gc_wrapper.h. - -2007-06-04 Mark Probst - - * interp.c, interp.h (RuntimeMethod): Due to the jit_code_hash - change in MonoDomain this had to be changed slightly, too. - -2006-05-09 Miguel de Icaza - - * interp.c (ves_exec_method_with_context): Pass a temporary to the - mono_load_remote_field routine, instead of passing a NULL. - -Thu Aug 4 20:09:40 BST 2005 Paolo Molaro - - * interp.c: a real zombie is supposed to at least walk. - Compilation fix. - -2005-03-07 Zoltan Varga - - * transform.c (generate): Add CEE_MONO_NOT_TAKEN. - -2005-01-31 Bernie Solomon - - * interp.c: fix typo - -2005-01-29 Ben Maurer - - * *: MonoMethod->signature might be NULL now. You *MUST* use - mono_method_signature. - -2005-01-20 Bernie Solomon - - * interp.c: mono_init_icall got renamed - -2005-01-03 Zoltan Varga - - * transform.c (generate): Handle MONO_CLASSCONST. - -2004-12-04 Gonzalo Paniagua Javier - - * interp.c: fix the build. Dunno if it's correct. - -2004-12-02 Bernie Solomon - - * mintops.def: - * transform.c: - * interp.c: cope with new thread interruption icall - -2004-11-12 Ben Maurer - - * transform.c: Fix bug with delegates in interp. - -2004-11-10 Lluis Sanchez Gual - - * interp.c: Added MonoRemotingTarget parameter to signature - interp_create_remoting_trampoline. - -Tue Nov 9 17:28:48 CET 2004 Paolo Molaro - - * interp.c: update to exception clause structure changes. - -2004-11-08 Ben Maurer - - * interp.c: warning free - -2004-10-29 Zoltan Varga - - * Makefile.am (libgc_libs): Do some automake magic so libmono/mono - depends on libmonogc. - -Wed Sep 22 19:06:02 CEST 2004 Paolo Molaro - - * interp.c: updates for stack walk interface. - -2004-09-09 Lluis Sanchez Gual - - * interp.c: In interp_walk_stack, don't crash if the context is not set - (this may happen if the method is called by unmanaged code). - -2004-08-17 Ben Maurer - - * interp.c: thread local alloc - -2004-08-05 Bernie Solomon - - * interp.c: (mono_interp_init) use g_thread_supported - to stop multiple g_thread_init calls. - Also attach domain to thread like mono_jit_init - -2004-07-31 Bernie Solomon - - * interp.h: add mono_interp_ftnptr_to_delegate - - * transform.c (generate): use mono_interp_ftnptr_to_delegate - as ical function. - - * interp.c: add mono_interp_ftnptr_to_delegate to create - interpreter style delegate. fixes pinvoke3 - -2004-07-28 Lluis Sanchez Gual - - * interp.c: Use mono_init_from_assembly instead of mono_init. - -2004-07-27 Bernie Solomon - - * transform.c (mono_interp_transform_method): - quick fix to cope with the fake ptr classes - -2004-07-26 Bernie Solomon - - * mintops.def: more options on ICALL op code - - * interp.c: cope with exception in ICALL ops, more of them - - * transforms.c: more ICALL opcodes - -2004-07-21 Bernie Solomon - - * mintops.def: rename the ICALL op codes to give a better - clue about their signature. - - * transform.c (generate): use new ICALL types and add - a case for two args + a result - - * interp.c (ves_exec_method_with_context): new ICALL - op codes. - -2004-07-21 Bernie Solomon - - * mintops.def: add MINT_DUP_VT - - * transform.c (generate): cope with CEE_DUP on value type - - * interp.c (ves_exec_method_with_context): implement MINT_DUP_VT - (interp_mono_runtime_invoke): don't unbox this for valuetypes - here as it is now done in the callers. - -2004-07-09 Ben Maurer - - * interp.c: register gc roots - -2004-07-08 Zoltan Varga - - * interp.c mintops.def transform.c: Replace CEE_MONO_PROC with - CEE_MONO_ICALL. - -2004-07-05 Zoltan Varga - - * mintops.h: Applied patch from Marcin Krzyzanowski (krzak@pld-linux.org). Add support for unaligned access on little endian machines. - - * interp.c:Applied patch from Marcin Krzyzanowski (krzak@pld-linux.org). Fix crash seen on amd64. - -2004-06-24 David Waite - - * interp.c: change to C90-style comments from C99/C++-style - -Mon Jun 21 14:06:03 CEST 2004 Paolo Molaro - - * interp.h: API updates. - -2004-05-21 Bernie Solomon - - * transform.c: ignore new LMF opcodes - -2004-05-20 Lluis Sanchez Gual - - * interp.c, interp.h: Use the new methods for handling thread.abort. - -2004-05-04 Zoltan Varga - - * interp.c (ves_exec_method_with_context): Disable explicit assignment - of 'esi' to the ip variable, since it causes register allocation errors - on some versions of gcc. Fixes #58010. - -2004-04-29 Bernie Solomon - - * transform.c (generate): missed a couple - of places that should use ADD_CODE so buffer - gets grown properly. - - * interp.c (interp_mono_runtime_invoke): - restore state better on catching exception - via longjmp here - -2004-04-29 Bernie Solomon - - * transform.c: - * interp.c: - Implement STARG for valuetypes as mcs needs it. - -2004-04-28 Bernie Solomon - - * transform.c: Make sure ENSURE_I4 is called on - 32 bit machines too. - (mono_interp_transform_method): allow some stack - space for tracing to work. - -2004-04-26 David Waite - - * interp.h: remove comma from end of enumeration constants - declarations - -2004-04-21 Bernie Solomon - - * interp.h: put in space for old type field - for PPC as tramp.c assumes it. Quick fix until that's fixed. - - * interp.c: reenable instruction tracing for DEBUG_INTERP - -2004-04-19 Bernie Solomon - - * Makefile.am: - * interp.h: - * interp.c: now interprets different VM code - * mintops.h: - * mintops.def: - * mintops.c: definition of new VM code - * transform.c: convert CIL to new VM code - -2004-04-14 Zoltan Varga - - * interp.c (ves_exec_method_with_context): Add support for STRWLPARRAY - marshalling convention. - -2004-03-29 Bernie Solomon - - * interp.c interp.h: remove child from MonoInvocation - as it isn't used. - -2004-03-25 Martin Baulig - - * interp.c (stackval_from_data): Added MONO_TYPE_GENERICINST. - (stackval_to_data): Added MONO_TYPE_GENERICINST. - (calc_offsets): Use mono_class_get_full() and mono_get_method_full(). - (ves_exec_method_with_context): Likewise. - -2004-03-04 Lluis Sanchez Gual - - * interp.c: Get the type of transparent proxies from its remote_class. - -2004-02-02 Zoltan Varga - - * interp.c (ves_exec_method_with_context): Add new marshalling - conventions. - -2004-01-22 Zoltan Varga - - * interp.c (mono_main): Remove call to mono_verify_corlib (), since - the verification code is not up-to-date. - -2004-01-19 Bernie Solomon - - * interp.c (ves_exec_method_with_context): - get_native_wrapper removed and call - mono_marshal_get_native_wrapper directly - with new DllNotFoundException handling - -Mon Jan 19 17:52:33 CET 2004 Paolo Molaro - - * interp.c: eliminate CSIZE macro. - -2004-01-15 Zoltan Varga - - * interp.c (ves_array_set): Check for ArrayTypeMismatchException. - -2004-01-12 Gonzalo Paniagua Javier - - * interp.c: call setlocale (). Fixes bug #52100. - -2003-12-19 Bernie Solomon - - * embed.h, main.c: new files to enable embedding - the interpreter - - * interp.c: make main callable from main.c - rearrange main for embedding - - * Makefile.am: changes now most code is in a library - -2003-11-21 Lluis Sanchez Gual - - * interp.c: Added support for context static fields. - -2003-10-31 Zoltan Varga - - * interp.c (mono_create_method_pointer): New function which contains - the arch independent part of method wrapper creation. Add a cache - for the wrapper code, since Delegate::Equals depends on the wrapper - address being constant for a method. Fixes #50366. - -2003-10-30 Bernie Solomon - - * interp.c: (ves_exec_method_with_context) - we need to lookup internal calls now. - don't free type in CEE_SIZEOF. - fix CEE_NEWOBJ inside wrapper methods - -2003-10-24 Zoltan Varga - - * interp.c: Update after appdomain changes. - -2003-10-13 Bernie Solomon - - * interp.c - set large stack size on HP 64bit - -2003-10-02 Bernie Solomon - - * hacks.h - work round HP 64 bit problem with isunordered - -2003-10-03 Zoltan Varga - - * interp.c (dump_frame): Avoid crash on frames without a method. Patch - sam@superduper.net (sam clegg). Fixes #46197. - (ves_exec_method_with_context): Fix unbox casting. - -2003-09-25 Bernie Solomon - - * interp.c - reinstate use of mono_marshal_get_delegate_invoke - for ordering and fix CALLI to handle wrapper. More wrapper handling - in CALL and LDSTR. Add another string conversion case. - -2003-09-25 Zoltan Varga - - * interp.c (ves_exec_method): Fix warning. - (ves_exec_method_with_context): Fix CGT_UN and CLT_UN. Patch by - David Waite (mass@akuma.org). - -2003-9-24 Bernie Solomon - - * interp.c: I broke calling native delegates reinstate - old code for the moment. - -2003-9-22 Bernie Solomon - - * interp.c: use mono_marshal_get_delegate_invoke to get delegate - invocation order consistent. Fix THROW_EX, fix ip in overflow - exceptions. - -Fri Sep 12 10:42:08 CEST 2003 Paolo Molaro - - * interp.c, interp.h: patch from Bernie Solomon : - 64 bit/opcodes/exception handling fixes. - -2003-08-30 Zoltan Varga - - * interp.c: Use mono_field_from_token () in the appropriate places. - This simplifies the code and also fixes #48051. - -2003-08-27 Zoltan Varga - - * interp.c (main): Fix the order of initialization calls so it maches - the order in the JIT.Patch by Bernie Solomon (bernard@ugsolutions.com). - Also remove the unused ms mutex. - - * interp.c: Get rid of metadata_section. - -2003-08-22 Zoltan Varga - - * interp.c (main): Call g_thread_init () to make glib thread-safe. - Fixes #47682. Thanks to Laurent Morichetti (l_m@pacbell.net) for - reporting this. - -2003-08-18 Zoltan Varga - - * interp.c: Get rid of duplicate definition of CHECK_MUL_OVERFLOW. - * interp.h interp.c: Get rid of VAL_VALUETA, use VAL_MP instead. Fix - the INITOBJ opcode which was the only user of VALUETA. - -2003-08-16 Zoltan Varga - - * interp.c (ves_exec_method): Implemented mul.ovf correctly for int32 - and int64. Implement the conv.ovf opcodes for all argument types. - -2003-08-15 Zoltan Varga - - * interp.c (ves_exec_method): Handle non-valuetypes in CEE_STOBJ. - Fixes #46781. - (ves_exec_method): Added support for the synchronized flag to the - interpreter. Also fixed the CALLI opcode, and made exception handling - work though the managed-unmanaged barrier. - -Fri Jul 25 19:06:27 CEST 2003 Paolo Molaro - - * interp.c: updates for new instructions. - -2003-07-22 Zoltan Varga - - * interp.c: Use the new metadata_section lock instead of metadata_lock. - Patch by Bernie Solomon (bernard@ugsolutions.com). - -Fri Jul 18 15:11:44 CEST 2003 Paolo Molaro - - * interp.c: 64 bit fixes from Laurent Morichetti . - Install cleanup function. - -2003-07-13 Zoltan Varga - - * interp.c: Keep alloca()-d data on a free list to prevent stack - overflow errors when valuetypes are allocated in a loop. Fixes - #27420. Is the new code still faster than using malloc/free ? - - * interp.c (ves_array_get): Add index checking to ves_array_get/set. - Fixes decimal-array.exe. - - * interp.c (interp_mono_runtime_invoke): Unbox value type instances - before calling the method. Fixes appdomain2.exe. - - * interp.c: Fix warnings. - - * interp.c: Report unhandled exceptions correctly. - - * interp.c: Implement CEE_ISINST and CEE_CASTCLASS using - mono_object_isinst. Fixes bug #45539 and reflection-enum.exe. - -Tue May 27 16:36:41 CEST 2003 Paolo Molaro - - * interp.c: don't use relative numbering stuff. - -Tue May 27 12:18:44 CEST 2003 Paolo Molaro - - * interp.c: update for mono_class_vtable() changes. - -Tue May 13 16:43:18 CEST 2003 Paolo Molaro - - * interp.c: handle thread static fields. - -Sun Apr 27 13:27:59 CEST 2003 Paolo Molaro - - * interp.c: check for arraytypemismatch. - -2003-04-23 Martin Baulig - - * interp.c: When running with --dieonex, use the debugging code to - print source lines in the backtrace. - -2003-02-09 Gonzalo Paniagua Javier - - * interp.c: added a dummy mono_runtime_install_handlers function to - avoid crashing when ves_pinvoke_method tries to call it. - -2003-02-06 Piers Haken - - * interp.c: warning cleanups - -2002-11-15 Dick Porter - - * interp.c: mono_runtime_init() now has an extra parameter for - thread attaching. - -2002-10-31 Dick Porter - - * Makefile.am: The previous automake-1.6 fix broke automake-1.4 on - cygwin. Try again. - -2002-09-27 Dick Porter - - * interp.c: Tell glib what the program name is, by passing it the - name of the managed file we're executing - -2002-08-28 Dick Porter - - * interp.c: mono_set_rootdir() doesnt take any args now - - * Makefile.am: Export HOST_CC and turn on optimisation for w32 builds - -2002-08-28 Nick Drochak - - * interp.c: check and throw exception if needed for overflow on - multiplication of integer types. - -2002-08-07 Dietmar Maurer - - * interp.c (interp_walk_stack): removed the createdelegate icall - -2002-08-02 Dietmar Maurer - - * interp.c (get_virtual_method): support proxies - (ves_exec_method): impl. LDFLD/STFLD for proxies. - -Fri Aug 2 13:00:41 CEST 2002 Paolo Molaro - - * interp.c, interp.h: implemented exception trap for runtime_invoke - and handle exceptions across managed/unmanaged boundaries. - -2002-08-01 Dietmar Maurer - - * interp.c (stackval_from_data): add pinvoke argument - (stackval_to_data): add pinvoke argument. We need consider the - fact that unmanages structures may have different sizes. - (ves_pinvoke_method): do not call stackval_from_data if the result - is a value type. - -Wed Jul 31 17:47:11 CEST 2002 Paolo Molaro - - * interp.c: simplified some more branch code. - -Wed Jul 31 16:50:42 CEST 2002 Paolo Molaro - - * interp.c: fixed indentation, simplified some code. - -Wed Jul 31 14:29:43 CEST 2002 Paolo Molaro - - * interp.c: fix so that mint can at least get to executing Main(). - -2002-07-31 Dietmar Maurer - - * interp.c: use the new marshaling code. better delegate/remoting - support. - (ves_exec_method): bug fix - directly jump to handle_exception. - -2002-07-29 Dietmar Maurer - - * interp.c (main): install compile_method handler - -Wed Jul 24 13:02:12 CEST 2002 Paolo Molaro - - * interp.c: implemented stack walking function. - -Fri Jul 19 14:21:18 CEST 2002 Paolo Molaro - - * interp.c: fix float boxing on LE systems. - -Sat Jul 13 19:54:56 CEST 2002 Paolo Molaro - - * interp.c: advance ip in conv.r.un. - -2002-07-01 Dick Porter - - * interp.c (ves_exec): Removed unneeded argument to - mono_runtime_run_main() - -2002-06-25 Dick Porter - - * interp.c (ves_exec): Pass the assembly to mono_runtime_run_main - -Wed Jun 19 17:01:37 CEST 2002 Paolo Molaro - - * interp.c: un-broke after stack trace changes. - -Fri May 31 16:17:20 CEST 2002 Paolo Molaro - - * interp.c, hacks.h: compiler compatibility fixes. - -Fri May 31 13:25:57 CEST 2002 Paolo Molaro - - * interp.c, mint.1: added --config command line option. - -Thu May 30 14:14:16 CEST 2002 Paolo Molaro - - * interp.c: lookup P/Invoke method addr only when needed. - -2002-05-29 Dietmar Maurer - - * interp.c (ves_exec_method): free type in CEE_SIZEOF - -Tue May 28 16:10:49 CEST 2002 Paolo Molaro - - * interp.c: fixed SIZEOF to work with typedef/typeref. - -Fri May 24 15:33:50 CEST 2002 Paolo Molaro - - * interp.c: added partial async delegate and remoting support. - -Thu May 23 18:45:38 CEST 2002 Paolo Molaro - - * interp.c: special case string ctors in invoke. - Handle null object in throw. Misc integer type mismatch fixes. - -2002-05-23 Dietmar Maurer - - * interp.c (ves_runtime_method): share more code with the jit. - -Wed May 22 12:31:40 CEST 2002 Paolo Molaro - - * interp.c: fixed finally handling. In trace mode show - exception handling operations and the contents of the stack in the same - line as the executing instruction. - -2002-05-20 Miguel de Icaza - - * interp.c: Updated help display. - -2002-05-20 Radek Doulik - - * interp.c (dump_stack): print boxed values for --noptr - (ves_exec_method): use stackval_to_data as pointed out by lupus - -2002-05-17 Radek Doulik - - * interp.c (dump_stack): if --noptr then print content of strings - in form [str:] - -2002-05-16 Radek Doulik - - * interp.c (ves_exec_method): use data.i instead of data.l in i32 - case - (ves_exec_method): set type in I64 <--> I32 conversions - -2002-05-15 Radek Doulik - - * interp.c (ves_runtime_method): moved stackval_from_data call - inside #else branch, consulted on irc with lupus - -2002-05-15 Dietmar Maurer - - * interp.c (ves_exec_method): use new mono_unhandled_exception() - -2002-05-14 Radek Doulik - - * interp.c: introduced new --noptr option to suppres pointer - address printing. I find this useful for comparing trace outputs - while porting to ppc - -Tue May 14 16:37:55 CEST 2002 Paolo Molaro - - * interp.c: some finally handling fixes and compilation fixes for - changes in the runtime lib. - -2002-04-30 Dick Porter - - * interp.c: Tell glib to not abort when g_log() etc print - recursively - -Mon Apr 22 16:52:03 CEST 2002 Paolo Molaro - - * interp.c: handle muslticast delegates. Implement a couple more - convert opcodes. Pretend we spend some time jitting... - -2002-04-20 Dietmar Maurer - - * interp.c (ves_exec_method): support internalcall String constructors - -2002-04-19 Dan Lewis - - * interp.c: support for new szarray format. - -Tue Apr 16 20:12:58 CEST 2002 Paolo Molaro - - * interp.c: removed profiling code (moved to common library). - Implemented inlining for some special methods. - -2002-04-15 Patrik Torstensson - - * interp.c: Using fullnames when adding icall's (array) - -Wed Apr 10 16:07:23 CEST 2002 Paolo Molaro - - * interp.c: quick implementation for opcodes needed by the new parse - routines in corlib. - -Tue Apr 9 13:08:26 CEST 2002 Paolo Molaro - - * interp.c: make the interp thread-safe wrt the metadata lib. - -Mon Apr 8 17:15:48 CEST 2002 Paolo Molaro - - * interp.c: display return value with --trace. - Call mono_runtime_init (). - -2002-04-06 Dietmar Maurer - - * interp.c (interp_mono_runtime_invoke): handle more types, - removed runtime_exec_main - -Thu Apr 4 11:36:52 CEST 2002 Paolo Molaro - - * interp.c: don't try to get an IL opcode for runtime and internal - call methods. - -Thu Mar 28 16:54:51 CET 2002 Paolo Molaro - - * interp.c: spring warning cleanup. - -Thu Mar 28 12:03:28 CET 2002 Paolo Molaro - - * interp.c: check obj address in stfld. - -2002-03-27 Dietmar Maurer - - * interp.c (ves_exec_method): CASTCLASS: fix for transparent proxy - -Tue Mar 26 20:09:10 CET 2002 Paolo Molaro - - * interp.c: set frame->ip before dumping the stack trace. - -Tue Mar 26 19:54:45 CET 2002 Paolo Molaro - - * interp.c: remove glib mem vtable code. - -2002-03-26 Dick Porter - - * interp.c: Show thread ID's in trace output. - - New option "--traceclassinit" to put debug output around - runtime_class_init(). - - Make sure all options are displayed in usage(). - -Tue Mar 26 17:03:14 CET 2002 Paolo Molaro - - * interp.c: support fieldrefs when accessing instance fields. - -Mon Mar 25 12:59:52 CET 2002 Paolo Molaro - - * interp.c: allow tracing to be done on a per-method basis. - Fix interp_mono_runtime_invoke() to deal correcttly with the return - value. Disable glib mem vtable setting. - -Thu Mar 21 18:08:37 CET 2002 Paolo Molaro - - * interp.c: set stack trace info when throwing an exception. - -Thu Mar 21 17:32:46 CET 2002 Paolo Molaro - - * interp.c: intern strings before executing a method (and don't - intern command line arguments anymore). Add sanity checks in alloca - use. - -Sat Mar 16 19:15:18 CET 2002 Paolo Molaro - - * interp.c: restore frame on return from unmanaged calls. - Add support for continuing execution up to x IL insn. - Fix exception handling when an exception is raised in the catch - handler of the same method that issued the first one. - -2002-03-11 Dietmar Maurer - - * interp.c (ves_runtime_method): set method_info field - -Mon Mar 11 14:48:07 CET 2002 Paolo Molaro - - * interp.c: corlib consistency checls moved to libmetadata. - -Mon Mar 11 11:27:27 CET 2002 Paolo Molaro - - * interp.c: use the new facilities in debug-helpers to - disassemble CIL code and match method names to MonoMethods. - -Thu Mar 7 17:20:59 CET 2002 Paolo Molaro - - * interp.c: Boehm-GC enable. Fix some overflow opcodes. - -Tue Mar 5 18:12:40 CET 2002 Paolo Molaro - - * interp.c: fix non-debug build and some more opcode work. - -Mon Mar 4 11:21:44 CET 2002 Paolo Molaro - - * interp.c: print the address of 'this' in tracing mode. - -Thu Feb 28 19:18:59 CET 2002 Paolo Molaro - - * interp.c: add checks for more binary consistency. - -2002-02-27 Dietmar Maurer - - * interp.c (interp_mono_runtime_invoke): use alloca instead of g_new0 - -Tue Feb 26 11:43:34 CET 2002 Paolo Molaro - - * interp.c: added profiling for object creation. - -Mon Feb 25 17:37:07 CET 2002 Paolo Molaro - - * interp.c: use correct value for guint64 max. - -2002-02-22 Radek Doulik - - * interp.c: s/gulong/guint64 as it differs on ppc - -Wed Feb 20 22:18:40 CET 2002 Paolo Molaro - - * interp.c: more complete runtime_invoke () implementation. - Fixed castclass/isinst to work correctly with arrays. - -Tue Feb 19 20:21:14 CET 2002 Paolo Molaro - - * interp.c: implement the runtime_invoke function. - -Mon Feb 18 15:49:20 CET 2002 Paolo Molaro - - * interp.c: fix alignment code. Make sure to init classes - in more cases. Command-line arguments are interned. - -2002-02-16 Radek Doulik - - * interp.c (ves_exec_method): test type of sp [-1] instead of sp - [0], because sp [-1] is the value going to be shifted, fixed in - CEE_SHL, CEE_SHR, CEE_UN opcodes) - -Sat Feb 16 12:00:24 CET 2002 Paolo Molaro - - * interp.c: fixed cut&paste error for ldind.r4 and ldind.r8. - -Fri Feb 15 15:07:27 CET 2002 Paolo Molaro - - * interp.c: use strrchr instead of rindex. use _isnan and _finite on - win32 systems. - -2002-02-14 Jeffrey Stedfast - - * interp.c (ves_exec_method): replace - 'g_assert (sp->type = VAL_VALUETA)' with - 'g_assert (sp->type == VAL_VALUETA)' otherwise - the assert always passes. FIXME: should the test have been !=? - -2002-02-14 Dietmar Maurer - - * interp.c (stackval_from_data): fix for MONO_TYPE_PTR - -Wed Feb 13 16:17:38 CET 2002 Paolo Molaro - - * interp.c: fixed newobj implementation for valuetypes bug found by - dietmar. sub.ovf dummy code. - -Tue Feb 12 14:08:47 CET 2002 Paolo Molaro - - * hacks.h: check against redefining preprocessor symbol. - * interp.c: fix profile info to return more sensible results. - -Mon Feb 11 13:05:29 CET 2002 Paolo Molaro - - * interp.c: added "die on exception" command line argument. - When we segfault, set the message in the exception to "Segmentation - fault" so people can recognise what's going on. - -2002-02-10 Miguel de Icaza - - * interp.c (ves_exec_method): Compare the element_class type token - in the class we got as well, instead of the element class vs the - toplevel class. - - This fixes the invalid cast exceptions during unboxing - -Fri Feb 8 13:01:03 CET 2002 Paolo Molaro - - * interp.c: use opcode information from libmetadata. - -2002-02-05 Dietmar Maurer - - * interp.c (ves_exec_method): CEE_UNBOX: use element_class for - type check. - -2002-02-04 Dietmar Maurer - - * interp.c (main): impl. __array_Address icall - -Fri Feb 1 16:03:53 CET 2002 Paolo Molaro - - * interp.c: exception fixes. Use mono_method_pointer_get () - to easy porting to other archs. Some support for overflow detection. - -2002-01-25 Dietmar Maurer - - * interp.c, jit.c (main): install runtime_exec_main handler - (main): bug fix - call TlsAlloc () before we execute code - -2002-01-23 Dick Porter - - * interp.c: Added some kludges to cope with CONV_OVF_I2, - CONV_OVF_I4 and ADD_OVF so that number formatting works. Also - initialise and cleanup the network support. - -Thu Jan 10 20:59:59 CET 2002 Paolo Molaro - - * interp.c, interp.h: add a flag to mono_create_trampoline () - to handle runtime methods. - -Sat Jan 5 15:45:14 CET 2002 Paolo Molaro - - * interp.c: allow classname:method name in --debug argument. - Fix box opcode for valuetypes. Fix a few opcode to take a 16 bit - index instead of 32 (stloc, ldloc, starg, etc.). - -Thu Jan 3 23:19:27 CET 2002 Paolo Molaro - - * interp.c: temporary mul.ovf, mul.ovf.un, add.ovf.un implementations - to get the compiler going. - -Mon Dec 24 17:23:45 CET 2001 Paolo Molaro - - * interp.c: fix ldc.i8. - -Thu Dec 20 20:09:48 CET 2001 Paolo Molaro - - * interp.c: fix delegate method invocation to handle both - static and instance methods. - -Tue Dec 18 18:48:50 CET 2001 Paolo Molaro - - * interp.c: make segv_handler static, handle runtime methods in stack - trace. - -Thu Dec 13 20:24:28 CET 2001 Paolo Molaro - - * interp.c: correctly handle exceptions generated in C code. - Install an handler for SIGSEGV. Bare-bones profiler and hook for the - verifier. - -Mon Dec 3 17:15:44 CET 2001 Paolo Molaro - - * interp.c: call mono_init() after registering internal calls. - -2001-11-30 Dick Porter - - * interp.c: Replace get_named_exception() with - mono_exception_from_name() - -Fri Nov 30 12:05:21 CET 2001 Paolo Molaro - - * interp.c: calculate locals and args offsets only once - per method call. Cache trampoline code as well. - -2001-11-23 Dietmar Maurer - - * interp.c (ves_exec_method): bug fix for exception5.cs - -Mon Nov 19 11:33:00 CET 2001 Paolo Molaro - - * interp.c: start adding support for handling exceptions across - managed/unmanaged boundaries. Cleanup Delegate method invocation. - Pass the correct target object in Delegate::Invoke and use the correct - 'this' pointer in ldvirtftn (bugs pointed out by Dietmar). - -Thu Nov 15 17:40:24 CET 2001 Paolo Molaro - - * interp.c: handle enums with underlying type different from int32. - More checks for C structs <-> C# objects consistency. - -Wed Nov 14 19:23:00 CET 2001 Paolo Molaro - - * interp.c: move the stack frame dumping code to a function so it can - be called from the debugger. Fix virtual method lookup for interfaces. - Throw exceptions instead of aborting in more places. - Print also the message in an exception. Updates for field renames in - corlib. - -2001-11-09 Dick Porter - - * Makefile.am (mint_LDADD): Don't need THREAD_LIBS any more - -2001-11-07 Miguel de Icaza - - * interp.c: Include stdlib to kill warning. - (check_corlib): Adjust format encodings to remove warnings. - -Wed Nov 7 15:47:36 CET 2001 Paolo Molaro - - * interp.c: updates for changes in array code. - -Fri Nov 2 19:06:54 CET 2001 Paolo Molaro - - * interp.c: hanlde field refs. Throw an exception on NULL references. - Check consistency of corlib types with the C struct representation. - -2001-10-25 Dietmar Maurer - - * interp.c (ves_exec_method): use relative numbering for runtime - type checks (and make it work with interfaces) - -2001-10-15 Dietmar Maurer - - * interp.c: removed newobj() - -2001-10-10 Dietmar Maurer - - * interp.c (get_virtual_method): use the vtable - (arch_compile_method): added to compute vtable entry - -Mon Oct 8 16:14:40 CEST 2001 Paolo Molaro - - * interp.c: use the accessors provided in object.h to deal with - MonoArrays. Updates for API renames in metadata. Throw exception - in ldelema if index is out of bounds. - -Mon Oct 8 10:44:25 CEST 2001 Paolo Molaro - - * interp.c: fixes for changes in metadata. - -2001-10-04 Dick Porter - - * interp.c (ves_runtime_method): init_class() the - mono_defaults.delegate_class - Include mono-endian.h not endian.h - -Tue Oct 2 18:51:25 CEST 2001 Paolo Molaro - - * interp.c: set frame->ip in the leave opcode. Make db_methods static. - -Sun Sep 30 11:57:15 CEST 2001 Paolo Molaro - - * interp.c: compiler and ANSI C portability fixes. - -Fri Sep 28 19:37:46 CEST 2001 Paolo Molaro - - * interp.c: Implemented ldtoken, conv.ovf.i. Use MonoClass->byval_arg - (and remove related kludges). Don't choke on access to arrays of - references. Throw an exception when an internalcall or P/Invoke - function don't have an implementation. Throw and EngineException - for unimplemented opcodes. - -Tue Sep 25 11:12:35 CEST 2001 Paolo Molaro - - * interp.c: fixed get_virtual_method () to deal with interface - methods better. - -Mon Sep 24 18:50:25 CEST 2001 Paolo Molaro - - * interp.c: catch a few more error conditions with exceptions instead of - erroring out. - Don't use g_print() in stack traces because it doesn't work with - some float values. - When we call an instance method of a valuetype class, unbox the 'this' - argument if it is an object. - Use mono_ldstr () to implement the ldstr opcode: it takes care of - interning the string if necessary. - Implemented new opcodes: ckfinite, cgt.un, clt.un, ldvirtftn, ldarga. - Fixes to handle NaNs when comparing doubles. - Make sure the loaded assembly has an entry point defined. - Fixed portability bugs in neg and not opcodes. - -2001-09-24 Dietmar Maurer - - * interp.c (ves_exec_method): LDC_I4: 8bit constants are signed - (ves_exec_method): bug fix for NOT/NEG - (main): fix bug in parameter parsing - -2001-09-23 Dick Porter - - * Makefile.am (mint_LDADD): rename PTHREAD_LIBS to THREAD_LIBS - -2001-09-23 Dick Porter - - * interp.c (main): Do some thread setup and cleanup around the - call to ves_exec() - -2001-09-21 Dick Porter - - * Makefile.am (mint_LDADD): Added PTHREAD_LIBS to the link line - -Thu Sep 20 16:32:42 CEST 2001 Paolo Molaro - - * interp.c: implemented some more opcodes: calli, rem.un, - shr.un, conv.u, cpobj, stobj, conv.r.un, conv.ovf.i1.un, - conv.ovf.i2.un, conv.ovf.i4.un, conv.ovf.i8.un, conv.ovf.i.un, - conv.ovf.u1.un, conv.ovf.u2.un, conv.ovf.u4.un, conv.ovf.u8.un, - conv.ovf.u.un. - Fix some 64 bit issues in the array element access code and a small bug. - Throw an exception on index out of range instead of asserting. - Throw an exception on a NULL array instead of dying. - Stomped a memory corruption bug (.cctor methods were freed after - executing them, but they are stores in MonoClass now...). - Added a simple facility to invoke the debugger when a named - function is entered (use the cmdline option --debug method_name). - * interp.h: fix 64 bit issue. - -Tue Sep 18 13:21:33 CEST 2001 Paolo Molaro - - * interp.c: fix some 64 bit issues. Safer support for delegates. - -2001-09-12 Miguel de Icaza - - * interp.c (ves_exec_method): implement conv.u8 opcode. - -Mon Sep 10 20:20:36 CEST 2001 Paolo Molaro - - * interp.c: endian fixes, comments. - -Fri Sep 7 18:45:38 CEST 2001 Paolo Molaro - - * interp.c, interp.h: make ves_exec_method () and stackval_from_data () - non static. Implement a couple of runtime methods needed to - use delegates (ves_runtime_method ()). - Implemented ldftn opcode. - -Thu Sep 6 15:41:24 CEST 2001 Paolo Molaro - - * Makefile.am: link to libmonoarch. - * interp.h, interp.c: use mono_create_trampoline (). - Pass the command line arguments to Main (String[]) methods. - -2001-08-30 Dietmar Maurer - - * interp.c (ves_pinvoke_method): removed the libffi dependency - -2001-08-29 Dietmar Maurer - - * interp.c (ves_array_set): moved from icall.c - (ves_array_get): moved from icall.c - - * icall.c: moved to metadata/icall.c - -Wed Aug 29 12:46:06 CEST 2001 Paolo Molaro - - * interp.c: some small optimizations. Fixes to do signed - compares when needed. Change C++ comments into C. - Implemented cgt, clt. Added --opcode-count cmdline switch. - -2001-08-28 Dietmar Maurer - - * interp.c (ves_exec_method): better check for value types (get - the class to detect if we have a value type), implemented CEE_CONV_U1, - CEE_CONV_U2, CEE_CEQ - - -Mon Aug 27 21:30:30 CEST 2001 Paolo Molaro - - * interp.c: warn and exit when Main () expects the cmdline arguments - instead of creashing. - -Mon Aug 27 20:16:37 CEST 2001 Paolo Molaro - - * interp.c: merge isinst/castclass handling. Hopefully implement - the right semantics for handling callvirt correctly (changes - here and there to support it). Integrate bugfix from Dietmar quickly - so he needs to handle the cvs conflict:-) - -Mon Aug 27 12:20:32 CEST 2001 Paolo Molaro - - * interp.c: fix compilation and updates for changes in metadata/. - -2001-08-26 Miguel de Icaza - - * interp.c (main): Add option handling for the interpreter, - support the `--trace' option. - -Sun Aug 26 23:04:46 CEST 2001 Paolo Molaro - - * interp.c: get in a dummy virtual method dispatch. - Added support for int64, native int and native uint as arguments. - Added debug enter/leave for icall and pinvoke methods, too. - Implement opcodes conv.i, conv.i8, ldelema. - -Sun Aug 26 11:37:30 CEST 2001 Paolo Molaro - - * interp.h, interp.c: load also a MonoClass pointer when we load - an address on the stack. Implemented conv.i1, conv.i2, con.i4, - conv.u4, conv.r4, conv.r8. Print the arguments in the stack trace - and the name of the exception. - -Sat Aug 25 15:56:03 CEST 2001 Paolo Molaro - - * interp.c: Implemented some opcodes: starg.s, ldobj, isinst, - ldarg, starg, ldloc, ldloca, stloc, initobj, cpblk, sizeof. - -Sat Aug 25 12:57:36 CEST 2001 Paolo Molaro - - * interp.c: handle enumerations specially (not as valuetypes). - -Fri Aug 24 19:34:04 CEST 2001 Paolo Molaro - - * interp.h, interp.c: add support for valuetypes. - -Fri Aug 24 16:09:20 CEST 2001 Paolo Molaro - - * interp.c: updates for merge of MonoParam in MonoType. - -Thu Aug 23 12:04:34 CEST 2001 Paolo Molaro - - * interp.c: removed beforefieldinit check, it's a useless flag. - Added a couple more test cases to tests/ dir. - -2001-08-22 Miguel de Icaza - - * interp.c (usage): Add version information - (ves_pinvoke_method): Typo fix. - -Wed Aug 22 20:37:51 CEST 2001 Paolo Molaro - - * interp.c: simplified init_class (). Make sure a class - is fully initialized before executing a method in the class. - Search for the class constructor only on beforefieldinit classes. - Implement a bunch of opcodes: br, brfalse, brtrue, beq, bge, - bgt, blt, ble, bne.un, bge.un, bgt.un, ble.un, blt.un, stind.i, - ldflda, ldsflda, ldelem.i8, stelem.i8, leave. - -Wed Aug 22 16:34:03 CEST 2001 Paolo Molaro - - * interp.c: Updates for changes in metadata/. Better output in debug mode - and in the stack trace. Completed rethrow handling - -Tue Aug 21 18:56:19 CEST 2001 Paolo Molaro - - * interp.c: new macro INIT_FRAME() to properly - initialize a MonoInvocation. Fixed a couple of buglets in exception code: - increase stack pointer when pushing the exception for catch blocks, - initialize frame->ex_handler to NULL, correctly try all the - catch blocks (don't incorrectly fallback on filter handling). - Added a couple more checks where we may need to throw an - exception. Added more exception creation functions. - Changed stackval_from_data() to take the target stackval as - argument. Implemented a couple more opcodes. - * interp.h: prepare stackval for value type code. - -2001-08-21 Miguel de Icaza - - * Makefile.am (mint_LDADD): Renamed interpreter to mint. - -2001-08-21 Dietmar Maurer - - * interp.c (get_named_exception): use the right constructor. - -Mon Aug 20 18:58:36 CEST 2001 Paolo Molaro - - * interp.c: fix buglet with the leave.s opcode. - -2001-08-20 Dietmar Maurer - - * icall.c: changed everything to support the new calling convention - - * hacks.h: added some macros for FreeBSD - - * interp.c (get_named_exception): use mono_object_new instead of - newobj, initialize the stack before we call the constructor. - -Sat Aug 18 12:43:38 CEST 2001 Paolo Molaro - - * interp.c, interp.h: added support code to create exceptions. - Changed interncal calling convnetion over to MonoInvocation, to support - exceptions, walking the stack back and forward and passing the 'this' - pointer separately (remove the cludges required before to pass this on the - stack). Use alloca heavily for both local vars and a copy of the incoming - arguments. Init local vars to zero. - Simplify stackval_from_data() and stackval_to_data() to only take a pointer - instead of pointer + offset. - Implement a few exceptions-related opcodes and the code to run finally, fault and - catch blocks as well as a stack trace if no handler is found. - -2001-08-16 Alex Graveley - - * Makefile.am (mono_int_LDADD): Link with ../../libffi/libffi.a - instead of ../../libffi/.libs/libffi.a. - -2001-08-10 Dietmar Maurer - - * interp.c (ves_exec_method): impl CASTCLASS - - * icall.c: moved the internal call stuff to this file - - * interp.c (ves_exec_method): impl. BOX/UNBOX - (ves_icall_System_Array_GetValue): impl. - (ves_icall_System_Array_SetValue): impl. - added myself to Authors - -2001-08-09 Dietmar Maurer - - * implemented arrays, but you will need a modified version of - Array.cs to get arrays working (will commit soon) - - * interp.c (ves_icall_array_Set): impl. - (ves_icall_array_Get): impl. - (ves_icall_array_ctor): impl. - (ves_icall_System_Array_GetRank): impl. - (ves_icall_System_Array_GetLength): impl. - (ves_icall_System_Array_GetLowerBound): impl. - (mono_lookup_internal_call): impl. - -2001-08-06 Dietmar Maurer - - * interp.c (ves_exec_method): impl. NEWARR - (ves_exec_method): impl. most LDELEM/STELEM opcodes, LDLEN - (newarr): impl. - (mono_get_ansi_string): impl. - (mono_lookup_internal_call): impl. - (ves_exec_method): implemented internal calls - -2001-08-05 Dietmar Maurer - - * interp.c (ves_pinvoke_method): removed all static vars. - -2001-08-02 Dietmar Maurer - - * interp.c (ves_exec_method): found a way to do unordered - compares, implemented CEE_BNE_UN_S, CEE_BGE_UN_S, CEE_BGT_UN_S, - CEE_BLE_UN_S, CEE_BLT_UN_S - -Wed Aug 1 22:51:38 CEST 2001 Paolo Molaro - - * interp.c: handle also MONO_TYPE_CLASS to/from the stack. - Change locals to be a memory blob, instead of the structured - (but wrong) stackval. Implement bne.un.s opcode. Make the program - exit with the error code from Main(). - -2001-08-01 Dietmar Maurer - - * interp.c (ves_exec_method): implemented LDSTR - -2001-07-31 Miguel de Icaza - - * interp.c (GET_NATI): Switched from using nati_t to cli/types.h - m_i type. Maybe we should rename the types to be m_i_t instead of - m_i alone. - - Make the code compile after I broke it. - -Tue Jul 31 23:46:33 CEST 2001 Paolo Molaro - - * interp.c: fix cleanup. - * Makefile.am: don't link with disassembler library. - -2001-07-31 Miguel de Icaza - - (ves_exec_method): Cleanup of the source code. - -Tue Jul 31 20:13:59 CEST 2001 Paolo Molaro - - * interp.c: implement stind.*, ldind.*, ldloca.s opcodes. - Provide better tracing with DEBUG_INTERP. - -Tue Jul 31 17:52:53 CEST 2001 Paolo Molaro - - * interp.c: massive namespace cleanup. - -Mon Jul 30 20:09:58 CEST 2001 Paolo Molaro - - * interp.c: update to use mono_method->name. - -Fri Jul 27 20:54:00 CEST 2001 Paolo Molaro - - * interp.c: start implementing callvirt. Classes with - class constructors are properly initialized when needed. - Fix error introduced in version 1.17. - -Fri Jul 27 14:03:19 CEST 2001 Paolo Molaro - - * interp.c: implement static field loading and storing. - -2001-07-27 Dietmar Maurer - - * interp.c (ves_pinvoke_method): impl. - -Fri Jul 27 11:49:19 CEST 2001 Paolo Molaro - - * interp.c: Removed some debugging printouts. Made stackval_to_data - static. Handle also instance methods in CALL opcode. Fix ret to properly - deal with void functions. Fixed constructor to leave the object on - the stack. - -Thu Jul 26 13:24:51 CEST 2001 Paolo Molaro - - * interp.c: ves_exec_method () doesn't take a MonoImage arg - anymore. Use the method cache in MonoImage. Updates to - mache recent changes in metadata. - Fix newobj code to use new metadata features. Call the class - constructor after allocationg the object. Implemented load field - and store field opcodes (the support functions need to be finished). - -Tue Jul 24 16:51:09 CEST 2001 Paolo Molaro - - * interp.c, hacks.h: moved a few ugly macros out of the code. - Implemented switch opcode. - -2001-07-23 Miguel de Icaza - - * interp.c (newobj): Added function to handle newobj opcode. - -2001-07-18 Miguel de Icaza - - * interp.c (ves_exec_method): Make the interpreter abort with more - information than it currently does. - - Enable the slow processor, as it is easier to debug. - -Sun Jul 15 17:50:23 CEST 2001 Paolo Molaro - - * Started changelog. - * interp.c: use new mono_get_method () function to get the complete - info on a method invocation: we support now method invocation with - multiple (or zero) simple arguments and with or without a return value. - Implement also a couple more opcodes. diff --git a/mono/interpreter/Makefile.am b/mono/interpreter/Makefile.am deleted file mode 100644 index 4cea04452be..00000000000 --- a/mono/interpreter/Makefile.am +++ /dev/null @@ -1,59 +0,0 @@ -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - $(LIBGC_CPPFLAGS) \ - $(GLIB_CFLAGS) - -if HOST_WIN32 -export HOST_CC -# The mingw math.h has "extern inline" functions that dont appear in libs, so -# optimisation is required to actually inline them -AM_CFLAGS = -O -endif - -if INTERP_SUPPORTED -bin_PROGRAMS = mint - -lib_LTLIBRARIES = libmint.la - -man_MANS = mint.1 -endif - -mint_SOURCES = \ - main.c - -mint_LDADD = \ - libmint.la - -libmint_la_SOURCES = \ - hacks.h \ - interp.h \ - interp.c \ - mintops.h \ - mintops.def \ - mintops.c \ - transform.c - -libmintincludedir = $(includedir)/mono-$(API_VER)/mono/interpreter - -libmintinclude_HEADERS = \ - embed.h - -# This is needed for automake dependency generation -if INCLUDED_LIBGC -libgc_libs=../../libgc/libmonogc.la -else -libgc_libs=$(LIBGC_LIBS) -endif - -libmint_la_LIBADD = \ - ../arch/libmonoarch.la \ - ../metadata/libmonoruntime.la \ - ../io-layer/libwapi.la \ - ../utils/libmonoutils.la \ - $(libgc_libs) \ - $(GLIB_LIBS) \ - $(LIBICONV) \ - $(ICU_LIBS) \ - -lm - -EXTRA_DIST = $(man_MANS) diff --git a/mono/interpreter/embed.h b/mono/interpreter/embed.h deleted file mode 100644 index b3a54490eed..00000000000 --- a/mono/interpreter/embed.h +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include - -int -mono_main (int argc, char* argv[]); - -MonoDomain * -mono_interp_init(const char *file); - -int -mono_interp_exec(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]); - -void -mono_interp_cleanup(MonoDomain *domain); - diff --git a/mono/interpreter/hacks.h b/mono/interpreter/hacks.h deleted file mode 100644 index 9697ccbad6f..00000000000 --- a/mono/interpreter/hacks.h +++ /dev/null @@ -1,153 +0,0 @@ -/* we need some special math function */ -#ifndef _ISOC99_SOURCE -#define _ISOC99_SOURCE -#endif -#include - -/* which are not defined on FreeBSD */ -#ifdef __GNUC__ - -#ifndef isunordered -# define isunordered(u, v) \ - (__extension__ \ - ({ __typeof__(u) __u = (u); __typeof__(v) __v = (v); \ - isnan(__u) || isnan(__v); })) -#endif - -#ifndef islessgreater -# define islessgreater(x, u) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered (__x, __y) && (__x < __y) || (__y < __x); })) -#endif - -#ifndef islessequal -# define islessequal(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered(__x, __y) && __x <= __y; })) -#endif - -#ifndef isless -# define isless(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered(__x, __y) && __x < __y; })) -#endif - -#ifndef isgreater -# define isgreater(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered(__x, __y) && __x > __y; })) -#endif - -#else - -/* isunordered seems to crash on HPUX when built 64 bits - so use generic implementation. -*/ -#if defined(__hpux) && SIZEOF_VOID_P == 8 -#undef isunordered -#undef islessgreater -#undef islessequal -#undef isless -#undef isgreater -#endif - -#ifndef isunordered -# define isunordered(u, v) (isnan(u) || isnan(v)) -#endif - -#ifndef islessgreater -# define islessgreater(x, u) (!isunordered (x, y) && (x < y) || (y < x)) -#endif - -#ifndef islessequal -# define islessequal(x, y) (!isunordered(x, y) && x <= y) -#endif - -#ifndef isless -# define isless(x, y) (!isunordered(x, y) && x < y) -#endif - -#ifndef isgreater -# define isgreater(x, y) (!isunordered(x, y) && x > y) -#endif - -#endif - -/* - * Attempt at using the goto label construct of GNU GCC: - * it turns out this does give some benefit: 5-15% speedup. - * Don't look at these macros, it hurts... - */ -#define GOTO_LABEL -#undef GOTO_LABEL -#ifdef GOTO_LABEL - -#define SWITCH(a) goto *goto_map [(a)]; -#define BREAK SWITCH(*ip) -#define CASE(l) l ## _LABEL: -#define DEFAULT \ - CEE_ILLEGAL_LABEL: \ - CEE_ENDMAC_LABEL: -#define SUB_SWITCH \ - CEE_PREFIX1_LABEL: \ - CEE_ARGLIST_LABEL: \ - CEE_CEQ_LABEL: \ - CEE_CGT_LABEL: \ - CEE_CGT_UN_LABEL: \ - CEE_CLT_LABEL: \ - CEE_CLT_UN_LABEL: \ - CEE_LDFTN_LABEL: \ - CEE_LDVIRTFTN_LABEL: \ - CEE_UNUSED56_LABEL: \ - CEE_LDARG_LABEL: \ - CEE_LDARGA_LABEL: \ - CEE_STARG_LABEL: \ - CEE_LDLOC_LABEL: \ - CEE_LDLOCA_LABEL: \ - CEE_STLOC_LABEL: \ - CEE_LOCALLOC_LABEL: \ - CEE_UNUSED57_LABEL: \ - CEE_ENDFILTER_LABEL: \ - CEE_UNALIGNED__LABEL: \ - CEE_VOLATILE__LABEL: \ - CEE_TAIL__LABEL: \ - CEE_INITOBJ_LABEL: \ - CEE_UNUSED68_LABEL: \ - CEE_CPBLK_LABEL: \ - CEE_INITBLK_LABEL: \ - CEE_UNUSED69_LABEL: \ - CEE_RETHROW_LABEL: \ - CEE_UNUSED_LABEL: \ - CEE_SIZEOF_LABEL: \ - CEE_REFANYTYPE_LABEL: \ - CEE_UNUSED52_LABEL: \ - CEE_UNUSED53_LABEL: \ - CEE_UNUSED54_LABEL: \ - CEE_UNUSED55_LABEL: \ - CEE_UNUSED70_LABEL: -#define GOTO_LABEL_VARS \ - const static void * const goto_map [] = {\ -#define OPDEF(a,b,c,d,e,f,g,h,i,j) \ \ - && a ## _LABEL, \ -#include "mono/cil/opcode.def" \ -#undef OPDEF \ - &&DUMMY_LABEL \ - }; \ - DUMMY_LABEL: - -#else - -#define SWITCH(a) switch(a) -#define BREAK break -#define CASE(l) case l: -#define DEFAULT \ - default: \ - g_error ("Unimplemented opcode: %x at 0x%x\n", *ip, ip-header->code); -#define SUB_SWITCH case 0xFE: -#define GOTO_LABEL_VARS - -#endif diff --git a/mono/interpreter/interp.c b/mono/interpreter/interp.c deleted file mode 100644 index 4525ff69ab3..00000000000 --- a/mono/interpreter/interp.c +++ /dev/null @@ -1,4515 +0,0 @@ -/* - * PLEASE NOTE: This is a research prototype. - * - * - * interp.c: Interpreter for CIL byte codes - * - * Authors: - * Paolo Molaro (lupus@ximian.com) - * Miguel de Icaza (miguel@ximian.com) - * Dietmar Maurer (dietmar@ximian.com) - * - * (C) 2001, 2002 Ximian, Inc. - */ -#ifndef __USE_ISOC99 -#define __USE_ISOC99 -#endif -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_ALLOCA_H -# include -#else -# ifdef __CYGWIN__ -# define alloca __builtin_alloca -# endif -#endif - -/* trim excessive headers */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "interp.h" -#include "mintops.h" -#include "embed.h" -#include "hacks.h" - -#define OPDEF(a,b,c,d,e,f,g,h,i,j) \ - a = i, - -enum { -#include "mono/cil/opcode.def" - CEE_LASTOP -}; -#undef OPDEF - -/* Mingw 2.1 doesnt need this any more, but leave it in for now for older versions */ -#ifdef _WIN32 -#define isnan _isnan -#define finite _finite -#endif -#ifndef HAVE_FINITE -#ifdef HAVE_ISFINITE -#define finite isfinite -#endif -#endif - -static gint *abort_requested; - -/* If true, then we output the opcodes as we interpret them */ -static int global_tracing = 0; -static int global_no_pointers = 0; - -int mono_interp_traceopt = 0; - -static int debug_indent_level = 0; - -#define INIT_FRAME(frame,parent_frame,obj_this,method_args,method_retval,mono_method) \ - do { \ - (frame)->parent = (parent_frame); \ - (frame)->obj = (obj_this); \ - (frame)->stack_args = (method_args); \ - (frame)->retval = (method_retval); \ - (frame)->runtime_method = mono_interp_get_runtime_method (mono_method); \ - (frame)->ex = NULL; \ - (frame)->ip = NULL; \ - (frame)->invoke_trap = 0; \ - } while (0) - -void ves_exec_method (MonoInvocation *frame); - -static char* dump_stack (stackval *stack, stackval *sp); -static char* dump_frame (MonoInvocation *inv); -static MonoArray *get_trace_ips (MonoDomain *domain, MonoInvocation *top); -static void ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context); - -typedef void (*ICallMethod) (MonoInvocation *frame); - -static guint32 die_on_exception = 0; -static guint32 thread_context_id = 0; - -#define DEBUG_INTERP 1 -#define COUNT_OPS 0 -#if DEBUG_INTERP - -static int break_on_method = 0; -static int nested_trace = 0; -static GList *db_methods = NULL; - -static void -output_indent (void) -{ - int h; - - for (h = 0; h < debug_indent_level; h++) - g_print (" "); -} - -static void -db_match_method (gpointer data, gpointer user_data) -{ - MonoMethod *m = (MonoMethod*)user_data; - MonoMethodDesc *desc = data; - - if (mono_method_desc_full_match (desc, m)) - break_on_method = 1; -} - -#define DEBUG_ENTER() \ - if (db_methods) { \ - g_list_foreach (db_methods, db_match_method, (gpointer)frame->runtime_method->method); \ - if (break_on_method) tracing=nested_trace ? (global_tracing = 2, 3) : 2; \ - break_on_method = 0; \ - } \ - if (tracing) { \ - MonoMethod *method = frame->runtime_method->method ;\ - char *mn, *args = dump_args (frame); \ - debug_indent_level++; \ - output_indent (); \ - mn = mono_method_full_name (method, FALSE); \ - g_print ("(%u) Entering %s (", GetCurrentThreadId(), mn); \ - g_free (mn); \ - g_print ("%s)\n", args); \ - g_free (args); \ - } \ - if (mono_profiler_events & MONO_PROFILE_ENTER_LEAVE) \ - mono_profiler_method_enter (frame->runtime_method->method); - -#define DEBUG_LEAVE() \ - if (tracing) { \ - char *mn, *args; \ - args = dump_retval (frame); \ - output_indent (); \ - mn = mono_method_full_name (frame->runtime_method->method, FALSE); \ - g_print ("(%u) Leaving %s", GetCurrentThreadId(), mn); \ - g_free (mn); \ - g_print (" => %s\n", args); \ - g_free (args); \ - debug_indent_level--; \ - if (tracing == 3) global_tracing = 0; \ - } \ - if (mono_profiler_events & MONO_PROFILE_ENTER_LEAVE) \ - mono_profiler_method_leave (frame->runtime_method->method); - -#else - -#define DEBUG_ENTER() -#define DEBUG_LEAVE() - -#endif - -static void -interp_ex_handler (MonoException *ex) { - ThreadContext *context = TlsGetValue (thread_context_id); - char *stack_trace; - if (context == NULL) - return; - stack_trace = dump_frame (context->current_frame); - ex->stack_trace = mono_string_new (mono_domain_get(), stack_trace); - g_free (stack_trace); - if (context->current_env == NULL || strcmp(ex->object.vtable->klass->name, "ExecutionEngineException") == 0) { - char *strace = mono_string_to_utf8 (ex->stack_trace); - fprintf(stderr, "Nothing can catch this exception: "); - fprintf(stderr, "%s", ex->object.vtable->klass->name); - if (ex->message != NULL) { - char *m = mono_string_to_utf8 (ex->message); - fprintf(stderr, ": %s", m); - g_free(m); - } - fprintf(stderr, "\n"); - fprintf(stderr, "%s\n", strace); - g_free (strace); - if (ex->inner_ex != NULL) { - ex = (MonoException *)ex->inner_ex; - fprintf(stderr, "Inner exception: %s", ex->object.vtable->klass->name); - if (ex->message != NULL) { - char *m = mono_string_to_utf8 (ex->message); - fprintf(stderr, ": %s", m); - g_free(m); - } - strace = mono_string_to_utf8 (ex->stack_trace); - fprintf(stderr, "\n"); - fprintf(stderr, "%s\n", strace); - g_free (strace); - } - /* wait for other threads to also collapse */ - Sleep(1000); - exit(1); - } - context->env_frame->ex = ex; - context->search_for_handler = 1; - longjmp (*context->current_env, 1); -} - -static void -ves_real_abort (int line, MonoMethod *mh, - const unsigned short *ip, stackval *stack, stackval *sp) -{ - fprintf (stderr, "Execution aborted in method: %s::%s\n", mh->klass->name, mh->name); - fprintf (stderr, "Line=%d IP=0x%04x, Aborted execution\n", line, - ip-(const unsigned short *)mono_method_get_header (mh)->code); - g_print ("0x%04x %02x\n", - ip-(const unsigned short *)mono_method_get_header (mh)->code, *ip); - if (sp > stack) - printf ("\t[%d] 0x%08x %0.5f\n", sp-stack, sp[-1].data.i, sp[-1].data.f); -} - -#define ves_abort() \ - do {\ - ves_real_abort(__LINE__, frame->runtime_method->method, ip, frame->stack, sp); \ - THROW_EX (mono_get_exception_execution_engine (NULL), ip); \ - } while (0); - -static gpointer -interp_create_remoting_trampoline (MonoMethod *method, MonoRemotingTarget target) -{ - return mono_interp_get_runtime_method (mono_marshal_get_remoting_invoke_for_target (method, target)); -} - -static mono_mutex_t runtime_method_lookup_section; - -RuntimeMethod* -mono_interp_get_runtime_method (MonoMethod *method) -{ - MonoDomain *domain = mono_domain_get (); - RuntimeMethod *rtm; - - mono_mutex_lock (&runtime_method_lookup_section); - if ((rtm = mono_internal_hash_table_lookup (&domain->jit_code_hash, method))) { - mono_mutex_unlock (&runtime_method_lookup_section); - return rtm; - } - rtm = mono_mempool_alloc (domain->mp, sizeof (RuntimeMethod)); - memset (rtm, 0, sizeof (*rtm)); - rtm->method = method; - rtm->param_count = mono_method_signature (method)->param_count; - rtm->hasthis = mono_method_signature (method)->hasthis; - rtm->valuetype = method->klass->valuetype; - mono_internal_hash_table_insert (&domain->jit_code_hash, method, rtm); - mono_mutex_unlock (&runtime_method_lookup_section); - - return rtm; -} - -static gpointer -interp_create_trampoline (MonoMethod *method) -{ - if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) - method = mono_marshal_get_synchronized_wrapper (method); - return mono_interp_get_runtime_method (method); -} - -static inline RuntimeMethod* -get_virtual_method (RuntimeMethod *runtime_method, MonoObject *obj) -{ - MonoMethod *m = runtime_method->method; - - if ((m->flags & METHOD_ATTRIBUTE_FINAL) || !(m->flags & METHOD_ATTRIBUTE_VIRTUAL)) { - if (obj->vtable->klass == mono_defaults.transparent_proxy_class) - return mono_interp_get_runtime_method (mono_marshal_get_remoting_invoke (m)); - else if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) - return mono_interp_get_runtime_method (mono_marshal_get_synchronized_wrapper (m)); - else - return runtime_method; - } - - if (m->klass->flags & TYPE_ATTRIBUTE_INTERFACE) { - return ((RuntimeMethod **)obj->vtable->interface_offsets [m->klass->interface_id]) [m->slot]; - } else { - return ((RuntimeMethod **)obj->vtable->vtable) [m->slot]; - } -} - -void inline -stackval_from_data (MonoType *type, stackval *result, char *data, gboolean pinvoke) -{ - if (type->byref) { - switch (type->type) { - case MONO_TYPE_OBJECT: - case MONO_TYPE_CLASS: - case MONO_TYPE_STRING: - case MONO_TYPE_ARRAY: - case MONO_TYPE_SZARRAY: - break; - default: - break; - } - result->data.p = *(gpointer*)data; - return; - } - switch (type->type) { - case MONO_TYPE_VOID: - return; - case MONO_TYPE_I1: - result->data.i = *(gint8*)data; - return; - case MONO_TYPE_U1: - case MONO_TYPE_BOOLEAN: - result->data.i = *(guint8*)data; - return; - case MONO_TYPE_I2: - result->data.i = *(gint16*)data; - return; - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - result->data.i = *(guint16*)data; - return; - case MONO_TYPE_I4: - result->data.i = *(gint32*)data; - return; - case MONO_TYPE_U: - case MONO_TYPE_I: - result->data.nati = *(mono_i*)data; - return; - case MONO_TYPE_PTR: - result->data.p = *(gpointer*)data; - return; - case MONO_TYPE_U4: - result->data.i = *(guint32*)data; - return; - case MONO_TYPE_R4: - result->data.f = *(float*)data; - return; - case MONO_TYPE_I8: - case MONO_TYPE_U8: - result->data.l = *(gint64*)data; - return; - case MONO_TYPE_R8: - result->data.f = *(double*)data; - return; - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_ARRAY: - result->data.p = *(gpointer*)data; - return; - case MONO_TYPE_VALUETYPE: - if (type->data.klass->enumtype) { - stackval_from_data (type->data.klass->enum_basetype, result, data, pinvoke); - return; - } else { - int size; - - if (pinvoke) - size = mono_class_native_size (type->data.klass, NULL); - else - size = mono_class_value_size (type->data.klass, NULL); - memcpy (result->data.vt, data, size); - } - return; - default: - g_warning ("got type 0x%02x", type->type); - g_assert_not_reached (); - } -} - -void inline -stackval_to_data (MonoType *type, stackval *val, char *data, gboolean pinvoke) -{ - if (type->byref) { - gpointer *p = (gpointer*)data; - *p = val->data.p; - return; - } - /* printf ("TODAT0 %p\n", data); */ - switch (type->type) { - case MONO_TYPE_I1: - case MONO_TYPE_U1: { - guint8 *p = (guint8*)data; - *p = val->data.i; - return; - } - case MONO_TYPE_BOOLEAN: { - guint8 *p = (guint8*)data; - *p = (val->data.i != 0); - return; - } - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: { - guint16 *p = (guint16*)data; - *p = val->data.i; - return; - } - case MONO_TYPE_I: { - mono_i *p = (mono_i*)data; - /* In theory the value used by stloc should match the local var type - but in practice it sometimes doesn't (a int32 gets dup'd and stloc'd into - a native int - both by csc and mcs). Not sure what to do about sign extension - as it is outside the spec... doing the obvious */ - *p = (mono_i)val->data.nati; - return; - } - case MONO_TYPE_U: { - mono_u *p = (mono_u*)data; - /* see above. */ - *p = (mono_u)val->data.nati; - return; - } - case MONO_TYPE_I4: - case MONO_TYPE_U4: { - gint32 *p = (gint32*)data; - *p = val->data.i; - return; - } - case MONO_TYPE_I8: - case MONO_TYPE_U8: { - gint64 *p = (gint64*)data; - *p = val->data.l; - return; - } - case MONO_TYPE_R4: { - float *p = (float*)data; - *p = val->data.f; - return; - } - case MONO_TYPE_R8: { - double *p = (double*)data; - *p = val->data.f; - return; - } - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_ARRAY: - case MONO_TYPE_PTR: { - gpointer *p = (gpointer*)data; - *p = val->data.p; - return; - } - case MONO_TYPE_VALUETYPE: - if (type->data.klass->enumtype) { - stackval_to_data (type->data.klass->enum_basetype, val, data, pinvoke); - return; - } else { - int size; - - if (pinvoke) - size = mono_class_native_size (type->data.klass, NULL); - else - size = mono_class_value_size (type->data.klass, NULL); - - memcpy (data, val->data.p, size); - } - return; - default: - g_warning ("got type %x", type->type); - g_assert_not_reached (); - } -} - -static void -fill_in_trace (MonoException *exception, MonoInvocation *frame) -{ - char *stack_trace = dump_frame (frame); - MonoDomain *domain = mono_domain_get(); - (exception)->stack_trace = mono_string_new (domain, stack_trace); - (exception)->trace_ips = get_trace_ips (domain, frame); - g_free (stack_trace); -} - -#define FILL_IN_TRACE(exception, frame) fill_in_trace(exception, frame) - -#define THROW_EX(exception,ex_ip) \ - do {\ - frame->ip = (ex_ip); \ - frame->ex = (MonoException*)(exception); \ - FILL_IN_TRACE(frame->ex, frame); \ - goto handle_exception; \ - } while (0) - -static MonoObject* -ves_array_create (MonoDomain *domain, MonoClass *klass, MonoMethodSignature *sig, stackval *values) -{ - guint32 *lengths; - guint32 *lower_bounds; - int i; - - lengths = alloca (sizeof (guint32) * klass->rank * 2); - for (i = 0; i < sig->param_count; ++i) { - lengths [i] = values->data.i; - values ++; - } - if (klass->rank == sig->param_count) { - /* Only lengths provided. */ - lower_bounds = NULL; - } else { - /* lower bounds are first. */ - lower_bounds = lengths; - lengths += klass->rank; - } - return (MonoObject*)mono_array_new_full (domain, klass, lengths, lower_bounds); -} - -static void -ves_array_set (MonoInvocation *frame) -{ - stackval *sp = frame->stack_args; - MonoObject *o; - MonoArray *ao; - MonoClass *ac; - gint32 i, t, pos, esize; - gpointer ea; - MonoType *mt; - - o = frame->obj; - ao = (MonoArray *)o; - ac = o->vtable->klass; - - g_assert (ac->rank >= 1); - - pos = sp [0].data.i; - if (ao->bounds != NULL) { - pos -= ao->bounds [0].lower_bound; - for (i = 1; i < ac->rank; i++) { - if ((t = sp [i].data.i - ao->bounds [i].lower_bound) >= - ao->bounds [i].length) { - frame->ex = mono_get_exception_index_out_of_range (); - FILL_IN_TRACE(frame->ex, frame); - return; - } - pos = pos*ao->bounds [i].length + sp [i].data.i - - ao->bounds [i].lower_bound; - } - } else if (pos >= ao->max_length) { - frame->ex = mono_get_exception_index_out_of_range (); - FILL_IN_TRACE(frame->ex, frame); - return; - } - -#if 0 /* FIX */ - if (sp [ac->rank].data.p && !mono_object_isinst (sp [ac->rank].data.p, mono_object_class (o)->element_class)) { - frame->ex = mono_get_exception_array_type_mismatch (); - FILL_IN_TRACE (frame->ex, frame); - return; - } -#endif - - esize = mono_array_element_size (ac); - ea = mono_array_addr_with_size (ao, esize, pos); - - mt = mono_method_signature (frame->runtime_method->method)->params [ac->rank]; - stackval_to_data (mt, &sp [ac->rank], ea, FALSE); -} - -static void -ves_array_get (MonoInvocation *frame) -{ - stackval *sp = frame->stack_args; - MonoObject *o; - MonoArray *ao; - MonoClass *ac; - gint32 i, t, pos, esize; - gpointer ea; - MonoType *mt; - - o = frame->obj; - ao = (MonoArray *)o; - ac = o->vtable->klass; - - g_assert (ac->rank >= 1); - - pos = sp [0].data.i; - if (ao->bounds != NULL) { - pos -= ao->bounds [0].lower_bound; - for (i = 1; i < ac->rank; i++) { - if ((t = sp [i].data.i - ao->bounds [i].lower_bound) >= - ao->bounds [i].length) { - frame->ex = mono_get_exception_index_out_of_range (); - FILL_IN_TRACE(frame->ex, frame); - return; - } - - pos = pos*ao->bounds [i].length + sp [i].data.i - - ao->bounds [i].lower_bound; - } - } else if (pos >= ao->max_length) { - frame->ex = mono_get_exception_index_out_of_range (); - FILL_IN_TRACE(frame->ex, frame); - return; - } - - esize = mono_array_element_size (ac); - ea = mono_array_addr_with_size (ao, esize, pos); - - mt = mono_method_signature (frame->runtime_method->method)->ret; - stackval_from_data (mt, frame->retval, ea, FALSE); -} - -static void -ves_array_element_address (MonoInvocation *frame) -{ - stackval *sp = frame->stack_args; - MonoObject *o; - MonoArray *ao; - MonoClass *ac; - gint32 i, t, pos, esize; - gpointer ea; - - o = frame->obj; - ao = (MonoArray *)o; - ac = o->vtable->klass; - - g_assert (ac->rank >= 1); - - pos = sp [0].data.i; - if (ao->bounds != NULL) { - pos -= ao->bounds [0].lower_bound; - for (i = 1; i < ac->rank; i++) { - if ((t = sp [i].data.i - ao->bounds [i].lower_bound) >= - ao->bounds [i].length) { - frame->ex = mono_get_exception_index_out_of_range (); - FILL_IN_TRACE(frame->ex, frame); - return; - } - pos = pos*ao->bounds [i].length + sp [i].data.i - - ao->bounds [i].lower_bound; - } - } else if (pos >= ao->max_length) { - frame->ex = mono_get_exception_index_out_of_range (); - FILL_IN_TRACE(frame->ex, frame); - return; - } - - esize = mono_array_element_size (ac); - ea = mono_array_addr_with_size (ao, esize, pos); - - frame->retval->data.p = ea; -} - -static void -interp_walk_stack (MonoStackWalk func, gboolean do_il_offset, gpointer user_data) -{ - ThreadContext *context = TlsGetValue (thread_context_id); - MonoInvocation *frame; - int il_offset; - MonoMethodHeader *hd; - - if (!context) return; - - frame = context->current_frame; - - while (frame) { - gboolean managed = FALSE; - MonoMethod *method = frame->runtime_method->method; - if (!method || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || - (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME))) - il_offset = -1; - else { - hd = mono_method_get_header (method); - il_offset = frame->ip - (const unsigned short *)hd->code; - if (!method->wrapper_type) - managed = TRUE; - } - if (func (method, -1, il_offset, managed, user_data)) - return; - frame = frame->parent; - } -} - -static void -ves_pinvoke_method (MonoInvocation *frame, MonoMethodSignature *sig, MonoFunc addr, gboolean string_ctor, ThreadContext *context) -{ - jmp_buf env; - MonoPIFunc func; - MonoInvocation *old_frame = context->current_frame; - MonoInvocation *old_env_frame = context->env_frame; - jmp_buf *old_env = context->current_env; - - if (setjmp (env)) { - context->current_frame = old_frame; - context->env_frame = old_env_frame; - context->current_env = old_env; - context->managed_code = 1; - return; - } - - frame->ex = NULL; - context->env_frame = frame; - context->current_env = &env; - - if (frame->runtime_method) { - func = frame->runtime_method->func; - } else { - func = mono_arch_create_trampoline (sig, string_ctor); - } - - context->current_frame = frame; - context->managed_code = 0; - - func (addr, &frame->retval->data.p, frame->obj, frame->stack_args); - - context->managed_code = 1; - /* domain can only be changed by native code */ - context->domain = mono_domain_get (); - - if (*abort_requested) - mono_thread_interruption_checkpoint (); - - if (string_ctor) { - stackval_from_data (&mono_defaults.string_class->byval_arg, - frame->retval, (char*)&frame->retval->data.p, sig->pinvoke); - } else if (!MONO_TYPE_ISSTRUCT (sig->ret)) - stackval_from_data (sig->ret, frame->retval, (char*)&frame->retval->data.p, sig->pinvoke); - - context->current_frame = old_frame; - context->env_frame = old_env_frame; - context->current_env = old_env; -} - -static void -interp_delegate_ctor (MonoDomain *domain, MonoObject *this, MonoObject *target, RuntimeMethod *runtime_method) -{ - MonoDelegate *delegate = (MonoDelegate *)this; - - delegate->method_info = mono_method_get_object (domain, runtime_method->method, NULL); - delegate->target = target; - - if (target && target->vtable->klass == mono_defaults.transparent_proxy_class) { - MonoMethod *method = mono_marshal_get_remoting_invoke (runtime_method->method); - delegate->method_ptr = mono_interp_get_runtime_method (method); - } else { - delegate->method_ptr = runtime_method; - } -} - -MonoDelegate* -mono_interp_ftnptr_to_delegate (MonoClass *klass, gpointer ftn) -{ - MonoDelegate *d; - MonoJitInfo *ji; - MonoDomain *domain = mono_domain_get (); - - d = (MonoDelegate*)mono_object_new (domain, klass); - - ji = mono_jit_info_table_find (domain, ftn); - if (ji == NULL) - mono_raise_exception (mono_get_exception_argument ("", "Function pointer was not created by a Delegate.")); - - /* FIXME: discard the wrapper and call the original method */ - interp_delegate_ctor (domain, (MonoObject*)d, NULL, mono_interp_get_runtime_method (ji->method)); - - return d; -} - -/* - * From the spec: - * runtime specifies that the implementation of the method is automatically - * provided by the runtime and is primarily used for the methods of delegates. - */ -static void -ves_runtime_method (MonoInvocation *frame, ThreadContext *context) -{ - MonoMethod *method = frame->runtime_method->method; - const char *name = method->name; - MonoObject *obj = (MonoObject*)frame->obj; - - mono_class_init (method->klass); - - if (obj && mono_object_isinst (obj, mono_defaults.multicastdelegate_class)) { - if (*name == '.' && (strcmp (name, ".ctor") == 0)) { - interp_delegate_ctor (context->domain, obj, frame->stack_args[0].data.p, frame->stack_args[1].data.p); - return; - } - } - - if (obj && mono_object_isinst (obj, mono_defaults.array_class)) { - if (*name == 'S' && (strcmp (name, "Set") == 0)) { - ves_array_set (frame); - return; - } - if (*name == 'G' && (strcmp (name, "Get") == 0)) { - ves_array_get (frame); - return; - } - if (*name == 'A' && (strcmp (name, "Address") == 0)) { - ves_array_element_address (frame); - return; - } - } - - g_error ("Don't know how to exec runtime method %s.%s::%s", - method->klass->name_space, method->klass->name, - method->name); -} - -static char* -dump_stack (stackval *stack, stackval *sp) -{ - stackval *s = stack; - GString *str = g_string_new (""); - - if (sp == stack) - return g_string_free (str, FALSE); - - while (s < sp) { - g_string_append_printf (str, "[%lld/0x%0llx] ", s->data.l, s->data.l); - ++s; - } - return g_string_free (str, FALSE); -} - -static void -dump_stackval (GString *str, stackval *s, MonoType *type) -{ - switch (type->type) { - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_CHAR: - case MONO_TYPE_BOOLEAN: - g_string_append_printf (str, "[%d] ", s->data.i); - break; - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_ARRAY: - case MONO_TYPE_PTR: - case MONO_TYPE_I: - case MONO_TYPE_U: - g_string_append_printf (str, "[%p] ", s->data.p); - break; - case MONO_TYPE_VALUETYPE: - if (type->data.klass->enumtype) - g_string_append_printf (str, "[%d] ", s->data.i); - else - g_string_append_printf (str, "[vt:%p] ", s->data.p); - break; - case MONO_TYPE_R4: - case MONO_TYPE_R8: - g_string_append_printf (str, "[%g] ", s->data.f); - break; - case MONO_TYPE_I8: - case MONO_TYPE_U8: - default: - g_string_append_printf (str, "[%lld/0x%0llx] ", s->data.l, s->data.l); - break; - } -} - -static char* -dump_args (MonoInvocation *inv) -{ - GString *str = g_string_new (""); - int i; - MonoMethodSignature *signature = mono_method_signature (inv->runtime_method->method); - - if (signature->param_count == 0) - return g_string_free (str, FALSE); - - if (signature->hasthis) - g_string_append_printf (str, "%p ", inv->obj); - - for (i = 0; i < signature->param_count; ++i) - dump_stackval (str, inv->stack_args + i, signature->params [i]); - - return g_string_free (str, FALSE); -} - -static char* -dump_retval (MonoInvocation *inv) -{ - GString *str = g_string_new (""); - MonoType *ret = mono_method_signature (inv->runtime_method->method)->ret; - - if (ret->type != MONO_TYPE_VOID) - dump_stackval (str, inv->retval, ret); - - return g_string_free (str, FALSE); -} - -static char* -dump_frame (MonoInvocation *inv) -{ - GString *str = g_string_new (""); - int i; - char *args; - for (i = 0; inv; inv = inv->parent) { - if (inv->runtime_method != NULL) { - MonoMethod *method = inv->runtime_method->method; - MonoClass *k; - - int codep = 0; - const char * opname = ""; - char *name; - gchar *source = NULL; - - k = method->klass; - - if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) == 0 && - (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) == 0) { - MonoMethodHeader *hd = mono_method_get_header (method); - - if (hd != NULL) { - if (inv->ip) { - opname = mono_interp_opname [*inv->ip]; - codep = inv->ip - inv->runtime_method->code; - } else - opname = ""; - - source = mono_debug_source_location_from_il_offset (method, codep, NULL); - } - } - args = dump_args (inv); - name = mono_method_full_name (method, TRUE); - if (source) - g_string_append_printf (str, "#%d: 0x%05x %-10s in %s (%s) at %s\n", i, codep, opname, - name, args, source); - else - g_string_append_printf (str, "#%d: 0x%05x %-10s in %s (%s)\n", i, codep, opname, - name, args); - g_free (name); - g_free (args); - g_free (source); - ++i; - } - } - return g_string_free (str, FALSE); -} - -static MonoArray * -get_trace_ips (MonoDomain *domain, MonoInvocation *top) -{ - int i; - MonoArray *res; - MonoInvocation *inv; - - for (i = 0, inv = top; inv; inv = inv->parent) - if (inv->runtime_method != NULL) - ++i; - - res = mono_array_new (domain, mono_defaults.int_class, 2 * i); - - for (i = 0, inv = top; inv; inv = inv->parent) - if (inv->runtime_method != NULL) { - mono_array_set (res, gpointer, i, inv->runtime_method); - ++i; - mono_array_set (res, gpointer, i, (gpointer)inv->ip); - ++i; - } - - return res; -} - - -#define MYGUINT64_MAX 18446744073709551615ULL -#define MYGINT64_MAX 9223372036854775807LL -#define MYGINT64_MIN (-MYGINT64_MAX -1LL) - -#define MYGUINT32_MAX 4294967295U -#define MYGINT32_MAX 2147483647 -#define MYGINT32_MIN (-MYGINT32_MAX -1) - -#define CHECK_ADD_OVERFLOW(a,b) \ - (gint32)(b) >= 0 ? (gint32)(MYGINT32_MAX) - (gint32)(b) < (gint32)(a) ? -1 : 0 \ - : (gint32)(MYGINT32_MIN) - (gint32)(b) > (gint32)(a) ? +1 : 0 - -#define CHECK_SUB_OVERFLOW(a,b) \ - (gint32)(b) < 0 ? (gint32)(MYGINT32_MAX) + (gint32)(b) < (gint32)(a) ? -1 : 0 \ - : (gint32)(MYGINT32_MIN) + (gint32)(b) > (gint32)(a) ? +1 : 0 - -#define CHECK_ADD_OVERFLOW_UN(a,b) \ - (guint32)(MYGUINT32_MAX) - (guint32)(b) < (guint32)(a) ? -1 : 0 - -#define CHECK_SUB_OVERFLOW_UN(a,b) \ - (guint32)(a) < (guint32)(b) ? -1 : 0 - -#define CHECK_ADD_OVERFLOW64(a,b) \ - (gint64)(b) >= 0 ? (gint64)(MYGINT64_MAX) - (gint64)(b) < (gint64)(a) ? -1 : 0 \ - : (gint64)(MYGINT64_MIN) - (gint64)(b) > (gint64)(a) ? +1 : 0 - -#define CHECK_SUB_OVERFLOW64(a,b) \ - (gint64)(b) < 0 ? (gint64)(MYGINT64_MAX) + (gint64)(b) < (gint64)(a) ? -1 : 0 \ - : (gint64)(MYGINT64_MIN) + (gint64)(b) > (gint64)(a) ? +1 : 0 - -#define CHECK_ADD_OVERFLOW64_UN(a,b) \ - (guint64)(MYGUINT64_MAX) - (guint64)(b) < (guint64)(a) ? -1 : 0 - -#define CHECK_SUB_OVERFLOW64_UN(a,b) \ - (guint64)(a) < (guint64)(b) ? -1 : 0 - -#if SIZEOF_VOID_P == 4 -#define CHECK_ADD_OVERFLOW_NAT(a,b) CHECK_ADD_OVERFLOW(a,b) -#define CHECK_ADD_OVERFLOW_NAT_UN(a,b) CHECK_ADD_OVERFLOW_UN(a,b) -#else -#define CHECK_ADD_OVERFLOW_NAT(a,b) CHECK_ADD_OVERFLOW64(a,b) -#define CHECK_ADD_OVERFLOW_NAT_UN(a,b) CHECK_ADD_OVERFLOW64_UN(a,b) -#endif - -/* Resolves to TRUE if the operands would overflow */ -#define CHECK_MUL_OVERFLOW(a,b) \ - ((gint32)(a) == 0) || ((gint32)(b) == 0) ? 0 : \ - (((gint32)(a) > 0) && ((gint32)(b) == -1)) ? FALSE : \ - (((gint32)(a) < 0) && ((gint32)(b) == -1)) ? (a == - MYGINT32_MAX) : \ - (((gint32)(a) > 0) && ((gint32)(b) > 0)) ? (gint32)(a) > ((MYGINT32_MAX) / (gint32)(b)) : \ - (((gint32)(a) > 0) && ((gint32)(b) < 0)) ? (gint32)(a) > ((MYGINT32_MIN) / (gint32)(b)) : \ - (((gint32)(a) < 0) && ((gint32)(b) > 0)) ? (gint32)(a) < ((MYGINT32_MIN) / (gint32)(b)) : \ - (gint32)(a) < ((MYGINT32_MAX) / (gint32)(b)) - -#define CHECK_MUL_OVERFLOW_UN(a,b) \ - ((guint32)(a) == 0) || ((guint32)(b) == 0) ? 0 : \ - (guint32)(b) > ((MYGUINT32_MAX) / (guint32)(a)) - -#define CHECK_MUL_OVERFLOW64(a,b) \ - ((gint64)(a) == 0) || ((gint64)(b) == 0) ? 0 : \ - (((gint64)(a) > 0) && ((gint64)(b) == -1)) ? FALSE : \ - (((gint64)(a) < 0) && ((gint64)(b) == -1)) ? (a == - MYGINT64_MAX) : \ - (((gint64)(a) > 0) && ((gint64)(b) > 0)) ? (gint64)(a) > ((MYGINT64_MAX) / (gint64)(b)) : \ - (((gint64)(a) > 0) && ((gint64)(b) < 0)) ? (gint64)(a) > ((MYGINT64_MIN) / (gint64)(b)) : \ - (((gint64)(a) < 0) && ((gint64)(b) > 0)) ? (gint64)(a) < ((MYGINT64_MIN) / (gint64)(b)) : \ - (gint64)(a) < ((MYGINT64_MAX) / (gint64)(b)) - -#define CHECK_MUL_OVERFLOW64_UN(a,b) \ - ((guint64)(a) == 0) || ((guint64)(b) == 0) ? 0 : \ - (guint64)(b) > ((MYGUINT64_MAX) / (guint64)(a)) - -#if SIZEOF_VOID_P == 4 -#define CHECK_MUL_OVERFLOW_NAT(a,b) CHECK_MUL_OVERFLOW(a,b) -#define CHECK_MUL_OVERFLOW_NAT_UN(a,b) CHECK_MUL_OVERFLOW_UN(a,b) -#else -#define CHECK_MUL_OVERFLOW_NAT(a,b) CHECK_MUL_OVERFLOW64(a,b) -#define CHECK_MUL_OVERFLOW_NAT_UN(a,b) CHECK_MUL_OVERFLOW64_UN(a,b) -#endif - -static MonoObject* -interp_mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc) -{ - MonoInvocation frame; - ThreadContext * volatile context = TlsGetValue (thread_context_id); - MonoObject *retval = NULL; - MonoMethodSignature *sig = mono_method_signature (method); - MonoClass *klass = mono_class_from_mono_type (sig->ret); - int i, type, isobject = 0; - void *ret = NULL; - stackval result; - stackval *args = alloca (sizeof (stackval) * sig->param_count); - ThreadContext context_struct; - MonoInvocation *old_frame = NULL; - jmp_buf env; - - frame.ex = NULL; - - if (setjmp(env)) { - if (context != &context_struct) { - context->domain = mono_domain_get (); - context->current_frame = old_frame; - context->managed_code = 0; - } else - TlsSetValue (thread_context_id, NULL); - if (exc != NULL) - *exc = (MonoObject *)frame.ex; - return retval; - } - - if (context == NULL) { - context = &context_struct; - context_struct.base_frame = &frame; - context_struct.current_frame = NULL; - context_struct.env_frame = &frame; - context_struct.current_env = &env; - context_struct.search_for_handler = 0; - context_struct.managed_code = 0; - TlsSetValue (thread_context_id, context); - } - else - old_frame = context->current_frame; - - context->domain = mono_domain_get (); - - switch (sig->ret->type) { - case MONO_TYPE_VOID: - break; - case MONO_TYPE_STRING: - case MONO_TYPE_OBJECT: - case MONO_TYPE_CLASS: - case MONO_TYPE_ARRAY: - case MONO_TYPE_SZARRAY: - isobject = 1; - break; - case MONO_TYPE_VALUETYPE: - retval = mono_object_new (context->domain, klass); - ret = ((char*)retval) + sizeof (MonoObject); - if (!sig->ret->data.klass->enumtype) - result.data.vt = ret; - break; - default: - retval = mono_object_new (context->domain, klass); - ret = ((char*)retval) + sizeof (MonoObject); - break; - } - - for (i = 0; i < sig->param_count; ++i) { - if (sig->params [i]->byref) { - args [i].data.p = params [i]; - continue; - } - type = sig->params [i]->type; -handle_enum: - switch (type) { - case MONO_TYPE_U1: - case MONO_TYPE_I1: - case MONO_TYPE_BOOLEAN: - args [i].data.i = *(MonoBoolean*)params [i]; - break; - case MONO_TYPE_U2: - case MONO_TYPE_I2: - case MONO_TYPE_CHAR: - args [i].data.i = *(gint16*)params [i]; - break; -#if SIZEOF_VOID_P == 4 - case MONO_TYPE_U: /* use VAL_POINTER? */ - case MONO_TYPE_I: -#endif - case MONO_TYPE_U4: - case MONO_TYPE_I4: - args [i].data.i = *(gint32*)params [i]; - break; -#if SIZEOF_VOID_P == 8 - case MONO_TYPE_U: - case MONO_TYPE_I: -#endif - case MONO_TYPE_U8: - case MONO_TYPE_I8: - args [i].data.l = *(gint64*)params [i]; - break; - case MONO_TYPE_VALUETYPE: - if (sig->params [i]->data.klass->enumtype) { - type = sig->params [i]->data.klass->enum_basetype->type; - goto handle_enum; - } else { - args [i].data.p = params [i]; - } - break; - case MONO_TYPE_STRING: - case MONO_TYPE_CLASS: - case MONO_TYPE_ARRAY: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_OBJECT: - args [i].data.p = params [i]; - break; - default: - g_error ("type 0x%x not handled in runtime invoke", sig->params [i]->type); - } - } - - if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) - method = mono_marshal_get_native_wrapper (method); - INIT_FRAME(&frame,context->current_frame,obj,args,&result,method); - if (exc) - frame.invoke_trap = 1; - context->managed_code = 1; - ves_exec_method_with_context (&frame, context); - context->managed_code = 0; - if (context == &context_struct) - TlsSetValue (thread_context_id, NULL); - else - context->current_frame = old_frame; - if (frame.ex != NULL) { - if (exc != NULL) { - *exc = (MonoObject*) frame.ex; - return NULL; - } - if (context->current_env != NULL) { - context->env_frame->ex = frame.ex; - longjmp(*context->current_env, 1); - } - else - printf("dropped exception...\n"); - } - if (sig->ret->type == MONO_TYPE_VOID && !method->string_ctor) - return NULL; - if (isobject || method->string_ctor) - return result.data.p; - stackval_to_data (sig->ret, &result, ret, sig->pinvoke); - return retval; -} - -static stackval * -do_icall (ThreadContext *context, int op, stackval *sp, gpointer ptr) -{ - MonoInvocation *old_frame = context->current_frame; - MonoInvocation *old_env_frame = context->env_frame; - jmp_buf *old_env = context->current_env; - jmp_buf env; - - if (setjmp (env)) { - context->current_frame = old_frame; - context->env_frame = old_env_frame; - context->current_env = old_env; - context->managed_code = 1; - return sp; - } - - context->env_frame = context->current_frame; - context->current_env = &env; - context->managed_code = 0; - - switch (op) { - case MINT_ICALL_V_V: { - void (*func)() = ptr; - func (); - break; - } - case MINT_ICALL_P_V: { - void (*func)(gpointer) = ptr; - func (sp [-1].data.p); - sp --; - break; - } - case MINT_ICALL_P_P: { - gpointer (*func)(gpointer) = ptr; - sp [-1].data.p = func (sp [-1].data.p); - break; - } - case MINT_ICALL_PP_V: { - void (*func)(gpointer,gpointer) = ptr; - sp -= 2; - func (sp [0].data.p, sp [1].data.p); - break; - } - case MINT_ICALL_PI_V: { - void (*func)(gpointer,int) = ptr; - sp -= 2; - func (sp [0].data.p, sp [1].data.i); - break; - } - case MINT_ICALL_PP_P: { - gpointer (*func)(gpointer,gpointer) = ptr; - --sp; - sp [-1].data.p = func (sp [-1].data.p, sp [0].data.p); - break; - } - case MINT_ICALL_PI_P: { - gpointer (*func)(gpointer,int) = ptr; - --sp; - sp [-1].data.p = func (sp [-1].data.p, sp [0].data.i); - break; - } - case MINT_ICALL_PPP_V: { - void (*func)(gpointer,gpointer,gpointer) = ptr; - sp -= 3; - func (sp [0].data.p, sp [1].data.p, sp [2].data.p); - break; - } - case MINT_ICALL_PPI_V: { - void (*func)(gpointer,gpointer,int) = ptr; - sp -= 3; - func (sp [0].data.p, sp [1].data.p, sp [2].data.i); - break; - } - default: - g_assert_not_reached (); - } - - context->env_frame = old_env_frame; - context->current_env = old_env; - - return sp; -} - -static mono_mutex_t create_method_pointer_mutex; - -static MonoGHashTable *method_pointer_hash = NULL; - -static void * -mono_create_method_pointer (MonoMethod *method) -{ - gpointer addr; - MonoJitInfo *ji; - - mono_mutex_lock (&create_method_pointer_mutex); - if (!method_pointer_hash) { - MONO_GC_REGISTER_ROOT (method_pointer_hash); - method_pointer_hash = mono_g_hash_table_new (NULL, NULL); - } - addr = mono_g_hash_table_lookup (method_pointer_hash, method); - if (addr) { - mono_mutex_unlock (&create_method_pointer_mutex); - return addr; - } - - /* - * If it is a static P/Invoke method, we can just return the pointer - * to the method implementation. - */ - if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL && ((MonoMethodPInvoke*) method)->addr) { - ji = g_new0 (MonoJitInfo, 1); - ji->method = method; - ji->code_size = 1; - ji->code_start = addr = ((MonoMethodPInvoke*) method)->addr; - - mono_jit_info_table_add (mono_get_root_domain (), ji); - } - else - addr = mono_arch_create_method_pointer (method); - - mono_g_hash_table_insert (method_pointer_hash, method, addr); - mono_mutex_unlock (&create_method_pointer_mutex); - - return addr; -} - -#if COUNT_OPS -static int opcode_counts[512]; - -#define COUNT_OP(op) opcode_counts[op]++ -#else -#define COUNT_OP(op) -#endif - -#if DEBUG_INTERP -#define DUMP_INSTR() \ - if (tracing > 1) { \ - char *ins; \ - if (sp > frame->stack) { \ - ins = dump_stack (frame->stack, sp); \ - } else { \ - ins = g_strdup (""); \ - } \ - sp->data.l = 0; \ - output_indent (); \ - g_print ("(%u) ", GetCurrentThreadId()); \ - mono_interp_dis_mintop(rtm->code, ip); \ - g_print ("\t%d:%s\n", vt_sp - vtalloc, ins); \ - g_free (ins); \ - } -#else -#define DUMP_INSTR() -#endif - -#ifdef __GNUC__ -#define USE_COMPUTED_GOTO 1 -#endif -#if USE_COMPUTED_GOTO -#define MINT_IN_SWITCH(op) COUNT_OP(op); goto *in_labels[op]; -#define MINT_IN_CASE(x) LAB_ ## x: -#if DEBUG_INTERP -#define MINT_IN_BREAK if (tracing > 1) goto main_loop; else { COUNT_OP(*ip); goto *in_labels[*ip]; } -#else -#define MINT_IN_BREAK { COUNT_OP(*ip); goto *in_labels[*ip]; } -#endif -#define MINT_IN_DEFAULT mint_default: if (0) goto mint_default; /* make gcc shut up */ -#else -#define MINT_IN_SWITCH(op) switch (op) -#define MINT_IN_CASE(x) case x: -#define MINT_IN_BREAK break -#define MINT_IN_DEFAULT default: -#endif - -/* - * Defining this causes register allocation errors in some versions of gcc: - * error: unable to find a register to spill in class `SIREG' - */ -/* #define MINT_USE_DEDICATED_IP_REG */ - -static void -ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context) -{ - MonoInvocation child_frame; - GSList *finally_ips = NULL; - const unsigned short *endfinally_ip = NULL; -#if defined(__GNUC__) && defined (i386) && defined (MINT_USE_DEDICATED_IP_REG) - register const unsigned short *ip asm ("%esi"); -#else - register const unsigned short *ip; -#endif - register stackval *sp; - RuntimeMethod *rtm; -#if DEBUG_INTERP - gint tracing = global_tracing; - unsigned char *vtalloc; -#endif - int i32; - unsigned char *vt_sp; - char *locals; - MonoObject *o = NULL; - MonoClass *c; -#if USE_COMPUTED_GOTO - static void *in_labels[] = { -#define OPDEF(a,b,c,d) \ - &&LAB_ ## a, -#include "mintops.def" - 0 }; -#endif - - frame->ex = NULL; - frame->ex_handler = NULL; - frame->ip = NULL; - context->current_frame = frame; - - DEBUG_ENTER (); - - if (!frame->runtime_method->transformed) { - context->managed_code = 0; - frame->ex = mono_interp_transform_method (frame->runtime_method, context); - context->managed_code = 1; - if (frame->ex) { - rtm = NULL; - ip = NULL; - goto exit_frame; - } - } - - rtm = frame->runtime_method; - frame->args = alloca (rtm->alloca_size); - sp = frame->stack = (stackval *)((char *)frame->args + rtm->args_size); -#if DEBUG_INTERP - if (tracing > 1) - memset(sp, 0, rtm->stack_size); -#endif - vt_sp = (char *)sp + rtm->stack_size; -#if DEBUG_INTERP - vtalloc = vt_sp; -#endif - locals = vt_sp + rtm->vt_stack_size; - - child_frame.parent = frame; - - /* ready to go */ - ip = rtm->code; - - /* - * using while (ip < end) may result in a 15% performance drop, - * but it may be useful for debug - */ - while (1) { - main_loop: - /* g_assert (sp >= frame->stack); */ - /* g_assert(vt_sp - vtalloc <= rtm->vt_stack_size); */ - DUMP_INSTR(); - MINT_IN_SWITCH (*ip) { - MINT_IN_CASE(MINT_INITLOCALS) - memset (locals, 0, rtm->locals_size); - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_NOP) - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BREAK) - ++ip; - G_BREAKPOINT (); /* this is not portable... */ - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDNULL) - sp->data.p = NULL; - ++ip; - ++sp; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_VTRESULT) { - int ret_size = * (guint16 *)(ip + 1); - char *ret_vt_sp = vt_sp; - vt_sp -= READ32(ip + 2); - if (ret_size > 0) { - memmove (vt_sp, ret_vt_sp, ret_size); - vt_sp += (ret_size + 7) & ~7; - } - ip += 4; - MINT_IN_BREAK; - } -#define LDC(n) do { sp->data.i = (n); ++ip; ++sp; } while (0) - MINT_IN_CASE(MINT_LDC_I4_M1) - LDC(-1); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_I4_0) - LDC(0); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_I4_1) - LDC(1); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_I4_2) - LDC(2); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_I4_3) - LDC(3); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_I4_4) - LDC(4); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_I4_5) - LDC(5); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_I4_6) - LDC(6); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_I4_7) - LDC(7); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_I4_8) - LDC(8); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_I4_S) - sp->data.i = *(const short *)(ip + 1); - ip += 2; - ++sp; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_I4) - ++ip; - sp->data.i = READ32 (ip); - ip += 2; - ++sp; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_I8) - ++ip; - sp->data.l = READ64 (ip); - ip += 4; - ++sp; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDC_R4) { - guint32 val; - ++ip; - val = READ32(ip); - sp->data.f = * (float *)&val; - ip += 2; - ++sp; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_LDC_R8) - sp->data.l = READ64 (ip + 1); /* note union usage */ - ip += 5; - ++sp; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_DUP) - sp [0] = sp[-1]; - ++sp; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_DUP_VT) - i32 = READ32 (ip + 1); - sp->data.p = vt_sp; - memcpy(sp->data.p, sp [-1].data.p, i32); - vt_sp += (i32 + 7) & ~7; - ++sp; - ip += 3; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_POP) - ++ip; - --sp; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_JMP) { - RuntimeMethod *new_method = rtm->data_items [* (guint16 *)(ip + 1)]; - if (!new_method->transformed) { - frame->ip = ip; - frame->ex = mono_interp_transform_method (new_method, context); - if (frame->ex) - goto exit_frame; - } - ip += 2; - if (new_method->alloca_size > rtm->alloca_size) - g_error ("MINT_JMP to method which needs more stack space (%d > %d)", new_method->alloca_size, rtm->alloca_size); - rtm = frame->runtime_method = new_method; - vt_sp = (char *)sp + rtm->stack_size; -#if DEBUG_INTERP - vtalloc = vt_sp; -#endif - locals = vt_sp + rtm->vt_stack_size; - ip = rtm->new_body_start; /* bypass storing input args from callers frame */ - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_CALLI) { - MonoMethodSignature *csignature; - stackval *endsp = sp; - - frame->ip = ip; - - csignature = rtm->data_items [* (guint16 *)(ip + 1)]; - ip += 2; - --sp; - --endsp; - child_frame.runtime_method = sp->data.p; - - sp->data.p = vt_sp; - child_frame.retval = sp; - /* decrement by the actual number of args */ - sp -= csignature->param_count; - child_frame.stack_args = sp; - if (csignature->hasthis) { - --sp; - child_frame.obj = sp->data.p; - } else { - child_frame.obj = NULL; - } - if (csignature->hasthis && - ((MonoObject *)child_frame.obj)->vtable->klass == mono_defaults.transparent_proxy_class) { - child_frame.runtime_method = mono_interp_get_runtime_method ( - mono_marshal_get_remoting_invoke (child_frame.runtime_method->method)); - } else if (child_frame.runtime_method->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) - child_frame.runtime_method = mono_interp_get_runtime_method ( - mono_marshal_get_native_wrapper (child_frame.runtime_method->method)); - - ves_exec_method_with_context (&child_frame, context); - - context->current_frame = frame; - - if (child_frame.ex) { - /* - * An exception occurred, need to run finally, fault and catch handlers.. - */ - frame->ex = child_frame.ex; - goto handle_finally; - } - - /* need to handle typedbyref ... */ - if (csignature->ret->type != MONO_TYPE_VOID) { - *sp = *endsp; - sp++; - } - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_CALLI_NAT) { - MonoMethodSignature *csignature; - stackval *endsp = sp; - unsigned char *code = NULL; - - frame->ip = ip; - - csignature = rtm->data_items [* (guint16 *)(ip + 1)]; - ip += 2; - --sp; - --endsp; - code = sp->data.p; - child_frame.runtime_method = NULL; - - sp->data.p = vt_sp; - child_frame.retval = sp; - /* decrement by the actual number of args */ - sp -= csignature->param_count; - child_frame.stack_args = sp; - if (csignature->hasthis) { - --sp; - child_frame.obj = sp->data.p; - } else { - child_frame.obj = NULL; - } - ves_pinvoke_method (&child_frame, csignature, (MonoFunc) code, FALSE, context); - - context->current_frame = frame; - - if (child_frame.ex) { - /* - * An exception occurred, need to run finally, fault and catch handlers.. - */ - frame->ex = child_frame.ex; - if (context->search_for_handler) { - context->search_for_handler = 0; - goto handle_exception; - } - goto handle_finally; - } - - /* need to handle typedbyref ... */ - if (csignature->ret->type != MONO_TYPE_VOID) { - *sp = *endsp; - sp++; - } - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_CALL) { - stackval *endsp = sp; - - frame->ip = ip; - - child_frame.runtime_method = rtm->data_items [* (guint16 *)(ip + 1)]; - ip += 2; - sp->data.p = vt_sp; - child_frame.retval = sp; - /* decrement by the actual number of args */ - sp -= child_frame.runtime_method->param_count; - child_frame.stack_args = sp; - if (child_frame.runtime_method->hasthis) { - --sp; - child_frame.obj = sp->data.p; - } else { - child_frame.obj = NULL; - } - if (child_frame.runtime_method->hasthis && !child_frame.runtime_method->valuetype && - ((MonoObject *)child_frame.obj)->vtable->klass == mono_defaults.transparent_proxy_class) { - child_frame.runtime_method = mono_interp_get_runtime_method ( - mono_marshal_get_remoting_invoke (child_frame.runtime_method->method)); - } - ves_exec_method_with_context (&child_frame, context); - - context->current_frame = frame; - - if (child_frame.ex) { - /* - * An exception occurred, need to run finally, fault and catch handlers.. - */ - frame->ex = child_frame.ex; - goto handle_finally; - } - - /* need to handle typedbyref ... */ - *sp = *endsp; - sp++; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_VCALL) { - frame->ip = ip; - - child_frame.runtime_method = rtm->data_items [* (guint16 *)(ip + 1)]; - ip += 2; - - sp->data.p = vt_sp; - child_frame.retval = sp; - /* decrement by the actual number of args */ - sp -= child_frame.runtime_method->param_count; - child_frame.stack_args = sp; - if (child_frame.runtime_method->hasthis) { - --sp; - child_frame.obj = sp->data.p; - } else { - child_frame.obj = NULL; - } - - if (child_frame.runtime_method->hasthis && !child_frame.runtime_method->valuetype && - ((MonoObject *)child_frame.obj)->vtable->klass == mono_defaults.transparent_proxy_class) { - child_frame.runtime_method = mono_interp_get_runtime_method ( - mono_marshal_get_remoting_invoke (child_frame.runtime_method->method)); - } - - ves_exec_method_with_context (&child_frame, context); - - context->current_frame = frame; - - if (child_frame.ex) { - /* - * An exception occurred, need to run finally, fault and catch handlers.. - */ - frame->ex = child_frame.ex; - goto handle_finally; - } - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_CALLVIRT) { - stackval *endsp = sp; - MonoObject *this_arg; - guint32 token; - - frame->ip = ip; - - token = * (unsigned short *)(ip + 1); - ip += 2; - child_frame.runtime_method = rtm->data_items [token]; - sp->data.p = vt_sp; - child_frame.retval = sp; - - /* decrement by the actual number of args */ - sp -= child_frame.runtime_method->param_count; - child_frame.stack_args = sp; - --sp; - child_frame.obj = this_arg = sp->data.p; - if (!this_arg) - THROW_EX (mono_get_exception_null_reference(), ip - 2); - child_frame.runtime_method = get_virtual_method (child_frame.runtime_method, this_arg); - - if (this_arg->vtable->klass->valuetype && child_frame.runtime_method->valuetype) { - child_frame.obj = (char *)this_arg + sizeof(MonoObject); - } - - ves_exec_method_with_context (&child_frame, context); - - context->current_frame = frame; - - if (child_frame.ex) { - /* - * An exception occurred, need to run finally, fault and catch handlers.. - */ - frame->ex = child_frame.ex; - if (context->search_for_handler) { - context->search_for_handler = 0; - goto handle_exception; - } - goto handle_finally; - } - - /* need to handle typedbyref ... */ - *sp = *endsp; - sp++; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_VCALLVIRT) { - MonoObject *this_arg; - guint32 token; - - frame->ip = ip; - - token = * (unsigned short *)(ip + 1); - ip += 2; - child_frame.runtime_method = rtm->data_items [token]; - sp->data.p = vt_sp; - child_frame.retval = sp; - - /* decrement by the actual number of args */ - sp -= child_frame.runtime_method->param_count; - child_frame.stack_args = sp; - --sp; - child_frame.obj = this_arg = sp->data.p; - if (!this_arg) - THROW_EX (mono_get_exception_null_reference(), ip - 2); - child_frame.runtime_method = get_virtual_method (child_frame.runtime_method, this_arg); - - if (this_arg->vtable->klass->valuetype && child_frame.runtime_method->valuetype) { - child_frame.obj = (char *)this_arg + sizeof(MonoObject); - } - - ves_exec_method_with_context (&child_frame, context); - - context->current_frame = frame; - - if (child_frame.ex) { - /* - * An exception occurred, need to run finally, fault and catch handlers.. - */ - frame->ex = child_frame.ex; - if (context->search_for_handler) { - context->search_for_handler = 0; - goto handle_exception; - } - goto handle_finally; - } - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_CALLINT) - ves_pinvoke_method (frame, mono_method_signature (frame->runtime_method->method), ((MonoMethodPInvoke*) frame->runtime_method->method)->addr, - frame->runtime_method->method->string_ctor, context); - if (frame->ex) { - rtm = NULL; - goto handle_exception; - } - goto exit_frame; - MINT_IN_CASE(MINT_CALLRUN) - ves_runtime_method (frame, context); - if (frame->ex) { - rtm = NULL; - goto handle_exception; - } - goto exit_frame; - MINT_IN_CASE(MINT_RET) - --sp; - *frame->retval = *sp; - if (sp > frame->stack) - g_warning ("ret: more values on stack: %d", sp-frame->stack); - goto exit_frame; - MINT_IN_CASE(MINT_RET_VOID) - if (sp > frame->stack) - g_warning ("ret.void: more values on stack: %d", sp-frame->stack); - goto exit_frame; - MINT_IN_CASE(MINT_RET_VT) - i32 = READ32(ip + 1); - --sp; - memcpy(frame->retval->data.p, sp->data.p, i32); - if (sp > frame->stack) - g_warning ("ret.vt: more values on stack: %d", sp-frame->stack); - goto exit_frame; - MINT_IN_CASE(MINT_BR_S) - ip += (short) *(ip + 1); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BR) - ip += (gint32) READ32(ip + 1); - MINT_IN_BREAK; -#define ZEROP_S(datamem, op) \ - --sp; \ - if (sp->data.datamem op 0) \ - ip += * (gint16 *)(ip + 1); \ - else \ - ip += 2; - -#define ZEROP(datamem, op) \ - --sp; \ - if (sp->data.datamem op 0) \ - ip += READ32(ip + 1); \ - else \ - ip += 3; - - MINT_IN_CASE(MINT_BRFALSE_I4_S) - ZEROP_S(i, ==); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BRFALSE_I8_S) - ZEROP_S(l, ==); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BRFALSE_R8_S) - ZEROP_S(f, ==); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BRFALSE_I4) - ZEROP(i, ==); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BRFALSE_I8) - ZEROP(l, ==); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BRFALSE_R8) - ZEROP_S(f, ==); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BRTRUE_I4_S) - ZEROP_S(i, !=); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BRTRUE_I8_S) - ZEROP_S(l, !=); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BRTRUE_R8_S) - ZEROP_S(f, !=); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BRTRUE_I4) - ZEROP(i, !=); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BRTRUE_I8) - ZEROP(l, !=); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BRTRUE_R8) - ZEROP(f, !=); - MINT_IN_BREAK; -#define CONDBR_S(cond) \ - sp -= 2; \ - if (cond) \ - ip += * (gint16 *)(ip + 1); \ - else \ - ip += 2; -#define BRELOP_S(datamem, op) \ - CONDBR_S(sp[0].data.datamem op sp[1].data.datamem) - -#define CONDBR(cond) \ - sp -= 2; \ - if (cond) \ - ip += READ32(ip + 1); \ - else \ - ip += 3; - -#define BRELOP(datamem, op) \ - CONDBR(sp[0].data.datamem op sp[1].data.datamem) - - MINT_IN_CASE(MINT_BEQ_I4_S) - BRELOP_S(i, ==) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BEQ_I8_S) - BRELOP_S(l, ==) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BEQ_R8_S) - CONDBR_S(!isunordered (sp [0].data.f, sp [1].data.f) && sp[0].data.f == sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BEQ_I4) - BRELOP(i, ==) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BEQ_I8) - BRELOP(l, ==) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BEQ_R8) - CONDBR(!isunordered (sp [0].data.f, sp [1].data.f) && sp[0].data.f == sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGE_I4_S) - BRELOP_S(i, >=) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGE_I8_S) - BRELOP_S(l, >=) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGE_R8_S) - CONDBR_S(!isunordered (sp [0].data.f, sp [1].data.f) && sp[0].data.f >= sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGE_I4) - BRELOP(i, >=) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGE_I8) - BRELOP(l, >=) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGE_R8) - CONDBR(!isunordered (sp [0].data.f, sp [1].data.f) && sp[0].data.f >= sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGT_I4_S) - BRELOP_S(i, >) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGT_I8_S) - BRELOP_S(l, >) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGT_R8_S) - CONDBR_S(!isunordered (sp [0].data.f, sp [1].data.f) && sp[0].data.f > sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGT_I4) - BRELOP(i, >) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGT_I8) - BRELOP(l, >) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGT_R8) - CONDBR(!isunordered (sp [0].data.f, sp [1].data.f) && sp[0].data.f > sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLT_I4_S) - BRELOP_S(i, <) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLT_I8_S) - BRELOP_S(l, <) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLT_R8_S) - CONDBR_S(!isunordered (sp [0].data.f, sp [1].data.f) && sp[0].data.f < sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLT_I4) - BRELOP(i, <) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLT_I8) - BRELOP(l, <) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLT_R8) - CONDBR(!isunordered (sp [0].data.f, sp [1].data.f) && sp[0].data.f < sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLE_I4_S) - BRELOP_S(i, <=) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLE_I8_S) - BRELOP_S(l, <=) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLE_R8_S) - CONDBR_S(!isunordered (sp [0].data.f, sp [1].data.f) && sp[0].data.f <= sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLE_I4) - BRELOP(i, <=) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLE_I8) - BRELOP(l, <=) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLE_R8) - CONDBR(!isunordered (sp [0].data.f, sp [1].data.f) && sp[0].data.f <= sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BNE_UN_I4_S) - BRELOP_S(i, !=) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BNE_UN_I8_S) - BRELOP_S(l, !=) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BNE_UN_R8_S) - CONDBR_S(isunordered (sp [0].data.f, sp [1].data.f) || sp[0].data.f != sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BNE_UN_I4) - BRELOP(i, !=) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BNE_UN_I8) - BRELOP(l, !=) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BNE_UN_R8) - CONDBR(isunordered (sp [0].data.f, sp [1].data.f) || sp[0].data.f != sp[1].data.f) - MINT_IN_BREAK; - -#define BRELOP_S_CAST(datamem, op, type) \ - sp -= 2; \ - if ((type) sp[0].data.datamem op (type) sp[1].data.datamem) \ - ip += * (gint16 *)(ip + 1); \ - else \ - ip += 2; - -#define BRELOP_CAST(datamem, op, type) \ - sp -= 2; \ - if ((type) sp[0].data.datamem op (type) sp[1].data.datamem) \ - ip += READ32(ip + 1); \ - else \ - ip += 3; - - MINT_IN_CASE(MINT_BGE_UN_I4_S) - BRELOP_S_CAST(i, >=, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGE_UN_I8_S) - BRELOP_S_CAST(l, >=, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGE_UN_R8_S) - CONDBR_S(isunordered (sp [0].data.f, sp [1].data.f) || sp[0].data.f >= sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGE_UN_I4) - BRELOP_CAST(i, >=, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGE_UN_I8) - BRELOP_CAST(l, >=, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGE_UN_R8) - CONDBR(isunordered (sp [0].data.f, sp [1].data.f) || sp[0].data.f >= sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGT_UN_I4_S) - BRELOP_S_CAST(i, >, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGT_UN_I8_S) - BRELOP_S_CAST(l, >, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGT_UN_R8_S) - CONDBR_S(isunordered (sp [0].data.f, sp [1].data.f) || sp[0].data.f > sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGT_UN_I4) - BRELOP_CAST(i, >, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGT_UN_I8) - BRELOP_CAST(l, >, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BGT_UN_R8) - CONDBR(isunordered (sp [0].data.f, sp [1].data.f) || sp[0].data.f > sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLE_UN_I4_S) - BRELOP_S_CAST(i, <=, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLE_UN_I8_S) - BRELOP_S_CAST(l, <=, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLE_UN_R8_S) - CONDBR_S(isunordered (sp [0].data.f, sp [1].data.f) || sp[0].data.f <= sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLE_UN_I4) - BRELOP_CAST(i, <=, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLE_UN_I8) - BRELOP_CAST(l, <=, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLE_UN_R8) - CONDBR(isunordered (sp [0].data.f, sp [1].data.f) || sp[0].data.f <= sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLT_UN_I4_S) - BRELOP_S_CAST(i, <, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLT_UN_I8_S) - BRELOP_S_CAST(l, <, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLT_UN_R8_S) - CONDBR_S(isunordered (sp [0].data.f, sp [1].data.f) || sp[0].data.f < sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLT_UN_I4) - BRELOP_CAST(i, <, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLT_UN_I8) - BRELOP_CAST(l, <, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BLT_UN_R8) - CONDBR(isunordered (sp [0].data.f, sp [1].data.f) || sp[0].data.f < sp[1].data.f) - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SWITCH) { - guint32 n; - const unsigned short *st; - ++ip; - n = READ32 (ip); - ip += 2; - st = ip + 2 * n; - --sp; - if ((guint32)sp->data.i < n) { - gint offset; - ip += 2 * (guint32)sp->data.i; - offset = READ32 (ip); - ip = st + offset; - } else { - ip = st; - } - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_LDIND_I1) - ++ip; - sp[-1].data.i = *(gint8*)sp[-1].data.p; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDIND_U1) - ++ip; - sp[-1].data.i = *(guint8*)sp[-1].data.p; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDIND_I2) - ++ip; - sp[-1].data.i = *(gint16*)sp[-1].data.p; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDIND_U2) - ++ip; - sp[-1].data.i = *(guint16*)sp[-1].data.p; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDIND_I4) /* Fall through */ - MINT_IN_CASE(MINT_LDIND_U4) - ++ip; - sp[-1].data.i = *(gint32*)sp[-1].data.p; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDIND_I8) - ++ip; - sp[-1].data.l = *(gint64*)sp[-1].data.p; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDIND_I) - ++ip; - sp[-1].data.p = *(gpointer*)sp[-1].data.p; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDIND_R4) - ++ip; - sp[-1].data.f = *(gfloat*)sp[-1].data.p; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDIND_R8) - ++ip; - sp[-1].data.f = *(gdouble*)sp[-1].data.p; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDIND_REF) - ++ip; - sp[-1].data.p = *(gpointer*)sp[-1].data.p; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_STIND_REF) - ++ip; - sp -= 2; - * (gpointer *) sp->data.p = sp[1].data.p; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_STIND_I1) - ++ip; - sp -= 2; - * (gint8 *) sp->data.p = (gint8)sp[1].data.i; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_STIND_I2) - ++ip; - sp -= 2; - * (gint16 *) sp->data.p = (gint16)sp[1].data.i; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_STIND_I4) - ++ip; - sp -= 2; - * (gint32 *) sp->data.p = sp[1].data.i; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_STIND_I) - ++ip; - sp -= 2; - * (mono_i *) sp->data.p = (mono_i)sp[1].data.p; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_STIND_I8) - ++ip; - sp -= 2; - * (gint64 *) sp->data.p = sp[1].data.l; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_STIND_R4) - ++ip; - sp -= 2; - * (float *) sp->data.p = (gfloat)sp[1].data.f; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_STIND_R8) - ++ip; - sp -= 2; - * (double *) sp->data.p = sp[1].data.f; - MINT_IN_BREAK; -#define BINOP(datamem, op) \ - --sp; \ - sp [-1].data.datamem = sp [-1].data.datamem op sp [0].data.datamem; \ - ++ip; - MINT_IN_CASE(MINT_ADD_I4) - BINOP(i, +); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_ADD_I8) - BINOP(l, +); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_ADD_R8) - BINOP(f, +); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_ADD1_I4) - ++sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SUB_I4) - BINOP(i, -); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SUB_I8) - BINOP(l, -); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SUB_R8) - BINOP(f, -); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SUB1_I4) - --sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_MUL_I4) - BINOP(i, *); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_MUL_I8) - BINOP(l, *); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_MUL_R8) - BINOP(f, *); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_DIV_I4) - if (sp [-1].data.i == 0) - THROW_EX (mono_get_exception_divide_by_zero (), ip); - BINOP(i, /); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_DIV_I8) - if (sp [-1].data.l == 0) - THROW_EX (mono_get_exception_divide_by_zero (), ip); - BINOP(l, /); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_DIV_R8) - BINOP(f, /); - MINT_IN_BREAK; - -#define BINOP_CAST(datamem, op, type) \ - --sp; \ - sp [-1].data.datamem = (type)sp [-1].data.datamem op (type)sp [0].data.datamem; \ - ++ip; - MINT_IN_CASE(MINT_DIV_UN_I4) - if (sp [-1].data.i == 0) - THROW_EX (mono_get_exception_divide_by_zero (), ip); - BINOP_CAST(i, /, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_DIV_UN_I8) - if (sp [-1].data.l == 0) - THROW_EX (mono_get_exception_divide_by_zero (), ip); - BINOP_CAST(l, /, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_REM_I4) - if (sp [-1].data.i == 0) - THROW_EX (mono_get_exception_divide_by_zero (), ip); - BINOP(i, %); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_REM_I8) - if (sp [-1].data.l == 0) - THROW_EX (mono_get_exception_divide_by_zero (), ip); - BINOP(l, %); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_REM_R8) - /* FIXME: what do we actually do here? */ - --sp; - sp [-1].data.f = fmod (sp [-1].data.f, sp [0].data.f); - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_REM_UN_I4) - if (sp [-1].data.i == 0) - THROW_EX (mono_get_exception_divide_by_zero (), ip); - BINOP_CAST(i, %, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_REM_UN_I8) - if (sp [-1].data.l == 0) - THROW_EX (mono_get_exception_divide_by_zero (), ip); - BINOP_CAST(l, %, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_AND_I4) - BINOP(i, &); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_AND_I8) - BINOP(l, &); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_OR_I4) - BINOP(i, |); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_OR_I8) - BINOP(l, |); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_XOR_I4) - BINOP(i, ^); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_XOR_I8) - BINOP(l, ^); - MINT_IN_BREAK; - -#define SHIFTOP(datamem, op) \ - --sp; \ - sp [-1].data.datamem = sp [-1].data.datamem op sp [0].data.i; \ - ++ip; - - MINT_IN_CASE(MINT_SHL_I4) - SHIFTOP(i, <<); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SHL_I8) - SHIFTOP(l, <<); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SHR_I4) - SHIFTOP(i, >>); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SHR_I8) - SHIFTOP(l, >>); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SHR_UN_I4) - --sp; - sp [-1].data.i = (guint32)sp [-1].data.i >> sp [0].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SHR_UN_I8) - --sp; - sp [-1].data.l = (guint64)sp [-1].data.l >> sp [0].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_NEG_I4) - sp [-1].data.i = - sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_NEG_I8) - sp [-1].data.l = - sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_NEG_R8) - sp [-1].data.f = - sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_NOT_I4) - sp [-1].data.i = ~ sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_NOT_I8) - sp [-1].data.l = ~ sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_I1_I4) - sp [-1].data.i = (gint8)sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_I1_I8) - sp [-1].data.i = (gint8)sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_I1_R8) - sp [-1].data.i = (gint8)sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_U1_I4) - sp [-1].data.i = (guint8)sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_U1_I8) - sp [-1].data.i = (guint8)sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_U1_R8) - sp [-1].data.i = (guint8)sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_I2_I4) - sp [-1].data.i = (gint16)sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_I2_I8) - sp [-1].data.i = (gint16)sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_I2_R8) - sp [-1].data.i = (gint16)sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_U2_I4) - sp [-1].data.i = (guint16)sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_U2_I8) - sp [-1].data.i = (guint16)sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_U2_R8) - sp [-1].data.i = (guint16)sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_I4_R8) - sp [-1].data.i = (gint32)sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_U4_I8) - MINT_IN_CASE(MINT_CONV_I4_I8) - sp [-1].data.i = (gint32)sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_I4_I8_SP) - sp [-2].data.i = (gint32)sp [-2].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_U4_R8) - sp [-1].data.i = (guint32)sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_I8_I4) - sp [-1].data.l = sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_I8_I4_SP) - sp [-2].data.l = sp [-2].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_I8_U4) - sp [-1].data.l = (guint32)sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_I8_R8) - sp [-1].data.l = (gint64)sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_R4_I4) - sp [-1].data.f = (float)sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_R4_I8) - sp [-1].data.f = (float)sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_R4_R8) - sp [-1].data.f = (float)sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_R8_I4) - sp [-1].data.f = (double)sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_R8_I8) - sp [-1].data.f = (double)sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_U8_I4) - sp [-1].data.l = sp [-1].data.i & 0xffffffff; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_U8_R8) - sp [-1].data.l = (guint64)sp [-1].data.f; - ++ip; - MINT_IN_BREAK; -#if 0 - MINT_IN_CASE(MINT_CPOBJ) { - MonoClass *vtklass; - ++ip; - vtklass = rtm->data_items[READ32 (ip)]; - ip += 2; - sp -= 2; - memcpy (sp [0].data.p, sp [1].data.p, mono_class_value_size (vtklass, NULL)); - MINT_IN_BREAK; - } -#endif - MINT_IN_CASE(MINT_LDOBJ) { - int size; - void *p; - c = rtm->data_items[* (guint16 *)(ip + 1)]; - ip += 2; - if (c->byval_arg.type != MONO_TYPE_VALUETYPE || c->byval_arg.data.klass->enumtype) { - p = sp [-1].data.p; - stackval_from_data (&c->byval_arg, &sp [-1], p, FALSE); - } else { - size = mono_class_value_size (c, NULL); - p = sp [-1].data.p; - sp [-1].data.p = vt_sp; - memcpy(vt_sp, p, size); - vt_sp += (size + 7) & ~7; - } - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_LDSTR) - sp->data.p = rtm->data_items [* (guint16 *)(ip + 1)]; - ++sp; - ip += 2; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_NEWOBJ) { - MonoClass *newobj_class; - MonoMethodSignature *csig; - stackval valuetype_this; - guint32 token; - stackval retval; - - frame->ip = ip; - - token = * (guint16 *)(ip + 1); - ip += 2; - - child_frame.runtime_method = rtm->data_items [token]; - csig = mono_method_signature (child_frame.runtime_method->method); - newobj_class = child_frame.runtime_method->method->klass; - /*if (profiling_classes) { - guint count = GPOINTER_TO_UINT (g_hash_table_lookup (profiling_classes, newobj_class)); - count++; - g_hash_table_insert (profiling_classes, newobj_class, GUINT_TO_POINTER (count)); - }*/ - - - if (newobj_class->parent == mono_defaults.array_class) { - sp -= csig->param_count; - o = ves_array_create (context->domain, newobj_class, csig, sp); - goto array_constructed; - } - - /* - * First arg is the object. - */ - if (newobj_class->valuetype) { - if (!newobj_class->enumtype && (newobj_class->byval_arg.type == MONO_TYPE_VALUETYPE)) { - child_frame.obj = vt_sp; - valuetype_this.data.p = vt_sp; - } else { - memset (&valuetype_this, 0, sizeof (stackval)); - child_frame.obj = &valuetype_this; - } - } else { - if (newobj_class != mono_defaults.string_class) { - context->managed_code = 0; - o = mono_object_new (context->domain, newobj_class); - context->managed_code = 1; - if (*abort_requested) - mono_thread_interruption_checkpoint (); - child_frame.obj = o; - } else { - child_frame.retval = &retval; - } - } - - if (csig->param_count) { - sp -= csig->param_count; - child_frame.stack_args = sp; - } else { - child_frame.stack_args = NULL; - } - - g_assert (csig->call_convention == MONO_CALL_DEFAULT); - - child_frame.ip = NULL; - child_frame.ex = NULL; - - ves_exec_method_with_context (&child_frame, context); - - context->current_frame = frame; - - if (child_frame.ex) { - /* - * An exception occurred, need to run finally, fault and catch handlers.. - */ - frame->ex = child_frame.ex; - goto handle_finally; - } - /* - * a constructor returns void, but we need to return the object we created - */ -array_constructed: - if (newobj_class->valuetype && !newobj_class->enumtype) { - *sp = valuetype_this; - } else if (newobj_class == mono_defaults.string_class) { - *sp = retval; - } else { - sp->data.p = o; - } - ++sp; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_CASTCLASS) - c = rtm->data_items [*(guint16 *)(ip + 1)]; - if ((o = sp [-1].data.p)) { - if (c->marshalbyref) { - if (!mono_object_isinst_mbyref (o, c)) - THROW_EX (mono_get_exception_invalid_cast (), ip); - } else { - MonoVTable *vt = o->vtable; - MonoClass *oklass = vt->klass; - if (c->flags & TYPE_ATTRIBUTE_INTERFACE) { - if (c->interface_id > vt->max_interface_id || - vt->interface_offsets [c->interface_id] == 0) { - THROW_EX (mono_get_exception_invalid_cast (), ip); - } - } else if (c->rank) { - if (!mono_object_isinst (o, c)) - THROW_EX (mono_get_exception_invalid_cast (), ip); - } else if (!mono_class_has_parent (oklass, c)) { - THROW_EX (mono_get_exception_invalid_cast (), ip); - } - } - } - ip += 2; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_ISINST) - c = rtm->data_items [*(guint16 *)(ip + 1)]; - if ((o = sp [-1].data.p)) { - if (c->marshalbyref) { - if (!mono_object_isinst_mbyref (o, c)) - sp [-1].data.p = NULL; - } else { - MonoVTable *vt = o->vtable; - MonoClass *oklass = vt->klass; - if (c->flags & TYPE_ATTRIBUTE_INTERFACE) { - if (c->interface_id > vt->max_interface_id || - vt->interface_offsets [c->interface_id] == 0) { - sp [-1].data.p = NULL; - } - } else if (c->rank) { - if (!mono_object_isinst (o, c)) - sp [-1].data.p = NULL; - } else if (!mono_class_has_parent (oklass, c)) { - sp [-1].data.p = NULL; - } - } - } - ip += 2; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_R_UN_I4) - sp [-1].data.f = (double)(guint32)sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_R_UN_I8) - sp [-1].data.f = (double)(guint64)sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_UNBOX) - c = rtm->data_items[*(guint16 *)(ip + 1)]; - - o = sp [-1].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference(), ip); - - if (!(mono_object_isinst (o, c) || - ((o->vtable->klass->rank == 0) && - (o->vtable->klass->element_class == c->element_class)))) - THROW_EX (mono_get_exception_invalid_cast (), ip); - - sp [-1].data.p = (char *)o + sizeof (MonoObject); - ip += 2; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_THROW) - --sp; - frame->ex_handler = NULL; - if (!sp->data.p) - sp->data.p = mono_get_exception_null_reference (); - THROW_EX ((MonoException *)sp->data.p, ip); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDFLDA) - o = sp [-1].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference (), ip); - sp[-1].data.p = (char *)o + * (guint16 *)(ip + 1); - ip += 2; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CKNULL) - o = sp [-1].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference (), ip); - ++ip; - MINT_IN_BREAK; - -#define LDFLD(datamem, fieldtype) \ - o = sp [-1].data.p; \ - if (!o) \ - THROW_EX (mono_get_exception_null_reference (), ip); \ - sp[-1].data.datamem = * (fieldtype *)((char *)o + * (guint16 *)(ip + 1)) ; \ - ip += 2; - - MINT_IN_CASE(MINT_LDFLD_I1) LDFLD(i, gint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDFLD_U1) LDFLD(i, guint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDFLD_I2) LDFLD(i, gint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDFLD_U2) LDFLD(i, guint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDFLD_I4) LDFLD(i, gint32); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDFLD_I8) LDFLD(l, gint64); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDFLD_R4) LDFLD(f, float); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDFLD_R8) LDFLD(f, double); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDFLD_O) LDFLD(p, gpointer); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDFLD_P) LDFLD(p, gpointer); MINT_IN_BREAK; - - MINT_IN_CASE(MINT_LDFLD_VT) - o = sp [-1].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference (), ip); - i32 = READ32(ip + 2); - sp [-1].data.p = vt_sp; - memcpy(sp [-1].data.p, (char *)o + * (guint16 *)(ip + 1), i32); - vt_sp += (i32 + 7) & ~7; - ip += 4; - MINT_IN_BREAK; - - MINT_IN_CASE(MINT_LDRMFLD) { - gpointer tmp; - MonoClassField *field; - char *addr; - - o = sp [-1].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference (), ip); - field = rtm->data_items[* (guint16 *)(ip + 1)]; - ip += 2; - if (o->vtable->klass == mono_defaults.transparent_proxy_class) { - MonoClass *klass = ((MonoTransparentProxy*)o)->remote_class->proxy_class; - - addr = mono_load_remote_field (o, klass, field, &tmp); - } else { - addr = (char*)o + field->offset; - } - - stackval_from_data (field->type, &sp [-1], addr, FALSE); - MINT_IN_BREAK; - } - - MINT_IN_CASE(MINT_LDRMFLD_VT) { - MonoClassField *field; - char *addr; - gpointer tmp; - - o = sp [-1].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference (), ip); - field = rtm->data_items[* (guint16 *)(ip + 1)]; - i32 = READ32(ip + 2); - ip += 4; - if (o->vtable->klass == mono_defaults.transparent_proxy_class) { - MonoClass *klass = ((MonoTransparentProxy*)o)->remote_class->proxy_class; - addr = mono_load_remote_field (o, klass, field, &tmp); - } else { - addr = (char*)o + field->offset; - } - - sp [-1].data.p = vt_sp; - memcpy(sp [-1].data.p, (char *)o + * (guint16 *)(ip + 1), i32); - vt_sp += (i32 + 7) & ~7; - memcpy(sp [-1].data.p, addr, i32); - MINT_IN_BREAK; - } - -#define STFLD(datamem, fieldtype) \ - o = sp [-2].data.p; \ - if (!o) \ - THROW_EX (mono_get_exception_null_reference (), ip); \ - sp -= 2; \ - * (fieldtype *)((char *)o + * (guint16 *)(ip + 1)) = sp[1].data.datamem; \ - ip += 2; - - MINT_IN_CASE(MINT_STFLD_I1) STFLD(i, gint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STFLD_U1) STFLD(i, guint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STFLD_I2) STFLD(i, gint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STFLD_U2) STFLD(i, guint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STFLD_I4) STFLD(i, gint32); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STFLD_I8) STFLD(l, gint64); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STFLD_R4) STFLD(f, float); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STFLD_R8) STFLD(f, double); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STFLD_O) STFLD(p, gpointer); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STFLD_P) STFLD(p, gpointer); MINT_IN_BREAK; - - MINT_IN_CASE(MINT_STFLD_VT) - o = sp [-2].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference (), ip); - i32 = READ32(ip + 2); - sp -= 2; - memcpy((char *)o + * (guint16 *)(ip + 1), sp [1].data.p, i32); - vt_sp -= (i32 + 7) & ~7; - ip += 4; - MINT_IN_BREAK; - - MINT_IN_CASE(MINT_STRMFLD) { - MonoClassField *field; - - o = sp [-2].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference (), ip); - - field = rtm->data_items[* (guint16 *)(ip + 1)]; - ip += 2; - - if (o->vtable->klass == mono_defaults.transparent_proxy_class) { - MonoClass *klass = ((MonoTransparentProxy*)o)->remote_class->proxy_class; - mono_store_remote_field (o, klass, field, &sp [-1].data); - } else - stackval_to_data (field->type, &sp [-1], (char*)o + field->offset, FALSE); - - sp -= 2; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_STRMFLD_VT) { - MonoClassField *field; - - o = sp [-2].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference (), ip); - field = rtm->data_items[* (guint16 *)(ip + 1)]; - i32 = READ32(ip + 2); - ip += 4; - - if (o->vtable->klass == mono_defaults.transparent_proxy_class) { - MonoClass *klass = ((MonoTransparentProxy*)o)->remote_class->proxy_class; - mono_store_remote_field (o, klass, field, &sp [-1].data); - } else - memcpy((char*)o + field->offset, sp [-1].data.p, i32); - - sp -= 2; - vt_sp -= (i32 + 7) & ~7; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_LDSFLDA) { - MonoClassField *field = rtm->data_items[*(guint16 *)(ip + 1)]; - MonoVTable *vt = mono_class_vtable (context->domain, field->parent); - gpointer addr; - - if (!vt->initialized) { - frame->ip = ip; - mono_runtime_class_init (vt); - } - ip += 2; - - if (context->domain->special_static_fields && (addr = g_hash_table_lookup (context->domain->special_static_fields, field))) - sp->data.p = mono_get_special_static_data (GPOINTER_TO_UINT (addr)); - else - sp->data.p = (char*)(vt->data) + field->offset; - ++sp; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_LDSFLD) { - MonoVTable *vt; - MonoClassField *field; - gpointer addr; - - field = rtm->data_items[*(guint16 *)(ip + 1)]; - vt = rtm->data_items [*(guint16 *)(ip + 2)]; - if (!vt->initialized) { - frame->ip = ip; - mono_runtime_class_init (vt); - } - ip += 3; - if (context->domain->special_static_fields && (addr = g_hash_table_lookup (context->domain->special_static_fields, field))) - addr = mono_get_special_static_data (GPOINTER_TO_UINT (addr)); - else - addr = (char*)(vt->data) + field->offset; - - stackval_from_data (field->type, sp, addr, FALSE); - ++sp; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_LDSFLD_I4) { - MonoClassField *field = rtm->data_items[*(guint16 *)(ip + 1)]; - MonoVTable *vt = rtm->data_items [*(guint16 *)(ip + 2)]; - if (!vt->initialized) { - frame->ip = ip; - mono_runtime_class_init (vt); - } - ip += 3; - sp->data.i = * (gint32 *)((char*)(vt->data) + field->offset); - ++sp; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_LDSFLD_O) { - MonoClassField *field = rtm->data_items[*(guint16 *)(ip + 1)]; - MonoVTable *vt = rtm->data_items [*(guint16 *)(ip + 2)]; - if (!vt->initialized) { - frame->ip = ip; - mono_runtime_class_init (vt); - } - ip += 3; - sp->data.p = * (gpointer *)((char*)(vt->data) + field->offset); - ++sp; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_LDSFLD_VT) { - MonoVTable *vt; - MonoClassField *field; - guint32 token; - gpointer addr; - int size; - - token = * (guint16 *)(ip + 1); - size = READ32(ip + 2); - field = rtm->data_items[token]; - ip += 4; - - vt = mono_class_vtable (context->domain, field->parent); - if (!vt->initialized) { - frame->ip = ip - 2; - mono_runtime_class_init (vt); - } - - if (context->domain->special_static_fields && (addr = g_hash_table_lookup (context->domain->special_static_fields, field))) - addr = mono_get_special_static_data (GPOINTER_TO_UINT (addr)); - else - addr = (char*)(vt->data) + field->offset; - - sp->data.p = vt_sp; - vt_sp += (size + 7) & ~7; - stackval_from_data (field->type, sp, addr, FALSE); - ++sp; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_STSFLD) { - MonoVTable *vt; - MonoClassField *field; - guint32 token; - gpointer addr; - - token = * (guint16 *)(ip + 1); - field = rtm->data_items[token]; - ip += 2; - --sp; - - vt = mono_class_vtable (context->domain, field->parent); - if (!vt->initialized) { - frame->ip = ip - 2; - mono_runtime_class_init (vt); - } - - if (context->domain->special_static_fields && (addr = g_hash_table_lookup (context->domain->special_static_fields, field))) - addr = mono_get_special_static_data (GPOINTER_TO_UINT (addr)); - else - addr = (char*)(vt->data) + field->offset; - - stackval_to_data (field->type, sp, addr, FALSE); - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_STSFLD_VT) { - MonoVTable *vt; - MonoClassField *field; - guint32 token; - gpointer addr; - int size; - - token = * (guint16 *)(ip + 1); - size = READ32(ip + 2); - field = rtm->data_items[token]; - ip += 4; - - vt = mono_class_vtable (context->domain, field->parent); - if (!vt->initialized) { - frame->ip = ip - 2; - mono_runtime_class_init (vt); - } - - if (context->domain->special_static_fields && (addr = g_hash_table_lookup (context->domain->special_static_fields, field))) - addr = mono_get_special_static_data (GPOINTER_TO_UINT (addr)); - else - addr = (char*)(vt->data) + field->offset; - --sp; - stackval_to_data (field->type, sp, addr, FALSE); - vt_sp -= (size + 7) & ~7; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_STOBJ_VT) { - int size; - c = rtm->data_items[* (guint16 *)(ip + 1)]; - ip += 2; - size = mono_class_value_size (c, NULL); - memcpy(sp [-2].data.p, sp [-1].data.p, size); - vt_sp -= (size + 7) & ~7; - sp -= 2; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_STOBJ) { - int size; - c = rtm->data_items[* (guint16 *)(ip + 1)]; - ip += 2; - size = mono_class_value_size (c, NULL); - memcpy(sp [-2].data.p, &sp [-1].data, size); - sp -= 2; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_CONV_OVF_I4_UN_R8) - if (sp [-1].data.f < 0 || sp [-1].data.f > MYGUINT32_MAX) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (guint32)sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_U8_I4) - if (sp [-1].data.i < 0) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.l = sp [-1].data.i; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_U8_R8) - MINT_IN_CASE(MINT_CONV_OVF_I8_UN_R8) - if (sp [-1].data.f < 0 || sp [-1].data.f > 9223372036854775807LL) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.l = (guint64)sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_I8_R8) - if (sp [-1].data.f < MYGINT64_MIN || sp [-1].data.f > MYGINT64_MAX) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.l = (gint64)sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_I4_UN_I8) - if ((mono_u)sp [-1].data.l > MYGUINT32_MAX) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (mono_u)sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_BOX) - c = rtm->data_items [* (guint16 *)(ip + 1)]; - - if (c->byval_arg.type == MONO_TYPE_VALUETYPE && !c->enumtype) { - int size = mono_class_value_size (c, NULL); - sp [-1].data.p = mono_value_box (context->domain, c, sp [-1].data.p); - size = (size + 7) & ~7; - vt_sp -= size; - } - else { - stackval_to_data (&c->byval_arg, &sp [-1], (char*)&sp [-1], FALSE); - sp [-1].data.p = mono_value_box (context->domain, c, &sp [-1]); - } - ip += 2; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_NEWARR) - sp [-1].data.p = (MonoObject*) mono_array_new (context->domain, rtm->data_items[*(guint16 *)(ip + 1)], sp [-1].data.i); - ip += 2; - /*if (profiling_classes) { - guint count = GPOINTER_TO_UINT (g_hash_table_lookup (profiling_classes, o->vtable->klass)); - count++; - g_hash_table_insert (profiling_classes, o->vtable->klass, GUINT_TO_POINTER (count)); - }*/ - - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDLEN) - o = sp [-1].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference (), ip); - sp [-1].data.nati = mono_array_length ((MonoArray *)o); - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_GETCHR) { - MonoString *s; - s = sp [-2].data.p; - if (!s) - THROW_EX (mono_get_exception_null_reference (), ip); - i32 = sp [-1].data.i; - if (i32 < 0 || i32 >= mono_string_length (s)) - THROW_EX (mono_get_exception_index_out_of_range (), ip); - --sp; - sp [-1].data.i = mono_string_chars(s)[i32]; - ++ip; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_STRLEN) - ++ip; - sp [-1].data.i = mono_string_length ((MonoString*)sp [-1].data.p); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_ARRAY_RANK) - o = sp [-1].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference (), ip); - sp [-1].data.i = mono_object_class (sp [-1].data.p)->rank; - ip++; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDELEMA) { - guint32 esize; - mono_u aindex; - - /*token = READ32 (ip)*/; - ip += 2; - sp -= 2; - - o = sp [0].data.p; - - aindex = sp [1].data.i; - if (aindex >= mono_array_length ((MonoArray *) o)) - THROW_EX (mono_get_exception_index_out_of_range (), ip - 2); - - /* check the array element corresponds to token */ - esize = mono_array_element_size (((MonoArray *) o)->obj.vtable->klass); - - sp->data.p = mono_array_addr_with_size ((MonoArray *) o, esize, aindex); - ++sp; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_LDELEM_I1) /* fall through */ - MINT_IN_CASE(MINT_LDELEM_U1) /* fall through */ - MINT_IN_CASE(MINT_LDELEM_I2) /* fall through */ - MINT_IN_CASE(MINT_LDELEM_U2) /* fall through */ - MINT_IN_CASE(MINT_LDELEM_I4) /* fall through */ - MINT_IN_CASE(MINT_LDELEM_U4) /* fall through */ - MINT_IN_CASE(MINT_LDELEM_I8) /* fall through */ - MINT_IN_CASE(MINT_LDELEM_I) /* fall through */ - MINT_IN_CASE(MINT_LDELEM_R4) /* fall through */ - MINT_IN_CASE(MINT_LDELEM_R8) /* fall through */ - MINT_IN_CASE(MINT_LDELEM_REF) { - MonoArray *o; - mono_u aindex; - - sp -= 2; - - o = sp [0].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference (), ip); - - aindex = sp [1].data.i; - if (aindex >= mono_array_length (o)) - THROW_EX (mono_get_exception_index_out_of_range (), ip); - - /* - * FIXME: throw mono_get_exception_array_type_mismatch () if needed - */ - switch (*ip) { - case MINT_LDELEM_I1: - sp [0].data.i = mono_array_get (o, gint8, aindex); - break; - case MINT_LDELEM_U1: - sp [0].data.i = mono_array_get (o, guint8, aindex); - break; - case MINT_LDELEM_I2: - sp [0].data.i = mono_array_get (o, gint16, aindex); - break; - case MINT_LDELEM_U2: - sp [0].data.i = mono_array_get (o, guint16, aindex); - break; - case MINT_LDELEM_I: - sp [0].data.nati = mono_array_get (o, mono_i, aindex); - break; - case MINT_LDELEM_I4: - sp [0].data.i = mono_array_get (o, gint32, aindex); - break; - case MINT_LDELEM_U4: - sp [0].data.i = mono_array_get (o, guint32, aindex); - break; - case MINT_LDELEM_I8: - sp [0].data.l = mono_array_get (o, guint64, aindex); - break; - case MINT_LDELEM_R4: - sp [0].data.f = mono_array_get (o, float, aindex); - break; - case MINT_LDELEM_R8: - sp [0].data.f = mono_array_get (o, double, aindex); - break; - case MINT_LDELEM_REF: - sp [0].data.p = mono_array_get (o, gpointer, aindex); - break; - default: - ves_abort(); - } - - ++ip; - ++sp; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_STELEM_I) /* fall through */ - MINT_IN_CASE(MINT_STELEM_I1) /* fall through */ - MINT_IN_CASE(MINT_STELEM_I2) /* fall through */ - MINT_IN_CASE(MINT_STELEM_I4) /* fall through */ - MINT_IN_CASE(MINT_STELEM_I8) /* fall through */ - MINT_IN_CASE(MINT_STELEM_R4) /* fall through */ - MINT_IN_CASE(MINT_STELEM_R8) /* fall through */ - MINT_IN_CASE(MINT_STELEM_REF) { - mono_u aindex; - - sp -= 3; - - o = sp [0].data.p; - if (!o) - THROW_EX (mono_get_exception_null_reference (), ip); - - aindex = sp [1].data.i; - if (aindex >= mono_array_length ((MonoArray *)o)) - THROW_EX (mono_get_exception_index_out_of_range (), ip); - - switch (*ip) { - case MINT_STELEM_I: - mono_array_set ((MonoArray *)o, mono_i, aindex, sp [2].data.nati); - break; - case MINT_STELEM_I1: - mono_array_set ((MonoArray *)o, gint8, aindex, sp [2].data.i); - break; - case MINT_STELEM_I2: - mono_array_set ((MonoArray *)o, gint16, aindex, sp [2].data.i); - break; - case MINT_STELEM_I4: - mono_array_set ((MonoArray *)o, gint32, aindex, sp [2].data.i); - break; - case MINT_STELEM_I8: - mono_array_set ((MonoArray *)o, gint64, aindex, sp [2].data.l); - break; - case MINT_STELEM_R4: - mono_array_set ((MonoArray *)o, float, aindex, sp [2].data.f); - break; - case MINT_STELEM_R8: - mono_array_set ((MonoArray *)o, double, aindex, sp [2].data.f); - break; - case MINT_STELEM_REF: - if (sp [2].data.p && !mono_object_isinst (sp [2].data.p, mono_object_class (o)->element_class)) - THROW_EX (mono_get_exception_array_type_mismatch (), ip); - mono_array_set ((MonoArray *)o, gpointer, aindex, sp [2].data.p); - break; - default: - ves_abort(); - } - - ++ip; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_CONV_OVF_I4_U4) - if (sp [-1].data.i < 0) - THROW_EX (mono_get_exception_overflow (), ip); - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_I4_I8) - if (sp [-1].data.l < MYGINT32_MIN || sp [-1].data.l > MYGINT32_MAX) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (gint32) sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_I4_R8) - if (sp [-1].data.f < MYGINT32_MIN || sp [-1].data.f > MYGINT32_MAX) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (gint32) sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_U4_I4) - if (sp [-1].data.i < 0) - THROW_EX (mono_get_exception_overflow (), ip); - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_U4_I8) - if (sp [-1].data.l < 0 || sp [-1].data.l > MYGUINT32_MAX) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (guint32) sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_U4_R8) - if (sp [-1].data.f < 0 || sp [-1].data.f > MYGUINT32_MAX) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (guint32) sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_I2_I4) - if (sp [-1].data.i < -32768 || sp [-1].data.i > 32767) - THROW_EX (mono_get_exception_overflow (), ip); - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_I2_I8) - if (sp [-1].data.l < -32768 || sp [-1].data.l > 32767) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (gint16) sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_I2_R8) - if (sp [-1].data.f < -32768 || sp [-1].data.f > 32767) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (gint16) sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_U2_I4) - if (sp [-1].data.i < 0 || sp [-1].data.i > 65535) - THROW_EX (mono_get_exception_overflow (), ip); - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_U2_I8) - if (sp [-1].data.l < 0 || sp [-1].data.l > 65535) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (guint16) sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_U2_R8) - if (sp [-1].data.f < 0 || sp [-1].data.f > 65535) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (guint16) sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_I1_I4) - if (sp [-1].data.i < -128 || sp [-1].data.i > 127) - THROW_EX (mono_get_exception_overflow (), ip); - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_I1_I8) - if (sp [-1].data.l < -128 || sp [-1].data.l > 127) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (gint8) sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_I1_R8) - if (sp [-1].data.f < -128 || sp [-1].data.f > 127) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (gint8) sp [-1].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_U1_I4) - if (sp [-1].data.i < 0 || sp [-1].data.i > 255) - THROW_EX (mono_get_exception_overflow (), ip); - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_U1_I8) - if (sp [-1].data.l < 0 || sp [-1].data.l > 255) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (guint8) sp [-1].data.l; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CONV_OVF_U1_R8) - if (sp [-1].data.f < 0 || sp [-1].data.f > 255) - THROW_EX (mono_get_exception_overflow (), ip); - sp [-1].data.i = (guint8) sp [-1].data.f; - ++ip; - MINT_IN_BREAK; -#if 0 - MINT_IN_CASE(MINT_LDELEM) - MINT_IN_CASE(MINT_STELEM) - MINT_IN_CASE(MINT_UNBOX_ANY) - - MINT_IN_CASE(MINT_REFANYVAL) ves_abort(); MINT_IN_BREAK; -#endif - MINT_IN_CASE(MINT_CKFINITE) - if (!finite(sp [-1].data.f)) - THROW_EX (mono_get_exception_arithmetic (), ip); - ++ip; - MINT_IN_BREAK; -#if 0 - MINT_IN_CASE(MINT_MKREFANY) ves_abort(); MINT_IN_BREAK; -#endif - MINT_IN_CASE(MINT_LDTOKEN) - sp->data.p = vt_sp; - vt_sp += 8; - * (gpointer *)sp->data.p = rtm->data_items[*(guint16 *)(ip + 1)]; - ip += 2; - ++sp; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_ADD_OVF_I4) - if (CHECK_ADD_OVERFLOW (sp [-2].data.i, sp [-1].data.i)) - THROW_EX (mono_get_exception_overflow (), ip); - BINOP(i, +); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_ADD_OVF_I8) - if (CHECK_ADD_OVERFLOW64 (sp [-2].data.l, sp [-1].data.l)) - THROW_EX (mono_get_exception_overflow (), ip); - BINOP(l, +); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_ADD_OVF_UN_I4) - if (CHECK_ADD_OVERFLOW_UN (sp [-2].data.i, sp [-1].data.i)) - THROW_EX (mono_get_exception_overflow (), ip); - BINOP_CAST(i, +, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_ADD_OVF_UN_I8) - if (CHECK_ADD_OVERFLOW64_UN (sp [-2].data.l, sp [-1].data.l)) - THROW_EX (mono_get_exception_overflow (), ip); - BINOP_CAST(l, +, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_MUL_OVF_I4) - if (CHECK_MUL_OVERFLOW (sp [-2].data.i, sp [-1].data.i)) - THROW_EX (mono_get_exception_overflow (), ip); - BINOP(i, *); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_MUL_OVF_I8) - if (CHECK_MUL_OVERFLOW64 (sp [-2].data.l, sp [-1].data.l)) - THROW_EX (mono_get_exception_overflow (), ip); - BINOP(l, *); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_MUL_OVF_UN_I4) - if (CHECK_MUL_OVERFLOW_UN (sp [-2].data.i, sp [-1].data.i)) - THROW_EX (mono_get_exception_overflow (), ip); - BINOP_CAST(i, *, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_MUL_OVF_UN_I8) - if (CHECK_MUL_OVERFLOW64_UN (sp [-2].data.l, sp [-1].data.l)) - THROW_EX (mono_get_exception_overflow (), ip); - BINOP_CAST(l, *, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SUB_OVF_I4) - if (CHECK_SUB_OVERFLOW (sp [-2].data.i, sp [-1].data.i)) - THROW_EX (mono_get_exception_overflow (), ip); - BINOP(i, -); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SUB_OVF_I8) - if (CHECK_SUB_OVERFLOW64 (sp [-2].data.l, sp [-1].data.l)) - THROW_EX (mono_get_exception_overflow (), ip); - BINOP(l, -); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SUB_OVF_UN_I4) - if (CHECK_SUB_OVERFLOW_UN (sp [-2].data.i, sp [-1].data.i)) - THROW_EX (mono_get_exception_overflow (), ip); - BINOP_CAST(i, -, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_SUB_OVF_UN_I8) - if (CHECK_SUB_OVERFLOW64_UN (sp [-2].data.l, sp [-1].data.l)) - THROW_EX (mono_get_exception_overflow (), ip); - BINOP_CAST(l, -, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_ENDFINALLY) - if (finally_ips) { - ip = finally_ips->data; - finally_ips = g_slist_remove (finally_ips, ip); - goto main_loop; - } - if (frame->ex) - goto handle_fault; - ves_abort(); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LEAVE) /* Fall through */ - MINT_IN_CASE(MINT_LEAVE_S) - while (sp > frame->stack) { - --sp; - } - frame->ip = ip; - if (*ip == MINT_LEAVE_S) { - ip += (short) *(ip + 1); - } else { - ip += (gint32) READ32 (ip + 1); - } - endfinally_ip = ip; - if (frame->ex_handler != NULL && MONO_OFFSET_IN_HANDLER(frame->ex_handler, frame->ip - rtm->code)) { - frame->ex_handler = NULL; - frame->ex = NULL; - } - goto handle_finally; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_ICALL_V_V) - MINT_IN_CASE(MINT_ICALL_P_V) - MINT_IN_CASE(MINT_ICALL_P_P) - MINT_IN_CASE(MINT_ICALL_PP_V) - MINT_IN_CASE(MINT_ICALL_PI_V) - MINT_IN_CASE(MINT_ICALL_PP_P) - MINT_IN_CASE(MINT_ICALL_PI_P) - MINT_IN_CASE(MINT_ICALL_PPP_V) - MINT_IN_CASE(MINT_ICALL_PPI_V) - sp = do_icall (context, *ip, sp, rtm->data_items [*(guint16 *)(ip + 1)]); - if (frame->ex != NULL) - goto handle_exception; - ip += 2; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_MONO_LDPTR) - sp->data.p = rtm->data_items [*(guint16 *)(ip + 1)]; - ip += 2; - ++sp; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_MONO_NEWOBJ) - sp->data.p = mono_object_new (context->domain, rtm->data_items [*(guint16 *)(ip + 1)]); - ip += 2; - sp++; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_MONO_FREE) - ++ip; - --sp; - g_free (sp->data.p); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_MONO_RETOBJ) - ++ip; - sp--; - stackval_from_data (mono_method_signature (frame->runtime_method->method)->ret, frame->retval, sp->data.p, - mono_method_signature (frame->runtime_method->method)->pinvoke); - if (sp > frame->stack) - g_warning ("retobj: more values on stack: %d", sp-frame->stack); - goto exit_frame; - -#define RELOP(datamem, op) \ - --sp; \ - sp [-1].data.i = sp [-1].data.datamem op sp [0].data.datamem; \ - ++ip; - MINT_IN_CASE(MINT_CEQ_I4) - RELOP(i, ==); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CEQ0_I4) - sp [-1].data.i = (sp [-1].data.i == 0); - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CEQ_I8) - RELOP(l, ==); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CEQ_R8) - --sp; - if (isunordered (sp [-1].data.f, sp [0].data.f)) - sp [-1].data.i = 0; - else - sp [-1].data.i = sp [-1].data.f == sp [0].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CGT_I4) - RELOP(i, >); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CGT_I8) - RELOP(l, >); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CGT_R8) - --sp; - if (isunordered (sp [-1].data.f, sp [0].data.f)) - sp [-1].data.i = 0; - else - sp [-1].data.i = sp [-1].data.f > sp [0].data.f; - ++ip; - MINT_IN_BREAK; - -#define RELOP_CAST(datamem, op, type) \ - --sp; \ - sp [-1].data.i = (type)sp [-1].data.datamem op (type)sp [0].data.datamem; \ - ++ip; - - MINT_IN_CASE(MINT_CGT_UN_I4) - RELOP_CAST(i, >, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CGT_UN_I8) - RELOP_CAST(l, >, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CGT_UN_R8) - --sp; - if (isunordered (sp [-1].data.f, sp [0].data.f)) - sp [-1].data.i = 1; - else - sp [-1].data.i = sp [-1].data.f > sp [0].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CLT_I4) - RELOP(i, <); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CLT_I8) - RELOP(l, <); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CLT_R8) - --sp; - if (isunordered (sp [-1].data.f, sp [0].data.f)) - sp [-1].data.i = 0; - else - sp [-1].data.i = sp [-1].data.f < sp [0].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CLT_UN_I4) - RELOP_CAST(i, <, guint32); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CLT_UN_I8) - RELOP_CAST(l, <, guint64); - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CLT_UN_R8) - --sp; - if (isunordered (sp [-1].data.f, sp [0].data.f)) - sp [-1].data.i = 1; - else - sp [-1].data.i = sp [-1].data.f < sp [0].data.f; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDFTN) { - sp->data.p = rtm->data_items [* (guint16 *)(ip + 1)]; - ++sp; - ip += 2; - MINT_IN_BREAK; - } - MINT_IN_CASE(MINT_LDVIRTFTN) { - RuntimeMethod *m = rtm->data_items [* (guint16 *)(ip + 1)]; - ip += 2; - --sp; - if (!sp->data.p) - THROW_EX (mono_get_exception_null_reference (), ip - 2); - - sp->data.p = get_virtual_method (m, sp->data.p); - ++sp; - MINT_IN_BREAK; - } - - MINT_IN_CASE(MINT_LDTHIS) - sp->data.p = frame->obj; - ++ip; - ++sp; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_STTHIS) - --sp; - frame->obj = sp->data.p; - ++ip; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDTHISA) - sp->data.p = &frame->obj; - ++ip; - ++sp; - MINT_IN_BREAK; - -#define LDARG(datamem, argtype) \ - sp->data.datamem = * (argtype *)(frame->args + * (guint16 *)(ip + 1)); \ - ip += 2; \ - ++sp; - - MINT_IN_CASE(MINT_LDARG_I1) LDARG(i, gint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDARG_U1) LDARG(i, guint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDARG_I2) LDARG(i, gint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDARG_U2) LDARG(i, guint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDARG_I4) LDARG(i, gint32); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDARG_I8) LDARG(l, gint64); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDARG_R4) LDARG(f, float); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDARG_R8) LDARG(f, double); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDARG_O) LDARG(p, gpointer); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDARG_P) LDARG(p, gpointer); MINT_IN_BREAK; - - MINT_IN_CASE(MINT_LDARG_VT) - sp->data.p = vt_sp; - i32 = READ32(ip + 2); - memcpy(sp->data.p, frame->args + * (guint16 *)(ip + 1), i32); - vt_sp += (i32 + 7) & ~7; - ip += 4; - ++sp; - MINT_IN_BREAK; - -#define STARG(datamem, argtype) \ - --sp; \ - * (argtype *)(frame->args + * (guint16 *)(ip + 1)) = sp->data.datamem; \ - ip += 2; \ - - MINT_IN_CASE(MINT_STARG_I1) STARG(i, gint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STARG_U1) STARG(i, guint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STARG_I2) STARG(i, gint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STARG_U2) STARG(i, guint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STARG_I4) STARG(i, gint32); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STARG_I8) STARG(l, gint64); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STARG_R4) STARG(f, float); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STARG_R8) STARG(f, double); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STARG_O) STARG(p, gpointer); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STARG_P) STARG(p, gpointer); MINT_IN_BREAK; - - MINT_IN_CASE(MINT_STARG_VT) - i32 = READ32(ip + 2); - --sp; - memcpy(frame->args + * (guint16 *)(ip + 1), sp->data.p, i32); - vt_sp -= (i32 + 7) & ~7; - ip += 4; - MINT_IN_BREAK; - -#define STINARG(datamem, argtype) \ - do { \ - int n = * (guint16 *)(ip + 1); \ - * (argtype *)(frame->args + rtm->arg_offsets [n]) = frame->stack_args [n].data.datamem; \ - ip += 2; \ - } while (0) - - MINT_IN_CASE(MINT_STINARG_I1) STINARG(i, gint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STINARG_U1) STINARG(i, guint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STINARG_I2) STINARG(i, gint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STINARG_U2) STINARG(i, guint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STINARG_I4) STINARG(i, gint32); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STINARG_I8) STINARG(l, gint64); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STINARG_R4) STINARG(f, float); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STINARG_R8) STINARG(f, double); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STINARG_O) STINARG(p, gpointer); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STINARG_P) STINARG(p, gpointer); MINT_IN_BREAK; - - MINT_IN_CASE(MINT_STINARG_VT) { - int n = * (guint16 *)(ip + 1); - i32 = READ32(ip + 2); - memcpy (frame->args + rtm->arg_offsets [n], frame->stack_args [n].data.p, i32); - ip += 4; - MINT_IN_BREAK; - } - - MINT_IN_CASE(MINT_LDARGA) - sp->data.p = frame->args + * (guint16 *)(ip + 1); - ip += 2; - ++sp; - MINT_IN_BREAK; - -#define LDLOC(datamem, argtype) \ - sp->data.datamem = * (argtype *)(locals + * (guint16 *)(ip + 1)); \ - ip += 2; \ - ++sp; - - MINT_IN_CASE(MINT_LDLOC_I1) LDLOC(i, gint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDLOC_U1) LDLOC(i, guint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDLOC_I2) LDLOC(i, gint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDLOC_U2) LDLOC(i, guint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDLOC_I4) LDLOC(i, gint32); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDLOC_I8) LDLOC(l, gint64); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDLOC_R4) LDLOC(f, float); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDLOC_R8) LDLOC(f, double); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDLOC_O) LDLOC(p, gpointer); MINT_IN_BREAK; - MINT_IN_CASE(MINT_LDLOC_P) LDLOC(p, gpointer); MINT_IN_BREAK; - - MINT_IN_CASE(MINT_LDLOC_VT) - sp->data.p = vt_sp; - i32 = READ32(ip + 2); - memcpy(sp->data.p, locals + * (guint16 *)(ip + 1), i32); - vt_sp += (i32 + 7) & ~7; - ip += 4; - ++sp; - MINT_IN_BREAK; - - MINT_IN_CASE(MINT_LDLOCA_S) - sp->data.p = locals + * (guint16 *)(ip + 1); - ip += 2; - ++sp; - MINT_IN_BREAK; - -#define STLOC(datamem, argtype) \ - --sp; \ - * (argtype *)(locals + * (guint16 *)(ip + 1)) = sp->data.datamem; \ - ip += 2; - - MINT_IN_CASE(MINT_STLOC_I1) STLOC(i, gint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STLOC_U1) STLOC(i, guint8); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STLOC_I2) STLOC(i, gint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STLOC_U2) STLOC(i, guint16); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STLOC_I4) STLOC(i, gint32); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STLOC_I8) STLOC(l, gint64); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STLOC_R4) STLOC(f, float); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STLOC_R8) STLOC(f, double); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STLOC_O) STLOC(p, gpointer); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STLOC_P) STLOC(p, gpointer); MINT_IN_BREAK; - -#define STLOC_NP(datamem, argtype) \ - * (argtype *)(locals + * (guint16 *)(ip + 1)) = sp [-1].data.datamem; \ - ip += 2; - - MINT_IN_CASE(MINT_STLOC_NP_I4) STLOC_NP(i, gint32); MINT_IN_BREAK; - MINT_IN_CASE(MINT_STLOC_NP_O) STLOC_NP(p, gpointer); MINT_IN_BREAK; - - MINT_IN_CASE(MINT_STLOC_VT) - i32 = READ32(ip + 2); - --sp; - memcpy(locals + * (guint16 *)(ip + 1), sp->data.p, i32); - vt_sp -= (i32 + 7) & ~7; - ip += 4; - MINT_IN_BREAK; - - MINT_IN_CASE(MINT_LOCALLOC) - if (sp != frame->stack + 1) /*FIX?*/ - THROW_EX (mono_get_exception_execution_engine (NULL), ip); - sp [-1].data.p = alloca (sp [-1].data.i); - ++ip; - MINT_IN_BREAK; -#if 0 - MINT_IN_CASE(MINT_ENDFILTER) ves_abort(); MINT_IN_BREAK; -#endif - MINT_IN_CASE(MINT_INITOBJ) - --sp; - memset (sp->data.vt, 0, READ32(ip + 1)); - ip += 3; - MINT_IN_BREAK; - MINT_IN_CASE(MINT_CPBLK) - sp -= 3; - if (!sp [0].data.p || !sp [1].data.p) - THROW_EX (mono_get_exception_null_reference(), ip - 1); - ++ip; - /* FIXME: value and size may be int64... */ - memcpy (sp [0].data.p, sp [1].data.p, sp [2].data.i); - MINT_IN_BREAK; -#if 0 - MINT_IN_CASE(MINT_CONSTRAINED_) { - guint32 token; - /* FIXME: implement */ - ++ip; - token = READ32 (ip); - ip += 2; - MINT_IN_BREAK; - } -#endif - MINT_IN_CASE(MINT_INITBLK) - sp -= 3; - if (!sp [0].data.p) - THROW_EX (mono_get_exception_null_reference(), ip - 1); - ++ip; - /* FIXME: value and size may be int64... */ - memset (sp [0].data.p, sp [1].data.i, sp [2].data.i); - MINT_IN_BREAK; -#if 0 - MINT_IN_CASE(MINT_NO_) - /* FIXME: implement */ - ip += 2; - MINT_IN_BREAK; -#endif - MINT_IN_CASE(MINT_RETHROW) - /* - * need to clarify what this should actually do: - * start the search from the last found handler in - * this method or continue in the caller or what. - * Also, do we need to run finally/fault handlers after a retrow? - * Well, this implementation will follow the usual search - * for an handler, considering the current ip as throw spot. - * We need to NULL frame->ex_handler for the later code to - * actually run the new found handler. - */ - frame->ex_handler = NULL; - THROW_EX (frame->ex, ip - 1); - MINT_IN_BREAK; - MINT_IN_DEFAULT - g_print ("Unimplemented opcode: %04x %s at 0x%x\n", *ip, mono_interp_opname[*ip], ip-rtm->code); - THROW_EX (mono_get_exception_execution_engine ("Unimplemented opcode"), ip); - } - } - - g_assert_not_reached (); - /* - * Exception handling code. - * The exception object is stored in frame->ex. - */ - - handle_exception: - { - int i; - guint32 ip_offset; - MonoInvocation *inv; - MonoExceptionClause *clause; - /*char *message;*/ - MonoObject *ex_obj; - -#if DEBUG_INTERP - if (tracing) - g_print ("* Handling exception '%s' at IL_%04x\n", - frame->ex == NULL ? "** Unknown **" : mono_object_class (frame->ex)->name, - rtm == NULL ? 0 : frame->ip - rtm->code); -#endif - if (die_on_exception) - goto die_on_ex; - - for (inv = frame; inv; inv = inv->parent) { - MonoMethod *method; - if (inv->runtime_method == NULL) - continue; - method = inv->runtime_method->method; - if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) - continue; - if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) - continue; - if (inv->ip == NULL) - continue; - ip_offset = inv->ip - inv->runtime_method->code; - inv->ex_handler = NULL; /* clear this in case we are trhowing an exception while handling one - this one wins */ - for (i = 0; i < inv->runtime_method->num_clauses; ++i) { - clause = &inv->runtime_method->clauses [i]; - if (clause->flags <= 1 && MONO_OFFSET_IN_CLAUSE (clause, ip_offset)) { - if (!clause->flags) { - if (mono_object_isinst ((MonoObject*)frame->ex, clause->data.catch_class)) { - /* - * OK, we found an handler, now we need to execute the finally - * and fault blocks before branching to the handler code. - */ - inv->ex_handler = clause; -#if DEBUG_INTERP - if (tracing) - g_print ("* Found handler at '%s'\n", method->name); -#endif - goto handle_finally; - } - } else { - /* FIXME: handle filter clauses */ - g_assert (0); - } - } - } - } - /* - * If we get here, no handler was found: print a stack trace. - */ - for (inv = frame; inv; inv = inv->parent) { - if (inv->invoke_trap) - goto handle_finally; - } -die_on_ex: - ex_obj = (MonoObject*)frame->ex; - mono_unhandled_exception (ex_obj); - exit (1); - } - handle_finally: - { - int i; - guint32 ip_offset; - MonoExceptionClause *clause; - GSList *old_list = finally_ips; - MonoMethod *method = frame->runtime_method->method; - MonoMethodHeader *header = mono_method_get_header (method); - -#if DEBUG_INTERP - if (tracing) - g_print ("* Handle finally IL_%04x\n", endfinally_ip == NULL ? 0 : endfinally_ip - rtm->code); -#endif - if (rtm == NULL || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) - || (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME))) { - goto exit_frame; - } - ip_offset = frame->ip - rtm->code; - - if (endfinally_ip != NULL) - finally_ips = g_slist_prepend(finally_ips, (void *)endfinally_ip); - for (i = 0; i < header->num_clauses; ++i) - if (frame->ex_handler == &rtm->clauses [i]) - break; - while (i > 0) { - --i; - clause = &rtm->clauses [i]; - if (MONO_OFFSET_IN_CLAUSE (clause, ip_offset) && (endfinally_ip == NULL || !(MONO_OFFSET_IN_CLAUSE (clause, endfinally_ip - rtm->code)))) { - if (clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY) { - ip = rtm->code + clause->handler_offset; - finally_ips = g_slist_prepend (finally_ips, (gpointer) ip); -#if DEBUG_INTERP - if (tracing) - g_print ("* Found finally at IL_%04x with exception: %s\n", clause->handler_offset, frame->ex? "yes": "no"); -#endif - } - } - } - - endfinally_ip = NULL; - - if (old_list != finally_ips && finally_ips) { - ip = finally_ips->data; - finally_ips = g_slist_remove (finally_ips, ip); - sp = frame->stack; /* spec says stack should be empty at endfinally so it should be at the start too */ - goto main_loop; - } - - /* - * If an exception is set, we need to execute the fault handler, too, - * otherwise, we continue normally. - */ - if (frame->ex) - goto handle_fault; - ves_abort(); - } - handle_fault: - { - int i; - guint32 ip_offset; - MonoExceptionClause *clause; - MonoMethodHeader *header = mono_method_get_header (frame->runtime_method->method); - -#if DEBUG_INTERP - if (tracing) - g_print ("* Handle fault\n"); -#endif - ip_offset = frame->ip - rtm->code; - for (i = 0; i < header->num_clauses; ++i) { - clause = &rtm->clauses [i]; - if (clause->flags == MONO_EXCEPTION_CLAUSE_FAULT && MONO_OFFSET_IN_CLAUSE (clause, ip_offset)) { - ip = rtm->code + clause->handler_offset; -#if DEBUG_INTERP - if (tracing) - g_print ("* Executing handler at IL_%04x\n", clause->handler_offset); -#endif - goto main_loop; - } - } - /* - * If the handler for the exception was found in this method, we jump - * to it right away, otherwise we return and let the caller run - * the finally, fault and catch blocks. - * This same code should be present in the endfault opcode, but it - * is corrently not assigned in the ECMA specs: LAMESPEC. - */ - if (frame->ex_handler) { -#if DEBUG_INTERP - if (tracing) - g_print ("* Executing handler at IL_%04x\n", frame->ex_handler->handler_offset); -#endif - ip = rtm->code + frame->ex_handler->handler_offset; - sp = frame->stack; - vt_sp = (char *)sp + rtm->stack_size; - sp->data.p = frame->ex; - ++sp; - goto main_loop; - } - goto exit_frame; - } -exit_frame: - DEBUG_LEAVE (); -} - -void -ves_exec_method (MonoInvocation *frame) -{ - ThreadContext *context = TlsGetValue (thread_context_id); - ThreadContext context_struct; - jmp_buf env; - - frame->ex = NULL; - - if (setjmp(env)) { - mono_unhandled_exception ((MonoObject*)frame->ex); - return; - } - if (context == NULL) { - context = &context_struct; - context_struct.domain = mono_domain_get (); - context_struct.base_frame = frame; - context_struct.current_frame = NULL; - context_struct.env_frame = frame; - context_struct.current_env = &env; - context_struct.search_for_handler = 0; - context_struct.managed_code = 0; - TlsSetValue (thread_context_id, context); - } - frame->ip = NULL; - frame->parent = context->current_frame; - frame->runtime_method = mono_interp_get_runtime_method (frame->method); - context->managed_code = 1; - ves_exec_method_with_context(frame, context); - context->managed_code = 0; - if (frame->ex) { - if (context != &context_struct && context->current_env) { - context->env_frame->ex = frame->ex; - longjmp (*context->current_env, 1); - } - else - mono_unhandled_exception ((MonoObject*)frame->ex); - } - if (context->base_frame == frame) - TlsSetValue (thread_context_id, NULL); - else - context->current_frame = frame->parent; -} - -static int -ves_exec (MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]) -{ - MonoImage *image = mono_assembly_get_image (assembly); - MonoMethod *method; - MonoObject *exc = NULL; - int rval; - - method = mono_get_method (image, mono_image_get_entry_point (image), NULL); - if (!method) - g_error ("No entry point method found in %s", mono_image_get_filename (image)); - - rval = mono_runtime_run_main (method, argc, argv, &exc); - if (exc != NULL) - mono_unhandled_exception (exc); - - return rval; -} - -static void -usage (void) -{ - fprintf (stderr, - "mint %s, the Mono ECMA CLI interpreter, (C) 2001, 2002 Ximian, Inc.\n\n" - "Usage is: mint [options] executable args...\n\n", VERSION); - fprintf (stderr, - "Runtime Debugging:\n" -#ifdef DEBUG_INTERP - " --debug\n" -#endif - " --dieonex\n" - " --noptr\t\t\tdon't print pointer addresses in trace output\n" - " --opcode-count\n" - " --print-vtable\n" - " --traceclassinit\n" - "\n" - "Development:\n" - " --debug method_name\n" - " --profile\n" - " --trace\n" - " --traceops\n" - "\n" - "Runtime:\n" - " --config filename load the specified config file instead of the default\n" - " --workers n maximum number of worker threads\n" - ); - exit (1); -} - -#ifdef RUN_TEST -static void -test_load_class (MonoImage* image) -{ - MonoTableInfo *t = &image->tables [MONO_TABLE_TYPEDEF]; - MonoClass *klass; - int i; - - for (i = 1; i <= t->rows; ++i) { - klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | i); - mono_class_init (klass); - } -} -#endif - -static void -add_signal_handler (int signo, void (*handler)(int)) -{ -#ifdef HOST_WIN32 - signal (signo, handler); -#else - struct sigaction sa; - - sa.sa_handler = handler; - sigemptyset (&sa.sa_mask); - sa.sa_flags = 0; - - g_assert (sigaction (signo, &sa, NULL) != -1); -#endif -} - -static void -segv_handler (int signum) -{ - ThreadContext *context = TlsGetValue (thread_context_id); - MonoException *segv_exception; - - if (context == NULL) - return; - segv_exception = mono_get_exception_null_reference (); - segv_exception->message = mono_string_new (mono_domain_get (), "Null Reference (SIGSEGV)"); - mono_raise_exception (segv_exception); -} - - -static void -quit_handler (int signum) -{ - ThreadContext *context = TlsGetValue (thread_context_id); - MonoException *quit_exception; - - if (context == NULL) - return; - quit_exception = mono_get_exception_execution_engine ("Interrupted (SIGQUIT)."); - mono_raise_exception (quit_exception); -} - -static void -abrt_handler (int signum) -{ - ThreadContext *context = TlsGetValue (thread_context_id); - MonoException *abrt_exception; - - if (context == NULL) - return; - abrt_exception = mono_get_exception_execution_engine ("Abort (SIGABRT)."); - mono_raise_exception (abrt_exception); -} - -static void -thread_abort_handler (int signum) -{ - ThreadContext *context = TlsGetValue (thread_context_id); - MonoException *exc; - - if (context == NULL) - return; - - exc = mono_thread_request_interruption (context->managed_code); - if (exc) mono_raise_exception (exc); -} - -static MonoBoolean -ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info, - MonoReflectionMethod **method, - gint32 *iloffset, gint32 *native_offset, - MonoString **file, gint32 *line, gint32 *column) -{ - ThreadContext *context = TlsGetValue (thread_context_id); - MonoInvocation *inv = context->current_frame; - int i; - - for (i = 0; inv && i < skip; inv = inv->parent) - if (inv->runtime_method != NULL) - ++i; - - if (iloffset) - *iloffset = 0; - if (native_offset) - *native_offset = 0; - if (method) - *method = inv == NULL ? NULL : mono_method_get_object (context->domain, inv->runtime_method->method, NULL); - if (line) - *line = 0; - if (need_file_info) { - if (column) - *column = 0; - if (file) - *file = mono_string_new (mono_domain_get (), "unknown"); - } - - return TRUE; -} - -static MonoArray * -ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info) -{ - MonoDomain *domain = mono_domain_get (); - MonoArray *res; - MonoArray *ta = exc->trace_ips; - int i, len; - - if (ta == NULL) { - /* Exception is not thrown yet */ - return mono_array_new (domain, mono_defaults.stack_frame_class, 0); - } - - len = mono_array_length (ta); - - res = mono_array_new (domain, mono_defaults.stack_frame_class, len > skip ? len - skip : 0); - - for (i = skip; i < len / 2; i++) { - MonoStackFrame *sf = (MonoStackFrame *)mono_object_new (domain, mono_defaults.stack_frame_class); - gushort *ip = mono_array_get (ta, gpointer, 2 * i + 1); - RuntimeMethod *rtm = mono_array_get (ta, gpointer, 2 * i); - - if (rtm != NULL) { - sf->method = mono_method_get_object (domain, rtm->method, NULL); - sf->native_offset = ip - rtm->code; - } - -#if 0 - sf->il_offset = mono_debug_il_offset_from_address (ji->method, sf->native_offset, domain); - - if (need_file_info) { - gchar *filename; - - filename = mono_debug_source_location_from_address (ji->method, sf->native_offset, &sf->line, domain); - - sf->filename = filename? mono_string_new (domain, filename): NULL; - sf->column = 0; - - g_free (filename); - } -#endif - - mono_array_set (res, gpointer, i, sf); - } - - return res; -} - -static MonoObject * -ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target, - MonoReflectionMethod *info) -{ - MonoClass *delegate_class = mono_class_from_mono_type (type->type); - MonoObject *delegate; - - mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class); - - delegate = mono_object_new (mono_object_domain (type), delegate_class); - - interp_delegate_ctor (mono_object_domain (type), delegate, target, mono_interp_get_runtime_method (info->method)); - - return delegate; -} - - -typedef struct -{ - MonoDomain *domain; - int enable_debugging; - char *file; - int argc; - char **argv; -} MainThreadArgs; - -static void main_thread_handler (gpointer user_data) -{ - MainThreadArgs *main_args=(MainThreadArgs *)user_data; - MonoAssembly *assembly; - - if (main_args->enable_debugging) { - mono_debug_init (MONO_DEBUG_FORMAT_MONO); - mono_debug_init_1 (main_args->domain); - } - - assembly = mono_domain_assembly_open (main_args->domain, - main_args->file); - - if (!assembly){ - fprintf (stderr, "Can not open image %s\n", main_args->file); - exit (1); - } - - if (main_args->enable_debugging) - mono_debug_init_2 (assembly); - -#ifdef RUN_TEST - test_load_class (assembly->image); -#else - - ves_exec (main_args->domain, assembly, main_args->argc, main_args->argv); -#endif -} - -static void -mono_runtime_install_handlers (void) -{ - add_signal_handler (SIGSEGV, segv_handler); - add_signal_handler (SIGINT, quit_handler); - add_signal_handler (SIGABRT, abrt_handler); - add_signal_handler (mono_thread_get_abort_signal (), thread_abort_handler); -} - -static void -quit_function (MonoDomain *domain, gpointer user_data) -{ - mono_profiler_shutdown (); - - mono_runtime_cleanup (domain); - mono_domain_free (domain, TRUE); - -} - -void -mono_interp_cleanup(MonoDomain *domain) -{ - quit_function (domain, NULL); -} - -int -mono_interp_exec(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]) -{ - return ves_exec (domain, assembly, argc, argv); -} - -MonoDomain * -mono_interp_init(const char *file) -{ - MonoDomain *domain; - - g_set_prgname (file); - mono_set_rootdir (); - - g_log_set_always_fatal (G_LOG_LEVEL_ERROR); - g_log_set_fatal_mask (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR); - - if (!g_thread_supported ()) - g_thread_init (NULL); - - thread_context_id = TlsAlloc (); - TlsSetValue (thread_context_id, NULL); - mono_mutex_init_recursive (&runtime_method_lookup_section); - mono_mutex_init_recursive (&create_method_pointer_mutex); - - mono_runtime_install_handlers (); - mono_interp_transform_init (); - mono_install_compile_method (mono_create_method_pointer); - mono_install_runtime_invoke (interp_mono_runtime_invoke); - mono_install_remoting_trampoline (interp_create_remoting_trampoline); - mono_install_trampoline (interp_create_trampoline); - - mono_install_handler (interp_ex_handler); - mono_install_stack_walk (interp_walk_stack); - mono_install_runtime_cleanup (quit_function); - abort_requested = mono_thread_interruption_request_flag (); - - domain = mono_init_from_assembly (file, file); -#ifdef __hpux /* generates very big stack frames */ - mono_threads_set_default_stacksize(32*1024*1024); -#endif - mono_icall_init (); - mono_add_internal_call ("System.Diagnostics.StackFrame::get_frame_info", ves_icall_get_frame_info); - mono_add_internal_call ("System.Diagnostics.StackTrace::get_trace", ves_icall_get_trace); - mono_add_internal_call ("Mono.Runtime::mono_runtime_install_handlers", mono_runtime_install_handlers); - mono_add_internal_call ("System.Delegate::CreateDelegate_internal", ves_icall_System_Delegate_CreateDelegate_internal); - - mono_register_jit_icall (mono_thread_interruption_checkpoint, "mono_thread_interruption_checkpoint", mono_create_icall_signature ("void"), FALSE); - - mono_runtime_init (domain, NULL, NULL); - - - mono_thread_attach (domain); - return domain; -} - -int -mono_main (int argc, char *argv []) -{ - MonoDomain *domain; - int retval = 0, i; - char *file, *config_file = NULL; - int enable_debugging = FALSE; - MainThreadArgs main_args; - const char *error; - - setlocale (LC_ALL, ""); - if (argc < 2) - usage (); - - MONO_GC_PRE_INIT (); - - for (i = 1; i < argc && argv [i][0] == '-'; i++){ - if (strcmp (argv [i], "--trace") == 0) - global_tracing = 1; - if (strcmp (argv [i], "--noptr") == 0) - global_no_pointers = 1; - if (strcmp (argv [i], "--traceops") == 0) - global_tracing = 2; - if (strcmp (argv [i], "--traceopt") == 0) - ++mono_interp_traceopt; - if (strcmp (argv [i], "--dieonex") == 0) { - die_on_exception = 1; - enable_debugging = 1; - } - if (strcmp (argv [i], "--print-vtable") == 0) - mono_print_vtable = TRUE; - if (strcmp (argv [i], "--profile") == 0) - mono_profiler_load (NULL); - if (strcmp (argv [i], "--config") == 0) - config_file = argv [++i]; - if (strcmp (argv [i], "--help") == 0) - usage (); -#if DEBUG_INTERP - if (strcmp (argv [i], "--debug") == 0) { - MonoMethodDesc *desc = mono_method_desc_new (argv [++i], FALSE); - if (!desc) - g_error ("Invalid method name '%s'", argv [i]); - db_methods = g_list_append (db_methods, desc); - } - if (strcmp (argv [i], "--nested") == 0) - nested_trace = 1; -#endif - } - - file = argv [i]; - - if (!file) - usage (); - - domain = mono_interp_init(file); - mono_config_parse (config_file); - - error = mono_check_corlib_version (); - if (error) { - fprintf (stderr, "Corlib not in sync with this runtime: %s\n", error); - fprintf (stderr, "Download a newer corlib at http://www.go-mono.com/daily.\n"); - exit (1); - } - - main_args.domain=domain; - main_args.file=file; - main_args.argc=argc-i; - main_args.argv=argv+i; - main_args.enable_debugging=enable_debugging; - - mono_runtime_exec_managed_code (domain, main_thread_handler, - &main_args); - - quit_function (domain, NULL); - - /* Get the return value from System.Environment.ExitCode */ - retval=mono_environment_exitcode_get (); - -#if COUNT_OPS - for (i = 0; i < 512; i++) - if (opcode_counts[i] != 0) - printf("%s %d\n", mono_interp_opname[i], opcode_counts[i]); -#endif - return retval; -} diff --git a/mono/interpreter/interp.h b/mono/interpreter/interp.h deleted file mode 100644 index 0953e5a54cf..00000000000 --- a/mono/interpreter/interp.h +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "config.h" - -enum { - VAL_I32 = 0, - VAL_DOUBLE = 1, - VAL_I64 = 2, - VAL_VALUET = 3, - VAL_POINTER = 4, - VAL_NATI = 0 + VAL_POINTER, - VAL_MP = 1 + VAL_POINTER, - VAL_TP = 2 + VAL_POINTER, - VAL_OBJ = 3 + VAL_POINTER -}; - -#if SIZEOF_VOID_P == 4 -typedef guint32 mono_u; -typedef gint32 mono_i; -#elif SIZEOF_VOID_P == 8 -typedef guint64 mono_u; -typedef gint64 mono_i; -#endif - -/* - * Value types are represented on the eval stack as pointers to the - * actual storage. The size field tells how much storage is allocated. - * A value type can't be larger than 16 MB. - */ -typedef struct { - union { - gint32 i; - gint64 l; - double f; - /* native size integer and pointer types */ - gpointer p; - mono_u nati; - gpointer vt; - } data; -#if defined(__ppc__) || defined(__powerpc__) - int pad; -#endif -} stackval; - -typedef struct _MonoInvocation MonoInvocation; - -typedef void (*MonoFunc) (void); -typedef void (*MonoPIFunc) (MonoFunc callme, void *retval, void *obj_this, stackval *arguments); - -/* - * Structure representing a method transformed for the interpreter - * This is domain specific - */ -typedef struct _RuntimeMethod -{ - /* NOTE: These first two elements (method and - next_jit_code_hash) must be in the same order and at the - same offset as in MonoJitInfo, because of the jit_code_hash - internal hash table in MonoDomain. */ - MonoMethod *method; - struct _RuntimeMethod *next_jit_code_hash; - guint32 locals_size; - guint32 args_size; - guint32 stack_size; - guint32 vt_stack_size; - guint32 alloca_size; - unsigned short *code; - unsigned short *new_body_start; /* after all STINARG instrs */ - MonoPIFunc func; - int num_clauses; - MonoExceptionClause *clauses; - void **data_items; - int transformed; - guint32 *arg_offsets; - guint32 *local_offsets; - unsigned int param_count; - unsigned int hasthis; - unsigned int valuetype; -} RuntimeMethod; - -struct _MonoInvocation { - MonoInvocation *parent; /* parent */ - RuntimeMethod *runtime_method; /* parent */ - MonoMethod *method; /* parent */ - stackval *retval; /* parent */ - void *obj; /* this - parent */ - char *args; - stackval *stack_args; /* parent */ - stackval *stack; - stackval *sp; /* For GC stack marking */ - /* exception info */ - unsigned char invoke_trap; - const unsigned short *ip; - MonoException *ex; - MonoExceptionClause *ex_handler; -}; - -typedef struct { - MonoDomain *domain; - MonoInvocation *base_frame; - MonoInvocation *current_frame; - MonoInvocation *env_frame; - jmp_buf *current_env; - unsigned char search_for_handler; - unsigned char managed_code; -} ThreadContext; - -void mono_init_icall (void); - -MonoException * -mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *context); - -MonoDelegate* -mono_interp_ftnptr_to_delegate (MonoClass *klass, gpointer ftn); - -void -mono_interp_transform_init (void); - -void inline stackval_from_data (MonoType *type, stackval *result, char *data, gboolean pinvoke); -void inline stackval_to_data (MonoType *type, stackval *val, char *data, gboolean pinvoke); -void ves_exec_method (MonoInvocation *frame); - -/* - * defined in an arch specific file. - */ -MonoPIFunc -mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor); - -RuntimeMethod * -mono_interp_get_runtime_method (MonoMethod *method); - -void *mono_arch_create_method_pointer (MonoMethod *method); - -extern int mono_interp_traceopt; diff --git a/mono/interpreter/main.c b/mono/interpreter/main.c deleted file mode 100644 index 70b5d96d1b7..00000000000 --- a/mono/interpreter/main.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "interp.h" -#include "embed.h" - -int -main (int argc, char* argv[]) -{ - return mono_main (argc, argv); -} - diff --git a/mono/interpreter/mint.1 b/mono/interpreter/mint.1 deleted file mode 100644 index 77e00c376f6..00000000000 --- a/mono/interpreter/mint.1 +++ /dev/null @@ -1,82 +0,0 @@ -.\" -.\" mint manual page. -.\" (C) Ximian, Inc. -.\" Author: -.\" Miguel de Icaza (miguel@gnu.org) -.\" -.TH Mono "Mono 1.0" -.SH NAME -mint \- Mono ECMA-CLI interpreter. -.SH SYNOPSIS -.PP -.B mint -[\-\-help] [\-\-opcode\-count] [\-\-trace] [\-\-traceops] [\-\-profile] -[\-\-config filename] [\-\-debug method] -program.exe [arguments...] -.SH DESCRIPTION -The \fImint\fP program is an interpreter for ECMA CLI byte codes. It -executes the bytecodes contains in -.I program.exe -and optionally passes -the -.I arguments -to it. -.SH OPTIONS -The following Generic options are supported: -.TP -.I "--help", "-h" -Displays usage instructions. -.TP -.I "--config filename" -Load the specified configuration file instead of the default one(s). -The default files are /etc/mono/config and ~/.mono/config or the file -specified in the MONO_CONFIG environment variable, if set. -.TP -.I "--trace" -Traces execution showing when methods are entered and left. -.I "--traceops" -Traces execution at the instruction level and displays the stack contents. -.I "--traceclassinit" -Shows when classes are initialized -.TP -.I "--noptr" -Suppresses printing of pointer addresses in trace output. -.TP -.I "--profile" -Performs runtime profiling of the code and displays statistics at the -end of execution. -.TP -.I "--opcode-count" -Displays the number of opcodes executed. -.TP -.I "--dieonex" -Aborts execution upon hitting an exception. -.TP -.I "--debug method" -Debugs the method whose name is `method'. You can specify the method -like this: `class:method' or `class::method' -.TP -.I "--opcode-count" -Displays the number of opcodes executed -.PP -.SH ENVIRONMENT VARIABLES -.TP -.I "MONO_PATH" -Provides a search path to mono and mint where to look for library files. -Directories are separated by the platform path separator (colons on unix). Example: -.B /home/username/lib:/usr/local/mono/lib -.PP -.SH FILES -Assemblies are lodaed from the installation lib directory. If you set -`prefix' to /usr, the assemblies will be located in /usr/lib. -.PP -/etc/mono/config, ~/.mono/config -.IP -Mono runtime configuration file. See the mono-config(5) manual page -for more information. -.SH MAILING LISTS -Visit http://mail.ximian.com/mailman/mono-list for details. -.SH WEB SITE -Visit: http://www.go-mono.com for details -.SH SEE ALSO -.BR mono(1), monodis(1) diff --git a/mono/interpreter/mintops.c b/mono/interpreter/mintops.c deleted file mode 100644 index 5b4d69269e8..00000000000 --- a/mono/interpreter/mintops.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Utilities for handling interpreter VM instructions - * - * Authors: - * Bernie Solomon (bernard@ugsolutions.com) - * - */ -#include -#include -#include "mintops.h" - -#define OPDEF(a,b,c,d) \ - b, -const char *mono_interp_opname[] = { -#include "mintops.def" - "" -}; -#undef OPDEF - -#define OPDEF(a,b,c,d) \ - c, -unsigned char mono_interp_oplen[] = { -#include "mintops.def" - 0 -}; -#undef OPDEF - - -#define OPDEF(a,b,c,d) \ - d, -MintOpArgType mono_interp_opargtype[] = { -#include "mintops.def" - 0 -}; -#undef OPDEF - -const guint16 * -mono_interp_dis_mintop(const guint16 *base, const guint16 *ip) -{ - int len = mono_interp_oplen [*ip]; - guint32 token; - int target; - if (len < 0 || len > 10) { - g_print ("op %d len %d\n", *ip, len); - g_assert_not_reached (); - } else if (len == 0) { /* SWITCH */ - int n = READ32 (ip + 1); - len = 3 + n * 2; - } - - g_print ("IL_%04x: %-10s", ip - base, mono_interp_opname [*ip]); - switch (mono_interp_opargtype [*ip]) { - case MintOpNoArgs: - break; - case MintOpUShortInt: - g_print (" %u", * (guint16 *)(ip + 1)); - break; - case MintOpTwoShorts: - g_print (" %u,%u", * (guint16 *)(ip + 1), * (guint16 *)(ip + 2)); - break; - case MintOpShortAndInt: - g_print (" %u,%u", * (guint16 *)(ip + 1), (guint32)READ32(ip + 2)); - break; - case MintOpShortInt: - g_print (" %d", * (short *)(ip + 1)); - break; - case MintOpClassToken: - case MintOpMethodToken: - case MintOpFieldToken: - token = * (guint16 *)(ip + 1); - g_print (" %u", token); - break; - case MintOpInt: - g_print (" %d", (gint32)READ32 (ip + 1)); - break; - case MintOpLongInt: - g_print (" %lld", (gint64)READ64 (ip + 1)); - break; - case MintOpFloat: { - gint32 tmp = READ32 (ip + 1); - g_print (" %g", * (float *)&tmp); - break; - } - case MintOpDouble: { - gint64 tmp = READ64 (ip + 1); - g_print (" %g", * (double *)&tmp); - break; - } - case MintOpShortBranch: - target = ip + * (short *)(ip + 1) - base; - g_print (" IL_%04x", target); - break; - case MintOpBranch: - target = ip + (gint32)READ32 (ip + 1) - base; - g_print (" IL_%04x", target); - break; - case MintOpSwitch: { - const guint16 *p = ip + 1; - int sval = (gint32)READ32 (p); - int i; - p += 2; - g_print ("("); - for (i = 0; i < sval; ++i) { - int offset; - if (i > 0) - g_print (", "); - offset = (gint32)READ32 (p); - g_print ("IL_%04x", ip - base + 3 + 2 * sval + offset); - p += 2; - } - g_print (")"); - break; - } - default: - g_print("unknown arg type\n"); - } - - return ip + len; -} - diff --git a/mono/interpreter/mintops.def b/mono/interpreter/mintops.def deleted file mode 100644 index 550ba655629..00000000000 --- a/mono/interpreter/mintops.def +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Definitions of VM instructions executed by interp.c - * - * Authors: - * Bernie Solomon (bernard@ugsolutions.com) - * - */ - -/* OPDEF (opsymbol, opstring, oplength, optype) */ - -OPDEF(MINT_NOP, "nop", 1, MintOpNoArgs) -OPDEF(MINT_BREAK, "break", 1, MintOpNoArgs) -OPDEF(MINT_LDNULL, "ldnull", 1, MintOpNoArgs) -OPDEF(MINT_DUP, "dup", 1, MintOpNoArgs) -OPDEF(MINT_DUP_VT, "dup.vt", 3, MintOpInt) -OPDEF(MINT_POP, "pop", 1, MintOpNoArgs) - -OPDEF(MINT_RET, "ret", 1, MintOpNoArgs) -OPDEF(MINT_RET_VOID, "ret.void", 1, MintOpNoArgs) -OPDEF(MINT_RET_VT, "ret.vt", 3, MintOpInt) - -OPDEF(MINT_VTRESULT, "vtresult", 4, MintOpShortAndInt) /*FIX should be unsigned*/ - -OPDEF(MINT_LDC_I4_M1, "ldc.i4.m1", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_0, "ldc.i4.0", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_1, "ldc.i4.1", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_2, "ldc.i4.2", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_3, "ldc.i4.3", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_4, "ldc.i4.4", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_5, "ldc.i4.5", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_6, "ldc.i4.6", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_7, "ldc.i4.7", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_8, "ldc.i4.8", 1, MintOpNoArgs) - -OPDEF(MINT_LDC_I4_S, "ldc.i4.s", 2, MintOpShortInt) -OPDEF(MINT_LDC_I4, "ldc.i4", 3, MintOpInt) -OPDEF(MINT_LDC_I8, "ldc.i8", 5, MintOpLongInt) - -OPDEF(MINT_LDC_R4, "ldc.r4", 3, MintOpFloat) -OPDEF(MINT_LDC_R8, "ldc.r8", 5, MintOpDouble) - -OPDEF(MINT_LDARG_I1, "ldarg.i1", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_U1, "ldarg.u1", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_I2, "ldarg.i2", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_U2, "ldarg.u2", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_I4, "ldarg.i4", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_I8, "ldarg.i8", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_R4, "ldarg.r4", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_R8, "ldarg.r8", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_O, "ldarg.o", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_P, "ldarg.p", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_VT, "ldarg.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_LDTHIS, "ldthis", 1, MintOpNoArgs) - -OPDEF(MINT_STARG_I1, "starg.i1", 2, MintOpUShortInt) -OPDEF(MINT_STARG_U1, "starg.u1", 2, MintOpUShortInt) -OPDEF(MINT_STARG_I2, "starg.i2", 2, MintOpUShortInt) -OPDEF(MINT_STARG_U2, "starg.u2", 2, MintOpUShortInt) -OPDEF(MINT_STARG_I4, "starg.i4", 2, MintOpUShortInt) -OPDEF(MINT_STARG_I8, "starg.i8", 2, MintOpUShortInt) -OPDEF(MINT_STARG_R4, "starg.r4", 2, MintOpUShortInt) -OPDEF(MINT_STARG_R8, "starg.r8", 2, MintOpUShortInt) -OPDEF(MINT_STARG_O, "starg.o", 2, MintOpUShortInt) -OPDEF(MINT_STARG_P, "starg.p", 2, MintOpUShortInt) -OPDEF(MINT_STARG_VT, "starg.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_STTHIS, "stthis", 1, MintOpNoArgs) - -OPDEF(MINT_STINARG_I1, "stinarg.i1", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_U1, "stinarg.u1", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_I2, "stinarg.i2", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_U2, "stinarg.u2", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_I4, "stinarg.i4", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_I8, "stinarg.i8", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_R4, "stinarg.r4", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_R8, "stinarg.r8", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_O, "stinarg.o", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_P, "stinarg.p", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_VT, "stinarg.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_LDARGA, "ldarga", 2, MintOpUShortInt) -OPDEF(MINT_LDTHISA, "ldthisa", 1, MintOpNoArgs) - -OPDEF(MINT_LDFLD_I1, "ldfld.i1", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_U1, "ldfld.u1", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_I2, "ldfld.i2", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_U2, "ldfld.u2", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_I4, "ldfld.i4", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_I8, "ldfld.i8", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_R4, "ldfld.r4", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_R8, "ldfld.r8", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_O, "ldfld.o", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_P, "ldfld.p", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_VT, "ldfld.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_LDRMFLD, "ldrmfld", 2, MintOpFieldToken) -OPDEF(MINT_LDRMFLD_VT, "ldrmfld.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_LDFLDA, "ldflda", 2, MintOpUShortInt) - -OPDEF(MINT_STFLD_I1, "stfld.i1", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_U1, "stfld.u1", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_I2, "stfld.i2", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_U2, "stfld.u2", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_I4, "stfld.i4", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_I8, "stfld.i8", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_R4, "stfld.r4", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_R8, "stfld.r8", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_O, "stfld.o", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_P, "stfld.p", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_VT, "stfld.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_STRMFLD, "strmfld", 2, MintOpFieldToken) -OPDEF(MINT_STRMFLD_VT, "strmfld.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_LDSFLD, "ldsfld", 3, MintOpTwoShorts) -OPDEF(MINT_LDSFLD_I4, "ldsfld.i4", 3, MintOpTwoShorts) -OPDEF(MINT_LDSFLD_O, "ldsfld.o", 3, MintOpTwoShorts) -OPDEF(MINT_LDSFLD_VT, "ldsfld.vt", 4, MintOpShortAndInt) -OPDEF(MINT_STSFLD, "stsfld", 2, MintOpUShortInt) -OPDEF(MINT_STSFLD_VT, "stsfld.vt", 4, MintOpShortAndInt) -OPDEF(MINT_LDSFLDA, "ldsflda", 2, MintOpUShortInt) - -OPDEF(MINT_LDLOC_I1, "ldloc.i1", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_U1, "ldloc.u1", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_I2, "ldloc.i2", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_U2, "ldloc.u2", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_I4, "ldloc.i4", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_I8, "ldloc.i8", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_R4, "ldloc.r4", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_R8, "ldloc.r8", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_O, "ldloc.o", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_P, "ldloc.p", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_VT, "ldloc.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_STLOC_I1, "stloc.i1", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_U1, "stloc.u1", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_I2, "stloc.i2", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_U2, "stloc.u2", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_I4, "stloc.i4", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_I8, "stloc.i8", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_R4, "stloc.r4", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_R8, "stloc.r8", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_O, "stloc.o", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_P, "stloc.p", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_VT, "stloc.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_STLOC_NP_I4, "stloc.np.i4", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_NP_O, "stloc.np.o", 2, MintOpUShortInt) - -OPDEF(MINT_LDLOCA_S, "ldloca.s", 2, MintOpUShortInt) - -OPDEF(MINT_LDIND_I1, "ldind.i1", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_U1, "ldind.u1", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_I2, "ldind.i2", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_U2, "ldind.u2", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_I4, "ldind.i4", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_U4, "ldind.u4", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_I8, "ldind.i8", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_I, "ldind.i", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_R4, "ldind.r4", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_R8, "ldind.r8", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_REF, "ldind.ref", 1, MintOpNoArgs) -OPDEF(MINT_STIND_I1, "stind.i1", 1, MintOpNoArgs) -OPDEF(MINT_STIND_I2, "stind.i2", 1, MintOpNoArgs) -OPDEF(MINT_STIND_I4, "stind.i4", 1, MintOpNoArgs) -OPDEF(MINT_STIND_I8, "stind.i8", 1, MintOpNoArgs) -OPDEF(MINT_STIND_I, "stind.i", 1, MintOpNoArgs) -OPDEF(MINT_STIND_R4, "stind.r4", 1, MintOpNoArgs) -OPDEF(MINT_STIND_R8, "stind.r8", 1, MintOpNoArgs) -OPDEF(MINT_STIND_REF, "stind.ref", 1, MintOpNoArgs) - -OPDEF(MINT_BR, "br", 3, MintOpBranch) -OPDEF(MINT_LEAVE, "leave", 3, MintOpBranch) -OPDEF(MINT_BR_S, "br.s", 2, MintOpShortBranch) -OPDEF(MINT_LEAVE_S, "leave.s", 2, MintOpShortBranch) - -OPDEF(MINT_THROW, "throw", 1, MintOpNoArgs) -OPDEF(MINT_RETHROW, "rethrow", 1, MintOpNoArgs) -OPDEF(MINT_ENDFINALLY, "endfinally", 1, MintOpNoArgs) - -OPDEF(MINT_BRFALSE_I4, "brfalse.i4", 3, MintOpBranch) -OPDEF(MINT_BRFALSE_I8, "brfalse.i8", 3, MintOpBranch) -OPDEF(MINT_BRFALSE_R8, "brfalse.r8", 3, MintOpBranch) -OPDEF(MINT_BRTRUE_I4, "brtrue.i4", 3, MintOpBranch) -OPDEF(MINT_BRTRUE_I8, "brtrue.i8", 3, MintOpBranch) -OPDEF(MINT_BRTRUE_R8, "brtrue.r8", 3, MintOpBranch) - -OPDEF(MINT_BRFALSE_I4_S, "brfalse.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BRFALSE_I8_S, "brfalse.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BRFALSE_R8_S, "brfalse.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BRTRUE_I4_S, "brtrue.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BRTRUE_I8_S, "brtrue.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BRTRUE_R8_S, "brtrue.r8.s", 2, MintOpShortBranch) - -OPDEF(MINT_BEQ_I4, "beq.i4", 3, MintOpBranch) -OPDEF(MINT_BEQ_I8, "beq.i8", 3, MintOpBranch) -OPDEF(MINT_BEQ_R8, "beq.r8", 3, MintOpBranch) -OPDEF(MINT_BGE_I4, "bge.i4", 3, MintOpBranch) -OPDEF(MINT_BGE_I8, "bge.i8", 3, MintOpBranch) -OPDEF(MINT_BGE_R8, "bge.r8", 3, MintOpBranch) -OPDEF(MINT_BGT_I4, "bgt.i4", 3, MintOpBranch) -OPDEF(MINT_BGT_I8, "bgt.i8", 3, MintOpBranch) -OPDEF(MINT_BGT_R8, "bgt.r8", 3, MintOpBranch) -OPDEF(MINT_BLT_I4, "blt.i4", 3, MintOpBranch) -OPDEF(MINT_BLT_I8, "blt.i8", 3, MintOpBranch) -OPDEF(MINT_BLT_R8, "blt.r8", 3, MintOpBranch) -OPDEF(MINT_BLE_I4, "ble.i4", 3, MintOpBranch) -OPDEF(MINT_BLE_I8, "ble.i8", 3, MintOpBranch) -OPDEF(MINT_BLE_R8, "ble.r8", 3, MintOpBranch) - -OPDEF(MINT_BNE_UN_I4, "bne.un.i4", 3, MintOpBranch) -OPDEF(MINT_BNE_UN_I8, "bne.un.i8", 3, MintOpBranch) -OPDEF(MINT_BNE_UN_R8, "bne.un.r8", 3, MintOpBranch) -OPDEF(MINT_BGE_UN_I4, "bge.un.i4", 3, MintOpBranch) -OPDEF(MINT_BGE_UN_I8, "bge.un.i8", 3, MintOpBranch) -OPDEF(MINT_BGE_UN_R8, "bge.un.r8", 3, MintOpBranch) -OPDEF(MINT_BGT_UN_I4, "bgt.un.i4", 3, MintOpBranch) -OPDEF(MINT_BGT_UN_I8, "bgt.un.i8", 3, MintOpBranch) -OPDEF(MINT_BGT_UN_R8, "bgt.un.r8", 3, MintOpBranch) -OPDEF(MINT_BLE_UN_I4, "ble.un.i4", 3, MintOpBranch) -OPDEF(MINT_BLE_UN_I8, "ble.un.i8", 3, MintOpBranch) -OPDEF(MINT_BLE_UN_R8, "ble.un.r8", 3, MintOpBranch) -OPDEF(MINT_BLT_UN_I4, "blt.un.i4", 3, MintOpBranch) -OPDEF(MINT_BLT_UN_I8, "blt.un.i8", 3, MintOpBranch) -OPDEF(MINT_BLT_UN_R8, "blt.un.r8", 3, MintOpBranch) - -OPDEF(MINT_BEQ_I4_S, "beq.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BEQ_I8_S, "beq.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BEQ_R8_S, "beq.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGE_I4_S, "bge.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BGE_I8_S, "bge.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGE_R8_S, "bge.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGT_I4_S, "bgt.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BGT_I8_S, "bgt.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGT_R8_S, "bgt.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLT_I4_S, "blt.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BLT_I8_S, "blt.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLT_R8_S, "blt.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLE_I4_S, "ble.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BLE_I8_S, "ble.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLE_R8_S, "ble.r8.s", 2, MintOpShortBranch) - -OPDEF(MINT_BNE_UN_I4_S, "bne.un.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BNE_UN_I8_S, "bne.un.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BNE_UN_R8_S, "bne.un.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGE_UN_I4_S, "bge.un.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BGE_UN_I8_S, "bge.un.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGE_UN_R8_S, "bge.un.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGT_UN_I4_S, "bgt.un.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BGT_UN_I8_S, "bgt.un.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGT_UN_R8_S, "bgt.un.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLE_UN_I4_S, "ble.un.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BLE_UN_I8_S, "ble.un.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLE_UN_R8_S, "ble.un.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLT_UN_I4_S, "blt.un.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BLT_UN_I8_S, "blt.un.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLT_UN_R8_S, "blt.un.r8.s", 2, MintOpShortBranch) - -OPDEF(MINT_SWITCH, "switch", 0, MintOpSwitch) - -OPDEF(MINT_LDSTR, "ldstr", 2, MintOpMethodToken) /* not really */ - -OPDEF(MINT_CALL, "call", 2, MintOpMethodToken) -OPDEF(MINT_VCALL, "vcall", 2, MintOpMethodToken) -OPDEF(MINT_CALLVIRT, "callvirt", 2, MintOpMethodToken) -OPDEF(MINT_VCALLVIRT, "vcallvirt", 2, MintOpMethodToken) -OPDEF(MINT_CALLI, "calli", 2, MintOpMethodToken) -OPDEF(MINT_CALLI_NAT, "calli.nat", 2, MintOpMethodToken) -OPDEF(MINT_JMP, "jmp", 2, MintOpMethodToken) - -OPDEF(MINT_CALLINT, "callint", 1, MintOpNoArgs) -OPDEF(MINT_CALLRUN, "callrun", 1, MintOpNoArgs) - -OPDEF(MINT_NEWOBJ, "newobj", 2, MintOpMethodToken) -OPDEF(MINT_INITOBJ, "initobj", 3, MintOpInt) -OPDEF(MINT_CASTCLASS, "castclass", 2, MintOpClassToken) -OPDEF(MINT_ISINST, "isinst", 2, MintOpClassToken) -OPDEF(MINT_NEWARR, "newarr", 2, MintOpClassToken) -OPDEF(MINT_BOX, "box", 2, MintOpClassToken) -OPDEF(MINT_UNBOX, "unbox", 2, MintOpClassToken) -OPDEF(MINT_LDTOKEN, "ldtoken", 2, MintOpClassToken) /* not really */ -OPDEF(MINT_LDFTN, "ldftn", 2, MintOpMethodToken) -OPDEF(MINT_LDVIRTFTN, "ldvirtftn", 2, MintOpMethodToken) -OPDEF(MINT_LDOBJ, "ldobj", 2, MintOpClassToken) -OPDEF(MINT_STOBJ, "stobj", 2, MintOpClassToken) -OPDEF(MINT_STOBJ_VT, "stobj.vt", 2, MintOpClassToken) -OPDEF(MINT_CPBLK, "cpblk", 1, MintOpNoArgs) -OPDEF(MINT_INITBLK, "initblk", 1, MintOpNoArgs) -OPDEF(MINT_LOCALLOC, "localloc", 1, MintOpNoArgs) -OPDEF(MINT_INITLOCALS, "initlocals", 1, MintOpNoArgs) - -OPDEF(MINT_LDELEM_I, "ldelem.i", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_I1, "ldelem.i1", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_U1, "ldelem.u1", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_I2, "ldelem.i2", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_U2, "ldelem.u2", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_I4, "ldelem.i4", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_U4, "ldelem.u4", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_I8, "ldelem.i8", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_R4, "ldelem.r4", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_R8, "ldelem.r8", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_REF, "ldelem.ref", 1, MintOpNoArgs) - -OPDEF(MINT_LDELEMA, "ldelema", 2, MintOpClassToken) - -OPDEF(MINT_STELEM_I, "stelem.i", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_I1, "stelem.i1", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_I2, "stelem.i2", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_I4, "stelem.i4", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_I8, "stelem.i8", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_R4, "stelem.r4", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_R8, "stelem.r8", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_REF, "stelem.ref", 1, MintOpNoArgs) - -OPDEF(MINT_LDLEN, "ldlen", 1, MintOpNoArgs) - -OPDEF(MINT_ADD_I4, "add.i4", 1, MintOpNoArgs) -OPDEF(MINT_ADD_I8, "add.i8", 1, MintOpNoArgs) -OPDEF(MINT_ADD_R8, "add.r8", 1, MintOpNoArgs) - -OPDEF(MINT_ADD1_I4, "add1.i4", 1, MintOpNoArgs) - -OPDEF(MINT_SUB_I4, "sub.i4", 1, MintOpNoArgs) -OPDEF(MINT_SUB_I8, "sub.i8", 1, MintOpNoArgs) -OPDEF(MINT_SUB_R8, "sub.r8", 1, MintOpNoArgs) - -OPDEF(MINT_SUB1_I4, "sub1.i4", 1, MintOpNoArgs) - -OPDEF(MINT_MUL_I4, "mul.i4", 1, MintOpNoArgs) -OPDEF(MINT_MUL_I8, "mul.i8", 1, MintOpNoArgs) -OPDEF(MINT_MUL_R8, "mul.r8", 1, MintOpNoArgs) - -OPDEF(MINT_DIV_I4, "div.i4", 1, MintOpNoArgs) -OPDEF(MINT_DIV_I8, "div.i8", 1, MintOpNoArgs) -OPDEF(MINT_DIV_R8, "div.r8", 1, MintOpNoArgs) - -OPDEF(MINT_DIV_UN_I4, "div.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_DIV_UN_I8, "div.un.i8", 1, MintOpNoArgs) - -OPDEF(MINT_ADD_OVF_I4, "add.ovf.i4", 1, MintOpNoArgs) -OPDEF(MINT_ADD_OVF_I8, "add.ovf.i8", 1, MintOpNoArgs) - -OPDEF(MINT_ADD_OVF_UN_I4, "add.ovf.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_ADD_OVF_UN_I8, "add.ovf.un.i8", 1, MintOpNoArgs) - -OPDEF(MINT_MUL_OVF_I4, "mul.ovf.i4", 1, MintOpNoArgs) -OPDEF(MINT_MUL_OVF_I8, "mul.ovf.i8", 1, MintOpNoArgs) - -OPDEF(MINT_MUL_OVF_UN_I4, "mul.ovf.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_MUL_OVF_UN_I8, "mul.ovf.un.i8", 1, MintOpNoArgs) - -OPDEF(MINT_SUB_OVF_I4, "sub.ovf.i4", 1, MintOpNoArgs) -OPDEF(MINT_SUB_OVF_I8, "sub.ovf.i8", 1, MintOpNoArgs) - -OPDEF(MINT_SUB_OVF_UN_I4, "sub.ovf.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_SUB_OVF_UN_I8, "sub.ovf.un.i8", 1, MintOpNoArgs) - -OPDEF(MINT_NEG_I4, "neg.i4", 1, MintOpNoArgs) -OPDEF(MINT_NEG_I8, "neg.i8", 1, MintOpNoArgs) -OPDEF(MINT_NEG_R8, "neg.r8", 1, MintOpNoArgs) - -OPDEF(MINT_NOT_I4, "not.i4", 1, MintOpNoArgs) -OPDEF(MINT_NOT_I8, "not.i8", 1, MintOpNoArgs) - -OPDEF(MINT_AND_I4, "and.i4", 1, MintOpNoArgs) -OPDEF(MINT_AND_I8, "and.i8", 1, MintOpNoArgs) - -OPDEF(MINT_OR_I4, "or.i4", 1, MintOpNoArgs) -OPDEF(MINT_OR_I8, "or.i8", 1, MintOpNoArgs) - -OPDEF(MINT_XOR_I4, "xor.i4", 1, MintOpNoArgs) -OPDEF(MINT_XOR_I8, "xor.i8", 1, MintOpNoArgs) - -OPDEF(MINT_REM_I4, "rem.i4", 1, MintOpNoArgs) -OPDEF(MINT_REM_I8, "rem.i8", 1, MintOpNoArgs) -OPDEF(MINT_REM_R8, "rem.r8", 1, MintOpNoArgs) - -OPDEF(MINT_REM_UN_I4, "rem.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_REM_UN_I8, "rem.un.i8", 1, MintOpNoArgs) - -OPDEF(MINT_SHR_UN_I4, "shr.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_SHR_UN_I8, "shr.un.i8", 1, MintOpNoArgs) -OPDEF(MINT_SHL_I4, "shl.i4", 1, MintOpNoArgs) -OPDEF(MINT_SHL_I8, "shl.i8", 1, MintOpNoArgs) -OPDEF(MINT_SHR_I4, "shr.i4", 1, MintOpNoArgs) -OPDEF(MINT_SHR_I8, "shr.i8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_R_UN_I4, "conv.r.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_R_UN_I8, "conv.r.un.i8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_I1_I4, "conv.i1.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I1_I8, "conv.i1.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I1_R8, "conv.i1.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_U1_I4, "conv.u1.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_U1_I8, "conv.u1.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_U1_R8, "conv.u1.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_I2_I4, "conv.i2.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I2_I8, "conv.i2.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I2_R8, "conv.i2.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_U2_I4, "conv.u2.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_U2_I8, "conv.u2.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_U2_R8, "conv.u2.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_I4_I8, "conv.i4.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I4_R8, "conv.i4.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_U4_I8, "conv.u4.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_U4_R8, "conv.u4.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_I8_I4, "conv.i8.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I8_U4, "conv.i8.u4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I8_R8, "conv.i8.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_R4_I4, "conv.r4.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_R4_I8, "conv.r4.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_R4_R8, "conv.r4.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_R8_I4, "conv.r8.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_R8_I8, "conv.r8.i8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_I4_I8_SP, "conv.i4.i8.sp", 1, MintOpNoArgs) /* special for narrowing sp[-2] on 64 bits */ -OPDEF(MINT_CONV_I8_I4_SP, "conv.i8.i4.sp", 1, MintOpNoArgs) /* special for widening sp[-2] on 64 bits */ - -OPDEF(MINT_CONV_U8_I4, "conv.u8.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_U8_R8, "conv.u8.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_I1_I4, "conv.ovf.i1.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I1_I8, "conv.ovf.i1.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I1_R8, "conv.ovf.i1.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_U1_I4, "conv.ovf.u1.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U1_I8, "conv.ovf.u1.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U1_R8, "conv.ovf.u1.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_I2_I4, "conv.ovf.i2.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I2_I8, "conv.ovf.i2.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I2_R8, "conv.ovf.i2.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_U2_I4, "conv.ovf.u2.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U2_I8, "conv.ovf.u2.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U2_R8, "conv.ovf.u2.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_I4_U4, "conv.ovf.i4.u4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I4_I8, "conv.ovf.i4.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I4_R8, "conv.ovf.i4.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_I4_UN_I8, "conv.ovf.i4.un.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I4_UN_R8, "conv.ovf.i4.un.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_U4_I4, "conv.ovf.u4.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U4_I8, "conv.ovf.u4.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U4_R8, "conv.ovf.u4.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_I8_R8, "conv.ovf.i8.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_I8_UN_R8, "conv.ovf.i8.un.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_U8_I4, "conv.ovf.u8.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U8_R8, "conv.ovf.u8.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CEQ_I4, "ceq.i4", 1, MintOpNoArgs) -OPDEF(MINT_CEQ_I8, "ceq.i8", 1, MintOpNoArgs) -OPDEF(MINT_CEQ_R8, "ceq.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CEQ0_I4, "ceq0.i4", 1, MintOpNoArgs) - -OPDEF(MINT_CGT_I4, "cgt.i4", 1, MintOpNoArgs) -OPDEF(MINT_CGT_I8, "cgt.i8", 1, MintOpNoArgs) -OPDEF(MINT_CGT_R8, "cgt.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CGT_UN_I4, "cgt.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_CGT_UN_I8, "cgt.un.i8", 1, MintOpNoArgs) -OPDEF(MINT_CGT_UN_R8, "cgt.un.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CLT_I4, "clt.i4", 1, MintOpNoArgs) -OPDEF(MINT_CLT_I8, "clt.i8", 1, MintOpNoArgs) -OPDEF(MINT_CLT_R8, "clt.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CLT_UN_I4, "clt.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_CLT_UN_I8, "clt.un.i8", 1, MintOpNoArgs) -OPDEF(MINT_CLT_UN_R8, "clt.un.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CKFINITE, "ckfinite", 1, MintOpNoArgs) - -OPDEF(MINT_CKNULL, "cknull", 1, MintOpNoArgs) - -OPDEF(MINT_GETCHR, "getchr", 1, MintOpNoArgs) -OPDEF(MINT_STRLEN, "strlen", 1, MintOpNoArgs) -OPDEF(MINT_ARRAY_RANK, "array_rank", 1, MintOpNoArgs) - -OPDEF(MINT_ICALL_V_V, "mono_icall_v_v", 2, MintOpClassToken) /* not really */ -OPDEF(MINT_ICALL_P_V, "mono_icall_p_v", 2, MintOpClassToken) -OPDEF(MINT_ICALL_P_P, "mono_icall_p_p", 2, MintOpClassToken) -OPDEF(MINT_ICALL_PP_V, "mono_icall_pp_v", 2, MintOpClassToken) -OPDEF(MINT_ICALL_PI_V, "mono_icall_pi_v", 2, MintOpClassToken) -OPDEF(MINT_ICALL_PP_P, "mono_icall_pp_p", 2, MintOpClassToken) -OPDEF(MINT_ICALL_PI_P, "mono_icall_pi_p", 2, MintOpClassToken) -OPDEF(MINT_ICALL_PPP_V, "mono_icall_ppp_v", 2, MintOpClassToken) -OPDEF(MINT_ICALL_PPI_V, "mono_icall_ppi_v", 2, MintOpClassToken) -OPDEF(MINT_MONO_LDPTR, "mono_ldptr", 2, MintOpClassToken) -OPDEF(MINT_MONO_NEWOBJ, "mono_newobj", 2, MintOpClassToken) -OPDEF(MINT_MONO_RETOBJ, "mono_retobj", 1, MintOpNoArgs) -OPDEF(MINT_MONO_FREE, "mono_free", 1, MintOpNoArgs) - - diff --git a/mono/interpreter/mintops.h b/mono/interpreter/mintops.h deleted file mode 100644 index e787526e2fe..00000000000 --- a/mono/interpreter/mintops.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __INTERPRETER_MINTOPS_H -#define __INTERPRETER_MINTOPS_H - -#include - -typedef enum -{ - MintOpNoArgs, - MintOpShortInt, - MintOpUShortInt, - MintOpInt, - MintOpLongInt, - MintOpFloat, - MintOpDouble, - MintOpBranch, - MintOpShortBranch, - MintOpSwitch, - MintOpMethodToken, - MintOpFieldToken, - MintOpClassToken, - MintOpTwoShorts, - MintOpShortAndInt -} MintOpArgType; - -#define OPDEF(a,b,c,d) \ - a, -enum { -#include "mintops.def" - MINT_LASTOP -}; -#undef OPDEF - -#if NO_UNALIGNED_ACCESS -# if G_BYTE_ORDER == G_LITTLE_ENDIAN -#define READ32(x) (((guint16 *)(x)) [0] | ((guint16 *)(x)) [1] << 16) -#define READ64(x) ((guint64)((guint16 *)(x)) [0] | \ - (guint64)((guint16 *)(x)) [1] << 16 | \ - (guint64)((guint16 *)(x)) [2] << 32 | \ - (guint64)((guint16 *)(x)) [3] << 48) -# else -#define READ32(x) (((guint16 *)(x)) [0] << 16 | ((guint16 *)(x)) [1]) -#define READ64(x) ((guint64)((guint16 *)(x)) [0] << 48 | \ - (guint64)((guint16 *)(x)) [1] << 32 | \ - (guint64)((guint16 *)(x)) [2] << 16 | \ - (guint64)((guint16 *)(x)) [3]) -# endif -#else /* unaligned access OK */ -#define READ32(x) (*(guint32 *)(x)) -#define READ64(x) (*(guint64 *)(x)) -#endif - -extern const char *mono_interp_opname[]; -extern unsigned char mono_interp_oplen[]; -extern MintOpArgType mono_interp_opargtype[]; -extern const guint16 *mono_interp_dis_mintop(const unsigned short *base, const guint16 *ip); - -#endif - diff --git a/mono/interpreter/transform.c b/mono/interpreter/transform.c deleted file mode 100644 index 2bd3f258183..00000000000 --- a/mono/interpreter/transform.c +++ /dev/null @@ -1,3049 +0,0 @@ -/* - * transform CIL into different opcodes for more - * efficient interpretation - * - * Written by Bernie Solomon (bernard@ugsolutions.com) - * Copyright (c) 2004. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define OPDEF(a,b,c,d,e,f,g,h,i,j) \ - a = i, - -enum { -#include "mono/cil/opcode.def" - CEE_LASTOP -}; -#undef OPDEF - -#include "mintops.h" -#include "interp.h" - -#define DEBUG 0 - -typedef struct -{ - MonoClass *klass; - unsigned char type; - unsigned char flags; -} StackInfo; - -typedef struct -{ - MonoMethod *method; - MonoMethodHeader *header; - RuntimeMethod *rtm; - const unsigned char *il_code; - const unsigned char *ip; - const unsigned char *last_ip; - const unsigned char *in_start; - int code_size; - int *in_offsets; - int *forward_refs; - StackInfo **stack_state; - int *stack_height; - int *vt_stack_size; - unsigned char *is_bb_start; - unsigned short *new_code; - unsigned short *new_code_end; - unsigned short *new_ip; - unsigned short *last_new_ip; - unsigned int max_code_size; - StackInfo *stack; - StackInfo *sp; - unsigned int max_stack_height; - unsigned int vt_sp; - unsigned int max_vt_sp; - int n_data_items; - int max_data_items; - void **data_items; - GHashTable *data_hash; -} TransformData; - -#define MINT_TYPE_I1 0 -#define MINT_TYPE_U1 1 -#define MINT_TYPE_I2 2 -#define MINT_TYPE_U2 3 -#define MINT_TYPE_I4 4 -#define MINT_TYPE_I8 5 -#define MINT_TYPE_R4 6 -#define MINT_TYPE_R8 7 -#define MINT_TYPE_O 8 -#define MINT_TYPE_P 9 -#define MINT_TYPE_VT 10 - -#define STACK_TYPE_I4 0 -#define STACK_TYPE_I8 1 -#define STACK_TYPE_R8 2 -#define STACK_TYPE_O 3 -#define STACK_TYPE_VT 4 -#define STACK_TYPE_MP 5 -#define STACK_TYPE_F 6 - -static const char *stack_type_string [] = { "I4", "I8", "R8", "O ", "VT", "MP", "F " }; - -#if SIZEOF_VOID_P == 8 -#define STACK_TYPE_I STACK_TYPE_I8 -#else -#define STACK_TYPE_I STACK_TYPE_I4 -#endif - -static int stack_type [] = { - STACK_TYPE_I4, /*I1*/ - STACK_TYPE_I4, /*U1*/ - STACK_TYPE_I4, /*I2*/ - STACK_TYPE_I4, /*U2*/ - STACK_TYPE_I4, /*I4*/ - STACK_TYPE_I8, /*I8*/ - STACK_TYPE_R8, /*R4*/ - STACK_TYPE_R8, /*R8*/ - STACK_TYPE_O, /*O*/ - STACK_TYPE_MP, /*P*/ - STACK_TYPE_VT -}; - -static void -grow_code (TransformData *td) -{ - unsigned int old_ip_offset = td->new_ip - td->new_code; - unsigned int old_last_ip_offset = td->last_new_ip - td->new_code; - g_assert (old_ip_offset <= td->max_code_size); - td->new_code = g_realloc (td->new_code, (td->max_code_size *= 2) * sizeof (td->new_code [0])); - td->new_code_end = td->new_code + td->max_code_size; - td->new_ip = td->new_code + old_ip_offset; - td->last_new_ip = td->new_code + old_last_ip_offset; -} - -#define ENSURE_CODE(td, n) \ - do { \ - if ((td)->new_ip + (n) > (td)->new_code_end) \ - grow_code (td); \ - } while (0) - -#define ADD_CODE(td, n) \ - do { \ - if ((td)->new_ip == (td)->new_code_end) \ - grow_code (td); \ - *(td)->new_ip++ = (n); \ - } while (0) - -#define CHECK_STACK(td, n) \ - do { \ - int stack_size = (td)->sp - (td)->stack; \ - if (stack_size < (n)) \ - g_warning ("%s.%s: not enough values (%d < %d) on stack at %04x", \ - (td)->method->klass->name, (td)->method->name, \ - stack_size, n, (td)->ip - (td)->il_code); \ - } while (0) - -#define ENSURE_I4(td, sp_off) \ - do { \ - if ((td)->sp [-sp_off].type == STACK_TYPE_I8) \ - ADD_CODE(td, sp_off == 1 ? MINT_CONV_I4_I8 : MINT_CONV_I4_I8_SP); \ - } while (0) - -static void -handle_branch(TransformData *td, int short_op, int long_op, int offset) -{ - int shorten_branch = 0; - int target = td->ip + offset - td->il_code; - if (target < 0 || target >= td->code_size) - g_assert_not_reached (); - if (offset > 0 && td->stack_height [target] < 0) { - td->stack_height [target] = td->sp - td->stack; - if (td->stack_height [target] > 0) - td->stack_state [target] = g_memdup (td->stack, td->stack_height [target] * sizeof (td->stack [0])); - td->vt_stack_size [target] = td->vt_sp; - } - if (offset < 0) { - offset = td->in_offsets [target] - (td->new_ip - td->new_code); - if (offset >= -32768) { - shorten_branch = 1; - } - } else { - int prev = td->forward_refs [target]; - td->forward_refs [td->ip - td->il_code] = prev; - td->forward_refs [target] = td->ip - td->il_code; - offset = 0; - if (td->header->code_size <= 25000) /* FIX to be precise somehow? */ - shorten_branch = 1; - } - if (shorten_branch) { - ADD_CODE(td, short_op); - ADD_CODE(td, offset); - } else { - ADD_CODE(td, long_op); - ADD_CODE(td, * (unsigned short *)(&offset)); - ADD_CODE(td, * ((unsigned short *)&offset + 1)); - } -} - -static void -one_arg_branch(TransformData *td, int mint_op, int offset) -{ - int type = td->sp [-1].type == STACK_TYPE_O || td->sp [-1].type == STACK_TYPE_MP ? STACK_TYPE_I : td->sp [-1].type; - int long_op = mint_op + type - STACK_TYPE_I4; - int short_op = long_op + MINT_BRFALSE_I4_S - MINT_BRFALSE_I4; - CHECK_STACK(td, 1); - --td->sp; - handle_branch (td, short_op, long_op, offset); -} - -static void -two_arg_branch(TransformData *td, int mint_op, int offset) -{ - int type1 = td->sp [-1].type == STACK_TYPE_O || td->sp [-1].type == STACK_TYPE_MP ? STACK_TYPE_I : td->sp [-1].type; - int type2 = td->sp [-2].type == STACK_TYPE_O || td->sp [-2].type == STACK_TYPE_MP ? STACK_TYPE_I : td->sp [-2].type; - int long_op = mint_op + type1 - STACK_TYPE_I4; - int short_op = long_op + MINT_BEQ_I4_S - MINT_BEQ_I4; - CHECK_STACK(td, 2); - if (type1 == STACK_TYPE_I4 && type2 == STACK_TYPE_I8) { - ADD_CODE(td, MINT_CONV_I8_I4); - td->in_offsets [td->ip - td->il_code]++; - } else if (type1 == STACK_TYPE_I8 && type2 == STACK_TYPE_I4) { - ADD_CODE(td, MINT_CONV_I8_I4_SP); - td->in_offsets [td->ip - td->il_code]++; - } else if (type1 != type2) { - g_warning("%s.%s: branch type mismatch %d %d", - td->method->klass->name, td->method->name, - td->sp [-1].type, td->sp [-2].type); - } - td->sp -= 2; - handle_branch (td, short_op, long_op, offset); -} - -static void -unary_arith_op(TransformData *td, int mint_op) -{ - int op = mint_op + td->sp [-1].type - STACK_TYPE_I4; - CHECK_STACK(td, 1); - ADD_CODE(td, op); -} - -static void -binary_arith_op(TransformData *td, int mint_op) -{ - int type1 = td->sp [-2].type; - int type2 = td->sp [-1].type; - int op; -#if SIZEOF_VOID_P == 8 - if ((type1 == STACK_TYPE_MP || type1 == STACK_TYPE_I8) && type2 == STACK_TYPE_I4) { - ADD_CODE(td, MINT_CONV_I8_I4); - type2 = STACK_TYPE_I8; - } - if (type1 == STACK_TYPE_I4 && (type2 == STACK_TYPE_MP || type2 == STACK_TYPE_I8)) { - ADD_CODE(td, MINT_CONV_I8_I4_SP); - type1 = STACK_TYPE_I8; - td->sp [-2].type = STACK_TYPE_I8; - } -#endif - if (type1 == STACK_TYPE_MP) - type1 = STACK_TYPE_I; - if (type2 == STACK_TYPE_MP) - type2 = STACK_TYPE_I; - if (type1 != type2) { - g_warning("%s.%s: %04x arith type mismatch %s %d %d", - td->method->klass->name, td->method->name, - td->ip - td->il_code, mono_interp_opname[mint_op], type1, type2); - } - op = mint_op + type1 - STACK_TYPE_I4; - CHECK_STACK(td, 2); - ADD_CODE(td, op); - --td->sp; -} - -static void -binary_int_op(TransformData *td, int mint_op) -{ - int op = mint_op + td->sp [-1].type - STACK_TYPE_I4; - CHECK_STACK(td, 2); - if (td->sp [-1].type != td->sp [-2].type) - g_warning("%s.%s: int type mismatch", td->method->klass->name, td->method->name); - ADD_CODE(td, op); - --td->sp; -} - -static void -shift_op(TransformData *td, int mint_op) -{ - int op = mint_op + td->sp [-2].type - STACK_TYPE_I4; - CHECK_STACK(td, 2); - if (td->sp [-1].type != STACK_TYPE_I4) { - g_warning("%s.%s: shift type mismatch %d", - td->method->klass->name, td->method->name, - td->sp [-2].type); - } - ADD_CODE(td, op); - --td->sp; -} - -static int -mint_type(MonoType *type) -{ - if (type->byref) - return MINT_TYPE_P; -enum_type: - switch (type->type) { - case MONO_TYPE_I1: - return MINT_TYPE_I1; - case MONO_TYPE_U1: - case MONO_TYPE_BOOLEAN: - return MINT_TYPE_U1; - case MONO_TYPE_I2: - return MINT_TYPE_I2; - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - return MINT_TYPE_U2; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - return MINT_TYPE_I4; - case MONO_TYPE_I: - case MONO_TYPE_U: -#if SIZEOF_VOID_P == 4 - return MINT_TYPE_I4; -#else - return MINT_TYPE_I8; -#endif - case MONO_TYPE_PTR: - return MINT_TYPE_P; - case MONO_TYPE_R4: - return MINT_TYPE_R4; - case MONO_TYPE_I8: - case MONO_TYPE_U8: - return MINT_TYPE_I8; - case MONO_TYPE_R8: - return MINT_TYPE_R8; - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_ARRAY: - return MINT_TYPE_O; - case MONO_TYPE_VALUETYPE: - if (type->data.klass->enumtype) { - type = type->data.klass->enum_basetype; - goto enum_type; - } else - return MINT_TYPE_VT; - default: - g_warning ("got type 0x%02x", type->type); - g_assert_not_reached (); - } - return -1; -} - -static int -can_store (int stack_type, int var_type) -{ - if (stack_type == STACK_TYPE_O || stack_type == STACK_TYPE_MP) - stack_type = STACK_TYPE_I; - if (var_type == STACK_TYPE_O || var_type == STACK_TYPE_MP) - var_type = STACK_TYPE_I; - return stack_type == var_type; -} - -#define SET_SIMPLE_TYPE(s, ty) \ - do { \ - (s)->type = (ty); \ - (s)->flags = 0; \ - (s)->klass = NULL; \ - } while (0) - -#define SET_TYPE(s, ty, k) \ - do { \ - (s)->type = (ty); \ - (s)->flags = 0; \ - (s)->klass = k; \ - } while (0) - -#define PUSH_SIMPLE_TYPE(td, ty) \ - do { \ - int sp_height; \ - (td)->sp++; \ - sp_height = (td)->sp - (td)->stack; \ - if (sp_height > (td)->max_stack_height) \ - (td)->max_stack_height = sp_height; \ - SET_SIMPLE_TYPE((td)->sp - 1, ty); \ - } while (0) - -#define PUSH_TYPE(td, ty, k) \ - do { \ - int sp_height; \ - (td)->sp++; \ - sp_height = (td)->sp - (td)->stack; \ - if (sp_height > (td)->max_stack_height) \ - (td)->max_stack_height = sp_height; \ - SET_TYPE((td)->sp - 1, ty, k); \ - } while (0) - -#define PUSH_VT(td, size) \ - do { \ - (td)->vt_sp += ((size) + 7) & ~7; \ - if ((td)->vt_sp > (td)->max_vt_sp) \ - (td)->max_vt_sp = (td)->vt_sp; \ - } while (0) - -#define POP_VT(td, size) \ - do { \ - (td)->vt_sp -= ((size) + 7) & ~7; \ - } while (0) - -#if NO_UNALIGNED_ACCESS -#define WRITE32(td, v) \ - do { \ - ENSURE_CODE(td, 2); \ - * (guint16 *)((td)->new_ip) = * (guint16 *)(v); \ - * ((guint16 *)((td)->new_ip) + 1) = * ((guint16 *)(v) + 1); \ - (td)->new_ip += 2; \ - } while (0) - -#define WRITE64(td, v) \ - do { \ - ENSURE_CODE(td, 4); \ - * (guint16 *)((td)->new_ip) = * (guint16 *)(v); \ - * ((guint16 *)((td)->new_ip) + 1) = * ((guint16 *)(v) + 1); \ - * ((guint16 *)((td)->new_ip) + 2) = * ((guint16 *)(v) + 2); \ - * ((guint16 *)((td)->new_ip) + 3) = * ((guint16 *)(v) + 3); \ - (td)->new_ip += 4; \ - } while (0) -#else -#define WRITE32(td, v) \ - do { \ - ENSURE_CODE(td, 2); \ - * (guint32 *)((td)->new_ip) = * (guint32 *)(v); \ - (td)->new_ip += 2; \ - } while (0) - -#define WRITE64(td, v) \ - do { \ - ENSURE_CODE(td, 4); \ - * (guint64 *)((td)->new_ip) = * (guint64 *)(v); \ - (td)->new_ip += 4; \ - } while (0) - -#endif - -static void -load_arg(TransformData *td, int n) -{ - int mt; - MonoClass *klass = NULL; - if (n == 0 && mono_method_signature (td->method)->hasthis) { - if (td->method->klass->valuetype) - mt = MINT_TYPE_P; - else { - mt = MINT_TYPE_O; - klass = td->method->klass; - } - ADD_CODE(td, MINT_LDTHIS); - } else { - MonoType *type; - n -= mono_method_signature (td->method)->hasthis; - type = mono_method_signature (td->method)->params [n]; - mt = mint_type (type); - if (mt == MINT_TYPE_VT) { - gint32 size; - if (mono_method_signature (td->method)->pinvoke) - size = mono_class_native_size (type->data.klass, NULL); - else - size = mono_class_value_size (type->data.klass, NULL); - PUSH_VT(td, size); - ADD_CODE(td, MINT_LDARG_VT); - ADD_CODE(td, td->rtm->arg_offsets [n]); /* FIX for large offset */ - WRITE32(td, &size); - klass = type->data.klass; - } else { - ADD_CODE(td, MINT_LDARG_I1 + (mt - MINT_TYPE_I1)); - ADD_CODE(td, td->rtm->arg_offsets [n]); /* FIX for large offset */ - if (mt == MINT_TYPE_O) - klass = mono_class_from_mono_type (type); - } - } - PUSH_TYPE(td, stack_type[mt], klass); -} - -static void -store_arg(TransformData *td, int n) -{ - int mt; - CHECK_STACK (td, 1); - if (n == 0 && mono_method_signature (td->method)->hasthis) - ADD_CODE(td, MINT_STTHIS); - else { - MonoType *type; - n -= mono_method_signature (td->method)->hasthis; - type = mono_method_signature (td->method)->params [n]; - mt = mint_type (type); - if (mt == MINT_TYPE_VT) { - gint32 size; - if (mono_method_signature (td->method)->pinvoke) - size = mono_class_native_size (type->data.klass, NULL); - else - size = mono_class_value_size (type->data.klass, NULL); - ADD_CODE(td, MINT_STARG_VT); - ADD_CODE(td, n); - WRITE32(td, &size); - if (td->sp [-1].type == STACK_TYPE_VT) - POP_VT(td, size); - } else { - ADD_CODE(td, MINT_STARG_I1 + (mt - MINT_TYPE_I1)); - ADD_CODE(td, td->rtm->arg_offsets [n]); - } - } - --td->sp; -} - -static void -store_inarg(TransformData *td, int n) -{ - MonoType *type = mono_method_signature (td->method)->params [n]; - int mt = mint_type (type); - if (mt == MINT_TYPE_VT) { - gint32 size; - if (mono_method_signature (td->method)->pinvoke) - size = mono_class_native_size (type->data.klass, NULL); - else - size = mono_class_value_size (type->data.klass, NULL); - ADD_CODE(td, MINT_STINARG_VT); - ADD_CODE(td, n); - WRITE32(td, &size); - } else { - ADD_CODE(td, MINT_STINARG_I1 + (mt - MINT_TYPE_I1)); - ADD_CODE(td, n); - } -} - -static void -load_local(TransformData *td, int n) -{ - MonoType *type = td->header->locals [n]; - int mt = mint_type (type); - int offset = td->rtm->local_offsets [n]; - MonoClass *klass = NULL; - if (mt == MINT_TYPE_VT) { - gint32 size = mono_class_value_size (type->data.klass, NULL); - PUSH_VT(td, size); - ADD_CODE(td, MINT_LDLOC_VT); - ADD_CODE(td, offset); /*FIX for large offset */ - WRITE32(td, &size); - klass = type->data.klass; - } else { - if (mt == MINT_TYPE_I4 && !td->is_bb_start [td->in_start - td->il_code] && td->last_new_ip != NULL && - td->last_new_ip [0] == MINT_STLOC_I4 && td->last_new_ip [1] == offset) { - td->last_new_ip [0] = MINT_STLOC_NP_I4; - } else if (mt == MINT_TYPE_O && !td->is_bb_start [td->in_start - td->il_code] && td->last_new_ip != NULL && - td->last_new_ip [0] == MINT_STLOC_O && td->last_new_ip [1] == offset) { - td->last_new_ip [0] = MINT_STLOC_NP_O; - } else { - ADD_CODE(td, MINT_LDLOC_I1 + (mt - MINT_TYPE_I1)); - ADD_CODE(td, offset); /*FIX for large offset */ - } - if (mt == MINT_TYPE_O) - klass = mono_class_from_mono_type (type); - } - PUSH_TYPE(td, stack_type[mt], klass); -} - -static void -store_local(TransformData *td, int n) -{ - MonoType *type = td->header->locals [n]; - int mt = mint_type (type); - int offset = td->rtm->local_offsets [n]; - CHECK_STACK (td, 1); -#if SIZEOF_VOID_P == 8 - if (td->sp [-1].type == STACK_TYPE_I4 && stack_type [mt] == STACK_TYPE_I8) { - ADD_CODE(td, MINT_CONV_I8_I4); - td->sp [-1].type = STACK_TYPE_I8; - } -#endif - if (!can_store(td->sp [-1].type, stack_type [mt])) { - g_warning("%s.%s: Store local stack type mismatch %d %d", - td->method->klass->name, td->method->name, - stack_type [mt], td->sp [-1].type); - } - if (mt == MINT_TYPE_VT) { - gint32 size = mono_class_value_size (type->data.klass, NULL); - ADD_CODE(td, MINT_STLOC_VT); - ADD_CODE(td, offset); /*FIX for large offset */ - WRITE32(td, &size); - if (td->sp [-1].type == STACK_TYPE_VT) - POP_VT(td, size); - } else { - ADD_CODE(td, MINT_STLOC_I1 + (mt - MINT_TYPE_I1)); - ADD_CODE(td, offset); /*FIX for large offset */ - } - --td->sp; -} - -#define SIMPLE_OP(td, op) \ - do { \ - ADD_CODE(&td, op); \ - ++td.ip; \ - } while (0) - -static guint16 -get_data_item_index (TransformData *td, void *ptr) -{ - gpointer p = g_hash_table_lookup (td->data_hash, ptr); - guint index; - if (p != NULL) - return GPOINTER_TO_UINT (p) - 1; - if (td->max_data_items == td->n_data_items) { - td->max_data_items = td->n_data_items == 0 ? 16 : 2 * td->max_data_items; - td->data_items = g_realloc (td->data_items, td->max_data_items * sizeof(td->data_items [0])); - } - index = td->n_data_items; - td->data_items [index] = ptr; - ++td->n_data_items; - g_hash_table_insert (td->data_hash, ptr, GUINT_TO_POINTER (index + 1)); - return index; -} - -static void -generate(MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start) -{ - MonoMethodHeader *header = mono_method_get_header (method); - MonoMethodSignature *signature = mono_method_signature (method); - MonoImage *image = method->klass->image; - MonoDomain *domain = mono_domain_get (); - MonoGenericContext *generic_context = NULL; - int offset, mt; - int i; - int i32; - MonoClass *klass; - MonoClassField *field; - const unsigned char *end; - int new_in_start_offset; - int body_start_offset; - int target; - guint32 token; - TransformData td; - int generating_code = 1; - - if (mono_method_signature (method)->is_inflated) - generic_context = ((MonoMethodInflated *) method)->context; - - memset(&td, 0, sizeof(td)); - td.method = method; - td.rtm = rtm; - td.is_bb_start = is_bb_start; - td.il_code = header->code; - td.code_size = header->code_size; - td.header = header; - td.max_code_size = td.code_size; - td.new_code = (unsigned short *)g_malloc(td.max_code_size * sizeof(gushort)); - td.new_code_end = td.new_code + td.max_code_size; - td.in_offsets = g_malloc0(header->code_size * sizeof(int)); - td.forward_refs = g_malloc(header->code_size * sizeof(int)); - td.stack_state = g_malloc0(header->code_size * sizeof(StackInfo *)); - td.stack_height = g_malloc(header->code_size * sizeof(int)); - td.vt_stack_size = g_malloc(header->code_size * sizeof(int)); - td.n_data_items = 0; - td.max_data_items = 0; - td.data_items = NULL; - td.data_hash = g_hash_table_new (NULL, NULL); - rtm->data_items = td.data_items; - for (i = 0; i < header->code_size; i++) { - td.forward_refs [i] = -1; - td.stack_height [i] = -1; - } - td.new_ip = td.new_code; - td.last_new_ip = NULL; - - td.stack = g_malloc0(header->max_stack * sizeof(td.stack[0])); - td.sp = td.stack; - td.max_stack_height = 0; - - for (i = 0; i < header->num_clauses; i++) { - MonoExceptionClause *c = header->clauses + i; - td.stack_height [c->handler_offset] = 0; - td.vt_stack_size [c->handler_offset] = 0; - td.is_bb_start [c->handler_offset] = 1; - if (c->flags == MONO_EXCEPTION_CLAUSE_NONE) { - td.stack_height [c->handler_offset] = 1; - td.stack_state [c->handler_offset] = g_malloc0(sizeof(StackInfo)); - td.stack_state [c->handler_offset][0].type = STACK_TYPE_O; - td.stack_state [c->handler_offset][0].klass = NULL; /*FIX*/ - } - } - - td.ip = header->code; - end = td.ip + header->code_size; - - if (mono_interp_traceopt) { - char *tmp = mono_disasm_code (NULL, method, td.ip, end); - char *name = mono_method_full_name (method, TRUE); - g_print ("Method %s, original code:\n", name); - g_print ("%s\n", tmp); - g_free (tmp); - g_free (name); - } - - for (i = 0; i < signature->param_count; i++) - store_inarg(&td, i); - - body_start_offset = td.new_ip - td.new_code; - - for (i = 0; i < header->num_locals; i++) { - int mt = mint_type(header->locals [i]); - if (mt == MINT_TYPE_VT || mt == MINT_TYPE_O) { - ADD_CODE(&td, MINT_INITLOCALS); - break; - } - } - - while (td.ip < end) { - int in_offset; - - g_assert (td.sp >= td.stack); - g_assert (td.vt_sp < 0x10000000); - in_offset = td.ip - header->code; - td.in_offsets [in_offset] = td.new_ip - td.new_code; - new_in_start_offset = td.new_ip - td.new_code; - td.in_start = td.ip; - while (td.forward_refs [in_offset] >= 0) { - int j = td.forward_refs [in_offset]; - int slot; - td.forward_refs [in_offset] = td.forward_refs [j]; - if (td.in_offsets [j] < 0) { - int old_switch_offset = -td.in_offsets [j]; - int new_switch_offset = td.in_offsets [old_switch_offset]; - int switch_case = (j - old_switch_offset - 5) / 4; - int n_cases = read32 (header->code + old_switch_offset + 1); - offset = (td.new_ip - td.new_code) - (new_switch_offset + 2 * n_cases + 3); - slot = new_switch_offset + 3 + 2 * switch_case; - td.new_code [slot] = * (unsigned short *)(&offset); - td.new_code [slot + 1] = * ((unsigned short *)&offset + 1); - } else { - int op = td.new_code [td.in_offsets [j]]; - if (mono_interp_opargtype [op] == MintOpShortBranch) { - offset = (td.new_ip - td.new_code) - td.in_offsets [j]; - g_assert (offset <= 32767); - slot = td.in_offsets [j] + 1; - td.new_code [slot] = offset; - } else { - offset = (td.new_ip - td.new_code) - td.in_offsets [j]; - slot = td.in_offsets [j] + 1; - td.new_code [slot] = * (unsigned short *)(&offset); - td.new_code [slot + 1] = * ((unsigned short *)&offset + 1); - } - } - } - if (td.stack_height [in_offset] >= 0) { - g_assert (is_bb_start [in_offset]); - if (td.stack_height [in_offset] > 0) - memcpy (td.stack, td.stack_state [in_offset], td.stack_height [in_offset] * sizeof(td.stack [0])); - td.sp = td.stack + td.stack_height [in_offset]; - td.vt_sp = td.vt_stack_size [in_offset]; - } - if (is_bb_start [in_offset]) { - generating_code = 1; - } - if (!generating_code) { - while (td.ip < end && !is_bb_start [td.ip - td.il_code]) - ++td.ip; - continue; - } - if (mono_interp_traceopt > 1) { - printf("IL_%04x %s %-10s -> IL_%04x, sp %d, %s %-12s vt_sp %u (max %u)\n", - td.ip - td.il_code, - td.is_bb_start [td.ip - td.il_code] == 3 ? "<>" : - td.is_bb_start [td.ip - td.il_code] == 2 ? "< " : - td.is_bb_start [td.ip - td.il_code] == 1 ? " >" : " ", - mono_opcode_name (*td.ip), td.new_ip - td.new_code, td.sp - td.stack, - td.sp > td.stack ? stack_type_string [td.sp [-1].type] : " ", - (td.sp > td.stack && (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_VT)) ? (td.sp [-1].klass == NULL ? "?" : td.sp [-1].klass->name) : "", - td.vt_sp, td.max_vt_sp); - } - switch (*td.ip) { - case CEE_NOP: - /* lose it */ - ++td.ip; - break; - case CEE_BREAK: - SIMPLE_OP(td, MINT_BREAK); - break; - case CEE_LDARG_0: - case CEE_LDARG_1: - case CEE_LDARG_2: - case CEE_LDARG_3: - load_arg (&td, *td.ip - CEE_LDARG_0); - ++td.ip; - break; - case CEE_LDLOC_0: - case CEE_LDLOC_1: - case CEE_LDLOC_2: - case CEE_LDLOC_3: - load_local (&td, *td.ip - CEE_LDLOC_0); - ++td.ip; - break; - case CEE_STLOC_0: - case CEE_STLOC_1: - case CEE_STLOC_2: - case CEE_STLOC_3: - store_local (&td, *td.ip - CEE_STLOC_0); - ++td.ip; - break; - case CEE_LDARG_S: - load_arg (&td, ((guint8 *)td.ip)[1]); - td.ip += 2; - break; - case CEE_LDARGA_S: { - int n = ((guint8 *)td.ip)[1]; - if (n == 0 && signature->hasthis) - ADD_CODE(&td, MINT_LDTHISA); - else { - ADD_CODE(&td, MINT_LDARGA); - ADD_CODE(&td, td.rtm->arg_offsets [n - signature->hasthis]); - } - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_MP); - td.ip += 2; - break; - } - case CEE_STARG_S: - store_arg (&td, ((guint8 *)td.ip)[1]); - td.ip += 2; - break; - case CEE_LDLOC_S: - load_local (&td, ((guint8 *)td.ip)[1]); - td.ip += 2; - break; - case CEE_LDLOCA_S: - ADD_CODE(&td, MINT_LDLOCA_S); - ADD_CODE(&td, td.rtm->local_offsets [((guint8 *)td.ip)[1]]); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_MP); - td.ip += 2; - break; - case CEE_STLOC_S: - store_local (&td, ((guint8 *)td.ip)[1]); - td.ip += 2; - break; - case CEE_LDNULL: - SIMPLE_OP(td, MINT_LDNULL); - PUSH_TYPE(&td, STACK_TYPE_O, NULL); - break; - case CEE_LDC_I4_M1: - SIMPLE_OP(td, MINT_LDC_I4_M1); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - break; - case CEE_LDC_I4_0: - if (!td.is_bb_start[td.ip + 1 - td.il_code] && td.ip [1] == 0xfe && td.ip [2] == CEE_CEQ && - td.sp > td.stack && td.sp [-1].type == STACK_TYPE_I4) { - SIMPLE_OP(td, MINT_CEQ0_I4); - td.ip += 2; - } else { - SIMPLE_OP(td, MINT_LDC_I4_0); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - } - break; - case CEE_LDC_I4_1: - if (!td.is_bb_start[td.ip + 1 - td.il_code] && - (td.ip [1] == CEE_ADD || td.ip [1] == CEE_SUB) && td.sp [-1].type == STACK_TYPE_I4) { - ADD_CODE(&td, td.ip [1] == CEE_ADD ? MINT_ADD1_I4 : MINT_SUB1_I4); - td.ip += 2; - } else { - SIMPLE_OP(td, MINT_LDC_I4_1); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - } - break; - case CEE_LDC_I4_2: - case CEE_LDC_I4_3: - case CEE_LDC_I4_4: - case CEE_LDC_I4_5: - case CEE_LDC_I4_6: - case CEE_LDC_I4_7: - case CEE_LDC_I4_8: - SIMPLE_OP(td, (*td.ip - CEE_LDC_I4_0) + MINT_LDC_I4_0); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - break; - case CEE_LDC_I4_S: - ADD_CODE(&td, MINT_LDC_I4_S); - ADD_CODE(&td, ((gint8 *) td.ip) [1]); - td.ip += 2; - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - break; - case CEE_LDC_I4: - i32 = read32 (td.ip + 1); - ADD_CODE(&td, MINT_LDC_I4); - WRITE32(&td, &i32); - td.ip += 5; - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - break; - case CEE_LDC_I8: { - gint64 val = read64 (td.ip + 1); - ADD_CODE(&td, MINT_LDC_I8); - WRITE64(&td, &val); - td.ip += 9; - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I8); - break; - } - case CEE_LDC_R4: { - float val; - readr4 (td.ip + 1, &val); - ADD_CODE(&td, MINT_LDC_R4); - WRITE32(&td, &val); - td.ip += 5; - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_R8); - break; - } - case CEE_LDC_R8: { - double val; - readr8 (td.ip + 1, &val); - ADD_CODE(&td, MINT_LDC_R8); - WRITE64(&td, &val); - td.ip += 9; - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_R8); - break; - } - case CEE_DUP: { - int type = td.sp [-1].type; - MonoClass *klass = td.sp [-1].klass; - if (td.sp [-1].type == STACK_TYPE_VT) { - gint32 size = mono_class_value_size (klass, NULL); - PUSH_VT(&td, size); - ADD_CODE(&td, MINT_DUP_VT); - WRITE32(&td, &size); - td.ip ++; - } else - SIMPLE_OP(td, MINT_DUP); - PUSH_TYPE(&td, type, klass); - break; - } - case CEE_POP: - CHECK_STACK(&td, 1); - SIMPLE_OP(td, MINT_POP); - if (td.sp [-1].type == STACK_TYPE_VT) { - int size = mono_class_value_size (td.sp [-1].klass, NULL); - size = (size + 7) & ~7; - ADD_CODE(&td, MINT_VTRESULT); - ADD_CODE(&td, 0); - WRITE32(&td, &size); - td.vt_sp -= size; - } - --td.sp; - break; - case CEE_JMP: { - MonoMethod *m; - if (td.sp > td.stack) - g_warning ("CEE_JMP: stack must be empty"); - token = read32 (td.ip + 1); - m = mono_get_method_full (image, token, NULL, generic_context); - ADD_CODE(&td, MINT_JMP); - ADD_CODE(&td, get_data_item_index (&td, mono_interp_get_runtime_method (m))); - td.ip += 5; - break; - } - case CEE_CALLVIRT: /* Fall through */ - case CEE_CALLI: /* Fall through */ - case CEE_CALL: { - MonoMethod *m; - MonoMethodSignature *csignature; - int virtual = *td.ip == CEE_CALLVIRT; - int calli = *td.ip == CEE_CALLI; - int i; - guint32 vt_stack_used = 0; - guint32 vt_res_size = 0; - int op = -1; - int native = 0; - int is_void = 0; - - token = read32 (td.ip + 1); - if (calli) { - CHECK_STACK(&td, 1); - native = (method->wrapper_type != MONO_WRAPPER_DELEGATE_INVOKE && td.sp [-1].type == STACK_TYPE_I); - --td.sp; - if (method->wrapper_type != MONO_WRAPPER_NONE) - csignature = (MonoMethodSignature *)mono_method_get_wrapper_data (method, token); - else - csignature = mono_metadata_parse_signature (image, token); - m = NULL; - } else { - if (method->wrapper_type == MONO_WRAPPER_NONE) - m = mono_get_method_full (image, token, NULL, generic_context); - else - m = (MonoMethod *)mono_method_get_wrapper_data (method, token); - csignature = mono_method_signature (m); - if (m->klass == mono_defaults.string_class) { - if (m->name [0] == 'g') { - if (strcmp (m->name, "get_Chars") == 0) - op = MINT_GETCHR; - else if (strcmp (m->name, "get_Length") == 0) - op = MINT_STRLEN; - } - } else if (m->klass == mono_defaults.array_class) { - if (strcmp (m->name, "get_Rank") == 0) - op = MINT_ARRAY_RANK; - else if (strcmp (m->name, "get_Length") == 0) - op = MINT_LDLEN; - } - } - CHECK_STACK(&td, csignature->param_count + csignature->hasthis); - if (!calli && (!virtual || (m->flags & METHOD_ATTRIBUTE_VIRTUAL) == 0) && - (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) == 0 && - (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) == 0) { - int called_inited = mono_class_vtable (domain, m->klass)->initialized; - MonoMethodHeader *mheader = mono_method_get_header (m); - - if (/*mono_metadata_signature_equal (method->signature, m->signature) */ method == m && *(td.ip + 5) == CEE_RET) { - int offset; - if (mono_interp_traceopt) - g_print ("Optimize tail call of %s.%s\n", m->klass->name, m->name); - for (i = csignature->param_count - 1; i >= 0; --i) - store_arg (&td, i + csignature->hasthis); - - if (csignature->hasthis) { - ADD_CODE(&td, MINT_STTHIS); - --td.sp; - } - ADD_CODE(&td, MINT_BR_S); - offset = body_start_offset - ((td.new_ip - 1) - td.new_code); - ADD_CODE(&td, offset); - if (!is_bb_start [td.ip + 5 - td.il_code]) - ++td.ip; /* gobble the CEE_RET if it isn't branched to */ - td.ip += 5; - break; - } else { - /* mheader might not exist if this is a delegate invoc, etc */ - if (mheader && *mheader->code == CEE_RET && called_inited) { - if (mono_interp_traceopt) - g_print ("Inline (empty) call of %s.%s\n", m->klass->name, m->name); - for (i = 0; i < csignature->param_count; i++) - ADD_CODE(&td, MINT_POP); /*FIX: vt */ - if (csignature->hasthis) { - if (virtual) - ADD_CODE(&td, MINT_CKNULL); - ADD_CODE(&td, MINT_POP); - } - td.sp -= csignature->param_count + csignature->hasthis; - td.ip += 5; - break; - } - } - } - if (method->wrapper_type == MONO_WRAPPER_NONE && m != NULL) { - if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) - m = mono_marshal_get_native_wrapper (m); - if (!virtual && m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) - m = mono_marshal_get_synchronized_wrapper (m); - } - g_assert (csignature->call_convention == MONO_CALL_DEFAULT || csignature->call_convention == MONO_CALL_C); - td.sp -= csignature->param_count + csignature->hasthis; - for (i = 0; i < csignature->param_count; ++i) { - if (td.sp [i + csignature->hasthis].type == STACK_TYPE_VT) { - gint32 size; - if (csignature->pinvoke && method->wrapper_type != MONO_WRAPPER_NONE) - size = mono_class_native_size (csignature->params [i]->data.klass, NULL); - else - size = mono_class_value_size (csignature->params [i]->data.klass, NULL); - size = (size + 7) & ~7; - vt_stack_used += size; - } - } - - /* need to handle typedbyref ... */ - if (csignature->ret->type != MONO_TYPE_VOID) { - int mt = mint_type(csignature->ret); - MonoClass *klass = NULL; - if (mt == MINT_TYPE_VT) { - if (csignature->pinvoke && method->wrapper_type != MONO_WRAPPER_NONE) - vt_res_size = mono_class_native_size (csignature->ret->data.klass, NULL); - else - vt_res_size = mono_class_value_size (csignature->ret->data.klass, NULL); - PUSH_VT(&td, vt_res_size); - klass = csignature->ret->data.klass; - } else if (mt == MINT_TYPE_O) - klass = mono_class_from_mono_type (csignature->ret); - PUSH_TYPE(&td, stack_type[mt], klass); - } else - is_void = TRUE; - - if (op >= 0) { - ADD_CODE(&td, op); -#if SIZEOF_VOID_P == 8 - if (op == MINT_LDLEN) - ADD_CODE(&td, MINT_CONV_I4_I8); -#endif - } else { - if (calli) - ADD_CODE(&td, native ? MINT_CALLI_NAT : MINT_CALLI); - else if (virtual) - ADD_CODE(&td, is_void ? MINT_VCALLVIRT : MINT_CALLVIRT); - else - ADD_CODE(&td, is_void ? MINT_VCALL : MINT_CALL); - ADD_CODE(&td, get_data_item_index (&td, calli? (void *)csignature : (void *)mono_interp_get_runtime_method (m))); - } - td.ip += 5; - if (vt_stack_used != 0 || vt_res_size != 0) { - ADD_CODE(&td, MINT_VTRESULT); - ADD_CODE(&td, vt_res_size); - WRITE32(&td, &vt_stack_used); - td.vt_sp -= vt_stack_used; - } - break; - } - case CEE_RET: { - int vt_size = 0; - if (signature->ret->type != MONO_TYPE_VOID) { - --td.sp; - if (mint_type(signature->ret) == MINT_TYPE_VT) { - vt_size = mono_class_value_size (signature->ret->data.klass, NULL); - vt_size = (vt_size + 7) & ~7; - } - } - if (td.sp > td.stack) - g_warning ("%s.%s: CEE_RET: more values on stack: %d", td.method->klass->name, td.method->name, td.sp - td.stack); - if (td.vt_sp != vt_size) - g_warning ("%s.%s: CEE_RET: value type stack: %d", td.method->klass->name, td.method->name, td.vt_sp); - if (vt_size == 0) - SIMPLE_OP(td, signature->ret->type == MONO_TYPE_VOID ? MINT_RET_VOID : MINT_RET); - else { - ADD_CODE(&td, MINT_RET_VT); - WRITE32(&td, &vt_size); - ++td.ip; - } - generating_code = 0; - break; - } - case CEE_BR: - handle_branch (&td, MINT_BR_S, MINT_BR, 5 + read32 (td.ip + 1)); - td.ip += 5; - generating_code = 0; - break; - case CEE_BR_S: - handle_branch (&td, MINT_BR_S, MINT_BR, 2 + (gint8)td.ip [1]); - td.ip += 2; - generating_code = 0; - break; - case CEE_BRFALSE: - one_arg_branch (&td, MINT_BRFALSE_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BRFALSE_S: - one_arg_branch (&td, MINT_BRFALSE_I4, 2 + (gint8)td.ip [1]); - td.ip += 2; - break; - case CEE_BRTRUE: - one_arg_branch (&td, MINT_BRTRUE_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BRTRUE_S: - one_arg_branch (&td, MINT_BRTRUE_I4, 2 + (gint8)td.ip [1]); - td.ip += 2; - break; - case CEE_BEQ: - two_arg_branch (&td, MINT_BEQ_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BEQ_S: - two_arg_branch (&td, MINT_BEQ_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BGE: - two_arg_branch (&td, MINT_BGE_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BGE_S: - two_arg_branch (&td, MINT_BGE_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BGT: - two_arg_branch (&td, MINT_BGT_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BGT_S: - two_arg_branch (&td, MINT_BGT_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BLT: - two_arg_branch (&td, MINT_BLT_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BLT_S: - two_arg_branch (&td, MINT_BLT_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BLE: - two_arg_branch (&td, MINT_BLE_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BLE_S: - two_arg_branch (&td, MINT_BLE_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BNE_UN: - two_arg_branch (&td, MINT_BNE_UN_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BNE_UN_S: - two_arg_branch (&td, MINT_BNE_UN_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BGE_UN: - two_arg_branch (&td, MINT_BGE_UN_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BGE_UN_S: - two_arg_branch (&td, MINT_BGE_UN_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BGT_UN: - two_arg_branch (&td, MINT_BGT_UN_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BGT_UN_S: - two_arg_branch (&td, MINT_BGT_UN_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BLE_UN: - two_arg_branch (&td, MINT_BLE_UN_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BLE_UN_S: - two_arg_branch (&td, MINT_BLE_UN_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BLT_UN: - two_arg_branch (&td, MINT_BLT_UN_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BLT_UN_S: - two_arg_branch (&td, MINT_BLT_UN_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_SWITCH: { - guint32 n; - const unsigned char *next_ip; - const unsigned char *base_ip = td.ip; - unsigned short *next_new_ip; - ++td.ip; - n = read32 (td.ip); - ADD_CODE(&td, MINT_SWITCH); - ADD_CODE(&td, * (unsigned short *)(&n)); - ADD_CODE(&td, * ((unsigned short *)&n + 1)); - td.ip += 4; - next_ip = td.ip + n * 4; - next_new_ip = td.new_ip + n * 2; - for (i = 0; i < n; i++) { - offset = read32 (td.ip); - target = next_ip - td.il_code + offset; - if (offset < 0) - target = td.in_offsets [target] - (next_new_ip - td.new_code); - else { - int prev = td.forward_refs [target]; - td.forward_refs [td.ip - td.il_code] = prev; - td.forward_refs [target] = td.ip - td.il_code; - td.in_offsets [td.ip - td.il_code] = - (base_ip - td.il_code); - } - ADD_CODE(&td, * (unsigned short *)(&target)); - ADD_CODE(&td, * ((unsigned short *)&target + 1)); - td.ip += 4; - } - --td.sp; - break; - } - case CEE_LDIND_I1: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_I1); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDIND_U1: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_U1); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDIND_I2: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_I2); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDIND_U2: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_U2); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDIND_I4: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_I4); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDIND_U4: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_U4); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDIND_I8: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_I8); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - break; - case CEE_LDIND_I: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_I); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I); - break; - case CEE_LDIND_R4: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_R4); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - break; - case CEE_LDIND_R8: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_R8); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - break; - case CEE_LDIND_REF: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_REF); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_O); - break; - case CEE_STIND_REF: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_REF); - td.sp -= 2; - break; - case CEE_STIND_I1: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_I1); - td.sp -= 2; - break; - case CEE_STIND_I2: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_I2); - td.sp -= 2; - break; - case CEE_STIND_I4: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_I4); - td.sp -= 2; - break; - case CEE_STIND_I: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_I); - td.sp -= 2; - break; - case CEE_STIND_I8: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_I8); - td.sp -= 2; - break; - case CEE_STIND_R4: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_R4); - td.sp -= 2; - break; - case CEE_STIND_R8: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_R8); - td.sp -= 2; - break; - case CEE_ADD: - binary_arith_op(&td, MINT_ADD_I4); - ++td.ip; - break; - case CEE_SUB: - binary_arith_op(&td, MINT_SUB_I4); - ++td.ip; - break; - case CEE_MUL: - binary_arith_op(&td, MINT_MUL_I4); - ++td.ip; - break; - case CEE_DIV: - binary_arith_op(&td, MINT_DIV_I4); - ++td.ip; - break; - case CEE_DIV_UN: - binary_arith_op(&td, MINT_DIV_UN_I4); - ++td.ip; - break; - case CEE_REM: - binary_int_op (&td, MINT_REM_I4); - ++td.ip; - break; - case CEE_REM_UN: - binary_int_op (&td, MINT_REM_UN_I4); - ++td.ip; - break; - case CEE_AND: - binary_int_op (&td, MINT_AND_I4); - ++td.ip; - break; - case CEE_OR: - binary_int_op (&td, MINT_OR_I4); - ++td.ip; - break; - case CEE_XOR: - binary_int_op (&td, MINT_XOR_I4); - ++td.ip; - break; - case CEE_SHL: - shift_op (&td, MINT_SHL_I4); - ++td.ip; - break; - case CEE_SHR: - shift_op (&td, MINT_SHR_I4); - ++td.ip; - break; - case CEE_SHR_UN: - shift_op (&td, MINT_SHR_UN_I4); - ++td.ip; - break; - case CEE_NEG: - unary_arith_op (&td, MINT_NEG_I4); - ++td.ip; - break; - case CEE_NOT: - unary_arith_op (&td, MINT_NOT_I4); - ++td.ip; - break; - case CEE_CONV_U1: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_U1_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_U1_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_U1_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_I1: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_I1_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_I1_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_I1_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_U2: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_U2_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_U2_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_U2_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_I2: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_I2_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_I2_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_I2_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_U: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: -#if SIZEOF_VOID_P == 4 - ADD_CODE(&td, MINT_CONV_U4_R8); -#else - ADD_CODE(&td, MINT_CONV_U8_R8); -#endif - break; - case STACK_TYPE_I4: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_U8_I4); -#endif - break; - case STACK_TYPE_I8: -#if SIZEOF_VOID_P == 4 - ADD_CODE(&td, MINT_CONV_U4_I8); -#endif - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I); - break; - case CEE_CONV_I: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_I8_R8); -#else - ADD_CODE(&td, MINT_CONV_I4_R8); -#endif - break; - case STACK_TYPE_I4: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_I8_I4); -#endif - break; - case STACK_TYPE_O: - break; - case STACK_TYPE_MP: - break; - case STACK_TYPE_I8: -#if SIZEOF_VOID_P == 4 - ADD_CODE(&td, MINT_CONV_I4_I8); -#endif - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I); - break; - case CEE_CONV_U4: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_U4_R8); - break; - case STACK_TYPE_I4: - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_U4_I8); - break; - case STACK_TYPE_MP: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_U4_I8); -#endif - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_I4: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_I4_R8); - break; - case STACK_TYPE_I4: - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_I4_I8); - break; - case STACK_TYPE_MP: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_I4_I8); -#endif - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_I8: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_I8_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_I8_I4); - break; - case STACK_TYPE_I8: - break; - case STACK_TYPE_MP: -#if SIZEOF_VOID_P == 4 - ADD_CODE(&td, MINT_CONV_I8_I4); -#endif - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - break; - case CEE_CONV_R4: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_R4_R8); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_R4_I8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_R4_I4); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - break; - case CEE_CONV_R8: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_R8_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_R8_I8); - break; - case STACK_TYPE_R8: - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - break; - case CEE_CONV_U8: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_U8_I4); - break; - case STACK_TYPE_I8: - break; - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_U8_R8); - break; - case STACK_TYPE_MP: -#if SIZEOF_VOID_P == 4 - ADD_CODE(&td, MINT_CONV_U8_I4); -#endif - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - break; -#if 0 - case CEE_CPOBJ: { - MonoClass *vtklass; - ++ip; - vtklass = mono_class_get_full (image, read32 (ip), generic_context); - ip += 4; - sp -= 2; - memcpy (sp [0].data.p, sp [1].data.p, mono_class_value_size (vtklass, NULL)); - break; - } -#endif - case CEE_LDOBJ: { - int size; - CHECK_STACK (&td, 1); - - token = read32 (td.ip + 1); - - if (method->wrapper_type != MONO_WRAPPER_NONE) - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - else - klass = mono_class_get_full (image, token, generic_context); - - ADD_CODE(&td, MINT_LDOBJ); - ADD_CODE(&td, get_data_item_index(&td, klass)); - if (klass->byval_arg.type == MONO_TYPE_VALUETYPE && !klass->byval_arg.data.klass->enumtype) { - size = mono_class_value_size (klass, NULL); - PUSH_VT(&td, size); - } - td.ip += 5; - SET_TYPE(td.sp - 1, stack_type[mint_type(&klass->byval_arg)], klass); - break; - } - case CEE_LDSTR: { - MonoString *s; - token = mono_metadata_token_index (read32 (td.ip + 1)); - td.ip += 5; - if (method->wrapper_type != MONO_WRAPPER_NONE) { - s = mono_string_new_wrapper( - mono_method_get_wrapper_data (method, token)); - } - else - s = mono_ldstr (domain, image, token); - ADD_CODE(&td, MINT_LDSTR); - ADD_CODE(&td, get_data_item_index (&td, s)); - PUSH_TYPE(&td, STACK_TYPE_O, mono_defaults.string_class); - break; - } - case CEE_NEWOBJ: { - MonoMethod *m; - MonoMethodSignature *csignature; - guint32 vt_stack_used = 0; - guint32 vt_res_size = 0; - - td.ip++; - token = read32 (td.ip); - td.ip += 4; - - if (method->wrapper_type != MONO_WRAPPER_NONE) - m = (MonoMethod *)mono_method_get_wrapper_data (method, token); - else - m = mono_get_method_full (image, token, NULL, generic_context); - - csignature = mono_method_signature (m); - klass = m->klass; - td.sp -= csignature->param_count; - ADD_CODE(&td, MINT_NEWOBJ); - ADD_CODE(&td, get_data_item_index (&td, mono_interp_get_runtime_method (m))); - if (klass->byval_arg.type == MONO_TYPE_VALUETYPE) { - vt_res_size = mono_class_value_size (klass, NULL); - PUSH_VT(&td, vt_res_size); - } - for (i = 0; i < csignature->param_count; ++i) { - int mt = mint_type(csignature->params [i]); - if (mt == MINT_TYPE_VT) { - gint32 size = mono_class_value_size (csignature->params [i]->data.klass, NULL); - size = (size + 7) & ~7; - vt_stack_used += size; - } - } - if (vt_stack_used != 0 || vt_res_size != 0) { - ADD_CODE(&td, MINT_VTRESULT); - ADD_CODE(&td, vt_res_size); - WRITE32(&td, &vt_stack_used); - td.vt_sp -= vt_stack_used; - } - PUSH_TYPE(&td, stack_type [mint_type (&klass->byval_arg)], klass); - break; - } - case CEE_CASTCLASS: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - klass = mono_class_get_full (image, token, generic_context); - ADD_CODE(&td, MINT_CASTCLASS); - ADD_CODE(&td, get_data_item_index (&td, klass)); - td.sp [-1].klass = klass; - td.ip += 5; - break; - case CEE_ISINST: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - klass = mono_class_get_full (image, token, generic_context); - ADD_CODE(&td, MINT_ISINST); - ADD_CODE(&td, get_data_item_index (&td, klass)); - td.ip += 5; - break; - case CEE_CONV_R_UN: - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_R_UN_I8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_R_UN_I4); - break; - default: - g_assert_not_reached (); - } - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - ++td.ip; - break; - case CEE_UNBOX: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - - if (method->wrapper_type != MONO_WRAPPER_NONE) - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - else - klass = mono_class_get_full (image, token, generic_context); - - ADD_CODE(&td, MINT_UNBOX); - ADD_CODE(&td, get_data_item_index (&td, klass)); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP); - td.ip += 5; - break; - case CEE_THROW: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_THROW); - --td.sp; - generating_code = 0; - break; - case CEE_LDFLDA: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - field = mono_field_from_token (image, token, &klass, generic_context); - mono_class_init (klass); - mt = mint_type(field->type); - ADD_CODE(&td, MINT_LDFLDA); - ADD_CODE(&td, klass->valuetype ? field->offset - sizeof(MonoObject) : field->offset); - td.ip += 5; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP); - break; - case CEE_LDFLD: { - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - field = mono_field_from_token (image, token, &klass, generic_context); - mono_class_init (klass); - mt = mint_type(field->type); - if (klass->marshalbyref) { - ADD_CODE(&td, mt == MINT_TYPE_VT ? MINT_LDRMFLD_VT : MINT_LDRMFLD); - ADD_CODE(&td, get_data_item_index (&td, field)); - } else { - ADD_CODE(&td, MINT_LDFLD_I1 + mt - MINT_TYPE_I1); - ADD_CODE(&td, klass->valuetype ? field->offset - sizeof(MonoObject) : field->offset); - } - klass = NULL; - if (mt == MINT_TYPE_VT) { - int size = mono_class_value_size (field->type->data.klass, NULL); - PUSH_VT(&td, size); - WRITE32(&td, &size); - klass = field->type->data.klass; - } else if (mt == MINT_TYPE_O) - klass = mono_class_from_mono_type (field->type); - td.ip += 5; - SET_TYPE(td.sp - 1, stack_type [mt], klass); - break; - } - case CEE_STFLD: - CHECK_STACK (&td, 2); - token = read32 (td.ip + 1); - field = mono_field_from_token (image, token, &klass, generic_context); - mono_class_init (klass); - mt = mint_type(field->type); - if (klass->marshalbyref) { - ADD_CODE(&td, mt == MINT_TYPE_VT ? MINT_STRMFLD_VT : MINT_STRMFLD); - ADD_CODE(&td, get_data_item_index (&td, field)); - } else { - ADD_CODE(&td, MINT_STFLD_I1 + mt - MINT_TYPE_I1); - ADD_CODE(&td, klass->valuetype ? field->offset - sizeof(MonoObject) : field->offset); - } - if (mt == MINT_TYPE_VT) { - int size = mono_class_value_size (field->type->data.klass, NULL); - POP_VT(&td, size); - WRITE32(&td, &size); - } - td.ip += 5; - td.sp -= 2; - break; - case CEE_LDSFLDA: - token = read32 (td.ip + 1); - field = mono_field_from_token (image, token, &klass, generic_context); - ADD_CODE(&td, MINT_LDSFLDA); - ADD_CODE(&td, get_data_item_index (&td, field)); - td.ip += 5; - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_MP); - break; - case CEE_LDSFLD: - token = read32 (td.ip + 1); - field = mono_field_from_token (image, token, &klass, generic_context); - mt = mint_type(field->type); - ADD_CODE(&td, mt == MINT_TYPE_VT ? MINT_LDSFLD_VT : MINT_LDSFLD); - ADD_CODE(&td, get_data_item_index (&td, field)); - klass = NULL; - if (mt == MINT_TYPE_VT) { - int size = mono_class_value_size (field->type->data.klass, NULL); - PUSH_VT(&td, size); - WRITE32(&td, &size); - klass = field->type->data.klass; - } else { - if (mt == MINT_TYPE_O) - klass = mono_class_from_mono_type (field->type); - if (!domain->special_static_fields || !g_hash_table_lookup (domain->special_static_fields, field)) { - if (mt == MINT_TYPE_O) - td.new_ip [-2] = MINT_LDSFLD_O; - else if (mt == MINT_TYPE_I4) - td.new_ip [-2] = MINT_LDSFLD_I4; - } - ADD_CODE(&td, get_data_item_index (&td, mono_class_vtable (domain, field->parent))); - } - td.ip += 5; - PUSH_TYPE(&td, stack_type [mt], klass); - break; - case CEE_STSFLD: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - field = mono_field_from_token (image, token, &klass, generic_context); - mt = mint_type(field->type); - ADD_CODE(&td, mt == MINT_TYPE_VT ? MINT_STSFLD_VT : MINT_STSFLD); - ADD_CODE(&td, get_data_item_index (&td, field)); - if (mt == MINT_TYPE_VT) { - int size = mono_class_value_size (field->type->data.klass, NULL); - POP_VT(&td, size); - WRITE32(&td, &size); - } - td.ip += 5; - --td.sp; - break; - case CEE_STOBJ: { - int size; - token = read32 (td.ip + 1); - - if (method->wrapper_type != MONO_WRAPPER_NONE) - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - else - klass = mono_class_get_full (image, token, generic_context); - - ADD_CODE(&td, td.sp [-1].type == STACK_TYPE_VT ? MINT_STOBJ_VT : MINT_STOBJ); - ADD_CODE(&td, get_data_item_index (&td, klass)); - if (td.sp [-1].type == STACK_TYPE_VT) { - size = mono_class_value_size (klass, NULL); - size = (size + 7) & ~7; - td.vt_sp -= size; - } - td.ip += 5; - td.sp -= 2; - break; - } - case CEE_CONV_OVF_I_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_OVF_I8_UN_R8); -#else - ADD_CODE(&td, MINT_CONV_OVF_I4_UN_R8); -#endif - break; - case STACK_TYPE_I8: - /*FIX*/ - break; - case STACK_TYPE_I4: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_I8_U4); -#endif - break; - default: - g_assert_not_reached (); - break; - } - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - ++td.ip; - break; - case CEE_CONV_OVF_I8_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_I8_UN_R8); - break; - case STACK_TYPE_I8: - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_I8_U4); - break; - default: - g_assert_not_reached (); - break; - } - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - ++td.ip; - break; - case CEE_BOX: { - int size; - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - if (method->wrapper_type != MONO_WRAPPER_NONE) - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - else - klass = mono_class_get_full (image, token, generic_context); - g_assert (klass->valuetype); - if (klass->byval_arg.type == MONO_TYPE_VALUETYPE && !klass->enumtype) { - size = mono_class_value_size (klass, NULL); - size = (size + 7) & ~7; - td.vt_sp -= size; - } - ADD_CODE(&td, MINT_BOX); - ADD_CODE(&td, get_data_item_index (&td, klass)); - SET_TYPE(td.sp - 1, STACK_TYPE_O, klass); - td.ip += 5; - break; - } - case CEE_NEWARR: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - - if (method->wrapper_type != MONO_WRAPPER_NONE) - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - else - klass = mono_class_get_full (image, token, generic_context); - - ADD_CODE(&td, MINT_NEWARR); - ADD_CODE(&td, get_data_item_index (&td, klass)); - SET_TYPE(td.sp - 1, STACK_TYPE_O, klass); - td.ip += 5; - break; - case CEE_LDLEN: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDLEN); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I); - break; - case CEE_LDELEMA: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - token = read32 (td.ip + 1); - - if (method->wrapper_type != MONO_WRAPPER_NONE) - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - else - klass = mono_class_get_full (image, token, generic_context); - - ADD_CODE(&td, MINT_LDELEMA); - ADD_CODE(&td, get_data_item_index (&td, klass)); - td.ip += 5; - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP); - break; - case CEE_LDELEM_I1: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_I1); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDELEM_U1: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_U1); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDELEM_I2: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_I2); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDELEM_U2: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_U2); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDELEM_I4: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_I4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDELEM_U4: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_U4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDELEM_I8: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_I8); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - break; - case CEE_LDELEM_I: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_I); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I); - break; - case CEE_LDELEM_R4: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_R4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - break; - case CEE_LDELEM_R8: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_R8); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - break; - case CEE_LDELEM_REF: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_REF); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_O); - break; - case CEE_STELEM_I: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_I); - td.sp -= 3; - break; - case CEE_STELEM_I1: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_I1); - td.sp -= 3; - break; - case CEE_STELEM_I2: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_I2); - td.sp -= 3; - break; - case CEE_STELEM_I4: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_I4); - td.sp -= 3; - break; - case CEE_STELEM_I8: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_I8); - td.sp -= 3; - break; - case CEE_STELEM_R4: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_R4); - td.sp -= 3; - break; - case CEE_STELEM_R8: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_R8); - td.sp -= 3; - break; - case CEE_STELEM_REF: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_REF); - td.sp -= 3; - break; -#if 0 - case CEE_LDELEM: - case CEE_STELEM: - case CEE_UNBOX_ANY: - - case CEE_CONV_OVF_U1: - - case CEE_CONV_OVF_I8: - -#if SIZEOF_VOID_P == 8 - case CEE_CONV_OVF_U: -#endif - case CEE_REFANYVAL: ves_abort(); break; -#endif - case CEE_CKFINITE: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_CKFINITE); - break; - case CEE_CONV_OVF_I1: - case CEE_CONV_OVF_I1_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_I1_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_OVF_I1_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_OVF_I1_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_OVF_U1: - case CEE_CONV_OVF_U1_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_U1_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_OVF_U1_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_OVF_U1_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_OVF_I2: - case CEE_CONV_OVF_I2_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_I2_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_OVF_I2_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_OVF_I2_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_OVF_U2_UN: - case CEE_CONV_OVF_U2: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_U2_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_OVF_U2_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_OVF_U2_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; -#if SIZEOF_VOID_P == 4 - case CEE_CONV_OVF_I: -#endif - case CEE_CONV_OVF_I4: - case CEE_CONV_OVF_I4_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_I4_R8); - break; - case STACK_TYPE_I4: - if (*td.ip == CEE_CONV_OVF_I4_UN) - ADD_CODE(&td, MINT_CONV_OVF_I4_U4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_OVF_I4_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; -#if SIZEOF_VOID_P == 4 - case CEE_CONV_OVF_U: -#endif - case CEE_CONV_OVF_U4: - case CEE_CONV_OVF_U4_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_U4_R8); - break; - case STACK_TYPE_I4: - if (*td.ip != CEE_CONV_OVF_U4_UN) - ADD_CODE(&td, MINT_CONV_OVF_U4_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_OVF_U4_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; -#if SIZEOF_VOID_P == 8 - case CEE_CONV_OVF_I: -#endif - case CEE_CONV_OVF_I8: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_I8_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_I8_I4); - break; - case STACK_TYPE_I8: - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - break; -#if SIZEOF_VOID_P == 8 - case CEE_CONV_OVF_U: -#endif - case CEE_CONV_OVF_U8: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_U8_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_OVF_U8_I4); - break; - case STACK_TYPE_I8: - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - break; - case CEE_LDTOKEN: { - int size; - gpointer handle; - token = read32 (td.ip + 1); - handle = mono_ldtoken (image, token, &klass, generic_context); - mt = mint_type(&klass->byval_arg); - g_assert (mt == MINT_TYPE_VT); - size = mono_class_value_size (klass, NULL); - g_assert (size == sizeof(gpointer)); - PUSH_VT(&td, sizeof(gpointer)); - ADD_CODE(&td, MINT_LDTOKEN); - ADD_CODE(&td, get_data_item_index (&td, handle)); - PUSH_SIMPLE_TYPE(&td, stack_type [mt]); - td.ip += 5; - break; - } - case CEE_ADD_OVF: - binary_arith_op(&td, MINT_ADD_OVF_I4); - ++td.ip; - break; - case CEE_ADD_OVF_UN: - binary_arith_op(&td, MINT_ADD_OVF_UN_I4); - ++td.ip; - break; - case CEE_MUL_OVF: - binary_arith_op(&td, MINT_MUL_OVF_I4); - ++td.ip; - break; - case CEE_MUL_OVF_UN: - binary_arith_op(&td, MINT_MUL_OVF_UN_I4); - ++td.ip; - break; - case CEE_SUB_OVF: - binary_arith_op(&td, MINT_SUB_OVF_I4); - ++td.ip; - break; - case CEE_SUB_OVF_UN: - binary_arith_op(&td, MINT_SUB_OVF_UN_I4); - ++td.ip; - break; - case CEE_ENDFINALLY: - SIMPLE_OP (td, MINT_ENDFINALLY); - generating_code = 0; - break; - case CEE_LEAVE: - td.sp = td.stack; - handle_branch (&td, MINT_LEAVE_S, MINT_LEAVE, 5 + read32 (td.ip + 1)); - td.ip += 5; - generating_code = 0; - break; - case CEE_LEAVE_S: - td.sp = td.stack; - handle_branch (&td, MINT_LEAVE_S, MINT_LEAVE, 2 + (gint8)td.ip [1]); - td.ip += 2; - generating_code = 0; - break; - case CEE_UNUSED41: - ++td.ip; - switch (*td.ip) { - case CEE_MONO_ICALL: { - guint32 token; - gpointer func; - MonoJitICallInfo *info; - - token = read32 (td.ip + 1); - td.ip += 5; - func = mono_method_get_wrapper_data (method, token); - info = mono_find_jit_icall_by_addr (func); - g_assert (info); - - CHECK_STACK (&td, info->sig->param_count); - switch (info->sig->param_count) { - case 0: - if (MONO_TYPE_IS_VOID (info->sig->ret)) - ADD_CODE (&td,MINT_ICALL_V_V); - else - g_assert_not_reached(); - break; - case 1: - if (MONO_TYPE_IS_VOID (info->sig->ret)) - ADD_CODE (&td,MINT_ICALL_P_V); - else - ADD_CODE (&td,MINT_ICALL_P_P); - break; - case 2: - if (MONO_TYPE_IS_VOID (info->sig->ret)) { - if (info->sig->params [1]->type == MONO_TYPE_I4) - ADD_CODE (&td,MINT_ICALL_PI_V); - else - ADD_CODE (&td,MINT_ICALL_PP_V); - } else { - if (info->sig->params [1]->type == MONO_TYPE_I4) - ADD_CODE (&td,MINT_ICALL_PI_P); - else - ADD_CODE (&td,MINT_ICALL_PP_P); - } - break; - case 3: - g_assert (MONO_TYPE_IS_VOID (info->sig->ret)); - if (info->sig->params [2]->type == MONO_TYPE_I4) - ADD_CODE (&td,MINT_ICALL_PPI_V); - else - ADD_CODE (&td,MINT_ICALL_PPP_V); - break; - default: - g_assert_not_reached (); - } - if (func == mono_ftnptr_to_delegate) - func = mono_interp_ftnptr_to_delegate; - ADD_CODE(&td, get_data_item_index (&td, func)); - td.sp -= info->sig->param_count; - - if (!MONO_TYPE_IS_VOID (info->sig->ret)) { - td.sp ++; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I); - } - break; - } - case CEE_MONO_VTADDR: { - int size; - CHECK_STACK (&td, 1); - if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) - size = mono_class_native_size(td.sp [-1].klass, NULL); - else - size = mono_class_value_size(td.sp [-1].klass, NULL); - size = (size + 7) & ~7; - ADD_CODE(&td, MINT_VTRESULT); - ADD_CODE(&td, 0); - WRITE32(&td, &size); - td.vt_sp -= size; - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP); - break; - } - case CEE_MONO_LDPTR: - case CEE_MONO_CLASSCONST: - token = read32 (td.ip + 1); - td.ip += 5; - ADD_CODE(&td, MINT_MONO_LDPTR); - ADD_CODE(&td, get_data_item_index (&td, mono_method_get_wrapper_data (method, token))); - td.sp [0].type = STACK_TYPE_I; - ++td.sp; - break; - case CEE_MONO_OBJADDR: - CHECK_STACK (&td, 1); - ++td.ip; - td.sp[-1].type = STACK_TYPE_MP; - /* do nothing? */ - break; - case CEE_MONO_NEWOBJ: - token = read32 (td.ip + 1); - td.ip += 5; - ADD_CODE(&td, MINT_MONO_NEWOBJ); - ADD_CODE(&td, get_data_item_index (&td, mono_method_get_wrapper_data (method, token))); - td.sp [0].type = STACK_TYPE_O; - ++td.sp; - break; - case CEE_MONO_RETOBJ: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - td.ip += 5; - ADD_CODE(&td, MINT_MONO_RETOBJ); - td.sp--; - - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - - /*stackval_from_data (signature->ret, frame->retval, sp->data.vt, signature->pinvoke);*/ - - if (td.sp > td.stack) - g_warning ("CEE_MONO_RETOBJ: more values on stack: %d", td.sp-td.stack); - break; - case CEE_MONO_LDNATIVEOBJ: - token = read32 (td.ip + 1); - td.ip += 5; - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - g_assert(klass->valuetype); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP); - break; - case CEE_MONO_SAVE_LMF: - case CEE_MONO_RESTORE_LMF: - case CEE_MONO_NOT_TAKEN: - ++td.ip; - break; - default: - g_error ("transform.c: Unimplemented opcode: 0xF0 %02x at 0x%x\n", *td.ip, td.ip-header->code); - } - break; -#if 0 - case CEE_PREFIX7: - case CEE_PREFIX6: - case CEE_PREFIX5: - case CEE_PREFIX4: - case CEE_PREFIX3: - case CEE_PREFIX2: - case CEE_PREFIXREF: ves_abort(); break; -#endif - /* - * Note: Exceptions thrown when executing a prefixed opcode need - * to take into account the number of prefix bytes (usually the - * throw point is just (ip - n_prefix_bytes). - */ - case CEE_PREFIX1: - ++td.ip; - switch (*td.ip) { -#if 0 - case CEE_ARGLIST: ves_abort(); break; -#endif - case CEE_CEQ: - CHECK_STACK(&td, 2); - if (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_MP) - ADD_CODE(&td, MINT_CEQ_I4 + STACK_TYPE_I - STACK_TYPE_I4); - else - ADD_CODE(&td, MINT_CEQ_I4 + td.sp [-1].type - STACK_TYPE_I4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - ++td.ip; - break; - case CEE_CGT: - CHECK_STACK(&td, 2); - if (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_MP) - ADD_CODE(&td, MINT_CGT_I4 + STACK_TYPE_I - STACK_TYPE_I4); - else - ADD_CODE(&td, MINT_CGT_I4 + td.sp [-1].type - STACK_TYPE_I4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - ++td.ip; - break; - case CEE_CGT_UN: - CHECK_STACK(&td, 2); - if (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_MP) - ADD_CODE(&td, MINT_CGT_UN_I4 + STACK_TYPE_I - STACK_TYPE_I4); - else - ADD_CODE(&td, MINT_CGT_UN_I4 + td.sp [-1].type - STACK_TYPE_I4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - ++td.ip; - break; - case CEE_CLT: - CHECK_STACK(&td, 2); - if (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_MP) - ADD_CODE(&td, MINT_CLT_I4 + STACK_TYPE_I - STACK_TYPE_I4); - else - ADD_CODE(&td, MINT_CLT_I4 + td.sp [-1].type - STACK_TYPE_I4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - ++td.ip; - break; - case CEE_CLT_UN: - CHECK_STACK(&td, 2); - if (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_MP) - ADD_CODE(&td, MINT_CLT_UN_I4 + STACK_TYPE_I - STACK_TYPE_I4); - else - ADD_CODE(&td, MINT_CLT_UN_I4 + td.sp [-1].type - STACK_TYPE_I4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - ++td.ip; - break; - case CEE_LDVIRTFTN: /* fallthrough */ - case CEE_LDFTN: { - MonoMethod *m; - if (*td.ip == CEE_LDVIRTFTN) { - CHECK_STACK (&td, 1); - --td.sp; - } - token = read32 (td.ip + 1); - if (method->wrapper_type != MONO_WRAPPER_NONE) - m = (MonoMethod *)mono_method_get_wrapper_data (method, token); - else - m = mono_get_method_full (image, token, NULL, generic_context); - - if (method->wrapper_type == MONO_WRAPPER_NONE && m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) - m = mono_marshal_get_synchronized_wrapper (m); - - ADD_CODE(&td, *td.ip == CEE_LDFTN ? MINT_LDFTN : MINT_LDVIRTFTN); - ADD_CODE(&td, get_data_item_index (&td, mono_interp_get_runtime_method (m))); - td.ip += 5; - PUSH_SIMPLE_TYPE (&td, STACK_TYPE_F); - break; - } - case CEE_LDARG: - load_arg (&td, read16 (td.ip + 1)); - td.ip += 3; - break; - case CEE_LDARGA: { - int n = read16 (td.ip + 1); - if (n == 0 && signature->hasthis) - ADD_CODE(&td, MINT_LDTHISA); - else { - ADD_CODE(&td, MINT_LDARGA); - ADD_CODE(&td, td.rtm->arg_offsets [n - signature->hasthis]); /* FIX for large offsets */ - } - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_MP); - td.ip += 3; - break; - } - case CEE_STARG: - store_arg (&td, read16 (td.ip + 1)); - td.ip += 3; - break; - case CEE_LDLOC: - load_local (&td, read16 (td.ip + 1)); - td.ip += 3; - break; - case CEE_LDLOCA: - ADD_CODE(&td, MINT_LDLOCA_S); - ADD_CODE(&td, td.rtm->local_offsets [read16 (td.ip + 1)]); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_MP); - td.ip += 3; - break; - case CEE_STLOC: - store_local (&td, read16 (td.ip + 1)); - td.ip += 3; - break; - case CEE_LOCALLOC: - CHECK_STACK (&td, 1); -#if SIZEOF_VOID_P == 8 - if (td.sp [-1].type == STACK_TYPE_I8) - ADD_CODE(&td, MINT_CONV_I4_I8); -#endif - ADD_CODE(&td, MINT_LOCALLOC); - if (td.sp != td.stack + 1) - g_warning("CEE_LOCALLOC: stack not empty"); - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP); - break; -#if 0 - case CEE_UNUSED57: ves_abort(); break; - case CEE_ENDFILTER: ves_abort(); break; -#endif - case CEE_UNALIGNED_: - ++td.ip; - /* FIX: should do something? */; - break; - case CEE_VOLATILE_: - ++td.ip; - /* FIX: should do something? */; - break; - case CEE_TAIL_: - ++td.ip; - /* FIX: should do something? */; - break; - case CEE_INITOBJ: - CHECK_STACK(&td, 1); - token = read32 (td.ip + 1); - klass = mono_class_get_full (image, token, generic_context); - ADD_CODE(&td, MINT_INITOBJ); - i32 = mono_class_value_size (klass, NULL); - WRITE32(&td, &i32); - td.ip += 5; - --td.sp; - break; - case CEE_CPBLK: - CHECK_STACK(&td, 3); - /* FIX? convert length to I8? */ - ADD_CODE(&td, MINT_CPBLK); - td.sp -= 3; - ++td.ip; - break; -#if 0 - case CEE_CONSTRAINED_: { - guint32 token; - /* FIXME: implement */ - ++ip; - token = read32 (ip); - ip += 4; - break; - } -#endif - case CEE_INITBLK: - CHECK_STACK(&td, 3); - ADD_CODE(&td, MINT_INITBLK); - td.sp -= 3; - break; -#if 0 - case CEE_NO_: - /* FIXME: implement */ - ip += 2; - break; -#endif - case CEE_RETHROW: - SIMPLE_OP (td, MINT_RETHROW); - generating_code = 0; - break; - case CEE_SIZEOF: { - guint32 align; - gint32 size; - token = read32 (td.ip + 1); - td.ip += 5; - if (mono_metadata_token_table (token) == MONO_TABLE_TYPESPEC) { - MonoType *type = mono_type_create_from_typespec (image, token); - size = mono_type_size (type, &align); - } else { - MonoClass *szclass = mono_class_get_full (image, token, generic_context); - mono_class_init (szclass); -#if 0 - if (!szclass->valuetype) - THROW_EX (mono_exception_from_name (mono_defaults.corlib, "System", "InvalidProgramException"), ip - 5); -#endif - size = mono_class_value_size (szclass, &align); - } - ADD_CODE(&td, MINT_LDC_I4); - WRITE32(&td, &size); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - break; - } -#if 0 - case CEE_REFANYTYPE: ves_abort(); break; -#endif - default: - g_error ("transform.c: Unimplemented opcode: 0xFE %02x at 0x%x\n", *td.ip, td.ip-header->code); - } - break; - default: - g_error ("transform.c: Unimplemented opcode: %02x at 0x%x\n", *td.ip, td.ip-header->code); - } - - if (td.new_ip - td.new_code != new_in_start_offset) - td.last_new_ip = td.new_code + new_in_start_offset; - else if (td.is_bb_start [td.in_start - td.il_code]) - td.is_bb_start [td.ip - td.il_code] = 1; - - td.last_ip = td.in_start; - } - - if (mono_interp_traceopt) { - const guint16 *p = td.new_code; - printf("Runtime method: %p, VT stack size: %d\n", rtm, td.max_vt_sp); - printf("Calculated stack size: %d, stated size: %d\n", td.max_stack_height, header->max_stack); - while (p < td.new_ip) { - p = mono_interp_dis_mintop(td.new_code, p); - printf("\n"); - } - } - - rtm->clauses = mono_mempool_alloc (domain->mp, header->num_clauses * sizeof(MonoExceptionClause)); - memcpy (rtm->clauses, header->clauses, header->num_clauses * sizeof(MonoExceptionClause)); - rtm->code = mono_mempool_alloc (domain->mp, (td.new_ip - td.new_code) * sizeof(gushort)); - memcpy (rtm->code, td.new_code, (td.new_ip - td.new_code) * sizeof(gushort)); - g_free (td.new_code); - rtm->new_body_start = rtm->code + body_start_offset; - rtm->num_clauses = header->num_clauses; - for (i = 0; i < header->num_clauses; i++) { - MonoExceptionClause *c = rtm->clauses + i; - int end_off = c->try_offset + c->try_len; - c->try_offset = td.in_offsets [c->try_offset]; - c->try_len = td.in_offsets [end_off] - c->try_offset; - end_off = c->handler_offset + c->handler_len; - c->handler_offset = td.in_offsets [c->handler_offset]; - c->handler_len = td.in_offsets [end_off] - c->handler_offset; - } - rtm->vt_stack_size = td.max_vt_sp; - rtm->alloca_size = rtm->locals_size + rtm->args_size + rtm->vt_stack_size + rtm->stack_size; - rtm->data_items = mono_mempool_alloc (domain->mp, td.n_data_items * sizeof (td.data_items [0])); - memcpy (rtm->data_items, td.data_items, td.n_data_items * sizeof (td.data_items [0])); - g_free (td.in_offsets); - g_free (td.forward_refs); - for (i = 0; i < header->code_size; ++i) - g_free (td.stack_state [i]); - g_free (td.stack_state); - g_free (td.stack_height); - g_free (td.vt_stack_size); - g_free (td.data_items); - g_hash_table_destroy (td.data_hash); -} - -static mono_mutex_t calc_section; - -void -mono_interp_transform_init (void) -{ - mono_mutex_init_recursive(&calc_section); -} - -MonoException * -mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *context) -{ - int i, align, size, offset; - MonoMethod *method = runtime_method->method; - MonoImage *image = method->klass->image; - MonoMethodHeader *header = mono_method_get_header (method); - MonoMethodSignature *signature = mono_method_signature (method); - register const unsigned char *ip, *end; - const MonoOpcode *opcode; - MonoMethod *m; - MonoClass *class; - MonoDomain *domain = mono_domain_get (); - unsigned char *is_bb_start; - int in; - MonoVTable *method_class_vt; - int backwards; - MonoGenericContext *generic_context = NULL; - - method_class_vt = mono_class_vtable (domain, runtime_method->method->klass); - if (!method_class_vt->initialized) { - jmp_buf env; - MonoInvocation *last_env_frame = context->env_frame; - jmp_buf *old_env = context->current_env; - - if (setjmp(env)) { - MonoException *failed = context->env_frame->ex; - context->env_frame->ex = NULL; - context->env_frame = last_env_frame; - context->current_env = old_env; - return failed; - } - context->env_frame = context->current_frame; - context->current_env = &env; - mono_runtime_class_init (method_class_vt); - context->env_frame = last_env_frame; - context->current_env = old_env; - } - - mono_profiler_method_jit (method); /* sort of... */ - - if (mono_method_signature (method)->is_inflated) - generic_context = ((MonoMethodInflated *) method)->context; - - if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) { - MonoMethod *nm = NULL; - mono_mutex_lock(&calc_section); - if (runtime_method->transformed) { - mono_mutex_unlock(&calc_section); - mono_profiler_method_end_jit (method, MONO_PROFILE_OK); - return NULL; - } - - /* assumes all internal calls with an array this are built in... */ - if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL && - (! mono_method_signature (method)->hasthis || method->klass->rank == 0)) { - runtime_method->code = g_malloc(sizeof(short)); - runtime_method->code[0] = MINT_CALLINT; - if (((MonoMethodPInvoke*) method)->addr == NULL) - ((MonoMethodPInvoke*) method)->addr = mono_lookup_internal_call (method); - runtime_method->func = mono_arch_create_trampoline (mono_method_signature (method), method->string_ctor); - } else { - const char *name = method->name; - if (method->klass->parent == mono_defaults.multicastdelegate_class) { - if (*name == 'I' && (strcmp (name, "Invoke") == 0)) { - nm = mono_marshal_get_delegate_invoke (method); - } else if (*name == 'B' && (strcmp (name, "BeginInvoke") == 0)) { - nm = mono_marshal_get_delegate_begin_invoke (method); - } else if (*name == 'E' && (strcmp (name, "EndInvoke") == 0)) { - nm = mono_marshal_get_delegate_end_invoke (method); - } - } - if (nm == NULL) { - runtime_method->code = g_malloc(sizeof(short)); - runtime_method->code[0] = MINT_CALLRUN; - } - } - if (nm == NULL) { - runtime_method->stack_size = sizeof (stackval); /* for tracing */ - runtime_method->alloca_size = runtime_method->stack_size; - runtime_method->transformed = TRUE; - mono_mutex_unlock(&calc_section); - mono_profiler_method_end_jit (method, MONO_PROFILE_OK); - return NULL; - } - method = nm; - header = mono_method_get_header (nm); - mono_mutex_unlock(&calc_section); - } - g_assert ((signature->param_count + signature->hasthis) < 1000); - g_assert (header->max_stack < 10000); - /* intern the strings in the method. */ - ip = header->code; - end = ip + header->code_size; - - is_bb_start = g_malloc0(header->code_size); - is_bb_start [0] = 1; - while (ip < end) { - in = *ip; - if (in == 0xfe) { - ip++; - in = *ip + 256; - } - else if (in == 0xf0) { - ip++; - in = *ip + MONO_CEE_MONO_ICALL; - } - opcode = &mono_opcodes [in]; - switch (opcode->argument) { - case MonoInlineNone: - ++ip; - break; - case MonoInlineString: - if (method->wrapper_type == MONO_WRAPPER_NONE) - mono_ldstr (domain, image, mono_metadata_token_index (read32 (ip + 1))); - ip += 5; - break; - case MonoInlineType: - if (method->wrapper_type == MONO_WRAPPER_NONE) { - class = mono_class_get_full (image, read32 (ip + 1), generic_context); - mono_class_init (class); - /* quick fix to not do this for the fake ptr classes - probably should not be getting the vtable at all here */ - if (!(class->flags & TYPE_ATTRIBUTE_INTERFACE) && class->interface_offsets != NULL) - mono_class_vtable (domain, class); - } - ip += 5; - break; - case MonoInlineMethod: - if (method->wrapper_type == MONO_WRAPPER_NONE && *ip != CEE_CALLI) { - m = mono_get_method_full (image, read32 (ip + 1), NULL, generic_context); - if (m == NULL) { - g_free (is_bb_start); - return mono_get_exception_missing_method (); - } - mono_class_init (m->klass); - if (!(m->klass->flags & TYPE_ATTRIBUTE_INTERFACE)) - mono_class_vtable (domain, m->klass); - } - ip += 5; - break; - case MonoInlineField: - case MonoInlineSig: - case MonoInlineI: - case MonoInlineTok: - case MonoShortInlineR: - ip += 5; - break; - case MonoInlineBrTarget: - offset = read32 (ip + 1); - ip += 5; - backwards = offset < 0; - offset += ip - header->code; - g_assert (offset >= 0 && offset < header->code_size); - is_bb_start [offset] |= backwards ? 2 : 1; - break; - case MonoShortInlineBrTarget: - offset = ((gint8 *)ip) [1]; - ip += 2; - backwards = offset < 0; - offset += ip - header->code; - g_assert (offset >= 0 && offset < header->code_size); - is_bb_start [offset] |= backwards ? 2 : 1; - break; - case MonoInlineVar: - ip += 3; - break; - case MonoShortInlineVar: - case MonoShortInlineI: - ip += 2; - break; - case MonoInlineSwitch: { - guint32 n; - const unsigned char *next_ip; - ++ip; - n = read32 (ip); - ip += 4; - next_ip = ip + 4 * n; - for (i = 0; i < n; i++) { - offset = read32 (ip); - backwards = offset < 0; - offset += next_ip - header->code; - g_assert (offset >= 0 && offset < header->code_size); - is_bb_start [offset] |= backwards ? 2 : 1; - ip += 4; - } - break; - } - case MonoInlineR: - case MonoInlineI8: - ip += 9; - break; - default: - g_assert_not_reached (); - } - } - - /* the rest needs to be locked so it is only done once */ - mono_mutex_lock(&calc_section); - if (runtime_method->transformed) { - mono_mutex_unlock(&calc_section); - g_free (is_bb_start); - mono_profiler_method_end_jit (method, MONO_PROFILE_OK); - return NULL; - } - - runtime_method->local_offsets = g_malloc (header->num_locals * sizeof(guint32)); - runtime_method->stack_size = (sizeof (stackval) + 2) * header->max_stack; /* + 1 for returns of called functions + 1 for 0-ing in trace*/ - runtime_method->stack_size = (runtime_method->stack_size + 7) & ~7; - offset = 0; - for (i = 0; i < header->num_locals; ++i) { - size = mono_type_size (header->locals [i], &align); - offset += align - 1; - offset &= ~(align - 1); - runtime_method->local_offsets [i] = offset; - offset += size; - } - offset = (offset + 7) & ~7; - runtime_method->locals_size = offset; - g_assert (runtime_method->locals_size < 65536); - offset = 0; - runtime_method->arg_offsets = g_malloc(signature->param_count * sizeof(guint32)); - for (i = 0; i < signature->param_count; ++i) { - if (signature->pinvoke) { - size = mono_type_native_stack_size (signature->params [i], &align); - align = 8; - } - else - size = mono_type_stack_size (signature->params [i], &align); - offset += align - 1; - offset &= ~(align - 1); - runtime_method->arg_offsets [i] = offset; - offset += size; - } - offset = (offset + 7) & ~7; - runtime_method->args_size = offset; - g_assert (runtime_method->args_size < 10000); - - generate(method, runtime_method, is_bb_start); - - g_free (is_bb_start); - - mono_profiler_method_end_jit (method, MONO_PROFILE_OK); - runtime_method->transformed = TRUE; - mono_mutex_unlock(&calc_section); - - return NULL; -} - diff --git a/mono/metadata/Makefile.am b/mono/metadata/Makefile.am index 5aa44a4acca..bfa08c4d39c 100644 --- a/mono/metadata/Makefile.am +++ b/mono/metadata/Makefile.am @@ -342,4 +342,4 @@ endif endif EXTRA_DIST = make-bundle.pl sample-bundle $(win32_sources) $(unix_sources) $(null_sources) runtime.h \ - tpool-poll.c tpool-epoll.c tpool-kqueue.c Makefile.am.in + tpool-poll.c tpool-epoll.c tpool-kqueue.c diff --git a/mono/metadata/class-internals.h b/mono/metadata/class-internals.h index ab4a5cb5789..32b5ef4561e 100644 --- a/mono/metadata/class-internals.h +++ b/mono/metadata/class-internals.h @@ -1228,13 +1228,9 @@ MONO_API MonoGenericContainer * mono_metadata_load_generic_params (MonoImage *image, guint32 token, MonoGenericContainer *parent_container); -MONO_API void -mono_metadata_load_generic_param_constraints (MonoImage *image, guint32 token, - MonoGenericContainer *container); - -gboolean -mono_metadata_load_generic_param_constraints_full (MonoImage *image, guint32 token, - MonoGenericContainer *container) MONO_INTERNAL; +MONO_API gboolean +mono_metadata_load_generic_param_constraints_checked (MonoImage *image, guint32 token, + MonoGenericContainer *container, MonoError *error); MonoMethodSignature* mono_create_icall_signature (const char *sigstr) MONO_INTERNAL; @@ -1298,7 +1294,7 @@ MONO_API gboolean mono_class_is_valid_enum (MonoClass *klass); MonoType * -mono_type_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *context) MONO_INTERNAL; +mono_type_get_checked (MonoImage *image, guint32 type_token, MonoGenericContext *context, MonoError *error) MONO_INTERNAL; gboolean mono_generic_class_is_generic_type_definition (MonoGenericClass *gklass) MONO_INTERNAL; @@ -1386,4 +1382,16 @@ mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bfla char* mono_class_full_name (MonoClass *klass) MONO_INTERNAL; +MonoClass* +mono_class_inflate_generic_class_checked (MonoClass *gklass, MonoGenericContext *context, MonoError *error) MONO_INTERNAL; + +MonoClass * +mono_class_get_checked (MonoImage *image, guint32 type_token, MonoError *error) MONO_INTERNAL; + +MonoClass * +mono_class_get_and_inflate_typespec_checked (MonoImage *image, guint32 type_token, MonoGenericContext *context, MonoError *error) MONO_INTERNAL; + +MonoClass * +mono_class_from_name_case_checked (MonoImage *image, const char* name_space, const char *name, MonoError *error) MONO_INTERNAL; + #endif /* __MONO_METADATA_CLASS_INTERBALS_H__ */ diff --git a/mono/metadata/class.c b/mono/metadata/class.c index 21e026a59d3..ec4c2285739 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -166,17 +166,25 @@ MonoClass * mono_class_from_typeref (MonoImage *image, guint32 type_token) { MonoError error; + MonoClass *class = mono_class_from_typeref_checked (image, type_token, &error); + g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/ + return class; +} + +MonoClass * +mono_class_from_typeref_checked (MonoImage *image, guint32 type_token, MonoError *error) +{ guint32 cols [MONO_TYPEREF_SIZE]; MonoTableInfo *t = &image->tables [MONO_TABLE_TYPEREF]; guint32 idx; const char *name, *nspace; - MonoClass *res; + MonoClass *res = NULL; MonoImage *module; - if (!mono_verifier_verify_typeref_row (image, (type_token & 0xffffff) - 1, &error)) { - mono_trace_warning (MONO_TRACE_TYPE, "Failed to resolve typeref from %s due to '%s'", image->name, mono_error_get_message (&error)); + mono_error_init (error); + + if (!mono_verifier_verify_typeref_row (image, (type_token & 0xffffff) - 1, error)) return NULL; - } mono_metadata_decode_row (t, (type_token&0xffffff)-1, cols, MONO_TYPEREF_SIZE); @@ -192,33 +200,26 @@ mono_class_from_typeref (MonoImage *image, guint32 type_token) The defacto behavior is that it's just a typedef in disguise. */ /* a typedef in disguise */ - return mono_class_from_name (image, nspace, name); + res = mono_class_from_name (image, nspace, name); /*FIXME proper error handling*/ + goto done; + case MONO_RESOLTION_SCOPE_MODULEREF: module = mono_image_load_module (image, idx); if (module) - return mono_class_from_name (module, nspace, name); - else { - char *msg = g_strdup_printf ("%s%s%s", nspace, nspace [0] ? "." : "", name); - char *human_name; - - human_name = mono_stringify_assembly_name (&image->assembly->aname); - mono_loader_set_error_type_load (msg, human_name); - g_free (msg); - g_free (human_name); - - return NULL; - } + res = mono_class_from_name (module, nspace, name); /*FIXME proper error handling*/ + goto done; + case MONO_RESOLTION_SCOPE_TYPEREF: { MonoClass *enclosing; GList *tmp; if (idx == mono_metadata_token_index (type_token)) { - mono_loader_set_error_bad_image (g_strdup_printf ("Image %s with self-referencing typeref token %08x.", image->name, type_token)); + mono_error_set_bad_image (error, image, "Image with self-referencing typeref token %08x.", type_token); return NULL; } - enclosing = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | idx); - if (!enclosing) + enclosing = mono_class_from_typeref_checked (image, MONO_TOKEN_TYPE_REF | idx, error); + if (!mono_error_ok (error)) return NULL; if (enclosing->nested_classes_inited && enclosing->ext) { @@ -236,28 +237,21 @@ mono_class_from_typeref (MonoImage *image, guint32 type_token) guint32 string_offset = mono_metadata_decode_row_col (&enclosing->image->tables [MONO_TABLE_TYPEDEF], class_nested - 1, MONO_TYPEDEF_NAME); const char *nname = mono_metadata_string_heap (enclosing->image, string_offset); - if (strcmp (nname, name) == 0) { - MonoClass *res = mono_class_create_from_typedef (enclosing->image, MONO_TOKEN_TYPE_DEF | class_nested, &error); - if (!mono_error_ok (&error)) { - mono_loader_set_error_from_mono_error (&error); - mono_error_cleanup (&error); /*FIXME don't swallow error message.*/ - return NULL; - } - return res; - } + if (strcmp (nname, name) == 0) + return mono_class_create_from_typedef (enclosing->image, MONO_TOKEN_TYPE_DEF | class_nested, error); i = mono_metadata_nesting_typedef (enclosing->image, enclosing->type_token, i + 1); } } g_warning ("TypeRef ResolutionScope not yet handled (%d) for %s.%s in image %s", idx, nspace, name, image->name); - return NULL; + goto done; } case MONO_RESOLTION_SCOPE_ASSEMBLYREF: break; } if (idx > image->tables [MONO_TABLE_ASSEMBLYREF].rows) { - mono_loader_set_error_bad_image (g_strdup_printf ("Image %s with invalid assemblyref token %08x.", image->name, idx)); + mono_error_set_bad_image (error, image, "Image with invalid assemblyref token %08x.", idx); return NULL; } @@ -272,13 +266,20 @@ mono_class_from_typeref (MonoImage *image, guint32 type_token) mono_assembly_get_assemblyref (image, idx - 1, &aname); human_name = mono_stringify_assembly_name (&aname); - mono_loader_set_error_assembly_load (human_name, image->assembly ? image->assembly->ref_only : FALSE); - g_free (human_name); - + mono_error_set_assembly_load_simple (error, human_name, image->assembly ? image->assembly->ref_only : FALSE); return NULL; } - return mono_class_from_name (image->references [idx - 1]->image, nspace, name); + res = mono_class_from_name (image->references [idx - 1]->image, nspace, name); + +done: + /* Generic case, should be avoided for when a better error is possible. */ + if (!res && mono_error_ok (error)) { + char *name = mono_class_name_from_token (image, type_token); + char *assembly = mono_assembly_name_from_token (image, type_token); + mono_error_set_type_load_name (error, name, assembly, "Could not resolve type with token %08x", type_token); + } + return res; } @@ -893,7 +894,7 @@ mono_class_inflate_generic_type_no_copy (MonoImage *image, MonoType *type, MonoG return inflated; } -static MonoClass* +MonoClass* mono_class_inflate_generic_class_checked (MonoClass *gklass, MonoGenericContext *context, MonoError *error) { MonoClass *res; @@ -1258,7 +1259,7 @@ mono_method_set_generic_container (MonoMethod *method, MonoGenericContainer* con * in a separate function since it is cheaper than calling mono_class_setup_fields. */ static MonoType* -mono_class_find_enum_basetype (MonoClass *class) +mono_class_find_enum_basetype (MonoClass *class, MonoError *error) { MonoGenericContainer *container = NULL; MonoImage *m = class->image; @@ -1267,6 +1268,8 @@ mono_class_find_enum_basetype (MonoClass *class) g_assert (class->enumtype); + mono_error_init (error); + if (class->generic_container) container = class->generic_container; else if (class->generic_class) { @@ -1291,27 +1294,41 @@ mono_class_find_enum_basetype (MonoClass *class) if (cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_STATIC) //no need to decode static fields continue; - if (!mono_verifier_verify_field_signature (class->image, cols [MONO_FIELD_SIGNATURE], NULL)) - return NULL; + if (!mono_verifier_verify_field_signature (class->image, cols [MONO_FIELD_SIGNATURE], NULL)) { + mono_error_set_bad_image (error, class->image, "Invalid field signature %x", cols [MONO_FIELD_SIGNATURE]); + goto fail; + } sig = mono_metadata_blob_heap (m, cols [MONO_FIELD_SIGNATURE]); mono_metadata_decode_value (sig, &sig); /* FIELD signature == 0x06 */ - if (*sig != 0x06) - return NULL; + if (*sig != 0x06) { + mono_error_set_bad_image (error, class->image, "Invalid field signature %x, expected 0x6 but got %x", cols [MONO_FIELD_SIGNATURE], *sig); + goto fail; + } ftype = mono_metadata_parse_type_full (m, container, MONO_PARSE_FIELD, cols [MONO_FIELD_FLAGS], sig + 1, &sig); - if (!ftype) - return NULL; + if (!ftype) { + if (mono_loader_get_last_error ()) /*FIXME plug the above to not leak errors*/ + mono_error_set_from_loader_error (error); + else + mono_error_set_bad_image (error, class->image, "Could not parse type for field signature %x", cols [MONO_FIELD_SIGNATURE]); + goto fail; + } if (class->generic_class) { //FIXME do we leak here? - ftype = mono_class_inflate_generic_type (ftype, mono_class_get_context (class)); + ftype = mono_class_inflate_generic_type_checked (ftype, mono_class_get_context (class), error); + if (!mono_error_ok (error)) + goto fail; ftype->attrs = cols [MONO_FIELD_FLAGS]; } return ftype; } + mono_error_set_type_load_class (error, class, "Could not find base type"); +fail: + g_assert (!mono_loader_get_last_error ()); return NULL; } @@ -5681,10 +5698,12 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError class->byval_arg.data.klass = class; class->byval_arg.type = MONO_TYPE_CLASS; } - parent = mono_class_get_full (image, parent_token, context); + parent = mono_class_get_checked (image, parent_token, error); + if (parent && context) /* Always inflate */ + parent = mono_class_inflate_generic_class_checked (parent, context, error); if (parent == NULL) { - mono_class_set_failure_from_loader_error (class, error, g_strdup_printf ("Could not load parent, token is %x", parent_token)); + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup (mono_error_get_message (error))); goto parent_failure; } @@ -5783,11 +5802,11 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError } if (class->enumtype) { - MonoType *enum_basetype = mono_class_find_enum_basetype (class); + MonoType *enum_basetype = mono_class_find_enum_basetype (class, error); if (!enum_basetype) { /*set it to a default value as the whole runtime can't handle this to be null*/ class->cast_class = class->element_class = mono_defaults.int32_class; - mono_class_set_failure_and_error (class, error, "Could not enum basetype"); + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup (mono_error_get_message (error))); mono_loader_unlock (); mono_profiler_class_loaded (class, MONO_PROFILE_FAILED); g_assert (!mono_loader_get_last_error ()); @@ -5801,8 +5820,8 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError * We must do this after the class has been constructed to make certain recursive scenarios * work. */ - if (class->generic_container && !mono_metadata_load_generic_param_constraints_full (image, type_token, class->generic_container)){ - mono_class_set_failure_from_loader_error (class, error, g_strdup ("Could not load generic parameter constraints")); + if (class->generic_container && !mono_metadata_load_generic_param_constraints_checked (image, type_token, class->generic_container, error)) { + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, g_strdup_printf ("Could not load generic parameter constrains due to %s", mono_error_get_message (error))); mono_loader_unlock (); mono_profiler_class_loaded (class, MONO_PROFILE_FAILED); g_assert (!mono_loader_get_last_error ()); @@ -6355,23 +6374,20 @@ mono_class_from_mono_type (MonoType *type) static MonoType * mono_type_retrieve_from_typespec (MonoImage *image, guint32 type_spec, MonoGenericContext *context, gboolean *did_inflate, MonoError *error) { - MonoType *t = mono_type_create_from_typespec (image, type_spec); + MonoType *t = mono_type_create_from_typespec_checked (image, type_spec, error); - mono_error_init (error); *did_inflate = FALSE; - if (!t) { - char *name = mono_class_name_from_token (image, type_spec); - char *assembly = mono_assembly_name_from_token (image, type_spec); - mono_error_set_type_load_name (error, name, assembly, "Could not resolve typespec token %08x", type_spec); + if (!t) return NULL; - } if (context && (context->class_inst || context->method_inst)) { MonoType *inflated = inflate_generic_type (NULL, t, context, error); - if (!mono_error_ok (error)) + if (!mono_error_ok (error)) { + g_assert (!mono_loader_get_last_error ()); return NULL; + } if (inflated) { t = inflated; @@ -7118,6 +7134,7 @@ mono_assembly_name_from_token (MonoImage *image, guint32 type_token) * @image: the image where the class resides * @type_token: the token for the class * @context: the generic context used to evaluate generic instantiations in + * @deprecated: Functions that expose MonoGenericContext are going away in mono 4.0 * * Returns: the MonoClass that represents @type_token in @image */ @@ -7125,49 +7142,79 @@ MonoClass * mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *context) { MonoError error; + MonoClass *class; + class = mono_class_get_checked (image, type_token, &error); + + if (class && context && mono_metadata_token_table (type_token) == MONO_TABLE_TYPESPEC) + class = mono_class_inflate_generic_class_checked (class, context, &error); + + if (!class) { + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /*FIXME don't swallow this error */ + } + return class; +} + + +MonoClass * +mono_class_get_and_inflate_typespec_checked (MonoImage *image, guint32 type_token, MonoGenericContext *context, MonoError *error) +{ + MonoClass *class; + + mono_error_init (error); + class = mono_class_get_checked (image, type_token, error); + + if (class && context && mono_metadata_token_table (type_token) == MONO_TABLE_TYPESPEC) + class = mono_class_inflate_generic_class_checked (class, context, error); + + return class; +} +/** + * mono_class_get_checked: + * @image: the image where the class resides + * @type_token: the token for the class + * @error: error object to return any error + * + * Returns: the MonoClass that represents @type_token in @image + */ +MonoClass * +mono_class_get_checked (MonoImage *image, guint32 type_token, MonoError *error) +{ MonoClass *class = NULL; + mono_error_init (error); + if (image_is_dynamic (image)) { int table = mono_metadata_token_table (type_token); if (table != MONO_TABLE_TYPEDEF && table != MONO_TABLE_TYPEREF && table != MONO_TABLE_TYPESPEC) { - mono_loader_set_error_bad_image (g_strdup ("Bad type token.")); + mono_error_set_bad_image (error, image,"Bad token table for dynamic image: %x", table); return NULL; } - return mono_lookup_dynamic_token (image, type_token, context); + class = mono_lookup_dynamic_token (image, type_token, NULL); /*FIXME proper error handling*/ + goto done; } switch (type_token & 0xff000000){ case MONO_TOKEN_TYPE_DEF: - class = mono_class_create_from_typedef (image, type_token, &error); - if (!mono_error_ok (&error)) { - mono_loader_set_error_from_mono_error (&error); - /*FIXME don't swallow the error message*/ - mono_error_cleanup (&error); - return NULL; - } + class = mono_class_create_from_typedef (image, type_token, error); break; case MONO_TOKEN_TYPE_REF: - class = mono_class_from_typeref (image, type_token); + class = mono_class_from_typeref_checked (image, type_token, error); break; case MONO_TOKEN_TYPE_SPEC: - class = mono_class_create_from_typespec (image, type_token, context, &error); - if (!mono_error_ok (&error)) { - /*FIXME don't swallow the error message*/ - mono_error_cleanup (&error); - } + class = mono_class_create_from_typespec (image, type_token, NULL, error); break; default: - g_warning ("unknown token type %x", type_token & 0xff000000); - g_assert_not_reached (); + mono_error_set_bad_image (error, image, "Unknown type token %x", type_token & 0xff000000); } - if (!class){ +done: + /* Generic case, should be avoided for when a better error is possible. */ + if (!class && mono_error_ok (error)) { char *name = mono_class_name_from_token (image, type_token); char *assembly = mono_assembly_name_from_token (image, type_token); - mono_loader_set_error_type_load (name, assembly); - g_free (name); - g_free (assembly); + mono_error_set_type_load_name (error, name, assembly, "Could not resolve type with token %08x", type_token); } return class; @@ -7175,42 +7222,44 @@ mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *c /** - * mono_type_get_full: + * mono_type_get_checked: * @image: the image where the type resides * @type_token: the token for the type * @context: the generic context used to evaluate generic instantiations in + * @error: Error handling context * * This functions exists to fullfill the fact that sometimes it's desirable to have access to the * * Returns: the MonoType that represents @type_token in @image */ MonoType * -mono_type_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *context) +mono_type_get_checked (MonoImage *image, guint32 type_token, MonoGenericContext *context, MonoError *error) { - MonoError error; MonoType *type = NULL; gboolean inflated = FALSE; + mono_error_init (error); + //FIXME: this will not fix the very issue for which mono_type_get_full exists -but how to do it then? if (image_is_dynamic (image)) return mono_class_get_type (mono_lookup_dynamic_token (image, type_token, context)); if ((type_token & 0xff000000) != MONO_TOKEN_TYPE_SPEC) { - MonoClass *class = mono_class_get_full (image, type_token, context); - return class ? mono_class_get_type (class) : NULL; - } + MonoClass *class = mono_class_get_checked (image, type_token, error); - type = mono_type_retrieve_from_typespec (image, type_token, context, &inflated, &error); + if (!class) { + g_assert (!mono_loader_get_last_error ()); + return NULL; + } - if (!mono_error_ok (&error)) { - /*FIXME don't swalloc the error message.*/ - char *name = mono_class_name_from_token (image, type_token); - char *assembly = mono_assembly_name_from_token (image, type_token); + g_assert (class); + return mono_class_get_type (class); + } - g_warning ("Error loading type %s from %s due to %s", name, assembly, mono_error_get_message (&error)); + type = mono_type_retrieve_from_typespec (image, type_token, context, &inflated, error); - mono_error_cleanup (&error); - mono_loader_set_error_type_load (name, assembly); + if (!type) { + g_assert (!mono_loader_get_last_error ()); return NULL; } @@ -7370,6 +7419,7 @@ find_nocase (gpointer key, gpointer value, gpointer user_data) * @image: The MonoImage where the type is looked up in * @name_space: the type namespace * @name: the type short name. + * @deprecated: use the _checked variant * * Obtains a MonoClass with a given namespace and a given name which * is located in the given MonoImage. The namespace and name @@ -7377,6 +7427,15 @@ find_nocase (gpointer key, gpointer value, gpointer user_data) */ MonoClass * mono_class_from_name_case (MonoImage *image, const char* name_space, const char *name) +{ + MonoError error; + MonoClass *res = mono_class_from_name_case_checked (image, name_space, name, &error); + g_assert (!mono_error_ok (&error)); + return res; +} + +MonoClass * +mono_class_from_name_case_checked (MonoImage *image, const char* name_space, const char *name, MonoError *error) { MonoTableInfo *t = &image->tables [MONO_TABLE_TYPEDEF]; guint32 cols [MONO_TYPEDEF_SIZE]; @@ -7384,6 +7443,8 @@ mono_class_from_name_case (MonoImage *image, const char* name_space, const char const char *nspace; guint32 i, visib; + mono_error_init (error); + if (image_is_dynamic (image)) { guint32 token = 0; FindUserData user_data; @@ -7412,7 +7473,7 @@ mono_class_from_name_case (MonoImage *image, const char* name_space, const char mono_image_unlock (image); if (token) - return mono_class_get (image, MONO_TOKEN_TYPE_DEF | token); + return mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | token, error); else return NULL; @@ -7431,7 +7492,7 @@ mono_class_from_name_case (MonoImage *image, const char* name_space, const char n = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAME]); nspace = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]); if (mono_utf8_strcasecmp (n, name) == 0 && mono_utf8_strcasecmp (nspace, name_space) == 0) - return mono_class_get (image, MONO_TOKEN_TYPE_DEF | i); + return mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | i, error); } return NULL; } @@ -8305,26 +8366,34 @@ mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class, case MONO_TOKEN_TYPE_DEF: case MONO_TOKEN_TYPE_REF: case MONO_TOKEN_TYPE_SPEC: { + MonoError error; MonoType *type; if (handle_class) *handle_class = mono_defaults.typehandle_class; - type = mono_type_get_full (image, token, context); - if (!type) + type = mono_type_get_checked (image, token, context, &error); + if (!type) { + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /* FIXME Don't swallow the error */ return NULL; + } mono_class_init (mono_class_from_mono_type (type)); /* We return a MonoType* as handle */ return type; } case MONO_TOKEN_FIELD_DEF: { MonoClass *class; + MonoError error; guint32 type = mono_metadata_typedef_from_field (image, mono_metadata_token_index (token)); if (!type) return NULL; if (handle_class) *handle_class = mono_defaults.fieldhandle_class; - class = mono_class_get_full (image, MONO_TOKEN_TYPE_DEF | type, context); - if (!class) + class = mono_class_get_and_inflate_typespec_checked (image, MONO_TOKEN_TYPE_DEF | type, context, &error); + if (!class) { + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /* FIXME Don't swallow the error */ return NULL; + } mono_class_init (class); return mono_class_get_field (class, token); } diff --git a/mono/metadata/class.h b/mono/metadata/class.h index a65bd4565e9..d9f315139b1 100644 --- a/mono/metadata/class.h +++ b/mono/metadata/class.h @@ -4,6 +4,7 @@ #include #include #include +#include MONO_BEGIN_DECLS @@ -37,6 +38,9 @@ mono_class_get_method_from_name_flags (MonoClass *klass, const char *name, int p MONO_API MonoClass * mono_class_from_typeref (MonoImage *image, uint32_t type_token); +MONO_API MonoClass * +mono_class_from_typeref_checked (MonoImage *image, uint32_t type_token, MonoError *error); + MONO_API MonoClass * mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, mono_bool is_mvar); diff --git a/mono/metadata/exception.c b/mono/metadata/exception.c index 24bfd6ed5ba..cf42445fa78 100644 --- a/mono/metadata/exception.c +++ b/mono/metadata/exception.c @@ -87,10 +87,12 @@ mono_exception_from_name_domain (MonoDomain *domain, MonoImage *image, MonoException * mono_exception_from_token (MonoImage *image, guint32 token) { + MonoError error; MonoClass *klass; MonoObject *o; - klass = mono_class_get (image, token); + klass = mono_class_get_checked (image, token, &error); + g_assert (mono_error_ok (&error)); /* FIXME handle the error. */ o = mono_object_new (mono_domain_get (), klass); g_assert (o != NULL); @@ -197,7 +199,9 @@ MonoException * mono_exception_from_token_two_strings (MonoImage *image, guint32 token, MonoString *a1, MonoString *a2) { - MonoClass *klass = mono_class_get (image, token); + MonoError error; + MonoClass *klass = mono_class_get_checked (image, token, &error); + g_assert (mono_error_ok (&error)); /* FIXME handle the error. */ return create_exception_two_strings (klass, a1, a2); } diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index ddec8e43053..763b2f638bf 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -907,11 +907,12 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (Mo ICALL_EXPORT void ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image) { - MONO_ARCH_SAVE_REGS; + MonoError error; mono_image_check_for_module_cctor (image); if (image->has_module_cctor) { - MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1); + MonoClass *module_klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | 1, &error); + mono_error_raise_exception (&error); /*It's fine to raise the exception here*/ mono_runtime_class_init (mono_class_vtable_full (mono_domain_get (), module_klass, TRUE)); } @@ -1673,8 +1674,7 @@ ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *fie { MonoError error; MonoType *type = mono_field_get_type_checked (field->field, &error); - if (!mono_error_ok (&error)) - mono_error_raise_exception (&error); + mono_error_raise_exception (&error); return type_array_from_modifiers (field->field->parent->image, type, optional); } @@ -5161,21 +5161,16 @@ mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArray **excepti attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS); visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK; if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) { - klass = mono_class_get (image, (i + 1) | MONO_TOKEN_TYPE_DEF); + MonoError error; + klass = mono_class_get_checked (image, (i + 1) | MONO_TOKEN_TYPE_DEF, &error); + g_assert (!mono_loader_get_last_error ()); /* Plug any leaks */ + if (klass) { mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg)); } else { - MonoLoaderError *error; - MonoException *ex; - - error = mono_loader_get_last_error (); - g_assert (error != NULL); - - ex = mono_loader_error_prepare_exception (error); + MonoException *ex = mono_error_convert_to_exception (&error); mono_array_setref (*exceptions, count, ex); } - if (mono_loader_get_last_error ()) - mono_loader_clear_error (); count++; } } @@ -5266,7 +5261,7 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, mono_loader_clear_error (); exl = mono_array_new (domain, mono_defaults.exception_class, length); - /* Types for which mono_class_get () succeeded */ + /* Types for which mono_class_get_checked () succeeded */ for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) { MonoException *exc = mono_class_get_exception_for_failure (tmp->data); mono_array_setref (exl, i, exc); @@ -5321,6 +5316,7 @@ ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName * ICALL_EXPORT MonoReflectionType* ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module) { + MonoError error; MonoDomain *domain = mono_object_domain (module); MonoClass *klass; @@ -5332,7 +5328,8 @@ ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module) /* These images do not have a global type */ return NULL; - klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF); + klass = mono_class_get_checked (module->image, 1 | MONO_TOKEN_TYPE_DEF, &error); + mono_error_raise_exception (&error); return mono_type_get_object (domain, &klass->byval_arg); } @@ -5442,19 +5439,20 @@ init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_arg } ICALL_EXPORT MonoType* -ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error) +ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error) { MonoClass *klass; int table = mono_metadata_token_table (token); int index = mono_metadata_token_index (token); MonoGenericContext context; + MonoError error; - *error = ResolveTokenError_Other; + *resolve_error = ResolveTokenError_Other; /* Validate token */ if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) && (table != MONO_TABLE_TYPESPEC)) { - *error = ResolveTokenError_BadTable; + *resolve_error = ResolveTokenError_BadTable; return NULL; } @@ -5470,15 +5468,15 @@ ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 t } if ((index <= 0) || (index > image->tables [table].rows)) { - *error = ResolveTokenError_OutOfRange; + *resolve_error = ResolveTokenError_OutOfRange; return NULL; } init_generic_context_from_args (&context, type_args, method_args); - klass = mono_class_get_full (image, token, &context); - - if (mono_loader_get_last_error ()) - mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ())); + klass = mono_class_get_checked (image, token, &error); + if (klass) + klass = mono_class_inflate_generic_class_checked (klass, &context, &error); + mono_error_raise_exception (&error); if (klass) return &klass->byval_arg; @@ -7415,6 +7413,8 @@ ves_icall_System_Char_GetDataTablePointers (int category_data_version, /* * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes * and avoid useless allocations. + * + * MAY THROW */ static MonoArray* type_array_from_modifiers (MonoImage *image, MonoType *type, int optional) @@ -7431,7 +7431,9 @@ type_array_from_modifiers (MonoImage *image, MonoType *type, int optional) count = 0; for (i = 0; i < type->num_mods; ++i) { if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) { - MonoClass *klass = mono_class_get (image, type->modifiers [i].token); + MonoError error; + MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, &error); + mono_error_raise_exception (&error); /* this is safe, no cleanup needed on callers */ mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg)); count++; } diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index 0f0ab038e96..09ea19b3d79 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -436,6 +436,7 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass, const char *fname; const char *ptr; guint32 idx = mono_metadata_token_index (token); + MonoError error; mono_metadata_decode_row (&tables [MONO_TABLE_MEMBERREF], idx-1, cols, MONO_MEMBERREF_SIZE); nindex = cols [MONO_MEMBERREF_CLASS] >> MONO_MEMBERREF_PARENT_BITS; @@ -451,15 +452,29 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass, switch (class) { case MONO_MEMBERREF_PARENT_TYPEDEF: class_table = MONO_TOKEN_TYPE_DEF; - klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | nindex); + klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | nindex, &error); + if (!mono_error_ok (&error)) { + /*FIXME don't swallow the error message*/ + mono_error_cleanup (&error); + } + break; case MONO_MEMBERREF_PARENT_TYPEREF: class_table = MONO_TOKEN_TYPE_REF; - klass = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | nindex); + klass = mono_class_from_typeref_checked (image, MONO_TOKEN_TYPE_REF | nindex, &error); + if (!mono_error_ok (&error)) { + /*FIXME don't swallow the error message*/ + mono_error_cleanup (&error); + } + break; case MONO_MEMBERREF_PARENT_TYPESPEC: class_table = MONO_TOKEN_TYPE_SPEC; - klass = mono_class_get_full (image, MONO_TOKEN_TYPE_SPEC | nindex, context); + klass = mono_class_get_and_inflate_typespec_checked (image, MONO_TOKEN_TYPE_SPEC | nindex, context, &error); + if (!mono_error_ok (&error)) { + /*FIXME don't swallow the error message*/ + mono_error_cleanup (&error); + } break; default: /*FIXME this must set a loader error!*/ @@ -512,6 +527,7 @@ MonoClassField* mono_field_from_token (MonoImage *image, guint32 token, MonoClass **retklass, MonoGenericContext *context) { + MonoError error; MonoClass *k; guint32 type; MonoClassField *field; @@ -542,9 +558,12 @@ mono_field_from_token (MonoImage *image, guint32 token, MonoClass **retklass, type = mono_metadata_typedef_from_field (image, mono_metadata_token_index (token)); if (!type) return NULL; - k = mono_class_get (image, MONO_TOKEN_TYPE_DEF | type); - if (!k) + k = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | type, &error); + if (!k) { + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /*FIXME don't swallow the error message*/ return NULL; + } mono_class_init (k); if (retklass) *retklass = k; @@ -940,6 +959,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp const char *mname; MonoMethodSignature *sig; const char *ptr; + MonoError error; mono_metadata_decode_row (&tables [MONO_TABLE_MEMBERREF], idx-1, cols, 3); nindex = cols [MONO_MEMBERREF_CLASS] >> MONO_MEMBERREF_PARENT_BITS; @@ -959,12 +979,10 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp switch (class) { case MONO_MEMBERREF_PARENT_TYPEREF: - klass = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | nindex); + klass = mono_class_from_typeref_checked (image, MONO_TOKEN_TYPE_REF | nindex, &error); if (!klass) { - char *name = mono_class_name_from_token (image, MONO_TOKEN_TYPE_REF | nindex); - g_warning ("Missing method %s in assembly %s, type %s", mname, image->name, name); - mono_loader_set_error_type_load (name, image->assembly_name); - g_free (name); + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /* FIXME Don't swallow the error */ return NULL; } break; @@ -972,22 +990,18 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp /* * Parse the TYPESPEC in the parent's context. */ - klass = mono_class_get_full (image, MONO_TOKEN_TYPE_SPEC | nindex, typespec_context); + klass = mono_class_get_and_inflate_typespec_checked (image, MONO_TOKEN_TYPE_SPEC | nindex, typespec_context, &error); if (!klass) { - char *name = mono_class_name_from_token (image, MONO_TOKEN_TYPE_SPEC | nindex); - g_warning ("Missing method %s in assembly %s, type %s", mname, image->name, name); - mono_loader_set_error_type_load (name, image->assembly_name); - g_free (name); + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /*FIXME don't swallow the error message*/ return NULL; } break; case MONO_MEMBERREF_PARENT_TYPEDEF: - klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | nindex); + klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | nindex, &error); if (!klass) { - char *name = mono_class_name_from_token (image, MONO_TOKEN_TYPE_DEF | nindex); - g_warning ("Missing method %s in assembly %s, type %s", mname, image->name, name); - mono_loader_set_error_type_load (name, image->assembly_name); - g_free (name); + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /*FIXME don't swallow the error message*/ return NULL; } break; @@ -1677,6 +1691,7 @@ static MonoMethod * mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass, MonoGenericContext *context, gboolean *used_context) { + MonoError error; MonoMethod *result; int table = mono_metadata_token_table (token); int idx = mono_metadata_token_index (token); @@ -1718,6 +1733,18 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass, return NULL; } + if (!klass) { + guint32 type = mono_metadata_typedef_from_method (image, token); + if (!type) + return NULL; + klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | type, &error); + if (klass == NULL) { + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /*FIXME don't swallow the error message*/ + return NULL; + } + } + mono_metadata_decode_row (&image->tables [MONO_TABLE_METHOD], idx - 1, cols, 6); if ((cols [2] & METHOD_ATTRIBUTE_PINVOKE_IMPL) || @@ -1730,15 +1757,6 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass, mono_stats.method_count ++; - if (!klass) { /*FIXME put this before the image alloc*/ - guint32 type = mono_metadata_typedef_from_method (image, token); - if (!type) - return NULL; - klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | type); - if (klass == NULL) - return NULL; - } - result->slot = -1; result->klass = klass; result->flags = cols [2]; @@ -1759,11 +1777,15 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass, if (*sig & 0x10) generic_container = mono_metadata_load_generic_params (image, token, container); if (generic_container) { + MonoError error; result->is_generic = TRUE; generic_container->owner.method = result; /*FIXME put this before the image alloc*/ - if (!mono_metadata_load_generic_param_constraints_full (image, token, generic_container)) + if (!mono_metadata_load_generic_param_constraints_checked (image, token, generic_container, &error)) { + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /*FIXME don't swallow the error message*/ return NULL; + } container = generic_container; } diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index 88bbaeb7a02..0c8fe33f219 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -2739,6 +2739,7 @@ mono_wrapper_info_create (MonoMethodBuilder *mb, WrapperSubtype subtype) static MonoClass* get_wrapper_target_class (MonoImage *image) { + MonoError error; MonoClass *klass; /* @@ -2754,10 +2755,12 @@ get_wrapper_target_class (MonoImage *image) * To avoid these problems, we put the wrappers into the class of * the image. */ - if (image_is_dynamic (image)) + if (image_is_dynamic (image)) { klass = ((MonoDynamicImage*)image)->wrappers_type; - else - klass = mono_class_get (image, mono_metadata_make_token (MONO_TABLE_TYPEDEF, 1)); + } else { + klass = mono_class_get_checked (image, mono_metadata_make_token (MONO_TABLE_TYPEDEF, 1), &error); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ + } g_assert (klass); return klass; @@ -9490,8 +9493,9 @@ mono_marshal_set_callconv_from_modopt (MonoMethod *method, MonoMethodSignature * /* Why is this a modopt ? */ if (sig->ret && sig->ret->num_mods) { for (i = 0; i < sig->ret->num_mods; ++i) { - MonoClass *cmod_class = mono_class_get (method->klass->image, sig->ret->modifiers [i].token); - g_assert (cmod_class); + MonoError error; + MonoClass *cmod_class = mono_class_get_checked (method->klass->image, sig->ret->modifiers [i].token, &error); + g_assert (mono_error_ok (&error)); if ((cmod_class->image == mono_defaults.corlib) && !strcmp (cmod_class->name_space, "System.Runtime.CompilerServices")) { if (!strcmp (cmod_class->name, "CallConvCdecl")) csig->call_convention = MONO_CALL_C; diff --git a/mono/metadata/metadata-internals.h b/mono/metadata/metadata-internals.h index b04b811d123..c283b7aae36 100644 --- a/mono/metadata/metadata-internals.h +++ b/mono/metadata/metadata-internals.h @@ -800,6 +800,8 @@ MonoMethod *mono_get_method_constrained_with_method (MonoImage *image, MonoMetho void mono_type_set_alignment (MonoTypeEnum type, int align) MONO_INTERNAL; MonoAotCacheConfig *mono_get_aot_cache_config (void) MONO_INTERNAL; +MonoType * +mono_type_create_from_typespec_checked (MonoImage *image, guint32 type_spec, MonoError *error) MONO_INTERNAL; #endif /* __MONO_METADATA_INTERNALS_H__ */ diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c index 03cac47ce37..6b598020f03 100644 --- a/mono/metadata/metadata.c +++ b/mono/metadata/metadata.c @@ -3200,11 +3200,15 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer case MONO_TYPE_CLASS: { guint32 token; MonoClass *class; + MonoError error; token = mono_metadata_parse_typedef_or_ref (m, ptr, &ptr); - class = mono_class_get (m, token); + class = mono_class_get_checked (m, token, &error); type->data.klass = class; - if (!class) + if (!class) { + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /*FIXME don't swallow the error message*/ return FALSE; + } if (!compare_type_literals (class->byval_arg.type, type->type)) return FALSE; break; @@ -3377,7 +3381,16 @@ parse_section_data (MonoImage *m, int *num_clauses, const unsigned char *ptr) if (ec->flags == MONO_EXCEPTION_CLAUSE_FILTER) { ec->data.filter_offset = tof_value; } else if (ec->flags == MONO_EXCEPTION_CLAUSE_NONE) { - ec->data.catch_class = tof_value? mono_class_get (m, tof_value): 0; + ec->data.catch_class = NULL; + if (tof_value) { + MonoError error; + ec->data.catch_class = mono_class_get_checked (m, tof_value, &error); + if (!mono_error_ok (&error)) { + mono_error_cleanup (&error); /* FIXME don't swallow the error */ + g_free (clauses); + return NULL; + } + } } else { ec->data.catch_class = NULL; } @@ -3480,7 +3493,7 @@ mono_method_get_header_summary (MonoMethod *method, MonoMethodHeaderSummary *sum MonoMethodHeader * mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, const char *ptr) { - MonoMethodHeader *mh; + MonoMethodHeader *mh = NULL; unsigned char flags = *(const unsigned char *) ptr; unsigned char format = flags & METHOD_HEADER_FORMAT_MASK; guint16 fat_flags; @@ -3536,11 +3549,11 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons if (local_var_sig_tok) { int idx = (local_var_sig_tok & 0xffffff)-1; if (idx >= t->rows || idx < 0) - return NULL; + goto fail; mono_metadata_decode_row (t, idx, cols, 1); if (!mono_verifier_verify_standalone_signature (m, cols [MONO_STAND_ALONE_SIGNATURE], NULL)) - return NULL; + goto fail; } if (fat_flags & METHOD_HEADER_MORE_SECTS) clauses = parse_section_data (m, &num_clauses, (const unsigned char*)ptr); @@ -3559,11 +3572,8 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons for (i = 0; i < len; ++i) { mh->locals [i] = mono_metadata_parse_type_internal (m, container, MONO_PARSE_LOCAL, 0, TRUE, locals_ptr, &locals_ptr); - if (!mh->locals [i]) { - g_free (clauses); - g_free (mh); - return NULL; - } + if (!mh->locals [i]) + goto fail; } } else { mh = g_malloc0 (MONO_SIZEOF_METHOD_HEADER + num_clauses * sizeof (MonoExceptionClause)); @@ -3581,6 +3591,11 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons mh->num_clauses = num_clauses; } return mh; +fail: + g_free (clauses); + g_free (mh); + return NULL; + } /* @@ -4042,15 +4057,19 @@ mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, Mono pos = start; while (pos < tdef->rows) { + MonoError error; MonoClass *iface; mono_metadata_decode_row (tdef, pos, cols, MONO_INTERFACEIMPL_SIZE); if (cols [MONO_INTERFACEIMPL_CLASS] != loc.idx) break; - iface = mono_class_get_full ( - meta, mono_metadata_token_from_dor (cols [MONO_INTERFACEIMPL_INTERFACE]), context); - if (iface == NULL) + iface = mono_class_get_and_inflate_typespec_checked ( + meta, mono_metadata_token_from_dor (cols [MONO_INTERFACEIMPL_INTERFACE]), context, &error); + if (iface == NULL) { + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /* FIXME Don't swallow the error */ return FALSE; + } result [pos - start] = iface; ++pos; } @@ -5279,12 +5298,26 @@ mono_metadata_implmap_from_method (MonoImage *meta, guint32 method_idx) /** * @image: context where the image is created * @type_spec: typespec token + * @deprecated use mono_type_create_from_typespec_checked that has proper error handling * * Creates a MonoType representing the TypeSpec indexed by the @type_spec * token. */ MonoType * mono_type_create_from_typespec (MonoImage *image, guint32 type_spec) +{ + MonoError error; + MonoType *type = mono_type_create_from_typespec_checked (image, type_spec, &error); + if (!type) { + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /* FIXME don't swallow error*/ + } + return type; +} + +MonoType * +mono_type_create_from_typespec_checked (MonoImage *image, guint32 type_spec, MonoError *error) + { guint32 idx = mono_metadata_token_index (type_spec); MonoTableInfo *t; @@ -5293,6 +5326,8 @@ mono_type_create_from_typespec (MonoImage *image, guint32 type_spec) guint32 len; MonoType *type, *type2; + mono_error_init (error); + mono_image_lock (image); type = g_hash_table_lookup (image->typespec_cache, GUINT_TO_POINTER (type_spec)); mono_image_unlock (image); @@ -5304,14 +5339,21 @@ mono_type_create_from_typespec (MonoImage *image, guint32 type_spec) mono_metadata_decode_row (t, idx-1, cols, MONO_TYPESPEC_SIZE); ptr = mono_metadata_blob_heap (image, cols [MONO_TYPESPEC_SIGNATURE]); - if (!mono_verifier_verify_typespec_signature (image, cols [MONO_TYPESPEC_SIGNATURE], type_spec, NULL)) + if (!mono_verifier_verify_typespec_signature (image, cols [MONO_TYPESPEC_SIGNATURE], type_spec, NULL)) { + mono_error_set_bad_image (error, image, "Could not verify type spec %08x.", type_spec); return NULL; + } len = mono_metadata_decode_value (ptr, &ptr); type = mono_metadata_parse_type_internal (image, NULL, MONO_PARSE_TYPE, 0, TRUE, ptr, &ptr); - if (!type) + if (!type) { + if (mono_loader_get_last_error ()) + mono_error_set_from_loader_error (error); + else + mono_error_set_bad_image (error, image, "Could not parse type spec %08x.", type_spec); return NULL; + } type2 = mono_metadata_type_dup (image, type); mono_metadata_free_type (type); @@ -5772,7 +5814,7 @@ mono_guid_to_string (const guint8 *guid) } static gboolean -get_constraints (MonoImage *image, int owner, MonoClass ***constraints, MonoGenericContainer *container) +get_constraints (MonoImage *image, int owner, MonoClass ***constraints, MonoGenericContainer *container, MonoError *error) { MonoTableInfo *tdef = &image->tables [MONO_TABLE_GENERICPARAMCONSTRAINT]; guint32 cols [MONO_GENPARCONSTRAINT_SIZE]; @@ -5781,13 +5823,15 @@ get_constraints (MonoImage *image, int owner, MonoClass ***constraints, MonoGene GSList *cons = NULL, *tmp; MonoGenericContext *context = &container->context; + mono_error_init (error); + *constraints = NULL; found = 0; for (i = 0; i < tdef->rows; ++i) { mono_metadata_decode_row (tdef, i, cols, MONO_GENPARCONSTRAINT_SIZE); if (cols [MONO_GENPARCONSTRAINT_GENERICPAR] == owner) { token = mono_metadata_token_from_dor (cols [MONO_GENPARCONSTRAINT_CONSTRAINT]); - klass = mono_class_get_full (image, token, context); + klass = mono_class_get_and_inflate_typespec_checked (image, token, context, error); if (!klass) { g_slist_free (cons); return FALSE; @@ -5866,40 +5910,24 @@ mono_metadata_has_generic_params (MonoImage *image, guint32 token) * Memory is allocated from IMAGE's mempool. */ gboolean -mono_metadata_load_generic_param_constraints_full (MonoImage *image, guint32 token, - MonoGenericContainer *container) +mono_metadata_load_generic_param_constraints_checked (MonoImage *image, guint32 token, + MonoGenericContainer *container, MonoError *error) { guint32 start_row, i, owner; + mono_error_init (error); + if (! (start_row = mono_metadata_get_generic_param_row (image, token, &owner))) return TRUE; for (i = 0; i < container->type_argc; i++) { - if (!get_constraints (image, start_row + i, &mono_generic_container_get_param_info (container, i)->constraints, container)) + if (!get_constraints (image, start_row + i, &mono_generic_container_get_param_info (container, i)->constraints, container, error)) { + g_assert (!mono_loader_get_last_error ()); return FALSE; + } } return TRUE; } -/* - * mono_metadata_load_generic_param_constraints: - * - * @image: metadata context - * @token: metadata token to load the contraints, can be methodef or typedef. - * @container: generic container to load into. - * - * Load the generic parameter constraints for the newly created generic type or method - * represented by @token and @container. The @container is the new container which has - * been returned by a call to mono_metadata_load_generic_params() with this @token. - * Memory is allocated from IMAGE's mempool. - */ -void -mono_metadata_load_generic_param_constraints (MonoImage *image, guint32 token, - MonoGenericContainer *container) -{ - mono_metadata_load_generic_param_constraints_full (image, token, container); - /*FIXME this function can potentially exit with a pending loader error and cause all sort of havok */ -} - /* * mono_metadata_load_generic_params: * diff --git a/mono/metadata/object.c b/mono/metadata/object.c index daa72aec6f2..a2aa759293b 100644 --- a/mono/metadata/object.c +++ b/mono/metadata/object.c @@ -287,8 +287,19 @@ mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception) if (!klass->image->checked_module_cctor) { mono_image_check_for_module_cctor (klass->image); if (klass->image->has_module_cctor) { - MonoClass *module_klass = mono_class_get (klass->image, MONO_TOKEN_TYPE_DEF | 1); - MonoVTable *module_vtable = mono_class_vtable_full (vtable->domain, module_klass, raise_exception); + MonoError error; + MonoClass *module_klass; + MonoVTable *module_vtable; + + module_klass = mono_class_get_checked (klass->image, MONO_TOKEN_TYPE_DEF | 1, &error); + if (!module_klass) { + exc = mono_error_convert_to_exception (&error); + if (raise_exception) + mono_raise_exception (exc); + return exc; + } + + module_vtable = mono_class_vtable_full (vtable->domain, module_klass, raise_exception); if (!module_vtable) return NULL; exc = mono_runtime_class_init_full (module_vtable, raise_exception); @@ -4596,9 +4607,11 @@ mono_class_get_allocation_ftn (MonoVTable *vtable, gboolean for_box, gboolean *p MonoObject * mono_object_new_from_token (MonoDomain *domain, MonoImage *image, guint32 token) { + MonoError error; MonoClass *class; - class = mono_class_get (image, token); + class = mono_class_get_checked (image, token, &error); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ return mono_object_new (domain, class); } diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index 3691da1b5dd..e74fe3f0d65 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -1702,8 +1702,10 @@ fieldref_encode_signature (MonoDynamicImage *assembly, MonoImage *field_image, M if (type->num_mods) { for (i = 0; i < type->num_mods; ++i) { if (field_image) { - MonoClass *class = mono_class_get (field_image, type->modifiers [i].token); - g_assert (class); + MonoError error; + MonoClass *class = mono_class_get_checked (field_image, type->modifiers [i].token, &error); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ + token = mono_image_typedef_or_ref (assembly, &class->byval_arg); } else { token = type->modifiers [i].token; @@ -3798,7 +3800,9 @@ mono_image_fill_export_table_from_module (MonoDomain *domain, MonoReflectionModu t = &image->tables [MONO_TABLE_TYPEDEF]; for (i = 0; i < t->rows; ++i) { - MonoClass *klass = mono_class_get (image, mono_metadata_make_token (MONO_TABLE_TYPEDEF, i + 1)); + MonoError error; + MonoClass *klass = mono_class_get_checked (image, mono_metadata_make_token (MONO_TABLE_TYPEDEF, i + 1), &error); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ if (klass->flags & TYPE_ATTRIBUTE_PUBLIC) mono_image_fill_export_table_from_class (domain, klass, module_index, 0, assembly); @@ -7487,10 +7491,13 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT if (!image) image = mono_defaults.corlib; - if (ignorecase) - klass = mono_class_from_name_case (image, info->name_space, info->name); - else + if (ignorecase) { + MonoError error; + klass = mono_class_from_name_case_checked (image, info->name_space, info->name, &error); + g_assert (mono_error_ok (&error)); /* FIXME Don't swallow the error */ + } else { klass = mono_class_from_name (image, info->name_space, info->name); + } if (!klass) return NULL; for (mod = info->nested; mod; mod = mod->next) { @@ -9970,7 +9977,7 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb) mono_class_set_ref_info (klass, tb); - /* Put into cache so mono_class_get () will find it. + /* Put into cache so mono_class_get_checked () will find it. Skip nested types as those should not be available on the global scope. */ if (!tb->nesting_type) mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx); diff --git a/mono/metadata/sgen-internal.c b/mono/metadata/sgen-internal.c index 37ac5c6f329..9474d7cec5a 100644 --- a/mono/metadata/sgen-internal.c +++ b/mono/metadata/sgen-internal.c @@ -27,11 +27,19 @@ #include "metadata/sgen-memory-governor.h" /* keep each size a multiple of ALLOC_ALIGN */ +#if SIZEOF_VOID_P == 4 static const int allocator_sizes [] = { 8, 16, 24, 32, 40, 48, 64, 80, - 96, 128, 160, 192, 224, 248, 320, 384, - 448, 528, 584, 680, 816, 1088, 1360, 2040, - 2336, 2728, 3272, 4088, 5456, 8184 }; + 96, 128, 160, 192, 224, 248, 296, 320, + 384, 448, 504, 528, 584, 680, 816, 1088, + 1360, 2040, 2336, 2728, 3272, 4088, 5456, 8184 }; +#else +static const int allocator_sizes [] = { + 8, 16, 24, 32, 40, 48, 64, 80, + 96, 128, 160, 192, 224, 248, 320, 328, + 384, 448, 528, 584, 680, 816, 1016, 1088, + 1360, 2040, 2336, 2728, 3272, 4088, 5456, 8184 }; +#endif #define NUM_ALLOCATORS (sizeof (allocator_sizes) / sizeof (int)) diff --git a/mono/metadata/verify.c b/mono/metadata/verify.c index 50781a4bbf4..95bde8efbc5 100644 --- a/mono/metadata/verify.c +++ b/mono/metadata/verify.c @@ -1004,11 +1004,13 @@ verifier_load_type (VerifyContext *ctx, int token, const char *opcode) { MonoClass *class = mono_method_get_wrapper_data (ctx->method, (guint32)token); type = class ? &class->byval_arg : NULL; } else { + MonoError error; if (!IS_TYPE_DEF_OR_REF_OR_SPEC (token) || !token_bounds_check (ctx->image, token)) { ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Invalid type token 0x%08x at 0x%04x", token, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE); return NULL; } - type = mono_type_get_full (ctx->image, token, ctx->generic_context); + type = mono_type_get_checked (ctx->image, token, ctx->generic_context, &error); + mono_error_cleanup (&error); /*FIXME don't swallow the error */ } if (!type || mono_loader_get_last_error ()) { diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index 5f388de76e8..299b6c2cc63 100644 --- a/mono/mini/aot-compiler.c +++ b/mono/mini/aot-compiler.c @@ -308,39 +308,33 @@ get_plt_entry_debug_sym (MonoAotCompile *acfg, MonoJumpInfo *ji, GHashTable *cac static void aot_printf (MonoAotCompile *acfg, const gchar *format, ...) { - char *msg; + FILE *output; va_list args; - va_start (args, format); - if (vasprintf (&msg, format, args) < 0) - return; - va_end (args); - if (acfg->logfile) - fprintf (acfg->logfile, "%s", msg); + output = acfg->logfile; else - printf ("%s", msg); + output = stdout; - free (msg); + va_start (args, format); + vfprintf (output, format, args); + va_end (args); } static void aot_printerrf (MonoAotCompile *acfg, const gchar *format, ...) { - char *msg; + FILE *output; va_list args; - va_start (args, format); - if (vasprintf (&msg, format, args) < 0) - return; - va_end (args); - if (acfg->logfile) - fprintf (acfg->logfile, "%s", msg); + output = acfg->logfile; else - fprintf (stderr, "%s", msg); + output = stderr; - free (msg); + va_start (args, format); + vfprintf (output, format, args); + va_end (args); } /* Wrappers around the image writer functions */ @@ -2339,7 +2333,9 @@ find_typespec_for_class (MonoAotCompile *acfg, MonoClass *klass) if (!acfg->typespec_classes) { acfg->typespec_classes = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoClass*) * len); for (i = 0; i < len; ++i) { - acfg->typespec_classes [i] = mono_class_get_full (acfg->image, MONO_TOKEN_TYPE_SPEC | (i + 1), NULL); + MonoError error; + acfg->typespec_classes [i] = mono_class_get_and_inflate_typespec_checked (acfg->image, MONO_TOKEN_TYPE_SPEC | (i + 1), NULL, &error); + g_assert (mono_error_ok (&error)); /* FIXME error handling */ } } for (i = 0; i < len; ++i) { @@ -3543,14 +3539,15 @@ add_wrappers (MonoAotCompile *acfg) /* delegate-invoke wrappers */ for (i = 0; i < acfg->image->tables [MONO_TABLE_TYPEDEF].rows; ++i) { + MonoError error; MonoClass *klass; MonoCustomAttrInfo *cattr; token = MONO_TOKEN_TYPE_DEF | (i + 1); - klass = mono_class_get (acfg->image, token); + klass = mono_class_get_checked (acfg->image, token, &error); if (!klass) { - mono_loader_clear_error (); + mono_error_cleanup (&error); continue; } @@ -3631,13 +3628,14 @@ add_wrappers (MonoAotCompile *acfg) /* array access wrappers */ for (i = 0; i < acfg->image->tables [MONO_TABLE_TYPESPEC].rows; ++i) { + MonoError error; MonoClass *klass; token = MONO_TOKEN_TYPE_SPEC | (i + 1); - klass = mono_class_get (acfg->image, token); + klass = mono_class_get_checked (acfg->image, token, &error); if (!klass) { - mono_loader_clear_error (); + mono_error_cleanup (&error); continue; } @@ -3814,13 +3812,14 @@ add_wrappers (MonoAotCompile *acfg) /* StructureToPtr/PtrToStructure wrappers */ for (i = 0; i < acfg->image->tables [MONO_TABLE_TYPEDEF].rows; ++i) { + MonoError error; MonoClass *klass; token = MONO_TOKEN_TYPE_DEF | (i + 1); - klass = mono_class_get (acfg->image, token); + klass = mono_class_get_checked (acfg->image, token, &error); if (!klass) { - mono_loader_clear_error (); + mono_error_cleanup (&error); continue; } @@ -4279,13 +4278,14 @@ add_generic_instances (MonoAotCompile *acfg) } for (i = 0; i < acfg->image->tables [MONO_TABLE_TYPESPEC].rows; ++i) { + MonoError error; MonoClass *klass; token = MONO_TOKEN_TYPE_SPEC | (i + 1); - klass = mono_class_get (acfg->image, token); + klass = mono_class_get_checked (acfg->image, token, &error); if (!klass || klass->rank) { - mono_loader_clear_error (); + mono_error_cleanup (&error); continue; } @@ -5606,14 +5606,15 @@ emit_exception_debug_info (MonoAotCompile *acfg, MonoCompile *cfg) static guint32 emit_klass_info (MonoAotCompile *acfg, guint32 token) { - MonoClass *klass = mono_class_get (acfg->image, token); + MonoError error; + MonoClass *klass = mono_class_get_checked (acfg->image, token, &error); guint8 *p, *buf; int i, buf_size, res; gboolean no_special_static, cant_encode; gpointer iter = NULL; if (!klass) { - mono_loader_clear_error (); + mono_error_cleanup (&error); buf_size = 16; @@ -7841,10 +7842,11 @@ emit_class_name_table (MonoAotCompile *acfg) for (i = 0; i < table_size; ++i) g_ptr_array_add (table, NULL); for (i = 0; i < acfg->image->tables [MONO_TABLE_TYPEDEF].rows; ++i) { + MonoError error; token = MONO_TOKEN_TYPE_DEF | (i + 1); - klass = mono_class_get (acfg->image, token); + klass = mono_class_get_checked (acfg->image, token, &error); if (!klass) { - mono_loader_clear_error (); + mono_error_cleanup (&error); continue; } full_name = mono_type_get_name_full (mono_class_get_type (klass), MONO_TYPE_NAME_FORMAT_FULL_NAME); diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c index 58b84126d2e..98361554a3e 100644 --- a/mono/mini/aot-runtime.c +++ b/mono/mini/aot-runtime.c @@ -405,6 +405,7 @@ decode_generic_context (MonoAotModule *module, MonoGenericContext *ctx, guint8 * static MonoClass* decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf) { + MonoError error; MonoImage *image; MonoClass *klass = NULL, *eklass; guint32 token, rank, idx; @@ -423,21 +424,24 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf) image = load_image (module, 0, TRUE); if (!image) return NULL; - klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF + idx); + klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF + idx, &error); + g_assert (mono_error_ok (&error)); break; case MONO_AOT_TYPEREF_TYPEDEF_INDEX_IMAGE: idx = decode_value (p, &p); image = load_image (module, decode_value (p, &p), TRUE); if (!image) return NULL; - klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF + idx); + klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF + idx, &error); + g_assert (mono_error_ok (&error)); break; case MONO_AOT_TYPEREF_TYPESPEC_TOKEN: token = decode_value (p, &p); image = module->assembly->image; if (!image) return NULL; - klass = mono_class_get (image, token); + klass = mono_class_get_checked (image, token, &error); + g_assert (mono_error_ok (&error)); break; case MONO_AOT_TYPEREF_GINST: { MonoClass *gclass; @@ -1399,6 +1403,7 @@ aot_cache_load_module (MonoAssembly *assembly, char **aot_name) MonoDomain *domain = mono_domain_get (); MonoAssembly *entry_assembly = domain->entry_assembly; + // FIXME: This cannot be used for mscorlib during startup, since entry_assembly is not set yet for (l = config->apps; l; l = l->next) { char *n = l->data; @@ -1450,12 +1455,15 @@ aot_cache_load_module (MonoAssembly *assembly, char **aot_name) if (module) return module; - mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: not found."); - - if (!strcmp (assembly->aname.name, "mscorlib") && !mono_defaults.corlib) - /* Can't AOT this during startup */ + if (!strcmp (assembly->aname.name, "mscorlib") && !mscorlib_aot_loaded) + /* + * Can't AOT this during startup, so we AOT it when called later from + * mono_aot_get_method (). + */ return NULL; + mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: not found."); + /* Only AOT one assembly per run to avoid slowing down execution too much */ if (cache_count > 0) return NULL; @@ -1464,11 +1472,12 @@ aot_cache_load_module (MonoAssembly *assembly, char **aot_name) /* Check for previous failure */ failure_fname = g_strdup_printf ("%s.failure", fname); failure_file = fopen (failure_fname, "r"); - g_free (failure_fname); - if (!failure_file) { - mono_trace (G_LOG_LEVEL_MESSAGE, MONO_TRACE_AOT, "AOT: assembly '%s' previously failed to compile '%s' ('%s')... ", assembly->image->name, failure_fname); + if (failure_file) { + mono_trace (G_LOG_LEVEL_MESSAGE, MONO_TRACE_AOT, "AOT: assembly '%s' previously failed to compile '%s' ('%s')... ", assembly->image->name, fname, failure_fname); + g_free (failure_fname); return NULL; } else { + g_free (failure_fname); fclose (failure_file); } @@ -1739,10 +1748,6 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) if (mono_security_cas_enabled ()) return; - if (enable_aot_cache && !strcmp (assembly->aname.name, "mscorlib") && !mono_defaults.corlib && !mono_aot_only) - /* Loaded later from mono_aot_get_method () */ - return; - mono_aot_lock (); if (static_aot_modules) info = g_hash_table_lookup (static_aot_modules, assembly->aname.name); @@ -2098,9 +2103,7 @@ mono_aot_init (void) if (g_getenv ("MONO_LASTAOT")) mono_last_aot_method = atoi (g_getenv ("MONO_LASTAOT")); -#ifdef ENABLE_AOT_CACHE aot_cache_init (); -#endif } void @@ -2292,8 +2295,11 @@ mono_aot_get_class_from_name (MonoImage *image, const char *name_space, const ch name_space2 = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]); if (!strcmp (name, name2) && !strcmp (name_space, name_space2)) { + MonoError error; amodule_unlock (amodule); - *klass = mono_class_get (image, token); + *klass = mono_class_get_checked (image, token, &error); + if (!mono_error_ok (&error)) + mono_error_cleanup (&error); /* FIXME don't swallow the error */ /* Add to cache */ if (*klass) { @@ -3798,10 +3804,10 @@ mono_aot_get_method (MonoDomain *domain, MonoMethod *method) if (enable_aot_cache && !amodule && domain->entry_assembly && klass->image == mono_defaults.corlib) { /* This cannot be AOTed during startup, so do it now */ if (!mscorlib_aot_loaded) { + mscorlib_aot_loaded = TRUE; load_aot_module (klass->image->assembly, NULL); amodule = klass->image->aot_module; } - mscorlib_aot_loaded = TRUE; } if (!amodule) diff --git a/mono/mini/dwarfwriter.c b/mono/mini/dwarfwriter.c index 9f68a62683e..67585763b69 100644 --- a/mono/mini/dwarfwriter.c +++ b/mono/mini/dwarfwriter.c @@ -1376,6 +1376,7 @@ static const guint8 *token_handler_ip; static char* token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token) { + MonoError error; char *res, *desc; MonoMethod *cmethod; MonoClass *klass; @@ -1389,10 +1390,12 @@ token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token) case CEE_ISINST: case CEE_CASTCLASS: case CEE_LDELEMA: - if (method->wrapper_type) + if (method->wrapper_type) { klass = data; - else - klass = mono_class_get_full (method->klass->image, token, NULL); + } else { + klass = mono_class_get_checked (method->klass->image, token, &error); + g_assert (mono_error_ok (&error)); /* FIXME error handling */ + } res = g_strdup_printf ("<%s>", klass->name); break; case CEE_NEWOBJ: diff --git a/mono/mini/jit-icalls.c b/mono/mini/jit-icalls.c index 8c7c00c8322..fcfcf4f3cd1 100644 --- a/mono/mini/jit-icalls.c +++ b/mono/mini/jit-icalls.c @@ -17,7 +17,7 @@ #endif #include "jit-icalls.h" - +#include void* mono_ldftn (MonoMethod *method) { @@ -1022,9 +1022,9 @@ mono_helper_ldstr_mscorlib (guint32 idx) MonoObject* mono_helper_newobj_mscorlib (guint32 idx) { - MonoClass *klass = mono_class_get (mono_defaults.corlib, MONO_TOKEN_TYPE_DEF | idx); - - g_assert (klass); + MonoError error; + MonoClass *klass = mono_class_get_checked (mono_defaults.corlib, MONO_TOKEN_TYPE_DEF | idx, &error); + mono_error_raise_exception (&error); return mono_object_new (mono_domain_get (), klass); } diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 27f26a14a76..a07fee2fd77 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -6338,6 +6338,7 @@ mini_get_method (MonoCompile *cfg, MonoMethod *m, guint32 token, MonoClass *klas static inline MonoClass* mini_get_class (MonoMethod *method, guint32 token, MonoGenericContext *context) { + MonoError error; MonoClass *klass; if (method->wrapper_type != MONO_WRAPPER_NONE) { @@ -6345,7 +6346,8 @@ mini_get_class (MonoMethod *method, guint32 token, MonoGenericContext *context) if (context) klass = mono_class_inflate_generic_class (klass, context); } else { - klass = mono_class_get_full (method->klass->image, token, context); + klass = mono_class_get_and_inflate_typespec_checked (method->klass->image, token, context, &error); + mono_error_cleanup (&error); /* FIXME don't swallow the error */ } if (klass) mono_class_init (klass); @@ -10943,7 +10945,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b MONO_INST_NEW (cfg, ins, *ip); --sp; CHECK_OPSIZE (5); - klass = mono_class_get_full (image, read32 (ip + 1), generic_context); + klass = mono_class_get_and_inflate_typespec_checked (image, read32 (ip + 1), generic_context, &error); + mono_error_cleanup (&error); /* FIXME don't swallow the error */ CHECK_TYPELOAD (klass); mono_class_init (klass); @@ -10983,7 +10986,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b MONO_INST_NEW (cfg, ins, *ip); --sp; CHECK_OPSIZE (5); - klass = mono_class_get_full (image, read32 (ip + 1), generic_context); + klass = mono_class_get_and_inflate_typespec_checked (image, read32 (ip + 1), generic_context, &error); + mono_error_cleanup (&error); /* FIXME don't swallow the error */ CHECK_TYPELOAD (klass); mono_class_init (klass); @@ -11106,10 +11110,12 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b tclass, MONO_RGCTX_INFO_REFLECTION_TYPE); } else if (cfg->compile_aot) { if (method->wrapper_type) { - if (mono_class_get (tclass->image, tclass->type_token) == tclass && !generic_context) { + mono_error_init (&error); //got to do it since there are multiple conditionals below + if (mono_class_get_checked (tclass->image, tclass->type_token, &error) == tclass && !generic_context) { /* Special case for static synchronized wrappers */ EMIT_NEW_TYPE_FROM_HANDLE_CONST (cfg, ins, tclass->image, tclass->type_token, generic_context); } else { + mono_error_cleanup (&error); /* FIXME don't swallow the error */ /* FIXME: n is not a normal token */ DISABLE_AOT (cfg); EMIT_NEW_PCONST (cfg, ins, NULL); @@ -12155,19 +12161,25 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b guint32 val; int ialign; - GSHAREDVT_FAILURE (*ip); - CHECK_STACK_OVF (1); CHECK_OPSIZE (6); token = read32 (ip + 2); if (mono_metadata_token_table (token) == MONO_TABLE_TYPESPEC && !image_is_dynamic (method->klass->image) && !generic_context) { - MonoType *type = mono_type_create_from_typespec (image, token); + MonoType *type = mono_type_create_from_typespec_checked (image, token, &error); + mono_error_cleanup (&error); /* FIXME don't swallow the error */ + if (!type) + UNVERIFIED; + val = mono_type_size (type, &ialign); } else { - MonoClass *klass = mono_class_get_full (image, token, generic_context); + MonoClass *klass = mono_class_get_and_inflate_typespec_checked (image, token, generic_context, &error); + mono_error_cleanup (&error); /* FIXME don't swallow the error */ CHECK_TYPELOAD (klass); mono_class_init (klass); val = mono_type_size (&klass->byval_arg, &ialign); + + if (mini_is_gsharedvt_klass (cfg, klass)) + GSHAREDVT_FAILURE (*ip); } EMIT_NEW_ICONST (cfg, ins, val); *sp++= ins; diff --git a/mono/utils/mono-error-internals.h b/mono/utils/mono-error-internals.h index 80672403089..ac2394fa41c 100644 --- a/mono/utils/mono-error-internals.h +++ b/mono/utils/mono-error-internals.h @@ -32,6 +32,9 @@ mono_error_set_error (MonoError *error, int error_code, const char *msg_format, void mono_error_set_assembly_load (MonoError *error, const char *assembly_name, const char *msg_format, ...) MONO_INTERNAL; +void +mono_error_set_assembly_load_simple (MonoError *error, const char *assembly_name, gboolean refection_only) MONO_INTERNAL; + void mono_error_set_type_load_class (MonoError *error, MonoClass *klass, const char *msg_format, ...) MONO_INTERNAL; @@ -68,6 +71,9 @@ mono_error_set_from_loader_error (MonoError *error) MONO_INTERNAL; MonoException* mono_error_prepare_exception (MonoError *error, MonoError *error_out) MONO_INTERNAL; +MonoException* +mono_error_convert_to_exception (MonoError *error) MONO_INTERNAL; + void mono_error_raise_exception (MonoError *error) MONO_INTERNAL; diff --git a/mono/utils/mono-error.c b/mono/utils/mono-error.c index a59de349f30..63d6fcc00f8 100644 --- a/mono/utils/mono-error.c +++ b/mono/utils/mono-error.c @@ -188,6 +188,16 @@ mono_error_set_assembly_load (MonoError *oerror, const char *assembly_name, cons set_error_message (); } + +void +mono_error_set_assembly_load_simple (MonoError *oerror, const char *assembly_name, gboolean refection_only) +{ + if (refection_only) + mono_error_set_assembly_load (oerror, assembly_name, "Cannot resolve dependency to assembly because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event."); + else + mono_error_set_assembly_load (oerror, assembly_name, "Could not load file or assembly or one of its dependencies."); +} + void mono_error_set_type_load_class (MonoError *oerror, MonoClass *klass, const char *msg_format, ...) { @@ -321,10 +331,7 @@ mono_error_set_from_loader_error (MonoError *oerror) break; case MONO_EXCEPTION_FILE_NOT_FOUND: - if (loader_error->ref_only) - mono_error_set_assembly_load (oerror, loader_error->assembly_name, "Cannot resolve dependency to assembly because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event."); - else - mono_error_set_assembly_load (oerror, loader_error->assembly_name, "Could not load file or assembly or one of its dependencies."); + mono_error_set_assembly_load_simple (oerror, loader_error->assembly_name, loader_error->ref_only); break; case MONO_EXCEPTION_METHOD_ACCESS: @@ -629,20 +636,18 @@ mono_error_prepare_exception (MonoError *oerror, MonoError *error_out) } /* -Raises the exception of @error. -Does nothing if @error has a success error code. -Aborts in case of a double fault. This happens when it can't recover from an error caused by trying -to construct the first exception object. -The error object @error is cleaned up. +Convert this MonoError to an exception if it's faulty or return NULL. +The error object is cleant after. */ -void -mono_error_raise_exception (MonoError *target_error) + +MonoException* +mono_error_convert_to_exception (MonoError *target_error) { MonoError error; MonoException *ex; if (mono_error_ok (target_error)) - return; + return NULL; ex = mono_error_prepare_exception (target_error, &error); if (!mono_error_ok (&error)) { @@ -654,6 +659,21 @@ mono_error_raise_exception (MonoError *target_error) mono_error_cleanup (&error); } mono_error_cleanup (target_error); + return ex; +} - mono_raise_exception (ex); + +/* +Raises the exception of @error. +Does nothing if @error has a success error code. +Aborts in case of a double fault. This happens when it can't recover from an error caused by trying +to construct the first exception object. +The error object @error is cleaned up. +*/ +void +mono_error_raise_exception (MonoError *target_error) +{ + MonoException *ex = mono_error_convert_to_exception (target_error); + if (ex) + mono_raise_exception (ex); } diff --git a/mono/utils/sha1.h b/mono/utils/sha1.h index 63eb2beffb4..588518266ca 100644 --- a/mono/utils/sha1.h +++ b/mono/utils/sha1.h @@ -21,7 +21,7 @@ typedef struct { guint8 buffer[SHA1_BLOCK_LENGTH]; } SHA1_CTX; -__BEGIN_DECLS +G_BEGIN_DECLS void SHA1Init(SHA1_CTX *); void SHA1Pad(SHA1_CTX *); void SHA1Transform(guint32 [5], const guint8 [SHA1_BLOCK_LENGTH]); @@ -31,7 +31,7 @@ char *SHA1End(SHA1_CTX *, char *); char *SHA1File(const char *, char *); char *SHA1FileChunk(const char *, char *, off_t, off_t); char *SHA1Data(const guint8 *, size_t, char *); -__END_DECLS +G_END_DECLS #define HTONDIGEST(x) do { \ x[0] = htonl(x[0]); \